TizenRefApp-8418 [Gallery] Implement AlertDialog 98/126598/1
authorIgor Nazarov <i.nazarov@samsung.com>
Fri, 21 Apr 2017 15:56:16 +0000 (18:56 +0300)
committerIgor Nazarov <i.nazarov@samsung.com>
Fri, 21 Apr 2017 15:56:16 +0000 (18:56 +0300)
- Implemented AlerdDialog presenter;
- Page builders changed to return WeakRefs;
- Other minor changes.

Change-Id: I059ffc02d239365265bb7bc4333328a97a69be4b

18 files changed:
edc/images.edc
edc/images/tw_ic_popup_btn_check.png [new file with mode: 0644]
edc/images/tw_ic_popup_btn_delete.png [new file with mode: 0644]
inc/presenters/AlertDialog.h [new file with mode: 0644]
inc/presenters/NoContentPage.h
inc/presenters/PreviewPage.h
inc/presenters/SelectModePresenter.h
inc/presenters/ThumbnailPage.h
inc/presenters/ViewerPage.h
inc/presenters/types.h
inc/resources.h
inc/view/ImageGrid.h
src/presenters/AlertDialog.cpp [new file with mode: 0644]
src/presenters/NoContentPage.cpp
src/presenters/PreviewPage.cpp
src/presenters/ThumbnailPage.cpp
src/presenters/ViewerPage.cpp
ucl/inc/ucl/util/types/classTypes.h

index 0caacb31385786b196ec9da4d7b0baf41d1b9d64..0a6d36237edf97197e7b0a7862c725fba5c59d2d 100644 (file)
@@ -40,3 +40,6 @@ RES_SQUARE_IMAGE("gallery_icon_no_photos.png", 98, GALLERY_COLOR_WHITE)
 RES_SQUARE_IMAGE("gallery_more_opt_delete.png", 68, GALLERY_COLOR_WHITE)
 RES_SQUARE_IMAGE("gallery_more_opt_save.png", 68, GALLERY_COLOR_WHITE)
 RES_SQUARE_IMAGE("gallery_more_opt_send_to_mobile.png", 68, GALLERY_COLOR_WHITE)
+
+RES_SQUARE_IMAGE("tw_ic_popup_btn_check.png", 50, GALLERY_COLOR_WHITE)
+RES_SQUARE_IMAGE("tw_ic_popup_btn_delete.png", 50, GALLERY_COLOR_WHITE)
diff --git a/edc/images/tw_ic_popup_btn_check.png b/edc/images/tw_ic_popup_btn_check.png
new file mode 100644 (file)
index 0000000..3dce121
Binary files /dev/null and b/edc/images/tw_ic_popup_btn_check.png differ
diff --git a/edc/images/tw_ic_popup_btn_delete.png b/edc/images/tw_ic_popup_btn_delete.png
new file mode 100644 (file)
index 0000000..58de36c
Binary files /dev/null and b/edc/images/tw_ic_popup_btn_delete.png differ
diff --git a/inc/presenters/AlertDialog.h b/inc/presenters/AlertDialog.h
new file mode 100644 (file)
index 0000000..59e0912
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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_ALERT_DIALOG_H__
+#define __GALLERY_PRESENTERS_ALERT_DIALOG_H__
+
+#include "ucl/gui/StyledWidget.h"
+#include "ucl/gui/Layout.h"
+
+#include "types.h"
+
+namespace gallery {
+
+       class AlertDialog final : public ucl::RefCountAware,
+                       public ucl::IDisposable {
+       public:
+               enum class Type {
+                       OK_CANCEL
+               };
+
+               enum Event {
+                       EVENT_CANCEL,
+                       EVENT_OK,
+                       EVENT_BACK
+               };
+
+               using EventHandler = ucl::WeakDelegate<
+                               bool(AlertDialog &dialog, int event)>;
+
+               class Builder {
+               public:
+                       Builder();
+                       Builder &setType(Type type);
+                       Builder &setTitle(ucl::TString title);
+                       Builder &setText(ucl::TString text);
+                       Builder &setHandler(const EventHandler &handler);
+                       AlertDialogWRef build(ucl::Widget &parent) const;
+               private:
+                       Type m_type;
+                       ucl::TString m_title;
+                       ucl::TString m_text;
+                       EventHandler m_handler;
+               };
+
+       public:
+               void dismiss();
+
+               // ucl::IDisposable //
+
+               virtual void dispose() final override;
+               virtual bool isDisposed() const final override;
+
+       private:
+               friend class ucl::RefCountObj<AlertDialog>;
+               AlertDialog(ucl::RefCountObjBase &rc,
+                               const EventHandler &handler);
+               virtual ~AlertDialog();
+
+               ucl::Result prepare(ucl::Widget &parent, Type type);
+               ucl::Result createPopup(ucl::Widget &parent, ucl::ElmStyle style);
+               ucl::Result createLayout(ucl::LayoutTheme theme);
+               ucl::Result createButton(Event event, ucl::EdjePart part,
+                               ucl::ElmStyle btnStyle, ucl::LayoutTheme iconTheme,
+                               const ucl::TString &text = nullptr);
+
+               void setTitle(const ucl::TString &title);
+               void setText(const ucl::TString &text);
+
+               void handleEvent(Event event);
+               bool dispatchEvent(Event event);
+
+               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);
+
+       private:
+               const EventHandler m_handler;
+               ucl::StyledWidgetSRef m_popup;
+               ucl::LayoutWRef m_layout;
+               bool m_isDismissed;
+       };
+}
+
+#endif // __GALLERY_PRESENTERS_ALERT_DIALOG_H__
index 67008e5c185d0f255d0fadfe20cc684217c3a215..639feb2f04abe90dcd04e9dda66d11e4a0823df3 100644 (file)
@@ -28,7 +28,7 @@ namespace gallery {
                        Builder();
                        ~Builder();
                        Builder &setNaviframe(const ucl::NaviframeSRef &navi);
-                       NoContentPageSRef build(ExitRequestHandler onExitRequest) const;
+                       NoContentPageWRef build(ExitRequestHandler onExitRequest) const;
                private:
                        ucl::NaviframeSRef m_navi;
                };
