--- /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 UI_POPUP_H
+#define UI_POPUP_H
+
+#include "Ui/Control.h"
+#include <functional>
+
+namespace Ui
+{
+ class View;
+ class Window;
+
+ class EXPORT_API Popup : public Control
+ {
+ public:
+ /**
+ * @brief Popup button press callback.
+ * @return Whether to close the popup.
+ */
+ typedef std::function<bool()> ButtonCallback;
+
+ Popup();
+ virtual ~Popup() override;
+
+ /**
+ * @brief Allows method overload instead of shadowing.
+ */
+ using Control::create;
+
+ /**
+ * @brief Create popup with title, text and close button.
+ * @param[in] parent Popup parent
+ * @param[in] title Popup title
+ * @param[in] text Popup text
+ * @param[in] buttonText Text for close button
+ * @return Created popup.
+ */
+ static Popup *create(Evas_Object *parent, const char *title,
+ const char *text, const char *buttonText);
+
+ /**
+ * @brief Set Popup title.
+ * @param[in] title Popup title
+ */
+ void setTitle(const char *title);
+
+ /**
+ * @brief Set Popup text.
+ * @param[in] text Popup text
+ */
+ void setText(const char *text);
+
+ /**
+ * @brief Set Popup content.
+ * @param[in] content Popup content
+ */
+ void setContent(Evas_Object *content);
+
+ /**
+ * @brief Set callback to be called when Popup is canceled.
+ * @param[in] callback Cancel callback
+ */
+ void setCancelCallback(ButtonCallback callback);
+
+ /**
+ * @brief Add Popup button.
+ * @param[in] text Button text
+ * @param[in] callback Button click callback
+ * @return Added button on success, otherwise nullptr.
+ */
+ Evas_Object *addButton(const char *text, ButtonCallback callback = nullptr);
+
+ /**
+ * @brief Show popup with animation.
+ */
+ void show();
+
+ /**
+ * @brief Close popup with animation.
+ */
+ void close();
+
+ protected:
+ /**
+ * @see Control::onCreate()
+ */
+ virtual Evas_Object *onCreate(Evas_Object *parent) override;
+
+ private:
+ void onCanceled();
+
+ void onViewNavigation(Evas_Object *obj, void *eventInfo);
+ void onViewDestroy(Evas *e, Evas_Object *obj, void *eventInfo);
+
+ void onButtonPressed(Evas_Object *obj, void *eventInfo);
+ void onButtonDestroy(Evas *e, Evas_Object *obj, void *eventInfo);
+ void onBackPressed(Evas_Object *obj, void *eventInfo);
+ void onBlockPressed(Evas_Object *obj, void *eventInfo);
+ void onDismissed(Evas_Object *obj, void *eventInfo);
+
+ size_t m_ButtonCount;
+ ButtonCallback m_OnCanceled;
+
+ View *m_View;
+ Window *m_Window;
+ };
+}
+
+#endif /* UI_POPUP_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 "Ui/Popup.h"
+#include "Ui/View.h"
+#include "Ui/Window.h"
+#include "Utils/Callback.h"
+#include "Utils/Range.h"
+
+#include <efl_extension.h>
+
+#define BUTTON_DATA_KEY "callback"
+
+using namespace Ui;
+
+Popup::Popup()
+ : m_ButtonCount(0), m_View(nullptr), m_Window(nullptr)
+{
+}
+
+Popup::~Popup()
+{
+ if (m_View) {
+ evas_object_smart_callback_del_full(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION,
+ makeCallback(&Popup::onViewNavigation), this);
+ evas_object_event_callback_del_full(m_View->getEvasObject(), EVAS_CALLBACK_DEL,
+ makeCallback(&Popup::onViewDestroy), this);
+ }
+}
+
+Popup *Popup::create(Evas_Object *parent, const char *title,
+ const char *text, const char *buttonText)
+{
+ Popup *popup = new Popup();
+ popup->create(parent);
+ popup->setTitle(title);
+ popup->setText(text);
+ popup->addButton(buttonText);
+ return popup;
+}
+
+void Popup::setTitle(const char *title)
+{
+ elm_object_translatable_part_text_set(getEvasObject(), "title,text", title);
+}
+
+void Popup::setText(const char *text)
+{
+ elm_object_translatable_part_text_set(getEvasObject(), "elm.text", text);
+}
+
+void Popup::setContent(Evas_Object *content)
+{
+ elm_object_part_content_set(getEvasObject(), "elm.swallow.content", content);
+}
+
+void Popup::setCancelCallback(ButtonCallback callback)
+{
+ m_OnCanceled = std::move(callback);
+}
+
+Evas_Object *Popup::addButton(const char *text, ButtonCallback callback)
+{
+ static const char *parts[] = { "button1", "button2", "button3" };
+ const char *part = Utils::at(parts, m_ButtonCount);
+ if (!part) {
+ return nullptr;
+ }
+
+ Evas_Object *button = elm_button_add(getEvasObject());
+ elm_object_style_set(button, "bottom");
+ elm_object_translatable_text_set(button, text);
+ elm_object_part_content_set(getEvasObject(), part, button);
+
+ evas_object_data_set(button, BUTTON_DATA_KEY, new ButtonCallback(std::move(callback)));
+ evas_object_event_callback_add(button, EVAS_CALLBACK_DEL,
+ makeCallback(&Popup::onButtonDestroy), this);
+ evas_object_smart_callback_add(button, "clicked",
+ makeCallback(&Popup::onButtonPressed), this);
+
+ ++m_ButtonCount;
+ return button;
+}
+
+void Popup::show()
+{
+ evas_object_show(getEvasObject());
+}
+
+void Popup::close()
+{
+ elm_popup_dismiss(getEvasObject());
+}
+
+Evas_Object *Popup::onCreate(Evas_Object *parent)
+{
+ m_View = findParent<View>(parent);
+ if (m_View) {
+ evas_object_smart_callback_add(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION,
+ makeCallback(&Popup::onViewNavigation), this);
+ evas_object_event_callback_add(m_View->getEvasObject(), EVAS_CALLBACK_DEL,
+ makeCallback(&Popup::onViewDestroy), this);
+ }
+
+ m_Window = findParent<Window>(parent);
+ if (m_Window) {
+ parent = m_Window->getBaseLayout();
+ }
+
+ Evas_Object *popup = elm_popup_add(parent);
+ elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
+ evas_object_smart_callback_add(popup, "dismissed",
+ makeCallback(&Popup::onDismissed), this);
+ evas_object_smart_callback_add(popup, "block,clicked",
+ makeCallback(&Popup::onBlockPressed), this);
+ eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK,
+ makeCallback(&Popup::onBackPressed), this);
+
+ return popup;
+}
+
+void Popup::onCanceled()
+{
+ if (!m_OnCanceled || m_OnCanceled()) {
+ close();
+ }
+}
+
+void Popup::onViewNavigation(Evas_Object *obj, void *eventInfo)
+{
+ if (!eventInfo) {
+ /* Don't close the popup if navigation is caused by window losing focus */
+ if (!m_Window || elm_win_focus_get(m_Window->getEvasObject())) {
+ onCanceled();
+ }
+ }
+}
+
+void Popup::onViewDestroy(Evas *e, Evas_Object *obj, void *eventInfo)
+{
+ m_View = nullptr;
+}
+
+void Popup::onButtonPressed(Evas_Object *obj, void *eventInfo)
+{
+ ButtonCallback *callback = (ButtonCallback *) evas_object_data_get(obj, BUTTON_DATA_KEY);
+ if (!(*callback)) {
+ callback = &m_OnCanceled;
+ }
+ if (!(*callback) || (*callback)()) {
+ close();
+ }
+}
+
+void Popup::onButtonDestroy(Evas *e, Evas_Object *obj, void *eventInfo)
+{
+ ButtonCallback *callback = (ButtonCallback *) evas_object_data_get(obj, BUTTON_DATA_KEY);
+ delete callback;
+}
+
+void Popup::onBlockPressed(Evas_Object *obj, void *eventInfo)
+{
+ if (m_ButtonCount == 0) {
+ onCanceled();
+ }
+}
+
+void Popup::onBackPressed(Evas_Object *obj, void *eventInfo)
+{
+ onCanceled();
+}
+
+void Popup::onDismissed(Evas_Object *obj, void *eventInfo)
+{
+ delete this;
+}
--- /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 "Ui/Toast.h"
+#include "Ui/Window.h"
+
+using namespace Ui;
+
+Evas_Object *Toast::onCreate(Evas_Object *parent)
+{
+ Evas_Object *popup = Popup::onCreate(findParent<Window>(parent)->getEvasObject());
+ elm_object_style_set(popup, "toast");
+ elm_popup_timeout_set(popup, 2.0);
+ evas_object_smart_callback_add(popup, "timeout",
+ [](void *data, Evas_Object *popup, void *) {
+ elm_popup_dismiss(popup);
+ }, this);
+
+ return popup;
+}