--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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));
+ }
+ }
+}