cancel
Showing results for 
Search instead for 
Did you mean: 

Modal Window from ListLayout

CYBR
Associate II

I have created a custom container which includes some text boxes, scrollists labels etc to allow the user to set the parameters for an alarm. I add one of these custom containers to my listlayout in code for each alarm to be set. So the user is presented with a list of alarms, and the opportunity to change the settings for each alarm. I have also created a modalwindow containing a keyboard. The desire is when the user clicks the box for an individual alarm to set the numeric value of the alarm limit, a modalwindow pops up, so the user can enter the new numeric value, which is saved into the model value and displayed in the relevant box in the list for this alarm, when he clicks save in the modal window and closes it.

The problem I have is that when the boxclickhandler displays the modalwindow, it only displays the tiny portion of the modal window which covers the listlayout, rather than popping up the modalwindow over the entire screen:

CYBR_0-1716684345138.png

I guess this is because the modalwindow is a member of the customcontainer in the listlayout, not the underlying screen, so only covers the container not the screen. I have tried to create the modalwindow in the screen, but cannot get the callback to the boxclickhandler in the container to call the screen modalwindow.

Any ideas how I can achieve this?

The next problem will then become how to put the existing setting from the clicked customcontainer text field into the modalwindow keyboard box, and how to retrieve the new set vale and put it back in the relevant text field (and the model saved value).

 

1 ACCEPTED SOLUTION

Accepted Solutions
CYBR
Associate II

Interesting. As far as I can tell my code is identical to yours. However, in trying to resolve this, I had included the following line in the CustomContainerAlarm.hpp file

#include <gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp>

With that present, it throws up these errors compiling the view file, as I explained above.

In file included from ../../TouchGFX/gui/include/gui/containers/CustomContainerAlarm.hpp:6,
                 from C:/TouchGFXProjects/Charge_Cont_V4/TouchGFX/gui/src/containers/CustomContainerAlarm.cpp:1:
../../TouchGFX/gui/include/gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp:23:28: error: 'CustomContainerAlarm' has not been declared
   23 |     void alarmLimitClicked(CustomContainerAlarm& element);
      |                            ^~~~~~~~~~~~~~~~~~~~
../../TouchGFX/gui/include/gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp:36:36: error: 'CustomContainerAlarm' was not declared in this scope; did you mean 'CustomContainerRelay'?
   36 |     Callback<ScreenAlarmSetupView, CustomContainerAlarm&> alarmLimitClickedCallback;
      |                                    ^~~~~~~~~~~~~~~~~~~~
      |                                    CustomContainerRelay
../../TouchGFX/gui/include/gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp:36:57: error: template argument 2 is invalid
   36 |     Callback<ScreenAlarmSetupView, CustomContainerAlarm&> alarmLimitClickedCallback;
      |                                                         ^
make: *** [Application/User/gui/subdir.mk:103: Application/User/gui/CustomContainerAlarm.o] Error 1
make: *** Waiting for unfinished jobs....

When I delete that line from the CustomContainerAlarm.hpp file, all the errors go away. Don't understand why (some kind of circular reference I guess), but problem solved. Thankyou for your help.

 

View solution in original post

5 REPLIES 5
JTP1
Lead

Hello CYBR

I think correct way to implement this is to get callback from listlayout object to view and then handle the click there (show modal kb, save the value to model after editing and update the listlayout object).

Have you check this ListLayout- example:

JTP1_0-1716701260761.png

It is very simple and demonstrates well how to get callback from listlayout- object.

About this value saving/reading from model, maybe check these articles to get basic idea:

https://support.touchgfx.com/docs/development/ui-development/software-architecture/model-view-presenter-design-pattern

https://support.touchgfx.com/docs/development/ui-development/touchgfx-engine-features/backend-communication

And then here is example 'MVP_toggleBtnExV1.zip' for saving and reading values from model:

https://community.st.com/t5/stm32-mcus-products/toggle-button-off-after-a-specific-interval/m-p/569065#M217071

Perhaps this helps you forward, don't hesitate to ask more.

Br JTP

 

CYBR
Associate II

Thanks. I have implemented the callback from the custom container, but the compiler is objecting to the custom container not being declared in the screen view and won't create the callback or the end function to display the keyboard. I have included the custom container definition, but it seems this is not enough. Perhaps it is because I am creating the custom container in code, not statically in touchgfx? Line 22 and 35 say CustomContainerAlarm not declared despite line 10.

 

 

#ifndef SCREENALARMSETUPVIEW_HPP
#define SCREENALARMSETUPVIEW_HPP

#include <gui_generated/screenalarmsetup_screen/ScreenAlarmSetupViewBase.hpp>
#include <gui/screenalarmsetup_screen/ScreenAlarmSetupPresenter.hpp>
#include <string.h>
#include <gui/common/CustomKeyboard.hpp>
#include <stdio.h>
#include <touchgfx/Unicode.hpp>
#include <gui/containers/CustomContainerAlarm.hpp>
#include <images/BitmapDatabase.hpp>
class ScreenAlarmSetupView : public ScreenAlarmSetupViewBase
{
public:
    ScreenAlarmSetupView();
    virtual ~ScreenAlarmSetupView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    virtual void okClicked();
    virtual void exitClicked();
//    void boxClickHandler(const Box& b, const ClickEvent& e);
    void alarmLimitClicked(CustomContainerAlarm& element);




protected:
    int i;
    int alarm_pg1_cntr=0;
    int alarm_pg2_cntr=0;
    int alarm_pg3_cntr=0;
    int alarm_pg4_cntr=0;
    int alarm_pg5_cntr=0;
    CustomKeyboard keyboard;
    Callback<ScreenAlarmSetupView, CustomContainerAlarm&> alarmLimitClickedCallback;

};

 

I am creating the list elements on the heap like this

 

