Creating components from templates: Numeric Keyboard
With this template you can add a new Numeric Keyboard component to your project. Numeric Keyboard component provides a grid with keys the user can touch. Activating a key feeds the corresponding event to the application as if the user had pressed the key on a real keyboard.
Components created with this template are intended to be adapted to your particular design expectations. After adding the new Numeric Keyboard you should edit the component, change its appearance and if desired also its behavior. Once you have adapted the component, you can embed instances of this Numeric Keyboard wherever you need in your GUI project. Because it serves as template, it is intentionally kept very simple. Nevertheless, Numeric Keyboards created by the template are working widgets. If desired, they can already be used as they are. The following figure demonstrates the default appearance of the Numeric Keyboard created by using the here described component template:

The approach with component templates has two functions. Primarily the templates should simplify the development of new components. Instead of creating the Numeric Keyboard from scratch you can use the available template. The second function is more educative. The template implements fully working Numeric Keyboard component you can investigate and learn about the corresponding programming aspects. The template is well documented. It contains annotations and inline comments with instructions helping you to understand how the component works and how it can be adapted to your particular needs.
This chapter provides an overview how the Numeric Keyboard component template is used within your own application and how you adapt this component according to your particular needs. You will find here also further details concerning the internal implementation of the Numeric Keyboard component.
Add new Numeric Keyboard component
To create a new Numeric Keyboard component from a template you simply Drag & Drop it between the Templates window and the Composer with an opened unit. This is important in that by using the component templates you add in fact a new class to your project. Classes, in turn, can exist within units only. The following are the typical steps to create a new Numeric Keyboard component from a template:
★First switch to the Composer page for the respective unit, where you want to add the new Numeric Keyboard component.
★Then ensure that the Templates window is visible.
★In Templates window switch to the folder Component Templates.
★In the folder locate the Numeric Keyboard template.
★Drag & Drop the template into the Composer window:

★Eventually name the new added component.
The new created Numeric Keyboard component appears accompanied by annotation providing helpful tips how to proceed. If undesired, you can select and delete the annotation.
Use the Numeric Keyboard component
Once you have created the Numeric Keyboard component, you can use it to assemble more complex components. Technically seen, you embed an instance of the Numeric Keyboard class in-place within some superior GUI component. At the runtime, the superior GUI component takes care of the correct initialization and the displaying of all embedded components, so they appear similarly as you have composed them at the design time. Usually, the superior component where you embed the keyboard instance will be the Application component.
Step 1. Add new Numeric Keyboard instance
The following are the typical steps to create a new instance of an already existing Numeric Keyboard component:
★First switch to the Composer page for the respective GUI component, where you want to add the new Numeric Keyboard. This is usually the Application component.
★Then ensure that the Browser window is visible.
★Within the Browser locate the class of the previously created Numeric Keyboard. This can be done easily with Browser's own filter function.
★Select the found class in the Browser window.
★Drag & Drop the selected class into the Composer area.

★Eventually name the new instance according to its function within the application.
Component templates are intended to create widgets which can be modified and adapted to your particular design expectations. In the following sections you will learn how to do this. Originally, if not yet modified, the Numeric Keyboard appears as a white rectangle surrounded by a border and filled with text and images to represent the keys. Our intention is to keep the component templates as minimalistic as possible so they don't distract you with less important design details.
Step 2. Inspect the Numeric Keyboard instance
As long as the Numeric Keyboard is selected you can inspect and modify its properties conveniently in the Inspector window as demonstrated with the property Bounds in the screenshot below. This is in so far worth mentioning as diverse features of the Numeric Keyboard are controlled by the corresponding properties. If you are not familiar with the concept of a property and the usage of Inspector window, please read first the preceding chapter Compositing component appearance.

The Numeric Keyboard component descends from the Mosaic class Core::Group. Consequently, all of the properties listed in the above screenshot are inherited from this base class. The Numeric Keyboard itself does not add any new property.
Step 3. Arrange the Numeric Keyboard within the Application component
Once added to the Application component, you can freely move the Numeric Keyboard instance, or you simply grab one of its corners and resize it in this way. You can control the position and the size of the component also by directly modifying its property Bounds.
Step 4. Present the keyboard when needed
Once you have embedded the Numeric Keyboard instance in your Application component, it is visible whenever the Application component is visible. However, in many applications the virtual keyboard should only appear when the user needs to enter data - for example, when a text editor is focused. The rest of the time, the keyboard should remain hidden to save screen space.
You can control the visibility of the keyboard by modifying its Visible and Enabled properties. To make the keyboard hidden by default, configure both properties to false when the keyboard instance is selected in the Composer:

