steering-wheel/TouchGFX/Middlewares/ST/touchgfx/framework/include/touchgfx/Application.hpp

396 lines
13 KiB
C++

/******************************************************************************
* Copyright (c) 2018(-2023) STMicroelectronics.
* All rights reserved.
*
* This file is part of the TouchGFX 4.21.2 distribution.
*
* This software is licensed under terms that can be found in the LICENSE file in
* the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
*******************************************************************************/
/**
* @file touchgfx/Application.hpp
*
* Declares the application class.
*/
#ifndef TOUCHGFX_APPLICATION_HPP
#define TOUCHGFX_APPLICATION_HPP
#include <touchgfx/Drawable.hpp>
#include <touchgfx/UIEventListener.hpp>
#include <touchgfx/events/ClickEvent.hpp>
#include <touchgfx/events/DragEvent.hpp>
#include <touchgfx/events/GestureEvent.hpp>
#include <touchgfx/hal/Config.hpp>
#include <touchgfx/hal/Types.hpp>
#include <touchgfx/lcd/LCD.hpp>
namespace touchgfx
{
class Drawable;
class Screen;
class Transition;
/**
* The Application class is the main interface for manipulating screen contents. It holds a
* pointer to the currently displayed Screen, and delegates draw requests and events to
* that Screen. Additionally it contains some global application settings.
*/
class Application : public UIEventListener
{
public:
/**
* Gets the single instance application.
*
* @return The instance of this application.
*/
static Application* getInstance();
/**
* Gets the current screen.
*
* @return The current screen.
*/
static Screen* getCurrentScreen()
{
return currentScreen;
}
/**
* This function can be called to send your application back to
* the start screen. The simulator will call this function when F5
* is pressed. To make this work, please implement this function
* in FrontendApplication.
*
* @note The application will not make a complete restart - if
* your Model contains data, this will not be reset, unless
* this is explicitly done in your
* FrontendApplication::changeToStartScreen().
*/
virtual void changeToStartScreen()
{
}
/**
* Switch to another Screen. Will call tearDownScreen on current Screen before switching,
* and subsequently call setupScreen and draw automatically for the new Screen.
*
* @param [in] newScreen A pointer to the new screen.
*/
virtual void switchScreen(Screen* newScreen);
/**
* An application specific function for switching screen. Overloading this can provide a
* means to switch screen from places that does not have access to a pointer to the new
* screen. Base implementation is empty.
*
* @param screenId An id that maps to the desired screen.
*/
virtual void appSwitchScreen(uint8_t screenId)
{
(void)screenId; // Unused variable
}
/** An application specific function for requesting redraw of entire screen. */
virtual void requestRedraw();
/**
* An application specific function for requesting redraw of given Rect.
*
* @param [in,out] rect The Rect that must be redrawn.
*/
virtual void requestRedraw(Rect& rect)
{
redraw = rect;
}
/**
* Handle a click event. Standard implementation is to delegate the event to the current
* screen. Called by the framework when a click is detected by some platform specific
* means.
*
* @param event The ClickEvent.
*/
virtual void handleClickEvent(const ClickEvent& event);
/**
* Handle drag events. Called by the framework when a drag is detected by some platform
* specific means. Standard implementation is to delegate drag event to current screen.
*
* @param event The drag event, expressed in absolute coordinates.
*/
virtual void handleDragEvent(const DragEvent& event);
/**
* Handle gestures. Called by the framework when a gesture is detected by some platform
* specific means. Standard implementation is to delegate drag event to current screen.
*
* @param event The gesture event.
*/
virtual void handleGestureEvent(const GestureEvent& event);
/**
* Handle tick. Standard implementation is to delegate tick to the widgets that have
* registered to receive one. Called by some platform specific means.
*/
virtual void handleTickEvent();
/**
* Handle an incoming character received by the HAL layer. Standard implementation
* delegates to current screen (which, in turn, does nothing).
*
* @param c The incoming character to handle.
*/
virtual void handleKeyEvent(uint8_t c);
/**
* Evaluates the pending Callback instances. If a callback is valid, it is executed and
* a Screen transition is executed. This base implementation is empty and does nothing.
*/
virtual void handlePendingScreenTransition();
/**
* Clears the cached areas so coming calls to invalidate are collected for future drawing.
*
* @see drawCachedAreas
*/
virtual void clearCachedAreas();
/**
* Draws all cached, invalidated areas on the screen.
*
* @see clearCachedAreas
*/
virtual void drawCachedAreas();
/**
* This function copies the parts that were updated in the
* previous frame (in the TFT buffer) to the active framebuffer
* (client buffer).
*
* This function only copies pixels in double buffering mode.
*/
void copyInvalidatedAreasFromTFTToClientBuffer();
/**
* Adds a widget to the list of widgets receiving ticks every frame (typically
* 16.67ms)
*
* @param [in] w The widget to add.
*
* @see unregisterTimerWidget
*
* @note The framework keeps track of the number of times a specific widget is registered.
*/
void registerTimerWidget(Drawable* w)
{
timerWidgets.add(w);
}
/** Clears all currently registered timer widgets. */
void clearAllTimerWidgets()
{
timerWidgets.clear();
}
/**
* Removes a widget from the list of widgets receiving ticks every frame (typically
* 16.67ms) milliseconds.
*
* @param [in] w The widget to remove.
*
* @note If widget has been registered multiple times, an equal number of calls to unregister
* are required to stop widget from receiving tick events.
*/
void unregisterTimerWidget(const Drawable* w)
{
timerWidgets.remove(w);
}
/**
* gets the number of timer widgets that are registered and active.
*
* @return The size of timerWidgets.
*/
uint16_t getNumberOfRegisteredTimerWidgets() const
{
return timerWidgets.getNumberOfActiveTimerWidgets();
}
/**
* Gets the number of timer events registered to a widget, i.e. how many times a
* drawable must be unregistered until it no longer receives timer ticks.
*
* @param w The widget to to get count from.
*
* @return 0 if the drawable is not registered as a timer widget, otherwise returns how
* many times the drawable is currently registered.
*/
uint16_t getTimerWidgetCountForDrawable(const Drawable* w) const
{
return timerWidgets.getCounter(w);
}
static const uint8_t MAX_TIMER_WIDGETS = 32; ///< Maximum number of widgets receiving ticks. @remarks Memory impact: x * (sizeof(Drawable*)+1)
static const uint16_t TICK_INTERVAL_MS = 10; ///< Deprecated, do not use this constant. Tick interval depends on VSYNC of your target platform.
/**
* Sets the DebugPrinter object to be used by the application to print debug messages.
*
* @param [in] printer The debug printer to configure.
*/
static void setDebugPrinter(DebugPrinter* printer)
{
debugPrinter = printer;
}
/**
* Returns the DebugPrinter object associated with the application.
*
* @return DebugPrinter The DebugPrinter object.
*/
static DebugPrinter* getDebugPrinter()
{
return debugPrinter;
}
/**
* Sets the debug string to be displayed onscreen on top of the framebuffer.
*/
static void invalidateDebugRegion()
{
if (debugPrinter)
{
debugRegionInvalidRect.expandToFit(debugPrinter->getRegion());
}
}
/**
* Sets the debug string to be displayed onscreen on top of the framebuffer.
*
* @param [in] string The debug string to display onscreen.
*/
static void setDebugString(const char* string)
{
if (debugPrinter)
{
debugPrinter->setString(string);
invalidateDebugRegion();
}
}
/**
* Invalidates the entire screen.
*
* @param area The area to invalidate.
*/
void invalidate();
/**
* Invalidates the given area.
*
* @param area The area to invalidate.
*/
void invalidateArea(Rect area);
protected:
/** Protected constructor. */
Application();
/**
* Initiate a draw operation of the entire screen. Standard implementation is to
* delegate draw request to the current Screen.
*/
virtual void draw();
/**
* Initiate a draw operation of the specified region of the screen. Standard
* implementation is to delegate draw request to the current Screen.
*
* @param [in] rect The area to draw.
*
* @note Unlike Widget::draw this is safe to call from user code as it will properly traverse
* widgets in z-order.
* @note The coordinates given must be absolute coordinates.
*/
virtual void draw(Rect& rect);
typedef Vector<Rect, 8> RectVector_t; ///< Type to ensure the same number of rects are in the Vector
/** A class to handle and manage timer widgets. */
class TimerWidgets
{
public:
/**
* Tick all active timer widgets. Adding and removing timer widgets during ticks is supported.
*/
void tickActive();
/**
* Adds timer widget. If a timer widget is added from a handleTickEvent(), the timer will not be
* ticket until the next tick (unless that same widget is already registered, and has not yet
* been ticked in this tick).
*
* @param [in] w The timer widget to add.
*/
void add(Drawable* w);
/**
* Removes the given timer widget.
*
* @param w The timer widget to remove.
*/
void remove(const Drawable* w);
/** Clears all timer widgets. */
void clear();
/**
* Gets a counter for a given timer widget. Normally the counter is 1 unless a timer widget has
* been registered several times.
*
* @param w The timer widget to get the counter for.
*
* @return The counter.
*/
uint16_t getCounter(const Drawable* w) const;
/**
* Gets number of active timer widgets.
*
* @return The number of active timer widgets.
*/
uint16_t getNumberOfActiveTimerWidgets() const;
/**
* Compacts the timer widgets. All widgets with a counter of 0 will be removed from the list,
* and the list will be compacted. Compacting the timer widgets during traversal (in
* tickActive()) is handled properly.
*/
void compact();
private:
Vector<Drawable*, MAX_TIMER_WIDGETS> widgets; ///< List of widgets that receive timer ticks.
uint8_t counters[MAX_TIMER_WIDGETS]; ///< A counter for each potentially registered timer widget. Increase when registering for timer events, decrease when unregistering.
uint16_t currentWidget; ///< The current widget, used in tickActive().
uint16_t lastWidget; ///< The last widget, used in tickActive().
} timerWidgets; ///< The timer widgets
RectVector_t cachedDirtyAreas; ///< When draw caching is enabled, these rects keeps track of the dirty screen area.
RectVector_t lastRects; ///< The dirty areas from last frame that needs to be redrawn because we have swapped frame buffers.
Rect redraw; ///< Rect describing application requested invalidate area
bool transitionHandled; ///< True if the transition is done and Screen::afterTransition has been called.
static Screen* currentScreen; ///< Pointer to currently displayed Screen.
static Transition* currentTransition; ///< Pointer to current transition.
static Application* instance; ///< Pointer to the instance of the Application-derived subclass. @note Must be set by subclass constructor!
static DebugPrinter* debugPrinter; ///< Pointer to the DebugPrinter instance.
static Rect debugRegionInvalidRect; ///< Invalidated Debug Region
};
} // namespace touchgfx
#endif // TOUCHGFX_APPLICATION_HPP