popup: Change the behavior of adding or removing buttons.
authorRyuan Choi <ryuan.choi@gmail.com>
Sun, 13 Oct 2013 15:57:42 +0000 (00:57 +0900)
committerDaniel Juyung Seo <seojuyung2@gmail.com>
Sun, 13 Oct 2013 16:04:01 +0000 (01:04 +0900)
Summary:
Although user should give the position of button such as button1, current elm_popup
changes button's position or style as the number of buttons while adding or removing
buttons.

So, when application developers add buttons as wrong order or removed buttons,
applications may be crashed.

This patch refactored the behavior not to change the position intended by application
developer.

Test Plan: added new test case to test_popup.

Reviewers: seoz

Reviewed By: seoz

Differential Revision: https://phab.enlightenment.org/D259

ChangeLog
NEWS
src/bin/test_popup.c
src/lib/elc_popup.c
src/lib/elm_widget_popup.h

index 3e9e5b3504aff7e94b57207e22c78478f5cc78a8..ec783e72c005632d8196ace07f52d56199f261e5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
         * scroller : fix the scroller to locate the current page correctly
         in case that the scroller is suddenly resized and then the drag
         couldn't capture the page location.
+
+2013-10-12  Ryuan Choi (ryuan)
+
+        * popup : Change the behavior about adding or removing buttons to keep the
+        user defined position of button.
diff --git a/NEWS b/NEWS
index 199215041f92753f6bfd5e6c4c00b423a1353818..9af53550e059fa6b7eb00e0be3af1e6b3e41351e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -147,6 +147,7 @@ Improvements:
    content is static object and it won't be updated by content position.
    This actually reduces the mapbuf calculation time muchly in case of complex
    layout.
+   * Popup: Change the behavior of adding/removing buttons dynamically. User defined button's position is kept.
 
 Fixes:
    * Now elm_datetime_field_limit_set() can set year limits wihtout problems.
index 814e14e94bd3ff31c50d683596dc9f7e6ca82d27..fa2d06ef316d8c05f23d5d71731c4baa18fbd1b6 100644 (file)
@@ -385,6 +385,65 @@ _popup_center_text_1button_hide_show_cb(void *data, Evas_Object *obj EINA_UNUSED
    evas_object_show(g_popup);
 }
 
+static void
+_toggle_button_cb(void *data,
+                  Evas_Object *obj,
+                  void *event_info EINA_UNUSED)
+{
+   Evas_Object *btn = data;
+   char buf[] = "button0";
+   int i;
+
+   i = (int)(uintptr_t)evas_object_data_get(btn, "index");
+
+   buf[6] = '0' + i + 1;
+   if (evas_object_visible_get(btn))
+     {
+        elm_object_part_content_unset(obj, buf);
+        evas_object_hide(btn);
+     }
+   else
+     elm_object_part_content_set(obj, buf, btn);
+}
+
+static void
+_popup_center_text_3button_add_remove_button_cb(void *data,
+                                                Evas_Object *obj EINA_UNUSED,
+                                                void *event_info EINA_UNUSED)
+{
+   Evas_Object *popup;
+   Evas_Object *btns[3];
+
+   char buf[256];
+   int i;
+
+   popup = elm_popup_add(data);
+
+   // popup title
+   elm_object_part_text_set(popup, "title,text",
+                            "Click the item to toggle button");
+
+   // popup buttons
+   for (i = 0; i < 3; ++i)
+     {
+        snprintf(buf, sizeof(buf), "Btn #%d", i + 1);
+        btns[i] = elm_button_add(popup);
+        evas_object_data_set(btns[i], "index", (void*)(uintptr_t)i);
+        elm_object_text_set(btns[i], buf);
+
+        elm_popup_item_append(popup, buf, NULL, _toggle_button_cb, btns[i]);
+
+        snprintf(buf, sizeof(buf), "button%d", i + 1);
+        elm_object_part_content_set(popup, buf, btns[i]);
+        evas_object_smart_callback_add(btns[i], "clicked",
+                                       _popup_close_cb, popup);
+     }
+
+   // popup show should be called after adding all the contents and the buttons
+   // of popup to set the focus into popup's contents correctly.
+   evas_object_show(popup);
+}
+
 static void
 _popup_transparent_cb(void *data, Evas_Object *obj EINA_UNUSED,
                       void *event_info EINA_UNUSED)
@@ -480,6 +539,8 @@ test_popup(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
                         _popup_center_title_text_2button_restack_cb, win);
    elm_list_item_append(list, "popup-center-text + 1 button (check hide, show)", NULL, NULL,
                         _popup_center_text_1button_hide_show_cb, win);
+   elm_list_item_append(list, "popup-center-text + 3 button (check add, remove buttons)", NULL, NULL,
+                        _popup_center_text_3button_add_remove_button_cb, win);
    elm_list_item_append(list, "popup-transparent", NULL, NULL,
                         _popup_transparent_cb, win);
    elm_list_item_append(list, "popup-center-title + list content + 1 button",
index 078a022b72a48569548b4cbb17f15eef2e069149..b2dbf51e617d4b9c35236aec2a40fe714f391745 100644 (file)
@@ -221,7 +221,7 @@ _elm_popup_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
      (sd->content, EVAS_CALLBACK_DEL, _on_content_del);
    evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _on_show);
 
