diff options
author | Thiep Ha <thiepha@gmail.com> | 2017-08-11 10:55:45 +0900 |
---|---|---|
committer | Thiep Ha <thiepha@gmail.com> | 2017-08-11 10:55:45 +0900 |
commit | 635af90cb6c8ba55fad0f4e1aaa6223db9b341f5 (patch) | |
tree | 36a2180f0477a3fbdbe242db5a3b999bd9633976 | |
parent | 746e0f62c48510885ce8b9fd52337542a26d478d (diff) | |
download | efl-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.c | 21 | ||||
-rw-r--r-- | src/examples/elementary/box_example_02.c | 2 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_box_layout.c | 292 |
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); } |