Creating components from templates: Toggle Button

With this template you can add a new Toggle Button component to your project. Toggle Button is a bistable, interactive widget the user can activate by touching within the Toggle Button's area. Each time the user activates a Toggle Button, the button alternates its state and sends a signal to an associated slot method where your particular implementation is executed. If the Toggle Button is focused the component can also be controlled by pressing keys on the keyboard or by using hardware buttons. This component is suitable to serve as a check box.

Components created with this template are intended to be adapted to your particular design expectations. After adding the new Toggle Button 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 Toggle Button wherever you need in your GUI project. Because it serves as template, it is intentionally kept very simple. Nevertheless, Toggle Buttons 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 Toggle Button 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 Toggle Button from scratch you can use the available template. The second function is more educative. The template implements fully working Toggle Button 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 Toggle Button 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 Toggle Button component.

Component templates versus ready-to-use widgets

Besides the here described Toggle Button component template, Embedded Wizard provides also a ready to use Toggle Button widget. It is finished implemented and ready to be used as it is. Within a certain limits, the appearance and partially also the behavior of the Toggle Button widget can be configured. The advantage of the approach is, that to customize it you don't need to write a single line of code. The flexibility of the provided widget, however, is limited by its implementation.

With the component template you are not limited. But you have to take care of the adaptation of the so created component. You have to write code. More deep understanding is required. Summarized, the ready to use widgets follow a convenient, simple but also limited approach where you don't need to write a single line of code. With the here described component templates you have to write code by which you are flexible to create very individual and sophisticated widgets. Which of the both approaches applies to you does depend on your application case. By understanding the differences in the both concepts you can select the optimal one.

Add new Toggle Button component

To create a new Toggle Button 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 Toggle Button component from a template:

First switch to the Composer page for the respective unit, where you want to add the new Toggle Button component.

Then ensure that the Templates window is visible.

In Templates window switch to the folder Component Templates.

In the folder locate the Toggle Button template.

Drag & Drop the template into the Composer window:

Eventually name the new added component.

The new created Toggle Button component appears accompanied by annotation providing helpful tips how to proceed. If undesired, you can select and delete the annotation.

Use the Toggle Button component

Once you have created the Toggle Button component, you can use it to assemble more complex components. Technically seen, you embed an instance of the Toggle Button 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.

Step 1. Add new Toggle Button instance

The following are the typical steps to create a new instance of an already existing Toggle Button component:

First switch to the Composer page for the respective GUI component, where you want to add the new Toggle Button.

Then ensure that the Browser window is visible.

Within the Browser locate the class of the previously created Toggle Button. 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 GUI component (e.g. DarkMode).

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 Toggle Button appears composed of rectangles and surrounded by a border. 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 Toggle Button instance

As long as the Toggle Button 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 Toggle Button 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 Toggle Button component descends from the Mosaic class Core::Group. Consequently, most of the properties listed in the above screenshot are inherited from this base class. Particular to the Toggle Button are only few following properties:

Property

Description

Active

The property Active stores the current state of the toggle button. As long as the property is false, the widget should appear in switched-off state. As soon as the property changes to true, the widget should appear in switched-on state.

OnToggle

The property OnToggle can refer to a slot method, which will receive a signal as soon as the user has toggled the button. Thereupon the method's logic will be executed. In the associated slot method you can evaluate the current value of the property Active.

Outlet

The property Outlet can refer to any other bool property the widget should remain synchronized with. When the user toggles the button, the affected property is automatically updated to reflect the button's current state. On the other hand, when the referred property is modified by another one, the button is automatically notified to remain in sync with the property.

This approach follows the model-view-controller (MVC) programming paradigm, where the Toggle Button has the function of the view and controller and the property referred via Outlet serves as model. See also Outlet properties.

Step 3. Arrange the Toggle Button within the superior component

Once added to the component, you can freely move the Toggle Button 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. If you want the Toggle Button to appear behind other views you can reorder it explicitly.

Step 4. Control the Toggle Button's state

The Toggle Button is a bistable component which can assume the state Off or On. This state corresponds to the value stored actually in the property Active. To query the actual state of the button, you simply evaluate this property. In turn, when you assign a value to Active, the button automatically updates its state to correspond to this value. For example:

// Is the button actually 'on'? if ( ToggleButton.Active ) ... [...] // Set the button in the state 'off': ToggleButton.Active = false;

Step 5. Implement Toggle Button's slot method

The Toggle Button is activated when the user after touching the button releases it again while the finger was still within the button's area. If the Toggle Button is controlled by keyboard events, the button is activated when the user has pressed the key Enter. This is the default behavior implemented in the Toggle Button template.

