cancel
Showing results for 
Search instead for 
Did you mean: 

How do I trigger a new virtual function when a touch button (flexButton) is released instead of pressed?

PFlor.2
Senior

I'm fairly new to TouchGFX as well as C++ inheritance so trying to understand how to implement a custom virtual function when a key is released. I see when I create an interaction in touchGFX so when a key is pressed it calls a virtual function...


_legacyfs_online_stmicro_images_0693W00000blHmxQAE.pngWhich creates the following in the base class of the custom container...


_legacyfs_online_stmicro_images_0693W00000blHiSQAU.pngI understand how to override the startBrewCycle() virtual function in the non-base cpp file which is called with the pressed even in the callback below...


_legacyfs_online_stmicro_images_0693W00000blHoPQAU.pngHow can I implement another virtual function stopBrewCycle() when the same button is released?

1 ACCEPTED SOLUTION

Accepted Solutions
JTP1
Lead

Hello

I found my old example, just modify it for flexbutton, maybe this helps. The flexButton click handler is bit more tricky than other button types. Here in the example flexbutton has just Box with border- element.

------

One way is to create ClickListener to the FlexButton, so set it on at Mixins of your flexButton:

0693W00000aIb0cQAC.pngThen add the callback definitions to the screen1.hpp (or whatever you have)

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
 
    // Add this public function definition:
      void flexButtonClickHandler(const touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > & ,const ClickEvent& e);
 
    //  int16_t pressCount=0;
    //  int16_t releaseCount=0;
 
protected:
 
    // And add this protected function definition:
      Callback<Screen1View, const touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > &,const ClickEvent&> flexButtonClickedCallback;
 
};

and then in screen1.cpp:

#include <gui/screen1_screen/Screen1View.hpp>
#include <touchgfx/Utils.hpp>
 
// Add this callback to the constructor:
Screen1View::Screen1View():
flexButtonClickedCallback(this,&Screen1View::flexButtonClickHandler)
{
 
}
 
void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
    // This sets the click action for flexButton1 !!
    flexButton1.setClickAction(flexButtonClickedCallback);
}
 
void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}
 
// Add this function
void Screen1View::flexButtonClickHandler(const touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger >& b,const ClickEvent& e)
{
	if(&b==&flexButton1) // button1 -> your button name
	{
		switch(e.getType())
		{
			case ClickEvent::PRESSED:
				touchgfx_printf("Pressed flexButton1 \r\n");
				//pressCount++;
			break;
 
			//case ClickEvent::RELEASED:
			//case ClickEvent::CANCEL:
			default:
				touchgfx_printf("Released or Cancel flexButton1 \r\n");
				//releaseCount++;
				// this handles REALEASED and CANCEL- events !
			break;
		}
 
//This is just debug print to display, since its tested also in device :
		//Unicode::snprintf(CounterBuffer, COUNTER_SIZE, "press:%3u release:%3u",pressCount,releaseCount);
		//Counter.invalidate();
	}
}

Please note that this works only with flexButton that has only Box with border. If you have some other elements, check in screen1base.hpp the inheritance structure of your flexButton

/* Screen1ViewBase.hpp
     * Member Declarations
     */
 
// HERE !!:
    touchgfx::ClickListener< touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger >  > flexButton1;

Only BoxWithBorder:

touchgfx::ClickListener< touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > > flexButton1;

All 4 elements:

 touchgfx::ClickListener< touchgfx::IconButtonStyle< touchgfx::TextButtonStyle< touchgfx::ImageButtonStyle< touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > > > > > flexButton1;

This case you must replace the callback and clickHandler function parameters to match your flexbutton elements at in Screen1.cpp and .hpp !

Example is tested with Simulator and F769IDisco evalkit. BTW what hardware you are using ?

View solution in original post

8 REPLIES 8
JTP1
Lead

Hello

I found my old example, just modify it for flexbutton, maybe this helps. The flexButton click handler is bit more tricky than other button types. Here in the example flexbutton has just Box with border- element.

------

One way is to create ClickListener to the FlexButton, so set it on at Mixins of your flexButton:

0693W00000aIb0cQAC.pngThen add the callback definitions to the screen1.hpp (or whatever you have)

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
 
    // Add this public function definition:
      void flexButtonClickHandler(const touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > & ,const ClickEvent& e);
 
    //  int16_t pressCount=0;
    //  int16_t releaseCount=0;
 
protected:
 
    // And add this protected function definition:
      Callback<Screen1View, const touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > &,const ClickEvent&> flexButtonClickedCallback;
 
};

and then in screen1.cpp:

#include <gui/screen1_screen/Screen1View.hpp>
#include <touchgfx/Utils.hpp>
 