When the user needs to enter data (for example, when a text editor gains focus), you show the keyboard by setting its properties Visible and Enabled to true and assigning the keyboard instance to the VirtualKeyboard property of the Application component:
// Show the keyboard when it is needed NumKeyboard.Visible = true; NumKeyboard.Enabled = true; VirtualKeyboard = NumKeyboard;
Assigning the keyboard instance to the VirtualKeyboard property is essential for the keyboard to work correctly. This ensures that:
★The keyboard receives all touch events before other GUI components
★The keyboard automatically becomes topmost and remains visible on top of all other views
★The keyboard-generated events are properly delivered to the focused components
When the user finishes entering data (for example, by pressing Enter or when the text editor loses focus), you can hide the keyboard again:
// Hide the keyboard when it is not needed anymore VirtualKeyboard = null; NumKeyboard.Visible = false; NumKeyboard.Enabled = false;
Step 5. Present the keyboard with animation
If you want the keyboard to slide in from the bottom of the screen (or perform any other animation) when shown, the most sophisticated approach is to use a fader. Faders provide professional fade-in and fade-out transitions with automatic component management. Following example demonstrates how to present the keyboard using the Effects::PositionFader:
var Effects::PositionFader fader = new Effects::PositionFader; var rect r = NumKeyboard.Bounds; // Final position of the keyboard: horizontally centered and aligned at bottom edge // of the Application component. r.x += Bounds.orect.center.x - r.center.x; r.y = Bounds.orect.y2 - r.h; // Configure the fade-in animation. The keyboard should slide in from the // bottom edge and be modulated in opacity. fader.Visible = true; fader.OpacityEffect.CycleDuration = 250; fader.OpacityEffect.Value1 = 0; fader.OpacityEffect.Value2 = 255; fader.PositionEffect.CycleDuration = 250; fader.PositionEffect.Timing = Effects::Timing.FastIn_EaseOut; fader.PositionEffect.Value1 = r.origin + point( 0, r.h ); fader.PositionEffect.Value2 = r.origin; // Present the keyboard with animation VirtualKeyboard = NumKeyboard; FadeGroup( NumKeyboard, fader, null, null, false );
This approach provides smooth animations and handles the keyboard presentation professionally. The FadeGroup() method is available in the Core::Group class (Base class of the Application component) and manages the fade transitions automatically.
Alternatively, if you prefer to use animation effects directly, you can modify the keyboard's position together with visibility. For this purpose you can use the Move and resize rect effect:
★Configure the effect with the start and end positions of the keyboard.
★Ensure the effect is connected to the property Bounds of the keyboard instance.
★Ensure the effect's timing is configured appropriately.
Then, to show the keyboard, just start the effect. Following code demonstrates the initialization of the effect to slide the keyboard from the bottom edge of the Application component:
var rect r = NumKeyboard.Bounds; // Final position of the keyboard horizontally center and aligned at bottom edge // of the Application component. r.x += Bounds.orect.center.x - r.center.x; r.y = Bounds.orect.y2 - r.h; // The end and start position of the keyboard RectEffect.Value2 = r; RectEffect.Value1 = r + point( 0, r.h ); // Configure the timing of the effect. The effect should control the Bounds property. RectEffect.Outlet = ^NumKeyboard.Bounds; RectEffect.NoOfCycles = 1; RectEffect.CycleDuration = 500; // Start the effect. At the same time make the virtual keyboard component visible // and able to react to user inputs. Assign the keyboard to VirtualKeyboard property. RectEffect.Enabled = true; NumKeyboard.Enabled = true; NumKeyboard.Visible = true; VirtualKeyboard = NumKeyboard;
Open the component for editing
Component templates are intended to create widgets which can be adapted and enhanced to your particular design expectations. For this purpose, once you have added a new Numeric Keyboard component to your project, you can open the component class for editing. Thereupon the implementation of the component appears in a new Composer page:

