cancel
Showing results for 
Search instead for 
Did you mean: 

custom widget

JNova.0
Associate III

Hello,
once again the same question - Custom Widget.
Everything I do now I do with a Custom Container, but I'm wondering how to do it with a Custom Widget.
Can an existing widget be used in a custom widget? For example, can I draw a circle and a line under the circle and have it in its own widget?
I'm trying to look at the sample QR Code example, but it's broken in the current version of touchgfx (at least I can't compile the result).
Is there any sample code for a custom widget besides the mentioned QR Code?

1 ACCEPTED SOLUTION

Accepted Solutions
JTP1
Lead

Hello

If somebody wonders what was problem is JNova codes, so heres the fixed version where the callback works from customContainer to parent. I put three containers to the screen and add own if..else handler for each to the callback handler.

Screen1View.cpp:

#include <gui/screen1_screen/Screen1View.hpp>
#include  <touchgfx/Utils.hpp>

Screen1View::Screen1View():
 jnCircleCheckBoxCallback(this, &Screen1View::jnCircleCheckBoxHandler) { }


void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
    jnCircleCheckBoxA1.setClickCallback(jnCircleCheckBoxCallback);
    jnCircleCheckBoxA2.setClickCallback(jnCircleCheckBoxCallback);
    jnCircleCheckBoxA3.setClickCallback(jnCircleCheckBoxCallback);
}

void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}

void Screen1View::jnCircleCheckBoxHandler(const jnCircleCheckBoxA &button, const ClickEvent &event)
{
	if(&button==&jnCircleCheckBoxA1)
		touchgfx_printf("Cb button 1 !!\n");
	else if(&button==&jnCircleCheckBoxA2)
		touchgfx_printf("Cb button 2 !!\n");
	else if(&button==&jnCircleCheckBoxA3)
		touchgfx_printf("Cb button 3 !!\n");

    // Handle button click event (PRESSED or RELEASED)
    if (event.getType() == ClickEvent::PRESSED) {
        // Handle button pressed event
    } else if (event.getType() == ClickEvent::RELEASED) {
        // Handle button released event
    }
}

 Screen1View.hpp:

#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP

#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    
	void jnCircleCheckBoxHandler(const jnCircleCheckBoxA &button, const ClickEvent &event);
protected:
 // Declaring callback type of box and clickEvent
    Callback<Screen1View, const jnCircleCheckBoxA&, const ClickEvent&> jnCircleCheckBoxCallback;
};

#endif // SCREEN1VIEW_HPP

jnCircleCheckBoxA.cpp (only clickhandler and callback related codes):

#include <gui/containers/jnCircleCheckBoxA.hpp>
#include  <touchgfx/Utils.hpp>

jnCircleCheckBoxA::jnCircleCheckBoxA() :
		jnClickedCallback(this, &jnCircleCheckBoxA::jnClickedHandler) {
	clickingBox.setClickAction(jnClickedCallback);
}

void jnCircleCheckBoxA::setClickCallback(GenericCallback<const jnCircleCheckBoxA&, const ClickEvent&>& mycallback)
    {
   		 clickCallback = &mycallback;
    }
void jnCircleCheckBoxA::jnClickedHandler(const Box &l, const ClickEvent &evt) {
	if (enabled) {
		
		touchgfx_printf("Click !!\n");
		//PRESSED, RELEASED
		if (evt.getType() == touchgfx::ClickEvent::PRESSED) {
			setChecked(!getChecked());
			if (clickCallback != 0) {
			 //Send signal to view
                clickCallback->execute(*this, evt);
           		 
			}
			
		}
	}
}

jnCircleCheckBoxA.hpp (also reduced):

public:
    jnCircleCheckBoxA();
    virtual ~jnCircleCheckBoxA() {}

    void jnClickedHandler(const Box& l, const ClickEvent& evt);
    void setClickCallback(GenericCallback<const jnCircleCheckBoxA&, const ClickEvent&>& mycallback);
  
protected:
	GenericCallback<const jnCircleCheckBoxA&, const ClickEvent&>* clickCallback;
	//Internal custom container callback for the ELEMENT click listener
	Callback<jnCircleCheckBoxA, const Box&, const ClickEvent&> jnClickedCallback;
};

#endif // JNCIRCLECHECKBOXA_HPP

 