Thereupon, the Toggle Button alternates the state of its bool property Active and sends a signal to the associated slot method. The slot method is connected to the component by simply assigning it to the for this purpose available property OnToggle. You can initialize OnToggle with already existing slot methods or you add a new one and implement it as desired. The following steps describe how to do this:

First add a new slot method to your GUI component.

Assign the slot method to the property OnToggle of the affected Toggle Button.

Open the slot method for editing.

In the Code Editor implement your desired operation to execute when the event occurs. Especially your implementation can evaluate the button's property Active to determine its actual toggle state. For example:

// React only when the button has changed from 'off' to 'on' state: if ( ToggleButton.Active ) ...

When you start the Prototyper now, you can interact with the button. Thereupon the button will trigger the associated slot method.

Step 6. Connect the Toggle Button with a data provider

To simplify the development of GUI applications, the Toggle Button implements a technique permitting you to connect a button directly to a data provider. Once connected, the button will remain in sync with the value stored actually in this provider. Similarly, if the user toggles the button, the associated value changes automatically. This technique corresponds to the model-view-controller (MVC) programming paradigm, where the Toggle Button has the function of the view and controller and the associated data provider serves as model. If you associate in your application several Toggle Buttons to one and the same data provider value, the underlying mechanisms will ensure, that after toggling one button all other affected buttons do update their state automatically.

The connection between the Toggle Button and the data provider is established by assigning to the Toggle Button's property Outlet a reference to a property existing within the data provider and storing the interesting value. Since Toggle Button is a bistable widget (it can assume only the states Off or On), the property suitable to be connected via reference to the button has to be declared with bool as its data type. Accordingly, the value false of the property corresponds to the state Off of the button and the value true to the state On.

Summarized, after assigning a reference to an existing bool property to the Toggle Button's own property Outlet, the button adapts its own state to automatically correspond to the actual value of the associated property. When the user toggles the button, the associated property is modified. You don't need to write a single line of code to benefit from this mechanisms. The aspects underlying this technique are explained in the sections Outlet properties and Notifications and Observer.

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 Toggle Button 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 Toggle Button appears composed of two rectangles surrounded by a border. Our intention is to keep the component templates as minimalistic as possible so they don't distract you with less important design details. The Toggle Button can react to touch, mouse and keyboard inputs. The color and position of the knob rectangle and the border reflect the actual state of the button. When the button is in Off state, the knob rectangle is left aligned and it appears red. When the button is in On state, the rectangle is right aligned and green. When the button is focused, the border appears thick.

This default functionality is implemented by following members belonging to the Toggle Button. These members are explicitly intended to be modified. Understanding this internal structure is thus the first step before you start to adapt the Toggle Button to your particular needs:

Icon

Member

Description

Active

The property Active stores the current state of the toggle button. As long as the property is false, the widget should appear in switched-off state. As soon as the property changes to true, the widget should appear in switched-on state.

OnSetActive

The onset method belongs to the property Active. Each time the value of the property is changed, the code implemented in the method is executed to reflect the new state in button's appearance.

Outlet

The property Outlet can refer to any other bool property the widget should remain synchronized with. When the user toggles the button, the affected property is automatically updated to reflect the button's current state. On the other hand, when the referred property is modified by another one, the button is automatically notified to remain in sync with the property.

This approach follows the model-view-controller (MVC) programming paradigm, where the Toggle Button has the function of the view and controller and the property referred via Outlet serves as model. See also Outlet properties.

OnSetOutlet

The onset method belongs to the property Outlet. Each time a new property reference is assigned to Outlet, the code implemented in the method is executed to register the button as observer for the referred property.

OnToggle

The property OnToggle can refer to a slot method, which will receive a signal as soon as the user has toggled the button. Wherever an instance of the Toggle Button is used, you can assign a slot method to this property. Thereupon the method's logic will be executed. In the associated slot method you can evaluate the current value of the property Active.

onPressTouch

This internal slot method is called when the user touches the button's area. This slot method is connected to the member TouchHandler.

onReleaseTouch

This internal slot method is called when the user releases the touch screen after touching the button's area. This activates the button if the finger was within the button's area. This slot method is connected to the member TouchHandler.

onEnterLeaveTouch

This internal slot method is called when the user drags the finger while pressing the button. This only updates the button to appear pressed or released. This slot method is connected to the member TouchHandler.

KeyHandler

This key handler reacts to key press events. When the user presses the key specified in the property Filter of the key handler, the handler is activated and the method onPressKey is called.