Originally, if not yet modified, the Numeric Keyboard appears displaying a grid of digit keys (0-9) as text views and special keys (Clear, Enter) as image views. A white background is surrounded by a border. When a key is pressed, it is highlighted with a red rectangle. Our intention is to keep the component templates as minimalistic as possible so they don't distract you with less important design details. The keyboard can react to touch inputs and provides visual feedback with a flash effect for quick taps.
This default functionality is implemented by following members belonging to the Numeric Keyboard. These members are explicitly intended to be modified. Understanding this internal structure is thus the first step before you start to adapt the keyboard to your particular needs:
Icon |
Member |
Description |
|---|---|---|
|
TouchHandler |
This simple touch handler enables the user to interact with the keyboard by touching and dragging. It covers the entire keyboard area and reports touch events to the corresponding slot methods. |
|
onPressTouch |
This internal slot method is called when the user touches the keyboard. It updates the recentPosition variable and requests a keyboard appearance update. |
|
onDragTouch |
This internal slot method is called when the user drags the finger across the keyboard. It updates the recent touch position and triggers visual feedback for the key at the new position. |
|
onReleaseTouch |
This internal slot method is called when the user releases the finger from the keyboard. Depending on the touch duration, it either immediately activates the key or starts the flash timer for quick taps. |
|
FlashTimer |
This timer object provides a short visual feedback flash effect when the user taps a key very quickly. The default duration is 50 milliseconds. |
|
onFlashTimer |
This internal slot method is called when the FlashTimer expires. It ends the flash feedback effect and activates the pressed key. |
|
activateKey |
This internal slot method is called when a key should be activated. It determines which key was pressed and generates the corresponding keyboard event for the application. |
|
Background |
This Filled Rectangle view displays the background of the keyboard. The background is white per default. |
|
Border |
This Border view displays the border of the keyboard with 3 pixel thickness in black color per default. |
|
Highlight |
This Filled Rectangle view provides visual feedback by highlighting the pressed key. It is moved to the position of the pressed key and displayed in red per default. |
|
TextKey0 .. TextKey9 |
These Text views represent the digit keys 0 through 9. Each displays one digit using the Resources::FontLarge font. |
|
ImageKeyClear |
This Image view represents the Clear (Backspace) key using an icon from Resources::KeyIconsMedium bitmap resource. |
|
ImageKeyEnter |
This Image view represents the Enter key using an icon from Resources::KeyIconsMedium bitmap resource. |
|
UpdateViewState |
This method is invoked automatically after touch events. The method updates the keyboard views to reflect which key is currently pressed and provides visual feedback. |
|
keyView |
This variable stores a reference to the view representing the currently pressed key. It is null if no key is pressed. |
|
recentPosition |
This variable stores the most recent touch position within the keyboard area. |
Understand the state management of the component
During its lifetime, the Numeric Keyboard will react to user touch interactions. To track which key is currently pressed, the keyboard manages the above mentioned variable keyView. This variable either refers to the view representing the pressed key or is null if no key is pressed. The variable is evaluated and updated within the implementation of the method UpdateViewState. This method determines which key the user is currently touching by searching for a view at the recent touch position:
// Determine the new state of the affected keyboard. var Core::View isKeyView = null; var bool isPressed = ( TouchHandler.Down && TouchHandler.Inside ) || FlashTimer.Enabled; // Search for the view representing the key at the recent touch position. if ( isPressed && ( recentPosition == TouchHandler.GetExtent())) isKeyView = FindViewAtPosition( null, recentPosition, Core::ViewState[]);
The local variable isKeyView will refer to the view at the current touch position. The keyboard then updates the appearance by comparing isKeyView (the currently pressed key) with keyView (the previously pressed key). If they differ, the keyboard updates the visual feedback accordingly - highlighting the new key and removing highlight from the previous key.
Depending on your design expectations, the default state management may require adaptations. Generally, you are free to modify the method UpdateViewState, add further state variables to your keyboard, or change how visual feedback is provided when keys are pressed.
Adapt the appearance of the component
Originally, if not yet modified, the Numeric Keyboard appears displaying digit keys as black text on white background, special keys as black icons, and a red rectangle that highlights the pressed key. Our intention is to keep the component templates as minimalistic as possible so they don't distract you with less important design details. It's up to you to adapt the keyboard to have the expected appearance. The available possibilities are explained in the following sections. Please note, that you can combine the different approaches according to your application case:
1. Modify existing views
The Numeric Keyboard template contains per default the views Background, Border, Highlight and the key views (TextKey0 .. TextKey9, ImageKeyClear, ImageKeyEnter). If desired, you can modify these views. For example, you can change the colors, fonts, or highlight style. For this purpose you change the implementation of the above explained method UpdateViewState responsible for providing visual feedback when keys are pressed.
When you open the method UpdateViewState you will see that it updates the key views depending on whether they are pressed or released. Text key views change their color from black to white when pressed, and image key views do the same. Additionally, the Highlight view is positioned behind the pressed key. By simply modifying this implementation you change the appearance. For example, you can change the highlight color from red to blue:
// If the user is actually pressing a key, arrange the background view // just behind the affected key view so it appears selected. if ( isKeyView != null ) { Highlight.Bounds = isKeyView.GetExtent(); Highlight.Color = #0000FFFF; // <-- blue color instead of red Highlight.Visible = true; } else Highlight.Visible = false;
Or you can change the pressed text color to yellow instead of white:
// If the user has pressed a key represented by a 'text' view, change the // color of the text to appear highlighted. if ( isTextKeyView != null ) isTextKeyView.Color = #FFFF00FF; // <-- yellow color
2. Remove existing views
If not needed, you can delete some of the per default existing key views. For example, if you don't need the Clear and Enter keys, you can remove the ImageKeyClear and ImageKeyEnter views. Doing this, please don't forget to also remove all references to the deleted views from the implementation of the UpdateViewState and activateKey methods. Otherwise you will get error messages next time the Composer contents is reloaded. To avoid this error message we recommend to perform the steps in following order:
★In the UpdateViewState method adapt the implementation to not refer anymore to the undesired view. Review the method, whether it contains code refering the affected view. Remove the code appropriately.
★In the activateKey method adapt the implementation to not handle the removed key. For example, if you decided to delete the ImageKeyClear view, remove the corresponding code block:
// Has the user touched the 'Clear' key? else if ( keyView == ImageKeyClear ) keyCode = Core::KeyCode.Backspace;
★Now you can delete the affected view(s).
Similarly, if you want to remove all text keys and keep only image-based keys, you should adapt the UpdateViewState and activateKey methods accordingly before deleting the text key views.
3. Add further keys to the component
You can add more keys to your keyboard. For example, you can add decimal point, plus/minus sign, or other special characters. Following steps explain the workflow:
★Name the just added view according to its function in the keyboard. For example TextKeyDot for a decimal point key.
★In order to arrange the view within the keyboard grid, move the view, or you simply grab one of its corners and resize it in this way. Make sure the view is positioned within the TouchHandler area. If you want the view to appear behind other views you can reorder it explicitly.
★If necessary, you can rearange or resize other views to make space for the new key.
★In Inspector window configure the properties of the just added view. For a text view, set the String property to the character you want to display (e.g. "."). For an image view, select the appropriate Bitmap and FrameNumber.
★If you used image views, enhance the activateKey method to handle the new key activation. See the existing implementation for the ImageKeyClear and ImageKeyEnter views.
4. Replace existing views
Also possible, you can replace the existing key views by other views. For example, you could replace all text-based digit keys with image-based keys for a more graphical appearance. For this purpose:
★Think about which views are adequate as replacement for the old views.
★Delete the old view(s).
★Add the desired view(s) to the component.
★Name the just added view according to its function.
★Eventually move the view, or you simply grab one of its corners and resize it in this way. If you want the view to appear behind other views you can reorder it explicitly.
★If necessary, in Inspector window configure the properties of the just added view.
★If necessary, modify the implementation of UpdateViewState and activateKey methods to work with the new view types. You may need to adjust the object runtime cast operations in UpdateViewState to recognize your new view types.
5. Add decoration views
You can add further views to your keyboard for decoration purposes. For example, you can add separator lines between keys, a background image, or a caption text. Following steps explain the workflow:
★First add the desired view to the component.
★Name the just added view according to its function.
★In order to arrange the view within the keyboard, move the view, or you simply grab one of its corners and resize it in this way. If you want the view to appear behind the keys you can reorder it explicitly by moving it before the key views in the Inspector's members list.
★In Inspector window configure the properties of the just added view.
Decoration views don't participate in key press detection, so you don't need to modify the UpdateViewState or activateKey methods for them.
IMPORTANT
If you add a Text or an Image view and arrange it within the area of the TouchHandler, the view will be considered as a potential key. Therefore avoid placing text or image views within this area. If this is inevitable, please adapt the UpdateViewState() method to ignore the decoration views.
Configure the layout of the component
The initial size of the Numeric Keyboard is determined by the thick blue border surrounding the Canvas area. You can configure the Canvas area size by clicking and dragging the edges of the surrounding border (see also Resize the Canvas area). For example, to make the keyboard wider, drag on its right edge:

