Support:Howto:Application Binding

Intro

Assumed knowledge

  • C++
  • General Handling of Visual Studio
  • Basic Handling of GSE

Prerequisites

  • Any Installed SDK: Desktop or EvalKit based
  • Installed CMake Version 3.0 or higher
  • IDE matching the used SDK

Guiliani Event Flow

Guiliani Event Flow

The most common way the Guiliani Event flow is triggered is a user interaction, like a touch on the display. The Guiliani Input device will be triggered or will poll a device driver and generate a GUIEvent which will then processed by the Event handler. That will forward it to affected controls. If the control shall interact with other controls or the application, it will queue a command or interacts with the Datapool. Both methods are described later. The control draws itself after that by calling the Graphics Wrapper which will handle the platform independent graphics library. The customer application can also queue commands or set values to the Datapool.

Datapool

The Datapool can be understood as a kind of database, which is easy-to-use. Controls can observe from or set values to the data pool. The application can set to or get from values using the Datapool asynchronously. The Datapool can be used for fast changing values, due to the low execution time and low latency.

Commands

Commands will be executed in the event loop. They’re queued until executed. Guiliani defines several standard commands and can be used with GSE by default:

Command Name Description
CMD_DIALOG_TRANSITION Changes to another dialog using an animated transition
CMD_LOAD_DIALOG Loads and displays a dialog at once
CMD_QUIT Quits the application
CMD_SETOBJECTSTATES Manipulates another object, like hides/shows it
CALLAPPLICATIONAPI Defines a Text API to do application binding

When using commands in GSE it can be populated to GSE with a custom extension.

Custom Extensions

Custom Extensions - Dependencies

The Application normally consists of the Guiliani library, user code, and custom extensions code. GSE consists of a GSE library, Guiliani and the same sources of Custom Extensions as the application. For further information on events please read our documentation.

DataPool

Create Controls

You can either create a new project from scratch or just modify an existing project for this Howto. First create these Controls on one or more dialogs with the given IDs:

Control Type ID
Gauge OBJ_GAUGE_DPOOL
Text field OBJ_TEXTFIELD_DPOOL
Horizontal slide OBJ_HOR_SLIDER_DPOOL
Vertical Slide OBJ_VER_SLIDER_DPOOL

The ID names are not important. but it is important that you can identify them later. The Gauge has different standard parameters than the others. To the values correctly, set the following attributes:

Attribute Value
MinAngle -45
MaxAngle 225
MaxValue 200

Example layout

Manage Datapool

Using the menu item "Resources->Manage datapool" it is possible to bind the control to a datapool entry. First we add a new Entry. You might change the name and add a description here. Now add the previously created controls as observers and close the dialog. Manage Data Pool window

See the effect

To see the effect choose File->Run Simulation... to simulate the results. When dragging one slide each of the controls at once shows the same value.

CallApplicationAPI

To demonstrate the CallApplicationAPI this Howto will let you add a button which will divide the DataPool value by two. As described above, the CallApplicationAPI is a built-in command which defines a Text API to do application binding. It requires two Strings:

  • ApplicationAPI: Here you can define an API name
  • Parameter: A parameter to this API

Configure CallApplicationAPI in GSE

First, add a new Button two a dialog of you project. You may want to change the text of the button to i.e. Divide by two. This can be done by unfolding StandardText and write your text into the Text Attribute.

To use the CallApplicationAPI unfold GUICommand and change CommandClassID to CMD_CALLAPPLICATIONAPI. You will see that the Attributes ApplicationAPI and Parameter appeared.

Enter attribute ApplicationAPI to "divide" and Parameter to 2.

Parameterizing CallApplicationAPI

Update generated sources

Simulation or Export also generate headers that are used in both GSE and your application. If you added IDs that you want to use in your application you need to copy the newly generated files into the application's include directory.

Since Guiliani 2.1 GSE can copy these files automatically when checking Overwrite Headers in StreamRuntime.

In Guiliani 2.0 or earlier it is needed to copy all headers from either the directory temp when you were simulating the application or the directory you exported to. Copy all header files from there to your application/include/GUIConfig.

Using CMake to create your IDE project

Startup CMake GUI. Set Path to SDK/projects/cmake as source code path. The Binary folder hosts the generated project. Enter a folder of your choice and press configure.You will now see a dialog where you can choose your IDE. After selecting the IDE press Finish. In the main window, it is needed to set the path to your application as GSE_ROOT_PATH_STREAMRUNTIME and your application's executable name in GSE_STREAMRUNTIME_APPNAME. Finally, Press Generate.

Implement CallApplicationAPI

Open File Path to your Application/src/custom_extension/CallApplicationAPICmd.cpp.

The main method of a Command is the Do method. it is called when a command is processed.

