cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple screens to share post-processing behavior

jchernus-fikst
Associate III

Hi there,

I'm curious how other folks handle this situation:

Presently, I have a number of screens that all complete some hardware process (ex. move motors) and then navigate back to the Home screen. I'm introducing some additional logic that, across all such screens, would add a conditional to determine what next screen to display (ex. Critical Battery screen if battery is low, ... , with the Home screen being the 'else' option should none of the other conditions be satisfied).

I don't want to duplicate and maintain this logic across all of the screens - where is a good place to put this? 

Thanks,

Julia

1 ACCEPTED SOLUTION

Accepted Solutions
Marc_LM
Senior

I checked into this at some point and the best place to put logic like that was inside the handleTickEvent inside the 
FrontendApplication.cpp. 

(1) dynamic startup screen:
https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/changing-screen-programatically/m-p/772635

(2) Save MVP into model:
https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/passing-references-from-screen-to-model/m-p/777461 

(3) Formal MVP (don't do it*):
https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/persistent-widgets-between-screens/m-p/690244

View solution in original post

4 REPLIES 4
ahsrabrifat
Senior II

Centralize your logic in one place (function, service, or manager), and have each screen delegate the post-process navigation decision to it.

Right, you correctly re-described what I'm looking to do. I am looking for some more guidance (an example) of how to do that best.

Option 1. Add this logic to the Model, and in the View call model->navigateToNextScreen(); which figures out where to go and sends that upstream like so:

void Model::navigateToNextScreen()
{
    if (batteryIsLow()) {
        modelListener->goToCriticalBatteryScreen();
    } else {
        modelListener->goToHomeScreen();
    }
}

Then do I implement those in each Presenter or in FrontendApplication?


Option 2. Create a new NavigationController.cpp file in `...\Project\CM7\TouchGFX\gui\src`, and put all of the logic there, and implement a navigation listener. Presenter calls the NavController, which figures out where to go, and the presenter inherits the NavListener and implements the screen change?

 

There are probably other options. This is my first TouchGFX project and I'm not sure I have enough forward-thinking to evaluate which option is best. I was hoping someone could share their wisdom and experience!

Thanks,

Julia

Marc_LM
Senior

I checked into this at some point and the best place to put logic like that was inside the handleTickEvent inside the 
FrontendApplication.cpp. 

(1) dynamic startup screen:
https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/changing-screen-programatically/m-p/772635

(2) Save MVP into model:
https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/passing-references-from-screen-to-model/m-p/777461 

(3) Formal MVP (don't do it*):
https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/persistent-widgets-between-screens/m-p/690244

jchernus-fikst
Associate III

Thanks, I did as you suggested and added the logic into FrontendApplication.cpp:

 

 

 
#include <gui/common/FrontendApplication.hpp>
#include <gui/common/SystemStates.hpp>
#include <gui/common/SystemConstants.hpp>

void FrontendApplication::handleTickEvent()
{
    model.tick();
    FrontendApplicationBase::handleTickEvent();

    /* CRITICAL BATTERY CHECK */
    static uint32_t tick_counter = 0;

    // Start with critical state because the splashScreen already handles navigating
    // to the criticalBatteryScreen on boot, so we don't need to duplicate the call.
    static BatteryState previous_battery_state = BatteryState::BATTERY_CRITICAL;

    tick_counter++;
    if (tick_counter >= DELAY_BETWEEN_CRITICAL_BATTERY_CHECKS_TICKS)
    {
        tick_counter = 0;
        Battery battery = model.getBattery();
        if (battery.state == BatteryState::BATTERY_CRITICAL && battery.state != previous_battery_state)
        {
            // If the battery just became critical, navigate to the critical battery screen
            gotocriticalBatteryScreenNoTransition();
        }
        previous_battery_state = battery.state;
    }
    /* END OF CRITICAL BATTERY CHECK */
}

FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)
    : FrontendApplicationBase(m, heap)
{

}