The views existing per default in the Numeric Keyboard template are automatically adjusted to fill the area of the component when it is resized. All other views you have eventually added later to the component are not adjusted automatically.
To control the adjustment you have to explicitly configure for each view its Layout property (see also Configure component layout). Let's assume, in order to display a caption text you have added a Text view to the Numeric Keyboard. Then you have arranged the view within the Canvas area according to your design expectation. If you want that the view remains aligned at the top edge filling the width of the component when it is resized, you configure its Layout property as shown below:

Implement the interface of the component
When creating your own Numeric Keyboard component you should ensure that instances of the keyboard can be configured to control all the features implemented in it. For example, if you have enhanced the keyboard by a caption text (e.g. "Enter PIN code"), you should add a property to specify this caption text. In this way keyboard instances can be configured to display different captions.
To control the features in your keyboard you use properties. A property can be understood as variable where the corresponding setting is stored, e.g. the caption text, color value, etc.. When the value of the property changes, the keyboard can react to it and update its appearance accordingly. The properties reflect thus the settings within your keyboard. Together they form the interface of the component.
Usually, each particular setting within a component is represented by the corresponding property. In its original version, the Numeric Keyboard doesn't contain any properties - all settings are fixed in the component's design. In order to enhance this interface by your own properties, following steps are necessary:
★Add a new property to the Numeric Keyboard component.
★Name the property according to the setting it should represent. For example, the property intended to store the caption text could be named Caption.
★Determine the data type of the property. For example, the property intended to store the caption text will use the string data type.
★Determine the initialization value of the property. This value should correspond to the keyboard's default state. For example, the property intended to store the caption text could be initialized with "" (empty string) if no caption text should appear per default.
★The property is accompanied by its onget method. Except particular cases, this method is not needed and can be deleted now.
★The property is accompanied by its onset method. Open this method for editing.
★Adapt the implementation of the onset method so it updates the keyboard according to its new value. For example, in case of the property intended to store the caption text, you will update the respective CaptionText view:
// The value doesn't change - nothing to do. if ( pure Caption == value ) return; // Remember the property's new value. pure Caption = value; // Update the CaptionText view to use the just assigned string. CaptionText.Color = value;
That is all. Now when you deal with instances of the Numeric Keyboard component, you can evaluate and modify the properties similarly to how you access variables. Especially, when the keyboard instance is selected, you see in Inspector window the property and can change it there. The modification is immediately visible in the Composer window.
If desired, the properties can also be modified at the runtime of your application. For example, the caption text can be changed dynamically. For this purpose you access and modify the affected property directly within Chora code:
// Change the caption text NumKeyboard.Caption = "Enter PUK code";
Understand the handling of touch inputs
The Numeric Keyboard is an interactive component that responds to touch and mouse inputs. For this purpose the template contains the Simple Touch Handler object named TouchHandler. The touch handler covers the entire keyboard area where keys are located. To this handler are associated three slot methods: onPressTouch, onReleaseTouch and onDragTouch. As their names imply the methods are invoked at the beginning of the interaction (press), at its end (release) and repeatedly while then user drags the finger (mouse pointer) inside the handler's area:

