TizenRefApp-8040 Implement circle menu 56/115556/3
authorSergei Kobec <s.kobec@samsung.com>
Mon, 20 Feb 2017 09:56:03 +0000 (11:56 +0200)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Wed, 22 Feb 2017 12:30:24 +0000 (04:30 -0800)
Change-Id: I45d61b8243d2bd4dbdb6e52c59be4e43cd48c64a
Signed-off-by: Sergei Kobec <s.kobec@samsung.com>
lib-apps-common/inc/Ui/CircleMenu.h [new file with mode: 0644]
lib-apps-common/inc/Ui/Menu.h [new file with mode: 0644]
lib-apps-common/src/Ui/CircleMenu.cpp [new file with mode: 0644]
lib-apps-common/src/Ui/Menu.cpp [new file with mode: 0644]

diff --git a/lib-apps-common/inc/Ui/CircleMenu.h b/lib-apps-common/inc/Ui/CircleMenu.h
new file mode 100644 (file)
index 0000000..493549b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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_CIRCLE_MENU_H
+#define UI_CIRCLE_MENU_H
+
+#include "Ui/Menu.h"
+#include <vector>
+
+namespace Ui
+{
+       class EXPORT_API CircleMenu : public Menu
+       {
+       public:
+               /**
+                * @see Menu::addItem().
+                */
+               Elm_Object_Item *addItem(const char *text, ItemCallback callback);
+
+               /**
+                * @see Menu::show().
+                */
+               void show();
+
+       private:
+               virtual Evas_Object *onCreate(Evas_Object *parent) override;
+               void updateItemsStyle();
+
+               std::vector<Elm_Object_Item *> m_Items;
+       };
+}
+
+#endif /* UI_CIRCLE_MENU_H */
diff --git a/lib-apps-common/inc/Ui/Menu.h b/lib-apps-common/inc/Ui/Menu.h
new file mode 100644 (file)
index 0000000..4266508
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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_MENU_H
+#define UI_MENU_H
+
+#include "Ui/Control.h"
+#include <functional>
+
+namespace Ui
+{
+       class View;
+       class Window;
+
+       class EXPORT_API Menu : public Control
+       {
+       public:
+               /**
+                * @brief Item selection callback
+                */
+               typedef std::function<void()> ItemCallback;
+
+               Menu();
+               virtual ~Menu() override;
+
+               /**
+                * @brief Add menu item
+                * @param[in]   text        Item text
+                * @param[in]   callback    Item selection callback
+                * @return Added item on success, otherwise nullptr
+                */
+               Elm_Object_Item *addItem(const char *text, ItemCallback callback);
+
+               /**
+                * @brief Show menu at the bottom of application window.
+                */
+               void show();
+
+       protected:
+               virtual Evas_Object *onCreate(Evas_Object *parent) override;
+
+       private:
+               void onViewNavigation(Evas_Object *obj, void *eventInfo);
+               void onWindowResized(Evas *e, Evas_Object *obj, void *eventInfo);
+
+               static void onItemSelect(void *data, Evas_Object *obj, void *item);
+               static void onItemDestroy(void *data, Evas_Object *obj, void *item);
+               void onDismissed(Evas_Object *obj, void *eventInfo);
+
+               View *m_View;
+               Window *m_Window;
+       };
+}
+
+#endif /* UI_MENU_H */
diff --git a/lib-apps-common/src/Ui/CircleMenu.cpp b/lib-apps-common/src/Ui/CircleMenu.cpp
new file mode 100644 (file)
index 0000000..0cdf6df
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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/CircleMenu.h"
+
+using namespace Ui;
+
+Elm_Object_Item *CircleMenu::addItem(const char *text, ItemCallback callback)
+{
+       m_Items.push_back(Menu::addItem(text, std::move(callback)));
+       return m_Items.back();
+}
+
+void CircleMenu::show()
+{
+       Evas_Coord x = 0, y = 0, w = 0, h = 0;
+       Evas_Object *parent = elm_object_parent_widget_get(getEvasObject());
+       evas_object_geometry_get(parent , &x, &y, &w, &h);
+       evas_object_move(getEvasObject(), x + (w / 2), y + (h / 2));
+       evas_object_show(getEvasObject());
+
+       updateItemsStyle();
+}
+
+Evas_Object *CircleMenu::onCreate(Evas_Object *parent)
+{
+       auto menu = Menu::onCreate(parent);
+       elm_object_style_set(menu, "select_mode");
+       elm_ctxpopup_direction_priority_set(menu,
+                       ELM_CTXPOPUP_DIRECTION_DOWN, ELM_CTXPOPUP_DIRECTION_DOWN,
+                       ELM_CTXPOPUP_DIRECTION_DOWN, ELM_CTXPOPUP_DIRECTION_DOWN);
+
+       return menu;
+}
+
+void CircleMenu::updateItemsStyle()
+{
+       if (m_Items.size() >= 2) {
+               elm_object_item_style_set(m_Items.front(), "select_mode/top");
+               elm_object_item_style_set(m_Items.back(), "select_mode/bottom");
+       }
+}
diff --git a/lib-apps-common/src/Ui/Menu.cpp b/lib-apps-common/src/Ui/Menu.cpp
new file mode 100644 (file)
index 0000000..fe526a4
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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/Menu.h"
+#include "Ui/View.h"
+#include "Ui/Window.h"
+#include "Utils/Callback.h"
+
+#include <efl_extension.h>
+
+using namespace Ui;
+
+Menu::Menu()
+       : m_View(nullptr), m_Window(nullptr)
+{
+}
+
+Menu::~Menu()
+{
+       if (m_View) {
+               evas_object_smart_callback_del_full(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION,
+                               makeCallback(&Menu::onViewNavigation), this);
+       }
+       if (m_Window) {
+               evas_object_event_callback_del_full(m_Window->getEvasObject(), EVAS_CALLBACK_RESIZE,
+                               makeCallback(&Menu::onWindowResized), this);
+       }
+}
+
+Elm_Object_Item *Menu::addItem(const char *text, ItemCallback callback)
+{
+       Elm_Object_Item *item = elm_ctxpopup_item_append(getEvasObject(), text, nullptr,
+                       &Menu::onItemSelect, new ItemCallback(std::move(callback)));
+       elm_object_item_text_translatable_set(item, EINA_TRUE);
+       elm_object_item_del_cb_set(item, &Menu::onItemDestroy);
+       return item;
+}
+
+void Menu::show()
+{
+       Evas_Coord y = 0, w = 0, h = 0;
+       Evas_Object *parent = elm_ctxpopup_hover_parent_get(getEvasObject());
+       evas_object_geometry_get(parent, nullptr, &y, &w, &h);
+
+       Evas_Object *menu = getEvasObject();
+       int menuWidth = 0;
+       evas_object_geometry_get(menu, nullptr, nullptr, &menuWidth, nullptr);
+       evas_object_move(menu, w / 2 - menuWidth / 2, y + h);
+       evas_object_show(menu);
+}
+
+Evas_Object *Menu::onCreate(Evas_Object *parent)
+{
+       Evas_Object *menu = elm_ctxpopup_add(parent);
+       elm_object_style_set(menu, "more/default");
+
+       evas_object_smart_callback_add(menu, "dismissed",
+                       makeCallback(&Menu::onDismissed), this);
+       eext_object_event_callback_add(menu, EEXT_CALLBACK_BACK,
+                       eext_ctxpopup_back_cb, nullptr);
+       eext_object_event_callback_add(menu, EEXT_CALLBACK_MORE,
+                       eext_ctxpopup_back_cb, nullptr);
+
+       m_View = findParent<View>(parent);
+       if (m_View) {
+               evas_object_smart_callback_add(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION,
+                               makeCallback(&Menu::onViewNavigation), this);
+       }
+
+       m_Window = findParent<Window>(parent);
+       if (m_Window) {
+               elm_ctxpopup_hover_parent_set(menu, m_Window->getEvasObject());
+               evas_object_event_callback_add(m_Window->getEvasObject(), EVAS_CALLBACK_RESIZE,
+                               makeCallback(&Menu::onWindowResized), this);
+       }
+
+       return menu;
+}
+
+void Menu::onViewNavigation(Evas_Object *obj, void *eventInfo)
+{
+       if (!eventInfo) {
+               elm_ctxpopup_dismiss(getEvasObject());
+       }
+}
+
+void Menu::onWindowResized(Evas *e, Evas_Object *obj, void *eventInfo)
+{
+       show();
+}
+
+void Menu::onItemSelect(void *data, Evas_Object *obj, void *item)
+{
+       ItemCallback &callback = *(ItemCallback *) data;
+       if (callback) {
+               callback();
+       }
+
+       elm_ctxpopup_dismiss(obj);
+}
+
+void Menu::onItemDestroy(void *data, Evas_Object *obj, void *item)
+{
+       delete (ItemCallback *) data;
+}
+
+void Menu::onDismissed(Evas_Object *obj, void *eventInfo)
+{
+       delete this;
+}