Efl.Ui.Box: Implement flow layouts

This reuses the Evas.Box code, since we are still using the
box internally. The flow layout function is far from perfect
(it works well only with items of same height).

This shows how to use specific layouts provided by EFL.
This commit is contained in:
Jean-Philippe Andre 2016-04-12 18:16:20 +09:00
parent 24eccb6d62
commit 548efd7fa4
9 changed files with 199 additions and 14 deletions

View File

@ -120,6 +120,7 @@ elm_eolian_files = \
lib/elementary/elm_diskselector_item.eo \
lib/elementary/elm_popup_item.eo \
lib/elementary/efl_ui_box.eo \
lib/elementary/efl_ui_box_flow.eo \
lib/elementary/efl_ui_grid.eo \
$(NULL)

View File

@ -91,6 +91,61 @@ margin_slider_cb(void *data, const Eo_Event *event)
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;
static Eina_Bool
flow_check_cb(void *data, const Eo_Event *event)
{
flow = elm_check_selected_get(event->obj);
efl_pack_layout_engine_set(data, flow ? EFL_UI_BOX_FLOW_CLASS : NULL, &s_flow_params);
return EO_CALLBACK_CONTINUE;
}
static Eina_Bool
horiz_check_cb(void *data, const Eo_Event *event)
{
Eina_Bool chk = elm_check_selected_get(event->obj);
efl_pack_direction_set(data, chk ? EFL_ORIENT_HORIZONTAL : EFL_ORIENT_VERTICAL);
return EO_CALLBACK_CONTINUE;
}
static Eina_Bool
homo_check_cb(void *data, const Eo_Event *event)
{
Eina_Bool chk = elm_check_selected_get(event->obj);
s_flow_params.homogenous = chk;
efl_pack_layout_engine_set(data, flow ? EFL_UI_BOX_FLOW_CLASS : NULL, &s_flow_params);
return EO_CALLBACK_CONTINUE;
}
static Eina_Bool
max_size_check_cb(void *data, const Eo_Event *event)
{
Eina_Bool chk = elm_check_selected_get(event->obj);
s_flow_params.max_size = chk;
efl_pack_layout_engine_set(data, flow ? EFL_UI_BOX_FLOW_CLASS : NULL, &s_flow_params);
return EO_CALLBACK_CONTINUE;
}
static Eina_Bool
left_check_cb(void *data, const Eo_Event *event)
{
Eina_Bool chk = elm_check_selected_get(event->obj);
if (chk)
{
s_flow_params.align_x = 0;
s_flow_params.align_y = 0;
}
else
{
s_flow_params.align_x = 0.5;
s_flow_params.align_y = 0.5;
}
efl_pack_layout_engine_set(data, flow ? EFL_UI_BOX_FLOW_CLASS : NULL, &s_flow_params);
return EO_CALLBACK_CONTINUE;
}
void
test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@ -182,6 +237,61 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
elm_radio_value_set(chk, NONE);
/* misc */
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, "Misc");
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
o = elm_check_add(win);
elm_check_selected_set(o, 0);
elm_object_text_set(o, "Flow");
eo_event_callback_add(o, ELM_CHECK_EVENT_CHANGED, flow_check_cb, bottombox);
evas_object_size_hint_align_set(o, 0, 0);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
o = elm_check_add(win);
elm_check_selected_set(o, 1);
elm_object_text_set(o, "Horizontal");
eo_event_callback_add(o, ELM_CHECK_EVENT_CHANGED, horiz_check_cb, bottombox);
evas_object_size_hint_align_set(o, 0, 0);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
o = elm_check_add(win);
elm_check_selected_set(o, 0);
elm_object_text_set(o, "Homogenous");
eo_event_callback_add(o, ELM_CHECK_EVENT_CHANGED, homo_check_cb, bottombox);
evas_object_size_hint_align_set(o, 0, 0);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
o = elm_check_add(win);
elm_check_selected_set(o, 0);
elm_object_text_set(o, "Homogenous + Max");
eo_event_callback_add(o, ELM_CHECK_EVENT_CHANGED, max_size_check_cb, bottombox);
evas_object_size_hint_align_set(o, 0, 0);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
o = elm_check_add(win);
elm_check_selected_set(o, 0);
elm_object_text_set(o, "Align left");
eo_event_callback_add(o, ELM_CHECK_EVENT_CHANGED, left_check_cb, bottombox);
evas_object_size_hint_align_set(o, 0, 0);
evas_object_size_hint_weight_set(o, 0, 1);
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
/* min size setter */
bx = eo_add(EFL_UI_BOX_CLASS, win,
efl_pack_direction_set(eo_self, EFL_ORIENT_DOWN));
@ -202,7 +312,7 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
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, min_slider_cb, NULL);
elm_slider_min_max_set(o, 1, 50);
elm_slider_min_max_set(o, 1, 150);
elm_slider_inverted_set(o, 1);
elm_slider_value_set(o, 50);
efl_pack(bx, o);
@ -290,7 +400,6 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
efl_gfx_visible_set(o, 1);
/* contents */
f = elm_frame_add(win);
elm_object_text_set(f, "Contents");

View File

