Working with Embedded Wizard: Creating non visual components

The preceding chapters were focused so far on the development of GUI components. These visual components are intended to display some contents on the screen and to process user interactions. In the classical Model-View-Controller (MVC) software architecture pattern, the visual components assume the role of the View.

In a typical GUI application, however, you will also find many other, non visual components. These remain the whole time in the background and take care of the data management, controlling and communication with the software and hardware of your device. Considering again the Model-View-Controller software architecture pattern, the non visual components take over the tasks of the Model and Controller.

From technical point of view, non visual components are ordinary classes you edit in the Composer window exactly as you have learned to edit the visual GUI components. The only difference is that non visual components don't descend from the Mosaic class Core::Group. Accordingly, when you edit a non visual component, the Composer doesn't present the Canvas area.

Create a new non visual component

The simplest approach to create a new non visual component is to add a new empty class to your project. How to do this is described in Add a new empty class. Please note, that with this approach you add a new class to your project, which is not derived from any other class. You see this in the type area of the brick. It displays simply class instead of the name of the ancestor class:

After creating the new class you should rename it according to its intended function. Let's assume, you want the new class to serve as storage for information about a single playlist entry, then you could name it PlayListRecord.

Edit the non visual component

In order to edit the non visual component you have to open the component class. Thereupon the content of the component in revealed in a new Composer page. Now you can add data members like variables, properties and arrays to it as well as implement methods and slot methods. If necessary you can also embed inside the new component instances of any other non visual component creating in this manner more complex nested components.

The following example project demonstrates the implementation of two non visual components. The first (PlayListRecord) is intended to store information about a single playlist entry, e.g. the song title and the song duration. In analogy to programming language C, this component can be considered as a data structure. The second component (PlayListDatabase), in turn, implements an interface to an imaginary playlist data base. Through this interface the number of available songs as well as information about the individual songs can be queried.

DOWNLOAD EXAMPLE

Please note, the example presents eventually features available as of version 8.10

Use the non visual components

Non visual components are used in the same way as you do with the visual components. In particular you can embed instances of the non visual component class into another component (being visual or non visual). Or you create instances of the component class dynamically by using the operator new:

// Create a new instance of the non visual 'PlayListDatabase' class and assign
// it to the property 'Database' of the 'PlayListView'
PlayListView.Database = new Application::PlayListDatabase;

If the non visual component is intended to be accessed and used globally, e.g. as the interface to your device hardware, you can create an autoobject from the component class. The autoobject represents then a global instance of your component you can access from everywhere within your project. For example, instead of creating the Application::PlayListDatabase instance dynamically with the new operator, you can add to your project an autoobject and use it:

// Assign to the property 'Database' of the 'PlayListView' the given
// autoobject.
PlayListView.Database = Application::PlayListDatabaseAutoobject;

/*

Later at another location in your project ...

*/

// Assign the autoobject also to 'OtherView'.
OtherView.Database = Application::PlayListDatabaseAutoobject;

The advantage of autoobjects is that the Embedded Wizard manages the objects automatically. If the object is accessed from different locations in your project, all locations use one and the same instance of the component. On the other hand, if the autoobject is not used anymore, Embedded Wizard releases the memory occupied by the object automatically.

Subclass existing class

In Embedded Wizard one class can descend from another one and so inherit its implementation. In the derived class the inherited implementation can be overridden and new functionality can be added. Since a non visual component is also a class, you can derive it simply from an already existing one instead of creating each component from scratch.

How a new component is derived from another existing one is described in Subclass an existing class. The original component and the components derived from it build an inheritance tree you can see in the Browser window:

Please note, when you open a class derived originally from another one, all inherited members represented usually by bricks are not displayed unless you override them. This special behavior is explained in Composer and inherited members.

Edit 'this' class properties

While you edit a class, you see in Inspector window a pseudo member named this. When you select this member, the Inspector will reveal all properties belonging to this actually edited class. For example:

In this manner you can conveniently evaluate or modify the properties. By modifying the properties you determine the default values valid for all instances of the class and other classes derived from it. Let's assume, you have developed a class to maintain a record from a song play list. Now, you want all instances of this class to have the property AutoPlayback being set true. In such case, change the property AutoPlayback of the selected this member to the value true. Later, when you create an instance of the affected class, the instance will have this initialization value unless you explicitly change it.