TizenRefApp-8432 [Gallery] Implement logic of activate by/deactivate by 45/127245/4
authorIgor Nazarov <i.nazarov@samsung.com>
Wed, 26 Apr 2017 15:43:36 +0000 (18:43 +0300)
committerIgor Nazarov <i.nazarov@samsung.com>
Thu, 27 Apr 2017 13:58:52 +0000 (16:58 +0300)
- Implemented Presenter base class with activateBy/deactivateBy
  functionality;
- All presenters derived from Presenter (except ProcessingPresenter);
- Some free functions moved to "util" namespace;
- "Widget &parent" replaced widh "ElmWidget &parent".

Change-Id: I4bbe74ca39fa8fedc5bf09fc28bd5b5adfbbcec8

27 files changed:
inc/presenters/AlertDialog.h
inc/presenters/MoreOptionsPresenter.h
inc/presenters/Page.h
inc/presenters/Page.hpp
inc/presenters/Presenter.h [new file with mode: 0644]
inc/presenters/ProcessingPresenter.h
inc/presenters/SelectModePresenter.h
inc/presenters/types.h
inc/view/ImageGrid.h
inc/view/ImageViewer.h
inc/view/PageContent.h
inc/view/helpers.h
src/presenters/AlertDialog.cpp
src/presenters/Instance.cpp
src/presenters/MoreOptionsPresenter.cpp
src/presenters/Page.cpp
src/presenters/Presenter.cpp [new file with mode: 0644]
src/presenters/ProcessingPresenter.cpp
src/presenters/SelectModePresenter.cpp
src/view/ImageGrid.cpp
src/view/ImageViewer.cpp
src/view/PageContent.cpp
src/view/helpers.cpp
ucl/inc/ucl/gui/Layout.h
ucl/inc/ucl/gui/Naviframe.h
ucl/src/gui/Layout.cpp
ucl/src/gui/Naviframe.cpp

index 59e0912056a4e056227b678c24ab45d6046a0343..7b8e8430d5b1f772fb73daae6b50f3d95d135806 100644 (file)
 #include "ucl/gui/StyledWidget.h"
 #include "ucl/gui/Layout.h"
 
