@@ 7,11 7,11 @@
namespace gui
{
-
+ /// GridLayout lays out items (widgets) in a grid.
class GridLayout : public BoxLayout
{
protected:
- /// size of singular grid element
+ /// Data container for size of singular grid element
struct GridSize
{
uint32_t x = 0;
@@ 19,35 19,59 @@ namespace gui
} grid;
public:
+ GridLayout(Item *parent,
+ const uint32_t &x,
+ const uint32_t &y,
+ const uint32_t &width,
+ const uint32_t &height,
+ GridSize cellSize);
GridLayout(
- Item *parent, const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h, GridSize grid);
- GridLayout(const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h, GridSize grid)
- : GridLayout(nullptr, x, y, w, h, grid)
+ const uint32_t &x, const uint32_t &y, const uint32_t &width, const uint32_t &height, GridSize cellSize)
+ : GridLayout(nullptr, x, y, width, height, cellSize)
{}
GridLayout() : GridLayout(0, 0, 0, 0, {0, 0})
{}
+ /// Calculates Items position.
+ ///@note It is called when new widgets are added to layout or on resize requests.
+ ///@attention Function does not yet resize items -> only items position are calculated"
void resizeItems() override;
+ /// Sets navigation for layout children (for widgets/items inside layout).
+ ///@note It is called when new widgets are added to layout or on resize requests.
void setNavigation() override;
-
+ /// calculated rows count in grid layout.
uint32_t rowSize = 0;
+ /// calculated columns count in grid layout.
uint32_t colSize = 0;
private:
+ /// function to handle items that do not fit into grid layout area
+ /// @param maxItemsInArea : maximum amount of items that fits into grid size
void handleItemsOutOfGridLayoutArea(uint32_t maxItemsInArea);
- Item *getFirstActiveItem(uint32_t startposition, int step);
+ /// retrieves active item from children items with defined step to next item
+ /// in case when item in startPosition is not active
+ /// @param startPosition : starting point for calculation
+ /// @param step : single step used to search for next item
+ /// @return pointer to active Item or nullptr in case when active Item has not been found
+ Item *getFirstActiveItem(uint32_t startPosition, int step);
+ /// retrieves index of last item in the selected column.
+ ///@param col : column index for which calculation shall be made
+ ///@return calculated last item index for selected column index
inline uint32_t getLastColumnIndex(uint32_t col)
{
- auto lastcolumnindex = col;
- while ((lastcolumnindex + colSize) < children.size())
- lastcolumnindex += colSize;
- return lastcolumnindex;
+ auto lastColumnIndex = col;
+ while ((lastColumnIndex + colSize) < children.size())
+ lastColumnIndex += colSize;
+ return lastColumnIndex;
}
+ /// retrieves index of last item in the selected row.
+ ///@param row : row index for which calculation shall be made
+ ///@return calculated last item index for selected row index
inline uint32_t getLastRowIndex(uint32_t row)
{
- uint32_t lastrowindex = colSize * row + (colSize - 1);
- while (lastrowindex >= children.size())
- lastrowindex--;
- return lastrowindex;
+ uint32_t lastRowIndex = colSize * row + (colSize - 1);
+ while (lastRowIndex >= children.size())
+ lastRowIndex--;
+ return lastRowIndex;
}
};
@@ 32,6 32,7 @@ namespace gui
namespace gui
{
+ /// enumaration that contains gui item types
enum class ItemType
{
ITEM = 0,
@@ 46,25 47,24 @@ namespace gui
VBOX,
HBOX
};
-
+ /// Base class for all GUI items.
+ /// @details It is a basic element for creating widgets and applications
+ /// that make up the GUI (Graphic User Interface) in MuditaOS
class Item
{
- private:
- /// list of timers so that item could have it's timers in itself
- std::list<std::unique_ptr<Timer>> timers;
-
public:
- // flag that informs whether item has a focus
+ /// flag that informs whether item has a focus
bool focus;
/// pointer to the child item that has focus
Item *focusItem = nullptr;
/// item type of the widget - could be used to check what type item we are working on
- /// right now unused except Text, where it calles callback for gui::BoxLayout which does nothing
+ /// right now unused except Text, where it calls callback for gui::BoxLayout which does nothing
ItemType type = ItemType::ITEM;
- // pointer to the parent Item
+ /// pointer to the parent Item
Item *parent = nullptr;
- // list of items that have the same parent.
+ /// list of item's children. @note Items can have only one parent.
std::list<Item *> children;
+ /// enumaration with options for item bounding box (size & position) area
enum class Area
{
Min,
@@ 72,15 72,16 @@ namespace gui
Draw,
Max,
};
- /// actual bounding box of the item. This is in coordinates of the parent widget.
+ /// actual bounding box (size & position) of the item. This is in coordinates of the parent widget.
BoundingBox widgetArea;
- /// bounding box of the item minimum size,
+ /// bounding box (size & position) of the item minimum size,
BoundingBox widgetMinimumArea;
- /// bounding box of the item maximal size,
+ /// bounding box (size & position) of the item maximal size,
BoundingBox widgetMaximumArea;
- // bounding box used for drawing. This is in coordinates of window
+ /// bounding box (size & position) used for drawing. This is in coordinates of window
BoundingBox drawArea; // drawableArea would be more accurate
// maximal bounding box size
+ /// gets bounding box for selected area
auto area(Area which = Area::Normal) -> BoundingBox &
{
switch (which) {
@@ 96,26 97,27 @@ namespace gui
return widgetArea;
}
}
-
Padding padding;
Margins margins;
-
Alignment alignment;
/// radius of corner, default 0
short radius = 0;
- /// flag that defines if item is active
- /// if false -> than it shouldn't be used with onInput, navigation etc.
+
+ /// flag that defines if item is active.
+ /// @details When flag is set to true item is focusable (focus on item can be set)
+ /// and clickable (item action can be activated). Otherwise item is non focusable and non clickable.
+ /// @note if false -> than it shouldn't be used with onInput, navigation etc.
bool activeItem = true;
/// flag that defines whether widget is visible (this is - should be rendered)
bool visible;
- // policy for changing vertical size if Item is placed inside layout
+ /// policy for changing vertical size if Item is placed inside layout.
LayoutVerticalPolicy verticalPolicy;
- // policy for changing horizontal size if Item is placed inside layout
+ /// policy for changing horizontal size if Item is placed inside layout.
LayoutHorizontalPolicy horizontalPolicy;
- // Maximum height to which Layout base widget can scale current widget
+ /// Maximum height to which Layout base widget can scale current widget.
uint16_t maxHeight;
- // Maximum width to which Layout base widget can scale current widget
+ /// Maximum width to which Layout base widget can scale current widget.
uint16_t maxWidth;
/// @defgroup callbacks Item callback functions
@@ 128,23 130,27 @@ namespace gui
/// @{
/// called when item looses/gains focus
+ /// @param `this` : item
std::function<bool(Item &)> focusChangedCallback;
/// called when item has dimensions changed
+ /// @param `this` : item
+ /// @param data : new bounding box area
/// @note should be part of widgetArea
std::function<bool(Item &, BoundingBox data)> dimensionChangedCallback;
/// called when item is activated, this is enter is pressed
- /// @param `this` item
+ /// @param `this` : item
std::function<bool(Item &)> activatedCallback;
/// callback when any key is pressed
- /// @param `this` item
- /// @param `InputEvent`
+ /// @param `this` : item
+ /// @param inputEvent : input event e.g. key pressed
std::function<bool(Item &, const InputEvent &inputEvent)> inputCallback;
/// callback when timer is called on Item and onTimer is executed
- /// @param `this` item
- /// @param `timer` which triggered this callback
+ /// @param `this` : item
+ /// @param `timer` : which triggered this callback
std::function<bool(Item &, Timer &)> timerCallback = nullptr;
- /// callback on navigation, called when item passes navigation to handle by it's children
+ /// callback on navigation, called when item passes navigation to handle by its children
+ /// @param `InputEvent` : input event e.g. key pressed
/// @attention when child handles navigation it should return true, so that parent won't perform action for that
std::function<bool(const InputEvent &)> itemNavigation = nullptr;
@@ 152,76 158,97 @@ namespace gui
/// @defgroup focus functions handling focus
/// @{
+
+ /// navigation handler for input events e.g. keyboard key pressed
+ /// @param inputEvent : input event e.g. key pressed
bool handleNavigation(const InputEvent inputEvent);
- /// sets/resets focus on `this` Item and runs focusChangedCallback for it
+ /// sets/resets focus on this Item and runs focusChangedCallback for it
+ /// @param state : true to set focus on item, false to clear focus from item
bool setFocus(bool state);
- /// sets/resets child with focus in `this` Item
- /// runs focusChangedCallback on item which changes
+ /// sets/resets focus on provided item child if one exists.
+ /// @param item : this
+ /// @note runs focusChangedCallback on item which changes
/// @attention focusItem is just a pointer, might crash if item with focus was removed
void setFocusItem(Item *item);
- /// gettter for focus item
+ /// getter for focus item
/// @attention focusItem is just a pointer, might crash if item with focus was removed
Item *getFocusItem() const;
+
/// @}
/// @defgroup callbackCallers functions which should call functors from callbacks group
/// @{
/// called from setFocus, does nothing (which means it doesn't call focusChangedCallback
+ /// @param state : new focus state
virtual bool onFocus(bool state);
- /// called when `this` Item was pressed with enter (middle key on phone action keys), used for callback input
- /// handling calls activatedCallback
- /// @param[in]: data unused
+ /// called when this Item was pressed with enter (middle key on phone action keys),
+ /// used for callback input handling calls activatedCallback
+ /// @param[in] data : unused
virtual bool onActivated(void *data);
/// called when any key is pressed, before onActivated , after focus
/// calls: inputCallback
+ /// @param InputEvent : input event e.g. key pressed
virtual bool onInput(const InputEvent &inputEvent);
- /// (should be) called each time when dimension of element was changed, added and used only with ListView
- /// calls: none, inconsistent api
+ /// (should be) called each time when dimension of element was changed
+ /// @param oldDim : old bounding box dimensions (item size & position)
+ /// @param newDim : new bounding box dimensions (item size & position)
/// @note TODO should be fixed so that api would be consistent
virtual bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim);
/// called on Timer event in application, triggeres timerCallback
- /// @param timer timer element which triggered this action
+ /// @param : timer timer element which triggered this action
virtual bool onTimer(Timer &timer);
/// @}
/// function called to add child to item
+ /// @param item : pointer to item (widget) that will be added to this item children's
/// similar approach to QT, adding widget will always succeed.
virtual void addWidget(Item *item);
- /// function to remove child item from element
+ /// function to remove child item from element
+ /// @param item : pointer to item (widget) that will be removed from this item children's
/// it's recursive for all elements underneath
- /// @attention It doesn't call `delete` please remove item after calling this function
+ /// @attention It doesn't call delete please remove item after calling this function
virtual bool removeWidget(Item *item);
/// call removeWidget on item and delete on item
+ /// @param item : pointer to item (widget) that will be deleted and removed from this item children's
virtual bool erase(Item *item);
/// remove all children and destroy them
virtual void erase();
/// sets `visible` flag
virtual void setVisible(bool value);
+ /// sets bounding box area (normal) for item
+ /// @param area : new bounding box dimensions (area) for item (item size & position)
virtual void setArea(BoundingBox area);
+ /// function for setting bounding box area (normal) on selected axis
+ /// @param axis : indicates axis X or Y for operation
+ /// @param posOnAxis : new position value for selected axis
+ /// @param posOnOrthogonalAxis : new position for axis orthogonal to selected
+ /// @param sizeOnAxis : new size for selected axis
+ /// @param sizeOnOrthogonalAxis : new size for orthogonal axis to selected
void setAreaInAxis(Axis axis,
uint32_t posOnAxis,
uint32_t posOnOrthogonalAxis,
uint32_t sizeOnAxis,
uint32_t sizeOnOrthogonalAxis);
/// sets position of element - this is sets area().x and area().y of item
- /// calls onDimensionChanged callback & updateDrawArea for item
+ /// @note calls onDimensionChanged callback & updateDrawArea for item
/// @attention should be bind to area
virtual void setPosition(const short &x, const short &y);
virtual void setPosition(const short &val, Axis axis);
[[nodiscard]] uint16_t getSize(Axis axis) const;
[[nodiscard]] uint16_t getPosition(Axis axis) const;
-
virtual void setMargins(const Margins &value);
[[nodiscard]] Margins getMargins();
-
virtual void setPadding(const Padding &value);
[[nodiscard]] Padding getPadding() const;
-
virtual void setAlignment(const Alignment &value);
[[nodiscard]] Alignment &getAlignment();
[[nodiscard]] Alignment getAlignment(Axis axis);
+ /// function to calculate absolute position in selected axis in case of alignment
+ /// @param axis : selected axis (X or Y)
+ /// @param itemSize : size of item on selected axis for this calculation
+ /// @return alignment for selected axis.
[[nodiscard]] virtual uint16_t getAxisAlignmentValue(Axis axis, uint16_t itemSize);
/// @defgroup size_range_setters Named the same way that are in QT minimum/maximum sizes setters
@@ 235,7 262,6 @@ namespace gui
void setMaximumWidth(uint32_t w);
void setMaximumHeight(uint32_t h);
void setMaximumSize(uint32_t w, uint32_t h);
-
void setMinimumSize(uint32_t val, Axis axis);
void setMinimumSize(uint32_t w, uint32_t h);
void setMinimumWidth(uint32_t w);
@@ 246,11 272,11 @@ namespace gui
/// if no parent available - sets size
/// @return true if handled positively
virtual auto requestSize(unsigned short request_w, unsigned short request_h) -> Size final;
- /// handle for layouts to implement to resize on demand ( i.e. when it needs to expand after addition/removal of
- /// chars )
+ /// handle for layouts to implement to resize on demand ( i.e. when it needs to expand after
+ /// addition/removal of chars )
///
- /// by default items do not resize of it's childrem so it's safe for them to pass handleRequestSize
- /// straight to setSize. Layout manages size of it's item in range { Area::Min <= size <= Area::Max } so for
+ /// @details by default items do not resize of their children so it's safe for them to pass handleRequestSize
+ /// straight to setSize. Layout manages size of its item in range { Area::Min <= size <= Area::Max } so in
/// that case layout should to i.e. store request size and than handle resizes appropriately
/// i.e. Text => text->requestSize => layout->storeRequest => layout use it in resizes
/// with this both:
@@ 258,16 284,11 @@ namespace gui
/// 2. resize requests from UI element
/// should be handled without infinite loop on resize ( item->setSize -> notify Layout -> layout: item->setSize
/// )
- ///
/// @return bool requested size granted {w,h}
virtual auto handleRequestResize(const Item *, unsigned short request_w, unsigned short request_h) -> Size;
- /// sets size of item
virtual void setSize(const unsigned short w, const unsigned short h);
void setSize(uint32_t val, Axis axis);
- /// used in ListView to position element sets area() = WidgetArea(params)
- /// calls onDimensionChanged & updateDrwArea
- /// @attention should be bind to area
virtual void setBoundingBox(const BoundingBox &new_box);
/// entry function to create commands to execute in renderer to draw on screen
/// @note we should consider lazy evaluation prior to drawing on screen, rather than on each resize of elements
@@ 276,30 297,45 @@ namespace gui
/// Implementation of DrawList per Item to be drawn on screen
/// This is called from buildDrawList before children elements are added
/// should be = 0;
+ /// @param : commands list of commands for renderer to draw elements on screen
virtual void buildDrawListImplementation(std::list<Command> &commands)
{}
+
+ /// pre hook function, if set it is executed before building draw command
+ /// at Item::buildDrawListImplementation()
+ /// @param `commandlist` : commands list of commands for renderer to draw elements on screen
std::function<void(std::list<Command> &)> preBuildDrawListHook = nullptr;
+ /// post hook function, if set it is executed after building draw command
+ /// at Item::buildDrawListImplementation()
+ /// @param `commandlist` : commands list of commands for renderer to draw elements on screen
std::function<void(std::list<Command> &)> postBuildDrawListHook = nullptr;
- /// sets radius of Item box
+ /// sets radius for item edges
/// @note this should be moved to Rect
virtual void setRadius(int value);
- /// get next navigation item in NavigationDirection
+ /// gets next navigation item in NavigationDirection
+ /// @param direction : navigation direction (LEFT,RIGHT,UP,DOWN)
+ /// @return pointer to next navigation item in selected direction
virtual Item *getNavigationItem(NavigationDirection direction);
- /// set next navigation item in NavigationDirection
+ /// sets navigation item in NavigationDirection
+ /// @param direction : navigation direction (LEFT,RIGHT,UP,DOWN)
+ /// @param item : pointer to next item for selected direction
virtual void setNavigationItem(NavigationDirection direction, Item *item);
- /// clear next navigation item in NavigationDirection
+ /// clears next navigation item in NavigationDirection
+ /// @param direction : navigation direction (LEFT,RIGHT,UP,DOWN)
virtual void clearNavigationItem(gui::NavigationDirection direction);
+ /// item constructor.
Item();
+
Item(Item &) = delete;
+ /// item virtual destructor.
virtual ~Item();
/// @defgroup inconsistent inconsistent size/offset accessors and setters
- /// all this elements should be checked for naming/use consistency
+ /// all these elements should be checked for naming/use consistency
/// possibly all of that should be handled via area() (and area should have callback pinned from Item on resize
/// @{
-
void setX(const int32_t x);
void setY(const int32_t y);
[[nodiscard]] int32_t getX() const
@@ 319,47 355,64 @@ namespace gui
return (widgetArea.h);
}
/// helper function to show where widget ends in x axis
+ /// @return item ends position in X axis
[[nodiscard]] int32_t offset_w() const
{
return getWidth() + widgetArea.x;
}
/// helper function to show where widget ends in y axis
+ /// @return item ends position in Y axis
[[nodiscard]] int32_t offset_h() const
{
return getHeight() + widgetArea.y;
}
+ /// helper function to show where widget ends in selected axis
+ /// @return item ends position in selected axis
[[nodiscard]] int32_t getOffset(Axis axis) const
{
return this->widgetArea.size(axis) + this->widgetArea.pos(axis);
};
/// @}
- /// adds timer to gui item
- /// this is needed so that timer for element would live as long as element lives
+ /// adds timer to GUI item.
+ /// @note this is needed so that timer for element would live as long as element lives.
+ /// @details Timers can be attached to Item
+ /// in order to pass on an ownership of timer to application/widget which uses its functionalities.
void attachTimer(std::unique_ptr<Timer> &&timer)
{
timers.emplace_back(std::move(timer));
}
- /// remove timer from item and as a result - destory it
+ /// remove timer from item and as a result - destory it.
void detachTimer(Timer &timer);
- /// simple check function to determine if item is active && visible
+ /// simple check function to determine if item is active && visible.
+ /// @return true if item is active and visible. Otherwise false.
inline bool isActive()
{
return (activeItem && visible);
}
+ /// @brief
virtual void accept(GuiVisitor &visitor);
protected:
/// On change of position or size this method will recalculate visible part of the widget
/// considering widgets hierarchy and calculate absolute position of drawing primitives.
virtual void updateDrawArea();
+ /// builds draw commands for all of item's children
+ /// @param `commandlist` : commands list of commands for renderer to draw elements on screen
virtual void buildChildrenDrawList(std::list<Command> &commands) final;
/// Pointer to navigation object. It is added when object is set for one of the directions
gui::Navigation *navigationDirections = nullptr;
- };
+ private:
+ /// list of attached timers to item.
+ std::list<std::unique_ptr<Timer>> timers;
+ };
+ /// gets navigation direction (LEFT,RIGHT,UP,DOWN) based on incoming input event
+ /// @param[in] evt : input event e.g. key pressed
NavigationDirection inputToNavigation(const InputEvent &evt);
+ /// checks whether input event is related to GUI navigation directions (LEFT,RIGHT,UP,DOWN)
+ /// @param evt : input event e.g. key pressed
bool isInputNavigation(const InputEvent &evt);
} /* namespace gui */