The Screen concept
In TouchGFX applications you can have any number of “screens”. A screen in TouchGFX is a logical grouping of UI elements (widgets) and their associated business logic. A screen consists of two classes: a View class containing all the widgets that are shown on this screen, and a Presenter containing business logic for this screen.
You can choose to implement your entire application within the context of a single screen (meaning you only have one View and one Presenter), but we recommend splitting unrelated parts of your UI into different screens, for two reasons:
1. TouchGFX includes a memory allocation scheme that automatically allocates the necessary RAM needed for the most RAM-consuming screen. Only this amount will be allocated, and this RAM block is reused across all screens in your application.
2. Having several screens makes your UI code much easier to maintain.
There are no exact rules as to how your application should be divided into screens, but there are certain guidelines that might assist you in deciding what screens should make up your specific application. Areas of the UI that are visually and functionally unrelated should be kept in different screens. If you consider a very simple thermostat application which has a main temperature readout display and a configuration menu, it would be a good idea to create a “Main Screen” for the temperature readout and a “Settings Screen” for showing the configuration menu. The View for the Main Screen would contain widgets for a background image, a few text areas for showing temperature and a button for switching to the configuration menu. The View for the configuration on the other hand would probably contain widgets for showing a list of configuration options and a different background image. If the configuration menu is capable of editing many different types of settings (dates, names with keyboard, temperatures, units etc.), this screen will grow large in complexity. In that case it might be beneficial to further divide the configuration menu into one screen showing the overall tree of menu options, and a different screen for editing a specific value. But this is something you will learn as your project progresses.
Because TouchGFX is implemented in C++ you have the option of taking advantage of object-oriented paradigms in your screens. If for instance all your screens need to display a status bar at the top, showing current time, battery level, et cetera you can create a base view class containing the status bar only and have all your views deriving from this class, so you get the status bar functionality automatically.
Currently active screen
Because of the way TouchGFX allocates memory for screens (only allocating for biggest View and biggest Presenter), only one View and one Presenter can be active at a time. So if your thermostat application is displaying the temperature readout, then the configuration menu screen is not running anywhere, and in fact is not even allocated.
If events are received from the “backend” (all your non-UI code that does the actual work of the thermostat) or from hardware peripherals, then these events can be delegated to the currently active screen. This provides a useful separation of concerns because some events will be of interest only to certain screens in your application. For instance, a received event notifying of a change in current temperature could be handled only by the main screen (which would update the text area showing current temperature), whereas the configuration screen could simply discard this event as it is of no interest since current temperature is not being displayed in this screen.
Model-View-Presenter (MVP) is a common way of dividing responsibilites in UI applications. It separates the concerns of setting up the graphical elements UI, reacting to changes and maintaining UI state permanently.
How the TouchGFX screen concept ties into the overall Model-View-Presenter architecture is illustrated in the following figure:
The Model class is a singleton which is always alive and has two purposes:
1. Store state information for the UI. The Views and Presenters are deallocated when switching screen, so they cannot be used to store information which should be kept across screen transitions. Use the Model for this instead.
2. Act as an interface towards the backend system, relaying events to and from the currently active screen.
The Model class is automatically setup to have a pointer to the currently active presenter. When changes occur in the Model the current active Presenter is notified of the change. This is done via methods in the ModelListener interface in the application.
More information and examples of how to communicate between the Model Class, the Backend and the current screen can be found in this article: Connecting the UI to your system
The View class (or more specifically, a user-defined class that derives from the TouchGFX View class) contains the widgets that are shown in this view as member objects. It also contains a
setupScreen and a
tearDownScreen function, which gets automatically called when this screen is entered/exited. Typically you would configure your widgets in the
Your View will also contain a pointer to the associated Presenter. This pointer is setup automatically by the framework. Using this pointer you can communicate UI events like button clicks to the Presenter.
The Presenter class (again, a user-defined class that derives from the TouchGFX Presenter class) is responsible for the business logic of the currently active screen. It will receive “backend” events from the Model, and UI events from the View and decide which action to take. For instance, if an alarm event is received from the Model, the Presenter might decide to tell the View that an alarm popup dialog should be displayed.
TouchGFX has a screen transition mechanism which makes it possible to animate the transition from one screen to another. The builtin transitions are
NoTransition which provides an instant switch from one screen to another, and
SlideTransition which will slide in the new screen either horizontally or vertically. It is quite easy to create your own custom transitions if needed.
- See the custom_transition_example for implementation of a custom transition.