When the user initially touches the keyboard, onPressTouch is called. This method:
★Requests a keyboard appearance update by calling InvalidateViewState()
★Handles the case when the user taps very rapidly - if a flash effect is still running from a previous tap, it completes that tap first
★Stores the current touch position in recentPosition
InvalidateViewState(); // Handle rapid successive taps if ( FlashTimer.Enabled ) { signal activateKey; FlashTimer.Enabled = false; } recentPosition = TouchHandler.CurrentPos;
When the user drags the finger across the keyboard, onDragTouch is called. This method:
★Requests a keyboard appearance update
★Updates the recentPosition to reflect the new touch location
This allows the keyboard to highlight different keys as the user drags between them, providing immediate visual feedback.
When the user releases the finger, onReleaseTouch is called. This method:
★Requests a keyboard appearance update
★Checks if the release occurred inside the keyboard area - if not, no key is activated
★Determines whether to activate the key immediately or start the flash timer
InvalidateViewState(); // User moved finger outside keyboard - don't activate if ( !TouchHandler.Inside ) return; // Long press - activate immediately if ( TouchHandler.HoldPeriod >= FlashTimer.Begin ) signal activateKey; // Quick tap - show flash feedback first else FlashTimer.Enabled = true;
If the user held the key long enough (more than 50ms specified by default in FlashTimer), the key is activated immediately. For very quick taps, the FlashTimer is started to provide a brief visual feedback before activation.
Usually you will not need to edit the implementation of these methods. They correspond already to whatever typical virtual keyboards do. Nevertheless, you are free to change this default functionality if you want some particular behavior to be implemented in your keyboard.
Adapt the feedback (flash) animation
The Numeric Keyboard provides visual feedback when keys are pressed. For longer key presses, the feedback is immediate - the key appearance changes while the user holds it. However, for very quick taps (shorter than 50ms), the key press and release happen so fast that the user might not see any feedback. To solve this, the keyboard uses a flash effect timer. The flash effect is implemented using the Core::Timer object named FlashTimer. The timer prolongates thereupon the visual effect. As soon as the timer expires, it signals its associated slot method: onFlashTimer:

