Efl.Ui.Box: Add pack_align property

While at first I wanted to remove the box_align / table_align
properties, it ends up being a necessary value in some cases.
This commit is contained in:
Jean-Philippe Andre 2016-04-15 17:06:14 +09:00
parent 101cb7fe2a
commit f2eff88640
6 changed files with 126 additions and 21 deletions

View File

@ -91,6 +91,26 @@ margin_slider_cb(void *data, const Eo_Event *event)
return EO_CALLBACK_CONTINUE;
}
static Eina_Bool
alignh_slider_cb(void *data, const Eo_Event *event)
{
double av, val;
val = elm_slider_value_get(event->obj);
efl_pack_align_get(data, NULL, &av);
efl_pack_align_set(data, val, av);
return EO_CALLBACK_CONTINUE;
}
static Eina_Bool
alignv_slider_cb(void *data, const Eo_Event *event)
{
double ah, val;
val = elm_slider_value_get(event->obj);
efl_pack_align_get(data, &ah, NULL);
efl_pack_align_set(data, ah, val);
return EO_CALLBACK_CONTINUE;
}
static Efl_Ui_Box_Flow_Params s_flow_params = { 0.5, 0.5, 0, 0 };
static Eina_Bool flow = EINA_FALSE;
@ -455,6 +475,46 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
efl_gfx_visible_set(o, 1);
/* Box align */
bx = eo_add(EFL_UI_BOX_CLASS, win,
efl_pack_direction_set(eo_self, EFL_ORIENT_DOWN));
evas_object_size_hint_align_set(bx, 0, -1);
evas_object_size_hint_weight_set(bx, 1, 1);
efl_pack(hbox, bx);
efl_gfx_visible_set(bx, 1);
o = elm_label_add(win);
elm_object_text_set(o, "Box align");
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
o = elm_slider_add(win);
elm_slider_indicator_format_set(o, "%.1f");
elm_slider_indicator_show_set(o, 1);
elm_slider_horizontal_set(o, 0);
evas_object_size_hint_align_set(o, 0.5, -1);
evas_object_size_hint_weight_set(o, 1, 1);
eo_event_callback_add(o, ELM_SLIDER_EVENT_CHANGED, alignv_slider_cb, bottombox);
elm_slider_min_max_set(o, -0.1, 1.0);
elm_slider_step_set(o, 0.1);
elm_slider_value_set(o, 0.5);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
o = elm_slider_add(win);
elm_slider_indicator_format_set(o, "%.1f");
elm_slider_indicator_show_set(o, 1);
elm_slider_horizontal_set(o, 1);
evas_object_size_hint_align_set(o, 0.5, -1);
evas_object_size_hint_weight_set(o, 1, 0);
eo_event_callback_add(o, ELM_SLIDER_EVENT_CHANGED, alignh_slider_cb, bottombox);
elm_slider_min_max_set(o, -0.1, 1.0);
elm_slider_step_set(o, 0.1);
elm_slider_value_set(o, 0.5);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
/* contents */
f = elm_frame_add(win);
elm_object_text_set(f, "Contents");

View File

@ -46,6 +46,15 @@ interface Efl.Pack (Efl.Pack_Item)
subobj: Efl.Pack_Item*;
}
}
@property pack_align {
[[Alignment of the container within its bounds]]
set {}
get {}
values {
align_horiz: double;
align_vert: double;
}
}
@property padding {
[[Padding between items contained in this object.]]
set {}

View File

@ -273,6 +273,8 @@ _efl_ui_box_eo_base_constructor(Eo *obj, Efl_Ui_Box_Data *pd)
pd->orient = EFL_ORIENT_RIGHT;
pd->layout_engine = MY_CLASS;
pd->align.h = 0.5;
pd->align.v = 0.5;
return obj;
}
@ -556,4 +558,24 @@ _efl_ui_box_efl_pack_padding_get(Eo *obj, Efl_Ui_Box_Data *pd, double *h, double
if (v) *v = pd->pad.v;
}
EOLIAN static void
_efl_ui_box_efl_pack_pack_align_set(Eo *obj, Efl_Ui_Box_Data *pd, double h, double v)
{
if (h < 0) h = -1;
if (v < 0) v = -1;
if (h > 1) h = 1;
if (v > 1) v = 1;
pd->align.h = h;
pd->align.v = v;
efl_pack_layout_request(obj);
}
EOLIAN static void
_efl_ui_box_efl_pack_pack_align_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd, double *h, double *v)
{
if (h) *h = pd->align.h;
if (v) *v = pd->align.v;
}
#include "efl_ui_box.eo.c"