@ -64,8 +64,9 @@ interface Efl.Pack (Efl.Pack_Item)
set { return: bool; }
get {}
values {
engine: const(Eo.Class)*; [[A class implementing a class function layout_do]]
data: void*; [[Any data to pass along to layout_do]]
engine: const(Eo.Class)*; [[A class implementing a class function layout_do.]]
data: const(void)*; [[Any data to pass along to layout_do.
Owned by the caller. Depends on the layout engine.]]
}
}
layout_update @protected {

View File

@ -5,7 +5,7 @@ interface Efl.Pack_Engine
layout_do @class {
params {
pack: Efl.Pack*;
data: void*;
data: const(void)*;
}
}
}

View File

@ -270,6 +270,7 @@ EAPI extern Elm_Version *elm_version;
#ifdef EFL_EO_API_SUPPORT
# include <efl_ui_box.eo.h>
# include <efl_ui_box_flow.eo.h>
#endif
/* include deprecated calls last of all */

View File

@ -1,8 +1,5 @@
#include "efl_ui_box_private.h"
// FIXME: stop using Evas.Box
#include <../evas/canvas/evas_box.eo.h>
/* COPIED FROM ELM_BOX
* - removed transition stuff (TODO: add back - needs clean API first)
*/
@ -168,7 +165,7 @@ _efl_ui_box_efl_pack_layout_update(Eo *obj, Efl_Ui_Box_Data *pd)
EOLIAN static void
_efl_ui_box_efl_pack_engine_layout_do(Eo *klass EINA_UNUSED,
void *_pd EINA_UNUSED,
Eo *obj, void *data EINA_UNUSED)
Eo *obj, const void *data EINA_UNUSED)
{
_layout_do(obj);
}
@ -177,10 +174,10 @@ EOLIAN static Eina_Bool
_efl_ui_box_efl_pack_layout_engine_set(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd,
const Eo_Class *klass, const void *data)
{
EINA_SAFETY_ON_FALSE_RETURN_VAL(eo_isa(klass, EFL_PACK_INTERFACE), EINA_FALSE);
pd->layout_engine = klass;
pd->layout_engine = klass ? klass : MY_CLASS;
pd->layout_data = data;
efl_pack_layout_request(obj);
_sizing_eval(obj, pd);
return EINA_TRUE;
}

View File

@ -0,0 +1,17 @@
struct Efl.Ui.Box_Flow_Params {
[[Extra parameters for Box_Flow layout. Can be omitted.]]
align_x: double;
align_y: double;
homogenous: bool;
max_size: bool;
}
class Efl.Ui.Box_Flow (Efl.Ui.Box, Efl.Pack_Engine)
{
[[A custom layout engine for @Efl.Ui.Box.]]
legacy_prefix: null;
data: null;
implements {
Efl.Pack_Engine.layout_do;
}
}

View File

@ -250,3 +250,59 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
evas_object_geometry_set(item->obj, x, y, w, h);
}
}
EOLIAN static void
_efl_ui_box_flow_efl_pack_engine_layout_do(Eo_Class *klass EINA_UNUSED,
void *_pd EINA_UNUSED,
Eo *obj, const void *data)
{
void (*func)(Evas_Box *obj, Evas_Object_Box_Data *priv, void *data);
const Efl_Ui_Box_Flow_Params *params = data;
double ax = 0.5, ay = 0.5;
Evas_Object_Box_Data *bd;
Efl_Ui_Box_Data *pd;
Eina_Bool homo = EINA_FALSE, maxsize = EINA_FALSE;
EINA_SAFETY_ON_FALSE_RETURN(eo_isa(obj, EFL_UI_BOX_CLASS));
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
bd = eo_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS);
pd = eo_data_scope_get(obj, EFL_UI_BOX_CLASS);
// FIXME: I wonder how this data will work with bindings? (lifetime, etc...)
if (params)
{
ax = params->align_x;
ay = params->align_y;
homo = params->homogenous;
maxsize = params->max_size;
}
if (_horiz(pd->orient))
{
if (homo)
{
if (maxsize)
func = evas_object_box_layout_homogeneous_max_size_horizontal;
else
func = evas_object_box_layout_homogeneous_horizontal;
}
else
func = evas_object_box_layout_flow_horizontal;
}
else
{
if (homo)
{
if (maxsize)
func = evas_object_box_layout_homogeneous_max_size_vertical;
else
func = evas_object_box_layout_homogeneous_vertical;
}
else
func = evas_object_box_layout_flow_vertical;
}
func(wd->resize_obj, bd, NULL);
}
#include "efl_ui_box_flow.eo.c"

View File

@ -10,6 +10,9 @@
#include <Elementary.h>
#include "elm_priv.h"
// FIXME: stop using Evas.Box
#include <../evas/canvas/evas_box.eo.h>
#define MY_CLASS EFL_UI_BOX_CLASS
#define MY_CLASS_NAME "Efl.Ui.Box"
@ -22,7 +25,7 @@ typedef struct _Box_Item_Iterator Box_Item_Iterator;
struct _Efl_Ui_Box_Data
{
const Eo_Class *layout_engine;
void *layout_data;
const void *layout_data;
Efl_Orient orient;
Eina_Bool homogeneous : 1;
@ -37,8 +40,8 @@ struct _Efl_Ui_Box_Data
struct _Box_Item_Iterator
{
Eina_List *list;
Eina_Iterator iterator;
Eina_List *list;
Eina_Iterator *real_iterator;
Efl_Ui_Box *object;
};