Add customizable actions to list view and presenter 49/206049/4
authorOskar Chodowicz <o.chodowicz@samsung.com>
Mon, 13 May 2019 13:57:27 +0000 (15:57 +0200)
committerOskar Chodowicz <o.chodowicz@samsung.com>
Thu, 30 May 2019 07:01:51 +0000 (09:01 +0200)
Change-Id: Iaf085b536ea454872a11039a6c8b50c79be4c366

src/presenter/Action.cpp [new file with mode: 0644]
src/presenter/Action.hpp [new file with mode: 0644]
src/presenter/ListPresenter.cpp
src/presenter/ListPresenter.hpp
src/presenter/Presenter.cpp
src/presenter/Presenter.hpp
src/view/ListView.cpp
src/view/ListView.hpp
src/view/NavigationContext.cpp
src/view/View.cpp
src/view/View.hpp

diff --git a/src/presenter/Action.cpp b/src/presenter/Action.cpp
new file mode 100644 (file)
index 0000000..6721b18
--- /dev/null
@@ -0,0 +1,14 @@
+#include "Action.hpp"
+
+Action::Action(std::string actionId, std::string title, std::function<void(Action *item)> onInvoke, bool enabled, bool state)
+       : actionId_(std::move(actionId)),
+         title_(std::move(title)),
+         onInvoke_(std::move(onInvoke)),
+         enabled_(enabled),
+         state_(state)
+{
+       if (actionId_ == "titleRightAction")
+               state_.attach([this](auto val) {
+                       onInvoke_(this);
+               });
+}
\ No newline at end of file
diff --git a/src/presenter/Action.hpp b/src/presenter/Action.hpp
new file mode 100644 (file)
index 0000000..7c5bc4d
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef ACTION_HPP
+#define ACTION_HPP
+
+#include "ObservableProperty.hpp"
+
+#include <functional>
+#include <string>
+
+struct Action
+{
+       Action(std::string actionId, std::string title, std::function<void(Action *item)> onInvoke, bool enabled_ = true, bool state = false);
+
+       const std::string actionId_;
+       ObservableProperty<std::string> title_;
+       const std::function<void(Action *item)> onInvoke_;
+       ObservableProperty<bool> enabled_ = true;
+       ObservableProperty<bool> state_ = false;
+};
+
+#endif
\ No newline at end of file
index 1ebee31..d0d166c 100644 (file)
@@ -4,3 +4,18 @@ const std::vector<ListGroup> &ListPresenter::getListGroups() const
 {
        return groups_;
 }
+
+Action *ListPresenter::getAction(const std::string &actionId) const
+{
+       auto it = actions_.find(actionId);
+       if (it == actions_.end()) {
+               ERROR("Action with id: %s doesn't exist", actionId.c_str());
+               return nullptr;
+       }
+       return it->second.get();
+}
+
+void ListPresenter::addAction(std::unique_ptr<Action> action)
+{
+       actions_.insert_or_assign(action->actionId_, std::move(action));
+}
index 519e843..2fe724b 100644 (file)
@@ -1,19 +1,25 @@
 #ifndef LIST_PRESENTER_HPP
 #define LIST_PRESENTER_HPP
 
+#include "Action.hpp"
 #include "ListGroup.hpp"
 #include "Observable.hpp"
 #include "Presenter.hpp"
 
+#include <unordered_map>
+
 class ListPresenter : public Presenter, public Observable<>
 {
        public:
        const std::vector<ListGroup> &getListGroups() const;
+       Action *getAction(const std::string &actionId) const;
+       void addAction(std::unique_ptr<Action> action);
 
        protected:
        using Presenter::Presenter;
 
        std::vector<ListGroup> groups_;
+       std::unordered_map<std::string, std::unique_ptr<Action>> actions_;
 };
 
 #endif
\ No newline at end of file
index 43ea078..724f8f9 100644 (file)
@@ -9,6 +9,11 @@ const TranslatedString Presenter::getTitle() const
        return title_;
 }
 
