popup: Change the behavior of adding or removing buttons.

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
This commit is contained in:
Ryuan Choi 2013-10-14 00:57:42 +09:00 committed by Daniel Juyung Seo
parent e23e151242
commit 4314560b49
5 changed files with 112 additions and 45 deletions

View File

@ -1689,3 +1689,8 @@
* 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.

View File

@ -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.

View 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",

View 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);
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)
if (delete)
{
/* shift left the remaining buttons */
for (i = pos; i < ELM_POPUP_ACTION_BUTTON_MAX - 1; i++)
{
sd->buttons[i] = sd->buttons[i + 1];
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);
}
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);
ELM_SAFE_FREE(sd->buttons[pos], free);
for (i = ELM_POPUP_ACTION_BUTTON_MAX - 1; i >= 0; i--)
{
if (sd->buttons[i])
{
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);

View 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;
};