diff --git a/src/modm/ui/display/color_graphic_display.hpp b/src/modm/ui/display/color_graphic_display.hpp index 5e9d1e4d2d..2647f1b01b 100644 --- a/src/modm/ui/display/color_graphic_display.hpp +++ b/src/modm/ui/display/color_graphic_display.hpp @@ -5,8 +5,6 @@ #include "graphic_display.hpp" -using namespace modm::platform; - namespace modm { diff --git a/src/modm/ui/gui/view.cpp b/src/modm/ui/gui/view.cpp index 75c5389d8c..1fd4c505f1 100644 --- a/src/modm/ui/gui/view.cpp +++ b/src/modm/ui/gui/view.cpp @@ -18,9 +18,10 @@ // ---------------------------------------------------------------------------- modm::gui::View::View(modm::gui::GuiViewStack* stack, uint8_t identifier, modm::gui::Dimension dimension) : - AbstractView(stack, identifier), stack(stack), - dimension(dimension) + dimension(dimension), + identifier(identifier), + alive(true) { this->display().clear(); } @@ -161,3 +162,9 @@ void modm::gui::View::markDrawn() (*iter)->markDrawn(); } } + +modm::ColorGraphicDisplay& +modm::gui::View::display() +{ + return stack->getDisplay(); +} diff --git a/src/modm/ui/gui/view.hpp b/src/modm/ui/gui/view.hpp index 69d02fcca3..91a41f112a 100644 --- a/src/modm/ui/gui/view.hpp +++ b/src/modm/ui/gui/view.hpp @@ -41,7 +41,7 @@ class GuiViewStack; * @ingroup modm_ui_gui * @author Thorsten Lajewski */ -class View : public modm::AbstractView +class View { friend class GuiViewStack; @@ -61,6 +61,14 @@ class View : public modm::AbstractView virtual void update(); + /** + * @brief hasChanged indicates the current displayed view has changed. + * This function prevents unnecessary drawing of the display + * @return if true the display has to be redrawn. + */ + virtual bool + hasChanged() = 0; + virtual void preUpdate() { @@ -75,14 +83,43 @@ class View : public modm::AbstractView virtual void draw(); + /** + * @brief shortButtonPress handle the action for the pressed button + */ + virtual void + shortButtonPress(modm::MenuButtons::Button /*button*/) + { + // nothing to be done + } + /// Add widget to view bool pack(Widget *w, const modm::glcd::Point &coord); + /** + * @brief isAlive tells the ViewStack if it should remove this screen. + * @return + */ + bool + isAlive() const + { + return this->alive; + } + /// Remove the view from the screen. The viewStack handles the deletion. void remove(); + /** + * @brief onRemove will be called right before the view gets deleted, + * can be reimplemented to reset external data. + */ + virtual void + onRemove() + { + // nothing to be done here + } + /// Set color palette for every contained widget void setColorPalette(ColorPalette& cp); @@ -105,12 +142,25 @@ class View : public modm::AbstractView return stack; } + modm::ColorGraphicDisplay& + display(); + + /** + * @brief getIdentifier of the view. + */ + inline uint8_t getIdentifier(){ + return this->identifier; + } + protected: modm::gui::GuiViewStack* stack; Dimension dimension; WidgetContainer widgets; modm::gui::ColorPalette colorpalette; + + const uint8_t identifier; + bool alive; }; } // namespace gui diff --git a/src/modm/ui/gui/view_stack.cpp b/src/modm/ui/gui/view_stack.cpp index de116a93fc..a5e1b614d3 100644 --- a/src/modm/ui/gui/view_stack.cpp +++ b/src/modm/ui/gui/view_stack.cpp @@ -20,7 +20,7 @@ // ---------------------------------------------------------------------------- modm::gui::GuiViewStack::GuiViewStack(modm::ColorGraphicDisplay* display, modm::gui::inputQueue* queue) : - ViewStack(display), + display(display), input_queue(queue) { } diff --git a/src/modm/ui/gui/view_stack.hpp b/src/modm/ui/gui/view_stack.hpp index 308ce0085d..18c90e9c07 100644 --- a/src/modm/ui/gui/view_stack.hpp +++ b/src/modm/ui/gui/view_stack.hpp @@ -41,7 +41,7 @@ namespace gui * @ingroup modm_ui_gui * @author Thorsten Lajewski */ -class GuiViewStack : public modm::ViewStack +class GuiViewStack { public: GuiViewStack(modm::ColorGraphicDisplay* display, modm::gui::inputQueue* queue); @@ -84,7 +84,29 @@ class GuiViewStack : public modm::ViewStack virtual void update(); + /** + * @brief shortButtonPress pass the button press to the current top view + * @param button the pressed button + */ + + void + shortButtonPress(modm::MenuButtons::Button button) + { + modm::gui::View* top = this->get(); + top->shortButtonPress(button); + } + + /** + * @brief getDisplay access underlying GraphicDisplay + */ + inline modm::ColorGraphicDisplay& + getDisplay() + { + return *this->display; + } + private: + modm::ColorGraphicDisplay *display; modm::Stack< modm::gui::View* , modm::LinkedList< modm::gui::View* > > stack; modm::gui::inputQueue *input_queue; }; diff --git a/src/modm/ui/menu/abstract_menu.cpp b/src/modm/ui/menu/abstract_menu.cpp deleted file mode 100644 index 146cf54108..0000000000 --- a/src/modm/ui/menu/abstract_menu.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2011, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * Copyright (c) 2013, Kevin Läufer - * Copyright (c) 2013, Thorsten Lajewski - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#include "abstract_menu.hpp" - -modm::AbstractMenu::AbstractMenu(modm::ViewStack* stack, uint8_t identifier): - modm::AbstractView(stack, identifier) -{ -} diff --git a/src/modm/ui/menu/abstract_menu.hpp b/src/modm/ui/menu/abstract_menu.hpp index 346744e3e8..78cafc0bac 100644 --- a/src/modm/ui/menu/abstract_menu.hpp +++ b/src/modm/ui/menu/abstract_menu.hpp @@ -30,12 +30,17 @@ namespace modm{ * \author Thorsten Lajewski * \ingroup modm_ui_menu */ - class AbstractMenu: public AbstractView + template > + class AbstractMenu : public AbstractView { public: - AbstractMenu(modm::ViewStack* stack, uint8_t identifier); + AbstractMenu(modm::ViewStack* stack, uint8_t identifier) : + modm::AbstractView(stack, identifier) + { + } + virtual ~AbstractMenu() {} virtual void shortButtonPress(modm::MenuButtons::Button button) = 0; diff --git a/src/modm/ui/menu/abstract_view.cpp b/src/modm/ui/menu/abstract_view.cpp deleted file mode 100644 index 96b5ba6e05..0000000000 --- a/src/modm/ui/menu/abstract_view.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2011, Fabian Greif - * Copyright (c) 2010-2011, 2013, Georgi Grinshpun - * Copyright (c) 2013, Kevin Läufer - * Copyright (c) 2013, Thorsten Lajewski - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#include "view_stack.hpp" -#include "abstract_view.hpp" - -// ---------------------------------------------------------------------------- -modm::AbstractView::AbstractView(modm::ViewStack* stack, uint8_t identifier) : - stack(stack), identifier(identifier), alive(true) -{ -} - -modm::AbstractView::~AbstractView() -{ -} - -// ---------------------------------------------------------------------------- -void -modm::AbstractView::update() -{ - //nothing to be done -} - -// ---------------------------------------------------------------------------- -void -modm::AbstractView::shortButtonPress(modm::MenuButtons::Button /*button*/) -{ - //nothing to be done -} - -// ---------------------------------------------------------------------------- -bool -modm::AbstractView::isAlive() const -{ - return this->alive; -} - -void -modm::AbstractView::remove() -{ - this->alive = false; -} - -void -modm::AbstractView::onRemove() -{ - //nothing to be done here -} - -// ---------------------------------------------------------------------------- - -modm::ColorGraphicDisplay& -modm::AbstractView::display() -{ - return stack->getDisplay(); -} diff --git a/src/modm/ui/menu/abstract_view.hpp b/src/modm/ui/menu/abstract_view.hpp index 42a141d5ec..e01eae6f30 100644 --- a/src/modm/ui/menu/abstract_view.hpp +++ b/src/modm/ui/menu/abstract_view.hpp @@ -5,6 +5,7 @@ * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski * Copyright (c) 2014, Sascha Schade + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -17,13 +18,14 @@ #ifndef MODM_ABSTRACT_VIEW_HPP #define MODM_ABSTRACT_VIEW_HPP -#include +#include -#include "menu_buttons.hpp" +#include "iabstract_view.hpp" namespace modm { // forward declaration + template class ViewStack; /** @@ -34,8 +36,10 @@ namespace modm *\ingroup modm_ui_menu */ - class AbstractView + template > + class AbstractView : public IAbstractView { + template friend class ViewStack; public: @@ -44,83 +48,27 @@ namespace modm * @param identifier can be used to determine which screen is the currently * displayed on the graphicDisplay */ - AbstractView(modm::ViewStack* stack, uint8_t identifier); - - virtual ~AbstractView() = 0; - - /** - * @brief update The update function of the top most display gets called - * as often as possible. Only the update of the top view in each - * ViewStack gets called. - */ - virtual void - update(); - - /** - * @brief hasChanged indicates the current displayed view has changed. - * This function prevents unnecessary drawing of the display - * @return if true the display has to be redrawn. - */ - virtual bool - hasChanged() = 0; - - /** - * @brief draw determine the output on the Graphic Display - */ - virtual void - draw() = 0; - - - /** - * @brief shortButtonPress handle the action for the pressed button - */ - virtual void - shortButtonPress(modm::MenuButtons::Button button); - - /** - * @brief isAlive tells the ViewStack if it should remove this screen. - * @return - */ - bool - isAlive() const; - - /** - * @brief remove the view from the screen. The viewStack handles the deletion. - */ - void - remove(); - - /** - * @brief getIdentifier of the view. - */ - inline uint8_t getIdentifier(){ - return this->identifier; + AbstractView(modm::ViewStack* stack, uint8_t identifier) : + IAbstractView(identifier), stack(stack) + { } - public: - - modm::ColorGraphicDisplay& - display(); + virtual ~AbstractView() = default; - /** - * @brief onRemove will be called right before the view gets deleted, - * can be reimplemented to reset external data. - */ - virtual void - onRemove(); - - inline modm::ViewStack* + inline modm::ViewStack* getViewStack() { return stack; } - private: - modm::ViewStack* stack; + modm::GraphicDisplay& + display() + { + return stack->getDisplay(); + } - public: - const uint8_t identifier; - bool alive; + private: + modm::ViewStack* stack; }; } diff --git a/src/modm/ui/menu/choice_menu.hpp b/src/modm/ui/menu/choice_menu.hpp index b1ab6e73f5..a4882748c4 100644 --- a/src/modm/ui/menu/choice_menu.hpp +++ b/src/modm/ui/menu/choice_menu.hpp @@ -2,6 +2,7 @@ * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski * Copyright (c) 2015, Niklas Hauser + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -37,13 +38,14 @@ namespace modm{ * \ingroup modm_ui_menu * */ - class ChoiceMenu: public AbstractMenu + template > + class ChoiceMenu : public AbstractMenu { public: - ChoiceMenu(modm::ViewStack* stack, uint8_t identifier); + ChoiceMenu(modm::ViewStack* stack, uint8_t identifier); - ChoiceMenu(modm::ViewStack* stack, uint8_t identifier, const char* title); + ChoiceMenu(modm::ViewStack* stack, uint8_t identifier, const char* title); /** * @brief addEntry a new entry to the ChoiceMenu @@ -112,4 +114,6 @@ namespace modm{ }; } +#include "choice_menu_impl.hpp" + #endif /* CHOICE_MENU_HPP*/ diff --git a/src/modm/ui/menu/choice_menu.cpp b/src/modm/ui/menu/choice_menu_impl.hpp similarity index 72% rename from src/modm/ui/menu/choice_menu.cpp rename to src/modm/ui/menu/choice_menu_impl.hpp index d8cb4a192c..31e886d604 100644 --- a/src/modm/ui/menu/choice_menu.cpp +++ b/src/modm/ui/menu/choice_menu_impl.hpp @@ -2,6 +2,7 @@ * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski * Copyright (c) 2015, Niklas Hauser + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -11,11 +12,15 @@ */ // ---------------------------------------------------------------------------- -#include "choice_menu.hpp" +#ifndef CHOICE_MENU_HPP +# error "Don't include this file directly, use choice_menu.hpp instead!" +#endif +#include "abstract_view.hpp" -modm::ChoiceMenu::ChoiceMenu(modm::ViewStack* stack, uint8_t identifier) : - modm::AbstractMenu(stack, identifier), +template +modm::ChoiceMenu::ChoiceMenu(modm::ViewStack* stack, uint8_t identifier) : + modm::AbstractMenu(stack, identifier), display_update_time(500), timer(display_update_time), buttonAction(false), @@ -23,11 +28,12 @@ modm::ChoiceMenu::ChoiceMenu(modm::ViewStack* stack, uint8_t identifier) : homePosition(0), position(0) { - this->maximalDrawnEntrys = (getViewStack()->getDisplay().getHeight()- 16) / 8 ; + this->maximalDrawnEntrys = (this->getViewStack()->getDisplay().getHeight()- 16) / 8 ; } -modm::ChoiceMenu::ChoiceMenu(modm::ViewStack* stack, uint8_t identifier, const char* title) : - modm::AbstractMenu(stack, identifier), +template +modm::ChoiceMenu::ChoiceMenu(modm::ViewStack* stack, uint8_t identifier, const char* title) : + modm::AbstractMenu(stack, identifier), display_update_time(500), timer(display_update_time), buttonAction(false), @@ -35,19 +41,19 @@ modm::ChoiceMenu::ChoiceMenu(modm::ViewStack* stack, uint8_t identifier, const c homePosition(0), position(0) { - this->maximalDrawnEntrys = (getViewStack()->getDisplay().getHeight()- 16) / 8 ; + this->maximalDrawnEntrys = (this->getViewStack()->getDisplay().getHeight()- 16) / 8 ; } -void -modm::ChoiceMenu::addEntry(const char* text, bool *valuePtr, bool defaultValue) +template void +modm::ChoiceMenu::addEntry(const char* text, bool *valuePtr, bool defaultValue) { - static uint16_t availableSpace = (getViewStack()->getDisplay().getWidth()-16)/6-6; + static uint16_t availableSpace = (this->getViewStack()->getDisplay().getWidth()-16)/6-6; modm::ChoiceMenuEntry entry(text, availableSpace, valuePtr, defaultValue); this->entries.append(entry); } -void -modm::ChoiceMenu::initialise() +template void +modm::ChoiceMenu::initialise() { EntryList::iterator iter = this->entries.begin(); for(; iter!= this->entries.end(); ++iter){ @@ -62,17 +68,16 @@ modm::ChoiceMenu::initialise() } } -void -modm::ChoiceMenu::setTitle(const char* text) +template void +modm::ChoiceMenu::setTitle(const char* text) { this->title = text; } - -void -modm::ChoiceMenu::draw() +template void +modm::ChoiceMenu::draw() { - modm::ColorGraphicDisplay* display = &getViewStack()->getDisplay(); + modm::GraphicDisplay* display = &this->getViewStack()->getDisplay(); display->clear(); display->setCursor(0,2); (*display) << this->title; @@ -115,8 +120,8 @@ modm::ChoiceMenu::draw() // TODO wenn möglich pfeil nach oben und nach unten einfügen } -bool -modm::ChoiceMenu::hasChanged() +template bool +modm::ChoiceMenu::hasChanged() { if (timer.execute() || this->buttonAction) { @@ -130,9 +135,8 @@ modm::ChoiceMenu::hasChanged() } } - -void -modm::ChoiceMenu::shortButtonPress(modm::MenuButtons::Button button) +template void +modm::ChoiceMenu::shortButtonPress(modm::MenuButtons::Button button) { switch(button) { diff --git a/src/modm/ui/menu/communicating_view.hpp b/src/modm/ui/menu/communicating_view.hpp index 4201321b7f..1a06a194f5 100644 --- a/src/modm/ui/menu/communicating_view.hpp +++ b/src/modm/ui/menu/communicating_view.hpp @@ -5,6 +5,7 @@ * Copyright (c) 2012-2013, 2017-2018, Niklas Hauser * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -24,18 +25,19 @@ namespace modm { /// @ingroup modm_ui_menu + template > class CommunicatingView : public xpcc::Communicatable { public: - CommunicatingView(modm::CommunicatingViewStack* /*stack*/) + CommunicatingView(modm::CommunicatingViewStack* /*stack*/) { } protected: - inline modm::CommunicatingViewStack* - getCommunicatingViewStack(modm::ViewStack* viewStack) + inline modm::CommunicatingViewStack* + getCommunicatingViewStack(modm::ViewStack* viewStack) { - return static_cast(viewStack); + return static_cast*>(viewStack); } }; } diff --git a/src/modm/ui/menu/communicating_view_stack.hpp b/src/modm/ui/menu/communicating_view_stack.hpp index 9f1c5cf7ed..f8d96fa1ef 100644 --- a/src/modm/ui/menu/communicating_view_stack.hpp +++ b/src/modm/ui/menu/communicating_view_stack.hpp @@ -6,6 +6,7 @@ * Copyright (c) 2012-2013, 2017-2018, Niklas Hauser * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -26,11 +27,12 @@ namespace modm { /// @ingroup modm_ui_menu - class CommunicatingViewStack : public ViewStack + template > + class CommunicatingViewStack : public ViewStack { public: - CommunicatingViewStack(modm::ColorGraphicDisplay* display, xpcc::Communicator* communicator) : - ViewStack(display), + CommunicatingViewStack(modm::GraphicDisplay* display, xpcc::Communicator* communicator) : + ViewStack(display), communicator(communicator) { } diff --git a/src/modm/ui/menu/iabstract_view.hpp b/src/modm/ui/menu/iabstract_view.hpp new file mode 100644 index 0000000000..dccaf210ca --- /dev/null +++ b/src/modm/ui/menu/iabstract_view.hpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020, Matthew Arnold + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_IABSTRACT_VIEW_HPP +#define MODM_IABSTRACT_VIEW_HPP + +#include + +#include "menu_buttons.hpp" + +namespace modm +{ + // forward declaration + template + class ViewStack; + + class IAbstractView + { + public: + template + friend class ViewStack; + + /** + * @param identifier can be used to determine which screen is the currently + * displayed on the graphicDisplay + */ + IAbstractView(uint8_t identifier) : + identifier(identifier), alive(true) + { + } + + virtual ~IAbstractView() = default; + + /** + * @brief update The update function of the top most display gets called + * as often as possible. Only the update of the top view in each + * ViewStack gets called. + */ + virtual void + update() + { + // nothing to be done + } + + /** + * @brief hasChanged indicates the current displayed view has changed. + * This function prevents unnecessary drawing of the display + * @return if true the display has to be redrawn. + */ + virtual bool + hasChanged() = 0; + + /** + * @brief draw determine the output on the Graphic Display + */ + virtual void + draw() = 0; + + + /** + * @brief shortButtonPress handle the action for the pressed button + */ + virtual void + shortButtonPress(modm::MenuButtons::Button /*button*/) + { + // nothing to be done + } + + /** + * @brief isAlive tells the ViewStack if it should remove this screen. + * @return + */ + bool + isAlive() const + { + return this->alive; + } + + /** + * @brief remove the view from the screen. The viewStack handles the deletion. + */ + void + remove() + { + this->alive = false; + } + + /** + * @brief getIdentifier of the view. + */ + inline uint8_t getIdentifier(){ + return this->identifier; + } + + public: + + /** + * @brief onRemove will be called right before the view gets deleted, + * can be reimplemented to reset external data. + */ + virtual void + onRemove() + { + // nothing to be done here + } + + private: + const uint8_t identifier; + bool alive; + }; +} + +#endif // MODM_IABSTRACT_VIEW_HPP diff --git a/src/modm/ui/menu/menu_entry_callback.hpp b/src/modm/ui/menu/menu_entry_callback.hpp index e5592aa961..23b4d5959a 100644 --- a/src/modm/ui/menu/menu_entry_callback.hpp +++ b/src/modm/ui/menu/menu_entry_callback.hpp @@ -5,6 +5,7 @@ * Copyright (c) 2012, Sascha Schade * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -22,14 +23,15 @@ namespace modm { /// @ingroup modm_ui_menu + template > class MenuEntryCallback { public: - typedef void (modm::AbstractMenu::*Function)(); + typedef void (modm::AbstractMenu::*Function)(); template MenuEntryCallback(M *menu, void (M::*function)()) : - menu(reinterpret_cast(menu)), + menu(reinterpret_cast *>(menu)), function(reinterpret_cast(function)) { } @@ -41,7 +43,7 @@ namespace modm } protected: - modm::AbstractMenu * const menu; + modm::AbstractMenu * const menu; Function const function; }; } diff --git a/src/modm/ui/menu/module.lb b/src/modm/ui/menu/module.lb index f729353585..75c4ec697e 100644 --- a/src/modm/ui/menu/module.lb +++ b/src/modm/ui/menu/module.lb @@ -39,7 +39,8 @@ def prepare(module, options): ":communication:xpcc", ":container", ":processing:timer", - ":ui:display") + ":ui:display", + ":utils") return True def build(env): diff --git a/src/modm/ui/menu/scrollable_text.cpp b/src/modm/ui/menu/scrollable_text.cpp index 72b35221ee..ded7621196 100644 --- a/src/modm/ui/menu/scrollable_text.cpp +++ b/src/modm/ui/menu/scrollable_text.cpp @@ -84,7 +84,7 @@ modm::ScrollableText::getText() if(this->needsScrolling()) { if(!this->isPaused()) - { + { for(uint16_t i = 0; ispace; ++i) { if( (i+this->startPosition) < this->length) @@ -126,5 +126,4 @@ modm::ScrollableText::setToStart() } this->print[space]='\0'; } - } diff --git a/src/modm/ui/menu/standard_menu.hpp b/src/modm/ui/menu/standard_menu.hpp index c7c9e92e40..d92c791f05 100644 --- a/src/modm/ui/menu/standard_menu.hpp +++ b/src/modm/ui/menu/standard_menu.hpp @@ -6,6 +6,7 @@ * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski * Copyright (c) 2015, Niklas Hauser + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -34,6 +35,7 @@ namespace modm * \ingroup modm_ui_menu * \author Thorsten Lajewski */ + template > struct MenuEntry { /** @@ -42,10 +44,10 @@ namespace modm * @param space, available to display menu entry in number of letters * @param func callback, which is called when entry is chosen */ - MenuEntry(const char* text, uint16_t space, MenuEntryCallback func); + MenuEntry(const char* text, uint16_t space, MenuEntryCallback func); ScrollableText text; - MenuEntryCallback callback; + MenuEntryCallback callback; }; /** @@ -61,21 +63,22 @@ namespace modm * \author Thorsten Lajewski */ - class StandardMenu : public AbstractMenu + template > + class StandardMenu : public AbstractMenu { public: - StandardMenu(modm::ViewStack* stack, uint8_t identifier); + StandardMenu(modm::ViewStack* stack, uint8_t identifier); - virtual ~StandardMenu() = 0; + virtual ~StandardMenu() {} - StandardMenu(modm::ViewStack* stack, uint8_t identifier, const char* title); + StandardMenu(modm::ViewStack* stack, uint8_t identifier, const char* title); /** * @brief addEntry adds a new option to the displayed list */ void - addEntry(const char* text, MenuEntryCallback func); + addEntry(const char* text, MenuEntryCallback func); /** * @brief setTitle set the title of the menu displayed on top of the list @@ -136,10 +139,14 @@ namespace modm protected: - typedef modm::DoublyLinkedList EntryList; - EntryList entries; + template + using EntryList = modm::DoublyLinkedList >; + + EntryList entries; }; } +#include "standard_menu_impl.hpp" + #endif // MODM_STANDARD_MENU_HPP diff --git a/src/modm/ui/menu/standard_menu.cpp b/src/modm/ui/menu/standard_menu_impl.hpp similarity index 61% rename from src/modm/ui/menu/standard_menu.cpp rename to src/modm/ui/menu/standard_menu_impl.hpp index 892f075a7b..f49bbfe10f 100644 --- a/src/modm/ui/menu/standard_menu.cpp +++ b/src/modm/ui/menu/standard_menu_impl.hpp @@ -2,6 +2,7 @@ * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski * Copyright (c) 2015, Niklas Hauser + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -11,16 +12,20 @@ */ // ---------------------------------------------------------------------------- -#include "standard_menu.hpp" +#ifndef MODM_STANDARD_MENU_HPP +# error "Don't include this file directly, use standard_menu.hpp instead!" +#endif -modm::MenuEntry::MenuEntry(const char* text, uint16_t space, MenuEntryCallback func): +template +modm::MenuEntry::MenuEntry(const char* text, uint16_t space, MenuEntryCallback func): text(text, space), callback(func) { } -modm::StandardMenu::StandardMenu(modm::ViewStack* stack, uint8_t identifier) : - modm::AbstractMenu(stack, identifier), +template +modm::StandardMenu::StandardMenu(modm::ViewStack* stack, uint8_t identifier) : + modm::AbstractMenu(stack, identifier), display_update_time(500), timer(std::chrono::milliseconds(display_update_time)), buttonAction(false), @@ -28,11 +33,12 @@ modm::StandardMenu::StandardMenu(modm::ViewStack* stack, uint8_t identifier) : homePosition(0), position(0) { - this->maximalDrawnEntrys = (getViewStack()->getDisplay().getHeight()- 16) / 8 ; + this->maximalDrawnEntrys = (this->getViewStack()->getDisplay().getHeight()- 16) / 8 ; } -modm::StandardMenu::StandardMenu(modm::ViewStack* stack, uint8_t identifier, const char* title) : - modm::AbstractMenu(stack, identifier), +template +modm::StandardMenu::StandardMenu(modm::ViewStack* stack, uint8_t identifier, const char* title) : + modm::AbstractMenu(stack, identifier), display_update_time(500), timer(std::chrono::milliseconds(display_update_time)), buttonAction(false), @@ -40,38 +46,34 @@ modm::StandardMenu::StandardMenu(modm::ViewStack* stack, uint8_t identifier, con homePosition(0), position(0) { - this->maximalDrawnEntrys = (getViewStack()->getDisplay().getHeight()- 16) / 8 ; + this->maximalDrawnEntrys = (this->getViewStack()->getDisplay().getHeight()- 16) / 8 ; } -modm::StandardMenu::~StandardMenu() +template void +modm::StandardMenu::addEntry(const char* text, MenuEntryCallback func) { -} - -void -modm::StandardMenu::addEntry(const char* text, MenuEntryCallback func) -{ - modm::MenuEntry entry(text, (getViewStack()->getDisplay().getWidth()-16)/6, func); + modm::MenuEntry entry(text, (this->getViewStack()->getDisplay().getWidth()-16)/6, func); this->entries.append(entry); } -void -modm::StandardMenu::setTitle(const char* text) +template void +modm::StandardMenu::setTitle(const char* text) { this->title = text; } -void -modm::StandardMenu::draw() +template void +modm::StandardMenu::draw() { - modm::ColorGraphicDisplay* display = &getViewStack()->getDisplay(); + typename modm::GraphicDisplay* display = &this->getViewStack()->getDisplay(); display->clear(); display->setCursor(0,2); (*display) << this->title; display->drawLine(0, 10, display->getWidth(), 10); uint8_t i, count = this->entries.getSize(); - EntryList::iterator iter = this->entries.begin(); + typename EntryList::iterator iter = this->entries.begin(); for(uint8_t j=0; jhomePosition; ++j) { @@ -98,8 +100,8 @@ modm::StandardMenu::draw() // todo add file up and / or down if some entrys are not displayed on screen } -bool -modm::StandardMenu::hasChanged() +template bool +modm::StandardMenu::hasChanged() { if (timer.execute() || this->buttonAction) { @@ -113,14 +115,14 @@ modm::StandardMenu::hasChanged() } } -void -modm::StandardMenu::selectedEntryFunction(uint8_t /*selected*/) +template void +modm::StandardMenu::selectedEntryFunction(uint8_t /*selected*/) { } -void -modm::StandardMenu::shortButtonPress(modm::MenuButtons::Button button) +template void +modm::StandardMenu::shortButtonPress(modm::MenuButtons::Button button) { switch(button) { @@ -128,7 +130,7 @@ modm::StandardMenu::shortButtonPress(modm::MenuButtons::Button button) { if (this->position + 1U < this->entries.getSize()) { - EntryList::iterator iter = this->entries.begin(); + typename EntryList::iterator iter = this->entries.begin(); for (uint8_t j=0; jposition; ++j) { @@ -159,7 +161,7 @@ modm::StandardMenu::shortButtonPress(modm::MenuButtons::Button button) { if (this->position > 0) { - EntryList::iterator iter = this->entries.begin(); + typename EntryList::iterator iter = this->entries.begin(); for (uint8_t j = 0; j < this->position; ++j) { @@ -198,7 +200,7 @@ modm::StandardMenu::shortButtonPress(modm::MenuButtons::Button button) } case modm::MenuButtons::RIGHT: { - EntryList::iterator iter = this->entries.begin(); + typename EntryList::iterator iter = this->entries.begin(); for (uint8_t j = 0; j < this->position; ++j) { diff --git a/src/modm/ui/menu/view_stack.cpp b/src/modm/ui/menu/view_stack.cpp deleted file mode 100644 index f133ecffbe..0000000000 --- a/src/modm/ui/menu/view_stack.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2011, Fabian Greif - * Copyright (c) 2010-2011, 2013, Georgi Grinshpun - * Copyright (c) 2013, Kevin Läufer - * Copyright (c) 2013, Thorsten Lajewski - * Copyright (c) 2014, Sascha Schade - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#include "view_stack.hpp" - -// ---------------------------------------------------------------------------- -modm::ViewStack::ViewStack(modm::ColorGraphicDisplay* display) : - display(display) -{ -} - -// ---------------------------------------------------------------------------- -modm::ViewStack::~ViewStack() -{ -} - -// ---------------------------------------------------------------------------- -void -modm::ViewStack::pop() -{ - modm::AbstractView *topElement = this->stack.get(); - this->stack.pop(); - - delete topElement; -} - -// ---------------------------------------------------------------------------- -void -modm::ViewStack::update() -{ - modm::AbstractView* top = this->get(); - - if (top == NULL) - return; - - top->update(); - if (top->isAlive()) - { - if (top->hasChanged()) - { - top->draw(); - this->display->update(); - } - } - else - { - // Remove old view - top->onRemove(); - this->pop(); - - // Get new screen - top = this->get(); - top->update(); - this->display->clear(); - top->draw(); - this->display->update(); - } -} - -// ---------------------------------------------------------------------------- -void -modm::ViewStack::shortButtonPress(modm::MenuButtons::Button button) -{ - modm::AbstractView* top = this->get(); - top->shortButtonPress(button); -} diff --git a/src/modm/ui/menu/view_stack.hpp b/src/modm/ui/menu/view_stack.hpp index 188e884af8..c897c99ebe 100644 --- a/src/modm/ui/menu/view_stack.hpp +++ b/src/modm/ui/menu/view_stack.hpp @@ -5,6 +5,7 @@ * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2013, Thorsten Lajewski * Copyright (c) 2014, Sascha Schade + * Copyright (c) 2020, Matthew Arnold * * This file is part of the modm project. * @@ -36,19 +37,26 @@ namespace modm * \author Thorsten Lajewski */ + template > class ViewStack { public: - ViewStack(modm::ColorGraphicDisplay* display); + ViewStack(modm::GraphicDisplay* display, const Allocator allocator = Allocator()) : + display(display), + allocator(allocator) + { + } - virtual ~ViewStack(); + virtual ~ViewStack() + { + } /** * @brief get the top view from the stack * @return pointer to view from stack */ - inline modm::AbstractView* + inline modm::AbstractView* get() { return this->stack.get(); @@ -62,11 +70,11 @@ namespace modm * @param view next displayed view */ inline void - push(modm::AbstractView* view) + push(modm::AbstractView* view) { this->stack.push(view); this->getDisplay().clear(); - modm::AbstractView* top = this->get(); + modm::AbstractView* top = this->get(); top->draw(); this->display->update(); } @@ -74,7 +82,7 @@ namespace modm /** * @brief getDisplay access underlying GraphicDisplay */ - inline modm::ColorGraphicDisplay& + inline modm::GraphicDisplay& getDisplay() { return *this->display; @@ -86,10 +94,46 @@ namespace modm */ void - pop(); + pop() + { + modm::AbstractView *topElement = this->stack.get(); + this->stack.pop(); + + allocator.destroy(topElement); + allocator.deallocate(topElement); + } virtual void - update(); + update() + { + modm::AbstractView* top = this->get(); + + if (top == NULL) + return; + + top->update(); + if (top->isAlive()) + { + if (top->hasChanged()) + { + top->draw(); + this->display->update(); + } + } + else + { + // Remove old view + top->onRemove(); + this->pop(); + + // Get new screen + top = this->get(); + top->update(); + this->display->clear(); + top->draw(); + this->display->update(); + } + } /** * @brief shortButtonPress pass the button press to the current top view @@ -97,11 +141,16 @@ namespace modm */ void - shortButtonPress(modm::MenuButtons::Button button); + shortButtonPress(modm::MenuButtons::Button button) + { + modm::AbstractView* top = this->get(); + top->shortButtonPress(button); + } protected: - modm::ColorGraphicDisplay* display; - modm::Stack< modm::AbstractView* , modm::LinkedList< modm::AbstractView* > > stack; + modm::GraphicDisplay* display; + modm::Stack< modm::AbstractView* , modm::LinkedList< modm::AbstractView* > > stack; + Allocator allocator; }; }