Take care.

Br JTP

View solution in original post

4 REPLIES 4
JNova.0
Associate III

Hello,
I've read the resources for the slider and looked at the Custom Container in the documentation (https://support.touchgfx.com/docs/development/ui-development/touchgfx-engine-features/custom-containers).
I combined this with a custom container I created and created my own fully programmable and editable component (without Base files) accordingly. It doesn't appear to be a widget, but rather a container, but that's okay.

I would still like to see how to properly create a custom widget. As I wrote, I can't get the QR Code to run.

JNova.0
Associate III
Hello,
I don't even know how long I've been trying to get a callback. I need to pass the press event to the screen. I've read the manual and looked at the examples as well, but after that time I'm lost.
Can someone please look at my code, open my checkbox (it's attached) and advise me what to write where to make it work. I understand the principle, but somehow I am not able to separate it. I deleted all my callback attempts and am sending clean code.
"jnCircleCheckBoxA" needs to be imported and added to the project.
 

 

-------------------------------
Screen2View.cpp
-------------------------------
#include <gui/screen2_screen/Screen2View.hpp>

Screen2View::Screen2View():
{
jnCircleCheckBoxA.setClickCallback(this, &Screen2View::jnCircleCheckBoxACallback);
}

void Screen2View::setupScreen()
{
    Screen2ViewBase::setupScreen();
}

void Screen2View::tearDownScreen()
{
    Screen2ViewBase::tearDownScreen();
}

void Screen2View::jnCircleCheckBoxACallback(const jnCircleCheckBoxA& button, const ClickEvent event)
{
    // Handle button click event (PRESSED or RELEASED)
    if (event == ClickEvent::PRESSED) {
        // Handle button pressed event
    } else if (event == ClickEvent::RELEASED) {
        // Handle button released event
    }
}

 

 

 

-------------------------------
Screen2View.hpp
-------------------------------

#ifndef SCREEN2VIEW_HPP
#define SCREEN2VIEW_HPP

#include <gui_generated/screen2_screen/Screen2ViewBase.hpp>
#include <gui/screen2_screen/Screen2Presenter.hpp>

class Screen2View : public Screen2ViewBase
{
public:
    Screen2View();
    virtual ~Screen2View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();

void jnCircleCheckBoxACallback(const jnCircleCheckBoxA& button, const ClickEvent event);
protected:
};

#endif // SCREEN2VIEW_HPP

 

 
-------------------------------
The "jnCircleCheckBoxA" code is in the custom container
In "jnCircleCheckBoxA" I was doing something like this:
 

 

jnCircleCheckBoxA.cpp
void jnCircleCheckBoxA::handleClickEvent(const ClickEvent& event) {
if (enabled) {
if (event.getType() == touchgfx::ClickEvent::PRESSED) {
setPressed(!getPressed());
            if (clickCallback != 0) {
                clickCallback->execute(*this, event.getType());
            }
}
}
}

jnCircleCheckBoxA.hpp
void setClickCallback(GenericCallback<const jnCircleCheckBoxA&, const ClickEvent>& mycallback)
    {
    clickCallback = &mycallback;
    }


GenericCallback<const jnCircleCheckBoxA&, const ClickEvent>* clickCallback;

 

 

Hello @JNova.0 ,

I think it is better to call widget the elements directly available in Designer and to call custom containers the elements that we create.

You can use widgets inside your custom containers and you can also use your previously created custom containers inside other custom containers.

The sample QrCode is not runnable from the get go, you still have to implement the part transforming the data into the QrCode data. I will be working on that soon and we will probably implement that as a widget directly inside Designer.
While I do that you can find resources here :
 - github for QrCode and barCode 
 - Long thread talking about QrCode in TouchGFX 
 - Someone implementing a QrCode in Designer 

You also asked about turning a circle (that is inside a custom container) into a clickable element.
You also want that click to do something in the screen.

To do so, I usually set the whole container as touchable.
If I don't want the whole container to be clickable, I will just create another custom container containing only the element I want to be touchable.
In your case, since you want a circle to be touchable, you have to add a little logic.

Then, once you get the click, you can "propagate" that click to the screen.
To do so, you should create :
 - a custom action in the custom container that will be called when the element is clicked
 - a custom trigger in the custom container that will be fetched by the screen
 - an interaction in the custom container that will be called by the action and emit your trigger
 - an interaction in your screen to fetch the trigger and then do whatever you want (ex : call new virtual function).

Please find attached an example.
I have created a custom container with a circle, a letter in the middle (this could be your checkmark in the form of an image with transparency) and a bar below it.
I insert that custom container in the screen.
When the button is clicked, the letter changes (at the custom container level) and the color of the background changes (at the screen level).

Hope this helps.

Don’t hesitate to give us a feedback or give more precisions and tell us if the issue is solved! 😊

Gaetan Godart
Software engineer at ST (TouchGFX)
JTP1
Lead

Hello

If somebody wonders what was problem is JNova codes, so heres the fixed version where the callback works from customContainer to parent. I put three containers to the screen and add own if..else handler for each to the callback handler.

Screen1View.cpp:

#include <gui/screen1_screen/Screen1View.hpp>
#include  <touchgfx/Utils.hpp>

Screen1View::Screen1View():
 jnCircleCheckBoxCallback(this, &Screen1View::jnCircleCheckBoxHandler) { }


void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
    jnCircleCheckBoxA1.setClickCallback(jnCircleCheckBoxCallback);
    jnCircleCheckBoxA2.setClickCallback(jnCircleCheckBoxCallback);
    jnCircleCheckBoxA3.setClickCallback(jnCircleCheckBoxCallback);
}

