Delete view and presenter on AppContext.pop() 24/208524/7
authorOskar Chodowicz <o.chodowicz@samsung.com>
Tue, 25 Jun 2019 11:44:43 +0000 (13:44 +0200)
committerLukasz Wlazly <l.wlazly@partner.samsung.com>
Thu, 27 Jun 2019 06:57:41 +0000 (08:57 +0200)
Change-Id: Ica17f0d6004b2964149ee3184b139143618b797a

19 files changed:
src/model/AddSwitchPageModel.cpp
src/presenter/AppContext.cpp
src/presenter/AppContext.hpp
src/presenter/SelectActionPagePresenter.cpp
src/presenter/SelectActionPagePresenter.hpp
src/presenter/UniversalSwitchPagePresenter.cpp
src/presenter/UniversalSwitchPagePresenter.hpp
src/ui/Naviframe.cpp
src/ui/Naviframe.hpp
src/view/ListView.cpp
src/view/ListView.hpp
src/view/NaviframeView.cpp [new file with mode: 0644]
src/view/NaviframeView.hpp [new file with mode: 0644]
src/view/NavigationContext.cpp
src/view/NavigationContext.hpp
src/view/SpinnerView.cpp
src/view/SpinnerView.hpp
src/view/SpinnerViewWithToggle.cpp
src/view/SpinnerViewWithToggle.hpp

index 5a6c93987988a6adc25acccccf54907138cbaaae..0af40616c465bd7b059b4106ac178ad42feb17f7 100644 (file)
@@ -6,9 +6,10 @@ AddSwitchPageModel::AddSwitchPageModel()
 {
        dBusClient_ = DBus::DBusClient(BUS, PATH, IFACE, DBus::ConnectionType::SESSION);
        synchronizeProviders();
-       dBusClient_.addSignal<void()>(std::string{"switchesConfigurationChanged"}, [this]() {
-               this->switchesConfigurationChanged_ = std::chrono::system_clock::now();
-       });
+       // temporary fix to defend against segfault because dbus signals doesn't unregister on object destroy
+       // dBusClient_.addSignal<void()>(std::string{"switchesConfigurationChanged"}, [this]() {
+       //      this->switchesConfigurationChanged_ = std::chrono::system_clock::now();
+       // });
 }
 
 void AddSwitchPageModel::synchronizeProviders()
index 75a4d762e82e4a17c449815c3cd616b878106cd2..57ca8be671150c279778976061cdaff800b84997 100644 (file)
@@ -18,17 +18,28 @@ void AppContext::push(std::unique_ptr<Presenter> presenter)
 {
        presentersStack_.push_back(std::move(presenter));
        presenterToBroadcast_ = presentersStack_.back().get();
+       countOfPagesToPop_ = 1;
        notify();
 }
 
-void AppContext::pop()
+void AppContext::pop(size_t countOfPagesToPop)
 {
+       if (countOfPagesToPop < 1)
+               return;
+
        presenterToBroadcast_ = nullptr;
-       notify();
-       presentersStack_.pop_back();
+       if (countOfPagesToPop > presentersStack_.size())
+               countOfPagesToPop_ = presentersStack_.size();
+       else
+               countOfPagesToPop_ = countOfPagesToPop;
+
+       for (auto i = 0u; i < countOfPagesToPop_; ++i)
+               presentersStack_.pop_back();
 
        if (presentersStack_.empty())
                ui_app_exit();
+       else
+               notify();
 }
 
 Presenter *AppContext::back()
@@ -67,9 +78,9 @@ bool AppContext::modalsEmpty()
 
 void AppContext::notify()
 {
-       for (auto &c : this->Observable<Presenter *>::onChangeCallbacks_)
+       for (auto &c : this->Observable<Presenter *, size_t>::onChangeCallbacks_)
                if (c)
-                       c(presenterToBroadcast_);
+                       c(presenterToBroadcast_, countOfPagesToPop_);
 }
 
 void AppContext::notifyAboutModal()
