From: Hermet Park Date: Wed, 23 Mar 2016 13:19:26 +0000 (+0900) Subject: introduce ui_menu for menu feature. X-Git-Tag: submit/tizen/20160617.075742~99 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=271bf418e8cd0acd68463a183a0acbb25ec72ab9;p=platform%2Fcore%2Fuifw%2Fui-viewmgr.git introduce ui_menu for menu feature. ui_menu is a interface for supporting menu feature. normally, ui_view has one ui_menu and in mobile case, ui_menu is decoration of ctxpopup. Change-Id: Ie725ed561666673e55bfce225d9987bc67a7ad63 --- diff --git a/src/examples/efl/CMakeLists.txt b/src/examples/efl/CMakeLists.txt index 89278af..319eadb 100644 --- a/src/examples/efl/CMakeLists.txt +++ b/src/examples/efl/CMakeLists.txt @@ -8,6 +8,7 @@ SET(EXAM_SRCS ../../lib/efl/ui_base_viewmgr.cpp ../../lib/efl/ui_base_key_listener.cpp ../../lib/efl/mobile/ui_controller.cpp + ../../lib/efl/mobile/ui_menu.cpp ../../lib/efl/mobile/ui_view.cpp ../../lib/efl/mobile/ui_key_listener.cpp ../../lib/efl/mobile/ui_viewmgr.cpp diff --git a/src/examples/efl/page1.h b/src/examples/efl/page1.h index 8074916..f31c860 100644 --- a/src/examples/efl/page1.h +++ b/src/examples/efl/page1.h @@ -67,11 +67,9 @@ public: view->set_content(content, "Title"); } - bool on_menu() + void on_menu(ui_menu *menu) { - ui_view *view = dynamic_cast(this->get_view()); - - Elm_Ctxpopup *ctxpopup = elm_ctxpopup_add(view->get_base()); + Elm_Ctxpopup *ctxpopup = elm_ctxpopup_add(menu->get_base()); elm_ctxpopup_item_append(ctxpopup, "Phone calls", NULL, ctxpopup_item_select_cb, this); elm_ctxpopup_item_append(ctxpopup, "Favorites", NULL, ctxpopup_item_select_cb, this); elm_ctxpopup_item_append(ctxpopup, "Search", NULL, ctxpopup_item_select_cb, this); @@ -82,9 +80,7 @@ public: elm_ctxpopup_item_append(ctxpopup, "Search", NULL, ctxpopup_item_select_cb, this); elm_ctxpopup_item_append(ctxpopup, "Dialer", NULL, ctxpopup_item_select_cb, this); - view->set_menu(ctxpopup); - - return true; + menu->set_content(ctxpopup); } void on_rotate(int degree) diff --git a/src/include/efl/mobile/ui_controller.h b/src/include/efl/mobile/ui_controller.h index 0ac055a..6260473 100644 --- a/src/include/efl/mobile/ui_controller.h +++ b/src/include/efl/mobile/ui_controller.h @@ -21,11 +21,13 @@ namespace efl_viewmgr { +class ui_menu; + class ui_controller: public ui_base_controller { public: virtual ~ui_controller(); - virtual bool on_menu(); + virtual void on_menu(ui_menu *menu); }; } diff --git a/src/include/efl/mobile/ui_key_listener.h b/src/include/efl/mobile/ui_key_listener.h index 4410870..927007e 100644 --- a/src/include/efl/mobile/ui_key_listener.h +++ b/src/include/efl/mobile/ui_key_listener.h @@ -34,4 +34,4 @@ public: } -#endif /* UI_BASIC_KEY_HANDLER_H */ +#endif /* UI_KEY_HANDLER_H */ diff --git a/src/include/efl/mobile/ui_menu.h b/src/include/efl/mobile/ui_menu.h new file mode 100644 index 0000000..0982280 --- /dev/null +++ b/src/include/efl/mobile/ui_menu.h @@ -0,0 +1,55 @@ +/* + * 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_MENU_H +#define UI_MENU_H + +#include "../ui_viewmanager_base.h" + +namespace efl_viewmgr +{ +class ui_view; + +class ui_menu +{ + friend class ui_view; +private: + ui_view *view; + Elm_Ctxpopup *ctxpopup; + + ui_menu(ui_view *view); + virtual ~ui_menu(); + + Elm_Win *get_window(); + +public: + virtual bool activate(); + virtual bool deactivate(); + virtual bool set_content(Elm_Ctxpopup* ctxpopup); + virtual Elm_Ctxpopup *unset_content(); + + virtual Elm_Ctxpopup *get_content() + { + return this->ctxpopup; + } + + virtual bool is_activated(); + virtual Evas_Object *get_base(); +}; + +} + +#endif /* UI_MENU_H */ diff --git a/src/include/efl/mobile/ui_view.h b/src/include/efl/mobile/ui_view.h index 36828ac..9941228 100644 --- a/src/include/efl/mobile/ui_view.h +++ b/src/include/efl/mobile/ui_view.h @@ -24,9 +24,12 @@ namespace efl_viewmgr class ui_view: public ui_base_view { + friend class ui_menu; + friend class ui_key_listener; + private: Elm_Layout *layout; //Base layout for view - Elm_Ctxpopup *ctxpopup; //Menu Widget + ui_menu *menu; //Menu bool create_layout(); bool destroy_layout(); @@ -34,6 +37,7 @@ private: protected: virtual void on_load(); virtual void on_unload(); + virtual void on_menu(); virtual void unload_content(); virtual void set_event_block(bool block); @@ -50,24 +54,20 @@ public: bool set_title_right_btn(Elm_Button *title_right_btn); bool set_title(const char *text); bool set_toolbar(Elm_Toolbar *toolbar); - bool set_menu(Elm_Ctxpopup *menu); - Elm_Ctxpopup *unset_menu(); Evas_Object *unset_content(); Elm_Button *unset_title_left_btn(); Elm_Button *unset_title_right_btn(); Elm_Toolbar *unset_toolbar(); - virtual void on_menu(); - virtual Evas_Object *get_base() { if (!this->layout)this->create_layout(); return this->layout; } - Elm_Ctxpopup *get_menu() + const ui_menu *get_menu() { - return this->ctxpopup; + return this->menu; } }; diff --git a/src/include/efl/mobile/ui_viewmanager.h b/src/include/efl/mobile/ui_viewmanager.h index 56b1fad..dc2f7d1 100644 --- a/src/include/efl/mobile/ui_viewmanager.h +++ b/src/include/efl/mobile/ui_viewmanager.h @@ -25,3 +25,4 @@ #include "ui_view.h" #include "ui_key_listener.h" #include "ui_viewmgr.h" +#include "ui_menu.h" diff --git a/src/include/efl/ui_base_controller.h b/src/include/efl/ui_base_controller.h index d72491f..dcf3d48 100644 --- a/src/include/efl/ui_base_controller.h +++ b/src/include/efl/ui_base_controller.h @@ -103,14 +103,6 @@ public: */ virtual void on_destroy() {} - /** @brief Back key callback. - * - * @note In default. current view will be popped by viewmgr in those scenarios - * that viewmgr is requested to poo the current view. - * If you return false in the overriding, then popping will be stopped. - */ - virtual bool on_back() { return true; } - /** @brief View rotate callback. * * @param degree Current rotation degree. @@ -130,6 +122,15 @@ public: * @note When current view is on landscape mode. */ virtual void on_landscape() {} + + /** @brief Back key callback. + * + * @note In default. current view will be popped by viewmgr in those scenarios + * that viewmgr is requested to poo the current view. + * If you return false in the overriding, then popping will be stopped. + */ + virtual bool on_back() { return true; } + }; } diff --git a/src/include/interface/ui_iface_controller.h b/src/include/interface/ui_iface_controller.h index a2e6199..0fa7caa 100644 --- a/src/include/interface/ui_iface_controller.h +++ b/src/include/interface/ui_iface_controller.h @@ -121,14 +121,6 @@ public: */ virtual void on_destroy() = 0; - /** @brief Back key callback. - * - * @note In default. current view will be popped by viewmgr in those scenarios - * that viewmgr is requested to poo the current view. - * If you return false in the overriding, then popping will be stopped. - */ - virtual bool on_back() = 0; - /** @brief View rotate callback. * * @param degree Current rotation degree. diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 5be1b72..0163173 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -7,6 +7,7 @@ SET(LIB_SRCS efl/ui_base_viewmgr.cpp efl/ui_base_key_listener.cpp efl/mobile/ui_controller.cpp + efl/mobile/ui_menu.cpp efl/mobile/ui_view.cpp efl/mobile/ui_key_listener.cpp efl/mobile/ui_viewmgr.cpp diff --git a/src/lib/efl/mobile/ui_controller.cpp b/src/lib/efl/mobile/ui_controller.cpp index d5ab72d..7bff689 100644 --- a/src/lib/efl/mobile/ui_controller.cpp +++ b/src/lib/efl/mobile/ui_controller.cpp @@ -23,7 +23,6 @@ ui_controller::~ui_controller() { } -bool ui_controller::on_menu() +void ui_controller::on_menu(ui_menu *menu) { - return true; } diff --git a/src/lib/efl/mobile/ui_menu.cpp b/src/lib/efl/mobile/ui_menu.cpp new file mode 100644 index 0000000..1878b48 --- /dev/null +++ b/src/lib/efl/mobile/ui_menu.cpp @@ -0,0 +1,168 @@ +/* + * 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/mobile/ui_viewmanager.h" + +using namespace efl_viewmgr; + +#define MY_VIEWMGR + +static void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info) +{ + evas_object_hide(obj); +} + +static void ctxpopup_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + ui_menu *menu = static_cast(data); + menu->unset_content(); +} + +static bool update_menu(ui_menu *menu) +{ + Elm_Win *win = menu->get_base(); + if (!win) return false; + + Elm_Ctxpopup *ctxpopup = menu->get_content(); + if (!ctxpopup) return false; + + /* We convince the top widget is a window */ + Evas_Coord w, h; + elm_win_screen_size_get(win, NULL, NULL, &w, &h); + int rot = elm_win_rotation_get(win); + + switch (rot) + { + case 0: + case 180: + evas_object_move(ctxpopup, (w / 2), h); + break; + case 90: + case 270: + evas_object_move(ctxpopup, (h / 2), w); + break; + } + + evas_object_show(ctxpopup); + + return true; +} + +static void win_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + ui_menu *menu = static_cast(data); + Elm_Ctxpopup *ctxpopup = menu->get_content(); + if (!ctxpopup) return; + if (!evas_object_visible_get(ctxpopup)) return; + update_menu(menu); +} + +ui_menu::ui_menu(ui_view *view) + : view(view), ctxpopup(NULL) +{ + Elm_Win *win = this->get_window(); + evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, win_resize_cb, this); +} + +ui_menu::~ui_menu() +{ + Elm_Win *win = this->get_window(); + if (win) evas_object_event_callback_del(win, EVAS_CALLBACK_RESIZE, win_resize_cb); + evas_object_del(this->ctxpopup); +} + +Elm_Win *ui_menu::get_window() +{ + ui_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_menu::deactivate() +{ + if (this->ctxpopup) + { + elm_ctxpopup_dismiss(this->ctxpopup); + } + else + { + LOGE("Content is not set! = ui_menu(%p)", this); + return false; + } + + return true; +} + +bool ui_menu::activate() +{ + return update_menu(this); +} + +bool ui_menu::set_content(Elm_Ctxpopup *ctxpopup) +{ + evas_object_del(this->ctxpopup); + + //validation! + //FIXME: isa ? + if (strcmp(evas_object_type_get(ctxpopup), "elm_ctxpopup")) + { + LOGE("Menu widget is not a ctxpopup!"); + return false; + } + + //FIXME: rename style. + elm_object_style_set(ctxpopup, "more/default"); + elm_ctxpopup_auto_hide_disabled_set(ctxpopup, EINA_TRUE); + evas_object_smart_callback_add(ctxpopup, "dismissed", ctxpopup_dismissed_cb, NULL); + evas_object_event_callback_add(ctxpopup, EVAS_CALLBACK_DEL, ctxpopup_del_cb, this); + + this->ctxpopup = ctxpopup; + + return true; +} + +bool ui_menu::is_activated() +{ + if (!this->ctxpopup) return false; + return evas_object_visible_get(this->ctxpopup); +} + +Elm_Ctxpopup *ui_menu::unset_content() +{ + if (!this->ctxpopup) return NULL; + + Elm_Ctxpopup *prev = this->ctxpopup; + this->ctxpopup = NULL; + evas_object_smart_callback_del(prev, "dismissed", ctxpopup_dismissed_cb); + evas_object_event_callback_del(prev, EVAS_CALLBACK_DEL, ctxpopup_del_cb); + return prev; +} + +Evas_Object *ui_menu::get_base() +{ + if (!this->view) + { + LOGE("View is null?? menu(%p)", this); + return NULL; + } + + return this->get_window(); +} diff --git a/src/lib/efl/mobile/ui_view.cpp b/src/lib/efl/mobile/ui_view.cpp index fe0380a..db07c9e 100644 --- a/src/lib/efl/mobile/ui_view.cpp +++ b/src/lib/efl/mobile/ui_view.cpp @@ -24,39 +24,7 @@ using namespace efl_viewmgr; using namespace viewmgr; #define MY_VIEWMGR dynamic_cast(this->get_viewmgr()) -#define MY_CONTROLLER dynamic_cast(this->get_controller())) - -static void menu_dismissed_cb(void *data, Evas_Object *obj, void *event_info) -{ - evas_object_hide(obj); -} - -static void menu_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - ui_view *view = static_cast(data); - view->unset_menu(); -} - -static void update_menu(Elm_Win *win, Elm_Ctxpopup *ctxpopup) -{ - /* We convince the top widget is a window */ - Evas_Coord w, h; - elm_win_screen_size_get(win, NULL, NULL, &w, &h); - int rot = elm_win_rotation_get(win); - - switch (rot) - { - case 0: - case 180: - evas_object_move(ctxpopup, (w / 2), h); - break; - case 90: - case 270: - evas_object_move(ctxpopup, (h / 2), w); - break; - } - evas_object_show(ctxpopup); -} +#define MY_CONTROLLER dynamic_cast(this->get_controller()) bool ui_view::destroy_layout() { @@ -117,38 +85,13 @@ bool ui_view::create_layout() } } - //FIXME: .... ? - evas_object_event_callback_add(layout, EVAS_CALLBACK_RESIZE, - [](void *data, Evas *e, Evas_Object *obj, void *event_info) -> void - { - ui_view *view = static_cast(data); - Elm_Ctxpopup *ctxpopup = view->get_menu(); - if (ctxpopup && evas_object_visible_get(ctxpopup)) - { - update_menu(dynamic_cast(view->get_viewmgr())->get_window(), ctxpopup); - } - }, - this); - - evas_object_event_callback_add(layout, EVAS_CALLBACK_MOVE, - [](void *data, Evas *e, Evas_Object *obj, void *event_info) -> void - { - ui_view *view = static_cast(data); - Elm_Ctxpopup *ctxpopup = view->get_menu(); - if (ctxpopup && evas_object_visible_get(ctxpopup)) - { - elm_ctxpopup_dismiss(ctxpopup); - } - }, - this); - this->layout = layout; return true; } ui_view::ui_view(ui_controller *controller, const char *name) - : ui_base_view(controller, name), layout(NULL), ctxpopup(NULL) + : ui_base_view(controller, name), layout(NULL), menu(NULL) { } @@ -159,7 +102,7 @@ ui_view::ui_view(const char *name) ui_view::~ui_view() { - evas_object_del(this->ctxpopup); + if (menu) delete(this->menu); destroy_layout(); } @@ -286,28 +229,6 @@ Evas_Object *ui_view::set_content(Evas_Object *content, const char *title, const return pcontent; } -bool ui_view::set_menu(Elm_Ctxpopup *menu) -{ - if (this->ctxpopup) evas_object_del(this->ctxpopup); - - //validation! - if (strcmp(evas_object_type_get(menu), "elm_ctxpopup")) - { - LOGE("Menu widget is not a ctxpopup!"); - return false; - } - - //FIXME: rename style. - elm_object_style_set(menu, "more/default"); - elm_ctxpopup_auto_hide_disabled_set(menu, EINA_TRUE); - evas_object_smart_callback_add(menu, "dismissed", menu_dismissed_cb, NULL); - evas_object_event_callback_add(menu, EVAS_CALLBACK_DEL, menu_del_cb, this); - - this->ctxpopup = menu; - - return true; -} - bool ui_view::set_toolbar(Elm_Toolbar *toolbar) { Elm_Layout *layout = this->get_base(); @@ -349,20 +270,24 @@ void ui_view::unload_content() void ui_view::on_menu() { - if (this->ctxpopup && evas_object_visible_get(this->ctxpopup)) + if (this->menu && this->menu->is_activated()) { - elm_ctxpopup_dismiss(this->ctxpopup); + this->menu->deactivate(); return; } if (this->get_controller()) { - (MY_CONTROLLER->on_menu(); + if (!this->menu) + { + this->menu = new ui_menu(this); + } + MY_CONTROLLER->on_menu(this->menu); } - if (this->ctxpopup) + if (this->menu && this->menu->get_content()) { - update_menu(MY_VIEWMGR->get_window(), this->ctxpopup); + this->menu->activate(); } } @@ -372,15 +297,6 @@ void ui_view::set_event_block(bool block) evas_object_freeze_events_set(this->get_base(), block); } -Elm_Ctxpopup* ui_view::unset_menu() -{ - Elm_Ctxpopup *menu = this->ctxpopup; - evas_object_event_callback_del(menu, EVAS_CALLBACK_DEL, menu_del_cb); - evas_object_smart_callback_del(menu, "dismissed", menu_dismissed_cb); - this->ctxpopup = NULL; - return menu; -} - Evas_Object *ui_view::unset_content() { Evas_Object *pcontent = ui_base_view::unset_content(); diff --git a/src/lib/efl/ui_base_key_listener.cpp b/src/lib/efl/ui_base_key_listener.cpp index 3a2bd92..8abefd8 100644 --- a/src/lib/efl/ui_base_key_listener.cpp +++ b/src/lib/efl/ui_base_key_listener.cpp @@ -42,6 +42,7 @@ static void event_proc(ui_base_key_listener *key_listener, Evas_Event_Key_Down * if (strcmp(ev->keyname, KEY_BACK) && strcmp(ev->keyname, KEY_BACK2)) return; + //FIXME: cancel menu?? view->on_back(); }