From: Hermet Park Date: Tue, 29 Mar 2016 02:35:56 +0000 (+0900) Subject: introduce ui_base_popup. X-Git-Tag: submit/tizen/20160617.075742~77^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=11604867fbac7c9dd9b90b11d0192f58cb5f9d44;p=platform%2Fcore%2Fuifw%2Fui-viewmgr.git introduce ui_base_popup. Change-Id: I62a256af1f4ad2fda3df3c4c37a13eefcba12ac1 --- diff --git a/src/examples/efl/CMakeLists.txt b/src/examples/efl/CMakeLists.txt index 319eadb..225f69c 100644 --- a/src/examples/efl/CMakeLists.txt +++ b/src/examples/efl/CMakeLists.txt @@ -3,6 +3,7 @@ SET(EXAM_SRCS ../../lib/interface/ui_iface_controller.cpp ../../lib/interface/ui_iface_view.cpp ../../lib/interface/ui_iface_viewmgr.cpp + ../../lib/efl/ui_base_popup.cpp ../../lib/efl/ui_base_controller.cpp ../../lib/efl/ui_base_view.cpp ../../lib/efl/ui_base_viewmgr.cpp diff --git a/src/examples/efl/page13.h b/src/examples/efl/page13.h index dfc6773..c9e0db1 100644 --- a/src/examples/efl/page13.h +++ b/src/examples/efl/page13.h @@ -19,6 +19,16 @@ * And make a button on right top side of title area to activate popup. * The created popup has view and it will be managed by viewmgr. */ + +static void popup_dismissed_cb(void *data, Evas_Object *obj, void *event_info) +{ + //FIXME: remove dismissed callback because this callback is called twice. + //It seems this is an efl or popup error, not this ui_popup nor example. + evas_object_smart_callback_del(obj, "dismissed", popup_dismissed_cb); + ui_base_popup *overlay = static_cast(data); + delete (overlay); +} + class page13: public ui_view { private: @@ -70,36 +80,31 @@ public: void create_popup() { -#if 0 - ui_popup_view *view = new ui_popup_view(this); - - Evas_Object *popup = elm_popup_add(view->get_base()); + //FIXME: is overlay a proper name? + ui_base_popup *overlay = new ui_base_popup(this); - elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + Elm_Popup *popup = elm_popup_add(overlay->get_base()); elm_object_text_set(popup, "This popup has only text which is set via desc set function, (This popup gets hidden when user clicks outside) here timeout of 3 sec is set."); elm_popup_timeout_set(popup, 3.0); + evas_object_smart_callback_add(popup, "dismissed", popup_dismissed_cb, overlay); evas_object_smart_callback_add(popup, "block,clicked", [](void *data, Evas_Object *obj, void *event_info) -> void { - evas_object_del(obj); + elm_popup_dismiss(obj); }, NULL); evas_object_smart_callback_add(popup, "timeout", [](void *data, Evas_Object *obj, void *event_info) -> void { - evas_object_del(obj); + elm_popup_dismiss(obj); }, NULL); - evas_object_show(popup); - - view->set_content(popup); - view->activate(); -#endif + overlay->set_content(popup); + overlay->activate(); } }; void create_page13(appdata_s *ad) { - /* A example for view class extension instead of using controller class. */ new page13("page13", ad); } diff --git a/src/include/efl/ui_base_popup.h b/src/include/efl/ui_base_popup.h new file mode 100644 index 0000000..a6f690a --- /dev/null +++ b/src/include/efl/ui_base_popup.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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_BASE_POPUP_H +#define UI_BASE_POPUP_H + +#include "../interface/ui_viewmanager_interface.h" + +namespace efl_viewmgr +{ +class ui_base_view; + +class ui_base_popup : public viewmgr::ui_iface_rotatable +{ + friend class ui_base_view; +private: + ui_base_view *view; + Elm_Popup *popup; + + Elm_Win *get_window(); + +public: + ui_base_popup(ui_base_view *view); + virtual ~ui_base_popup(); + + virtual bool activate(); + virtual bool deactivate(); + virtual bool set_content(Elm_Ctxpopup* ctxpopup); + virtual Elm_Popup *unset_content(); + virtual void on_back(); + virtual bool is_activated(); + + virtual Evas_Object *get_base(); + virtual int get_degree(); + virtual Elm_Popup *get_content() + { + return this->popup; + } +}; + +} + +#endif /* UI_BASE_POPUP_H */ diff --git a/src/include/efl/ui_base_view.h b/src/include/efl/ui_base_view.h index b0e95a1..d1e7c08 100644 --- a/src/include/efl/ui_base_view.h +++ b/src/include/efl/ui_base_view.h @@ -26,6 +26,7 @@ namespace efl_viewmgr { class ui_base_controller; +class ui_base_popup; /** * @class ui_base_view @@ -42,6 +43,14 @@ class ui_base_controller; class ui_base_view: public viewmgr::ui_iface_view, public viewmgr::ui_iface_rotatable { friend class ui_base_viewmgr; + friend class ui_base_popup; + +private: + list popup_list; + + void connect_popup(ui_base_popup *popup); + void disconnect_popup(ui_base_popup *popup); + bool deactivate_popup(bool top_one); protected: /** @brief Unload current view's content @@ -78,6 +87,14 @@ protected: */ virtual void on_landscape(); + /** @brief view deactivate state. + * + * @note this state will be triggered by ui_iface_viewmgr. + * + * @see ui_iface_controller for this state in detail. + */ + virtual void on_deactivate(); + public: ///Constructor. ui_base_view(ui_base_controller *controller, const char *name = NULL); diff --git a/src/include/efl/ui_viewmanager_base.h b/src/include/efl/ui_viewmanager_base.h index dc9c759..c2659ec 100644 --- a/src/include/efl/ui_viewmanager_base.h +++ b/src/include/efl/ui_viewmanager_base.h @@ -25,4 +25,4 @@ #include "ui_base_controller.h" #include "ui_base_view.h" #include "ui_base_key_listener.h" - +#include "ui_base_popup.h" diff --git a/src/include/interface/ui_iface_viewmgr.h b/src/include/interface/ui_iface_viewmgr.h index afdd8b4..4cfe687 100644 --- a/src/include/interface/ui_iface_viewmgr.h +++ b/src/include/interface/ui_iface_viewmgr.h @@ -44,7 +44,7 @@ class ui_iface_viewmgr private: static bool soft_key; //If system doesn't support HW back key, then this value is @c true. static bool event_block; //Event block on view transition. This value should be configurable by system. - list view_list; //View list. + list view_list; //View list. bool activated; //Activated status of this viewmgr. /** @@ -107,6 +107,7 @@ protected: */ bool pop_view_finished(ui_iface_view *view); +//FIXME: Necessary? #if 0 /** * @brief Return a list of views which this viewmgr has. diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 0163173..a768555d 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -2,6 +2,7 @@ SET(LIB_SRCS interface/ui_iface_controller.cpp interface/ui_iface_view.cpp interface/ui_iface_viewmgr.cpp + efl/ui_base_popup.cpp efl/ui_base_controller.cpp efl/ui_base_view.cpp efl/ui_base_viewmgr.cpp diff --git a/src/lib/efl/ui_base_popup.cpp b/src/lib/efl/ui_base_popup.cpp new file mode 100644 index 0000000..588f4a9 --- /dev/null +++ b/src/lib/efl/ui_base_popup.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 "../../include/efl/ui_viewmanager_base.h" + +using namespace efl_viewmgr; + +static bool update_popup(ui_base_popup *popup) +{ + Elm_Win *win = popup->get_base(); + if (!win) return false; + + Elm_Popup *_popup = popup->get_content(); + if (!_popup) return false; + + evas_object_show(_popup); + + return true; +} + +static void popup_dismissed_cb(void *data, Evas_Object *obj, void *event_info) +{ + evas_object_hide(obj); +} + +static void popup_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + ui_base_popup *popup = static_cast(data); + popup->unset_content(); +} + +ui_base_popup::ui_base_popup(ui_base_view *view) + : view(view), popup(NULL) +{ + view->connect_popup(this); +} + +ui_base_popup::~ui_base_popup() +{ + this->view->disconnect_popup(this); + this->unset_content(); + evas_object_del(this->popup); +} + +Elm_Win *ui_base_popup::get_window() +{ + ui_base_viewmgr *viewmgr = dynamic_cast(this->view->get_viewmgr()); + if (!viewmgr) + { + LOGE("Viewmgr is null?? menu(%p)", this); + return NULL; + } + return viewmgr->get_window(); +} + +bool ui_base_popup::deactivate() +{ + if (!this->popup) + { + LOGE("Content is not set! = ui_base_popup(%p)", this); + return false; + } + + elm_popup_dismiss(this->popup); + this->view->on_resume(); + + return true; +} + +bool ui_base_popup::activate() +{ + bool ret = update_popup(this); + if (ret) this->view->on_pause(); + return ret; +} + +bool ui_base_popup::set_content(Elm_Popup *popup) +{ + evas_object_del(this->popup); + + //validation! + //FIXME: isa ? + if (strcmp(evas_object_type_get(popup), "elm_popup")) + { + LOGE("Menu widget is not a popup!"); + return false; + } + + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + + //FIXME: rename style. + evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, popup_del_cb, this); + evas_object_smart_callback_add(popup, "dismissed", popup_dismissed_cb, this); + + this->popup = popup; + + return true; +} + +bool ui_base_popup::is_activated() +{ + if (!this->popup) return false; + return evas_object_visible_get(this->popup); +} + +Elm_Popup *ui_base_popup::unset_content() +{ + if (!this->popup) return NULL; + + Elm_Popup *prev = this->popup; + this->popup = NULL; + evas_object_event_callback_del(prev, EVAS_CALLBACK_DEL, popup_del_cb); + evas_object_smart_callback_del(prev, "dismissed", popup_dismissed_cb); + return prev; +} + +Evas_Object *ui_base_popup::get_base() +{ + if (!this->view) + { + LOGE("View is null?? menu(%p)", this); + return NULL; + } + + return this->get_window(); +} + +void ui_base_popup::on_back() +{ + this->deactivate(); +} + +int ui_base_popup::get_degree() +{ + return this->view->get_degree(); +} diff --git a/src/lib/efl/ui_base_view.cpp b/src/lib/efl/ui_base_view.cpp index e28abcd..a01da67 100644 --- a/src/lib/efl/ui_base_view.cpp +++ b/src/lib/efl/ui_base_view.cpp @@ -21,6 +21,17 @@ using namespace viewmgr; #define MY_CONTROLLER dynamic_cast(this->get_controller()) #define MY_VIEWMGR dynamic_cast(this->get_viewmgr()) +typedef list::reverse_iterator popup_ritr; + +void ui_base_view::connect_popup(ui_base_popup *popup) +{ + this->popup_list.push_back(popup); +} + +void ui_base_view::disconnect_popup(ui_base_popup *popup) +{ + this->popup_list.remove(popup); +} ui_base_view::ui_base_view(ui_base_controller *controller, const char *name) : ui_iface_view(controller, name) @@ -95,8 +106,30 @@ void ui_base_view::set_indicator(ui_view_indicator indicator) viewmgr->set_indicator(indicator); } +bool ui_base_view::deactivate_popup(bool top_one) +{ + for (popup_ritr it = this->popup_list.rbegin(); it != this->popup_list.rend(); it++) + { + ui_base_popup *popup = *it; + if (!popup->is_activated()) continue; + popup->on_back(); + //deactivate only one top one? or all popups? + if (top_one) return true; + } + return false; +} + +void ui_base_view::on_deactivate() +{ + deactivate_popup(false); + ui_iface_view::on_deactivate(); +} + void ui_base_view::on_back() { + //If any popup is activated, deactivate the popup first. + if (this->deactivate_popup(true)) return; + if (this->get_controller()) { if (!MY_CONTROLLER->on_back()) diff --git a/src/lib/interface/ui_iface_viewmgr.cpp b/src/lib/interface/ui_iface_viewmgr.cpp index e09976e..a77951a 100644 --- a/src/lib/interface/ui_iface_viewmgr.cpp +++ b/src/lib/interface/ui_iface_viewmgr.cpp @@ -18,6 +18,10 @@ using namespace viewmgr; + +typedef list ::iterator view_itr; +typedef list::reverse_iterator view_ritr; + //FIXME: Read system profile to decide whether support software key or not. bool ui_iface_viewmgr::soft_key = true; //FIXME: Read system profile to decide whether support event block or not. @@ -102,7 +106,7 @@ ui_iface_viewmgr::ui_iface_viewmgr() ui_iface_viewmgr::~ui_iface_viewmgr() { //Terminate views - for (typename std::list::reverse_iterator it = this->view_list.rbegin(); it != this->view_list.rend(); it++) + for (view_ritr it = this->view_list.rbegin(); it != this->view_list.rend(); it++) { ui_iface_view *view = *it; view->on_deactivate(); @@ -140,7 +144,7 @@ ui_iface_viewmgr::push_view(ui_iface_view *view) this->set_event_block(pview, true); } - view_list.push_back(view); + this->view_list.push_back(view); if (!view->get_content()) { @@ -185,7 +189,7 @@ bool ui_iface_viewmgr::pop_view() //Below object has to be used in child class... //Make this getter method? or define instance? //previous page is to be an active page. - auto nx = std::prev(this->view_list.end(), 2); + auto nx = prev(this->view_list.end(), 2); ui_iface_view *pview = *nx; pview->on_load(); pview->on_deactivate(); @@ -196,7 +200,7 @@ bool ui_iface_viewmgr::pop_view() bool ui_iface_viewmgr::insert_view_before(ui_iface_view *view, ui_iface_view *before) { - typename std::list::iterator it; + view_itr it; if (!view) { @@ -232,7 +236,7 @@ bool ui_iface_viewmgr::insert_view_before(ui_iface_view *view, ui_iface_view *be bool ui_iface_viewmgr::insert_view_after(ui_iface_view *view, ui_iface_view *after) { - typename std::list::iterator it; + view_itr it; if (!view) { @@ -290,8 +294,8 @@ ui_iface_viewmgr::get_view(unsigned int idx) LOGE("Invalid idx(%d)! =? (idx range: %d ~ %d)", idx, 0, this->view_list.size() - 1); return NULL; } - typename std::list::iterator it = this->view_list.begin(); - std::advance(it, idx); + view_itr it = this->view_list.begin(); + advance(it, idx); return *it; } @@ -299,7 +303,7 @@ int ui_iface_viewmgr::get_view_index(const ui_iface_view *view) { int idx = 0; - for (typename std::list::iterator it = this->view_list.begin(); it != this->view_list.end(); it++) + for (view_itr it = this->view_list.begin(); it != this->view_list.end(); it++) { if (view == *it) return idx; ++idx;