-   sd->button_count = 0;
+   sd->last_button_number = 0;
 
    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
      {
@@ -336,7 +336,7 @@ _elm_popup_smart_theme(Eo *obj, void *_pd, va_list *list)
 
    if (sd->action_area)
      {
-        snprintf(buf, sizeof(buf), "buttons%i", sd->button_count);
+        snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
         if (!elm_layout_theme_set(sd->action_area, "popup", buf, style))
           CRITICAL("Failed to set layout!");
         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
@@ -549,37 +549,36 @@ _button_remove(Evas_Object *obj,
    ELM_POPUP_DATA_GET(obj, sd);
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
 
-   if (!sd->button_count) return;
+   if (!sd->last_button_number) return;
 
    if (!sd->buttons[pos]) return;
 
-   if (delete) evas_object_del(sd->buttons[pos]->btn);
+   if (delete)
+     {
+        evas_object_del(sd->buttons[pos]->btn);
+     }
+   else
+     {
+        evas_object_event_callback_del
+          (sd->buttons[pos]->btn, EVAS_CALLBACK_DEL, _on_button_del);
+        snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", pos + 1);
+        elm_object_part_content_unset(sd->action_area, buf);
+     }
 
-   evas_object_event_callback_del
-     (sd->buttons[pos]->btn, EVAS_CALLBACK_DEL, _on_button_del);
    ELM_SAFE_FREE(sd->buttons[pos], free);
-   sd->button_count -= 1;
 
-   if (!sd->no_shift)
+   for (i = ELM_POPUP_ACTION_BUTTON_MAX - 1; i >= 0; i--)
      {
-        /* shift left the remaining buttons */
-        for (i = pos; i < ELM_POPUP_ACTION_BUTTON_MAX - 1; i++)
+        if (sd->buttons[i])
           {
-             sd->buttons[i] = sd->buttons[i + 1];
-
-             snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", pos + 1);
-             elm_object_part_content_unset(sd->action_area, buf);
-             snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", pos);
-             elm_object_part_content_set
-               (sd->action_area, buf, sd->buttons[i]->btn);
+             sd->last_button_number = i + 1;
+             break;
           }
      }
 
-   if (!sd->button_count)
+   if (!sd->last_button_number)
      {
         _visuals_set(obj);
-        edje_object_part_unswallow
-          (obj, edje_object_part_swallow_get(obj, "elm.swallow.action_area"));
         evas_object_del(sd->action_area);
         sd->action_area = NULL;
         edje_object_message_signal_process(wd->resize_obj);
@@ -589,7 +588,7 @@ _button_remove(Evas_Object *obj,
         char style[1024];
         
         snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
-        snprintf(buf, sizeof(buf), "buttons%i", sd->button_count);
+        snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
         if (!elm_layout_theme_set(sd->action_area, "popup", buf, style))
           CRITICAL("Failed to set layout!");
      }
@@ -1107,7 +1106,6 @@ _action_button_set(Evas_Object *obj,
                    Evas_Object *btn,
                    unsigned int idx)
 {
-   Action_Area_Data *adata;
    char buf[128], style[1024];
 
    ELM_POPUP_DATA_GET(obj, sd);
@@ -1121,15 +1119,29 @@ _action_button_set(Evas_Object *obj,
         return;
      }
 
-   if (!sd->buttons[idx]) sd->button_count++;
-   else
+   if (sd->buttons[idx])
      {
-        sd->no_shift = EINA_TRUE;
         evas_object_del(sd->buttons[idx]->btn);
-        sd->no_shift = EINA_FALSE;
+        free(sd->buttons[idx]);
      }
 
-   snprintf(buf, sizeof(buf), "buttons%i", sd->button_count);
+   sd->buttons[idx] = ELM_NEW(Action_Area_Data);
+   sd->buttons[idx]->obj = obj;
+   sd->buttons[idx]->btn = btn;
+
+   evas_object_event_callback_add
+     (btn, EVAS_CALLBACK_DEL, _on_button_del, obj);
+
+   for (unsigned int i = ELM_POPUP_ACTION_BUTTON_MAX - 1; i >= idx; i--)
+     {
+        if (sd->buttons[i])
+          {
+             sd->last_button_number = i + 1;
+             break;
+          }
+     }
+
+   snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
    if (!sd->action_area)
      {
         sd->action_area = elm_layout_add(obj);
@@ -1138,29 +1150,18 @@ _action_button_set(Evas_Object *obj,
            _size_hints_changed_cb, obj);
         edje_object_part_swallow
           (wd->resize_obj, "elm.swallow.action_area", sd->action_area);
+
+        _visuals_set(obj);
      }
 
    snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
    if (!elm_layout_theme_set(sd->action_area, "popup", buf, style))
      CRITICAL("Failed to set layout!");
 
-   adata = ELM_NEW(Action_Area_Data);
-   adata->obj = obj;
-   adata->btn = btn;
-
-   elm_object_style_set(btn, style);
-   
-   evas_object_event_callback_add
-     (btn, EVAS_CALLBACK_DEL, _on_button_del, obj);
-
-   sd->buttons[idx] = adata;
-
    snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", idx + 1);
    elm_object_part_content_set
      (sd->action_area, buf, sd->buttons[idx]->btn);
 
-   if (sd->button_count == 1) _visuals_set(obj);
-
    edje_object_message_signal_process(wd->resize_obj);
    if (sd->items) _scroller_size_calc(obj);
 
index 5150258723ca341a8018b12f87cb60e387a94547..bfca443a1054336d5196932999d1c951f0418da1 100644 (file)
@@ -38,12 +38,11 @@ struct _Elm_Popup_Smart_Data
    const char           *title_text;
    Action_Area_Data     *buttons[ELM_POPUP_ACTION_BUTTON_MAX];
    Elm_Wrap_Type         content_text_wrap_type;
-   unsigned int          button_count;
+   unsigned int          last_button_number;
    Evas_Coord            max_sc_w;
    Evas_Coord            max_sc_h;
 
    Eina_Bool             visible : 1;
-   Eina_Bool             no_shift : 1;
    Eina_Bool             scr_size_recalc : 1;
 };