elm: Add an Edje layout for elm_win
authorHenrique Dante de Almeida <hdante@profusion.mobi>
Thu, 17 Jan 2013 22:11:15 +0000 (22:11 +0000)
committerBruno Dilly <bdilly@profusion.mobi>
Thu, 17 Jan 2013 22:11:15 +0000 (22:11 +0000)
The layout has two parts, one for placing a menu bar on the window and
the other for placing the actual window contents. The content part is
an Evas box with a custom layout that mimics the standard widget
placement rules inside the window (adapted from resize_objects_eval
and resize_job)

Note: a custom layout was written here, because it's not possible to
use a common stacking layout, since applications do not follow the
stacking rules (they don't use EVAS_HINT_FILL and
evas_object_size_hint_align_set). Maybe, with time, applications
could be changed to use them, so the custom layout may be removed.

Patch by: Henrique Dante de Almeida <hdante@profusion.mobi>

SVN revision: 82957

legacy/elementary/data/themes/widgets/win.edc
legacy/elementary/src/lib/elm_win.c

index bcdf78b..24c02ab 100644 (file)
@@ -244,3 +244,52 @@ group { name: "elm/win/inwin/minimal_vertical";
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+
+group { name: "elm/win/base/default";
+   parts {
+      part { type: RECT; name: "dbg";
+         description { state: "default" 0.0;
+            color: 242 242 242 255;
+            align: 0.5 0;
+         }
+      }
+
+      part { type: SWALLOW; name: "elm.swallow.menu";
+         description { state: "default" 0.0;
+            rel2.relative: 1.0 0.0;
+            visible: 0;
+            align: 0.5 0;
+            fixed: 1 1;
+         }
+
+         description { state: "visible" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+            fixed: 0 1;
+         }
+      }
+
+      part { type: SWALLOW; name: "elm.swallow.contents";
+         description { state: "default" 0.0;
+            rel1 {
+               to_y: "elm.swallow.menu";
+               relative: 0.0 1.0;
+            }
+         }
+      }
+   }
+   programs {
+      program { name: "show_menu";
+         signal: "elm,action,show_menu";
+         source: "elm";
+         action: STATE_SET "visible" 0.0;
+         target: "elm.swallow.menu";
+      }
+      program { name: "hide_menu";
+         signal: "elm,action,hide";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.swallow.menu";
+      }
+   }
+}
index 0da040e..bcb33d9 100644 (file)
@@ -57,6 +57,8 @@ struct _Elm_Win_Smart_Data
    Evas                 *evas;
    Evas_Object          *parent; /* parent *window* object*/
    Evas_Object          *img_obj, *frame_obj;
+   Eo                   *layout;
+   Eo                   *box;
    Evas_Coord           fx, fy, fw, fh;
    Eina_List            *resize_objs; /* a window may have
                                        * *multiple* resize
@@ -209,6 +211,12 @@ static Eina_Bool _elm_win_auto_throttled = EINA_FALSE;
 static Ecore_Job *_elm_win_state_eval_job = NULL;
 
 static void
+_elm_win_on_resize_obj_changed_size_hints(void *data,
+                                          Evas *e,
+                                          Evas_Object *obj,
+                                          void *event_info);
+
+static void
 _elm_win_state_eval(void *data __UNUSED__)
 {
    Eina_List *l;
@@ -1414,6 +1422,13 @@ _elm_win_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
 {
    Elm_Win_Smart_Data *sd = _pd;
 
+   evas_object_event_callback_del_full(sd->layout,
+                                      EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                      _elm_win_on_resize_obj_changed_size_hints,
+                                      obj);
+   evas_object_del(sd->box);
+   evas_object_del(sd->layout);
+
    /* NB: child deletion handled by parent's smart del */
 
    if ((trap) && (trap->del))
@@ -2504,6 +2519,48 @@ _elm_win_cb_show(void *data __UNUSED__,
 }
 
 static void
+_window_layout_stack(Evas_Object *o, Evas_Object_Box_Data *p, void *data)
+{
+   const Eina_List *l;
+   Evas_Object *child;
+   Evas_Object_Box_Option *opt;
+   Evas_Coord x, y, w, h;
+   double wx, wy;
+   Evas_Coord minw = -1, minh = -1;
+   double weight_x = EVAS_HINT_EXPAND;
+   double weight_y = EVAS_HINT_EXPAND;
+
+   EINA_LIST_FOREACH(p->children, l, opt)
+     {
+        child = opt->obj;
+        evas_object_size_hint_weight_get(child, &wx, &wy);
+        if (wx == 0.0) weight_x = 0;
+        if (wy == 0.0) weight_y = 0;
+
+        evas_object_size_hint_min_get(child, &w, &h);
+        if (w > minw) minw = w;
+        if (h > minh) minh = h;
+     }
+
+   evas_object_size_hint_min_set(o, minw, minh);
+   evas_object_geometry_get(o, &x, &y, &w, &h);
+   if (w < minw) w = minw;
+   if (h < minh) h = minh;
+   evas_object_resize(o, w, h);
+
+   EINA_LIST_FOREACH(p->children, l, opt)
+     {
+        child = opt->obj;
+        evas_object_move(child, x, y);
+        evas_object_resize(child, w, h);
+     }
+
+   ELM_WIN_DATA_GET(data, sd);
+   evas_object_size_hint_weight_set(sd->layout, weight_x, weight_y);
+   evas_object_smart_changed(sd->layout);
+}
+
+static void
 _win_constructor(Eo *obj, void *_pd, va_list *list)
 {
    Elm_Win_Smart_Data *sd = _pd;
@@ -2942,6 +2999,18 @@ _win_constructor(Eo *obj, void *_pd, va_list *list)
      {
         // do nothing
      }
+
+   sd->layout = edje_object_add(sd->evas);
+   _elm_theme_object_set(obj, sd->layout, "win", "base", "default");
+   sd->box = evas_object_box_add(sd->evas);
+   evas_object_box_layout_set(sd->box, _window_layout_stack, obj, NULL);
+   edje_object_part_swallow(sd->layout, "elm.swallow.contents", sd->box);
+   evas_object_move(sd->layout, 0, 0);
+   evas_object_resize(sd->layout, 1, 1);
+   edje_object_update_hints_set(sd->layout, EINA_TRUE);
+   evas_object_event_callback_add(sd->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _elm_win_on_resize_obj_changed_size_hints, obj);
+   evas_object_show(sd->layout);
 }
 
 static void