cancel
Showing results for 
Search instead for 
Did you mean: 

How to unresister Click and Drag Event manually

SYama.11
Associate II

Hi,

I'm trying to change screen with button on a screen and hardware button.

But, I don't want to add another screen because some parameter is shared,

So, I use pointers for some widgets and generate/delete the widgets at runtime.

However, when I press the trigger key to change screen during pressing the button on the screen and release the button after the screen has changed, the program has crashed.

I think that the program try to call "Button::handleClickEvent" of the button that has already deleted but failed, it has crashed.

Here's a some sample code.

class sampleScreen {
~~~~~~~~~~
  virtual void setupScreen();
~~~~~~~~~~
  void buttonPressed();
  void triggerKeyPressed();
  void switchScreen();
~~~~~~~~~~
  Button* button;
~~~~~~~~~~
}
 
sampleScreen::setupScreen() {
  button = new Button();
~~~~~~~~~~
  add(*button);
  getRootContainer().invalidate();
}
 
void sampleScreen::buttonPressed() {
  switchScreen();
}
 
void sampleScreen::triggerKeyPressed() {
  switchScreen();
}
 
void sampleScreen::switchScreen() {
  remove(*button);
  delete button;
  getRootContainer().invalidate();
}

​If there is a way to unresister to listen click event manually when the program switches screen.

Do you know how to do this ? Or should I change plan ?

1 ACCEPTED SOLUTION

Accepted Solutions

Hello,

I'm sorry but I still don't understand exactly what is the application about.

Anyway, if you really want to remove the clickEvent from a widget (like a button), you need to implement the ClickEvent in your Screen, without calling the ClikcEvent of your ScreenBase. This way, only the ClickEvent in your screen will be executed and not the one from the widget.

In the ClickEvent function implemented in your Screen, you can have a flag that authorize the click from the widget in one case but not in other cases like something as follows :

void ScreenView::handleClickEvent(const ClickEvent& evt)
{
   if(buttonExist) // execute the button clickEvent function
  {
      ScreenViewBase::handleClickEvent(evt);
  }
   // Else do nothing
}

In the end, I still suggest to have different screens, because constantly removing and recreating widgets at runtime on the same screen can become quite a mess and not very stable in my opinion.

But if it works this way then this is what matters most ;)

/Alexandre

View solution in original post

7 REPLIES 7
Alexandre RENOUX
Principal

Hello,

You say you don't want to add another screen because some parameters are shared but you can actually share parameters between screens.

For that you need to save the parameters/variables in the Model. There's only one model in your application that is shared with all the screens.

So creating another screen would be a better and easier idea.

/Alexandre

Hello Alexandre,

Thank you for your answer.

I understood to use the Model for parameters to save, but how about widgets like background images or something (e.g. clock, status icons...etc.)?

Should I save widget parameters (Color, BitmapId, TypedTextId, Position and Size...) in the Model and read values everytime entering the screen?

I don't like the idea because when the application gets large, the Model has so many parameters but they are not used in all screens.

Furthermore, I'm afraid that dividing screens sacrifices the readability of the code because those screens are no longer related. So I have to write same functions in the presenter of each screen.

What do you think?

Hello,

"'I'm afraid that dividing screens sacrifices the readability of the code"

On the contrary actually, I think that having different screens helps dividing the code in different files therefore increasing the readability.

"So I have to write same functions in the presenter of each screen."

True to a certain extent.

I feel like (correct me if I'm wrong) that you want a kind of template. Like the backgrounds, icons, etc... must be shared.

In this case, you don't need to share all the parameters in the Model but only one variable that will tell which set of background, icons, etc. must be implemented for each screen. Depending on the value of the shared variable, the position, BitmapId, Size, etc. will be the same.

Also if you really have to save a significant number of parameters, you can store then in structures to ease the understanding and implement only a couple of functions.

I don't know exactly what you are trying to do, so a picture or something similar might be useful to have more insight on your project.

/Alexandre

SYama.11
Associate II

deleted​

Hello Alexandre,

"I feel like (correct me if I'm wrong) that you want a kind of template. Like the backgrounds, icons, etc... must be shared."

Yes. That's nearly what I want to do, and I think I can solve the problem by the way what you suggest.

Our project is the first one who use TouchGFX for product and I'm creating a demo project for other members who use TouchGFX after us.

However, the demo project is taken over from a predecessor, and the project was designed like this.

0693W000001shmjQAA.jpg

When the switch screen was called, all widgets are removed from the Root Container by calling deleteScreen() function and the application calls createScreen() function.

In the createScreen() function, the widgets are initialized and added to the Root Container.

void DemoScreenView::createPage(demo::UIFormIndex const index)
{
	std::queue<Drawable*> drawableQue;
	demo::createDemoPages[index](drawableQue, presenter);
	while (!drawableQue.empty()) {
		add(*drawableQue.front());
		drawableQue.pop();
	}
	getRootContainer().invalidate();
}
 
void DemoScreenView::deletePage()
{
  Application::getInstance()->clearAllTimerWidgets();
 
	Drawable* drawable = nullptr;
	while (drawable = getRootContainer().getFirstChild()) {
		remove(*drawable);
		delete drawable;
	}
}

The parameters of the widgets are defined in the other file and the code has those widgets like this.

// DemoPageDifinitions.hpp
struct DemoPage1Content {
	PixelDataWidget* bgPixel;
	Button* demoButton;
	...
};
 
 
void createDemoPage1(std::queue<Drawable*> &drawableQue, DemoPagePresenter *const listener);
void createDemoPage2(std::queue<Drawable*> &drawableQue, DemoPagePresenter *const listener);
...
 
static void (*createDemoPages[Index::NumPages])(std::queue<Drawable*> &drawableQue, DemoPagePresenter *const listener) =
{
	createDemoPage1,
	createDemoPage2,
	...
};
 
// DemoPageDefinitions.cpp
void createDemoPage1(queue<Drawable*> &drawableQue, DemoPagePresenter *const presenter)
{
	// widget initialize here
	demoPage1.bgPixel = new PixelDataWidget();
	...
 
	drawableQue.push(&demoPage1.bgPixel);
	drawableQue.push(&demoPage1.demoButton);
	...
};

I don't know why he implemented so.​ and I do think I should add screens.

But I don't want to spend much time to modify a demo project, so I asked if there's a way to solve.

That is the situation and what I'm going to do.

Hello,

I'm sorry but I still don't understand exactly what is the application about.

Anyway, if you really want to remove the clickEvent from a widget (like a button), you need to implement the ClickEvent in your Screen, without calling the ClikcEvent of your ScreenBase. This way, only the ClickEvent in your screen will be executed and not the one from the widget.

In the ClickEvent function implemented in your Screen, you can have a flag that authorize the click from the widget in one case but not in other cases like something as follows :

void ScreenView::handleClickEvent(const ClickEvent& evt)
{
   if(buttonExist) // execute the button clickEvent function
  {
      ScreenViewBase::handleClickEvent(evt);
  }
   // Else do nothing
}

In the end, I still suggest to have different screens, because constantly removing and recreating widgets at runtime on the same screen can become quite a mess and not very stable in my opinion.

But if it works this way then this is what matters most ;)

/Alexandre

Hello Alexandre,

"I'm sorry but I still don't understand exactly what is the application about."

Well, this application is just a demo application to show widgets TouchGFX have, so that the other who is interested in using TouchGFX can know what it can do.

It has some screens and you can switch screens by pressing button on the screen or hardware switch.

Here's some examples of the screens.

Screen1 Button Demo​ (and some test widgets)

0693W000001shlRQAQ.bmp

Screen2 Animated Image Demo

0693W000001shlWQAQ.bmp

Screen3 List Layout and Scrollable Container Demo0693W000001shlbQAA.bmp

​Anyway, I think overriding ClickEvent would be the answer what I wanted.

And I decided to re-design the application because each screen have widgets which receives ClickEvent and the overriden ClickEvent would be too complicated.

Thank you for your advice. It helps me a lot.