efl_ui_popup_alert_scroll: Add expandable property
authorJaehyun Cho <jae_hyun.cho@samsung.com>
Mon, 11 Dec 2017 04:55:02 +0000 (13:55 +0900)
committerJaehyun Cho <jae_hyun.cho@samsung.com>
Mon, 11 Dec 2017 05:00:21 +0000 (14:00 +0900)
Summary:
The expandable property allows popup to expand its size up to the given
maximum size.
So by setting expandable property, popup expands its scrollable content
size from the minimum size of the content to the given maximum size.

Reviewers: jpeg

Subscribers: cedric, thiepha, woohyun, Blackmole, herb

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

src/lib/elementary/efl_ui_popup_alert_scroll.c
src/lib/elementary/efl_ui_popup_alert_scroll.eo
src/lib/elementary/efl_ui_popup_alert_scroll_private.h

index 7a5dd0b..64025d6 100644 (file)
 
 static const char PART_NAME_SCROLLER[] = "scroller";
 
-EOLIAN static void
-_efl_ui_popup_alert_scroll_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Popup_Alert_Scroll_Data *pd EINA_UNUSED)
+static void
+_scroller_sizing_eval(Eo *obj, Efl_Ui_Popup_Alert_Scroll_Data *pd,
+                      Eina_Size2D exp_scr_min, Eina_Size2D min)
 {
-   elm_layout_sizing_eval(efl_super(obj, MY_CLASS));
+   Eina_Size2D max_size;
+   max_size.w = -1;
+   max_size.h = -1;
+
+   if (pd->max_size.w != -1)
+     max_size.w = (exp_scr_min.w > pd->max_size.w) ? exp_scr_min.w : pd->max_size.w;
+   if (pd->max_size.h != -1)
+     max_size.h = (exp_scr_min.h > pd->max_size.h) ? exp_scr_min.h : pd->max_size.h;
+
+   Eina_Size2D size;
+   size.w = (exp_scr_min.w > pd->size.w) ? exp_scr_min.w : pd->size.w;
+   size.h = (exp_scr_min.h > pd->size.h) ? exp_scr_min.h : pd->size.h;
+
+   Eina_Size2D new_min = exp_scr_min;
+
+   if ((max_size.w == -1) && (max_size.h == -1))
+     {
+        elm_scroller_content_min_limit(pd->scroller, EINA_FALSE, EINA_FALSE);
+        efl_gfx_size_set(obj, size);
+     }
+   else if ((max_size.w == -1) && (max_size.h != -1))
+     {
+        if (max_size.h < min.h)
+          {
+             elm_scroller_content_min_limit(pd->scroller, EINA_FALSE, EINA_FALSE);
+             efl_gfx_size_set(obj, EINA_SIZE2D(size.w, max_size.h));
+          }
+        else
+          {
+             new_min.h = min.h;
+             elm_scroller_content_min_limit(pd->scroller, EINA_FALSE, EINA_TRUE);
+             efl_gfx_size_set(obj, EINA_SIZE2D(size.w, min.h));
+          }
+     }
+   else if ((max_size.w != -1) && (max_size.h == -1))
+     {
+        if (max_size.w < min.w)
+          {
+             elm_scroller_content_min_limit(pd->scroller, EINA_FALSE, EINA_FALSE);
+             efl_gfx_size_set(obj, EINA_SIZE2D(max_size.w, size.h));
+          }
+        else
+          {
+             new_min.w = min.w;
+             elm_scroller_content_min_limit(pd->scroller, EINA_TRUE, EINA_FALSE);
+             efl_gfx_size_set(obj, EINA_SIZE2D(min.w, size.h));
+          }
+     }
+   else if ((max_size.w != -1) && (max_size.h != -1))
+     {
+        Eina_Size2D new_size;
+        Eina_Bool min_limit_w = EINA_FALSE;
+        Eina_Bool min_limit_h = EINA_FALSE;
+
+        if (max_size.w < min.w)
+          {
+             new_size.w = max_size.w;
+          }
+        else
+          {
+             min_limit_w = EINA_TRUE;
+             new_min.w = min.w;
+             new_size.w = min.w;
+          }
+
+        if (max_size.h < min.h)
+          {
+             new_size.h = max_size.h;
+          }
+        else
+          {
+             min_limit_h = EINA_TRUE;
+             new_min.h = min.h;
+             new_size.h = min.h;
+          }
+
+        elm_scroller_content_min_limit(pd->scroller, min_limit_w, min_limit_h);
+        efl_gfx_size_set(obj, new_size);
+     }
+
+   efl_gfx_size_hint_min_set(obj, new_min);
+}
 