This method takes care of two tasks. At first it requests an invocation of the UpdateViewState method to update the visual appearance of the virtual keyboard. The key at the recently touched position should not appear pressed anymore. The second task is to send a signal to the slot method activateKey. Following code demonstrates this implementation:
// Request the keyboard to update its appearance InvalidateViewState(); // Now activate the key signal activateKey;
The FlashTimer object is configured per default with the value 50 milliseconds. If necessary you can change this behavior and specify other delay. The timer provides for this purpose the property Begin. For example, if you want the feedback effect to take 250 ms, change this property to the value 250. For more details, see Specify the timer interval and the initial delay.
Understand the keyboard event generation
The Numeric Keyboard component generates keyboard events that can be received by other GUI components in your application, such as text editors. The event generation happens in the activateKey slot method. When a key is activated (either immediately after a long press or after the flash effect for quick taps), the activateKey method is called. This method:
★Determines which key was pressed by examining the keyView variable
★Converts the pressed key to either a character code or a key code
★Generates keyboard events using the DriveKeyboardHitting() method
var Views::Text textKeyView = (Views::Text)keyView; var char charCode = '\0'; var Core::KeyCode keyCode = Core::KeyCode.NoKey; // Text key - use the displayed character if ( textKeyView != null ) charCode = textKeyView.String[0]; // Enter key else if ( keyView == ImageKeyEnter ) keyCode = Core::KeyCode.Enter; // Clear key (Backspace) else if ( keyView == ImageKeyClear ) keyCode = Core::KeyCode.Backspace; // Generate the keyboard events if ( charCode != '\0' ) { GetRoot().DriveKeyboardHitting( Core::KeyCode.NoKey, charCode, true ); GetRoot().DriveKeyboardHitting( Core::KeyCode.NoKey, charCode, false ); } if ( keyCode != Core::KeyCode.NoKey ) { GetRoot().DriveKeyboardHitting( keyCode, '\0', true ); GetRoot().DriveKeyboardHitting( keyCode, '\0', false ); }
For each key press, the method generates two events: (1) press event (DriveKeyboardHitting( ..., true )) and (2) corresponding release event (DriveKeyboardHitting( ..., false )). This pair of events simulates the complete key press cycle, just as if the user had pressed a key on a physical keyboard. Depending on the taped view, the method distinguishes between two types of keys:
★Character keys (digits 0-9): These are represented by text views and generate character codes. The character is extracted from the view's String property. For example, pressing the "5" key generates the character code '5'.
★Special keys (Enter, Clear): These are represented by image views and generate key codes from the Core::KeyCode enumeration. For example, the Clear key generates Core::KeyCode.Backspace.
When you add new keys to your keyboard, you need to adapt the activateKey method to handle them:
★For character keys (displayed as text): No changes needed - the method automatically extracts the character from the text view's String property.
★For special keys (displayed as images): Add a new condition to map the key to the appropriate key code:
// Has the user touched your custom special key? else if ( keyView == ImageKeyCustom ) keyCode = Core::KeyCode.SomeKeyCode;
You can find available key codes in the Core::KeyCode enumeration documentation.
Similar to events generated by a physical keyboard, the events generated by a virtual keyboard are delivered to GUI components along the so-called focus path:
★The DriveKeyboardHitting() method sends the event to the root object (the application component)
★The root object forwards the event to the component at the end of the focus path (the currently focused component)
★If a text editor has focus, it will receive and process the character, updating its content accordingly
★If the focused component ignored the event, the event is deliver to the next superior component
This approach follows the standard keyboard event handling pattern in Embedded Wizard, ensuring your virtual keyboard integrates seamlessly with other GUI components. For more details see Handling keyboard events and Keyboard events and the focus path.
Perform state changes with animations
In the section Adapt the appearance of the component you learned how the keyboard updates its appearance when keys are pressed and released. Accordingly, when the user touches a key, the key appears highlighted instantly. When the user releases the key, it returns to its normal appearance immediately. The default implementation performs such appearance updates instantly, just in the moment when the respective state change took place.
If desired, you can modify the Numeric Keyboard to update its appearance with animations. For example, instead of instantly switching the highlight color, the keyboard can smoothly fade between colors, or scale the key size for a "bounce" effect. For this purpose you use the Animation Effects. With an Animation Effect you can animate a property of a view existing in the keyboard. Following are the steps how to do this:
★Depending on the data type of the property to animate, add the appropriate Animation Effect to the Numeric Keyboard. For example, to animate the color of the highlight, add a Pulse color effect.
★Connect the effect object with the property to animate. For example, if you want to animate the color of the Highlight view, connect the Pulse color effect with the property Color of the Highlight view.
★Configure the duration and eventually the desired timing (easing) for the animation. For example, a duration of 100 milliseconds with Effects::Timing.EaseIn_EaseOut timing.
★Once started, the effect will animate the property endlessly. In our case, however, the animation should stop at its end. For this purpose set the effect's property NoOfCycles to the value 1.
★Configure the key values for the animation. In case of the pulse color effect, it is the start and the end color. For example, to animate the highlight color from transparent to red, configure the effect's property Value1 with #FF000000 (transparent red) and the property Value2 with #FF0000FF (opaque red). This step is appropriate if the key values are fixed, known at the design time. Otherwise, the key values must be set at runtime shortly before the effect is triggered.
★Open the method UpdateViewState and modify its implementation to trigger the effect object when a key is pressed or released. For example in case of the above mentioned pulse color effect to animate the highlight color, following implementation could be adequate:
// Detect a state alternation when the user presses a new or releases a // previously pressed key. if ( isKeyView != keyView ) { // ... existing code to update views instantly ... // Start the fade-in animation when a key is pressed if (( isKeyView != null ) && ( keyView == null )) { HighlightColorEffect.Reversed = false; HighlightColorEffect.Enabled = true; } // Start the fade-out animation when a key is released else if (( isKeyView == null ) && ( keyView != null )) { HighlightColorEffect.Reversed = true; HighlightColorEffect.Enabled = true; } }
★Since the properties of the affected views are now modified with animations, you will eventually need to adapt their initial values to correspond to the default state of the keyboard. For example, you might need to set the property Color of the Highlight view to the animation's start value.









