elm_panel: set hidden property when panel is close/open

Summary:
 - elm_panel has a property named hidden which stores
   open/close status.
 - This is updated when:
    1. bring_in animation is done(anim_stop_cb).
    2. mouse_up on panel.
    3. API is called. (elm_panel_toggle, elm_panel_hidden_set)
 - In case 3, API changes hidden, and starts bring_in animation
   which will call anim_stop_cb() which will update hidden again.
 - If bring_in animation is canceled (eg: sizing_eval),
   anim_stop_cb will be called and calculate hidden status
   which will not guarantee updated hidden state by APIs.

Test Plan:
   1. Call any APIs which will call elm_layout_sizing_eval(panel)
      right after calling elm_panel_toggle()/elm_panel_hidden_set().
   2. Delete content of panel during "toggled" cb.

Reviewers: jpeg, eunue, cedric

Subscribers: conr2d, cedric, jpeg

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

Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
This commit is contained in:
Sungtaek Hong 2017-06-08 16:00:20 +09:00 committed by Jean-Philippe Andre
parent b310e5892c
commit 9dd997f389
2 changed files with 142 additions and 211 deletions

View File

@ -280,6 +280,27 @@ _clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUS
elm_panel_toggle(panel); elm_panel_toggle(panel);
} }
static void
_toggled_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Evas_Object *list;
int i;
if (!elm_check_state_get(data)) return;
list = elm_object_content_get(obj);
evas_object_del(list);
list = elm_list_add(obj);
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
for (i = 0; i < 7; i++)
elm_list_item_append(list, "panel list item", NULL, NULL, NULL, NULL);
elm_object_content_set(obj, list);
printf("Panel toggled:%s\n", elm_panel_hidden_get(obj) ? "hidden" : "visible");
}
static void static void
_changed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) _changed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{ {
@ -322,6 +343,11 @@ test_panel2(void *data EINA_UNUSED,
evas_object_smart_callback_add(check, "changed", _changed_cb, NULL); evas_object_smart_callback_add(check, "changed", _changed_cb, NULL);
check = elm_check_add(box);
elm_object_text_set(check, "Reset content on toggle");
evas_object_show(check);
elm_box_pack_end(box, check);
// toggle button // toggle button
button = elm_button_add(box); button = elm_button_add(box);
evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, 0); evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, 0);
@ -365,5 +391,6 @@ test_panel2(void *data EINA_UNUSED,
elm_list_item_append(list, "panel list item", NULL, NULL, NULL, NULL); elm_list_item_append(list, "panel list item", NULL, NULL, NULL, NULL);
elm_object_content_set(panel, list); elm_object_content_set(panel, list);
evas_object_smart_callback_add(panel, "toggled", _toggled_cb, check);
evas_object_smart_callback_add(button, "clicked", _clicked_cb, panel); evas_object_smart_callback_add(button, "clicked", _clicked_cb, panel);
} }

View File

@ -219,7 +219,6 @@ EOLIAN static Elm_Theme_Apply
_elm_panel_elm_widget_theme_apply(Eo *obj, Elm_Panel_Data *sd) _elm_panel_elm_widget_theme_apply(Eo *obj, Elm_Panel_Data *sd)
{ {
const char *str; const char *str;
int w, h;
Evas_Coord minw = 0, minh = 0; Evas_Coord minw = 0, minh = 0;
Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED; Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
@ -237,9 +236,6 @@ _elm_panel_elm_widget_theme_apply(Eo *obj, Elm_Panel_Data *sd)
elm_widget_theme_object_set(obj, sd->scr_edje, "scroller", "panel", elm_widget_theme_object_set(obj, sd->scr_edje, "scroller", "panel",
elm_widget_style_get(obj)); elm_widget_style_get(obj));
_scrollable_layout_theme_set(obj, sd); _scrollable_layout_theme_set(obj, sd);
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
if (!sd->hidden) _drawer_open(obj, w, h, EINA_FALSE);
else _drawer_close(obj, w, h, EINA_FALSE);
handler_size = edje_object_data_get(sd->scr_edje, "handler_size"); handler_size = edje_object_data_get(sd->scr_edje, "handler_size");
if (handler_size) if (handler_size)
sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size)); sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size));
@ -516,131 +512,56 @@ static Eina_Bool
_state_sync(Evas_Object *obj) _state_sync(Evas_Object *obj)
{ {
ELM_PANEL_DATA_GET(obj, sd); ELM_PANEL_DATA_GET(obj, sd);
Evas_Object *ao; Evas_Coord pos, panel_size, w, h, threshold;
Evas_Coord pos, panel_size, w, h; Eina_Bool horizontal = EINA_FALSE, reverse = EINA_FALSE;
Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE;
evas_object_geometry_get(obj, NULL, NULL, &w, &h); evas_object_geometry_get(obj, NULL, NULL, &w, &h);
if (!evas_object_visible_get(sd->bx)) return EINA_TRUE; if (!evas_object_visible_get(sd->bx)) return EINA_TRUE;
switch (sd->orient) switch (sd->orient)
{ {
case ELM_PANEL_ORIENT_TOP:
if (h <= 0) return EINA_TRUE;
panel_size = h * sd->content_size_ratio;
elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
if (pos == 0) open = EINA_TRUE;
else if (pos == panel_size) open = EINA_FALSE;
else return EINA_FALSE;
break;
case ELM_PANEL_ORIENT_BOTTOM: case ELM_PANEL_ORIENT_BOTTOM:
if (h <= 0) return EINA_TRUE; reverse = EINA_TRUE;
case ELM_PANEL_ORIENT_TOP:
panel_size = h * sd->content_size_ratio;
elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
if (pos == panel_size) open = EINA_TRUE;
else if (pos == 0) open = EINA_FALSE;
else return EINA_FALSE;
break;
case ELM_PANEL_ORIENT_LEFT:
if (w <= 0) return EINA_TRUE;
panel_size = w * sd->content_size_ratio;
elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
horizontal = EINA_TRUE;
if (!elm_widget_mirrored_get(obj))
{
if (pos == 0) open = EINA_TRUE;
else if (pos == panel_size) open = EINA_FALSE;
else return EINA_FALSE;
}
else
{
if (pos == panel_size) open = EINA_TRUE;
else if (pos == 0) open = EINA_FALSE;
else return EINA_FALSE;
}
break; break;
case ELM_PANEL_ORIENT_RIGHT: case ELM_PANEL_ORIENT_RIGHT:
reverse = EINA_TRUE;
case ELM_PANEL_ORIENT_LEFT:
horizontal = EINA_TRUE;
break;
}
if (horizontal)
{
if (w <= 0) return EINA_TRUE; if (w <= 0) return EINA_TRUE;
panel_size = w * sd->content_size_ratio; panel_size = w * sd->content_size_ratio;
elm_interface_scrollable_content_pos_get(obj, &pos, NULL); elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
horizontal = EINA_TRUE; reverse ^= elm_widget_mirrored_get(obj);
if (elm_widget_mirrored_get(obj))
{
if (pos == 0) open = EINA_TRUE;
else if (pos == panel_size) open = EINA_FALSE;
else return EINA_FALSE;
} }
else else
{ {
if (pos == panel_size) open = EINA_TRUE; if (h <= 0) return EINA_TRUE;
else if (pos == 0) open = EINA_FALSE;
else return EINA_FALSE;
}
break;
}
if (open) panel_size = h * sd->content_size_ratio;
{ elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
if (sd->hidden)
{
sd->hidden = EINA_FALSE;
efl_event_callback_legacy_call(obj, ELM_PANEL_EVENT_TOGGLED, NULL);
} }
elm_interface_scrollable_single_direction_set threshold = (sd->hidden) ? panel_size - (panel_size / 4) : (panel_size / 4);
(obj, ELM_SCROLLER_SINGLE_DIRECTION_HARD);
//focus & access if (reverse)
elm_object_tree_focus_allow_set(obj, EINA_TRUE);
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
{ {
ao = _access_object_get(obj, ACCESS_OUTLINE_PART); if (pos > panel_size - threshold) sd->hidden = EINA_FALSE;
evas_object_show(ao); else sd->hidden = EINA_TRUE;
_elm_access_highlight_set(ao);
}
else
elm_object_focus_set(obj, EINA_TRUE);
} }
else else
{ {
if (!sd->hidden) if (pos < threshold) sd->hidden = EINA_FALSE;
{ else sd->hidden = EINA_TRUE;
sd->hidden = EINA_TRUE;
efl_event_callback_legacy_call(obj, ELM_PANEL_EVENT_TOGGLED, NULL);
} }
if (horizontal) return EINA_FALSE;
elm_interface_scrollable_movement_block_set
(obj, ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
else
elm_interface_scrollable_movement_block_set
(obj, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL);
sd->freeze = EINA_TRUE;
elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
elm_interface_scrollable_single_direction_set
(obj, ELM_SCROLLER_SINGLE_DIRECTION_NONE);
//focus & access
elm_object_tree_focus_allow_set(obj, EINA_FALSE);
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
{
ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
evas_object_hide(ao);
}
}
return EINA_TRUE;
} }
static Eina_Bool static Eina_Bool
@ -811,116 +732,21 @@ _on_mouse_up(void *data,
{ {
Elm_Panel_Data *sd = data; Elm_Panel_Data *sd = data;
Evas_Event_Mouse_Up *ev = event_info; Evas_Event_Mouse_Up *ev = event_info;
Evas_Coord panel_size, threshold, pos, w, h; Evas_Coord w, h;
Eina_Bool hidden;
hidden = sd->hidden;
evas_object_geometry_get(obj, NULL, NULL, &w, &h); evas_object_geometry_get(obj, NULL, NULL, &w, &h);
ELM_SAFE_FREE(sd->timer, ecore_timer_del); ELM_SAFE_FREE(sd->timer, ecore_timer_del);
if (_state_sync(obj)) return; if (_state_sync(obj)) return;
switch (sd->orient) if (sd->hidden) _drawer_close(obj, w, h, EINA_TRUE);
{ else _drawer_open(obj, w, h, EINA_TRUE);
case ELM_PANEL_ORIENT_TOP:
panel_size = h * sd->content_size_ratio;
threshold = panel_size / 4;
elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
if (sd->hidden) if (sd->hidden != hidden)
{ efl_event_callback_legacy_call(obj, ELM_PANEL_EVENT_TOGGLED, NULL);
if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
else
{
if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
break;
case ELM_PANEL_ORIENT_BOTTOM:
panel_size = h * sd->content_size_ratio;
threshold = panel_size / 4;
elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
if (sd->hidden)
{
if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
else
{
if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
break;
case ELM_PANEL_ORIENT_LEFT:
panel_size = w * sd->content_size_ratio;
threshold = panel_size / 4;
elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
if (elm_widget_mirrored_get(obj))
{
if (sd->hidden)
{
if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
else
{
if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
}
else
{
if (sd->hidden)
{
if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
else
{
if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
}
break;
case ELM_PANEL_ORIENT_RIGHT:
panel_size = w * sd->content_size_ratio;
threshold = panel_size / 4;
elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
if (!elm_widget_mirrored_get(obj))
{
if (sd->hidden)
{
if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
else
{
if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
}
else
{
if (sd->hidden)
{
if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
else
{
if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
else _drawer_close(obj, w, h, EINA_TRUE);
}
}
break;
}
if (!sd->freeze && sd->hidden) if (!sd->freeze && sd->hidden)
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
@ -1312,8 +1138,86 @@ _elm_panel_elm_widget_on_focus_region(Eo *obj,
static void static void
_anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED) _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
{ {
ELM_PANEL_DATA_GET(obj, sd);
Evas_Object *ao;
Evas_Coord pos, w, h, panel_size = 0;
Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE, reverse = EINA_FALSE;
if (elm_widget_disabled_get(obj)) return; if (elm_widget_disabled_get(obj)) return;
_state_sync(obj);
switch (sd->orient)
{
case ELM_PANEL_ORIENT_BOTTOM:
reverse = EINA_TRUE;
case ELM_PANEL_ORIENT_TOP:
break;
case ELM_PANEL_ORIENT_RIGHT:
reverse = EINA_TRUE;
case ELM_PANEL_ORIENT_LEFT:
horizontal = EINA_TRUE;
break;
}
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
if (horizontal)
{
if (w <= 0) return;
panel_size = w * sd->content_size_ratio;
elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
reverse ^= elm_widget_mirrored_get(obj);
}
else
{
if (h <= 0) return;
panel_size = h * sd->content_size_ratio;
elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
}
if (pos == 0) open = !reverse;
else if (pos == panel_size) open = reverse;
else return;
if (open)
{
elm_interface_scrollable_single_direction_set
(obj, ELM_SCROLLER_SINGLE_DIRECTION_HARD);
//focus & access
elm_object_tree_focus_allow_set(obj, EINA_TRUE);
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
{
ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
evas_object_show(ao);
_elm_access_highlight_set(ao);
}
else
elm_object_focus_set(obj, EINA_TRUE);
}
else
{
if (horizontal)
elm_interface_scrollable_movement_block_set
(obj, ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
else
elm_interface_scrollable_movement_block_set
(obj, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL);
sd->freeze = EINA_TRUE;
elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
elm_interface_scrollable_single_direction_set
(obj, ELM_SCROLLER_SINGLE_DIRECTION_NONE);
//focus & access
elm_object_tree_focus_allow_set(obj, EINA_FALSE);
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
{
ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
evas_object_hide(ao);
}
}
} }
static void static void