index 60fdc4cf504925074c25453016e463720173453a..f878b085191f51467a09eee1b586037fffc81f62 100644 (file)
 #include <memory>
 #include <string>
 
-class AppContext : public Observable<Presenter *>, public Observable<ModalPresenter *>
+class AppContext : public Observable<Presenter *, size_t>, public Observable<ModalPresenter *>
 {
        public:
        AppContext();
        void push(std::unique_ptr<Presenter> presenter);
-       void pop();
+       void pop(size_t countOfPagesToPop = 1);
        Presenter *back();
        bool empty();
        void notify();
@@ -36,6 +36,7 @@ class AppContext : public Observable<Presenter *>, public Observable<ModalPresen
        std::vector<std::unique_ptr<Presenter>> presentersStack_;
        std::vector<std::unique_ptr<ModalPresenter>> modalPresentersStack_;
        Presenter *presenterToBroadcast_ = nullptr;
+       size_t countOfPagesToPop_ = 1;
        ModalPresenter *modalPresenterToBroadcast_ = nullptr;
 };
 
index ed8c88bd3affc9e8551061eacebec4303cae7f79..9fe29eb21239c09b4c59779dc65169b2738714ae 100644 (file)
@@ -1,6 +1,8 @@
 #include "SelectActionPagePresenter.hpp"
 
-SelectActionPagePresenter::SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, int countOfPagesToPop)
+#include "AppContext.hpp"
+
+SelectActionPagePresenter::SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop)
        : switchId_(std::move(switchId)), userName_(std::move(userName)), changeType_(changeType), countOfPagesToPop_(countOfPagesToPop)
 {
        setTitle("IDS_ACCS_UNIVERSAL_SWITCH_SELECT_ACTION");
@@ -31,5 +33,5 @@ void SelectActionPagePresenter::addOrUpdateSwitchConfigurationItem(const std::st
                ASSERT(0, "Unhandled change type");
                break;
        }
-       //Singleton<AppContext>::instance().pop(countOfPagesToPop+1);
+       Singleton<AppContext>::instance().pop(countOfPagesToPop_ + 1);
 }
\ No newline at end of file
index cf01cd2a11e2889be35162c34dc2306c25c4fd64..5dbf89670f4e2d6c74de0fd89663a9ade1d3defa 100644 (file)
@@ -8,14 +8,14 @@
 class SelectActionPagePresenter : public ListPresenter
 {
        public:
-       SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, int countOfPagesToPop);
+       SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop);
 
        private:
        void addOrUpdateSwitchConfigurationItem(const std::string &activityType);
        const std::string switchId_;
        const std::string userName_;
        ChangeType changeType_;
-       const int countOfPagesToPop_;
+       const size_t countOfPagesToPop_;
        SelectActionPageModel model_;
 };
 
index 41e8257f7221be7c917dc604092b5194d4b5cbd4..503dbac4467cd62b03f80dee6e8530da979219ed 100644 (file)
@@ -49,8 +49,9 @@ UniversalSwitchPagePresenter::UniversalSwitchPagePresenter()
                items.front()->title_ = value ? "IDS_ST_BODY_ON" : "IDS_ST_BODY_OFF";
                items.front()->widgetState_ = value;
        });
+}
 
-       onPopCallback_ = [this]() {
-               model_.configurationServiceState_ = false;
-       };
+UniversalSwitchPagePresenter::~UniversalSwitchPagePresenter()
+{
+       model_.configurationServiceState_ = false;
 }
\ No newline at end of file
index c303ac28e47f9f75f6d18de03a754d4fcd4c110b..86dc7030c78e3fc01f1847e9e9541908c431ec83 100644 (file)
@@ -9,6 +9,7 @@ class UniversalSwitchPagePresenter : public ListPresenter
 {
        public:
        UniversalSwitchPagePresenter();
+       ~UniversalSwitchPagePresenter();
 
        private:
        std::unique_ptr<UniversalSwitchSettingsPage> universalSwitchSettingsPage_;
index e31fed7a4655e943c39eb9992cd984dee43b0a45..24d431e2084a27b171c4886a4bd7c08e2d5d7232 100644 (file)
@@ -13,10 +13,14 @@ void NaviframeItem::setPartContent(const std::string &part, Widget *content)
        elm_object_item_part_content_set(item_, part.c_str(), content->getObject());
 }
 
-void Naviframe::createEflObject()
+void Naviframe::createEflObject(std::function<void()> onBackButtonPressed)
 {
        uniqueObj_.reset(elm_naviframe_add(parent_->getObject()));
-       eext_object_event_callback_add(uniqueObj_.get(), EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
+       if (onBackButtonPressed)
+               setEextEventCallback(EEXT_CALLBACK_BACK, onBackButtonPressed);
+       else
+               eext_object_event_callback_add(uniqueObj_.get(), EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
+
        eext_object_event_callback_add(uniqueObj_.get(), EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
        elm_naviframe_content_preserve_on_pop_set(uniqueObj_.get(), EINA_TRUE);
 }
index 5ddea31a91f67105ddd3038268f1116629575181..81e287b9583abccdf14ec86ade57aad2f13431e6 100644 (file)
@@ -46,7 +46,7 @@ class Naviframe : public Layout
        using Layout::Layout;
 
        private:
-       void createEflObject();
+       void createEflObject(std::function<void()> onBackButtonPressed = {});
        void onPop(Elm_Object_Item *item);
        static Eina_Bool callbackMethod(void *data, Elm_Object_Item *it);
        void onPopAnimationEnd();
index 94f25b77da8445b4a9fa70df1084e406c31e7bb4..54130361bcf81be8955fa21056b1f560721c797e 100644 (file)
@@ -1,13 +1,15 @@
 #include "ListView.hpp"
 
+#include "AppContext.hpp"
 #include "Button.hpp"
 #include "Check.hpp"
 #include "Genlist.hpp"
 #include "ListPresenter.hpp"
 #include "NavigationContext.hpp"
+#include "Singleton.hpp"
 
 ListView::ListView(const NavigationContext &context, Presenter *presenter)
-       : View(context), listPresenter_(dynamic_cast<ListPresenter *>(presenter))
+       : NaviframeView(context), listPresenter_(dynamic_cast<ListPresenter *>(presenter))
 {
        ASSERT(listPresenter_, "ListPresenter required");
 
@@ -50,13 +52,13 @@ ListView::ListView(const NavigationContext &context, Presenter *presenter)
                        });
                } else {
                        backItem_ = Widget::make<Button>(context.getNaviframe(),
-                               [naviframe = context.getNaviframe()]() { naviframe->popBack(); },
+                               []() { Singleton<AppContext>::instance().pop(); },
                                "IDS_ST_BUTTON_BACK",
                                Button::BACK_BUTTON_ARROW_STYLE);
                }
        }
 
-       naviframe->pushBack(listPresenter_->getTitle(), genlist_, listPresenter_->getOnPopCallback(), backItem_);
+       naviframeItem_ = naviframe->pushBack(listPresenter_->getTitle(), genlist_, {}, backItem_);
 
        if (auto action = listPresenter_->getAction("titleRightAction")) {
                titleRightButton_ = Widget::make<Button>(context.getNaviframe(), [this, action]() {
index c1311ffc4c0efd38017ecc2679cc1fd5d10c7deb..094647127e28074bdbeac45d08596fb761f86892 100644 (file)
@@ -3,12 +3,12 @@
 
 #include "Button.hpp"
 #include "ListPresenter.hpp"
+#include "NaviframeView.hpp"
 #include "Presenter.hpp"
-#include "View.hpp"
 
 #include <unordered_map>
 
-class ListView : public View
+class ListView : public NaviframeView
 {
        public:
        ListView(const NavigationContext &context, Presenter *presenter);
diff --git a/src/view/NaviframeView.cpp b/src/view/NaviframeView.cpp
new file mode 100644 (file)
index 0000000..9ea3c9e
--- /dev/null
@@ -0,0 +1,6 @@
+#include "NaviframeView.hpp"
+
+#include "NavigationContext.hpp"
+
+NaviframeView::NaviframeView(const NavigationContext &context) : View(context)
+{}
\ No newline at end of file
diff --git a/src/view/NaviframeView.hpp b/src/view/NaviframeView.hpp
new file mode 100644 (file)
index 0000000..1b36455
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef NAVIFRAME_VIEW_HPP
+#define NAVIFRAME_VIEW_HPP
+
+#include "Naviframe.hpp"
+#include "View.hpp"
+
+class NaviframeView : public View
+{
+       public:
+       NaviframeView(const NavigationContext &context);
+       NaviframeItem naviframeItem_ = {};
+};
+
+#endif
\ No newline at end of file
index f137ddb345299dcd91c633df314c8e468cb28161..2d60bfce67b13e5b2c32756c5ca08d8bd9054204 100644 (file)
@@ -19,7 +19,9 @@ NavigationContext::NavigationContext()
        window_->setConformant(true);
        window_->addResizeObject(conformant);
 
-       naviframe_ = Widget::make<Naviframe>(conformant);
+       naviframe_ = Widget::make<Naviframe>(conformant, []() {
+               Singleton<AppContext>::instance().pop();
+       });
        conformant->setContent(naviframe_);
 
        conformant->emitSignal("elm,state,virtualkeypad,enable");
@@ -29,11 +31,17 @@ NavigationContext::NavigationContext()
 
        window_->show();
 
-       Singleton<AppContext>::instance().Observable<Presenter *>::attach([this](auto presenter) {
-               if (presenter)
+       Singleton<AppContext>::instance().Observable<Presenter *, size_t>::attach([this](auto presenter, auto count) {
+               if (presenter) {
                        this->emplaceView(presenter);
-               else
-                       this->popView();
+               } else {
+                       NaviframeItem naviframeItem;
+                       for (auto i = 0u; i < count; ++i) {
+                               this->popView();
+                               naviframeItem = viewsStack_.back()->naviframeItem_;
+                       }
+                       this->naviframe_->popBack(naviframeItem);
+               }
        });
 
        Singleton<AppContext>::instance().Observable<ModalPresenter *>::attach([this](auto presenter) {
index 19ab8ab3cbecd4c2b5413d764eeeb763698d7088..a3301e497b905fc7ac740869a81e88d0e032cd93 100644 (file)
@@ -3,8 +3,8 @@
 
 #include "ModalView.hpp"
 #include "Naviframe.hpp"
+#include "NaviframeView.hpp"
 #include "Presenter.hpp"
-#include "View.hpp"
 #include "Window.hpp"
 
 #include <memory>
@@ -26,7 +26,7 @@ class NavigationContext
 
        std::unique_ptr<Window> window_;
        Naviframe *naviframe_;
-       std::vector<std::unique_ptr<View>> viewsStack_;
+       std::vector<std::unique_ptr<NaviframeView>> viewsStack_;
        std::vector<std::unique_ptr<ModalView>> modalViewsStack_;
 };
 
index e13970c2c19a38883d841f5128747820e81b0858..ae61af4eee51080136b4558199f1425a0f830719 100644 (file)
@@ -1,12 +1,14 @@
 #include "SpinnerView.hpp"
 
+#include "AppContext.hpp"
 #include "Box.hpp"
 #include "Label.hpp"
 #include "Layout.hpp"
 #include "NavigationContext.hpp"
+#include "Singleton.hpp"
 
 SpinnerView::SpinnerView(const NavigationContext &context, Presenter *presenter)
-       : View(context), spinnerPresenter_(dynamic_cast<SpinnerPresenter *>(presenter))
+       : NaviframeView(context), spinnerPresenter_(dynamic_cast<SpinnerPresenter *>(presenter))
 {
        ASSERT(spinnerPresenter_, "SpinnerPresenter required");
 
@@ -28,9 +30,9 @@ SpinnerView::SpinnerView(const NavigationContext &context, Presenter *presenter)
        layout->setPartText("description", spinnerPresenter_->getLabel());
 
        backItem_ = Widget::make<Button>(context.getNaviframe(),
-               [naviframe = context.getNaviframe()]() { naviframe->popBack(); },
+               []() { Singleton<AppContext>::instance().pop(); },
                "IDS_ST_BUTTON_BACK",
                Button::BACK_BUTTON_ARROW_STYLE);
 
-       naviframe->pushBack(spinnerPresenter_->getTitle(), layout, spinnerPresenter_->getOnPopCallback(), backItem_);
+       naviframeItem_ = naviframe->pushBack(spinnerPresenter_->getTitle(), layout, {}, backItem_);
 }
\ No newline at end of file
index 399a4944e71e704d3e87c181e8b343083c371feb..d62473ba3f8925d372f127a282980e41671b4f18 100644 (file)
@@ -2,11 +2,11 @@
 #define SPINNER_VIEW_HPP
 
 #include "Button.hpp"
+#include "NaviframeView.hpp"
 #include "Spinner.hpp"
 #include "SpinnerPresenter.hpp"
-#include "View.hpp"
 
-class SpinnerView : public View
+class SpinnerView : public NaviframeView
 {
        public:
        SpinnerView(const NavigationContext &context, Presenter *presenter);
index 61989fdecf1cce76879234fde2da8d788ddbc6b0..fa407669ebc14f29e8432e6c1672aac0db370874 100644 (file)
@@ -3,9 +3,10 @@
 #include "AppContext.hpp"
 #include "Layout.hpp"
 #include "NavigationContext.hpp"
+#include "Singleton.hpp"
 
 SpinnerViewWithToggle::SpinnerViewWithToggle(const NavigationContext &context, Presenter *presenter)
-       : View(context), spinnerPresenter_(dynamic_cast<SpinnerPresenterWithToggle *>(presenter))
+       : NaviframeView(context), spinnerPresenter_(dynamic_cast<SpinnerPresenterWithToggle *>(presenter))
 {
        ASSERT(spinnerPresenter_, "SpinnerPresenterWithToggle required");
 
@@ -36,9 +37,9 @@ SpinnerViewWithToggle::SpinnerViewWithToggle(const NavigationContext &context, P
        layout_->setPartText("description", spinnerPresenter_->getLabel());
 
        backItem_ = Widget::make<Button>(context.getNaviframe(),
-               [naviframe = context.getNaviframe()]() { naviframe->popBack(); },
+               []() { Singleton<AppContext>::instance().pop(); },
                "IDS_ST_BUTTON_BACK",
                Button::BACK_BUTTON_ARROW_STYLE);
 
-       naviframe->pushBack(spinnerPresenter_->getTitle(), layout_, spinnerPresenter_->getOnPopCallback(), backItem_);
+       naviframe->pushBack(spinnerPresenter_->getTitle(), layout_, {}, backItem_);
 }
\ No newline at end of file
index b5354e09d55d13a5601f025a89410858670b3a48..e49ef885da6084121fb49d8750bd904c92758afe 100644 (file)
@@ -4,11 +4,11 @@
 #include "Button.hpp"
 #include "Check.hpp"
 #include "Layout.hpp"
+#include "NaviframeView.hpp"
 #include "Spinner.hpp"
 #include "SpinnerPresenterWithToggle.hpp"
-#include "View.hpp"
 
-class SpinnerViewWithToggle : public View
+class SpinnerViewWithToggle : public NaviframeView
 {
        public:
        SpinnerViewWithToggle(const NavigationContext &context, Presenter *presenter);