eext_panel: add a new eext widget 79/174179/1
authorJaeun Choi <jaeun12.choi@samsung.com>
Wed, 10 Jan 2018 05:07:58 +0000 (14:07 +0900)
committerJaeun Choi <jaeun12.choi@samsung.com>
Thu, 29 Mar 2018 02:04:06 +0000 (11:04 +0900)
this patch doesn't include accessibility implementation.

Change-Id: I4f6ffc33a7508a12a1e325c45fce2859f136a6f2

inc/CMakeLists.txt
inc/wearable/efl_extension_common_private.h
inc/wearable/efl_extension_panel.h [new file with mode: 0644]
src/CMakeLists.txt
src/wearable/efl_extension_panel.c [new file with mode: 0644]

index 394181312c8992a525a4b55e687aee967eb8aa15..6e714a35f97515280c5ae12544f4b2249b8b596c 100644 (file)
@@ -18,6 +18,7 @@ SET(WEARABLE_LIB_INCS
        wearable/efl_extension_common.h
        wearable/efl_extension_rotary_selector.h
        wearable/efl_extension_more_option.h
+       wearable/efl_extension_panel.h
 )
 
 SET(LIB_INCS
index b04dccb57e78d5d6bee1431035c1b132cda2cfba..d07c09db32a1065604d0c6c7130b27fb4d01b2fe 100644 (file)
@@ -234,6 +234,19 @@ struct _Eext_More_Option_Data {
    //
 };
 
+typedef struct _Eext_Panel_Data Eext_Panel_Data;
+struct _Eext_Panel_Data {
+   Evas_Object *parent;
+   Evas_Object *eext_panel;
+   Evas_Object *primary_panel;
+   Evas_Object *assist_panel;
+   Evas_Object *panel_bg;
+
+   Eina_Bool is_zoom_out;
+   Eina_Bool is_mouse_down;
+   Eina_Bool panel_hide_cb_added;
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/inc/wearable/efl_extension_panel.h b/inc/wearable/efl_extension_panel.h
new file mode 100644 (file)
index 0000000..8f63bab
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __EFL_EXTENSION_PANEL_H__
+#define __EFL_EXTENSION_PANEL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup CAPI_EFL_EXTENSION_PANEL_MODULE Efl Extension Panel
+ * @ingroup CAPI_EFL_EXTENSION_COMMON_UI_MODULE
+ * @brief Eext_panel is composed of primary panel and assist panel.
+ *        Assist panel becomes visible by dragging the edge of the screen.
+ *
+ * @{
+ */
+
+/**
+ * @WEARABLE_ONLY
+ * @brief Add a new Eext_Panel
+ * @details Because the return value is a handle of elm_layout object,
+ *          the elm_layout APIs are applicable to eext_panel.
+ *
+ *          This widget emits the following signals:
+ *          @li "assist,panel,visible": When the assist panel becomes draggable
+ *                                      and visible
+ *          @li "assist,panel,hidden": When the assist panel becomes completely
+ *                                     invisible and not draggable
+ *
+ * @param[in] parent The parent object
+ *
+ * @return A new eext_panel handle, otherwise @c NULL if it cannot be created
+ * @if WEARABLE @since_tizen 4.0
+ * @endif
+ */
+EAPI Evas_Object* eext_panel_add(Evas_Object *parent);
+
+
+/**
+ * @WEARABLE_ONLY
+ * @brief Set the content at a part of a given eext_panel widget
+ *
+ * @remarks Eext panel holds two (primary and assist) child objects as its
+ *          contents in the given parts. This API sets a new content to a given
+ *          part. If any object is already set as a content object in the given
+ *          part, the previous object is automatically deleted with this call.
+ *          If the @p content is NULL, this call will just delete the previous
+ *          object.
+ *
+ *          The part names works as follows:
+ *          @li "primary": If you set an object as the content of this part,
+ *                         the object is visible by default before assist panel
+ *                         is dragged.
+ *          @li "assist": If you set an object as the content of this part,
+ *                        the object is hidden by default and becomes visible
+ *                        by dragging the edge of the screen.
+ *
+ * @param[in] obj Eext panel
+ * @param[in] part_name Eext panel's part name to set
+ * @param[in] content The new content for that part
+ *
+ * @if WEARABLE @since_tizen 4.0
+ * @endif
+ */
+EAPI void eext_panel_part_content_set(Evas_Object *obj, const char *part_name, Evas_Object *content);
+
+/**
+ * @WEARABLE_ONLY
+ * @brief Get the content from the part of the given eext_panel widget
+ *
+ * @param[in] obj Eext panel
+ * @param[in] part_name Eext panel part name
+ * @return The content of the object at the given part, otherwise @c NULL in case of an error
+ *
+ * @if WEARABLE @since_tizen 4.0
+ * @endif
+ */
+EAPI Evas_Object* eext_panel_part_content_get(const Evas_Object *obj, const char *part_name);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EFL_EXTENSION_PANEL_H__ */
index bc79ec0e7544bcbc6fd79756cb809bdd0d6a1930..50b04d79943ed9291340fa47d96c076bd2ca19bb 100755 (executable)
@@ -28,6 +28,7 @@ SET(WEARABLE_LIB_SRCS
        wearable/circle/efl_extension_rotary.c
        wearable/efl_extension_rotary_selector.c
        wearable/efl_extension_more_option.c
+       wearable/efl_extension_panel.c
        )
 SET(WEARABLE_EO_FILES
        )
diff --git a/src/wearable/efl_extension_panel.c b/src/wearable/efl_extension_panel.c
new file mode 100644 (file)
index 0000000..15952e0
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "efl_extension.h"
+#include "efl_extension_private.h"
+#include "wearable/circle/efl_extension_circle_private.h"
+#include "wearable/efl_extension_common_private.h"
+
+#define EEXT_PANEL_DATA_KEY "eext_panel_data"
+
+
+static Eext_Panel_Data *
+_eext_panel_data_init(Evas_Object *obj, Evas_Object *parent)
+{
+   Eext_Panel_Data *pd = NULL;
+
+   pd = (Eext_Panel_Data *)calloc(1, sizeof(Eext_Panel_Data));
+
+   if (!pd)
+     {
+        ERR("pd is NULL!!");
+        return NULL;
+     }
+
+   pd->parent = parent;
+   pd->eext_panel = obj;
+   pd->is_zoom_out = EINA_FALSE;
+   pd->is_mouse_down = EINA_FALSE;
+   pd->panel_hide_cb_added = EINA_FALSE;
+
+   return pd;
+}
+
+static Eext_Panel_Data *
+_eext_panel_data_get(const Evas_Object *eext_panel)
+{
+   if (!eext_panel)
+     {
+        ERR("eext_panel is NULL!!");
+        return NULL;
+     }
+
+   return evas_object_data_get(eext_panel, EEXT_PANEL_DATA_KEY);
+}
+
+static void
+_panel_hide_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   if (!obj)
+     {
+        ERR("panel is NULL!!");
+        return;
+     }
+
+   if (!elm_panel_hidden_get(obj)) elm_panel_toggle(obj);
+}
+
+static void
+_panel_unhold_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Eext_Panel_Data *pd = data;
+   double curve[4] = {0.25, 0.46, 0.45, 1.0};
+   Evas_Map *map;
+   Elm_Transit *tran;
+
+   map = evas_map_new(4);
+   evas_map_util_points_populate_from_object(map, pd->primary_panel);
+   evas_object_map_set(pd->primary_panel, map);
+   evas_object_map_enable_set(pd->primary_panel, EINA_TRUE);
+   evas_map_free(map);
+
+   tran = elm_transit_add();
+   elm_transit_effect_zoom_add(tran, 1.0, 0.9);
+   elm_transit_object_add(tran, pd->primary_panel);
+   elm_transit_duration_set(tran, 0.25);
+   elm_transit_tween_mode_set(tran, ELM_TRANSIT_TWEEN_MODE_BEZIER_CURVE);
+   elm_transit_tween_mode_factor_n_set(tran, 4, curve);
+   elm_transit_objects_final_state_keep_set(tran, EINA_TRUE);
+   elm_transit_go(tran);
+
+   pd->is_zoom_out = EINA_TRUE;
+
+   if (!pd->panel_hide_cb_added)
+     {
+        eext_object_event_callback_add(pd->assist_panel, EEXT_CALLBACK_BACK,
+                                       _panel_hide_cb, NULL);
+        pd->panel_hide_cb_added = EINA_TRUE;
+     }
+
+   evas_object_smart_callback_call(pd->eext_panel, "assist,panel,visible", NULL);
+}
+
+static void
+_panel_hold_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Eext_Panel_Data *pd = data;
+   double curve[4] = {0.25, 0.46, 0.45, 1.0};
+   Evas_Map *map;
+   Elm_Transit *tran;
+
+   map = evas_map_new(4);
+   evas_map_util_points_populate_from_object(map, pd->primary_panel);
+   evas_object_map_set(pd->primary_panel, map);
+   evas_object_map_enable_set(pd->primary_panel, EINA_TRUE);
+   evas_map_free(map);
+
+   if (pd->is_zoom_out)
+     {
+        tran = elm_transit_add();
+        elm_transit_effect_zoom_add(tran, 0.9, 1.0);
+        elm_transit_object_add(tran, pd->primary_panel);
+        elm_transit_duration_set(tran, 0.25);
+        elm_transit_tween_mode_set(tran, ELM_TRANSIT_TWEEN_MODE_BEZIER_CURVE);
+        elm_transit_tween_mode_factor_n_set(tran, 4, curve);
+        elm_transit_objects_final_state_keep_set(tran, EINA_TRUE);
+        elm_transit_go(tran);
+
+        pd->is_zoom_out = EINA_FALSE;
+     }
+
+   if (pd->panel_hide_cb_added)
+     {
+        eext_object_event_callback_del(pd->assist_panel, EEXT_CALLBACK_BACK,
+                                       _panel_hide_cb);
+        pd->panel_hide_cb_added = EINA_FALSE;
+     }
+
+   evas_object_smart_callback_call(pd->eext_panel, "assist,panel,hidden", NULL);
+}
+
+static void
+_panel_scroll_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+   Eext_Panel_Data *pd = data;
+   Elm_Panel_Scroll_Info *ev = event_info;
+   double curve[4] = {0.25, 0.46, 0.45, 1.0};
+
+   int col = 229 * ev->rel_y;
+   evas_object_color_set(pd->panel_bg, 0, 0, 0, col);
+}
+
+static void
+_panel_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                   void *event_info EINA_UNUSED)
+{
+   Eext_Panel_Data *pd = data;
+
+   pd->is_mouse_down = EINA_FALSE;
+}
+
+static void
+_panel_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                     void *event_info EINA_UNUSED)
+{
+   Eext_Panel_Data *pd = data;
+
+   pd->is_mouse_down = EINA_TRUE;
+}
+
+static void
+_eext_panel_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   Eext_Panel_Data *pd = data;
+
+   free(pd);
+}
+
+EAPI Evas_Object *
+eext_panel_add(Evas_Object *parent)
+{
+   Evas_Object *layout, *primary_ly, *panel;
+   Eina_Bool ret;
+
+   if (!parent) return NULL;
+
+   Eext_Panel_Data *pd = NULL;
+
+   layout = elm_layout_add(parent);
+   if (!layout)
+     {
+        ERR("eext_panel is NULL!!");
+        return NULL;
+     }
+
+   pd = _eext_panel_data_init(layout, parent);
+   if (!pd)
+     {
+        evas_object_del(layout);
+        return NULL;
+     }
+
+   evas_object_data_set(layout, EEXT_PANEL_DATA_KEY, pd);
+
+   ret = elm_layout_theme_set(layout, "layout", "drawer", "panel");
+   if (!ret)
+     {
+        ERR("Failed to set theme!!");
+        evas_object_del(layout);
+        free(pd);
+        return NULL;
+     }
+
+   primary_ly = elm_layout_add(layout);
+   if (!primary_ly)
+     {
+        ERR("Primary layout is NULL!!");
+        evas_object_del(layout);
+        free(pd);
+        return NULL;
+     }
+
+   ret = elm_layout_theme_set(primary_ly, "layout", "panel", "primary");
+   if (!ret)
+     {
+        ERR("Failed to set primary layout theme!!");
+        evas_object_del(primary_ly);
+        evas_object_del(layout);
+        free(pd);
+        return NULL;
+     }
+
+   elm_object_part_content_set(layout, "elm.swallow.content", primary_ly);
+   evas_object_show(primary_ly);
+
+   pd->primary_panel = primary_ly;
+
+   panel = elm_panel_add(layout);
+   if (!panel)
+     {
+        ERR("Assist panel is NULL!!");
+        evas_object_del(primary_ly);
+        evas_object_del(layout);
+        free(pd);
+        return NULL;
+     }
+   elm_panel_scrollable_set(panel, EINA_TRUE);
+   elm_panel_scrollable_content_size_set(panel, 1.0);
+   elm_object_style_set(panel, "assist");
+   elm_panel_hidden_set(panel, EINA_TRUE);
+   elm_panel_orient_set(panel, ELM_PANEL_ORIENT_BOTTOM);
+   elm_object_part_content_set(layout, "elm.swallow.right", panel);
+
+   pd->assist_panel = panel;
+
+   pd->panel_bg = evas_object_rectangle_add(evas_object_evas_get(layout));
+   evas_object_color_set(pd->panel_bg, 0, 0, 0, 0);
+   elm_object_part_content_set(layout, "elm.swallow.bg", pd->panel_bg);
+
+   elm_object_signal_callback_add(panel, "elm,state,unhold", "elm",
+                                  (Edje_Signal_Cb)_panel_unhold_cb, pd);
+   elm_object_signal_callback_add(panel, "elm,state,hold", "elm",
+                                  (Edje_Signal_Cb)_panel_hold_cb, pd);
+   evas_object_smart_callback_add(panel, "scroll", _panel_scroll_cb, pd);
+   evas_object_event_callback_add(panel, EVAS_CALLBACK_MOUSE_UP,
+                                  _panel_mouse_up_cb, pd);
+   evas_object_event_callback_add(panel, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _panel_mouse_down_cb, pd);
+   evas_object_event_callback_add(layout, EVAS_CALLBACK_DEL,
+                                  _eext_panel_del_cb, pd);
+
+   return layout;
+}
+
+EAPI void
+eext_panel_part_content_set(Evas_Object *obj, const char *part_name,
+                            Evas_Object *content)
+{
+   Eext_Panel_Data *pd = NULL;
+
+   if (!obj)
+     {
+        ERR("obj is NULL!!");
+        return;
+     }
+   if (!part_name)
+     {
+        ERR("part_name is NULL!!");
+        return;
+     }
+   if (!content)
+     {
+        ERR("content is NULL!!");
+        return;
+     }
+
+   pd = _eext_panel_data_get(obj);
+   if (!pd)
+     {
+        ERR("pd is NULL!!");
+        return;
+     }
+
+   if (!strcmp(part_name, "primary"))
+     {
+        elm_object_part_content_set(pd->primary_panel, "elm.swallow.content",
+                                    content);
+     }
+   else if (!strcmp(part_name, "assist"))
+     {
+        elm_object_content_set(pd->assist_panel, content);
+     }
+   else
+     {
+        ERR("Not supported part name!!!");
+        return;
+     }
+}
+
+EAPI Evas_Object *
+eext_panel_part_content_get(const Evas_Object *obj, const char *part_name)
+{
+   Eext_Panel_Data *pd = NULL;
+
+   if (!obj)
+     {
+        ERR("obj is NULL!!");
+        return NULL;
+     }
+   if (!part_name)
+     {
+        ERR("part_name is NULL!!");
+        return NULL;
+     }
+
+   pd = _eext_panel_data_get(obj);
+   if (!pd)
+     {
+        ERR("pd is NULL!!");
+        return NULL;
+     }
+
+   if (!strcmp(part_name, "primary"))
+     {
+        return elm_object_part_content_get(pd->primary_panel,
+                                           "elm.swallow.content");
+     }
+   else if (!strcmp(part_name, "assist"))
+     {
+        return elm_object_content_get(pd->assist_panel);
+     }
+   else
+     {
+        ERR("Not supported part name!!!");
+        return NULL;
+     }
+}
+