Creating components from templates: Vertical Value Bar

With this template you can add a new Vertical Value Bar component to your project. Value bar is a kind of virtual instrument intended to display values (e.g. voltage, speed, sound volume, etc.) as a track with size corresponding to the value. The widget is not suitable to be controlled by the user interactively. If you are looking for such interactive component, please see Vertical Slider.

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

Component templates versus ready-to-use widgets

Besides the here described Vertical Value Bar component template, Embedded Wizard provides also a ready to use Vertical Value Bar 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 Vertical Value Bar 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 Vertical Value Bar component

To create a new Vertical Value Bar 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 Vertical Value Bar component from a template:

First switch to the Composer page for the respective unit, where you want to add the new Vertical Value Bar component.

Then ensure that the Templates window is visible.

In Templates window switch to the folder Component Templates.

In the folder locate the Vertical Value Bar template.

Drag & Drop the template into the Composer window:

Eventually name the new added component.

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

Use the Vertical Value Bar component

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

The following are the typical steps to create a new instance of an already existing Vertical Value Bar component:

First switch to the Composer page for the respective GUI component, where you want to add the new Vertical Value Bar.

Then ensure that the Browser window is visible.

Within the Browser locate the class of the previously created Vertical Value Bar. 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. MicrophoneVolume).

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 Vertical Value Bar appears composed of two rectangles. When the displayed value changes, the height of the inner rectangle is adapted accordingly. 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 Value Bar instance

As long as the Vertical Value Bar 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 Vertical Value Bar 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 Vertical Value Bar 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 Vertical Value Bar are only few following properties:

Property

Description

CurrentValue

The property CurrentValue stores the momentary value of the value bar. This value corresponds to the height of the track (bar) and it is limited automatically to the range specified by the properties MinValue and MaxValue.

MaxValue

The property MaxValue defines the maximum value for the value bar's property CurrentValue. This corresponds to the maximum height of the track (bar).

MinValue

The property MinValue defines the minimum value for the value bar's property CurrentValue. This corresponds to the minimum height of the track (bar).

Outlet

The property Outlet can refer to any other int32 property the value bar should remain synchronized with. When the referred property is modified by other widget or by the application logic, the Vertical Value Bar is automatically notified to remain in sync with the property.

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

Step 3. Arrange the Value Bar within the superior component

Once added to the component, you can freely move the Vertical Value Bar 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 Vertical Value Bar to appear behind other views you can reorder it explicitly.

Step 4. Determine the Vertical Value Bar's value range and its current value

The Vertical Value Bar is intended to display an integer value as a vertical track. The height of this track corresponds to the widget's property CurrentValue. By evaluating this property you can simply query the value which is actually displayed in the affected widget. Accordingly, when you modify the property CurrentValue, the affected value bar will implicitly update the height of its track. For example:

// Evaluate the current value of the widget. if ( ValueBar.CurrentValue > 80 ) ... [...] // Change the value of the widget. ValueBar.CurrentValue = 50;

The possible value range for the property CurrentValue is determined by the both properties MinValue and MaxValue, whereby the value specified in the property MinValue corresponds to the minimum height of the displayed track and the value of the property MaxValue to its maximum height. Thus, the value of the property CurrentValue lies always between MinValue and MaxValue. The following figure demonstrates the relations between the three properties:

Step 5. Connect the Value Bar with a data provider

To simplify the development of GUI applications, the Vertical Value Bar implements a technique permitting you to connect it directly to a data provider. Once connected, the widget will remain in sync with the value stored actually in this provider. This technique corresponds to the model-view-controller (MVC) programming paradigm, where the value bar has the function of the view and the associated data provider serves as model. If you associate in your application several value bars and other widgets to one and the same data provider value, the underlying mechanisms will ensure, that after interacting with one widget all other affected Vertical Value Bars do update their state automatically.