void ScreenAlarmSetupView::setupScreen()
{
    ScreenAlarmSetupViewBase::setupScreen();

/*
 * There are multiple pages of alarms in the swipe container. Each holds a ListLayoutAlarmListx.
 */
    listLayoutAlarmList1.setWidthHeight(0,0); //Compensates for the list height that is set to 200 by the designer
    listLayoutAlarmList1.setDirection(touchgfx::SOUTH);
    listLayoutAlarmList2.setWidthHeight(0,0); //Compensates for the list height that is set to 200 by the designer
    listLayoutAlarmList2.setDirection(touchgfx::SOUTH);
    listLayoutAlarmList3.setWidthHeight(0,0); //Compensates for the list height that is set to 200 by the designer
    listLayoutAlarmList3.setDirection(touchgfx::SOUTH);
    listLayoutAlarmList4.setWidthHeight(0,0); //Compensates for the list height that is set to 200 by the designer
    listLayoutAlarmList4.setDirection(touchgfx::SOUTH);
    listLayoutAlarmList5.setWidthHeight(0,0); //Compensates for the list height that is set to 200 by the designer
    listLayoutAlarmList5.setDirection(touchgfx::SOUTH);

    for(i=0;i<NUMALARMS;i++)
    {
    	switch (presenter->getAlarmPage(i))
    	{
			case 1:
				if(alarm_pg1_cntr<4) //just to make sure we don't put too many on a page
				{
					CustomContainerAlarm *ac = new CustomContainerAlarm();
					ac->setListElements(i, presenter->getAlarmType(i), (int)!presenter->getAlarmEnable(i), presenter->getAlarmPriority(i), presenter->getLimitF(i), presenter->getAlarmDigState(i), presenter->getAlarmDigIn(i), presenter->getAlarmRelay(i));
					ac->setLimitAction(alarmLimitClickedCallback);
					listLayoutAlarmList1.add(*ac);
					alarm_pg1_cntr++;
				}
				break;

 

So how do I "declare" CustomContainerAlarm in ScreenAlarmSetupView?

Hello

I think it should work just like this. I made some changes to list layout example, remove static declaration of listElements

#ifndef MAIN_VIEW_HPP
#define MAIN_VIEW_HPP

#include <gui_generated/main_screen/MainViewBase.hpp>
#include <gui/main_screen/MainPresenter.hpp>
#include <gui/containers/CustomListElement.hpp>

class MainView : public MainViewBase
{
public:
    MainView();
    virtual ~MainView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();

    /**
     * Handler of list element clicks.
     */
    void listElementClicked(CustomListElement& element);

protected:
    //static const int numberOfListElements = 10;
    //CustomListElement listElements[numberOfListElements];

    // Callback that is assigned to each list element
    Callback<MainView, CustomListElement&> listElementClickedCallback;
};

#endif // MAIN_VIEW_HPP

 and add dynamic creator like in your code

#include <gui/main_screen/MainView.hpp>
#include <BitmapDatabase.hpp>

MainView::MainView()
    : listElementClickedCallback(this, &MainView::listElementClicked)
{
}

void MainView::setupScreen()
{
    //list.setHeight(0); //Compensates for the list height that is set to 200 by the designer

   	
	  for(int i=0;i<4;i++)
    {
    	CustomListElement *ac = new CustomListElement();
		ac->setAction(listElementClickedCallback);
		list.add(*ac);
	}
						
}

void MainView::tearDownScreen()
{
}

void MainView::listElementClicked(CustomListElement& element)
{
    // The button of the list element has been pressed
    // so it is removed from the list
    list.remove(element);
    scrollCnt.invalidate();
}

 It works fine.

Maybe you find some difference on your code which causes CustomContainerAlarm to be not declared. Can you show more of your code ?

Br JTP

CYBR
Associate II

Interesting. As far as I can tell my code is identical to yours. However, in trying to resolve this, I had included the following line in the CustomContainerAlarm.hpp file

#include <gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp>

With that present, it throws up these errors compiling the view file, as I explained above.

In file included from ../../TouchGFX/gui/include/gui/containers/CustomContainerAlarm.hpp:6,
                 from C:/TouchGFXProjects/Charge_Cont_V4/TouchGFX/gui/src/containers/CustomContainerAlarm.cpp:1:
../../TouchGFX/gui/include/gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp:23:28: error: 'CustomContainerAlarm' has not been declared
   23 |     void alarmLimitClicked(CustomContainerAlarm& element);
      |                            ^~~~~~~~~~~~~~~~~~~~
../../TouchGFX/gui/include/gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp:36:36: error: 'CustomContainerAlarm' was not declared in this scope; did you mean 'CustomContainerRelay'?
   36 |     Callback<ScreenAlarmSetupView, CustomContainerAlarm&> alarmLimitClickedCallback;
      |                                    ^~~~~~~~~~~~~~~~~~~~
      |                                    CustomContainerRelay
../../TouchGFX/gui/include/gui/screenalarmsetup_screen/ScreenAlarmSetupView.hpp:36:57: error: template argument 2 is invalid
   36 |     Callback<ScreenAlarmSetupView, CustomContainerAlarm&> alarmLimitClickedCallback;
      |                                                         ^
make: *** [Application/User/gui/subdir.mk:103: Application/User/gui/CustomContainerAlarm.o] Error 1
make: *** Waiting for unfinished jobs....

When I delete that line from the CustomContainerAlarm.hpp file, all the errors go away. Don't understand why (some kind of circular reference I guess), but problem solved. Thankyou for your help.

 

Good to hear you got the problem solved. 

Naturally it gives this error because view- class .hpp tries to declare callback-function with alarmContainer as parameter, and alarmContainer is not defined yet in the beginning of alarmContainer.hpp (when view.hpp was included). 

br JTP