+static void
+_sizing_eval(Eo *obj, Efl_Ui_Popup_Alert_Scroll_Data *pd)
+{
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-   Evas_Coord minw = -1, minh = -1;
+   Evas_Coord obj_minw = -1, obj_minh = -1;
+   Evas_Coord scr_minw = -1, scr_minh = -1;
+
+   //Calculate popup's min size including scroller's min size
+     {
+        elm_scroller_content_min_limit(pd->scroller, EINA_TRUE, EINA_TRUE);
+
+        elm_coords_finger_size_adjust(1, &scr_minw, 1, &scr_minh);
+        edje_object_size_min_restricted_calc
+           (wd->resize_obj, &scr_minw, &scr_minh, scr_minw, scr_minh);
+     }
+
+   //Calculate popup's min size except scroller's min size
+     {
+        elm_scroller_content_min_limit(pd->scroller, EINA_FALSE, EINA_FALSE);
+
+        elm_coords_finger_size_adjust(1, &obj_minw, 1, &obj_minh);
+        edje_object_size_min_restricted_calc
+           (wd->resize_obj, &obj_minw, &obj_minh, obj_minw, obj_minh);
+     }
+
+   _scroller_sizing_eval(obj, pd, EINA_SIZE2D(obj_minw, obj_minh), EINA_SIZE2D(scr_minw, scr_minh));
+}
+
+EOLIAN static void
+_efl_ui_popup_alert_scroll_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Popup_Alert_Scroll_Data *pd)
+{
+   if (pd->needs_size_calc) return;
+   pd->needs_size_calc = EINA_TRUE;
+
+   evas_object_smart_changed(obj);
+}
+
+EOLIAN static void
+_efl_ui_popup_alert_scroll_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Popup_Alert_Scroll_Data *pd)
+{
+   /* When elm_layout_sizing_eval() is called, just flag is set instead of size
+    * calculation.
+    * The actual size calculation is done here when the object is rendered to
+    * avoid duplicate size calculations. */
+   if (pd->needs_size_calc)
+     {
+        _sizing_eval(obj, pd);
 
-   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
-   edje_object_size_min_restricted_calc
-      (wd->resize_obj, &minw, &minh, minw, minh);
-   efl_gfx_size_hint_min_set(obj, EINA_SIZE2D(minw, minh));
+        pd->needs_size_calc = EINA_FALSE;
+     }
 }
 
 static Eina_Bool
@@ -91,6 +216,48 @@ _efl_ui_popup_alert_scroll_text_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Alert_Scro
    return efl_text_get(efl_part(efl_super(obj, MY_CLASS), part));
 }
 
+static void
+_efl_ui_popup_alert_scroll_expandable_set(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Alert_Scroll_Data *pd, Eina_Size2D max_size)
+{
+   Eina_Bool valid_max_w = EINA_FALSE;
+   Eina_Bool valid_max_h = EINA_FALSE;
+
+   if ((max_size.w == -1) || (max_size.w >= 0))
+     valid_max_w = EINA_TRUE;
+
+   if ((max_size.h == -1) || (max_size.h >= 0))
+     valid_max_h = EINA_TRUE;
+
+   if (!valid_max_w || !valid_max_h)
+     {
+        ERR("Invalid max size(%d, %d)!"
+            "The max size should be equal to or bigger than 0. "
+            "To disable expandable property, set -1 to the max size.",
+            max_size.w, max_size.h);
+        return;
+     }
+
+   pd->max_size = max_size;
+
+   elm_layout_sizing_eval(obj);
+}
+
+static Eina_Size2D
+_efl_ui_popup_alert_scroll_expandable_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Alert_Scroll_Data *pd)
+{
+   return pd->max_size;
+}
+
+EOLIAN static void
+_efl_ui_popup_alert_scroll_efl_ui_popup_popup_size_set(Eo *obj, Efl_Ui_Popup_Alert_Scroll_Data *pd, Eina_Size2D size)
+{
+   pd->size = size;
+
+   efl_gfx_size_set(obj, size);
+
+   elm_layout_sizing_eval(obj);
+}
+
 EOLIAN static Eo *
 _efl_ui_popup_alert_scroll_efl_object_constructor(Eo *obj,
                                                   Efl_Ui_Popup_Alert_Scroll_Data *pd)
@@ -114,6 +281,10 @@ _efl_ui_popup_alert_scroll_efl_object_constructor(Eo *obj,
    efl_content_set(efl_part(efl_super(obj, MY_CLASS), "elm.swallow.content"),
                    pd->scroller);
 
+   pd->size = EINA_SIZE2D(0, 0);
+   pd->max_size = EINA_SIZE2D(-1, -1);
+   pd->needs_size_calc = EINA_FALSE;
+
    return obj;
 }
 
index af80115..8dd6e7d 100644 (file)
@@ -1,8 +1,33 @@
+import eina_types;
+
 class Efl.Ui.Popup_Alert_Scroll(Efl.Ui.Popup_Alert)
 {
    [[EFL UI Popup Alert Scroll class]]
+   methods {
+       @property expandable @beta {
+           set {
+             [[Set the expandable max size of popup.
+
+               If the given max_size is -1, then popup appears with its size.
+               However, if the given max_size is bigger than 0, then popup size is upto the given max_size. If popup content's min size is bigger than the given max_size, then scroller appears in the popup content area.
+             ]]
+           }
+           get {
+             [[Get the expandable max size of popup.
+
+               If the given max_size is -1, then popup appears with its size.
+               However, if the given max_size is bigger than 0, then popup size is upto the given max_size. If popup content's min size is bigger than the given max_size, then scroller appears in the popup content area.
+             ]]
+           }
+           values {
+              max_size: Eina.Size2D; [[A 2D max size in pixel units.]]
+           }
+       }
+   }
    implements {
       Efl.Object.constructor;
+      Efl.Canvas.Group.group_calculate;
       Efl.Part.part;
+      Efl.Ui.Popup.popup_size { set;}
    }
 }
index c1219b9..68b5ef0 100644 (file)
@@ -1,13 +1,18 @@
 #ifndef EFL_UI_POPUP_ALERT_SCROLL_H
 #define EFL_UI_POPUP_ALERT_SCROLL_H
 
+#define EFL_UI_POPUP_ALERT_SCROLL_BETA
+
 #include "Elementary.h"
 
 typedef struct _Efl_Ui_Popup_Alert_Scroll_Data Efl_Ui_Popup_Alert_Scroll_Data;
 struct _Efl_Ui_Popup_Alert_Scroll_Data
 {
-   Eo *scroller;
-   Eo *content;
+   Eo         *scroller;
+   Eo         *content;
+   Eina_Size2D size;
+   Eina_Size2D max_size;
+   Eina_Bool   needs_size_calc : 1;
 };
 
 #endif