index 7bae7c3094694ba33afce0009589bbe15e5eb63e..64a0a8cfb0bb804bb58e30adff01b7162a46389a 100644 (file)
@@ -34,7 +34,7 @@ namespace gallery {
                        Builder &setAlbum(const IMediaAlbumSRef &album);
                        Builder &setStartItemIndex(int index);
                        Builder &setSelectModeStartup(bool value);
-                       PreviewPageSRef build(ExitRequestHandler onExitRequest) const;
+                       PreviewPageWRef build(ExitRequestHandler onExitRequest) const;
                private:
                        ucl::NaviframeSRef m_navi;
                        IMediaAlbumSRef m_album;
index 20fc1d17090c946b591c5336301624222756d875..73924a4a3a1b89f98bdfb743d3c6c34e594cfb7e 100644 (file)
@@ -25,10 +25,11 @@ namespace gallery {
 
        class SelectModePresenter final : public ucl::RefCountAware {
        public:
-               enum Event {
-                       EVENT_SELECT_ALL,
-                       EVENT_DESELECT_ALL,
-                       EVENT_BOTTOM_BUTTON_CLICK
+               enum {
+                       FLAG_NO_BOTTOM_BUTTON = 1,
+                       FLAG_NO_MORE_OPTIONS = 2,
+                       FLAG_NO_DIM_ON_ZERO_SELECT = 4,
+                       FLAG_NO_DISMISS_ON_ROTARY = 8
                };
 
                class Builder {
@@ -40,11 +41,10 @@ namespace gallery {
                        int m_flags;
                };
 
-               enum {
-                       FLAG_NO_BOTTOM_BUTTON = 1,
-                       FLAG_NO_MORE_OPTIONS = 2,
-                       FLAG_NO_DIM_ON_ZERO_SELECT = 4,
-                       FLAG_NO_DISMISS_ON_ROTARY = 8
+               enum Event {
+                       EVENT_SELECT_ALL,
+                       EVENT_DESELECT_ALL,
+                       EVENT_BOTTOM_BUTTON_CLICK
                };
 
        public:
index 941ce9051d93527bbcacf0f2b1e5f16f104952c8..07ade6e4aa0f5eb352f08ef7ffca9b438c8f2dd0 100644 (file)
@@ -32,7 +32,7 @@ namespace gallery {
                        ~Builder();
                        Builder &setNaviframe(const ucl::NaviframeSRef &navi);
                        Builder &setAlbum(const IMediaAlbumSRef &album);
-                       ThumbnailPageSRef build(ExitRequestHandler onExitRequest) const;
+                       ThumbnailPageWRef build(ExitRequestHandler onExitRequest) const;
                private:
                        ucl::NaviframeSRef m_navi;
                        IMediaAlbumSRef m_album;
index c944dc425680733cecae78a01b58102c4f7beb53..8fa80e2317c8a355268d9d43a42f2e02afb51913 100644 (file)
@@ -31,7 +31,7 @@ namespace gallery {
                        Builder &setMedia(const MediaItemSRef &media);
                        Builder &setZoomIn(int x, int y);
                        Builder &setExitOnZoomOut(bool value);
-                       ViewerPageSRef build(ExitRequestHandler onExitRequest) const;
+                       ViewerPageWRef build(ExitRequestHandler onExitRequest) const;
                private:
                        ucl::NaviframeSRef m_navi;
                        MediaItemSRef m_media;
index a8a7d059850166024eb195a59fce953d545fe049..726bb13a591938d1042d849cffb96c6f20b2166e 100644 (file)
@@ -40,6 +40,8 @@ namespace gallery {
        UCL_DECLARE_REF_ALIASES(ISelectModeListener);
        UCL_DECLARE_REF_ALIASES(SelectModePresenter);
 
+       UCL_DECLARE_REF_ALIASES(AlertDialog);
+
        UCL_DECLARE_REF_ALIASES(Page);
 
        UCL_DECLARE_REF_ALIASES(NoContentPage);
index 09030517ccd94aa397d675a80ab39e36f40624ed..f230a1f7cab38f3e1924635fa9465a5a6d82f7d9 100644 (file)
@@ -31,6 +31,9 @@ namespace gallery {
        constexpr auto ICON_MORE_OPT_SAVE = "gallery_more_opt_save.png";
        constexpr auto ICON_MORE_OPT_SEND = "gallery_more_opt_send_to_mobile.png";
 
+       constexpr auto ICON_POPUP_OK = "tw_ic_popup_btn_check.png";
+       constexpr auto ICON_POPUP_CANCEL = "tw_ic_popup_btn_delete.png";
+
        extern const ucl::TString STR_APP_NAME;
        extern const ucl::TString STR_NO_PHOTOS;
        extern const ucl::TString STR_SELECT_ALL;
index 92fe0345b88b2c0e0de27197869bdf614927eb00..18304fa16e9cac889ff2411f31d38647d9c1a953 100644 (file)
@@ -32,12 +32,6 @@ namespace gallery {
                        LINEAR
                };
 
-               enum ItemEvent {
-                       ITEM_EVENT_CLICK,
-                       ITEM_EVENT_DOUBLE_TAP,
-                       ITEM_EVENT_TAP_AND_HOLD
-               };
-
                class Builder {
                public:
                        Builder();
@@ -51,6 +45,12 @@ namespace gallery {
                        bool m_selectModeStartup;
                };
 
+               enum ItemEvent {
+                       ITEM_EVENT_CLICK,
+                       ITEM_EVENT_DOUBLE_TAP,
+                       ITEM_EVENT_TAP_AND_HOLD
+               };
+
                enum {
                        UF_LOSE_IMAGE = 1,
                        UF_LOSE_BG = 2,
diff --git a/src/presenters/AlertDialog.cpp b/src/presenters/AlertDialog.cpp
new file mode 100644 (file)
index 0000000..26bf265
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * 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/AlertDialog.h"
+
+#include "resources.h"
+#include "common.h"
+
+namespace gallery { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr EoDataKey BTN_EVENT_DATA {"gallery,btn,event,data"};
+
+       constexpr ElmStyle POPUP_STYLE {"circle"};
+       constexpr EdjePart PART_BUTTON1 {"button1"};
+       constexpr EdjePart PART_BUTTON2 {"button2"};
+
+       constexpr ElmStyle LEFT_POPUP_BTN_STYLE {"popup/circle/left"};
+       constexpr ElmStyle RIGHT_POPUP_BTN_STYLE {"popup/circle/right"};
+
+       constexpr LayoutTheme LAYOUT_POPUP_2BUTTONS
+                       {"layout", "popup", "content/circle/buttons2"};
+
+       void *asData(const AlertDialog::Event event)
+       {
+               return reinterpret_cast<void *>(static_cast<intptr_t>(event));
+       }
+
+       AlertDialog::Event asEvent(void *const data)
+       {
+               return static_cast<AlertDialog::Event>(
+                               reinterpret_cast<intptr_t>(data));
+       }
+
+       AlertDialog::Event getEvent(const Widget &widget)
+       {
+               return asEvent(widget.getData(BTN_EVENT_DATA));
+       }
+}}}
+
+namespace gallery {
+
+       using namespace ucl;
+
+       // AlertDialog::Builder //
+
+       AlertDialog::Builder::Builder() :
+               m_type(Type::OK_CANCEL)
+       {
+       }
+
+       AlertDialog::Builder &AlertDialog::Builder::setType(const Type type)
+       {
+               m_type = type;
+               return *this;
+       }
+
+       AlertDialog::Builder &AlertDialog::Builder::setTitle(TString title)
+       {
+               m_title = std::move(title);
+               return *this;
+       }
+
+       AlertDialog::Builder &AlertDialog::Builder::setText(TString text)
+       {
+               m_text = std::move(text);
+               return *this;
+       }
+
+       AlertDialog::Builder &AlertDialog::Builder::setHandler(
+                       const EventHandler &handler)
+       {
+               m_handler = handler;
+               return *this;
+       }
+
+       AlertDialogWRef AlertDialog::Builder::build(Widget &parent) const
+       {
+               if (!m_handler) {
+                       LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "m_handler is NULL");
+               }
+
+               auto result = makeShared<AlertDialog>(m_handler);
+
+               FAIL_RETURN_VALUE(result->prepare(parent, m_type), {},
+                               "result->prepare() failed!");
+
+               result->setTitle(m_title);
+               result->setText(m_text);
+
+               return result;
+       }
+
+       // AlertDialog //
+
+       AlertDialog::AlertDialog(RefCountObjBase &rc,
+                       const EventHandler &handler) :
+               RefCountAware(&rc),
+               m_handler(handler),
+               m_isDismissed(false)
+       {
+       }
+
+       AlertDialog::~AlertDialog()
+       {
+       }
+
+       Result AlertDialog::prepare(Widget &parent, const Type type)
+       {
+               FAIL_RETURN(createPopup(parent, impl::POPUP_STYLE),
+                               "createPopup() failed!");
+
+               FAIL_RETURN(createLayout(impl::LAYOUT_POPUP_2BUTTONS),
+                               "createLayout() failed!");
+
+               FAIL_RETURN(createButton(EVENT_CANCEL, impl::PART_BUTTON1,
+                               impl::LEFT_POPUP_BTN_STYLE, getImageTheme(ICON_POPUP_CANCEL)),
+                               "createButton() failed!");
+
+               FAIL_RETURN(createButton(EVENT_OK, impl::PART_BUTTON2,
+                               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;
+       }
+
+       void AlertDialog::onPopupDel(Widget &widget, void *eventInfo)
+       {
+               eext_object_event_callback_del(widget, EEXT_CALLBACK_BACK,
+                               CALLBACK_A(AlertDialog::onPopupHWBackKey));
+               m_rc->unref();
+       }
+
+       Result AlertDialog::createPopup(Widget &parent, const ElmStyle style)
+       {
+               Evas_Object *const popupEo = elm_popup_add(parent);
+               if (!popupEo) {
+                       LOG_RETURN(RES_FAIL, "elm_popup_add() failed!");
+               }
+
+               m_popup = makeShared<StyledWidget>(popupEo, true);
+               m_popup->setStyle(style);
+
+               show(*m_popup);
+
+               m_popup->addEventHandler(POPUP_DISMISSED, WEAK_DELEGATE(
+                               AlertDialog::onPopupDismissed, asWeak(*this)));
+
+               eext_object_event_callback_add(*m_popup, EEXT_CALLBACK_BACK,
+                               CALLBACK_A(AlertDialog::onPopupHWBackKey), this);
+
+               return RES_OK;
+       }
+
+       Result AlertDialog::createLayout(const LayoutTheme theme)
+       {
+               m_layout = Layout::Builder().
+                               setTheme(theme).
+                               build(*m_popup);
+               if (!m_layout) {
+                       LOG_RETURN(RES_FAIL, "Layout::build() failed!");
+               }
+
+               m_popup->setContent(*m_layout);
+
+               return RES_OK;
+       }
+
+       Result AlertDialog::createButton(const Event event,
+                       const EdjePart part, const ElmStyle btnStyle,
+                       const LayoutTheme iconTheme, const TString &text)
+       {
+               const auto btn = makeShared<StyledWidget>(elm_button_add(*m_popup));
+               btn->setStyle(btnStyle);
+               m_popup->setContent(*btn, part);
+
+               if (isValid(iconTheme)) {
+                       const auto icon = Layout::Builder().
+                                       setTheme(iconTheme).
+                                       build(*btn);
+                       if (!icon) {
+                               LOG_RETURN(RES_FAIL, "Layout::build() failed!");
+                       }
+                       btn->setContent(*icon);
+               }
+
+               if (isNotEmpty(text)) {
+                       btn->setText(text);
+               }
+
+               show(*btn);
+
+               btn->setData(impl::BTN_EVENT_DATA, impl::asData(event));
+               btn->addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
+                               AlertDialog::onBtnClick, asWeak(*this)));
+
+               return RES_OK;
+       }
+
+       void AlertDialog::setTitle(const TString &title)
+       {
+               if (m_layout) {
+                       m_layout->setText(title, PART_TITLE);
+               }
+       }
+
+       void AlertDialog::setText(const TString &text)
+       {
+               if (m_layout) {
+                       m_layout->setText(text);
+               }
+       }
+
+       void AlertDialog::dismiss()
+       {
+               if (m_popup && !m_isDismissed) {
+                       m_isDismissed = true;
+                       elm_popup_dismiss(*m_popup);
+               }
+       }
+
+       void AlertDialog::dispose()
+       {
+               if (m_popup) {
+                       m_popup->markForDeletion();
+                       m_popup.reset();
+               }
+       }
+
+       bool AlertDialog::isDisposed() const
+       {
+               return !!m_popup;
+       }
+
+       void AlertDialog::handleEvent(const Event event)
+       {
+               const auto keepAliver = asShared(*this);
+               if (dispatchEvent(event)) {
+                       dismiss();
+               }
+       }
+
+       bool AlertDialog::dispatchEvent(const Event event)
+       {
+               if (!m_handler) {
+                       WLOG("Handler was destroyed!");
+                       return true;
+               }
+               return m_handler(*this, event);
+       }
+
+       void AlertDialog::onPopupDismissed(Widget &widget, void *eventInfo)
+       {
+               dispose();
+       }
+
+       void AlertDialog::onPopupHWBackKey(Evas_Object *obj, void *eventInfo)
+       {
+               if (!m_isDismissed) {
+                       handleEvent(EVENT_BACK);
+               }
+       }
+
+       void AlertDialog::onBtnClick(Widget &widget, void *eventInfo)
+       {
+               if (!m_isDismissed) {
+                       handleEvent(impl::getEvent(widget));
+               }
+       }
+}
index 8d72c3dc7a1fa247b0d09ea95d1e8c1963f84caa..535b6e99582a51e0c94ff5b744f4898fab5dc487 100644 (file)
@@ -42,7 +42,7 @@ namespace gallery {
                return *this;
        }
 
-       NoContentPageSRef NoContentPage::Builder::build(
+       NoContentPageWRef NoContentPage::Builder::build(
                        const ExitRequestHandler onExitRequest) const
        {
                if (!onExitRequest) {
index f7ee75fa4efeb421d7457a3506806add6b809624..0354a0f02bf12d538973e135bd70ea39f52ab915 100644 (file)
@@ -75,7 +75,7 @@ namespace gallery {
                return *this;
        }
 
-       PreviewPageSRef PreviewPage::Builder::build(
+       PreviewPageWRef PreviewPage::Builder::build(
                        const ExitRequestHandler onExitRequest) const
        {
                if (!onExitRequest) {
index d07a3405ca5e600ab5a3f6fec919ebb90be87b95..e2bb389a31269995f8a3921bca8a1d71e935115a 100644 (file)
@@ -59,7 +59,7 @@ namespace gallery {
                return *this;
        }
 
-       ThumbnailPageSRef ThumbnailPage::Builder::build(
+       ThumbnailPageWRef ThumbnailPage::Builder::build(
                        const ExitRequestHandler onExitRequest) const
        {
                if (!onExitRequest) {
index a6944b8dd32ec1dd6f64c82bcec95ea234f3196b..5d8242bbe4d213eebed16cbab930bc961fbc2cd3 100644 (file)
@@ -68,7 +68,7 @@ namespace gallery {
                return *this;
        }
 
-       ViewerPageSRef ViewerPage::Builder::build(
+       ViewerPageWRef ViewerPage::Builder::build(
                        const ExitRequestHandler onExitRequest) const
        {
                if (!onExitRequest) {
index b340c34183c15cdf143c8b9c0b09acd7120df89a..89d33dd41bb6cf9f15aa3c9bed6182f24edb3f23 100644 (file)
@@ -39,6 +39,7 @@ namespace ucl {
        class IDisposable : public Polymorphic {
        public:
                virtual void dispose() = 0;
+               virtual bool isDisposed() const = 0;
        protected:
                virtual ~IDisposable() = default;
        };