forked from enlightenment/efl
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
This commit is contained in:
parent
8721caf787
commit
e3a791c4b1
|
@ -177,6 +177,11 @@ _child_aspect_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
|
||||||
calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1];
|
calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1];
|
||||||
}
|
}
|
||||||
//calculate min size
|
//calculate min size
|
||||||
|
if (calc->aspect[1] > calc->aspect[0])
|
||||||
|
calc->min[1] = calc->min[0] * calc->aspect[1] / calc->aspect[0];
|
||||||
|
else
|
||||||
|
calc->min[0] = calc->min[1] * calc->aspect[0] / calc->aspect[1];
|
||||||
|
|
||||||
if (calc->want[0].length < calc->min[0])
|
if (calc->want[0].length < calc->min[0])
|
||||||
{
|
{
|
||||||
calc->want[0].length = calc->min[0];
|
calc->want[0].length = calc->min[0];
|
||||||
|
@ -298,8 +303,17 @@ _child_chain_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
|
||||||
cur_pos += o->calc.space[axis].length;
|
cur_pos += o->calc.space[axis].length;
|
||||||
o->calc.space[axis].length -= o->calc.margin[START] + o->calc.margin[END];
|
o->calc.space[axis].length -= o->calc.margin[START] + o->calc.margin[END];
|
||||||
o->calc.chain_state[axis] = RELATIVE_CALC_DONE;
|
o->calc.chain_state[axis] = RELATIVE_CALC_DONE;
|
||||||
|
child->calc.m0[axis] += o->calc.min[axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
child->calc.mi[axis] = head->rel[START].relative * (head->calc.to[START]->calc.mj[axis] -
|
||||||
|
head->calc.to[START]->calc.mi[axis]) + head->calc.to[START]->calc.mi[axis];
|
||||||
|
child->calc.mj[axis] = tail->rel[END].relative * (tail->calc.to[END]->calc.mj[axis] -
|
||||||
|
tail->calc.to[END]->calc.mi[axis]) + tail->calc.to[END]->calc.mi[axis];
|
||||||
|
child->calc.m0[axis] += -child->calc.min[axis] +
|
||||||
|
(head->calc.to[START]->calc.m0[axis] * head->rel[START].relative) +
|
||||||
|
(tail->calc.to[END]->calc.m0[axis] * (1 - tail->rel[END].relative));
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,6 +369,32 @@ _child_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis)
|
||||||
(calc->space[axis].length - calc->want[axis].length) * calc->align[axis];
|
(calc->space[axis].length - calc->want[axis].length) * calc->align[axis];
|
||||||
|
|
||||||
child->calc.state[axis] = RELATIVE_CALC_DONE;
|
child->calc.state[axis] = RELATIVE_CALC_DONE;
|
||||||
|
if (child->calc.chain_state[axis] == RELATIVE_CALC_DONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//calculate relative layout min
|
||||||
|
calc->mi[axis] = child->rel[START].relative * (calc->to[START]->calc.mj[axis] -
|
||||||
|
calc->to[START]->calc.mi[axis]) + calc->to[START]->calc.mi[axis];
|
||||||
|
calc->mj[axis] = child->rel[END].relative * (calc->to[END]->calc.mj[axis] -
|
||||||
|
calc->to[END]->calc.mi[axis]) + calc->to[END]->calc.mi[axis];
|
||||||
|
calc->m0[axis] = calc->to[START]->calc.m0[axis] * child->rel[START].relative;
|
||||||
|
|
||||||
|
if ((calc->to[START] == calc->to[END]) &&
|
||||||
|
EINA_DBL_EQ(child->rel[START].relative, child->rel[END].relative))
|
||||||
|
{
|
||||||
|
double r, a; // relative, align
|
||||||
|
r = calc->mi[axis] +
|
||||||
|
(child->rel[START].relative * (calc->mj[axis] - calc->mi[axis]));
|
||||||
|
a = calc->align[axis];
|
||||||
|
calc->m0[axis] += (calc->min[axis] + calc->margin[START] + calc->margin[END]) *
|
||||||
|
((EINA_DBL_EQ(r, 0.0) || (!EINA_DBL_EQ(r, 1.0) && (a < r))) ?
|
||||||
|
((1 - a) / (1 - r)) : (a / r));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
calc->m0[axis] += calc->to[END]->calc.m0[axis] * (1 - child->rel[END].relative);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -386,18 +426,36 @@ _hash_clear_cb(void *data)
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
|
_hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
|
||||||
void *data, void *fdata EINA_UNUSED)
|
void *data, void *fdata)
|
||||||
{
|
{
|
||||||
Efl_Ui_Relative_Layout_Child *child = data;
|
Efl_Ui_Relative_Layout_Child *child = data;
|
||||||
|
Efl_Ui_Relative_Layout_Calc *calc = &(child->calc);
|
||||||
|
Efl_Ui_Relative_Layout_Data *pd = fdata;
|
||||||
Eina_Rect want;
|
Eina_Rect want;
|
||||||
|
int axis, layout_min;
|
||||||
|
double min_len;
|
||||||
|
|
||||||
_child_calc(child, 0);
|
_child_calc(child, 0);
|
||||||
_child_calc(child, 1);
|
_child_calc(child, 1);
|
||||||
|
|
||||||
want.x = child->calc.want[0].position;
|
want.x = calc->want[0].position;
|
||||||
want.w = child->calc.want[0].length;
|
want.w = calc->want[0].length;
|
||||||
want.y = child->calc.want[1].position;
|
want.y = calc->want[1].position;
|
||||||
want.h = child->calc.want[1].length;
|
want.h = calc->want[1].length;
|
||||||
|
|
||||||
|
for (axis = 0; axis < 2; axis++)
|
||||||
|
{
|
||||||
|
layout_min = 0;
|
||||||
|
min_len = calc->mj[axis] - calc->mi[axis];
|
||||||
|
if (EINA_DBL_EQ(min_len, 0.0))
|
||||||
|
layout_min = calc->m0[axis];
|
||||||
|
else
|
||||||
|
layout_min = ((calc->min[axis] + calc->margin[START] +
|
||||||
|
calc->margin[END] + calc->m0[axis]) / fabs(min_len)) + 0.5;
|
||||||
|
|
||||||
|
if (pd->base->calc.min[axis] < layout_min)
|
||||||
|
pd->base->calc.min[axis] = layout_min;
|
||||||
|
}
|
||||||
|
|
||||||
efl_gfx_entity_geometry_set(child->obj, want);
|
efl_gfx_entity_geometry_set(child->obj, want);
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -437,6 +495,8 @@ _hash_child_init_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key E
|
||||||
calc->max[1] = max.h;
|
calc->max[1] = max.h;
|
||||||
calc->min[0] = min.w;
|
calc->min[0] = min.w;
|
||||||
calc->min[1] = min.h;
|
calc->min[1] = min.h;
|
||||||
|
calc->m0[0] = 0.0;
|
||||||
|
calc->m0[1] = 0.0;
|
||||||
|
|
||||||
calc->want[0].position = 0;
|
calc->want[0].position = 0;
|
||||||
calc->want[0].length = 0;
|
calc->want[0].length = 0;
|
||||||
|
@ -477,9 +537,13 @@ _efl_ui_relative_layout_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Relative_L
|
||||||
pd->base->calc.want[0].length = want.w;
|
pd->base->calc.want[0].length = want.w;
|
||||||
pd->base->calc.want[1].position = want.y;
|
pd->base->calc.want[1].position = want.y;
|
||||||
pd->base->calc.want[1].length = want.h;
|
pd->base->calc.want[1].length = want.h;
|
||||||
|
pd->base->calc.min[0] = 0;
|
||||||
|
pd->base->calc.min[1] = 0;
|
||||||
|
|
||||||
eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, pd);
|
eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, pd);
|
||||||
eina_hash_foreach(pd->children, _hash_child_calc_foreach_cb, NULL);
|
eina_hash_foreach(pd->children, _hash_child_calc_foreach_cb, pd);
|
||||||
|
|
||||||
|
efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(pd->base->calc.min[0], pd->base->calc.min[1]));
|
||||||
|
|
||||||
efl_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
|
efl_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
|
||||||
}
|
}
|
||||||
|
@ -550,6 +614,8 @@ _efl_ui_relative_layout_efl_object_constructor(Eo *obj, Efl_Ui_Relative_Layout_D
|
||||||
pd->base->rel[TOP].relative = 0.0;
|
pd->base->rel[TOP].relative = 0.0;
|
||||||
pd->base->rel[BOTTOM].to = obj;
|
pd->base->rel[BOTTOM].to = obj;
|
||||||
pd->base->rel[BOTTOM].relative = 1.0;
|
pd->base->rel[BOTTOM].relative = 1.0;
|
||||||
|
pd->base->calc.mi[0] = pd->base->calc.mi[1] = 0.0;
|
||||||
|
pd->base->calc.mj[0] = pd->base->calc.mj[1] = 1.0;
|
||||||
pd->base->calc.state[0] = RELATIVE_CALC_DONE;
|
pd->base->calc.state[0] = RELATIVE_CALC_DONE;
|
||||||
pd->base->calc.state[1] = RELATIVE_CALC_DONE;
|
pd->base->calc.state[1] = RELATIVE_CALC_DONE;
|
||||||
pd->base->calc.chain_state[0] = RELATIVE_CALC_DONE;
|
pd->base->calc.chain_state[0] = RELATIVE_CALC_DONE;
|
||||||
|
|
|
@ -36,6 +36,34 @@ struct _Efl_Ui_Relative_Layout_Calc
|
||||||
double weight[2];
|
double weight[2];
|
||||||
double align[2];
|
double align[2];
|
||||||
double comp_factor;
|
double comp_factor;
|
||||||
|
/* m0 is static min size which is added to the other children min size.
|
||||||
|
* only if both (target, relative)[0] and (target, relative)[1] are same,
|
||||||
|
* it has non-zero value. it is calculated as (min * (align / relative)) if
|
||||||
|
* align is greater than relative, (min * ((1 - align) / (1 - relative))) otherwise.
|
||||||
|
* mi, mj are transformed relative based on layout min size. they are
|
||||||
|
* calculated as (target.mi + (relative * (target.mj - target.mi))). for example,
|
||||||
|
* there are two children of relative_layout that has different target base.
|
||||||
|
* | | obj1 | obj2 |
|
||||||
|
* | min | 100 | 100 |
|
||||||
|
* |left.target | layout| obj1 |
|
||||||
|
* |left.relative | 0.0 | 0.5 |
|
||||||
|
* |right.target | layout| obj1 |
|
||||||
|
* |right.relative| 0.5 | 1.0 |
|
||||||
|
* | mi | 0.0 | 0.25 |
|
||||||
|
* | mj | 0.5 | 0.5 |
|
||||||
|
*
|
||||||
|
* obj1.mi = layout.mi(0.0) + (obj1.relative(0.0) * (layout.mj(1.0) - layout.mi(0.0))) = 0.0
|
||||||
|
* obj1.mj = layout.mi(0.0) + (obj1.relative(0.5) * (layout.mj(1.0) - layout.mi(0.0))) = 0.5
|
||||||
|
* obj2.mi = obj1.mi(0.0) + (obj2.relative(0.5) * (obj1.mj(0.5) - obj1.mi(0.0))) = 0.25
|
||||||
|
* obj2.mj = obj1.mi(0.0) + (obj2.relative(1.0) * (obj1.mj(0.5) - obj1.mi(0.0))) = 0.5
|
||||||
|
* layout min size is calculated as maximum of (child_min + m0) / (mj - mi).
|
||||||
|
* in the example, obj1 require layout min size as
|
||||||
|
* ((child_min(100) + m0(0)) / (mj(0.5) - mi(0.0))) = 200. obj2 require
|
||||||
|
* layout min size as ((100 + 0) / (0.5 - 0.25)) = 400. as a result, layout
|
||||||
|
* min size is max(200, 400) = 400.
|
||||||
|
*/
|
||||||
|
double m0[2];
|
||||||
|
double mi[2], mj[2];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int position;
|
int position;
|
||||||
|
|
Loading…
Reference in New Issue