cancel
Showing results for 
Search instead for 
Did you mean: 

How to perform action on REPEAT button release

reniervdw1
Associate II

I have a simple repeat button that increments a value as you hold it in. However, I would like to change the repeat button on release so that the next time it is held in, it decrements the value.

I'm new to object orientated programming as well so a complete answer will be highly appreciated. Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
Martin KJELDSEN
Chief III

When the RepeatButton is PRESSED, an internal timer starts. For each tick, it executes some code and in this code a callback is fired (the standard callback inherited from the Button class).

void RepeatButton::handleTickEvent()
{
    Button::handleTickEvent();
 
    if (pressed)
    {
     ...
    }
}

So, basically, you need to do two things:

  • Keep track of a new variable that toggles between modes (increase, decrease)
  • Modify the handleTickEvent method to be able to also decrease a counter and not just increase.

Take a look at RepeatButton.cpp.

/Martin

View solution in original post

15 REPLIES 15
TDK
Guru

You don't need any object oriented programming to do this. Are you new to all programming? Have you looked at any sample projects? Have you made a project which just blinks an LED? Gotta start somewhere.

If you feel a post has answered your question, please click "Accept as Solution".
Martin KJELDSEN
Chief III

When the RepeatButton is PRESSED, an internal timer starts. For each tick, it executes some code and in this code a callback is fired (the standard callback inherited from the Button class).

void RepeatButton::handleTickEvent()
{
    Button::handleTickEvent();
 
    if (pressed)
    {
     ...
    }
}

So, basically, you need to do two things:

  • Keep track of a new variable that toggles between modes (increase, decrease)
  • Modify the handleTickEvent method to be able to also decrease a counter and not just increase.

Take a look at RepeatButton.cpp.

/Martin

Hi Martin,

Thanks for the reply I appreciate it

Seems like all is working now.

I had to make use of static functions and variables inside the Model. Is that bad practice or can I leave it that way?

I want to keep an output active as long as the button is pressed. When the finger is removed from the button, the output will be disabled. I have defined Interaction which is called when the button is pressed. ''Call Virtual Function''. When pressed here, it enters and does not enter again. I need to keep the output active as long as it is pressed.

Can you help me?

Hello,

Have you use the code shared by Martin in your project ? Could you share your implementation/project ?

/Romain

Esbenimu
Associate II

Thanks for your quick answer. Yes, I added the RepeatButton.cpp software as follows, but it didn't work at all.

void RepeatButton::handleTickEvent()

{

  Button::handleTickEvent();

  if (!pressed)

  {

   Long_Press_Control = 0; // esbenimu

    return;

  }

  if (ticks == ticksBeforeContinuous)

  {

   Long_Press_Control = BUT_STILL_PUSH; // esbenimu

    executeAction();

    ticks = 0;

    ticksBeforeContinuous = ticksInterval;

  }

  else

  {

    ticks++;

  }

}

I also added a code as below. In this code, only the first button is pressed, it becomes Pressed, as long as the button is pressed, it is not pressed again.

In other words, although the button remains pressed, the led does not stay on, it goes out.

I also checked if it is constantly in this routine, it does.

(Timer_Set_Value ++;

Timer_Set_Value_Change = 1;)

MainScreenView.cpp

void MainScreenView::handleTickEvent()

{

if (ManuelButton.getPressedState())

{

Long_Press_Control = BUT_STILL_PUSH;

HAL_GPIO_WritePin(BUT3_LED_RD_GPIO_Port, BUT3_LED_RD_Pin, GPIO_PIN_SET);

}

else

{

Long_Press_Control = 0;

Timer_Set_Value ++;

Timer_Set_Value_Change = 1;

HAL_GPIO_WritePin(BUT3_LED_RD_GPIO_Port, BUT3_LED_RD_Pin, GPIO_PIN_RESET);

}

}

Thanks for your quick answer. Yes, I added the RepeatButton.cpp software as follows, but it didn't work at all.

void RepeatButton::handleTickEvent()

{

  Button::handleTickEvent();

  if (!pressed)

  {

  Long_Press_Control = 0; // esbenimu

    return;

  }

  if (ticks == ticksBeforeContinuous)

  {

  Long_Press_Control = BUT_STILL_PUSH; // esbenimu

    executeAction();

    ticks = 0;

    ticksBeforeContinuous = ticksInterval;

  }

  else

  {

    ticks++;

  }

}

I also added a code as below. In this code, only the first button is pressed, it becomes Pressed, as long as the button is pressed, it is not pressed again.

In other words, although the button remains pressed, the led does not stay on, it goes out.

I also checked if it is constantly in this routine, it does.

(Timer_Set_Value ++;

Timer_Set_Value_Change = 1;)

MainScreenView.cpp

void MainScreenView::handleTickEvent()

{

if (ManuelButton.getPressedState())

{

Long_Press_Control = BUT_STILL_PUSH;

HAL_GPIO_WritePin(BUT3_LED_RD_GPIO_Port, BUT3_LED_RD_Pin, GPIO_PIN_SET);

}

else

{

Long_Press_Control = 0;

Timer_Set_Value ++;

Timer_Set_Value_Change = 1;

HAL_GPIO_WritePin(BUT3_LED_RD_GPIO_Port, BUT3_LED_RD_Pin, GPIO_PIN_RESET);

}

}

Hello

If you only need to get Led on when button is pressed and set Led off when button is released, you could create ClickListener for button and get Pressed / Released events with callback from button. This way the implementation is much more simple.

Here is simple example. Screen name is Screen1 and basic button is called button1:

First check the ClickListener- parameterer in the button Properties - Mixins:

0693W00000aIb0cQAC.pngThen generate the code. Edit Screen1View.hpp and add two definitions:

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    
    // Add this public function definition:
    void buttonClickHandler(const Button& b,const ClickEvent& e);
 
protected:
 
    // And add this protected function definition:
    Callback<Screen1View, const Button&,const ClickEvent&> buttonClickedCallback;
 
};

and then Screen1View.cpp

#include <gui/screen1_screen/Screen1View.hpp>
 
// Add this callback to the constructor:
Screen1View::Screen1View():
buttonClickedCallback(this,&Screen1View::buttonClickHandler)
{
 
}
 
void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
 
    // This sets the click action for button1 !!
    // Replace button1 with correct button name if needed
    button1.setClickAction(buttonClickedCallback);
}
 
void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}
 
// Add this function
void Screen1View::buttonClickHandler(const Button& b,const ClickEvent& e)
{
	if(&b==&button1) // button1 -> your button name
	{
		switch(e.getType())
		{
			case ClickEvent::PRESSED:
				// Set LED on here !!
			break;
 
			default:
				// this handles REALEASED and CANCEL- events !
				// Set LED off here !!
			break;
		}
	}
}

I updated the software as you suggested. When I press the button, the led turns on but immediately goes out. Even though I keep the button pressed, it enters the "Led off" part. So as long as the button is pressed, the led does not stay on. I'm debugging. I mark the break point for the "led off" command. Even though I hold down the button, the program comes to the break point.

Do I need to do another setting?