Hello, all.
This is a patch for extended mode box.
When we insert objects into the horizontal mode box, the width of the box
increases according to the sum of items' min size without any limitation. In
a special case, such as typing recipients in the iphone email application,
objects in the box needs to be aligned automatically within the box width.
When a box is resized, all items are positioned as much as acceptable and
the remained items are put into the next line(under the max height of the
first aligned objects). This will be repeated until all items are displayed.
The extended mode box is an added feature and it doesn't break normal box
behavior at all.
I think it's not easy to explain whole features in extended mode box, so I
attached the test application for elementary_test.
Please test 'Box Extended' in elementary_test first and review this source
code next.
If any issues are there or this doesn't meet any other requirement, please
let me know it.
Thanks.
P.S. One more thing, when I sent a patch for scroller I missed adding the
function declaration to the header file. So I included it in this patch.
Index: elm_box.c
===================================================================
--- elm_box.c (revision 55575)
+++ elm_box.c (working copy)
@@ -29,6 +29,7 @@ struct _Widget_Data
Evas_Object *box;
Eina_Bool horizontal:1;
Eina_Bool homogeneous:1;
+ Eina_Bool extended:1;
};
struct _Elm_Box_Transition
@@ -155,7 +156,7 @@ _layout(Evas_Object *o, Evas_Object_Box_Data *priv
{
Widget_Data *wd = data;
if (!wd) return;
- _els_box_layout(o, priv, wd->horizontal, wd->homogeneous);
+ _els_box_layout_ex(o, priv, wd->horizontal, wd->homogeneous, wd->extended);
}
static Eina_Bool
@@ -892,3 +893,44 @@ elm_box_align_get(const Evas_Object *obj, double *
if (!wd) return;
evas_object_box_align_get(wd->box, horizontal, vertical);
}
+
+/**
+ * Set extended mode
+ *
+ * If enabled, box aligns all items within the box size(width). When the total
min size of the items is greater than the box size, box aligns items to the
next line like line wrapping in multiline text.
+ *
+ * @param obj The box object
+ * @param extended The extended mode flag (1 = on, 0 = off)
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_extended_mode_set(Evas_Object *obj, Eina_Bool extended)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->extended = !!extended;
+ if (extended)
+ wd->horizontal = 1; /* Do NOT support vertical extended mode */
+ evas_object_smart_calculate(wd->box);
+}
+
+/**
+ * Get the extended mode
+ *
+ * @param obj The box object
+ * @return If is extended mode
+ *
+ * @ingroup Box
+ */
+EAPI Eina_Bool
+elm_box_extended_mode_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return EINA_FALSE;
+ return wd->extended;
+}
+
+
Index: els_box.c
===================================================================
--- els_box.c (revision 55575)
+++ els_box.c (working copy)
@@ -2,15 +2,20 @@
#include "elm_priv.h"
static void
-_smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int
horizontal, int homogeneous)
+_smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int
horizontal, int homogeneous, int extended)
{
- Evas_Coord minw, minh, mnw, mnh;
+ Evas_Coord minw, minh, maxw, maxh, mnw, mnh, ww;
+ Evas_Coord w, cw = 0, cmaxh = 0;
const Eina_List *l;
Evas_Object_Box_Option *opt;
+ double wx;
/* FIXME: need to calc max */
minw = 0;
minh = 0;
+ maxw = -1;
+ maxh = -1;
+
if (homogeneous)
{
EINA_LIST_FOREACH(priv->children, l, opt)
@@ -26,27 +31,118 @@ static void
}
else
{
- EINA_LIST_FOREACH(priv->children, l, opt)
- {
- evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
- if (horizontal)
- {
- if (minh < mnh) minh = mnh;
- minw += mnw;
- }
- else
- {
- if (minw < mnw) minw = mnw;
- minh += mnh;
- }
- }
+ if (horizontal && extended)
+ {
+ evas_object_geometry_get(box, NULL, NULL, &w, NULL);
+ evas_object_size_hint_min_get(box, &minw, NULL);
+ }
+
+ EINA_LIST_FOREACH(priv->children, l, opt)
+ {
+ evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
+
+ if (horizontal)
+ {
+ if (extended)
+ {
+ evas_object_size_hint_weight_get(opt->obj, &wx, NULL);
+
+ if(wx)
+ {
+ if (mnw != -1 && (w - cw) >= mnw)
+ ww = w - cw;
+ else
+ ww = w;
+ }
+ else
+ ww = mnw;
+
+ if ((cw + mnw) > w)
+ {
+ minh += cmaxh;
+
+ cw = 0;
+ cmaxh = 0;
+ }
+ cw += ww;
+ if (cmaxh < mnh) cmaxh = mnh;
+ }
+ else
+ {
+ if (minh < mnh) minh = mnh;
+ minw += mnw;
+ }
+ }
+ else
+ {
+ if (minw < mnw) minw = mnw;
+ minh += mnh;
+ }
+ }
+
+ if(horizontal && extended)
+ {
+ minh += cmaxh;
+ }
+
}
evas_object_size_hint_min_set(box, minw, minh);
}
+static Evas_Coord
+_smart_extents_calculate_max_height(Evas_Object *box, Evas_Object_Box_Data
*priv, int obj_index)
+{
+ Evas_Coord mnw, mnh, cw = 0, cmaxh = 0, w, ww;
+ const Eina_List *l;
+ Evas_Object_Box_Option *opt;
+ int index = 0;
+ double wx;
+
+ evas_object_geometry_get(box, NULL, NULL, &w, NULL);
+
+ EINA_LIST_FOREACH(priv->children, l, opt)
+ {
+ evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
+ evas_object_size_hint_weight_get(opt->obj, &wx, NULL);
+
+ if(wx)
+ {
+ if (mnw != -1 && (w - cw) >= mnw)
+ ww = w - cw;
+ else
+ ww = w;
+ }
+ else
+ ww = mnw;
+
+ if ((cw + ww) > w)
+ {
+ if (index > obj_index )
+ {
+ return cmaxh;
+ }
+ cw = 0;
+ cmaxh = 0;
+ }
+
+ cw += ww;
+ if (cmaxh < mnh) cmaxh = mnh;
+
+ index++;
+ }
+
+ return cmaxh;
+}
+
void
_els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal,
int homogeneous)
{
+ _els_box_layout_ex(o, priv, horizontal, homogeneous, 0);
+}
+
+void
+_els_box_layout_ex(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal,
int homogeneous, int extended)
+{
Evas_Coord x, y, w, h, xx, yy;
const Eina_List *l;
Evas_Object *obj;
@@ -55,7 +151,7 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Da
double ax, ay;
Evas_Object_Box_Option *opt;
- _smart_extents_calculate(o, priv, horizontal, homogeneous);
+ _smart_extents_calculate(o, priv, horizontal, homogeneous, extended);
evas_object_geometry_get(o, &x, &y, &w, &h);
@@ -86,7 +182,7 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Da
if (wy > 0.0) expand++;
}
}
- if (!expand)
+ if ((!expand) && (!extended))
{
evas_object_size_hint_align_get(o, &ax, &ay);
if (horizontal)
@@ -104,6 +200,9 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Da
hdif = h - minh;
xx = x;
yy = y;
+
+ Evas_Coord cw = 0, ch = 0, cmaxh = 0, obj_index = 0;
+
EINA_LIST_FOREACH(priv->children, l, opt)
{
Evas_Coord mnw, mnh, mxw, mxh;
@@ -145,30 +244,70 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Da
}
else
{
- Evas_Coord ww, hh, ow, oh;
+ if (extended)
+ {
+ Evas_Coord ww, hh, ow, oh;
+ if(wx)
+ {
+ if (mnw != -1 && (w - cw) >= mnw)
+ ww = w - cw;
+ else
+ ww = w;
+ }
+ else
+ ww = mnw;
+ hh = _smart_extents_calculate_max_height(o, priv,
obj_index);
- ww = mnw;
- if ((expand > 0) && (xw))
- {
- if (expand == 1) ow = wdif;
- else ow = (w - minw) / expand;
- wdif -= ow;
- ww += ow;
- }
- hh = h;
- ow = mnw;
- if (fw) ow = ww;
- if ((mxw >= 0) && (mxw < ow)) ow = mxw;
- oh = mnh;
- if (fh) oh = hh;
- if ((mxh >= 0) && (mxh < oh)) oh = mxh;
- evas_object_move(obj,
- xx + (Evas_Coord)(((double)(ww - ow)) * ax),
- yy + (Evas_Coord)(((double)(hh - oh)) * ay));
- evas_object_resize(obj, ow, oh);
- xx += ww;
- }
- }
+ ow = mnw;
+ if (fw) ow = ww;
+ if ((mxw >= 0) && (mxw < ow)) ow = mxw;
+ oh = mnh;
+ if (fh) oh = hh;
+ if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+
+ if ((cw + ww) > w)
+ {
+ ch += cmaxh;
+
+ cw = 0;
+ cmaxh = 0;
+ }
+
+ evas_object_move(obj,
+ xx + cw + (Evas_Coord)(((double)(ww -
ow)) * ax),
+ yy + ch + (Evas_Coord)(((double)(hh -
oh)) * ay));
+ evas_object_resize(obj, ow, oh);
+
+ cw += ww;
+ if (cmaxh < hh) cmaxh = hh;
+ }
+ else
+ {
+ Evas_Coord ww, hh, ow, oh;
+
+ ww = mnw;
+ if ((expand > 0) && (xw))
+ {
+ if (expand == 1) ow = wdif;
+ else ow = (w - minw) / expand;
+ wdif -= ow;
+ ww += ow;
+ }
+ hh = h;
+ ow = mnw;
+ if (fw) ow = ww;
+ if ((mxw >= 0) && (mxw < ow)) ow = mxw;
+ oh = mnh;
+ if (fh) oh = hh;
+ if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+ evas_object_move(obj,
+ xx + (Evas_Coord)(((double)(ww - ow))
* ax),
+ yy + (Evas_Coord)(((double)(hh - oh))
* ay));
+ evas_object_resize(obj, ow, oh);
+ xx += ww;
+ }
+ }
+ }
else
{
if (homogeneous)
@@ -215,6 +354,8 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Da
yy += hh;
}
}
+
+ obj_index++;
}
}
Index: Elementary.h.in
===================================================================
--- Elementary.h.in (revision 55575)
+++ Elementary.h.in (working copy)
@@ -656,6 +656,8 @@ extern "C" {
EAPI Eina_Bool elm_box_horizontal_get(const Evas_Object *obj)
EINA_ARG_NONNULL(1);
EAPI void elm_box_homogenous_set(Evas_Object *obj, Eina_Bool
homogenous) EINA_ARG_NONNULL(1);
EAPI Eina_Bool elm_box_homogenous_get(const Evas_Object *obj)
EINA_ARG_NONNULL(1);
+ EAPI void elm_box_extended_mode_set(Evas_Object *obj,
Eina_Bool extended) EINA_ARG_NONNULL(1);
+ EAPI Eina_Bool elm_box_extended_mode_get(const Evas_Object *obj)
EINA_ARG_NONNULL(1);
EAPI void elm_box_pack_start(Evas_Object *obj, Evas_Object
*subobj) EINA_ARG_NONNULL(1);
EAPI void elm_box_pack_end(Evas_Object *obj, Evas_Object
*subobj) EINA_ARG_NONNULL(1);
EAPI void elm_box_pack_before(Evas_Object *obj, Evas_Object
*subobj, Evas_Object *before) EINA_ARG_NONNULL(1);
@@ -781,6 +783,8 @@ extern "C" {
EAPI void elm_scroller_page_relative_set(Evas_Object *obj, double
h_pagerel, double v_pagerel) EINA_ARG_NONNULL(1);
EAPI void elm_scroller_page_size_set(Evas_Object *obj, Evas_Coord
h_pagesize, Evas_Coord v_pagesize) EINA_ARG_NONNULL(1);
EAPI void elm_scroller_region_bring_in(Evas_Object *obj, Evas_Coord
x, Evas_Coord y, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+ EAPI void elm_scroller_propagate_events_set(Evas_Object *obj,
Eina_Bool set) EINA_ARG_NONNULL(1);
+
/* smart callbacks called:
* "edge,left"
* "edge,right"
Index: test.c
===================================================================
--- test.c (revision 55575)
+++ test.c (working copy)
@@ -13,6 +13,7 @@ void test_box_vert(void *data, Evas_Object *obj, v
void test_box_vert2(void *data, Evas_Object *obj, void *event_info);
void test_box_horiz(void *data, Evas_Object *obj, void *event_info);
void test_box_transition(void *data, Evas_Object *obj, void *event_info);
+void test_box_ex(void *data, Evas_Object *obj, void *event_info);
void test_button(void *data, Evas_Object *obj, void *event_info);
void test_transit(void *data, Evas_Object *obj, void *event_info);
void test_transit2(void *data, Evas_Object *obj, void *event_info);
@@ -248,6 +249,7 @@ my_win_main(char *autorun)
ADD_TEST("Box Vert 2", test_box_vert2);
ADD_TEST("Box Horiz", test_box_horiz);
ADD_TEST("Box Transition", test_box_transition);
+ ADD_TEST("Box Extended", test_box_ex);
ADD_TEST("Buttons", test_button);
ADD_TEST("Transit", test_transit);
ADD_TEST("Transit 2", test_transit2);
Index: test_box.c
===================================================================
--- test_box.c (revision 55575)
+++ test_box.c (working copy)
@@ -122,6 +122,138 @@ test_box_vert2(void *data __UNUSED__, Evas_Object
}
void
+test_box_ex(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void
*event_info __UNUSED__)
+{
+ Evas_Object *win, *bg, *bx, *lb, *bt;
+ char buf[PATH_MAX];
+
+ win = elm_win_add(NULL, "extended box", ELM_WIN_BASIC);
+ elm_win_title_set(win, "Extended Box");
+ elm_win_autodel_set(win, 1);
+ evas_object_resize(win, 300, 500);
+
+ bg = elm_bg_add(win);
+ elm_win_resize_object_add(win, bg);
+ evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(bg);
+
+ bx = elm_box_add(win);
+ elm_box_horizontal_set(bx, 1);
+ elm_box_extended_mode_set(bx, 1);
+ elm_win_resize_object_add(win, bx);
+ evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(bx);
+
+ lb = elm_label_add(win);
+ elm_label_label_set(lb, "Please resize the window and check the layout!");
+ evas_object_size_hint_min_set(lb, 100, 50);
+ evas_object_size_hint_weight_set(lb, 1, 1);
+ evas_object_size_hint_align_set(lb, 0.5, 0.5);
+ elm_box_pack_end(bx, lb);
+ evas_object_show(lb);
+
+ lb = elm_label_add(win);
+ elm_label_label_set(lb, "-- no weight test --");
+ evas_object_size_hint_min_set(lb, 100, 30);
+ evas_object_size_hint_weight_set(lb, 1, 0);
+ evas_object_size_hint_align_set(lb, 0, 0.5);
+ elm_box_pack_end(bx, lb);
+ evas_object_show(lb);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "w(100) h(50)");
+ evas_object_size_hint_min_set(bt, 100, 50);
+ evas_object_size_hint_align_set(bt, 0.5, 0.5);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "w(110) h(30)");
+ evas_object_size_hint_min_set(bt, 110, 30);
+ evas_object_size_hint_align_set(bt, 0.5, 0.5);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "w(90) h(40)");
+ evas_object_size_hint_min_set(bt, 90, 40);
+ evas_object_size_hint_align_set(bt, 0.5, 0.5);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "w(120) h(100)");
+ evas_object_size_hint_min_set(bt, 120, 100);
+ evas_object_size_hint_align_set(bt, 0.5, 0.5);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "w(80) h(50)");
+ evas_object_size_hint_min_set(bt, 80, 50);
+ evas_object_size_hint_align_set(bt, 0.5, 0.5);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ lb = elm_label_add(win);
+ elm_label_label_set(lb, "");
+ evas_object_size_hint_min_set(lb, 0, 0);
+ evas_object_size_hint_weight_set(lb, 1, 0);
+ evas_object_size_hint_align_set(lb, 0, 0.5);
+ elm_box_pack_end(bx, lb);
+ evas_object_show(lb);
+
+ lb = elm_label_add(win);
+ elm_label_label_set(lb, "-- weight and align test --");
+ evas_object_size_hint_min_set(lb, 200, 50);
+ evas_object_size_hint_weight_set(lb, 1, 0);
+ evas_object_size_hint_align_set(lb, 0, 1);
+ elm_box_pack_end(bx, lb);
+ evas_object_show(lb);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "w(90) h(90)");
+ evas_object_size_hint_min_set(bt, 90, 90);
+ evas_object_size_hint_align_set(bt, 0.5, 0.5);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "vertically filled");
+ evas_object_size_hint_min_set(bt, 100, 40);
+ evas_object_size_hint_weight_set(bt, 0, 1);
+ evas_object_size_hint_align_set(bt, 0.5, -1);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "bottom aligned");
+ evas_object_size_hint_min_set(bt, 100, 40);
+ evas_object_size_hint_weight_set(bt, 0, 1);
+ evas_object_size_hint_align_set(bt, 0.5, 1);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "top aligned");
+ evas_object_size_hint_min_set(bt, 100, 40);
+ evas_object_size_hint_weight_set(bt, 0, 1);
+ evas_object_size_hint_align_set(bt, 0.5, 0);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
+ elm_button_label_set(bt, "horizontally filled");
+ evas_object_size_hint_min_set(bt, 100, 40);
+ evas_object_size_hint_weight_set(bt, 1, 0);
+ evas_object_size_hint_align_set(bt, -1, 0.5);
+ elm_box_pack_end(bx, bt);
+ evas_object_show(bt);
+
+ evas_object_show(win);
+}
+
+void
test_box_horiz(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void
*event_info __UNUSED__)
{
Evas_Object *win, *bg, *bx, *ic;
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel