summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYeongjong Lee <yj34.lee@samsung.com>2019-05-29 17:24:21 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2019-05-29 17:24:21 +0900
commite3a791c4b176b7c396b1f4c56cd7a1ad54f1b745 (patch)
tree6cc45b067dc45dc404204ff50acbcf2177e4131f
parent8721caf787ce1a9abb6198f41bfc1a033d4f799a (diff)
efl_ui_relative_layout: allow to respect the min size of its child
Summary: It will have the same policy as the Efl.Ui.Box, Table. Test Plan: elementary_test -to 'efl.ui.relative_layout' Reviewers: Jaehyun_Cho, herb Reviewed By: Jaehyun_Cho Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9029
-rw-r--r--src/lib/elementary/efl_ui_relative_layout.c78
-rw-r--r--src/lib/elementary/efl_ui_relative_layout_private.h28
2 files changed, 100 insertions, 6 deletions
diff --git a/src/lib/elementary/efl_ui_relative_layout.c b/src/lib/elementary/efl_ui_relative_layout.c
index 530179cab4..a0814cebad 100644
--- a/src/lib/elementary/efl_ui_relative_layout.c
+++ b/src/lib/elementary/efl_ui_relative_layout.c
@@ -177,6 +177,11 @@ _child_aspect_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
177 calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1]; 177 calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1];
178 } 178 }
179 //calculate min size 179 //calculate min size
180 if (calc->aspect[1] > calc->aspect[0])
181 calc->min[1] = calc->min[0] * calc->aspect[1] / calc->aspect[0];
182 else
183 calc->min[0] = calc->min[1] * calc->aspect[0] / calc->aspect[1];
184
180 if (calc->want[0].length < calc->min[0]) 185 if (calc->want[0].length < calc->min[0])
181 { 186 {
182 calc->want[0].length = calc->min[0]; 187 calc->want[0].length = calc->min[0];
@@ -298,8 +303,17 @@ _child_chain_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
298 cur_pos += o->calc.space[axis].length; 303 cur_pos += o->calc.space[axis].length;
299 o->calc.space[axis].length -= o->calc.margin[START] + o->calc.margin[END]; 304 o->calc.space[axis].length -= o->calc.margin[START] + o->calc.margin[END];
300 o->calc.chain_state[axis] = RELATIVE_CALC_DONE; 305 o->calc.chain_state[axis] = RELATIVE_CALC_DONE;
306 child->calc.m0[axis] += o->calc.min[axis];
301 } 307 }
302 308
309 child->calc.mi[axis] = head->rel[START].relative * (head->calc.to[START]->calc.mj[axis] -
310 head->calc.to[START]->calc.mi[axis]) + head->calc.to[START]->calc.mi[axis];
311 child->calc.mj[axis] = tail->rel[END].relative * (tail->calc.to[END]->calc.mj[axis] -
312 tail->calc.to[END]->calc.mi[axis]) + tail->calc.to[END]->calc.mi[axis];
313 child->calc.m0[axis] += -child->calc.min[axis] +
314 (head->calc.to[START]->calc.m0[axis] * head->rel[START].relative) +
315 (tail->calc.to[END]->calc.m0[axis] * (1 - tail->rel[END].relative));
316
303 return EINA_TRUE; 317 return EINA_TRUE;
304} 318}
305 319
@@ -355,6 +369,32 @@ _child_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
355 (calc->space[axis].length - calc->want[axis].length) * calc->align[axis]; 369 (calc->space[axis].length - calc->want[axis].length) * calc->align[axis];
356 370
357 child->calc.state[axis] = RELATIVE_CALC_DONE; 371 child->calc.state[axis] = RELATIVE_CALC_DONE;
372 if (child->calc.chain_state[axis] == RELATIVE_CALC_DONE)
373 return;
374
375 //calculate relative layout min
376 calc->mi[axis] = child->rel[START].relative * (calc->to[START]->calc.mj[axis] -
377 calc->to[START]->calc.mi[axis]) + calc->to[START]->calc.mi[axis];
378 calc->mj[axis] = child->rel[END].relative * (calc->to[END]->calc.mj[axis] -
379 calc->to[END]->calc.mi[axis]) + calc->to[END]->calc.mi[axis];
380 calc->m0[axis] = calc->to[START]->calc.m0[axis] * child->rel[START].relative;
381
382 if ((calc->to[START] == calc->to[END]) &&
383 EINA_DBL_EQ(child->rel[START].relative, child->rel[END].relative))
384 {
385 double r, a; // relative, align
386 r = calc->mi[axis] +
387 (child->rel[START].relative * (calc->mj[axis] - calc->mi[axis]));
388 a = calc->align[axis];
389 calc->m0[axis] += (calc->min[axis] + calc->margin[START] + calc->margin[END]) *
390 ((EINA_DBL_EQ(r, 0.0) || (!EINA_DBL_EQ(r, 1.0) && (a < r))) ?
391 ((1 - a) / (1 - r)) : (a / r));
392 }
393 else
394 {
395 calc->m0[axis] += calc->to[END]->calc.m0[axis] * (1 - child->rel[END].relative);
396 }
397
358} 398}
359 399
360static void 400static void
@@ -386,18 +426,36 @@ _hash_clear_cb(void *data)
386 426
387static Eina_Bool 427static Eina_Bool
388_hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, 428_hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
389 void *data, void *fdata EINA_UNUSED) 429 void *data, void *fdata)
390{ 430{
391 Efl_Ui_Relative_Layout_Child *child = data; 431 Efl_Ui_Relative_Layout_Child *child = data;
432 Efl_Ui_Relative_Layout_Calc *calc = &(child->calc);
433 Efl_Ui_Relative_Layout_Data *pd = fdata;
392 Eina_Rect want; 434 Eina_Rect want;
435 int axis, layout_min;
436 double min_len;
393 437
394 _child_calc(child, 0); 438 _child_calc(child, 0);
395 _child_calc(child, 1); 439 _child_calc(child, 1);
396 440
397 want.x = child->calc.want[0].position; 441 want.x = calc->want[0].position;
398 want.w = child->calc.want[0].length; 442 want.w = calc->want[0].length;
399 want.y = child->calc.want[1].position; 443 want.y = calc->want[1].position;
400 want.h = child->calc.want[1].length; 444 want.h = calc->want[1].length;
445
446 for (axis = 0; axis < 2; axis++)
447 {
448 layout_min = 0;
449 min_len = calc->mj[axis] - calc->mi[axis];
450 if (EINA_DBL_EQ(min_len, 0.0))
451 layout_min = calc->m0[axis];
452 else
453 layout_min = ((calc->min[axis] + calc->margin[START] +
454 calc->margin[END] + calc->m0[axis]) / fabs(min_len)) + 0.5;
455
456 if (pd->base->calc.min[axis] < layout_min)
457 pd->base->calc.min[axis] = layout_min;
458 }
401 459
402 efl_gfx_entity_geometry_set(child->obj, want); 460 efl_gfx_entity_geometry_set(child->obj, want);
403 return EINA_TRUE; 461 return EINA_TRUE;
@@ -437,6 +495,8 @@ _hash_child_init_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key E
437 calc->max[1] = max.h; 495 calc->max[1] = max.h;
438 calc->min[0] = min.w; 496 calc->min[0] = min.w;
439 calc->min[1] = min.h; 497 calc->min[1] = min.h;
498 calc->m0[0] = 0.0;
499 calc->m0[1] = 0.0;
440 500
441 calc->want[0].position = 0; 501 calc->want[0].position = 0;
442 calc->want[0].length = 0; 502 calc->want[0].length = 0;
@@ -477,9 +537,13 @@ _efl_ui_relative_layout_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Relative_L
477 pd->base->calc.want[0].length = want.w; 537 pd->base->calc.want[0].length = want.w;
478 pd->base->calc.want[1].position = want.y; 538 pd->base->calc.want[1].position = want.y;
479 pd->base->calc.want[1].length = want.h; 539 pd->base->calc.want[1].length = want.h;
540 pd->base->calc.min[0] = 0;
541 pd->base->calc.min[1] = 0;
480 542
481 eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, pd); 543 eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, pd);
482 eina_hash_foreach(pd->children, _hash_child_calc_foreach_cb, NULL); 544 eina_hash_foreach(pd->children, _hash_child_calc_foreach_cb, pd);
545
546 efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(pd->base->calc.min[0], pd->base->calc.min[1]));
483 547
484 efl_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL); 548 efl_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
485} 549}
@@ -550,6 +614,8 @@ _efl_ui_relative_layout_efl_object_constructor(Eo *obj, Efl_Ui_Relative_Layout_D
550 pd->base->rel[TOP].relative = 0.0; 614 pd->base->rel[TOP].relative = 0.0;
551 pd->base->rel[BOTTOM].to = obj; 615 pd->base->rel[BOTTOM].to = obj;
552 pd->base->rel[BOTTOM].relative = 1.0; 616 pd->base->rel[BOTTOM].relative = 1.0;
617 pd->base->calc.mi[0] = pd->base->calc.mi[1] = 0.0;
618 pd->base->calc.mj[0] = pd->base->calc.mj[1] = 1.0;
553 pd->base->calc.state[0] = RELATIVE_CALC_DONE; 619 pd->base->calc.state[0] = RELATIVE_CALC_DONE;
554 pd->base->calc.state[1] = RELATIVE_CALC_DONE; 620 pd->base->calc.state[1] = RELATIVE_CALC_DONE;
555 pd->base->calc.chain_state[0] = RELATIVE_CALC_DONE; 621 pd->base->calc.chain_state[0] = RELATIVE_CALC_DONE;
diff --git a/src/lib/elementary/efl_ui_relative_layout_private.h b/src/lib/elementary/efl_ui_relative_layout_private.h
index 2aa150a333..79a22bed1d 100644
--- a/src/lib/elementary/efl_ui_relative_layout_private.h
+++ b/src/lib/elementary/efl_ui_relative_layout_private.h
@@ -36,6 +36,34 @@ struct _Efl_Ui_Relative_Layout_Calc
36 double weight[2]; 36 double weight[2];
37 double align[2]; 37 double align[2];
38 double comp_factor; 38 double comp_factor;
39 /* m0 is static min size which is added to the other children min size.
40 * only if both (target, relative)[0] and (target, relative)[1] are same,
41 * it has non-zero value. it is calculated as (min * (align / relative)) if
42 * align is greater than relative, (min * ((1 - align) / (1 - relative))) otherwise.
43 * mi, mj are transformed relative based on layout min size. they are
44 * calculated as (target.mi + (relative * (target.mj - target.mi))). for example,
45 * there are two children of relative_layout that has different target base.
46 * | | obj1 | obj2 |
47 * | min | 100 | 100 |
48 * |left.target | layout| obj1 |
49 * |left.relative | 0.0 | 0.5 |
50 * |right.target | layout| obj1 |
51 * |right.relative| 0.5 | 1.0 |
52 * | mi | 0.0 | 0.25 |
53 * | mj | 0.5 | 0.5 |
54 *
55 * obj1.mi = layout.mi(0.0) + (obj1.relative(0.0) * (layout.mj(1.0) - layout.mi(0.0))) = 0.0
56 * obj1.mj = layout.mi(0.0) + (obj1.relative(0.5) * (layout.mj(1.0) - layout.mi(0.0))) = 0.5
57 * obj2.mi = obj1.mi(0.0) + (obj2.relative(0.5) * (obj1.mj(0.5) - obj1.mi(0.0))) = 0.25
58 * obj2.mj = obj1.mi(0.0) + (obj2.relative(1.0) * (obj1.mj(0.5) - obj1.mi(0.0))) = 0.5
59 * layout min size is calculated as maximum of (child_min + m0) / (mj - mi).
60 * in the example, obj1 require layout min size as
61 * ((child_min(100) + m0(0)) / (mj(0.5) - mi(0.0))) = 200. obj2 require
62 * layout min size as ((100 + 0) / (0.5 - 0.25)) = 400. as a result, layout
63 * min size is max(200, 400) = 400.
64 */
65 double m0[2];
66 double mi[2], mj[2];
39 67
40 struct { 68 struct {
41 int position; 69 int position;