onPressKey

This internal slot method is called when the KeyHandler is activated (when the user has pressed the key specified in the property Filter of the key handler).

FlashTimer

This timer object is used to flash the button when the user has tapped it very quickly or the button has been activated with the keyboard. This is just for the visual feedback effect. The timer is configured to expire after 50 ms. It sends then a signal to the slot method onFlashTimer.

onFlashTimer

This internal slot method is called when the FlashTimer is expired. It ends the short flash feedback effect.

onOutlet

This internal slot method will receive a signal, if the value of the property referred by Outlet has been changed by another widget or by the application logic. In response to this notification, the Toggle Button will update its own Active property to reflect the new value of the referred property.

Background

This Filled Rectangle view displays in the template the background of the button. The background is white per default.

Border

This Border view displays in the template the border of the button. Depending on the button's actual state variables enabled, selected and pressed the border is either black, gray and the thickness of the border changes.

Knob

This Filled Rectangle view represents the switch. Depending on the button's actual state variables enabled, pressed and checked the rectangle is left or right aligned and its color changes between red and green.

TouchHandler

This Simple Touch Handler reacts to touch and mouse events and invokes the associated slot methods: onPressTouch, onReleaseTouch and onEnterLeaveTouch.

UpdateViewState

This method is invoked automatically after the state of the component has been changed. In case of the Toggle Button, the method updates the views Knob and Border so they reflect the button's current state.

enabled

This variable stores the current state of the button. It is true if the button is allowed to handle user inputs (the component is enabled). See also Control the Enabled state of nested components. If the button is actually disabled, the variable is consequently false.

selected

This variable stores the current state of the button. It is true if the button is actually focused for keyboard inputs (more precisely, the button is selected within its owner component). The user can thereupon control the button via keyboard.

pressed

This variable stores the current state of the button. It is true if the button should appear pressed. This is usually the case when the user touches the button actively. We can say, the button is armed during this state.

checked

This variable stores the current state of the button. It is true if the button is actually in the On state and false if it is in the Off state.

Understand the state management of the component

During its lifetime, the Toggle Button will assume different states as direct effect of user interactions, as result of timer triggered animations or simply enforced by other superior state alternations within the GUI application. To track its current state the Toggle Button manages the above mentioned variables: enabled, selected, pressed and checked. The variables are evaluated and updated within the implementation of the method UpdateViewState.

UpdateViewState evaluates then the common component states (Enabled and Selected) and verifies whether the user is actually interacting with the button (TouchHandler) or whether the button is performing an animation (FlashTimer). At the end of the method the estimated states are stored in the above mentioned variables:

// Estimate the new state var bool isEnabled = aState.contains( Core::ViewState[ Enabled ]); var bool isSelected = aState.contains( Core::ViewState[ Selected ]); var bool isPressed = ( TouchHandler.Down && TouchHandler.Inside ) || FlashTimer.Enabled; var bool isChecked = Active; [...] // Remember the new state enabled = isEnabled; selected = isSelected; pressed = isPressed; checked = isChecked;

For example, the local variable isPressed will become true if the user is actually touching within the button's area (the variables Down and Inside of the TouchHandler are both true) or if the button is performing the feedback animation after the user has tapped it very quickly (FlashTimer is enabled). Being in this state, the button should appear pressed.

When common component states (Enabled or Selected) have changed, the method UpdateViewState is invoked automatically. You don't need to worry about it. Any other state alternations need to explicitly request an invocation of the UpdateViewState method. This is especially true for state alternations caused by touch handlers, keyboard handlers or timer objects. When you modify the Toggle Button to handle other user inputs or perform other animations always ensure that each state alternation (each event) does request an invocation of UpdateViewState. In your implementation you use for this purpose the method InvalidateViewState.

For example, the slot method onEnterLeaveTouch is associated to the TouchHandler and it is invoked when after touching the button the user drags the finger out of its area and again into its area. In response to this, the pressed state of the button has to be updated. The method onEnterLeaveTouch requests thus the invocation of UpdateViewState:

// Request the invocation of the UpdateViewState method. InvalidateViewState();

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 Toggle Button or even remove the existing functionality if it is not needed in your case.

For example, the default implementation of the Toggle Button template manages the state selected. This state indicates that the button is actually selected within the superior component. The button could thus receive keyboard events. However, whether the button is really able to receive events does depend on the selection status of its owner component and all other superior components. Only when the button lies on the focus path, the button will receive keyboard events. If your application case requires the button to distinguish this additional state, you do following:

Add new variable to your Toggle Button component.

Rename the variable to e.g. focused.

