summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiep Ha <thiepha@gmail.com>2017-08-11 10:55:45 +0900
committerThiep Ha <thiepha@gmail.com>2017-08-11 10:55:45 +0900
commit635af90cb6c8ba55fad0f4e1aaa6223db9b341f5 (patch)
tree36a2180f0477a3fbdbe242db5a3b999bd9633976
parent746e0f62c48510885ce8b9fd52337542a26d478d (diff)
downloadefl-635af90cb6c8ba55fad0f4e1aaa6223db9b341f5.tar.gz
Aspect support
Try to support AS by calculating items having AS before items without it. However, we should calculate all items together: - calculate available slot for each item based on weight - calculate size for AS items based on AS restriction - for other items, calculate based on fill also - calculate align after having available slot and final size
-rw-r--r--src/bin/elementary/test_ui_box.c21
-rw-r--r--src/examples/elementary/box_example_02.c2
-rw-r--r--src/lib/elementary/efl_ui_box_layout.c292
3 files changed, 258 insertions, 57 deletions
diff --git a/src/bin/elementary/test_ui_box.c b/src/bin/elementary/test_ui_box.c
index 6f3ac05f09..6e14bd8ac3 100644
--- a/src/bin/elementary/test_ui_box.c
+++ b/src/bin/elementary/test_ui_box.c
@@ -18,6 +18,7 @@ typedef enum {
TWO
} Weight_Mode;
+/*
static void
weights_cb(void *data, const Efl_Event *event)
{
@@ -210,6 +211,7 @@ custom_check_cb(void *data, const Efl_Event *event)
// function was just overridden.
efl_pack_layout_request(box);
}
+*/
void
test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
@@ -231,7 +233,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
/* controls */
- f = elm_frame_add(win);
+ /*f = elm_frame_add(win);
elm_object_text_set(f, "Controls");
efl_gfx_size_hint_align_set(f, -1, -1);
efl_gfx_size_hint_weight_set(f, 1, 0);
@@ -244,7 +246,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
efl_gfx_visible_set(hbox, 1);
- /* weights radio group */
+ /* weights radio group *
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_orientation_set(efl_added, EFL_ORIENT_DOWN));
efl_gfx_size_hint_align_set(bx, 0, -1);
@@ -298,7 +300,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
elm_radio_value_set(chk, NONE);
- /* misc */
+ /* misc *
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_orientation_set(efl_added, EFL_ORIENT_DOWN));
efl_gfx_size_hint_align_set(bx, 0, -1);
@@ -353,7 +355,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
efl_gfx_visible_set(o, 1);
- /* user min size setter */
+ /* user min size setter *
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_orientation_set(efl_added, EFL_ORIENT_DOWN));
efl_gfx_size_hint_align_set(bx, 0, -1);
@@ -380,7 +382,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
efl_gfx_visible_set(o, 1);
- /* inner box padding */
+ /* inner box padding *
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_orientation_set(efl_added, EFL_ORIENT_DOWN));
efl_gfx_size_hint_align_set(bx, 0, -1);
@@ -407,7 +409,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
efl_gfx_visible_set(o, 1);
- /* outer margin */
+ /* outer margin *
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_orientation_set(efl_added, EFL_ORIENT_DOWN));
efl_gfx_size_hint_align_set(bx, 0, -1);
@@ -434,7 +436,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
efl_gfx_visible_set(o, 1);
- /* Box align */
+ /* Box align *
bx = efl_add(EFL_UI_BOX_CLASS, win,
efl_orientation_set(efl_added, EFL_ORIENT_DOWN));
efl_gfx_size_hint_align_set(bx, 0, -1);
@@ -472,7 +474,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
elm_slider_step_set(o, 0.1);
elm_slider_value_set(o, 0.5);
efl_pack(bx, o);
- efl_gfx_visible_set(o, 1);
+ efl_gfx_visible_set(o, 1);*/
/* contents */
@@ -493,13 +495,14 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
objects[i++] = o = elm_button_add(win);
elm_object_text_set(o, "Btn1");
+ efl_gfx_size_hint_weight_set(o, 1, 1);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
objects[i++] = o = elm_button_add(win);
elm_object_text_set(o, "Button 2");
efl_gfx_size_hint_align_set(o, -1, -1);
- efl_gfx_size_hint_aspect_set(o, EFL_GFX_SIZE_HINT_ASPECT_BOTH, 2, 1);
+ efl_gfx_size_hint_aspect_set(o, EFL_GFX_SIZE_HINT_ASPECT_BOTH, 3, 1);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
diff --git a/src/examples/elementary/box_example_02.c b/src/examples/elementary/box_example_02.c
index 5e086b6b6d..653b6c7993 100644
--- a/src/examples/elementary/box_example_02.c
+++ b/src/examples/elementary/box_example_02.c
@@ -151,7 +151,7 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
evas_object_box_layout_stack);
elm_box_layout_set(bx, evas_object_box_layout_horizontal, NULL, NULL);
- _test_box_transition_change(&tdata);
+ //_test_box_transition_change(&tdata);
evas_object_resize(win, 300, 320);
evas_object_show(win);
diff --git a/src/lib/elementary/efl_ui_box_layout.c b/src/lib/elementary/efl_ui_box_layout.c
index cdd1a50353..f861253207 100644
--- a/src/lib/elementary/efl_ui_box_layout.c
+++ b/src/lib/elementary/efl_ui_box_layout.c
@@ -21,6 +21,7 @@ struct _Item_Calc
int id;
};
+#define D(format, args...) WRN("item: %d (%s): " format, id, elm_object_text_get((items[id]).obj), ##args)
void
_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
{
@@ -41,6 +42,7 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
evas_object_geometry_get(ui_box, &boxx, &boxy, &boxw, &boxh);
efl_gfx_size_hint_margin_get(ui_box, &boxl, &boxr, &boxt, &boxb);
scale = evas_object_scale_get(ui_box);
+ WRN("box geo: %d %d %d %d ------------------------------", boxx, boxy, boxw, boxh);
// Box align: used if "item has max size and fill" or "no item has a weight"
// Note: cells always expand on the orthogonal direction
@@ -81,7 +83,8 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
efl_gfx_size_hint_max_get(o, &item->max[0], &item->max[1]);
efl_gfx_size_hint_combined_min_get(o, &item->want[0], &item->want[1]);
efl_gfx_size_hint_aspect_get(o, &item->aspect, &item->aw, &item->ah);
- efl_gfx_size_hint_min_get(0, &item->min[0], &item->min[1]);
+ efl_gfx_size_hint_min_get(o, &item->min[0], &item->min[1]);
+ D("weight: %1.f %.1f, align: %.1f %.1f, min: %d %d, max: %d %d, aspect: (%d) %d %d", item->weight[0], item->weight[1], item->align[0], item->align[1], item->min[0], item->min[1], item->max[0], item->max[1], item->aspect, item->aw, item->ah);
if (item->aw == 0 || item->ah == 0)
{
item->aw = item->ah = 0;
@@ -90,12 +93,74 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
//aspect ratio support
//lam sao de tinh chi tinh min + van support aspect ratio???
- //if (item->aspect == EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL ||
- // item->aspect == EFL_GFX_SIZE_HINT_ASPECT_BOTH)
+ if (item->aspect >= EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
{
- int minh = item->want[0] * item->ah / item->aw;
- if (item->want[1] < minh)
- item->want[1] = minh;
+ int w1, h1;
+ if (horiz)
+ {
+ if (item->min[0] > 0)
+ {
+ w1 = item->min[0];
+ h1 = w1 * item->ah / item->aw;
+ if (h1 < item->min[1])
+ {
+ h1 = item->min[1];
+ w1 = h1 * item->aw / item->ah;
+ }
+ D("min: %d %d, w h: %d %d", item->min[0], item->min[1], w1, h1);
+ }
+ else if (item->min[1] > 0)
+ {
+ h1 = item->min[1];
+ w1 = h1 * item->aw / item->ah;
+ if (w1 < item->min[0])
+ {
+ w1 = item->min[0];
+ h1 = w1 * item->ah / item->aw;
+ }
+ D("min: %d %d, w h: %d %d", item->min[0], item->min[1], w1, h1);
+ }
+ else
+ {
+ //no min: keep combined min + aspect
+ if (item->aw < item->ah)
+ {
+ w1 = item->want[0];
+ h1 = w1 * item->ah / item->aw;
+ D("want: %d %d, w h: %d %d", item->want[0], item->want[1], w1, h1);
+ }
+ else
+ {
+ h1 = item->want[1];
+ w1 = h1 * item->aw / item->ah;
+ D("want: %d %d, w h: %d %d", item->want[0], item->want[1], w1, h1);
+ }
+ }
+ if (w1 > 0 || h1 > 0)
+ {
+ item->want[0] = w1;
+ item->want[1] = h1;
+ }
+ }
+ else
+ {
+ //FIXME: add more handling as horiz case
+ w1 = item->min[0];
+ h1 = w1 * item->ah / item->aw;
+ if (h1 < item->min[1])
+ {
+ h1 = item->min[1];
+ w1 = h1 * item->aw / item->ah;
+ }
+ if (w1 > 0 || h1 > 0)
+ {
+ item->want[0] = w1;
+ item->want[1] = h1;
+ }
+ }
+ //int minh = item->want[0] * item->ah / item->aw;
+ //if (item->want[1] < minh)
+ // item->want[1] = minh;
}
if (item->weight[0] < 0) item->weight[0] = 0;
@@ -132,6 +197,7 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
wantw = item->want[0];
}
+ D("want: %d %d :: %d %d", item->want[0], item->want[1], wantw, wanth);
item->id = id++;
}
@@ -229,33 +295,86 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
wanth + pad * (count - 1) + boxt + boxb);
}*/
+ WRN("total weight: %.1f %.1f, extra: %.1f", weight[0], weight[1], extra);
if (extra < 0) extra = 0;
- if (EINA_DBL_EQ(weight[!horiz], 0))
- {
- if (box_fill[!horiz])
- {
- // box is filled, set all weights to be equal
- zeroweight = EINA_TRUE;
- }
- else
- {
- // move bounding box according to box align
- cur_pos = extra * box_align[!horiz];
- }
- weight[!horiz] = count;
- }
-
double cx, cy, cw, ch, x, y, w, h;
//work on items having aspect ratio first
for (id = 0; id < count; id++)
{
item = &items[id];
- if (item->aspect)
+ if (item->aspect >= EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
{
if (horiz)
{
- ch = boxh;
+ //consider aspect, min, max, fill
+ int old_w = item->want[0];
+ int w1 = item->want[0];
+ int h1 = item->want[1];
+ if (weight[0] > 0)
+ w1 = item->want[0] + extra * item->weight[0] / weight[0];
+ h1 = w1 * item->ah / item->aw;
+ D("w h: %d %d, want: %d %d, extra: %d, weight: %.1f / %.1f", w1, h1, item->want[0], item->want[1], extra, item->weight[0], weight[0]);
+ if (h1 < item->want[1])
+ {
+ h1 = item->want[1];
+ w1 = h1 * item->aw / item->ah;
+ D("w h: %d %d", w1, h1);
+ }
+ if (item->aspect == EFL_GFX_SIZE_HINT_ASPECT_BOTH ||
+ item->aspect == EFL_GFX_SIZE_HINT_ASPECT_VERTICAL)
+ {
+ if (h1 > boxh)
+ {
+ h1 = boxh;
+ w1 = h1 * item->aw / item->ah;
+ }
+ }
+
+ //aspect and fill: aspect does not respect fill
+ /*if (item->align[1] < 0) //should check in first place
+ {
+ h1 = boxh;
+ w1 = h1 * item->aw / item->ah;
+ D("w, h: %d %d", w1, h1);
+ }*/
+
+ //aspect and max
+ double mar = 0.0;
+ if ((item->max[0] != INT_MAX) && (item->max[1] != INT_MAX))
+ {
+ mar = item->max[0] / (double)item->max[1];
+ D("mar: %.2f, max: %d %d", mar, item->max[0], item->max[1]);
+ if (item->ah > 0)
+ {
+ double ar = item->aw / (double)item->ah;
+ D("ar: %.2f, mar: %.2f", ar, mar);
+ if (ar < mar)
+ {
+ if (h1 > item->max[1])
+ {
+ h1 = item->max[1];
+ w1 = h1 * item->aw / item->ah;
+ }
+ D("w, h: %d %d", w1, h1);
+ }
+ else
+ {
+ if (w1 > item->max[0])
+ {
+ w1 = item->max[0];
+ h1 = w1 * item->ah / item->aw;
+ }
+ D("w, h: %d %d", w1, h1);
+ }
+ }
+ }
+ item->want[0] = w1;
+ item->want[1] = h1;
+ extra -= item->want[0] - old_w;
+ weight[0] -= item->weight[0];
+ D("horiz: w, h: %d %d, extra: %d", w1, h1, extra);
+ /*ch = boxh;
if (ch > item->max[1])
ch = item->max[1];
cw = ch * item->aw / item->ah;
@@ -263,11 +382,31 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
{
cw = item->max[0];
ch = cw * item->ah / item->aw;
- }
+ }*/
}
else
{
- cw = boxw;
+ int w1, h1;
+ int old_h = item->want[1];
+
+ h1 = item->want[1] + extra * item->weight[1] / weight[1];
+ w1 = h1 * item->aw / item->ah;
+
+ if (item->aspect == EFL_GFX_SIZE_HINT_ASPECT_BOTH ||
+ item->aspect == EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
+ {
+ if (w1 > boxw)
+ {
+ w1 = boxw;
+ h1 = w1 * item->ah / item->aw;
+ }
+ }
+ D("vertical: w,h: %d %d", w1, h1);
+ item->want[0] = w1;
+ item->want[1] = h1;
+ extra -= item->want[1] - old_h;
+ weight[1] -= item->weight[1];
+ /*cw = boxw;
if (cw > item->max[0])
cw = item->max[0];
ch = cw * item->ah / item->aw;
@@ -275,11 +414,26 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
{
ch = item->max[1];
cw = ch * item->aw / item->ah;
- }
+ }*/
}
}
}
+ if (EINA_DBL_EQ(weight[!horiz], 0))
+ {
+ if (box_fill[!horiz])
+ {
+ // box is filled, set all weights to be equal
+ zeroweight = EINA_TRUE;
+ }
+ else
+ {
+ // move bounding box according to box align
+ cur_pos = extra * box_align[!horiz];
+ }
+ weight[!horiz] = count;
+ }
+
for (id = 0; id < count; id++)
{
double cx, cy, cw, ch, x, y, w, h;
@@ -293,55 +447,88 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
{
cx = boxx + cur_pos;
cy = boxy;
- cw = item->want[0] + rounding + (zeroweight ? 1.0 : item->weight[0]) * extra / weight[0];
- ch = boxh;
+ //phan phoi extra cho cac items
+ if (item->aspect >= EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
+ {
+ cw = item->want[0];
+ ch = item->want[1];
+ }
+ else
+ {
+ cw = item->want[0] + rounding + (zeroweight ? 1.0 : item->weight[0]) * extra / weight[0];
+ ch = boxh;
+ }
cur_pos += cw + pad;
}
else
{
cx = boxx;
cy = boxy + cur_pos;
- cw = boxw;
- ch = item->want[1] + rounding + (zeroweight ? 1.0 : item->weight[1]) * extra / weight[1];
+ if (item->aspect >= EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
+ {
+ cw = item->want[0];
+ ch = item->want[1];
+ }
+ else
+ {
+ cw = boxw;
+ ch = item->want[1] + rounding + (zeroweight ? 1.0 : item->weight[1]) * extra / weight[1];
+ }
cur_pos += ch + pad;
}
// horizontally
if (item->max[0] < INT_MAX)
{
- w = MIN(MAX(item->want[0] - item->pad[0] - item->pad[1], item->max[0]), cw);
+ if (item->aspect < EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
+ w = MIN(MAX(item->want[0] - item->pad[0] - item->pad[1], item->max[0]), cw);
+ else
+ w = item->want[0];
if (item->align[0] < 0)
{
// bad case: fill+max are not good together
x = cx + ((cw - w) * box_align[0]) + item->pad[0];
}
else
- x = cx + ((cw - w) * item->align[0]) + item->pad[0];
+ {
+ x = cx + ((cw - w) * item->align[0]) + item->pad[0];
+ D("x: %.1f, cx: %.1f", x, cx);
+ }
}
else if (item->align[0] < 0)
{
// fill x
- w = cw - item->pad[0] - item->pad[1];
+ if (item->aspect < EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
+ w = cw - item->pad[0] - item->pad[1];
+ else
+ w = item->want[0];
x = cx + item->pad[0];
+ D("x: %.1f, cx: %.1f", x, cx);
}
else
{
- w = item->want[0] - item->pad[0] - item->pad[1];
+ //lam sao support align + weight???
+ //w = item->want[0] - item->pad[0] - item->pad[1];
+ w = cw - item->pad[0] - item->pad[1];
x = cx + ((cw - w) * item->align[0]) + item->pad[0];
+ D("x: %.1f, cx: %.1f", x, cx);
}
//aspect ratio
- if (item->aspect)
+ /*if (item->aspect)
{
- h = w * item->ah / item->aw;
- if (h > wanth)
- wanth = h;
- }
+ h = w * item->ah / item->aw;
+ if (h > wanth)
+ wanth = h;
+ }*/
/////
// vertically
if (item->max[1] < INT_MAX)
{
- h = MIN(MAX(item->want[1] - item->pad[2] - item->pad[3], item->max[1]), ch);
+ if (item->aspect < EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
+ h = MIN(MAX(item->want[1] - item->pad[2] - item->pad[3], item->max[1]), ch);
+ else
+ h = item->want[1];
if (item->align[1] < 0)
{
// bad case: fill+max are not good together
@@ -353,7 +540,10 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
else if (item->align[1] < 0)
{
// fill y
- h = ch - item->pad[2] - item->pad[3];
+ if (item->aspect < EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL)
+ h = ch - item->pad[2] - item->pad[3];
+ else
+ h = item->want[1];
y = cy + item->pad[2];
}
else
@@ -361,29 +551,37 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
h = item->want[1] - item->pad[2] - item->pad[3];
y = cy + ((ch - h) * item->align[1]) + item->pad[2];
}
- if (item->aspect)
+ /*if (item->aspect)
{
- w = h * item->aw / item->ah;
- cur_pos = cur_pos - cw + w;
- if (w > wantw)
- wantw = w;
- }
+ w = h * item->aw / item->ah;
+ cur_pos = cur_pos - cw + w;
+ //if (w > wantw)
+ // wantw = w;
+ wantw += w;
+ }*/
//DBG("[%2d/%2d] cell: %.0f,%.0f %.0fx%.0f item: %.0f,%.0f %.0fx%.0f",
// id, count, cx, cy, cw, ch, x, y, w, h);
+ D("geo: %.0f %.0f %.0f %.0f", x, y, w, h);
evas_object_geometry_set(item->obj, x, y, w, h);
}
+ int hh, hw;
if (horiz)
{
evas_object_size_hint_min_set(ui_box,
wantw + boxl + boxr + pad * (count - 1),
wanth + boxt + boxb);
+ hw = wantw + boxl + boxr + pad * (count - 1);
+ hh = wanth + boxt + boxb;
}
else
{
evas_object_size_hint_min_set(ui_box,
wantw + boxl + boxr,
wanth + pad * (count - 1) + boxt + boxb);
+ hw = wantw + boxl + boxr;
+ hh = wanth + pad * (count - 1) + boxt + boxb;
}
+ WRN("box min: %d %d", hw, hh);
}