elm_panel: set hidden property when panel is close/open
authorSungtaek Hong <sth253.hong@samsung.com>
Thu, 8 Jun 2017 07:00:20 +0000 (16:00 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Thu, 8 Jun 2017 07:15:35 +0000 (16:15 +0900)
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>
src/bin/elementary/test_panel.c
src/lib/elementary/elm_panel.c

index 9c8d4eb..41bffed 100644 (file)
@@ -281,6 +281,27 @@ _clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUS
 }
 
 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
 _changed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
    elm_config_scroll_thumbscroll_enabled_set(elm_check_state_get(obj));
@@ -322,6 +343,11 @@ test_panel2(void *data EINA_UNUSED,
 
    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
    button = elm_button_add(box);
    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_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);
 }
index c79b460..b48df12 100644 (file)
@@ -219,7 +219,6 @@ EOLIAN static Elm_Theme_Apply
 _elm_panel_elm_widget_theme_apply(Eo *obj, Elm_Panel_Data *sd)
 {
    const char *str;
-   int w, h;
    Evas_Coord minw = 0, minh = 0;
 
    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_style_get(obj));
         _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");
         if (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)
 {
    ELM_PANEL_DATA_GET(obj, sd);
-   Evas_Object *ao;
-   Evas_Coord pos, panel_size, w, h;
-   Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE;
+   Evas_Coord pos, panel_size, w, h, threshold;
+   Eina_Bool horizontal = EINA_FALSE, reverse = EINA_FALSE;
+
    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
 
    if (!evas_object_visible_get(sd->bx)) return EINA_TRUE;
 
    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:
-         if (h <= 0) return EINA_TRUE;
-
-         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;
+         reverse = EINA_TRUE;
+      case ELM_PANEL_ORIENT_TOP:
          break;
 
+      case ELM_PANEL_ORIENT_RIGHT:
+         reverse = EINA_TRUE;
       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;
+     }
 
-      case ELM_PANEL_ORIENT_RIGHT:
+   if (horizontal)
+     {
          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;
+         reverse ^= elm_widget_mirrored_get(obj);
+     }
+   else
+     {
+         if (h <= 0) return 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;
+         panel_size = h * sd->content_size_ratio;
+         elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
      }
+   threshold = (sd->hidden) ? panel_size - (panel_size / 4) : (panel_size / 4);
 
-   if (open)
+   if (reverse)
      {
-        if (sd->hidden)
-          {
-             sd->hidden = EINA_FALSE;
-             efl_event_callback_legacy_call(obj, ELM_PANEL_EVENT_TOGGLED, NULL);
-          }
-        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);
+         if (pos > panel_size - threshold) sd->hidden = EINA_FALSE;
+         else sd->hidden = EINA_TRUE;
      }
    else
      {
-        if (!sd->hidden)
-          {
-             sd->hidden = EINA_TRUE;
-             efl_event_callback_legacy_call(obj, ELM_PANEL_EVENT_TOGGLED, NULL);
-          }
-
-        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);
-          }
+         if (pos < threshold) sd->hidden = EINA_FALSE;
+         else sd->hidden = EINA_TRUE;
      }
 
-   return EINA_TRUE;
+   return EINA_FALSE;
 }
 
 static Eina_Bool
@@ -811,116 +732,21 @@ _on_mouse_up(void *data,
 {
    Elm_Panel_Data *sd = data;
    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);
 
    ELM_SAFE_FREE(sd->timer, ecore_timer_del);
 
    if (_state_sync(obj)) return;
 
-   switch (sd->orient)
-     {
-      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) _drawer_close(obj, w, h, EINA_TRUE);
+   else _drawer_open(obj, w, h, EINA_TRUE);
 
-         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_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->hidden != hidden)
+     efl_event_callback_legacy_call(obj, ELM_PANEL_EVENT_TOGGLED, NULL);
 
    if (!sd->freeze && sd->hidden)
      ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
@@ -1312,8 +1138,86 @@ _elm_panel_elm_widget_on_focus_region(Eo *obj,
 static void
 _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;
-   _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