Difference between revisions of "Support:Howto:Application Binding"

From Guiliani

Line 108: Line 108:
  
 
=== Using CMake to create your IDE project ===
 
=== Using CMake to create your IDE project ===
Startup CMake. Set ''Path to your Application/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 press ''Generate''.
+
Startup CMake. 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 ===
 
=== Implement CallApplicationAPI ===
Line 115: Line 114:
  
 
The main method of a Command is the '''Do''' method. it is called when a command is processed.
 
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.
 +
 +
<syntaxhighlight lang="c++" line>
 +
if (kAPI == "Divide")
 +
{
 +
eC_Int iParam=0;
 +
kParam.ToInt(iParam);
 +
CDataPoolEntry* pkEntry = NULL;
 +
 +
CGUIDataPool::Get(DATAPOOL_ID1, &pkEntry);
 +
eC_Int iValue;
 +
iValue = pkEntry->Get().ToInt();
 +
iValue /= iParam;
 +
CGUIDataPool::Set(DATAPOOL_ID1, CGUIValue(iValue));
 +
}
 +
</syntaxhighlight>
 +
 +
To use the DataPool add this include:
 +
<syntaxhighlight lang="c++" line>
 +
#include "GUIDataPool.h"
 +
</syntaxhighlight>
 +
 +
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 halfs 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.
 +
<syntaxhighlight lang="c++" line>
 +
public:
 +
    virtual eC_Bool DoDraw();
 +
</syntaxhighlight>
 +
 +
==== MyControl.cpp ====
 +
Now add the graphical represantation to the control. The following first sets the foreground color to semi-transparent full red (Line 3).  Line 4 draws a filled rect over the whole area of the control.
 +
 +
<syntaxhighlight lang="c++" line>
 +
eC_Bool MyControl::DoDraw()
 +
{
 +
GETGFX.SetForegroundColor(0x7FFF0000);
 +
GETGFX.FilledRect(GetAbsRect());
 +
return true;
 +
}
 +
</syntaxhighlight>
 +
For painting the graphics wrapper is needed
 +
Add the include
 +
<syntaxhighlight lang="c++" line>
 +
#include "GfxWrap.h"
 +
</syntaxhighlight>
 +
over
 +
<syntaxhighlight lang="c++" line>
 +
#include "GUIMemLeakWatcher.h"
 +
</syntaxhighlight>
 +
 +
=== Test the reults ===
 +
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.
 +
<syntaxhighlight lang="c++" line>
 +
private:
 +
eC_UByte m_ubMyAlpha;
 +
eC_UInt m_uiColor;
 +
</syntaxhighlight>
 +
 +
==== MyControl.cpp ====
 +
Then add them to the constructor's initializer list to have some standard values (This is full black).
 +
<syntaxhighlight lang="c++" line>
 +
m_uiColor(0),
 +
m_ubMyAlpha(255)
 +
</syntaxhighlight>
 +
 +
 +
The DoDraw-Method needs also to be updated to calciulate the color out of the attibutes ''MyColor'' and ''MyAlpha'':
 +
<syntaxhighlight lang="c++" line>
 +
eC_Bool MyControl::DoDraw()
 +
{
 +
//GETGFX.SetForegroundColor(0x7FFF0000);
 +
GETGFX.SetForegroundColor((m_ubMyAlpha << 24 )+ m_uiColor);
 +
GETGFX.FilledRect(GetAbsRect());
 +
return true;
 +
}
 +
</syntaxhighlight>
 +
 +
 +
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():
 +
<syntaxhighlight lang="c++" line>
 +
...
 +
    switch (cuiVersion)
 +
    {
 +
    case 1:
 +
        // ************************************************************
 +
        // NOTE:    Insert custom attribute read calls here.
 +
        // ************************************************************
 +
m_uiColor = 0x00FF0000;
 +
m_ubMyAlpha = 127;
 +
break;
 +
case 2:
 +
m_uiColor = (GETINPUTSTREAM.ReadHex("MyColor") & 0x00FFFFFF);
 +
m_ubMyAlpha = static_cast<eC_UByte>( GETINPUTSTREAM.ReadShort("MyAlpha") & 0x00ff);
 +
 +
        break;
 +
    default:
 +
        break;
 +
    }
 +
</syntaxhighlight>
 +
 +
 +
void MyControl::WriteToStream():
 +
<syntaxhighlight lang="c++" line>
 +
...
 +
GETOUTPUTSTREAM.WriteHex(m_uiColor, "MyColor");
 +
GETOUTPUTSTREAM.WriteShort(m_ubMyAlpha, "MyAlpha");
 +
</syntaxhighlight>
 +
 +
 +
Finnaly update the version of the control. Change
 +
<syntaxhighlight lang="c++" line>
 +
#define MYCONTROL_VERSION 1
 +
</syntaxhighlight>
 +
to
 +
<syntaxhighlight lang="c++" line>
 +
#define MYCONTROL_VERSION 2
 +
</syntaxhighlight>
 +
 +
=== 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 https://www.guiliani.de/mediawiki/downloads/Guiliani_doc_2.0/index.html].

Revision as of 17:18, 27 January 2017

Intro

Assumed knowledge

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

Prerequisites

  • Any Installed SDK: Desktop or Board 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 describe 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

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.

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 builtin command which defines a Text API to do application binding. It requires two Strings:

  • ApplicationAPI: Here you can define an API name
  • Parameter: A paramter 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.

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 simualting 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. 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 halfs 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 represantation to the control. The following first sets the foreground color to semi-transparent full red (Line 3). Line 4 draws a filled rect 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 reults

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 calciulate the color out of the attibutes 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 https://www.guiliani.de/mediawiki/downloads/Guiliani_doc_2.0/index.html].