View File

@ -23,6 +23,8 @@ class Efl.Ui.Box (Elm.Widget, Efl.Pack_Engine, Efl.Pack_Linear)
Efl.Pack.pack;
Efl.Pack.padding.get;
Efl.Pack.padding.set;
Efl.Pack.pack_align.get;
Efl.Pack.pack_align.set;
Efl.Pack.layout_update;
Efl.Pack.layout_request;
Efl.Pack.layout_engine.get;

View File

@ -31,17 +31,28 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
Eina_Bool horiz = _horiz(pd->orient), zeroweight = EINA_FALSE;
int id = 0, count, boxl = 0, boxr = 0, boxt = 0, boxb = 0;
int length, want, deficit = 0, pad, extra = 0, rounding = 0;
double cur_pos = 0, weight = 0, scale;
double cur_pos = 0, weight[2] = { 0, 0 }, scale;
double box_align[2];
Eina_Bool box_fill[2] = { EINA_FALSE, EINA_FALSE };
evas_object_geometry_get(ui_box, &boxx, &boxy, &boxw, &boxh);
evas_object_size_hint_padding_get(ui_box, &boxl, &boxr, &boxt, &boxb);
scale = evas_object_scale_get(ui_box);
// Box align: used if "item has max size and fill" or "no item has a weight"
//box_align[0] = bd->align.h;
//box_align[1] = bd->align.v;
evas_object_size_hint_align_get(ui_box, &box_align[0], &box_align[1]);
// Note: cells always expand on the orthogonal direction
box_align[0] = pd->align.h;
box_align[1] = pd->align.v;
if (box_align[0] < 0)
{
box_fill[0] = EINA_TRUE;
box_align[0] = 0.5;
}
if (box_align[1] < 0)
{
box_fill[1] = EINA_TRUE;
box_align[1] = 0.5;
}
count = eina_list_count(bd->children);
if (!count)
@ -89,16 +100,16 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
item->want[0] = MAX(item->req[0], item->min[0]) + item->pad[0] + item->pad[1];
item->want[1] = MAX(item->req[1], item->min[1]) + item->pad[2] + item->pad[3];
weight[0] += item->weight[0];
weight[1] += item->weight[1];
if (horiz)
{
weight += item->weight[0];
wantw += item->want[0];
if (item->want[1] > wanth)
wanth = item->want[1];
}
else
{
weight += item->weight[1];
wanth += item->want[1];
if (item->want[0] > wantw)
wantw = item->want[0];
@ -110,6 +121,8 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
// box outer margin
boxw -= boxl + boxr;
boxh -= boxt + boxb;
boxx += boxl;
boxy += boxt;
// total space & available space
if (horiz)
@ -151,10 +164,9 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
extra = 0;
}
if (!weight)
if (!weight[!horiz])
{
double balign = box_align[!horiz];
if (balign < 0)
if (box_fill[!horiz])
{
// box is filled, set all weights to be equal
zeroweight = EINA_TRUE;
@ -162,15 +174,11 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
else
{
// move bounding box according to box align
cur_pos = extra * balign;
cur_pos = extra * box_align[!horiz];
}
weight = count;
weight[!horiz] = count;
}
// reset box_align to 0.5 if filled (only used by items with max size)
if (box_align[0] < 0) box_align[0] = 0.5;
if (box_align[1] < 0) box_align[1] = 0.5;
for (id = 0; id < count; id++)
{
double cx, cy, cw, ch, x, y, w, h;
@ -182,18 +190,18 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
if (horiz)
{
cx = boxx + boxl + cur_pos;
cy = boxy + boxt;
cw = item->want[0] + rounding + (zeroweight ? 1.0 : item->weight[0]) * extra / weight;
cx = boxx + cur_pos;
cy = boxy;
cw = item->want[0] + rounding + (zeroweight ? 1.0 : item->weight[0]) * extra / weight[0];
ch = boxh;
cur_pos += cw + pad;
}
else
{
cx = boxx + boxl;
cy = boxy + boxt + cur_pos;
cx = boxx;
cy = boxy + cur_pos;
cw = boxw;
ch = item->want[1] + rounding + (zeroweight ? 1.0 : item->weight[1]) * extra / weight;
ch = item->want[1] + rounding + (zeroweight ? 1.0 : item->weight[1]) * extra / weight[1];
cur_pos += ch + pad;
}

View File

@ -36,6 +36,10 @@ struct _Efl_Ui_Box_Data
double h, v;
Eina_Bool scalable: 1;
} pad;
struct {
double h, v;
} align;
};
struct _Box_Item_Iterator