The connection between the Vertical Value Bar and the data provider is established by assigning to the value bar's property Outlet a reference to a property existing within the data provider and storing the interesting value. Since Vertical Value Bar is intended to deal with integer values, the property suitable to be connected via reference to the value bar has to be declared with int32 as its data type. Accordingly, the value of the referenced property corresponds to the Vertical Value Bar's current value.

Summarized, after assigning a reference to an existing int32 property to the Vertical Value Bar's own property Outlet, the widget adapts its own state to automatically correspond to the actual value of the associated property. 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 Vertical Value Bar 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 Vertical Value Bar appears composed of two rectangles. The inner red rectangle represents the track (bar) and the white rectangle behind it fills the background of the component. Our intention is to keep the component templates as minimalistic as possible so they don't distract you with less important design details. Especially the height of the inner rectangle (track) corresponds to widget's CurrentValue property.

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

Icon

Member

Description

CurrentValue

The property CurrentValue stores the momentary value of the value bar. This value corresponds to the height of the track and it is limited automatically to the range specified by the properties MinValue and MaxValue.

MinValue

The property MinValue defines the minimum value for the value bar's property CurrentValue. This corresponds to the minimum height of the track.

MaxValue

The property MaxValue defines the maximum value for the value bar's property CurrentValue. This corresponds to the maximum height of the track.

OnSetCurrentValue

The onset method belongs to the property CurrentValue. Each time the value of the property is changed, the code implemented in the method is executed to update the height of the track.

OnGetCurrentValue

The onget method belongs to the property CurrentValue. Each time the value of the property is evaluated within an expression, the code implemented in the method is executed to ensure that the returned value lies within the range specified in the properties MinValue and MaxValue.

OnSetMinValue

The onset method belongs to the property MinValue. Each time the value of the property is changed, the code implemented in the method is executed to update the height of the track.

OnSetMaxValue

The onset method belongs to the property MaxValue. Each time the value of the property is changed, the code implemented in the method is executed to update the height of the track.

Outlet

The property Outlet can refer to any other int32 property the widget should remain synchronized with. When the referred property is modified by other widget or the application logic, the Vertical Value Bar is automatically notified to remain in sync with the property.

This approach follows the model-view-controller (MVC) programming paradigm, where the value bar has the function of the view 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 Vertical Value Bar as observer for the referred property.

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 Vertical Value Bar will update its own CurrentValue property to reflect the new value of the referred property.

Background

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

Track

This Filled Rectangle view represents the track (bar). The height of the rectangle corresponds to the value of the property CurrentValue within the range determined by the properties MinValue and MaxValue.

UpdateViewState

This method is invoked automatically after the state of the component has been changed. In case of the Vertical Value Bar, the method updates the view Track so it reflects the widget's current state.

pos

This variable stores the current position of bar's upper edge.

Understand the state management of the component

During its lifetime, the Vertical Value Bar will assume different states. To track its current state the value bar implements the method UpdateViewState. The following code snippet demonstrates the corresponding operations:

// Get the min/max positions for the upper edge of the value bar. var int32 minPos = 6; var int32 maxPos = Bounds.h - 6; var int32 oldPos = Track.Bounds.y1; var int32 newPos = minPos; // Convert the widget's current value to a pixel position within the // allowed range. if ( MaxValue != MinValue ) newPos = ((( -CurrentValue + MaxValue ) * ( maxPos - minPos )) / ( MaxValue - MinValue )) + minPos;

In case of the value bar, the method UpdateViewState limits to calculate the height of the Track view. Precisely, it calculates the position of this view's upper edge and stores it in the local variable newPos This position correlates directly with the value of the property CurrentValue and the range specified by the properties MinValue and MaxValue. If CurrentValue is equal MinValue, the edge is aligned at the bottommost position. If CurrentValue is equal MaxValue, the edge is topmost aligned. All other intermediate values result in the position being interpolated linearly within this range of motion.

In this default implementation, the position can move along the entire value bar's height except 6 pixel large margins on its top and bottom edges. You can modify this default implementation and, for example, calculate with other margins. Let's assume you want to enlarge the margins to 10 pixel. In such case, you would need to make following modifications in the value bar component:

In the method UpdateViewState change the initialization of the local variable minPos and maxPos according to the desired range:

var int32 minPos = 10; var int32 maxPos = Bounds.h - 10;

Since the position of the bottom edge of the Track view is static (it is not affected by the UpdateViewState method) you may eventually need to move this bottom edge manually to be 10 pixel far away from the bottom edge of the component itself so the Track appears symmetric.

If desired, you are free to add further state variables to your Vertical Value Bar or even remove the existing functionality if it is not needed in your case. Let's assume, the value bar should manage an overload state. The state would become true if CurrentValue exceeds a predetermined threshold value (e.g. 90% of the possible value range). If your application case requires the value bar to distinguish this additional state, you do following:

Add new variable to your Vertical Value Bar component.

Rename the variable to reflect the corresponding state, e.g. overload.

Configure the data-type of the variable to bool.

In the UpdateViewState method adapt the implementation as follows:

// Get the min/max positions for the upper edge of the value bar. var int32 minPos = 6; var int32 maxPos = Bounds.h - 6; var int32 oldPos = Track.Bounds.y1; var int32 newPos = minPos; var bool isOverload = false; // Convert the widget's current value to a pixel position within the allowed range. // Also estimate the 'overload' state. if ( MaxValue != MinValue ) { newPos = ((( -CurrentValue + MaxValue ) * ( maxPos - minPos )) / ( MaxValue - MinValue )) + minPos; // Estimate the new value for the state 'overload'. Here, the state is 'true' if // CurrentValue is greater than or equal to 90% of the possible value range: isOverload = ((( CurrentValue - MinValue ) * 10 ) / ( MaxValue - MinValue )) >= 9; } [...] // Remember the new state. The variable 'overload' stores thus the latest state. overload = isOverload;

If you decide to enhance the value bar by further states, please note that you will eventually need to explicitly request an invocation of the UpdateViewState method in order to update the component as effect of the state alternation. This is especially the case when the state alternation is triggered by some timer or any other external event. In your implementation you use for this purpose the method InvalidateViewState. How this work can be seen in the property CurrentValue. When new value is assigned to this property, its associated onset method OnSetCurrentValue is invoked. This method requests thus the invocation of UpdateViewState:

// Store the new value ... pure CurrentValue = value; // ... and finally, force an update. InvalidateViewState();

Thereupon the UpdateViewState method can handle the alternation of CurrentValue and update the height of the Track view accordingly or the state of the above introduces variable overload.

Adapt the appearance of the component

Originally, if not yet modified, the Vertical Value Bar appears composed of two rectangles. The inner red rectangle represents the track (bar) and the white rectangle behind it fills the background of the component. The height of the inner rectangle (track) corresponds to widget's CurrentValue property. 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 widget 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 Vertical Value Bar template contains per default the views Background and Track. If desired, you can modify the views. For example, you can display them with other colors depending on the actual state of the widget. For this purpose you change the implementation of the above explained method UpdateViewState responsible for tracking the state alternations within the value bar.

When you open the method UpdateViewState you will see that it does not only calculate the value for the local variable newPos but also updates the views existing within the component. Accordingly, depending on the actual state of the value bar the height of the view Track is adapted to correspond to the just calculated newPos value:

[...] // If the just calculated position does differ from the actual (old) // position, adjust the size and evtl. the position of your views. if ( newPos != oldPos ) Track.Bounds.y1 = newPos;

If desired, you can enhance this implementation and, for example, colorize the track depending on its actual height. The track could then change between green and red colors if it is wider than 50% available space. For this purpose you add following code to the method UpdateViewState:

// Colorize the track according to its actual height. If the height // of the track exceeds 50% possible height, the track appears red. if ( newPos < ( Bounds.h / 2 )) Track.Color = #FF0000FF; // <-- red color else Track.Color = #00FF00FF; // <-- green color