Configure the data-type of the variable to bool.

In the UpdateViewState method adapt the implementation as follows:

// Estimate the new state var bool isEnabled = aState.contains( Core::ViewState[ Enabled ]); var bool isSelected = aState.contains( Core::ViewState[ Selected ]); var bool isPressed = ( TouchHandler.Down && TouchHandler.Inside ) || FlashTimer.Enabled; var bool isChecked = Active; var bool isFocused = aState.contains( Core::ViewState[ Focused ]); [...] // Remember the new state enabled = isEnabled; selected = isSelected; pressed = isPressed; checked = isChecked; focused = isFocused;

Adapt the appearance of the component

Originally, if not yet modified, the Toggle Button appears composed of two rectangles surrounded by a border. 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 button 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 Toggle Button template contains per default the views Background, Knob and Border. If desired, you can modify the views. For example, you can display them with other colors depending on the actual state of the button. For this purpose you change the implementation of the above explained method UpdateViewState responsible for tracking the state alternations within the Toggle Button.

When you open the method UpdateViewState you will see that it does not only update the state variables but also updates the views existing within the component. Accordingly, depending on the actual state of the button the view Knob is displayed with other colors and the view Border with other line thickness. Furthermore, the position of the view Knob changes according to whether the button is actually Off or On. By simply modifying this implementation you change the appearance. For example, you change the knob color from green to blue when the button is in On position:

if ( !isEnabled ) { Border.Color = #CCCCCCFF; Border.Width = 1; } else if ( isPressed ) { Border.Color = #000000FF; Border.Width = 3; } else if ( isSelected ) { Border.Color = #444444FF; Border.Width = 3; } // Enabled but not pressed nor selected. else { Border.Color = #444444FF; Border.Width = 1; } // Then arrange the knob at the position corresponding to the button's current // state. if ( isPressed ) Knob.Bounds.origin.x = ( Bounds.w - Knob.Bounds.w ) / 2; else if ( isChecked ) Knob.Bounds.origin.x = Bounds.w - Knob.Bounds.w - 10; else Knob.Bounds.origin.x = 10; // Finally set the color of the knob depending on the button's state. if ( isPressed ) Knob.Color = #888888FF; else if ( isEnabled && isChecked ) Knob.Color = #0000CCFF; // <--- blue else if ( isEnabled && !isChecked ) Knob.Color = #FF0000FF; else if ( isChecked ) Knob.Color = #44FF44FF; else Knob.Color = #FF4444FF;

2. Remove existing views

If not needed, you can delete the per default existing views Background, Knob and Border. Doing this, please don't forget to also remove all references to the deleted views from the implementation of the UpdateViewState method. 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. For example, if you decided to delete the Border view, simply remove all corresponding code lines. The remaining implementation looks then like this:

// Arrange the knob at the position corresponding to the button's current state. if ( isPressed ) Knob.Bounds.origin.x = ( Bounds.w - Knob.Bounds.w ) / 2; else if ( isChecked ) Knob.Bounds.origin.x = Bounds.w - Knob.Bounds.w - 10; else Knob.Bounds.origin.x = 10; // Finally set the color of the knob depending on the button's state. if ( isPressed ) Knob.Color = #888888FF; else if ( isEnabled && isChecked ) Knob.Color = #00CC00FF; else if ( isEnabled && !isChecked ) Knob.Color = #FF0000FF; else if ( isChecked ) Knob.Color = #44FF44FF; else Knob.Color = #FF4444FF;

Now you can delete the affected view.

3. Add further views to the component

You can add further views to your Toggle Button. For example, you can add a Text view to display some button caption. Or you add an Image view to display an icon within the button. The appearance of the views (e.g. colors) can be fixed, predetermined at the design time. Or it can change according to the actual state of the button. For example, if the button is pressed, the text size can change or the icon can appear slightly shifted. Following steps explain the workflow:

First add the desired view to the component. For example add a Text view.

Name the just added view according to its function in the component. For example CaptionText.

In order to arrange the view within the Toggle Button, 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.

In Inspector window configure the properties of the just added view. For example, in case of the Text view you can select the font to render the text.

In the UpdateViewState method adapt the implementation to update the properties of the view according to the button's current state. This can be, for example, the color of the Text view depending on the actual enabled state of the button. For this purpose you could add following code to the method:

// Update the appearance of the CaptionText view. if ( !isEnabled ) CaptionText.Color = #CCCCCCFF; // light gray color // Enabled, evtl. selected or pressed. else CaptionText.Color = #000000FF; // black color

4. Replace existing views

Also possible, you can replace the existing views by other views. For example, in the original version, the Toggle Button displays the knob as an ordinary filled rectangle. To make the component more sophisticated, you could replace the here used Filled Rectangle view by e.g. Image view. For this purpose:

Think about which view is adequate as replacement for the old view existing per default in the component. An overview of existing views is found in the section Using Views.

Delete the old view.

Add the desired view to the component.

Name the just added view to have the name of the previously removed view.

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 other methods existing in the component if these evaluate/modify the properties of the replaced view.

Configure the layout of the component

The initial size of the Toggle Button is determined by the thick blue border surrounding the Canvas area. It corresponds to the size that all instances of this Toggle Button component will have by default. If desired, you can adjust the Canvas area and change this default size accordingly. This could be for example the case when you plan to create a large Toggle Button. For this purpose you click and drag the edges of the surrounding border (see also Resize the Canvas area). Once the size is changed, you can then adapt (move, resize) the views existing within the component. For example, to make the Toggle Button higher you adjust its bottom edge:

The resulting size of the Toggle Button, however, is not necessarily fixed. It can be adjusted for each button instance individually when the button instance is arranged within a superior GUI component or it can change dynamically at the runtime. The GUI application can thus contain multiple instances of the button, each with another size. From this arises the question, how the Toggle Button will react to its size alternation?

In case of the views existing per default in the Toggle Button template (Background and Border), the views are automatically adjusted to fill the entire area of the button. The same is true for the TouchHandler, which should usually fill the entire button otherwise the user can't interact with it. All other views, you have added later to the Toggle Button 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 some caption text you have added a Text view to the Toggle Button. Then you have arranged the view within the Canvas area according to your design expectation. If you want now that the view grows and shrinks according to size changes of the Toggle Button, you enable in the property Layout of this view following settings:

Now the Toggle Button knows how to react to its size changes. Each button instance can have individual size and the enclosed views are automatically arranged within the available area:

Implement the interface of the component

When creating your own Toggle Button component you should ensure that instances of the button can be configured to control all the features implemented in it. For example, if you have enhanced the button to display some caption text, you should allow this text to be specified individually for each button instance. In this way several button instances can exist at the same time, each displaying another caption.

To control the features in your button you use properties. A property can be understood as variable where the corresponding setting is stored, e.g. the caption text to display in the button. When the value of the property changes, the button can react to it and update its appearance accordingly. The properties reflect thus the settings within your button. Together they form the interface of the component.

Usually, each particular setting within a component is represented by the corresponding property. Thus, a button where color and icon can be configured will require two properties: one for the color and one for the icon bitmap. In its original version, the Toggle Button contains already three properties Active, Outlet and OnToggle. It allows the button instance to configure its actual state (On or Off) or to exchange data with the button. In order to enhance this interface by your own properties, following steps are necessary:

Add a new property to the Toggle Button 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 store a string.

Determine the initialization value of the property. This value should correspond to the button's default state. For example, the property intended to store the caption text should be initialized with exact the string the button will display if no other text is specified (e.g. "Text").

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 button according to its new value. For example, in case of the property intended to store the caption text, you will probably update some Text view where the caption is displayed:

// The value doesn't change - nothing to do. if ( pure Caption == value ) return; // Remember the property's new value. pure Caption = value; // Update the view to display the just modified caption. CaptionText.String = value;

That is all. Now when you deal with instances of the Toggle Button component, you can evaluate and modify the properties similarly to how you access variables. Especially, when the button 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. The button caption, for example, can be adapted to provide useful information for the user concerning the corresponding operation. For this purpose you access and modify the affected property directly within Chora code:

var string networkName = ... // Let the button display concrete details to the associated operation. ToggleButton.Caption = "Enable SSID: " + networkName;

Understand the handling of touch inputs

The Toggle Button is an interactive component. It can be controlled via touch screen or by the mouse device. For this purpose the template contains the Simple Touch Handler object named TouchHandler. To this handler are associated three slot methods: onPressTouch, onReleaseTouch and onEnterLeaveTouch. As their names imply the methods are invoked at the beginning of the interaction (press), at its end (release) and repeatedly during the interaction if the user drags the finger (mouse pointer) out (leave) and in (enter) the handler's area:

The methods take care of two tasks. At first they request an invocation of the UpdateViewState method if due to the performed touch (mouse) interaction the visual appearance of the button does need the update. The second task is toggling the button's Active state and sending a signal to the slot method associated to button's property OnToggle. This is the case when the user has released the button. As such this task is implemented in the onReleaseTouch method. Following code demonstrates this implementation:

// Did the user moved the finger outside the button's area? In such case // the button is not activated. if ( !TouchHandler.Inside ) return; // The user interaction has been passed over to the another touch handler if ( TouchHandler.AutoDeflected ) return; // The user has pressed and held the button for longer time. This was enough // long to give a visual 'press' feedback to the user. The button can be // activated immediately. if ( TouchHandler.HoldPeriod >= FlashTimer.Begin ) { // Toggle the button's state and notify the owner of the button. Active = !Active; postsignal OnToggle; // If a property is associated to the button, update it accordingly and notify // other widgets also associated to this property. if ( Outlet != null ) { Outlet^ = Active; notifyobservers Outlet; } } // The user has tapped the button very quickly. Defer the button activation // to give the user first a short visual feedback that the button has been // pressed. else FlashTimer.Enabled = true;

Usually you will not need to edit the implementation of the methods. It corresponds already to whatever typical buttons do. Nevertheless, you are free to change this default functionality if you want some particular behavior to be implemented in your button. For example, for safety reasons it can be reasonable to prevent the button from being activated if the user touched it too briefly. In such case add a condition to the implementation of the onReleaseTouch method to evaluate how long the user held the button pressed. If the period is too short, the button is not activated:

// Did the user moved the finger outside the button's area? In such case // the button is not activated. if ( !TouchHandler.Inside ) return; // The user interaction has been passed over to the another touch handler if ( TouchHandler.AutoDeflected ) return; // The user has to touch the button for at least 250 ms. if ( TouchHandler.HoldPeriod < 250 ) return; // Toggle the button's state and notify the owner of the button. Active = !Active; postsignal OnToggle; // If a property is associated to the button, update it accordingly and notify // other widgets also associated to this property. if ( Outlet != null ) { Outlet^ = Active; notifyobservers Outlet; }

Per default the TouchHandler is configured to handle all touch events. If necessary you can change this behavior and restrict the button to react only when the user performs a particular touch interaction. The TouchHandler provides for this purpose diverse configuration properties like MinStrikeCount, MaxStrikeCount, NoOfFingers or LimitToFinger. For example, if you want the button to react only when the user has touched it simultaneously with two fingers, set the handler's property NoOfFingers to the value 2. For more details, see Configure the filter condition.

If your device does not contain any touch screen nor mouse, the per default existing TouchHandler and its associated slot methods are unnecessary ballast. You can remove them in such case. We recommend to do this in following order to avoid eventual error message because of broken references between still existing and the already removed members:

First edit the UpdateViewState method and remove all expressions evaluating TouchHandler.

Edit the onPressKey method and remove the if condition evaluating the state of the TouchHandler.

Using the Inspector window delete the TouchHandler object.

Delete the three slot methods: onPressTouch, onReleaseTouch and onEnterLeaveTouch.

Finally delete the annotation grouping the slot methods.

Understand the handling of keyboard inputs

The Toggle Button is an interactive component. It can be controlled via keyboard or hardware buttons. For this purpose the template contains the Key Press Handler object named KeyHandler. To this handler is associated the slot method: onPressKey. This method is invoked when the user presses a key matching the filter condition specified in the KeyHandler object. This is per default the key Enter:

This method takes care of two tasks. At first it requests an invocation of the UpdateViewState method if due to the performed interaction the visual appearance of the button does need the update. The second task is starting the FlashTimer. This timer determines a delay to flash briefly the button. If the user presses the key very quickly (faster than the delay specified in the timer), the default implementation of the method toggles the button's Active state and sends a signal to the slot method associated to button's property OnToggle. Following code demonstrates this implementation:

// Ignore keyboard events when the user is interacting with the button via the // touch screen. if ( TouchHandler.Down ) return; // Ignore repetitions of key events (e.g. when the user holds the key pressed) if ( KeyHandler.Repetition ) return; // Pressing the key flashes the button for a short period. This is a kind of // feedback effect. Request the button to update its appearance accordingly. // The update will occur in the UpdateViewState() method. InvalidateViewState(); // The button is still performing the feedback flash effect from the preceding // tap/key event. This can occur when the user taps the button or presses the // key in a very rapid succession. Thus complete this preceding tap (simulate // the timer expiration) before starting a new button interaction. if ( FlashTimer.Enabled ) { FlashTimer.Enabled = false; // Toggle the button's state and notify the owner of the button. Active = !Active; postsignal OnToggle; // If a property is associated to the button, update it accordingly and notify // other widgets also associated to this property. if ( Outlet != null ) { Outlet^ = Active; notifyobservers Outlet; } } // Start the feedback flash effect. FlashTimer.Enabled = true;

Usually you will not need to edit the implementation of this method. It corresponds already to whatever typical buttons do. Nevertheless, you are free to change this default functionality if you want some particular behavior to be implemented in your button. For example, the actual implementation toggles the button just in the moment when the user presses the key. Instead, if you want the button to be toggled when the user releases the key, following adaptations would be adequate:

Add a new slot method to the Toggle Button component.

Name the slot method to onReleaseKey.

Assign the slot method to the property OnRelease of the KeyHandler object.

Implement the slot method onReleaseKey with following code:

// Ignore keyboard events when the user is interacting with the button via the // touch screen. if ( TouchHandler.Down ) return; // Releasing the key should de-highlight the button. Request the button to update // its appearance accordingly. The update will occur in the UpdateViewState() // method. InvalidateViewState(); // The user has pressed and held the key for longer time. This was enough // long to give a visual 'press' feedback to the user. The button can be // toggled immediately. if ( KeyHandler.RepetitionCount > 1 ) { // Toggle the button's state and notify the owner of the button. Active = !Active; postsignal OnToggle; // If a property is associated to the button, update it accordingly and notify // other widgets also associated to this property. if ( Outlet != null ) { Outlet^ = Active; notifyobservers Outlet; } } // The user has tapped the key very quickly. Defer the button activation // to give the user first a short visual feedback that the button has been // pressed. else FlashTimer.Enabled = true;

Now replace the original implementation of the onPressKey slot method with following code:

// Ignore repetitions of key events (e.g. when the user holds the key pressed) if ( KeyHandler.Repetition ) return; // Pressing the key should highlight the button. Request the button to update // its appearance accordingly. The update will occur in the UpdateViewState() // method. InvalidateViewState();

Finally adapt the implementation of the UpdateViewState method to initialize the pressed state depending on whether the user actually holds down the key (KeyHandler.Down is true):

[...] var bool isPressed = ( TouchHandler.Down && TouchHandler.Inside ) || FlashTimer.Enabled || KeyHandler.Down; [...]

With the above modifications you changed the behavior of the button to not be toggled with the key press event anymore. Instead the button is activated when the user releases the key again. Additionally, the button appears pressed as long as the user holds down the associated key. Per default the KeyHandler is configured to accept the key Enter. If necessary you can change also this behavior and adapt the button to react to other key or key groups. The KeyHandler provides for this purpose the configuration property Filter. For example, if you want the button to react when the user has pressed the Space key, set the property Filter to the value Core::KeyCode.Space. For more details, see Configure the filter condition.

If your device does not contain any keyboard nor hardware buttons, the per default existing KeyHandler and its associated slot method are unnecessary ballast. You can remove them in such case. We recommend to do this in following order to avoid eventual error messages because of broken references between still existing and the already removed members:

First delete the KeyHandler object.

Then delete the slot method: onPressKey.

Finally delete the annotation grouping the handler and the slot method.

Understand the Outlet updates

The Toggle Button can be connected via its property Outlet with any other bool property the widget should remain synchronized with. When the user toggles the button, the affected property is automatically updated to reflect the button's current state. On the other hand, when the referred property is modified by another one, the button is automatically notified to remain in sync with the property. This approach follows the model-view-controller (MVC) programming paradigm, where the Toggle Button has the function of the view and controller and the property referred via Outlet serves as model. See also Outlet properties.

When the state of the button changes due to a user interaction, the button updates the value of the referred property. This is, for example, the case in the slot method onReleaseTouch. The implementation found there simply assigns the actual state of the Toggle Button's Active property to the property referred via Outlet and broadcasts a notification to all other widgets connected to the same property so they also can update their state accordingly:

// If a property is associated to the button, update it accordingly and notify // other widgets also associated to this property. if ( Outlet != null ) { Outlet^ = Active; notifyobservers Outlet; }

In order to react to alternations of the referred property (to receive notifications broadcasted by other widgets connected with the same property), the Toggle Button implements the method onOutlet. Each time the referred property is notified, this slot method is automatically invoked and following code is executed:

// Read the current value of the associated property and update accordingly // the state of the toggle button. if ( Outlet != null ) Active = Outlet^;

In order to be invoked, the method onOutlet needs to be registered with the referred property as so-called observer. The corresponding code is implemented in the onset method OnSetOutlet. Thus, just in the moment when a property reference is assigned to the Toggle Button's Outlet property, following code is executed:

// Check if the new outlet differs from the currently used outlet if ( pure Outlet == value ) return; // Detach from the previous outlet if ( pure Outlet != null ) detachobserver onOutlet, pure Outlet; // Store the new outlet ... pure Outlet = value; // ... and attach to the new one if ( value != null ) attachobserver onOutlet, value; // Finally, retrieve the current state of the property associated via 'Outlet'. if ( value != null ) postsignal onOutlet;

Adapt the feedback (flash) animation

When the user touches the button or presses the associated key, the button changes its visual appearance to provide to the user a kind of feedback that the user successfully hit it. If the user taps the button very quickly, however, the time elapsed between the press and release events is possibly too short to highlight the button sufficiently and so provide the desired feedback. In such case the implementation responsible for handling touch and keyboard events triggers the 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 button. The button should not appear pressed anymore. The second task is to toggle the button's Active state and send a signal to the slot method associated to button's property OnToggle. Following code demonstrates this implementation:

// The feedback flash timer is finished. Request the button to update its // appearance. The update will occur in the UpdateViewState() method. InvalidateViewState(); // With the end of the feedback flash effect the button is activated. // Toggle the button's state and notify the owner of the button. Active = !Active; postsignal OnToggle; // If a property is associated to the button, update it accordingly and notify // other widgets also associated to this property. if ( Outlet != null ) { Outlet^ = Active; notifyobservers Outlet; }

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.

Perform state changes with animations

In the section Adapt the appearance of the component you learned how state alternations within the Toggle Button are processed and how views existing in the component are updated in order to reflect the actual state. Accordingly, when the user touches the button, the button does appear pressed. When the user releases the button again, the button restores its released appearance. The default implementation performs such appearance updates instantly, just in the moment when the respective interaction took place.

If desired, you can modify the Toggle Button to update its appearance with animations. For example, instead of instantly switching between the pressed and released appearance, such button can fade-in/out the views, modulate their colors or move the views within the component. For this purpose you use the Animation Effects. With an Animation Effect you can animate a property of a view existing in the button. 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 Toggle Button. For example, to animate a rect property, add a Move and resize rect effect.

Connect the effect object with the property to animate. For example, if you want to animate the position of the Knob view, connect the Move and resize rect effect with the property Bounds of the Knob view.

Configure the duration and eventually the desired timing (easing) for the animation.

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 move and resize rect effect, it is the start and the end position/size of the animated view. This step is appropriate if the key values are fixed, known at the design time. Otherwise, the key values must be calculated and set at runtime shortly before the effect is triggered.

Open the method UpdateViewState and modify its implementation to trigger the effect object when the button switches between the states pressed and released. For example in case of the above mentioned move and resize rect effect to animate the position of the Knob view, following implementation could be adequate:

// Determine the new state of the toggle button. var bool isEnabled = aState.contains( Core::ViewState[ Enabled ]); var bool isSelected = aState.contains( Core::ViewState[ Selected ]); var bool isPressed = ( TouchHandler.Down && TouchHandler.Inside ) || FlashTimer.Enabled; var bool isChecked = Active; // First evaluate the common state so the button if ( !isEnabled ) { Border.Color = #CCCCCCFF; Border.Width = 1; } else if ( isPressed ) { Border.Color = #000000FF; Border.Width = 3; } else if ( isSelected ) { Border.Color = #444444FF; Border.Width = 3; } // Enabled but not pressed nor selected. else { Border.Color = #444444FF; Border.Width = 1; } // If the user has pressed or released the button -> start an animation to // slide the 'Knob' view. if ( pressed != isPressed ) { var rect value1 = Knob.Bounds; var rect value2 = Knob.Bounds; // Depending on the actual On/Off state of the toggle, estimate the position // of the Knob view. This is the first 'key' value for the animation. if ( isChecked ) value1.origin.x = Bounds.w - value1.w - 10; else value1.origin.x = 10; // The second 'key' value specifies the position in center of the component. value2.origin.x = ( Bounds.w - value2.w ) / 2; RectEffect.Value1 = value1; RectEffect.Value2 = value2; // Start the animation effect. Note, the direction of the effect changes when // the user releases the button again. RectEffect.Reversed = !isPressed; RectEffect.Enabled = true; } // Finally set the color of the knob depending on the button's state. if ( isPressed ) Knob.Color = #888888FF; else if ( isEnabled && isChecked ) Knob.Color = #00CC00FF; else if ( isEnabled && !isChecked ) Knob.Color = #FF0000FF; else if ( isChecked ) Knob.Color = #44FF44FF; else Knob.Color = #FF4444FF; // Remember the current state. enabled = isEnabled; selected = isSelected; pressed = isPressed; checked = isChecked;