void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}

void Screen1View::jnCircleCheckBoxHandler(const jnCircleCheckBoxA &button, const ClickEvent &event)
{
	if(&button==&jnCircleCheckBoxA1)
		touchgfx_printf("Cb button 1 !!\n");
	else if(&button==&jnCircleCheckBoxA2)
		touchgfx_printf("Cb button 2 !!\n");
	else if(&button==&jnCircleCheckBoxA3)
		touchgfx_printf("Cb button 3 !!\n");

    // Handle button click event (PRESSED or RELEASED)
    if (event.getType() == ClickEvent::PRESSED) {
        // Handle button pressed event
    } else if (event.getType() == ClickEvent::RELEASED) {
        // Handle button released event
    }
}

 Screen1View.hpp:

#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP

#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    
	void jnCircleCheckBoxHandler(const jnCircleCheckBoxA &button, const ClickEvent &event);
protected:
 // Declaring callback type of box and clickEvent
    Callback<Screen1View, const jnCircleCheckBoxA&, const ClickEvent&> jnCircleCheckBoxCallback;
};

#endif // SCREEN1VIEW_HPP

jnCircleCheckBoxA.cpp (only clickhandler and callback related codes):

#include <gui/containers/jnCircleCheckBoxA.hpp>
#include  <touchgfx/Utils.hpp>

jnCircleCheckBoxA::jnCircleCheckBoxA() :
		jnClickedCallback(this, &jnCircleCheckBoxA::jnClickedHandler) {
	clickingBox.setClickAction(jnClickedCallback);
}

void jnCircleCheckBoxA::setClickCallback(GenericCallback<const jnCircleCheckBoxA&, const ClickEvent&>& mycallback)
    {
   		 clickCallback = &mycallback;
    }
void jnCircleCheckBoxA::jnClickedHandler(const Box &l, const ClickEvent &evt) {
	if (enabled) {
		
		touchgfx_printf("Click !!\n");
		//PRESSED, RELEASED
		if (evt.getType() == touchgfx::ClickEvent::PRESSED) {
			setChecked(!getChecked());
			if (clickCallback != 0) {
			 //Send signal to view
                clickCallback->execute(*this, evt);
           		 
			}
			
		}
	}
}

jnCircleCheckBoxA.hpp (also reduced):

public:
    jnCircleCheckBoxA();
    virtual ~jnCircleCheckBoxA() {}

    void jnClickedHandler(const Box& l, const ClickEvent& evt);
    void setClickCallback(GenericCallback<const jnCircleCheckBoxA&, const ClickEvent&>& mycallback);
  
protected:
	GenericCallback<const jnCircleCheckBoxA&, const ClickEvent&>* clickCallback;
	//Internal custom container callback for the ELEMENT click listener
	Callback<jnCircleCheckBoxA, const Box&, const ClickEvent&> jnClickedCallback;
};

#endif // JNCIRCLECHECKBOXA_HPP

 

Take care.

Br JTP