+void Presenter::setTitle(const std::string &title)
+{
+       title_ = title;
+}
+
 const std::function<void()> Presenter::getOnPopCallback() const
 {
        return onPopCallback_;
index 9915302..47ad30d 100644 (file)
@@ -13,6 +13,7 @@ class Presenter
        virtual ~Presenter() = default;
 
        const TranslatedString getTitle() const;
+       void setTitle(const std::string &title);
        const std::function<void()> getOnPopCallback() const;
        virtual void onAppPause();
        virtual void onAppResume();
index a463036..530b696 100644 (file)
@@ -1,5 +1,7 @@
 #include "ListView.hpp"
 
+#include "Button.hpp"
+#include "Check.hpp"
 #include "Genlist.hpp"
 #include "ListPresenter.hpp"
 #include "NavigationContext.hpp"
@@ -16,7 +18,64 @@ ListView::ListView(const NavigationContext &context, Presenter *presenter)
 
        addItemsToGenlist();
 
-       naviframe->pushBack(listPresenter_->getTitle(), genlist_, listPresenter_->getOnPopCallback(), prevButton_);
+       if (auto action = listPresenter_->getAction("selectAll")) {
+               auto checkbox = Widget::make<Check>(context.getNaviframe());
+               checkbox->setState(action->state_.value());
+               checkbox->setEvasSmartCallback("changed", [this, action, checkbox]() {
+                       action->state_ = checkbox->getState();
+               });
+               action->state_.attach([this, checkbox](auto val) {
+                       checkbox->setState(val);
+               });
+               action->enabled_.attach([this, checkbox](auto val) {
+                       checkbox->disable(!val);
+               });
+               backItem_ = checkbox;
+       } else {
+               if (auto action = listPresenter_->getAction("previousView")) {
+                       auto wrappedOnClick = [this, action]() {
+                               action->onInvoke_(action);
+                       };
+                       backItem_ = Widget::make<Button>(context.getNaviframe(),
+                               wrappedOnClick,
+                               "IDS_ST_BUTTON_BACK",
+                               Button::BACK_BUTTON_ARROW_STYLE);
+                       action->enabled_.attach([this](auto val) {
+                               backItem_->disable(!val);
+                       });
+               } else {
+                       backItem_ = Widget::make<Button>(context.getNaviframe(),
+                               [naviframe = context.getNaviframe()]() { naviframe->popBack(); },
+                               "IDS_ST_BUTTON_BACK",
+                               Button::BACK_BUTTON_ARROW_STYLE);
+               }
+       }
+
+       naviframe->pushBack(listPresenter_->getTitle(), genlist_, listPresenter_->getOnPopCallback(), backItem_);
+
+       if (auto action = listPresenter_->getAction("titleRightAction")) {
+               titleRightButton_ = Widget::make<Button>(context.getNaviframe(), [this, action]() {
+                       action->onInvoke_(action);
+               },
+                       "<font_size=30>" + TranslatedString{action->title_.value()}.str() + "</font_size>",
+                       "naviframe/title_right");
+               action->title_.attach([this](auto val) {
+                       auto formatedText = "<font_size=30>" + TranslatedString{val}.str() + "</font_size>";
+                       titleRightButton_->setText(formatedText);
+               });
+               action->enabled_.attach([this](auto val) {
+                       titleRightButton_->disable(!val);
+               });
+               naviframe->setPartContent("title_right_btn", titleRightButton_);
+       }
+}
+
+ListView::~ListView()
+{
+       if (titleRightButton_) {
+               auto parent = titleRightButton_->getParent();
+               parent->removeChild(titleRightButton_);
+       }
 }
 
 void ListView::addItemsToGenlist()
index 8d42c3b..c1311ff 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef LIST_VIEW_HPP
 #define LIST_VIEW_HPP
 
+#include "Button.hpp"
 #include "ListPresenter.hpp"
 #include "Presenter.hpp"
 #include "View.hpp"
@@ -11,6 +12,7 @@ class ListView : public View
 {
        public:
        ListView(const NavigationContext &context, Presenter *presenter);
+       ~ListView();
 
        private:
        void addItemsToGenlist();
@@ -19,6 +21,8 @@ class ListView : public View
        ListPresenter *listPresenter_ = nullptr;
        Genlist *genlist_ = nullptr;
        std::unordered_map<GenlistItem *, ListItem *> itemsMapping_;
+       Widget *backItem_ = nullptr;
+       Button *titleRightButton_ = nullptr;
 };
 
 #endif
\ No newline at end of file
index b7b14b3..a3c4ba7 100644 (file)
@@ -50,8 +50,8 @@ void NavigationContext::emplaceView(Presenter *presenter)
         * In order to add new Presenter class, one should cast received pointer to derived type
         * and push proper View on viewStack_ 
        */
-       auto lp = dynamic_cast<ListPresenter *>(presenter);
-       if (lp) {
+
+       if (auto lp = dynamic_cast<ListPresenter *>(presenter)) {
                viewsStack_.push_back(std::make_unique<ListView>(*this, lp));
                return;
        }
index a5a1170..0c7cf4b 100644 (file)
@@ -4,8 +4,4 @@
 
 View::View(const NavigationContext &context)
 {
-       prevButton_ = Widget::make<Button>(context.getNaviframe(),
-               [naviframe = context.getNaviframe()]() { naviframe->popBack(); },
-               "IDS_ST_BUTTON_BACK",
-               Button::BACK_BUTTON_ARROW_STYLE);
 }
\ No newline at end of file
index 14519a4..c7e82e6 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef VIEW_HPP
 #define VIEW_HPP
 
-#include "Button.hpp"
 #include "Presenter.hpp"
 
 class NavigationContext;
@@ -12,7 +11,6 @@ class View
        virtual ~View() = default;
 
        protected:
-       Button *prevButton_ = nullptr;
 };
 
 #endif
\ No newline at end of file