-#include "types.h"
+#include "Presenter.h"
 
 namespace gallery {
 
-       class AlertDialog final : public ucl::RefCountAware,
+       class AlertDialog final : public Presenter,
                        public ucl::IDisposable {
        public:
                enum class Type {
@@ -47,7 +47,7 @@ namespace gallery {
                        Builder &setTitle(ucl::TString title);
                        Builder &setText(ucl::TString text);
                        Builder &setHandler(const EventHandler &handler);
-                       AlertDialogWRef build(ucl::Widget &parent) const;
+                       AlertDialogWRef build(ucl::ElmWidget &parent) const;
                private:
                        Type m_type;
                        ucl::TString m_title;
@@ -69,8 +69,8 @@ namespace gallery {
                                const EventHandler &handler);
                virtual ~AlertDialog();
 
-               ucl::Result prepare(ucl::Widget &parent, Type type);
-               ucl::Result createPopup(ucl::Widget &parent, ucl::ElmStyle style);
+               ucl::Result prepare(ucl::ElmWidget &parent, Type type);
+               ucl::Result createPopup(ucl::ElmWidget &parent, ucl::ElmStyle style);
                ucl::Result createLayout(ucl::LayoutTheme theme);
                ucl::Result createButton(Event event, ucl::EdjePart part,
                                ucl::ElmStyle btnStyle, ucl::LayoutTheme iconTheme,
@@ -84,7 +84,6 @@ namespace gallery {
 
                void onPopupDismissed(ucl::Widget &widget, void *eventInfo);
                void onPopupHWBackKey(Evas_Object *obj, void *eventInfo);
-               void onPopupDel(ucl::Widget &widget, void *eventInfo);
 
                void onBtnClick(ucl::Widget &widget, void *eventInfo);
 
index b8edfb76bbd7f71a5a94a32589c8231ce2ecb302..b765dd18f143735e0825e6d6c3bd0179ea20cc65 100644 (file)
 #ifndef __GALLERY_PRESENTERS_MORE_OPTIONS_PRESENTER_H__
 #define __GALLERY_PRESENTERS_MORE_OPTIONS_PRESENTER_H__
 
-#include "ucl/gui/Widget.h"
 #include "ucl/misc/HashMap.h"
 
-#include "types.h"
+#include "Presenter.h"
 
 namespace gallery {
 
-       class MoreOptionsPresenter final : public ucl::RefCountAware {
+       class MoreOptionsPresenter final : public Presenter {
        public:
                class Builder {
                public:
@@ -33,7 +32,7 @@ namespace gallery {
                        bool isEmpty() const;
                        Builder &clear();
                        Builder &addOption(MoreOption option);
-                       MoreOptionsPresenterSRef build(ucl::Widget &parent) const;
+                       MoreOptionsPresenterSRef build(ucl::ElmWidget &parent) const;
                private:
                        ucl::SharedRef<MoreOptions> m_options;
                };
@@ -55,7 +54,7 @@ namespace gallery {
                                const MoreOptionsCSRef &options);
                virtual ~MoreOptionsPresenter();
 
-               ucl::Result prepare(ucl::Widget &parent);
+               ucl::Result prepare(ucl::ElmWidget &parent);
                ucl::Result addItem(const MoreOption &option);
 
                void onOpened(ucl::Widget &widget, void *eventInfo);
@@ -66,7 +65,7 @@ namespace gallery {
        private:
                const MoreOptionsCSRef m_options;
                ucl::HashMap<void *, const MoreOption *> m_map;
-               ucl::WidgetSRef m_widget;
+               ucl::ElmWidgetSRef m_widget;
                IMoreOptionsListenerWRef m_listener;
        };
 }
index e1362cc6980a72c23f2f3ab1ddb266da3cd90615..915a1be7ff00b8a924c9c9ea799588041b0e4e40 100644 (file)
 
 #include "ucl/gui/Naviframe.h"
 
-#include "types.h"
+#include "Presenter.h"
 
 namespace gallery {
 
-       class Page : public ucl::RefCountAware {
+       class Page : public Presenter {
        public:
                using ExitRequestHandler = ucl::Delegate<void(Page &page)>;
 
        public:
                ucl::Naviframe &getNaviframe();
 
-               bool isActive() const;
-
                bool isAtTop() const;
                bool isAtBottom() const;
 
@@ -60,8 +58,6 @@ namespace gallery {
 
                void requestExit();
 
-               virtual void onActivate();
-               virtual void onDeactivate();
                virtual void onBackKey();
 
        private:
@@ -69,8 +65,6 @@ namespace gallery {
 
                void dispatchTopPageChanged();
 
-               void activate();
-               void deactivate();
                void updateActiveState();
 
                void onTransitionStarted(ucl::Widget &widget, void *eventInfo);
@@ -84,7 +78,6 @@ namespace gallery {
                const ucl::NaviframeSRef m_navi;
                const ExitRequestHandler m_onExitRequest;
                ucl::NaviItem m_item;
-               bool m_isActive;
        };
 
        // Non-member functions //
index 9c900e2370d3648e4497f28da45697d73ae81d5e..b0e1ae7755b9d2cb67aed526681b668dcc10358f 100644 (file)
@@ -46,11 +46,6 @@ namespace gallery {
                return *m_navi;
        }
 
-       inline bool Page::isActive() const
-       {
-               return m_isActive;
-       }
-
        inline bool Page::isAtTop() const
        {
                return (m_navi->getTopItem() == m_item);
diff --git a/inc/presenters/Presenter.h b/inc/presenters/Presenter.h
new file mode 100644 (file)
index 0000000..3400cff
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GALLERY_PRESENTERS_PRESENTER_H__
+#define __GALLERY_PRESENTERS_PRESENTER_H__
+
+#include <unordered_set>
+
+#include "ucl/gui/ElmWidget.h"
+
+#include "types.h"
+
+namespace gallery {
+
+       class Presenter : public ucl::RefCountAware {
+       public:
+               struct DeactivatorInfo {
+                       void *deactivator;
+                       bool isBroadcast;
+               };
+
+       public:
+               bool isActive() const;
+               bool isDeactivatedBy(void *deactivator) const;
+
+               void activateBy(void *deactivator);
+               void deactivateBy(void *deactivator);
+
+       protected:
+               Presenter(ucl::RefCountObjBase &rc);
+               virtual ~Presenter();
+
+               ucl::Result prepare(ucl::ElmWidget &widget);
+
+               void addDeactivatorSource(ucl::Widget &source);
+               void addDeactivatorException(void *deactivator);
+
+               void sendActivateBy(ucl::Widget &sender, void *deactivator);
+               void sendDeactivateBy(ucl::Widget &sender, void *deactivator);
+
+               void broadcastActivateBy(void *deactivator);
+               void broadcastDeactivateBy(void *deactivator);
+
+               virtual void onActivate();
+               virtual void onDeactivate();
+               virtual void onActivateBy(const DeactivatorInfo &info);
+               virtual void onDeactivateBy(const DeactivatorInfo &info);
+
+       private:
+               void sendDeactivator(ucl::Widget &sender,
+                               ucl::SmartEvent event, void *deactivator);
+               void broadcastDeactivator(ucl::SmartEvent event, void *deactivator);
+
+               void sendDeactivatorInfo(ucl::Widget &sender, ucl::SmartEvent event,
+                               const DeactivatorInfo &info);
+
+               void activateByImpl(const DeactivatorInfo &info);
+               void deactivateByImpl(const DeactivatorInfo &info);
+
+               void onActivateBySmart(ucl::Widget &widget, void *eventInfo);
+               void onDeactivateBySmart(ucl::Widget &widget, void *eventInfo);
+
+       private:
+               std::unordered_set<void *> m_deactivatorExceptions;
+               std::unordered_set<void *> m_deactivators;
+               ucl::WidgetWRef m_topWidget;
+               bool m_isPrepared;
+       };
+}
+
+#endif // __GALLERY_PRESENTERS_PRESENTER_H__
index 58e5a3a8338f027174891705054a31b97065772a..ed6c41005fa8573cb96fd5e8ea58ea4d1912421e 100644 (file)
@@ -38,7 +38,7 @@ namespace gallery {
                        Builder &setCompleteText(ucl::TString text);
                        Builder &setIconType(IconType value);
                        Builder &setForceProgress(bool value);
-                       ProcessingPresenterSRef build(ucl::Widget &parent) const;
+                       ProcessingPresenterSRef build(ucl::ElmWidget &parent) const;
                private:
                        ucl::TString m_processingText;
                        ucl::TString m_completeText;
@@ -58,12 +58,12 @@ namespace gallery {
                ProcessingPresenter(ucl::RefCountObjBase &rc, IconType iconType);
                virtual ~ProcessingPresenter();
 
-               ucl::Result prepare(ucl::Widget &parent,
+               ucl::Result prepare(ucl::ElmWidget &parent,
                                const ucl::TString &processingText,
                                const ucl::TString &completeText,
                                bool forceProgress);
 
-               ucl::Result createWidget(ucl::Widget &parent,
+               ucl::Result createWidget(ucl::ElmWidget &parent,
                                const ucl::TString &processingText);
                ucl::Result createProgress();
                ucl::Result createPopup(const ucl::TString &completeText);
index 73924a4a3a1b89f98bdfb743d3c6c34e594cfb7e..b46cba2189bcfd52d96915f80774b2cc6b5d4c48 100644 (file)
 
 #include "ucl/gui/StyledWidget.h"
 
-#include "types.h"
+#include "Presenter.h"
 
 namespace gallery {
 
-       class SelectModePresenter final : public ucl::RefCountAware {
+       class SelectModePresenter final : public Presenter {
        public:
                enum {
                        FLAG_NO_BOTTOM_BUTTON = 1,
@@ -53,9 +53,6 @@ namespace gallery {
                void setVisible(bool value);
                bool isVisible() const;
 
-               void setActive(bool value);
-               bool isActive() const;
-
                void setBottomButtonText(const ucl::TString &value);
 
                void update(int selectCount, int totalCount = -1);
@@ -72,7 +69,8 @@ namespace gallery {
 
                void showPopup();
                void movePopup();
-               void dismissPopup(bool force = false);
+               void dismissPopup();
+               void deletePopup();
 
                void dispatchEvent(Event event);
 
@@ -86,17 +84,20 @@ namespace gallery {
                void onBottomBtnClick(ucl::Widget &widget, void *eventInfo);
                Eina_Bool onRotary(Eext_Rotary_Event_Info *info);
 
+               // Presenter //
+               virtual void onDeactivate() final override;
+
        private:
                const PageContentSRef m_content;
                const int m_flags;
                ucl::StyledWidgetSRef m_selectButton;
                ucl::StyledWidgetSRef m_bottomButton;
-               ucl::StyledWidgetWRef m_popup;
+               ucl::StyledWidgetSRef m_popup;
                ISelectModeListenerWRef m_listener;
                int m_totalCount;
                int m_selectCount;
                bool m_isVisible;
-               bool m_isActive;
+               bool m_isPopupDismissed;
        };
 }
 
index 9b79a455038fa91438c0beb50082e93dac6688b5..b7fdb1aeafadb876f8dfdd86863fb73b0ae7c8d6 100644 (file)
@@ -34,6 +34,8 @@ namespace gallery {
 
        using MoreOptions = std::list<MoreOption>;
 
+       UCL_DECLARE_REF_ALIASES(Presenter);
+
        UCL_DECLARE_REF_ALIASES(IMoreOptionsListener);
        UCL_DECLARE_REF_ALIASES(MoreOptionsPresenter);
 
index 18304fa16e9cac889ff2411f31d38647d9c1a953..3f1c3853a28c70a5d91ace56c7bc6835ee16c910 100644 (file)
@@ -38,7 +38,7 @@ namespace gallery {
                        Builder &setType(Type value);
                        Builder &setListener(IImageGridListener *value);
                        Builder &setSelectModeStartup(bool value);
-                       ImageGridSRef build(Widget &parent) const;
+                       ImageGridSRef build(ElmWidget &parent) const;
                private:
                        Type m_type;
                        IImageGridListener *m_listener;
index 3182ae7ccc6d4719c27d15d777a1c7b8f4592071..d0b6058d48ad435990f79aedba6023c4a38ae839 100644 (file)
@@ -32,7 +32,7 @@ namespace gallery {
                public:
                        Builder();
                        Builder &setImageSize(int w, int h);
-                       ImageViewerSRef build(ucl::Widget &parent) const;
+                       ImageViewerSRef build(ucl::ElmWidget &parent) const;
                private:
                        int m_imageW;
                        int m_imageH;
index 371299e14a366a6a2ca9f696b34cc58e6c1b1080..3995ccc7a3a5d1c6dc3f0ff9b26778ae94c6547d 100644 (file)
@@ -29,7 +29,7 @@ namespace gallery {
                public:
                        Builder();
                        Builder &setFlags(int flags);
-                       PageContentSRef build(ucl::Widget &parent) const;
+                       PageContentSRef build(ucl::ElmWidget &parent) const;
                private:
                        int m_flags;
                };
index 5cf4fd5355c91a6730bf7d9b719c92d401e3d590..abf8b15a9f63f713adfba55d879d24a7458a2565 100644 (file)
@@ -25,10 +25,13 @@ namespace ucl {
        class Naviframe;
 }
 
-namespace gallery {
+namespace gallery { namespace util {
 
        ucl::Result createCircleSurface(ucl::Naviframe &navi);
        Eext_Circle_Surface *getCircleSurface(const ucl::ElmWidget &widget);
+}}
+
+namespace gallery {
 
        void addRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data);
        void delRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data);
index 26bf2653e25155a8128b398fb8bc649482d6f221..fac680f5c0f1c5917cb726e1577fcfc34c0c9400 100644 (file)
@@ -88,7 +88,7 @@ namespace gallery {
                return *this;
        }
 
-       AlertDialogWRef AlertDialog::Builder::build(Widget &parent) const
+       AlertDialogWRef AlertDialog::Builder::build(ElmWidget &parent) const
        {
                if (!m_handler) {
                        LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "m_handler is NULL");
@@ -109,7 +109,7 @@ namespace gallery {
 
        AlertDialog::AlertDialog(RefCountObjBase &rc,
                        const EventHandler &handler) :
-               RefCountAware(&rc),
+               Presenter(rc),
                m_handler(handler),
                m_isDismissed(false)
        {
@@ -119,8 +119,11 @@ namespace gallery {
        {
        }
 
-       Result AlertDialog::prepare(Widget &parent, const Type type)
+       Result AlertDialog::prepare(ElmWidget &parent, const Type type)
        {
+               FAIL_RETURN(Presenter::prepare(parent),
+                               "Presenter::prepare() failed!");
+
                FAIL_RETURN(createPopup(parent, impl::POPUP_STYLE),
                                "createPopup() failed!");
 
@@ -135,22 +138,15 @@ namespace gallery {
                                impl::RIGHT_POPUP_BTN_STYLE, getImageTheme(ICON_POPUP_OK)),
                                "createButton() failed!");
 
-               m_popup->addEventHandler(WidgetEvent::DEL, WEAK_DELEGATE(
-                               AlertDialog::onPopupDel, asWeak(*this)));
-               m_popup->setIsOwner(false);
                m_rc->ref();
 
-               return RES_OK;
-       }
+               addDeactivatorException(this);
+               broadcastDeactivateBy(this);
 
-       void AlertDialog::onPopupDel(Widget &widget, void *eventInfo)
-       {
-               eext_object_event_callback_del(widget, EEXT_CALLBACK_BACK,
-                               CALLBACK_A(AlertDialog::onPopupHWBackKey));
-               m_rc->unref();
+               return RES_OK;
        }
 
-       Result AlertDialog::createPopup(Widget &parent, const ElmStyle style)
+       Result AlertDialog::createPopup(ElmWidget &parent, const ElmStyle style)
        {
                Evas_Object *const popupEo = elm_popup_add(parent);
                if (!popupEo) {
@@ -234,6 +230,7 @@ namespace gallery {
        {
                if (m_popup && !m_isDismissed) {
                        m_isDismissed = true;
+                       deactivateBy(m_popup.get());
                        elm_popup_dismiss(*m_popup);
                }
        }
@@ -241,8 +238,14 @@ namespace gallery {
        void AlertDialog::dispose()
        {
                if (m_popup) {
-                       m_popup->markForDeletion();
+                       eext_object_event_callback_del(*m_popup, EEXT_CALLBACK_BACK,
+                                       CALLBACK_A(AlertDialog::onPopupHWBackKey));
+
                        m_popup.reset();
+
+                       deactivateBy(m_popup.get());
+                       broadcastActivateBy(this);
+                       m_rc->unref();
                }
        }
 
@@ -275,14 +278,14 @@ namespace gallery {
 
        void AlertDialog::onPopupHWBackKey(Evas_Object *obj, void *eventInfo)
        {
-               if (!m_isDismissed) {
+               if (isActive()) {
                        handleEvent(EVENT_BACK);
                }
        }
 
        void AlertDialog::onBtnClick(Widget &widget, void *eventInfo)
        {
-               if (!m_isDismissed) {
+               if (isActive()) {
                        handleEvent(impl::getEvent(widget));
                }
        }
index db092d30c07adb82c8bef2901142a382928978fd..debee11d0dc3b3e4f48710a94c54c995c636e2b0 100644 (file)
@@ -75,8 +75,8 @@ namespace gallery {
 
                m_win->getConformant().setContent(*m_navi);
 
-               FAIL_RETURN(createCircleSurface(*m_navi),
-                               "createCircleSurface() failed!");
+               FAIL_RETURN(util::createCircleSurface(*m_navi),
+                               "util::createCircleSurface() failed!");
 
                m_sysEventProvider.addEventHandler(
                                DELEGATE(Instance::onSysEvent, this));
index a111dc58ba851525dbce6780598b268a69f31f9c..012865c7150687d47619f7329012b597f586bab6 100644 (file)
@@ -87,7 +87,7 @@ namespace gallery {
        }
 
        MoreOptionsPresenterSRef MoreOptionsPresenter::Builder::build(
-                       Widget &parent) const
+                       ElmWidget &parent) const
        {
                if (isEmpty()) {
                        LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "Builder is empty!");
@@ -105,22 +105,30 @@ namespace gallery {
 
        MoreOptionsPresenter::MoreOptionsPresenter(RefCountObjBase &rc,
                        const MoreOptionsCSRef &options) :
-               RefCountAware(&rc),
+               Presenter(rc),
                m_options(options)
        {
        }
 
        MoreOptionsPresenter::~MoreOptionsPresenter()
        {
+               if (m_widget) {
+                       sendActivateBy(*m_widget, this);
+               }
        }
 
-       Result MoreOptionsPresenter::prepare(Widget &parent)
+       Result MoreOptionsPresenter::prepare(ElmWidget &parent)
        {
-               m_widget = makeShared<Layout>(eext_more_option_add(parent), true);
-               if (!m_widget) {
+               FAIL_RETURN(Presenter::prepare(parent), "Presenter::prepare() failed!");
+
+               Evas_Object *const more = eext_more_option_add(parent);
+               if (!more) {
                        LOG_RETURN(RES_FAIL, "eext_more_option_add() failed!");
                }
 
+               const auto layout = makeShared<Layout>(more, true);
+               m_widget = layout;
+
                for (auto &option: *m_options) {
                        FAIL_RETURN(addItem(option), "addItem() failed!");
                }
@@ -166,6 +174,8 @@ namespace gallery {
 
        void MoreOptionsPresenter::onOpened(Widget &widget, void *eventInfo)
        {
+               sendDeactivateBy(*m_widget, this);
+               activateBy(m_widget.get());
                if (m_listener) {
                        m_listener->onMoreOptionsOpened(*this);
                }
@@ -173,6 +183,8 @@ namespace gallery {
 
        void MoreOptionsPresenter::onClosed(Widget &widget, void *eventInfo)
        {
+               deactivateBy(m_widget.get());
+               sendActivateBy(*m_widget, this);
                if (m_listener) {
                        m_listener->onMoreOptionsClosed(*this);
                }
@@ -180,7 +192,7 @@ namespace gallery {
 
        void MoreOptionsPresenter::onItemClicked(Widget &widget, void *eventInfo)
        {
-               if (m_listener && isOpened()) {
+               if (m_listener && isActive() && isOpened()) {
                        const auto item = m_map.get(eventInfo);
                        if (item) {
                                m_listener->onMoreOptionClicked(*this, *item);
@@ -192,7 +204,7 @@ namespace gallery {
 
        void MoreOptionsPresenter::onItemSelected(Widget &widget, void *eventInfo)
        {
-               if (m_listener && isOpened()) {
+               if (m_listener) {
                        const auto item = m_map.get(eventInfo);
                        if (item) {
                                m_listener->onMoreOptionSelected(*this, *item);
index fff45582fb727cec7ec8bd3a6f774381ea4c09fa..f1404f961402e2750ee49ecb852ddba7577658d5 100644 (file)
@@ -31,13 +31,14 @@ namespace gallery {
 
        Page::Page(RefCountObjBase &rc, const NaviframeSRef &navi,
                        const ExitRequestHandler onExitRequest) :
-               RefCountAware(&rc),
+               Presenter(rc),
                m_navi(navi),
-               m_onExitRequest(onExitRequest),
-               m_isActive(false)
+               m_onExitRequest(onExitRequest)
        {
                UCL_ASSERT(navi, "navi is NULL!");
                UCL_ASSERT(onExitRequest, "onExitRequest is NULL!");
+
+               deactivateBy(m_navi.get());
        }
 
        Page::~Page()
@@ -46,6 +47,9 @@ namespace gallery {
 
        Result Page::preparePart2()
        {
+               FAIL_RETURN(Presenter::prepare(*m_navi),
+                               "Presenter::prepare() failed!");
+
                Evas_Object *content = m_item.getContent();
                if (!content) {
                        LOG_RETURN(RES_FAIL, "content is NULL");
@@ -140,34 +144,18 @@ namespace gallery {
                m_onExitRequest(*this);
        }
 
-       void Page::activate()
-       {
-               if (!m_isActive) {
-                       m_isActive = true;
-                       onActivate();
-               }
-       }
-
-       void Page::deactivate()
-       {
-               if (m_isActive) {
-                       m_isActive = false;
-                       onDeactivate();
-               }
-       }
-
        void Page::updateActiveState()
        {
                if (isAtTop()) {
-                       activate();
+                       activateBy(m_navi.get());
                } else {
-                       deactivate();
+                       deactivateBy(m_navi.get());
                }
        }
 
        void Page::onTransitionStarted(Widget &widget, void *eventInfo)
        {
-               deactivate();
+               deactivateBy(m_navi.get());
        }
 
        void Page::onTransitionFinished(Widget &widget, void *eventInfo)
@@ -182,19 +170,11 @@ namespace gallery {
 
        void Page::onHWBackKey(Evas_Object *obj, void *eventInfo)
        {
-               if (m_isActive) {
+               if (isActive()) {
                        onBackKey();
                }
        }
 
-       void Page::onActivate()
-       {
-       }
-
-       void Page::onDeactivate()
-       {
-       }
-
        void Page::onBackKey()
        {
                requestExit();
diff --git a/src/presenters/Presenter.cpp b/src/presenters/Presenter.cpp
new file mode 100644 (file)
index 0000000..e461cda
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "presenters/Presenter.h"
+
+#include "common.h"
+
+namespace gallery { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr SmartEvent ACTIVATE_BY {"gallery,activate,by"};
+       constexpr SmartEvent DEACTIVATE_BY {"gallery,deactivate,by"};
+}}}
+
+namespace gallery {
+
+       using namespace ucl;
+
+       Presenter::Presenter(RefCountObjBase &rc) :
+               RefCountAware(&rc),
+               m_isPrepared(false)
+       {
+       }
+
+       Presenter::~Presenter()
+       {
+       }
+
+       Result Presenter::prepare(ElmWidget &widget)
+       {
+               m_topWidget = asWeak(asWidget(widget.getTopWidget()));
+               if (!m_topWidget) {
+                       LOG_RETURN(RES_FAIL, "m_topWidget is NULL!");
+               }
+
+               addDeactivatorSource(*m_topWidget);
+
+               m_isPrepared = true;
+
+               return RES_OK;
+       }
+
+       void Presenter::addDeactivatorSource(Widget &source)
+       {
+               source.addEventHandler(impl::ACTIVATE_BY,
+                               WEAK_DELEGATE(Presenter::onActivateBySmart, asWeak(*this)));
+               source.addEventHandler(impl::DEACTIVATE_BY,
+                               WEAK_DELEGATE(Presenter::onDeactivateBySmart, asWeak(*this)));
+       }
+
+       void Presenter::addDeactivatorException(void *const deactivator)
+       {
+               const auto pair = m_deactivatorExceptions.insert(deactivator);
+               if (pair.second) {
+                       activateBy(deactivator);
+               }
+       }
+
+       void Presenter::sendActivateBy(Widget &sender, void *const deactivator)
+       {
+               sendDeactivator(sender, impl::ACTIVATE_BY, deactivator);
+       }
+
+       void Presenter::sendDeactivateBy(Widget &sender, void *const deactivator)
+       {
+               sendDeactivator(sender, impl::DEACTIVATE_BY, deactivator);
+       }
+
+       void Presenter::broadcastActivateBy(void *const deactivator)
+       {
+               broadcastDeactivator(impl::ACTIVATE_BY, deactivator);
+       }
+
+       void Presenter::broadcastDeactivateBy(void *const deactivator)
+       {
+               broadcastDeactivator(impl::DEACTIVATE_BY, deactivator);
+       }
+
+       void Presenter::sendDeactivator(Widget &sender,
+                       SmartEvent event, void *deactivator)
+       {
+               sendDeactivatorInfo(sender, event, {deactivator, false});
+       }
+
+       void Presenter::broadcastDeactivator(const SmartEvent event,
+                       void *const deactivator)
+       {
+               if (m_topWidget) {
+                       sendDeactivatorInfo(*m_topWidget, event, {deactivator, true});
+               } else {
+                       ELOG("m_topWidget is NULL!");
+               }
+       }
+
+       void Presenter::sendDeactivatorInfo(Widget &sender,
+                       const SmartEvent event, const DeactivatorInfo &info)
+       {
+               sender.callEvent(event, const_cast<DeactivatorInfo *>(&info));
+       }
+
+       bool Presenter::isActive() const
+       {
+               return isEmpty(m_deactivators);
+       }
+
+       bool Presenter::isDeactivatedBy(void *const deactivator) const
+       {
+               return (m_deactivators.find(deactivator) != m_deactivators.end());
+       }
+
+       void Presenter::activateBy(void *const deactivator)
+       {
+               activateByImpl({deactivator, false});
+       }
+
+       void Presenter::deactivateBy(void *const deactivator)
+       {
+               deactivateByImpl({deactivator, false});
+       }
+
+       void Presenter::activateByImpl(const DeactivatorInfo &info)
+       {
+               const auto count = m_deactivators.erase(info.deactivator);
+               if (m_isPrepared && (count > 0)) {
+                       onActivateBy(info);
+                       if (m_deactivators.size() == 0) {
+                               onActivate();
+                       }
+               }
+       }
+
+       void Presenter::deactivateByImpl(const DeactivatorInfo &info)
+       {
+               if (m_deactivatorExceptions.find(info.deactivator) !=
+                               m_deactivatorExceptions.end()) {
+                       return;
+               }
+               const auto pair = m_deactivators.insert(info.deactivator);
+               if (m_isPrepared && pair.second) {
+                       onDeactivateBy(info);
+                       if (m_deactivators.size() == 1) {
+                               onDeactivate();
+                       }
+               }
+       }
+
+       void Presenter::onActivateBySmart(Widget &widget, void *eventInfo)
+       {
+               activateByImpl(*static_cast<DeactivatorInfo *>(eventInfo));
+       }
+
+       void Presenter::onDeactivateBySmart(Widget &widget, void *eventInfo)
+       {
+               deactivateByImpl(*static_cast<DeactivatorInfo *>(eventInfo));
+       }
+
+       void Presenter::onActivate()
+       {
+       }
+
+       void Presenter::onDeactivate()
+       {
+       }
+
+       void Presenter::onActivateBy(const DeactivatorInfo &info)
+       {
+       }
+
+       void Presenter::onDeactivateBy(const DeactivatorInfo &info)
+       {
+       }
+}
index 1fa4de6edf48553194da52f058e8821f363056e6..42887ed697a0d26c4d95b3a6a188c0b7afbec28c 100644 (file)
@@ -87,7 +87,7 @@ namespace gallery {
        }
 
        ProcessingPresenterSRef ProcessingPresenter::Builder::
-                       build(Widget &parent) const
+                       build(ElmWidget &parent) const
        {
                auto result = makeShared<ProcessingPresenter>(m_iconType);
 
@@ -117,7 +117,7 @@ namespace gallery {
                dismissPopup(true);
        }
 
-       Result ProcessingPresenter::prepare(Widget &parent,
+       Result ProcessingPresenter::prepare(ElmWidget &parent,
                        const TString &processingText,
                        const TString &completeText,
                        const bool forceProgress)
@@ -142,7 +142,7 @@ namespace gallery {
                return RES_OK;
        }
 
-       Result ProcessingPresenter::createWidget(Widget &parent,
+       Result ProcessingPresenter::createWidget(ElmWidget &parent,
                        const TString &processingText)
        {
                m_widget = Layout::Builder().
index 6a407037edd5f96fd1c3861c30e58433fbbe17d8..031da3e32071f358d61c0045f02aa25a8860f6b7 100644 (file)
@@ -72,13 +72,13 @@ namespace gallery {
 
        SelectModePresenter::SelectModePresenter(RefCountObjBase &rc,
                        PageContent &content, const int flags) :
-               RefCountAware(&rc),
+               Presenter(rc),
                m_content(asShared(content)),
                m_flags(flags),
                m_totalCount(0),
                m_selectCount(0),
                m_isVisible(false),
-               m_isActive(true)
+               m_isPopupDismissed(false)
        {
        }
 
@@ -88,11 +88,14 @@ namespace gallery {
                        delRotaryEventHandler(CALLBACK_A(
                                        SelectModePresenter::onRotary), this);
                }
-               dismissPopup(true);
+               deletePopup();
        }
 
        Result SelectModePresenter::prepare()
        {
+               FAIL_RETURN(Presenter::prepare(*m_content),
+                               "Presenter::prepare() failed!");
+
                m_selectButton = makeShared<StyledWidget>(
                                elm_button_add(*m_content), true);
                m_selectButton->setStyle(impl::SELECT_BTN_STYLE);
@@ -117,6 +120,9 @@ namespace gallery {
                                        SelectModePresenter::onRotary), this);
                }
 
+               addDeactivatorException(this);
+               Presenter::prepare(*m_selectButton);
+
                return RES_OK;
        }
 
@@ -148,9 +154,10 @@ namespace gallery {
                }
 
                if (m_isVisible) {
+                       activateBy(m_selectButton.get());
                        doUpdate();
                } else {
-                       dismissPopup(true);
+                       deactivateBy(m_selectButton.get());
                        if ((m_flags & (FLAG_NO_MORE_OPTIONS |
                                        FLAG_NO_DIM_ON_ZERO_SELECT)) == 0) {
                                m_content->setMoreOptionsVisible(true);
@@ -163,21 +170,9 @@ namespace gallery {
                return m_isVisible;
        }
 
-       void SelectModePresenter::setActive(const bool value)
+       void SelectModePresenter::onDeactivate()
        {
-               if (value == m_isActive) {
-                       return;
-               }
-               m_isActive = value;
-
-               if (!m_isActive) {
-                       dismissPopup(true);
-               }
-       }
-
-       bool SelectModePresenter::isActive() const
-       {
-               return m_isActive;
+               deletePopup();
        }
 
        void SelectModePresenter::setBottomButtonText(const TString &value)
@@ -239,7 +234,9 @@ namespace gallery {
 
        void SelectModePresenter::showPopup()
        {
-               m_popup = makeShared<StyledWidget>(elm_ctxpopup_add(*m_content));
+               m_isPopupDismissed = false;
+
+               m_popup = makeShared<StyledWidget>(elm_ctxpopup_add(*m_content), true);
                m_popup->setStyle(impl::SELECT_POPUP_STYLE);
 
                elm_ctxpopup_direction_priority_set(*m_popup,
@@ -275,6 +272,8 @@ namespace gallery {
 
                eext_object_event_callback_add(*m_popup, EEXT_CALLBACK_BACK,
                                CALLBACK_A(SelectModePresenter::onPopupHWBackKey), this);
+
+               broadcastDeactivateBy(this);
        }
 
        void SelectModePresenter::movePopup()
@@ -291,17 +290,23 @@ namespace gallery {
                m_popup->move(cx + (cw / 2), cy + ((ch - ph) / 2));
        }
 
-       void SelectModePresenter::dismissPopup(const bool force)
+       void SelectModePresenter::dismissPopup()
+       {
+               if (m_popup && !m_isPopupDismissed) {
+                       m_isPopupDismissed = true;
+                       elm_ctxpopup_dismiss(*m_popup);
+               }
+       }
+
+       void SelectModePresenter::deletePopup()
        {
                if (m_popup) {
                        eext_object_event_callback_del(*m_popup, EEXT_CALLBACK_BACK,
                                        CALLBACK_A(SelectModePresenter::onPopupHWBackKey));
-                       if (force) {
-                               m_popup->markForDeletion();
-                       } else {
-                               elm_ctxpopup_dismiss(*m_popup);
-                       }
+
                        m_popup.reset();
+
+                       broadcastActivateBy(this);
                }
        }
 
@@ -315,13 +320,15 @@ namespace gallery {
        void SelectModePresenter::onPopupDismissed(
                        Widget &widget, void *eventInfo)
        {
-               widget.markForDeletion();
+               deletePopup();
        }
 
        void SelectModePresenter::onPopupHWBackKey(
                        Evas_Object *obj, void *eventInfo)
        {
-               dismissPopup();
+               if (isActive()) {
+                       dismissPopup();
+               }
        }
 
        void SelectModePresenter::onSelectAll(
@@ -345,7 +352,7 @@ namespace gallery {
        void SelectModePresenter::onSelectBtnClick(
                        Widget &widget, void *eventInfo)
        {
-               if (m_isVisible && m_isActive && !m_popup && (m_totalCount > 0)) {
+               if (isActive() && !m_popup && (m_totalCount > 0)) {
                        showPopup();
                }
        }
@@ -353,14 +360,14 @@ namespace gallery {
        void SelectModePresenter::onBottomBtnClick(
                        Widget &widget, void *eventInfo)
        {
-               if (m_isVisible && m_isActive && !m_popup && (m_selectCount > 0)) {
+               if (isActive() && !m_popup && (m_selectCount > 0)) {
                        dispatchEvent(EVENT_BOTTOM_BUTTON_CLICK);
                }
        }
 
        Eina_Bool SelectModePresenter::onRotary(Eext_Rotary_Event_Info *info)
        {
-               if (m_isVisible && m_isActive) {
+               if (isActive()) {
                        dismissPopup();
                }
                return EINA_TRUE;
index 9510560b08e6fbdd06e1ee089037409f15626861..dc8a55e2ce0851acaef169faaa99939a7d6dc96c 100644 (file)
@@ -88,7 +88,7 @@ namespace gallery {
                return *this;
        }
 
-       ImageGridSRef ImageGrid::Builder::build(Widget &parent) const
+       ImageGridSRef ImageGrid::Builder::build(ElmWidget &parent) const
        {
                Evas_Object *const scrollerEo = elm_scroller_add(parent);
                if (!scrollerEo) {
@@ -216,7 +216,7 @@ namespace gallery {
                public:
                        friend class RefCountObj<Item>;
                        Item(RefCountObjBase &rc,
-                                       const ImageGrid &imageGrid, Widget &parent) :
+                                       const ImageGrid &imageGrid, ElmWidget &parent) :
                                RefCountAware(&rc),
                                m_imageGrid(imageGrid),
                                m_btn(elm_button_add(parent)),
@@ -665,9 +665,9 @@ namespace gallery {
 
        void ImageGrid::createCircleScroller()
        {
-               const auto sfc = getCircleSurface(*m_scroller);
+               const auto sfc = util::getCircleSurface(*m_scroller);
                if (!sfc) {
-                       LOG_RETURN_VOID(RES_FAIL, "getCircleSurface() failed!");
+                       LOG_RETURN_VOID(RES_FAIL, "util::getCircleSurface() failed!");
                }
 
                m_circleScroller = eext_circle_object_scroller_add(*m_scroller, sfc);
@@ -1015,7 +1015,7 @@ namespace gallery {
                for (int i = m_slotCount; i < newSlotCount; ++i) {
                        const bool isOdd = ((m_beginSlotIndex + i) & 1);
 
-                       auto slot = util::makeUnique(new Slot(*this, isOdd));
+                       auto slot = ucl::util::makeUnique(new Slot(*this, isOdd));
 
                        if (m_slotSize == 0) {
                                UCL_ASSERT(!isOdd, "Must be even!");
index 9f3896246da72cbe3878645b814f3dfdcd24f7fa..1cae519abbc669dbcd269662405e034859f988d7 100644 (file)
@@ -45,7 +45,7 @@ namespace gallery {
                return *this;
        }
 
-       ImageViewerSRef ImageViewer::Builder::build(Widget &parent) const
+       ImageViewerSRef ImageViewer::Builder::build(ElmWidget &parent) const
        {
                if ((m_imageW <= 0) || (m_imageH <= 0)) {
                        LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "Image size is invalid");
index cf6ea5c9c29ac6f1f631676eafa833b2bb145a37..6d9f43e2e5459c71770cb7753c557c4099cf5e03 100644 (file)
@@ -69,7 +69,7 @@ namespace gallery {
                return *this;
        }
 
-       PageContentSRef PageContent::Builder::build(Widget &parent) const
+       PageContentSRef PageContent::Builder::build(ElmWidget &parent) const
        {
                auto layout = Layout::Builder().
                                setTheme(impl::LAYOUT_MORE_OPTIONS).
index f7f6e3248e4743b4400853e6c48532d21c58a671..402bf35481428e3dd910a9ff80de211e394301a7 100644 (file)
@@ -30,7 +30,7 @@ namespace gallery { namespace { namespace impl {
        constexpr EoDataKey CIRCLE_SURFACE {"gallery,eext,circle,surface"};
 }}}
 
-namespace gallery {
+namespace gallery { namespace util {
 
        using namespace ucl;
 
@@ -73,6 +73,11 @@ namespace gallery {
 
                return sfc;
        }
+}}
+
+namespace gallery {
+
+       using namespace ucl;
 
        void addRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data)
        {
@@ -99,4 +104,3 @@ namespace gallery {
                return {"layout", "gallery_image", fileName};
        }
 }
-
index 0df33ab2e52d226008d334ba9812ef5148663eca..ec21f450e118b2d1c56e0d52d1b85aece9600fdd 100644 (file)
@@ -32,7 +32,7 @@ namespace ucl {
                        Builder &setEdjeFile(std::string filePath, EdjeGroup group);
                        Builder &setIsOwner(bool value);
                        Builder &setNeedBindToEo(bool value);
-                       LayoutSRef build(Widget &parent) const;
+                       LayoutSRef build(ElmWidget &parent) const;
                private:
                        LayoutTheme m_theme;
                        std::string m_edjeFilePath;
index 73c1d51db615e5348b534e0a344ebb691d5d758b..5a6622242f4087a636735eec76e73e5141808673 100644 (file)
@@ -36,7 +36,7 @@ namespace ucl {
                        Builder();
                        Builder &setStyle(ElmStyle value);
                        Builder &setNeedBindToEo(bool value);
-                       NaviframeSRef build(Widget &parent) const;
+                       NaviframeSRef build(ElmWidget &parent) const;
                private:
                        ElmStyle m_style;
                        bool m_needBindToEo;
index 6cf0e1276a52a1cb0c4f9f22a9b3f7413f79cf7f..1509fc5a8726a206db29d24dff86d92c765d0e22 100644 (file)
@@ -24,7 +24,7 @@ namespace ucl {
 
        // Layout::Builder //
 
-       LayoutSRef Layout::Builder::build(Widget &parent) const
+       LayoutSRef Layout::Builder::build(ElmWidget &parent) const
        {
                Evas_Object *const eo = elm_layout_add(parent);
                if (!eo) {
index f7da68fad7b4187d7bbe54195d39a2c10cede7eb..1d78998e26a4f9b4bd9cbff3692110f7177f6b0c 100644 (file)
@@ -22,7 +22,7 @@ namespace ucl {
 
        // Naviframe::Builder //
 
-       NaviframeSRef Naviframe::Builder::build(Widget &parent) const
+       NaviframeSRef Naviframe::Builder::build(ElmWidget &parent) const
        {
                Evas_Object *const eo = elm_naviframe_add(parent);
                if (!eo) {