Also possible: the above section explained how to enhance the component by new states (e.g. overload). If you have followed these steps, you can evaluate now this new state and depending on it colorize the Track view. The track will then appear red if the overload state is true:

// Colorize the track according to widget's actual 'overload' state: if ( isOverload ) Track.Color = #FF0000FF; // <-- red color else Track.Color = #00FF00FF; // <-- green color

2. Remove existing views

If not needed, you can delete the per default existing views Background and Track. 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 verify the implementation to not refer anymore to the undesired view.

Now you can delete the affected view.

3. Add further views to the component

You can add further views to your Vertical Value Bar. For example, you can add a Text view to display some caption. Or you add an Image view to display an icon within the widget. 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 value bar. For example, the text color can change according to the value displayed in the value bar. 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 Vertical Value Bar, 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 widget's current state. This can be, for example, the color of the Text view depending on the actual state of the widget. For this purpose you could add following code to the method:

// If the bar is greater than 50%? if ( newPos < ( Bounds.h / 2 )) CaptionText.Color = #FF0000FF; // red color else CaptionText.Color = #00FF00FF; // green color

Also possible: the above section explained how to enhance the component by new states (e.g. overload). If you have followed these steps, you can evaluate now this new state and depending on it colorize the text view. The text will then appear red if the overload state is true:

// Colorize the text according to widget's actual 'overload' state: if ( isOverload ) CaptionText.Color = #FF0000FF; // <-- red color else CaptionText.Color = #00FF00FF; // <-- green color

4. Replace existing views

Also possible, you can replace the existing views by other views. For example, in the original version, the Vertical Value Bar displays the track as an ordinary filled rectangle. To make the component more sophisticated, you could replace the here used Filled Rectangle view by e.g. Bitmap Frame 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 Vertical Value Bar is determined by the thick blue border surrounding the Canvas area. It corresponds to the size that all instances of this value bar 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 Vertical Value Bar. 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 value bar wider you adjust its right edge:

The resulting size of the Vertical Value Bar, however, is not necessarily fixed. It can be adjusted for each component instance individually when the 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 value bar, each with another size. From this arises the question, how the Vertical Value Bar will react to its size alternation?

In case of the views existing per default in the value bar template (e.g. Background), the views are automatically adjusted to fill the area of the widget. All other views you have eventually added later to the value bar 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 value bar. 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 value bar, you enable in the property Layout of this view following settings:

Now the Vertical Value Bar knows how to react to its size changes. Each widget 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 Vertical Value Bar component you should ensure that instances of the widget can be configured to control all the features implemented in it. For example, if you have enhanced the component to display some caption text, you should allow this text to be specified individually for each instance. In this way several value bar instances can exist at the same time, each displaying another caption.

To control the features in your component 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 Vertical Value Bar. When the value of the property changes, the component can react to it and update its appearance accordingly. The properties reflect thus the settings within your widget. Together they form the interface of the component.

Usually, each particular setting within a component is represented by the corresponding property. Thus, a value bar 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 Vertical Value Bar contains already four properties CurrentValue, MinValue, MaxValue and Outlet. It allows the component instance to configure its actual state (the value and the value range) or to exchange data with the component. In order to enhance this interface by your own properties, following steps are necessary:

Add a new property to the Vertical Value Bar 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 widget's default state. For example, the property intended to store the caption text should be initialized with exact the string the widget 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 Vertical Value Bar 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 Vertical Value Bar component, you can evaluate and modify the properties similarly to how you access variables. Especially, when an 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 caption, for example, can be adapted to provide useful information for the user concerning the displayed value. For this purpose you access and modify the affected property directly within Chora code:

var string engineName = ... // Let the Value Bar display concrete details to the associated value. ValueBar.Caption = "Engine: " + engineName;

Understand the Outlet updates

The Vertical Value Bar can be connected via its property Outlet with any other int32 property the widget should remain synchronized with. When the referred property is modified by other widgets or by the application logic, the component is automatically notified to remain in sync with the property. This approach follows the model-view-controller (MVC) programming paradigm, where the value bar has the function of the view and the property referred via Outlet serves as model. See also Outlet properties.