// Add this callback to the constructor:
Screen1View::Screen1View():
flexButtonClickedCallback(this,&Screen1View::flexButtonClickHandler)
{
 
}
 
void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
    // This sets the click action for flexButton1 !!
    flexButton1.setClickAction(flexButtonClickedCallback);
}
 
void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}
 
// Add this function
void Screen1View::flexButtonClickHandler(const touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger >& b,const ClickEvent& e)
{
	if(&b==&flexButton1) // button1 -> your button name
	{
		switch(e.getType())
		{
			case ClickEvent::PRESSED:
				touchgfx_printf("Pressed flexButton1 \r\n");
				//pressCount++;
			break;
 
			//case ClickEvent::RELEASED:
			//case ClickEvent::CANCEL:
			default:
				touchgfx_printf("Released or Cancel flexButton1 \r\n");
				//releaseCount++;
				// this handles REALEASED and CANCEL- events !
			break;
		}
 
//This is just debug print to display, since its tested also in device :
		//Unicode::snprintf(CounterBuffer, COUNTER_SIZE, "press:%3u release:%3u",pressCount,releaseCount);
		//Counter.invalidate();
	}
}

Please note that this works only with flexButton that has only Box with border. If you have some other elements, check in screen1base.hpp the inheritance structure of your flexButton

/* Screen1ViewBase.hpp
     * Member Declarations
     */
 
// HERE !!:
    touchgfx::ClickListener< touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger >  > flexButton1;

Only BoxWithBorder:

touchgfx::ClickListener< touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > > flexButton1;

All 4 elements:

 touchgfx::ClickListener< touchgfx::IconButtonStyle< touchgfx::TextButtonStyle< touchgfx::ImageButtonStyle< touchgfx::BoxWithBorderButtonStyle< touchgfx::TouchButtonTrigger > > > > > flexButton1;

This case you must replace the callback and clickHandler function parameters to match your flexbutton elements at in Screen1.cpp and .hpp !

Example is tested with Simulator and F769IDisco evalkit. BTW what hardware you are using ?

Osman SOYKURT
ST Employee

Hello PFlor.2,

This thread also treats this subject, but it's pretty much what JTP wrote, I think his answer is good.

Basically, you'll need to get the event type of your click and this is what he's doing in here :

switch(e.getType())
{
	case ClickEvent::PRESSED:
...

/Osman

Osman SOYKURT
ST Software Developer | TouchGFX

Thanks for this information, I think this is exactly what I need. I've been working on other aspects but will try this out shortly.

I also need to be able to trigger a virtual function once the button has been held down for 2 seconds as well but think I could use aspects of this for that as well. Maybe wait 2 seconds after the initial press then check to see if still isPressed or not.

Using STM32H643 on custom hardware.

Note also that you can do this system without new callbacks, just use handleTickEvent. This handleTickEvent will be called automatically with in every frame. This is not the most elegant way but it does it job:

// add to view.hpp:
      void handleTickEvent();
 
      bool exButtonPressed=0;
      uint32_t ButtonPressedTimeCounter=0;
// add to view.cpp:
void Screen1View::handleTickEvent()
{
	bool buttonPressedNow;
 
	buttonPressedNow=yourFlexButton.getPressed();
 
	if(buttonPressedNow)
	{
		if(exButtonPressed==0)
		{
			// handle button pressed down if needed
			ButtonPressedTimeCounter=0;
		}
		else // also last time was pressed
		{
 			// note that this increment can overflow, it takes years
 			// of continuos press but anyway.
 			// It could have some protection like
 			// if(ButtonPressedTimeCounter<0xFFFFFFFF)
			ButtonPressedTimeCounter++;
 
			//replace '120' with your 2 sec frame rate
			if(ButtonPressedTimeCounter==120)
			{
				// handle 2 sec button pressed
			}
		}
	}
	else // not pressed now
	{
		// last time was ?
		if(exButtonPressed)
		{
			// handle button released
		}
	}
	exButtonPressed=buttonPressedNow;
}

I have finally gotten around to try this solution and while it builds I do not get any printf feedback to indicate the flexButtonClickHandler is functioning.  Can you please see what I could be missing?

PFlor2_2-1688679211819.png

 

PFlor2_1-1688679128132.png

 

PFlor2_0-1688678884113.png

 

 

JTP1
Lead

Hello. Hmm...did you put 'setAction' - call to the 'initialize' - function ? Otherwise it looks ok with quick review.

You can also test the functionality by changing trigger to 'click' instead of repeat, i have never use click callbacks with repeat button.

Br. J.T

was missing the setAction in initialize, thanks so much for the assitance

 

Thanks JTP1...I was missing the setAction.  Totally missed you had sent a reply on 7/6.  Thanks again for the assistance!