rotary_selector: enable add item in the editing mode 74/145274/2
authorThiep Ha <thiep.ha@samsung.com>
Tue, 22 Aug 2017 02:45:13 +0000 (11:45 +0900)
committerThiep Ha <thiep.ha@samsung.com>
Tue, 22 Aug 2017 03:25:23 +0000 (12:25 +0900)
In the editing mode, if the add item is enabled, the add item
is added at the end of the list. When the add item is clicked,
application should handle to the clicked signal and add items.

Change-Id: I1e25cd97e4ee6537edce6e352f0e45508e377e94

inc/wearable/efl_extension_common_private.h
inc/wearable/efl_extension_more_option.h
inc/wearable/efl_extension_rotary_selector.h
src/wearable/efl_extension_more_option.c
src/wearable/efl_extension_rotary_selector.c

index 3dca83f066d6a329becf61114c0dbfce92cefcd0..feece806015b822f53fe58d181901c166b89c9c1 100644 (file)
@@ -156,6 +156,8 @@ struct _Eext_Rotary_Selector_Data {
    Eext_Rotary_Selector_Item *tmp_drag_item;
    Eina_Bool drag_done;
    int del_item_index;
+   Eext_Rotary_Selector_Item *add_item;
+   Eina_Bool add_enabled;
    //for accessibility
    Evas_Object *event_area_access_object;
    Eext_Rotary_Selector_Accessibility_Eventarea_Hightlihgted_State event_area_highlighted_state;
index 12ac7539285a47c381e11831175cb4f1fc68e197..0a619c84cf27f68f6e3b29e99810ffc7bd46b0d1 100644 (file)
@@ -361,10 +361,48 @@ EAPI void eext_more_option_editing_enabled_set(Evas_Object *obj, Eina_Bool enabl
 
 /**
  * @WEARABLE_ONLY
- * @brief Get whether the item can be deleted in the edit mode or not.
+ * @brief Get whether item(s) can be added in the edit mode or not.
  *
  * @param[in] obj The more option object
- * @see eext_more_option_item_delete_enabled_get()
+ * @see eext_more_option_add_item_enabled_set()
+ * @see eext_more_option_editing_enabled_get()
+ * @see eext_more_option_editing_enabled_set()
+ * @return EINA_TRUE if item(s) can be added, otherwise EINA_FALSE
+ *
+ * @details When add item is enabled, in the editing mode, the add item
+ * is shown at the end of the item list. If users click the add item,
+ * the "add_item,clicked" signal is emitted.
+ *
+ * @if WEARABLE @since_tizen 4.0
+ * @endif
+ */
+EAPI Eina_Bool eext_more_option_add_item_enabled_get(const Evas_Object *obj);
+
+/**
+ * @WEARABLE_ONLY
+ * @brief Set whether item(s) can be added in the edit mode or not.
+ *
+ * @param[in] obj The more option object
+ * @param[in] enabled enable delete item in the edit mode
+ * @see eext_more_option_add_item_enabled_get()
+ * @see eext_more_option_editing_enabled_get()
+ * @see eext_more_option_editing_enabled_set()
+ *
+ * @details When add item is enabled, in the editing mode, the add item
+ * is shown at the end of the item list. If users click the add item,
+ * the "add_item,clicked" signal is emitted.
+ *
+ * @if WEARABLE @since_tizen 4.0
+ * @endif
+ */
+EAPI void eext_more_option_add_item_enabled_set(Evas_Object *obj, Eina_Bool enabled);
+
+/**
+ * @WEARABLE_ONLY
+ * @brief Get whether the item can be deleted in the edit mode or not.
+ *
+ * @param[in] item The more option object item
+ * @see eext_more_option_item_delete_enabled_set()
  * @see eext_more_option_editing_enabled_get()
  * @see eext_more_option_editing_enabled_set()
  * @return EINA_TRUE if item can be deleted, otherwise EINA_FALSE
@@ -379,7 +417,7 @@ EAPI Eina_Bool eext_more_option_item_delete_enabled_get(const Eext_Object_Item *
  * @brief Set whether the item can be deleted in the edit mode or not.
  *        By default, it is enabled.
  *
- * @param[in] obj The more option object
+ * @param[in] item The more option object item
  * @param[in] enabled enable delete item in the edit mode
  * @see eext_more_option_item_delete_enabled_get()
  * @see eext_more_option_editing_enabled_get()
index a5e7f56f8c597001ff2fa266fc25d1a02a820ab2..9bd788f6e5c61376aa5979fdb20ea5fe2b651925 100644 (file)
@@ -473,9 +473,47 @@ EAPI void eext_rotary_selector_editing_enabled_set(Evas_Object *obj, Eina_Bool e
 
 /**
  * @WEARABLE_ONLY
- * @brief Set whether the item can be deleted in the edit mode or not.
+ * @brief Get whether item(s) can be added in the edit mode or not.
  *
  * @param[in] obj The rotary selector
+ * @see eext_rotary_selector_add_item_enabled_set()
+ * @see eext_rotary_selector_editing_enabled_set()
+ * @see eext_rotary_selector_editing_enabled_get()
+ * @return EINA_TRUE if item(s) can be added, otherwise EINA_FALSE
+ *
+ * @details When add item is enabled, in the editing mode, the add item
+ * is shown at the end of the item list. If users click the add item,
+ * the "add_item,clicked" signal is emitted.
+ *
+ * @if WEARABLE @since_tizen 4.0
+ * @endif
+ */
+EAPI Eina_Bool eext_rotary_selector_add_item_enabled_get(const Evas_Object *obj);
+
+/**
+ * @WEARABLE_ONLY
+ * @brief Set whether item(s) can be added in the edit mode or not.
+ *
+ * @param[in] obj The rotary selector
+ * @param[in] enabled enable showing add item in editing mode
+ * @see eext_rotary_selector_add_item_enabled_get()
+ * @see eext_rotary_selector_editing_enabled_set()
+ * @see eext_rotary_selector_editing_enabled_get()
+ *
+ * @details When add item is enabled, in the editing mode, the add item
+ * is shown at the end of the item list. If users click the add item,
+ * the "add_item,clicked" signal is emitted.
+ *
+ * @if WEARABLE @since_tizen 4.0
+ * @endif
+ */
+EAPI void eext_rotary_selector_add_item_enabled_set(Evas_Object *obj, Eina_Bool enabled);
+
+/**
+ * @WEARABLE_ONLY
+ * @brief Set whether the item can be deleted in the edit mode or not.
+ *
+ * @param[in] item The rotary selector item
  * @param[in] enabled enable delete item in the edit mode
  * @see eext_rotary_selector_item_delete_enabled_get()
  * @see eext_rotary_selector_editing_enabled_set()
@@ -490,8 +528,8 @@ EAPI void eext_rotary_selector_item_delete_enabled_set(Eext_Object_Item *item, E
  * @WEARABLE_ONLY
  * @brief Get whether the item can be deleted in the edit mode or not.
  *
- * @param[in] obj The rotary selector
- * @see eext_rotary_selector_item_delete_enabled_get()
+ * @param[in] item The rotary selector item
+ * @see eext_rotary_selector_item_delete_enabled_set()
  * @see eext_rotary_selector_editing_enabled_set()
  * @see eext_rotary_selector_editing_enabled_get()
  * @return EINA_TRUE if item can be deleted, otherwise EINA_FALSE
index 1ccfdb7c866fe2782295443182619b34766f59e5..e1218e3d174dc09af43c6b675a88305e6de8550e 100644 (file)
@@ -722,6 +722,50 @@ eext_more_option_editing_enabled_get(const Evas_Object *obj)
    return eext_rotary_selector_editing_enabled_get(mold->rotary_selector);
 }
 
+EAPI Eina_Bool
+eext_more_option_add_item_enabled_get(const Evas_Object *obj)
+{
+   const Evas_Object *more_option = obj;
+   Eext_More_Option_Data *mold = NULL;
+
+   if (!more_option)
+     {
+        ERR("more_option is NULL!!");
+        return EINA_FALSE;
+     }
+
+   mold = _more_option_data_get(more_option);
+   if (!mold)
+     {
+        ERR("mold is NULL!!");
+        return EINA_FALSE;
+     }
+
+   return eext_rotary_selector_add_item_enabled_get(mold->rotary_selector);
+}
+
+EAPI void
+eext_more_option_add_item_enabled_set(Evas_Object *obj, Eina_Bool enabled)
+{
+   const Evas_Object *more_option = obj;
+   Eext_More_Option_Data *mold = NULL;
+
+   if (!more_option)
+     {
+        ERR("more_option is NULL!!");
+        return;
+     }
+
+   mold = _more_option_data_get(more_option);
+   if (!mold)
+     {
+        ERR("mold is NULL!!");
+        return;
+     }
+
+   return eext_rotary_selector_add_item_enabled_set(mold->rotary_selector, enabled);
+}
+
 EAPI Eina_Bool
 eext_more_option_item_delete_enabled_get(const Eext_Object_Item *item)
 {
index e1b731ea8d47359b1b4667043333be7303755522..4426280696bf3168c4c6f40cbad0f4af6de64b82 100644 (file)
@@ -206,7 +206,7 @@ static void _layer_items_invalidate(Eext_Rotary_Selector_Data *rsd);
 static void _item_rearrange(Eext_Rotary_Selector_Data *rsd, int selected_index);
 static void _item_select(Eext_Rotary_Selector_Data *rsd, int index);
 static void _item_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
-static Eext_Rotary_Selector_Item *_item_create(Eext_Rotary_Selector_Data *rsd);
+static Eext_Rotary_Selector_Item *_item_create(Eext_Rotary_Selector_Data *rsd, Eina_Bool is_add_item);
 static void _item_selected_signal_send(Eext_Rotary_Selector_Data *rsd, int previous_item_index, int current_item_index);
 static void _item_touched_signal_send(Eext_Rotary_Selector_Data *rsd, int index, Eina_Bool pressed, Eina_Bool sound);
 
@@ -228,6 +228,7 @@ static void _selector_update(Eext_Rotary_Selector_Data *rsd, Eina_Bool page_chan
 static void _selector_content_update(Eext_Rotary_Selector_Data *rsd);
 static void _selector_clicked_signal(void *data, Evas_Object *obj, const char *emission, const char *source);
 static void _selector_animation_finished_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _editing_mode_turnoff(Eext_Rotary_Selector_Data *rsd);
 
 // ----------------------------------------- Accessibility API --------------------------------------//
 static Eina_Bool _accessibility_event_area_highlighted_cb(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info);
@@ -607,6 +608,7 @@ _dnd_pos_cb(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_A
              int first_index = rsd->current_page * _ROTARY_SELECTOR_PAGE_ITEM_MAX;
              const float touchAreaAngle[] = {45.f, 75.f, 105.f, 135.f, 165.f, 195.f,
                                                    225.f, 255.f, 285.f, 315.f, 340.f};
+             int count = eina_list_count(rsd->item_list);
 
              //cancel stand timer
              if (rsd->stand_timer)
@@ -619,9 +621,15 @@ _dnd_pos_cb(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_A
                   if(angle < touchAreaAngle[i]) break;
                }
              new_index = first_index + i;
-             rsd->drop_item_index = new_index;
-             if (new_index != rsd->drag_item_index)
+
+             if ((!rsd->add_enabled && new_index >= count) ||
+                 (rsd->add_enabled && new_index >= count - 1))
+               {
+                  rsd->drop_item_index = _ROTARY_SELECTOR_PRESSED_ITEM_INDEX_INVALID;
+               }
+             else
                {
+                  rsd->drop_item_index = new_index;
                   rsd->stand_timer = ecore_timer_add(rsd->longpress_timeout,
                                                      _drag_item_move, rsd);
                }
@@ -664,7 +672,7 @@ _image_create_icon(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord
    if (yoff) *yoff = rsd->item_height / 2;
 
 
-   tmp_item = _item_create(rsd);
+   tmp_item = _item_create(rsd, EINA_FALSE);
    if (!tmp_item)
      return NULL;
    evas_object_show(tmp_item->base.obj);
@@ -752,8 +760,6 @@ _image_create_icon(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord
    return new_icon;
 #endif
 
-
-   ERR("done");
    return icon;
 }
 
@@ -879,6 +885,7 @@ _event_area_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_inf
                   rsd->pressed_item_index = new_index;
                   if (rsd->editing)
                     {
+                       int add_idx;
                        rsd->on_delete_icon = _delete_icon_mouse_on_check(rsd, new_index,
                                                             ev->canvas.x, ev->canvas.y);
                        if (rsd->on_delete_icon)
@@ -889,14 +896,19 @@ _event_area_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_inf
                             elm_object_signal_emit(it->base.obj,
                                        "elm,action,button,delete,selected", "");
                          }
-                       rsd->drag_item_index = new_index;
                        if (rsd->longpress_timer)
                          {
                             ecore_timer_del(rsd->longpress_timer);
                             rsd->longpress_timer = NULL;
                          }
-                       rsd->longpress_timer = ecore_timer_add(rsd->longpress_timeout,
-                                                              _item_longpress_cb, rsd);
+
+                       add_idx = eina_list_count(rsd->item_list) - 1;
+                       if (!rsd->add_enabled || (new_index != add_idx))
+                         {
+                            rsd->drag_item_index = new_index;
+                            rsd->longpress_timer = ecore_timer_add(rsd->longpress_timeout,
+                                                                   _item_longpress_cb, rsd);
+                         }
                     }
                   else
                     {
@@ -1100,6 +1112,7 @@ _event_area_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
                {
                   if (rsd->editing)
                     {
+                       int add_idx = eina_list_count(rsd->item_list) - 1;
                        if (rsd->on_delete_icon)
                          {
                             Eina_Bool still_on = _delete_icon_mouse_on_check(rsd, new_index, ev->canvas.x, ev->canvas.y);
@@ -1118,6 +1131,12 @@ _event_area_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
                                  rsd->item_del_timer = ecore_timer_add(_ROTARY_SELECTOR_DEL_ANIMATION_DURATION, _del_item_timer_cb, rsd);
                               }
                          }
+                       else if (rsd->add_enabled && (new_index == add_idx))
+                         {
+                            _editing_mode_turnoff(rsd);
+                            evas_object_smart_callback_call(rsd->rotary_selector,
+                                                            "add_item,clicked", NULL);
+                         }
                     }
                   else
                     {
@@ -1709,6 +1728,20 @@ _rotary_selector_item_delete_icon_hide(Eext_Rotary_Selector_Data *rsd)
      }
 }
 
+static void
+_add_item_create(Eext_Rotary_Selector_Data *rsd)
+{
+   Eext_Rotary_Selector_Item *add_item = _item_create(rsd, EINA_TRUE);
+   if (!add_item)
+     return;
+
+   add_item->delete_enabled = EINA_FALSE;
+   rsd->item_list = eina_list_append(rsd->item_list, add_item);
+   add_item->index = rsd->item_count;
+   rsd->item_count++;
+   rsd->add_item = add_item;
+}
+
 static Eina_Bool
 _editing_timer_cb(void *data)
 {
@@ -1722,6 +1755,14 @@ _editing_timer_cb(void *data)
    elm_object_part_text_set(elm_object_part_content_get(rsd->rotary_selector, "content"),
                             "selector,sub_text", "");
    rsd->editing = EINA_TRUE;
+   if (rsd->add_enabled)
+     {
+        _add_item_create(rsd);
+
+        _item_rearrange(rsd, rsd->selected_index);
+        _items_transformation_update(rsd);
+        _items_invalidate(rsd);
+     }
    _rotary_selector_item_delete_icon_show(rsd);
 
    bg = elm_object_part_content_get(rsd->rotary_selector, "selector,bg_image");
@@ -1741,7 +1782,18 @@ _editing_mode_turnoff(Eext_Rotary_Selector_Data *rsd)
    _rotary_selector_item_delete_icon_hide(rsd);
    bg = elm_object_part_content_get(rsd->rotary_selector, "selector,bg_image");
    elm_object_signal_emit(bg, "elm,selector,bg,show", "elm");
+
+   if (rsd->add_enabled)
+     {
+        rsd->item_list = eina_list_remove(rsd->item_list, rsd->add_item);
+        evas_object_del(rsd->add_item->base.obj);
+        _item_rearrange(rsd, rsd->selected_index);
+        _items_transformation_update(rsd);
+        _items_invalidate(rsd);
+     }
    _selector_update(rsd, EINA_FALSE, EINA_FALSE);
+   eext_object_event_callback_del(rsd->rotary_selector, EEXT_CALLBACK_BACK,
+                                  _back_event_cb);
 }
 
 static void
@@ -1805,8 +1857,11 @@ static void _back_event_cb(void *data, Evas_Object *obj, void *event_info)
         _editing_mode_turnoff(rsd);
         rsd->editing = EINA_FALSE;
      }
-   eext_object_event_callback_del(rsd->rotary_selector, EEXT_CALLBACK_BACK,
-                                  _back_event_cb);
+   else
+     {
+        eext_object_event_callback_del(rsd->rotary_selector, EEXT_CALLBACK_BACK,
+                                       _back_event_cb);
+     }
 }
 // ----------------------------------------- item API --------------------------------------//
 static void
@@ -2052,7 +2107,7 @@ _item_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
 }
 
 static Eext_Rotary_Selector_Item *
-_item_create(Eext_Rotary_Selector_Data *rsd)
+_item_create(Eext_Rotary_Selector_Data *rsd, Eina_Bool is_add_item)
 {
    Eext_Rotary_Selector_Item *item = NULL;
    Evas_Object *button = NULL;
@@ -2072,14 +2127,20 @@ _item_create(Eext_Rotary_Selector_Data *rsd)
 
    evas_object_size_hint_weight_set(button,EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
-   elm_object_style_set(button, "rotary_selector_item");
+   if (!is_add_item)
+     elm_object_style_set(button, "rotary_selector_item");
+   else
+     elm_object_style_set(button, "rotary_selector_add_item");
    evas_object_move(button, -_ROTARY_SELECTOR_SCREEN_WIDTH, -_ROTARY_SELECTOR_SCREEN_HEIGHT);
    evas_object_resize(button, rsd->item_width, rsd->item_height);
    evas_object_smart_member_add(button, rotary_selector);
 
-   Evas_Object *action_bg = elm_layout_add(button);
-   elm_layout_theme_set(action_bg, "rotary_selector", "item", "bg_image");
-   elm_object_part_content_set(button, "item,bg_image", action_bg);
+   if (!is_add_item)
+     {
+        Evas_Object *action_bg = elm_layout_add(button);
+        elm_layout_theme_set(action_bg, "rotary_selector", "item", "bg_image");
+        elm_object_part_content_set(button, "item,bg_image", action_bg);
+     }
 
    item = (Eext_Rotary_Selector_Item *)calloc(1, sizeof(Eext_Rotary_Selector_Item));
    if (!item)
@@ -2786,7 +2847,7 @@ eext_rotary_selector_item_append(Evas_Object *obj)
         return NULL;
      }
 
-   item = _item_create(rsd);
+   item = _item_create(rsd, EINA_FALSE);
    if (!item)
      {
         ERR("item is NULL!!");
@@ -2823,7 +2884,7 @@ eext_rotary_selector_item_prepend(Evas_Object *obj)
         return NULL;
      }
 
-   item = _item_create(rsd);
+   item = _item_create(rsd, EINA_FALSE);
    if (!item)
      {
         ERR("item is NULL!!");
@@ -2861,7 +2922,7 @@ eext_rotary_selector_item_insert_after(Evas_Object *obj, Eext_Object_Item *after
         return NULL;
      }
 
-   item = _item_create(rsd);
+   item = _item_create(rsd, EINA_FALSE);
    if (!item)
      {
         ERR("item is NULL!!");
@@ -2903,7 +2964,7 @@ eext_rotary_selector_item_insert_before(Evas_Object *obj, Eext_Object_Item *befo
         return NULL;
      }
 
-   item = _item_create(rsd);
+   item = _item_create(rsd, EINA_FALSE);
    if (!item)
      {
         ERR("item is NULL!!");
@@ -3675,6 +3736,30 @@ eext_rotary_selector_editing_enabled_set(Evas_Object *obj, Eina_Bool enabled)
    rsd->edit_mode_enabled = enabled;
 }
 
+EAPI Eina_Bool
+eext_rotary_selector_add_item_enabled_get(const Evas_Object *obj)
+{
+   Eext_Rotary_Selector_Data *rsd = _eext_rotary_selector_data_get(obj);
+   if (!rsd)
+     {
+        ERR("rsd is NULL!!");
+        return EINA_FALSE;
+     }
+   return rsd->add_enabled;
+}
+
+EAPI void
+eext_rotary_selector_add_item_enabled_set(Evas_Object *obj, Eina_Bool enabled)
+{
+   Eext_Rotary_Selector_Data *rsd = _eext_rotary_selector_data_get(obj);
+   if (!rsd)
+     {
+        ERR("rsd is NULL!!");
+        return;
+     }
+   rsd->add_enabled = enabled;
+}
+
 EAPI Eina_Bool
 eext_rotary_selector_item_delete_enabled_get(const Eext_Object_Item *item)
 {
@@ -3703,8 +3788,6 @@ eext_rotary_selector_item_delete_enabled_set(Eext_Object_Item *item, Eina_Bool e
    rotary_selector_item->delete_enabled = enabled;
 }
 
-
-
 // ----------------------------------------- Accessibility API --------------------------------------//
 static void
 _accessibility_item_btn_highlighted_cb(void *data, Evas_Object *obj, void *event_info)