In order to react to alternations of the referred property (to receive notifications broadcasted by other widgets connected with the same property), the Vertical Value Bar 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 value bar. if ( Outlet != null ) CurrentValue = 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 value bar'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;

Perform state changes with animations

In the section Adapt the appearance of the component you learned how state alternations within the Vertical Value Bar are processed and how views existing in the component are updated in order to reflect the actual state. As example, when the property CurrentValue changes, the height of the track is updated (precisely its upper edge is moved).

The default implementation performs such appearance updates instantly, just in the moment when the respective alternation took place. If desired, you can modify the Vertical Value Bar to update its appearance with animations. Such value bar can fade-in/out the views, modulate their colors, move the views within the component or resize the track smoothly. For this purpose you use the Animation Effects. With an Animation Effect you can animate a property of a view existing in the component.

The above section explained how to enhance the component by new states (e.g. overload). If you have followed these steps, you can evaluate now this new state and depending on it colorize the Track view. The track will then appear red if the overload state is true and green when it is false. If you want this color transition to be performed with an animation, following are the necessary steps:

Depending on the data type of the property to animate, add the appropriate Animation Effect to the value bar. For example, to animate a color property, 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 Track view, connect the Pulse color effect with the property Color of the Track 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 pulse color effect, it is the start and the end color. For example, to animate the color between green and red, configure the effect's property Value1 with the #00FF00FF (green) and the property Value2 with #FF0000FF (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 the component switches between the states overload and not overload. For example in case of the above mentioned pulse color effect to animate the color of the Track, following implementation could be adequate:

[...] var int32 newPos = ...; var bool isOverload = ...; [...] // Switching from not overload -> overload state. Start the animation. if ( isOverload && !overload ) { ColorEffect.Reversed = false; ColorEffect.Enabled = true; } // Switching from overload -> not overload state. Start the animation. else if ( !isOverload && overload ) { ColorEffect.Reversed = true; ColorEffect.Enabled = true; } [...] // Remember the new state overload = isOverload;

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 widget. For example, you might need to set the property Color of the view Track to the value #00FF00FF (default color is green).

If desired, you can also animate the height of the track, so it slides smoothly when the CurrentValue property changes. Usually you connect the effect object with the property to animate. In case of the here described track animation, there is no property permitting an exclusive modification of the height. Instead the size and position of the Track view has to specified at once in its property Bounds when the height changes. The simplest way to deal with this application case is the implementation of some glue code between the effect object and the Bounds property. The following are the steps how to do this:

Add a Change int32 effect. This is because the height of the track is expressed as an integer value.

Add a new slot method to the component.

Assign the just added slot method to effect object's property OnAnimate. The effect will thereupon trigger the method while it is performing the animation.

Implement the slot method with following code:

// Move the upper edge of the Track view according to the actual progress // of the animation effect. Track.Bounds.y1 = Int32Effect.Value;

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

Once started, the effect will run 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.

Open the method UpdateViewState and remove the following code section to not affect the Track instantly. The height of the view is controlled now by the animation effect implemented in a slot method explained above:

// REMOVE FOLLOWING CODE from the method UpdateViewState() if ( newPos != oldPos ) Track.Bounds.y1 = newPos;

So far the animation effect object is prepared. As next we have to take care of starting the animation. For this purpose it is necessary to compare the latest stored position of the track with a new calculated position. Following steps are necessary:

Add following code to the method UpdateViewState to trigger the effect object when the component switches the states. For example in case of the change int32 effect to animate the height of the Track, following implementation should be added to the method in the place of the above removed code section:

[...] // If the position of the track's bottom edge changes, start the effect to // smoothly resize the track to the new position. if ( newPos != pos ) { Int32Effect.Enabled = false; Int32Effect.Value1 = Int32Effect.Value; // <-- the latest position Int32Effect.Value2 = newPos; Int32Effect.Enabled = true; } [...]