This code gets the Datapool entry, divides it by the parameter and sets it to the datapool. We also need some conversions, because the API parameter is always a string and the GUIDataPool stores GUIValues which is a kind of Variant.

 1 if (kAPI == "Divide")
 2 {
 3 		eC_Int iParam=0;
 4 		kParam.ToInt(iParam);
 5 		CDataPoolEntry* pkEntry = NULL;
 6 		
 7 		CGUIDataPool::Get(DATAPOOL_ID1, &pkEntry);
 8 		eC_Int iValue;
 9 		iValue = pkEntry->Get().ToInt();
10 		iValue /= iParam;
11 		CGUIDataPool::Set(DATAPOOL_ID1, CGUIValue(iValue));
12 }

To use the DataPool add this include:

1 #include "GUIDataPool.h"

After recompiling, start the GSE from the bin directory, load the project and run the simulation. If you now move the sliders and press the button, you will see that the value halves each time you press the button.

Custom Extensions

To demonstrate Custom extensions this Howto will let you adds a new control named MyControl in include/custom_extension and src\custom_extension of your application.

Create a new Custom Extension using GSE

Open GSE and your project. Choose Custom Extensions->Create Custom Extensions. Choose Add Control. Enter name MyControl and press Generate. Close GSE.

It’s needed to add the newly created sources to your IDE's project. So we need to regenerate the project using CMake. Just Press Configure and Generate.

You will now find MyControl.h and MyControl.cpp in the project.

Add new code

The new control shall only paint a semi-transparent rectangle. So it is needed to overwrite the DoDraw-method.

MyControl.h

Add the virtual DoDraw method to the public area of MyControl.

1 public:
2     virtual eC_Bool DoDraw();

MyControl.cpp

Now add the graphical representation to the control. The following first sets the foreground color to semi-transparent full red (Line 3). Line 4 draws a filled rectangle over the whole area of the control.

1 eC_Bool MyControl::DoDraw()
2 {
3 	GETGFX.SetForegroundColor(0x7FFF0000);
4 	GETGFX.FilledRect(GetAbsRect());
5 	return true;
6  }

For painting the graphics wrapper is needed Add the include

1 #include "GfxWrap.h"

over

1 #include "GUIMemLeakWatcher.h"

Test the results

Compile the whole project. After starting GSE and Loading your project you see a new Control MyControl. Add it to your dialog. You see the intended red area.

Defining attributes

Now it's time to add some custom attributes. This part shows how to make the color and alpha changeable. This is done by customizing the streaming methods ReadFromStream and WriteToStream.

MyControl.h

First it's needed to add the color and alpha attributes to the MyControl class' private area.

1 private:
2 	eC_UByte m_ubMyAlpha;
3 	eC_UInt m_uiColor;

MyControl.cpp

Then add them to the constructor's initializer list to have some standard values (This is full black).

1 	m_uiColor(0),
2 	m_ubMyAlpha(255)


The DoDraw-Method needs also to be updated to calculate the color out of the attributes MyColor and MyAlpha:

1 eC_Bool MyControl::DoDraw()
2 {
3 	//GETGFX.SetForegroundColor(0x7FFF0000);
4 	GETGFX.SetForegroundColor((m_ubMyAlpha << 24 )+ m_uiColor);
5 	GETGFX.FilledRect(GetAbsRect());
6 	return true;
7  }


Publish the attributes to the streaming files. It's needed to create a new version of the control, because its attributes are changed by the following changes:

void MyControl::ReadFromStream():

 1 ...
 2     switch (cuiVersion)
 3     {
 4     case 1:
 5         // ************************************************************
 6         // NOTE:    Insert custom attribute read calls here.
 7         // ************************************************************
 8 		m_uiColor = 0x00FF0000;
 9 		m_ubMyAlpha = 127;
10 		break;
11 	case 2:
12 		m_uiColor = (GETINPUTSTREAM.ReadHex("MyColor") & 0x00FFFFFF);
13 		m_ubMyAlpha = static_cast<eC_UByte>( GETINPUTSTREAM.ReadShort("MyAlpha") & 0x00ff);
14 
15         break;
16     default:
17         break;
18     }


void MyControl::WriteToStream():

1 ...
2 	GETOUTPUTSTREAM.WriteHex(m_uiColor, "MyColor");
3 	GETOUTPUTSTREAM.WriteShort(m_ubMyAlpha, "MyAlpha");


Finnaly update the version of the control. Change

1 #define MYCONTROL_VERSION 1

to

1 #define MYCONTROL_VERSION 2

Final test

After recompilation open your project in GSE. Now you can see the new defined attributes of the MyControl. Felle free to play with the values.

For further information on application programming using Guiliani please read our documentation.