forked from enlightenment/efl
Efl.Ui.Grid: Implement custom layout functions
Untested yet. Will need to add the common 3 classes: - standard - homogenous - homogenous max_size And then implement a true custom layout function, that respects weights in a certain manner (need to define it clearly).
This commit is contained in:
parent
e4889ca367
commit
a0f92d9bef
|
@ -200,13 +200,13 @@ static const Eo_Class_Description custom_engine_class_desc = {
|
|||
EO_CLASS_DESCRIPTION_OPS(custom_engine_op_desc), NULL, 0, NULL, NULL
|
||||
};
|
||||
|
||||
EO_DEFINE_CLASS(custom_engine_class_get, &custom_engine_class_desc, EFL_PACK_ENGINE_INTERFACE, NULL)
|
||||
EO_DEFINE_CLASS(_test_ui_box_custom_engine_class_get, &custom_engine_class_desc, EFL_PACK_ENGINE_INTERFACE, NULL)
|
||||
|
||||
static Eina_Bool
|
||||
custom_check_cb(void *data, const Eo_Event *event)
|
||||
{
|
||||
Eina_Bool chk = elm_check_selected_get(event->obj);
|
||||
efl_pack_layout_engine_set(data, chk ? custom_engine_class_get() : NULL, NULL);
|
||||
efl_pack_layout_engine_set(data, chk ? _test_ui_box_custom_engine_class_get() : NULL, NULL);
|
||||
return EO_CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,47 +10,68 @@ typedef enum {
|
|||
NONE_BUT_FILL,
|
||||
EQUAL,
|
||||
ONE,
|
||||
TWO
|
||||
TWO,
|
||||
CUSTOM
|
||||
} Weight_Mode;
|
||||
|
||||
#define P(i) ((void*)(intptr_t)i)
|
||||
#define I(p) ((int)(intptr_t)p)
|
||||
static void _custom_engine_layout_do(Eo *obj, void *pd, Efl_Pack *pack, const void *data);
|
||||
|
||||
/* Common Eo Class boilerplate. */
|
||||
static const Eo_Op_Description custom_engine_op_desc[] = {
|
||||
EO_OP_CLASS_FUNC_OVERRIDE(efl_pack_engine_layout_do, _custom_engine_layout_do),
|
||||
};
|
||||
|
||||
static const Eo_Class_Description custom_engine_class_desc = {
|
||||
EO_VERSION, "Custom Layout Engine", EO_CLASS_TYPE_INTERFACE,
|
||||
EO_CLASS_DESCRIPTION_OPS(custom_engine_op_desc), NULL, 0, NULL, NULL
|
||||
};
|
||||
|
||||
EO_DEFINE_CLASS(_test_ui_grid_custom_engine_class_get, &custom_engine_class_desc, EFL_PACK_ENGINE_INTERFACE, NULL)
|
||||
|
||||
#define CUSTOM_ENGINE_CLASS _test_ui_grid_custom_engine_class_get()
|
||||
|
||||
static Eina_Bool
|
||||
weights_cb(void *data, const Eo_Event *event)
|
||||
{
|
||||
Weight_Mode mode = elm_radio_state_value_get(event->obj);
|
||||
Eo *grid = data;
|
||||
|
||||
if (mode != CUSTOM)
|
||||
efl_pack_layout_engine_set(grid, NULL, NULL);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case NONE:
|
||||
evas_object_size_hint_align_set(data, 0.5, 0.5);
|
||||
evas_object_size_hint_align_set(grid, 0.5, 0.5);
|
||||
for (int i = 0; i < 7; i++)
|
||||
evas_object_size_hint_weight_set(objects[i], 0, 0);
|
||||
break;
|
||||
case NONE_BUT_FILL:
|
||||
evas_object_size_hint_align_set(data, -1, -1);
|
||||
evas_object_size_hint_align_set(grid, -1, -1);
|
||||
for (int i = 0; i < 7; i++)
|
||||
evas_object_size_hint_weight_set(objects[i], 0, 0);
|
||||
break;
|
||||
case EQUAL:
|
||||
evas_object_size_hint_align_set(data, 0.5, 0.5);
|
||||
evas_object_size_hint_align_set(grid, 0.5, 0.5);
|
||||
for (int i = 0; i < 7; i++)
|
||||
evas_object_size_hint_weight_set(objects[i], 1, 1);
|
||||
break;
|
||||
case ONE:
|
||||
evas_object_size_hint_align_set(data, 0.5, 0.5);
|
||||
evas_object_size_hint_align_set(grid, 0.5, 0.5);
|
||||
for (int i = 0; i < 6; i++)
|
||||
evas_object_size_hint_weight_set(objects[i], 0, 0);
|
||||
evas_object_size_hint_weight_set(objects[6], 1, 1);
|
||||
break;
|
||||
case TWO:
|
||||
evas_object_size_hint_align_set(data, 0.5, 0.5);
|
||||
evas_object_size_hint_align_set(grid, 0.5, 0.5);
|
||||
for (int i = 0; i < 5; i++)
|
||||
evas_object_size_hint_weight_set(objects[i], 0, 0);
|
||||
evas_object_size_hint_weight_set(objects[5], 1, 1);
|
||||
evas_object_size_hint_weight_set(objects[6], 1, 1);
|
||||
break;
|
||||
case CUSTOM:
|
||||
efl_pack_layout_engine_set(grid, CUSTOM_ENGINE_CLASS, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return EO_CALLBACK_CONTINUE;
|
||||
|
@ -123,6 +144,49 @@ child_evt_cb(void *data, const Eo_Event *event)
|
|||
return EO_CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_custom_engine_layout_do(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
|
||||
Efl_Pack *pack, const void *data EINA_UNUSED)
|
||||
{
|
||||
/* Example custom layout for grid:
|
||||
* divide space into regions of same size, place objects in center of their
|
||||
* cells using their min size
|
||||
* Note: This is a TERRIBLE layout function (disregards align, weight, ...)
|
||||
*/
|
||||
|
||||
int rows, cols, gw, gh, gx, gy, c, r, cs, rs, gmw = 0, gmh = 0;
|
||||
Eina_Iterator *it;
|
||||
Eo *item;
|
||||
|
||||
efl_gfx_size_get(pack, &gw, &gh);
|
||||
efl_gfx_position_get(pack, &gx, &gy);
|
||||
|
||||
efl_pack_grid_size_get(pack, &cols, &rows);
|
||||
if (!cols || !rows) goto end;
|
||||
|
||||
it = efl_pack_contents_iterate(pack);
|
||||
EINA_ITERATOR_FOREACH(it, item)
|
||||
{
|
||||
if (efl_pack_child_position_get(pack, item, &c, &r, &cs, &rs))
|
||||
{
|
||||
int x, y, mw, mh;
|
||||
|
||||
evas_object_size_hint_min_get(item, &mw, &mh);
|
||||
x = gx + c * gw / cols + (cs * gw / cols - mw) / 2;
|
||||
y = gy + r * gh / rows + (rs * gh / rows - mh) / 2;
|
||||
efl_gfx_size_set(item, mw, mh);
|
||||
efl_gfx_position_set(item, x, y);
|
||||
|
||||
gmw = MAX(gmw, mw);
|
||||
gmh = MAX(gmh, mh);
|
||||
}
|
||||
}
|
||||
eina_iterator_free(it);
|
||||
|
||||
end:
|
||||
evas_object_size_hint_min_set(pack, gmw * cols, gmh * rows);
|
||||
}
|
||||
|
||||
void
|
||||
test_ui_grid(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
|
@ -211,6 +275,15 @@ test_ui_grid(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_i
|
|||
efl_pack(bx, o);
|
||||
efl_gfx_visible_set(o, 1);
|
||||
|
||||
o = elm_radio_add(win);
|
||||
elm_object_text_set(o, "Custom layout");
|
||||
eo_event_callback_add(o, ELM_RADIO_EVENT_CHANGED, weights_cb, grid);
|
||||
evas_object_size_hint_align_set(o, 0, 0.5);
|
||||
elm_radio_state_value_set(o, CUSTOM);
|
||||
elm_radio_group_add(o, chk);
|
||||
efl_pack(bx, o);
|
||||
efl_gfx_visible_set(o, 1);
|
||||
|
||||
elm_radio_value_set(chk, EQUAL);
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ interface Efl.Pack_Grid (Efl.Pack_Linear)
|
|||
@property pack_child_position {
|
||||
[[position and span of the $subobj in this container, may be modified to move the $subobj]]
|
||||
set { [[same as grid_pack]] }
|
||||
get {}
|
||||
get { return: bool; [[returns false if item is not a child]] }
|
||||
keys {
|
||||
subobj: Efl.Pack_Item*;
|
||||
}
|
||||
|
|
|
@ -148,16 +148,6 @@ _evas_box_custom_layout(Evas_Object *evas_box EINA_UNUSED,
|
|||
efl_pack_layout_update(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_layout_do(Efl_Ui_Box *obj)
|
||||
{
|
||||
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
||||
Evas_Object_Box_Data *bd;
|
||||
|
||||
bd = eo_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS);
|
||||
_efl_ui_box_custom_layout(obj, bd);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_box_efl_pack_layout_update(Eo *obj, Efl_Ui_Box_Data *pd)
|
||||
{
|
||||
|
@ -170,7 +160,11 @@ _efl_ui_box_efl_pack_engine_layout_do(Eo *klass EINA_UNUSED,
|
|||
void *_pd EINA_UNUSED,
|
||||
Eo *obj, const void *data EINA_UNUSED)
|
||||
{
|
||||
_layout_do(obj);
|
||||
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
||||
Evas_Object_Box_Data *bd;
|
||||
|
||||
bd = eo_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS);
|
||||
_efl_ui_box_custom_layout(obj, bd);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "elm_priv.h"
|
||||
|
||||
#include "efl_ui_grid.eo.h"
|
||||
#include "../evas/canvas/evas_table.eo.h"
|
||||
|
||||
#define MY_CLASS EFL_UI_GRID_CLASS
|
||||
#define MY_CLASS_NAME "Efl.Ui.Grid"
|
||||
|
@ -15,6 +16,7 @@
|
|||
typedef struct _Efl_Ui_Grid_Data Efl_Ui_Grid_Data;
|
||||
typedef struct _Grid_Item_Iterator Grid_Item_Iterator;
|
||||
typedef struct _Grid_Item Grid_Item;
|
||||
typedef struct _Custom_Table_Data Custom_Table_Data;
|
||||
|
||||
static Eina_Bool _subobj_del_cb(void *data, const Eo_Event *event);
|
||||
static void _item_remove(Efl_Ui_Grid *obj, Efl_Ui_Grid_Data *pd, Efl_Pack_Item *subobj);
|
||||
|
@ -34,6 +36,9 @@ struct _Grid_Item
|
|||
|
||||
struct _Efl_Ui_Grid_Data
|
||||
{
|
||||
const Eo_Class *layout_engine;
|
||||
const void *layout_data;
|
||||
|
||||
Grid_Item *items;
|
||||
int count;
|
||||
|
||||
|
@ -49,12 +54,18 @@ struct _Efl_Ui_Grid_Data
|
|||
|
||||
struct _Grid_Item_Iterator
|
||||
{
|
||||
Eina_List *list;
|
||||
Eina_Iterator iterator;
|
||||
Eina_Iterator *real_iterator;
|
||||
Eina_List *list;
|
||||
Efl_Ui_Grid *object;
|
||||
};
|
||||
|
||||
struct _Custom_Table_Data
|
||||
{
|
||||
Efl_Ui_Grid *parent;
|
||||
Efl_Ui_Grid_Data *gd;
|
||||
};
|
||||
|
||||
static const Eo_Callback_Array_Item subobj_callbacks [] = {
|
||||
{ EO_BASE_EVENT_DEL, _subobj_del_cb },
|
||||
{ NULL, NULL }
|
||||
|
@ -173,7 +184,6 @@ _efl_ui_grid_elm_widget_theme_apply(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
|||
static void
|
||||
_layout_updated_emit(Efl_Ui_Grid *obj)
|
||||
{
|
||||
/* FIXME: can't be called properly since there is no smart calc event */
|
||||
eo_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
|
||||
}
|
||||
|
||||
|
@ -197,7 +207,6 @@ _sizing_eval(Evas_Object *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
|||
if ((maxw >= 0) && (w > maxw)) w = maxw;
|
||||
if ((maxh >= 0) && (h > maxh)) h = maxh;
|
||||
evas_object_resize(obj, w, h);
|
||||
_layout_updated_emit(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -210,14 +219,93 @@ _table_size_hints_changed(void *data, Evas *e EINA_UNUSED,
|
|||
_sizing_eval(data, pd);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_grid_evas_object_smart_add(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
||||
/* Custom table class: overrides smart_calculate. */
|
||||
static void _custom_table_calc(Eo *obj, Custom_Table_Data *pd);
|
||||
|
||||
static const Eo_Op_Description custom_table_op_desc[] = {
|
||||
EO_OP_CLASS_FUNC_OVERRIDE(evas_obj_smart_calculate, _custom_table_calc),
|
||||
};
|
||||
|
||||
static const Eo_Class_Description custom_table_class_desc = {
|
||||
EO_VERSION, "Efl.Ui.Grid.Internal", EO_CLASS_TYPE_REGULAR,
|
||||
EO_CLASS_DESCRIPTION_OPS(custom_table_op_desc), NULL,
|
||||
sizeof(Custom_Table_Data), NULL, NULL
|
||||
};
|
||||
|
||||
EO_DEFINE_CLASS(_efl_ui_grid_custom_table_class_get, &custom_table_class_desc,
|
||||
EVAS_TABLE_CLASS, NULL)
|
||||
|
||||
#define CUSTOM_TABLE_CLASS _efl_ui_grid_custom_table_class_get()
|
||||
|
||||
static void
|
||||
_custom_table_calc(Eo *obj, Custom_Table_Data *pd)
|
||||
{
|
||||
int cols, rows;
|
||||
|
||||
evas_object_table_col_row_size_get(obj, &cols, &rows);
|
||||
if ((cols < 1) || (rows < 1)) return;
|
||||
|
||||
efl_pack_layout_update(pd->parent);
|
||||
_layout_updated_emit(pd->parent);
|
||||
}
|
||||
/* End of custom table class */
|
||||
|
||||
EOLIAN Eina_Bool
|
||||
_efl_ui_grid_efl_pack_layout_engine_set(Eo *obj, Efl_Ui_Grid_Data *pd, const Eo_Class *engine, const void *data)
|
||||
{
|
||||
pd->layout_engine = engine ? engine : eo_class_get(obj);
|
||||
pd->layout_data = data;
|
||||
efl_pack_layout_request(obj);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN void
|
||||
_efl_ui_grid_efl_pack_layout_engine_get(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, const Eo_Class **engine, const void **data)
|
||||
{
|
||||
if (engine) *engine = pd->layout_engine;
|
||||
if (data) *data = pd->layout_data;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_grid_efl_pack_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
|
||||
{
|
||||
_sizing_eval(obj, pd);
|
||||
efl_pack_engine_layout_do(pd->layout_engine, obj, pd->layout_data);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_grid_efl_pack_engine_layout_do(Eo *klass EINA_UNUSED,
|
||||
void *_pd EINA_UNUSED,
|
||||
Eo *obj, const void *data EINA_UNUSED)
|
||||
{
|
||||
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
||||
|
||||
evas_obj_smart_calculate(eo_super(wd->resize_obj, CUSTOM_TABLE_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN void
|
||||
_efl_ui_grid_evas_object_smart_calculate(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
||||
{
|
||||
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
||||
|
||||
efl_pack_layout_update(obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_grid_evas_object_smart_add(Eo *obj, Efl_Ui_Grid_Data *pd)
|
||||
{
|
||||
Custom_Table_Data *custom;
|
||||
Evas_Object *table;
|
||||
|
||||
pd->layout_engine = MY_CLASS;
|
||||
|
||||
elm_widget_sub_object_parent_add(obj);
|
||||
|
||||
table = evas_object_table_add(evas_object_evas_get(obj));
|
||||
table = eo_add(CUSTOM_TABLE_CLASS, obj);
|
||||
custom = eo_data_scope_get(table, CUSTOM_TABLE_CLASS);
|
||||
custom->gd = pd;
|
||||
custom->parent = obj;
|
||||
|
||||
evas_object_table_homogeneous_set(table, EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE);
|
||||
elm_widget_resize_object_set(obj, table, EINA_TRUE);
|
||||
|
||||
|
@ -276,6 +364,8 @@ _efl_ui_grid_eo_base_constructor(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_grid_efl_pack_padding_set(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, double h, double v, Eina_Bool scalable)
|
||||
{
|
||||
|
@ -408,11 +498,12 @@ _efl_ui_grid_efl_pack_grid_pack_child_position_set(Eo *obj, Efl_Ui_Grid_Data *pd
|
|||
_pack_at(obj, pd, subobj, col, row, colspan, rowspan, EINA_FALSE);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_grid_efl_pack_grid_pack_child_position_get(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, Evas_Object *subobj, int *col, int *row, int *colspan, int *rowspan)
|
||||
{
|
||||
int c = -1, r = -1, cs = 0, rs = 0;
|
||||
Grid_Item *gi;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
if (obj != elm_widget_parent_widget_get(subobj))
|
||||
{
|
||||
|
@ -429,11 +520,14 @@ _efl_ui_grid_efl_pack_grid_pack_child_position_get(Eo *obj, Efl_Ui_Grid_Data *pd
|
|||
rs = gi->row_span;
|
||||
}
|
||||
|
||||
ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
if (col) *col = c;
|
||||
if (row) *row = r;
|
||||
if (colspan) *colspan = cs;
|
||||
if (rowspan) *rowspan = rs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Pack_Item *
|
||||
|
@ -533,21 +627,6 @@ _efl_ui_grid_efl_pack_unpack_all(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
|||
evas_object_table_clear(wd->resize_obj, EINA_FALSE);
|
||||
}
|
||||
|
||||
EOLIAN void
|
||||
_efl_ui_grid_evas_object_smart_calculate(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
||||
{
|
||||
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
||||
|
||||
evas_object_smart_calculate(wd->resize_obj);
|
||||
}
|
||||
|
||||
EOLIAN void
|
||||
_efl_ui_grid_efl_pack_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
|
||||
{
|
||||
_sizing_eval(obj, pd);
|
||||
_layout_updated_emit(obj);
|
||||
}
|
||||
|
||||
EOLIAN void
|
||||
_efl_ui_grid_efl_pack_layout_request(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
class Efl.Ui.Grid (Elm.Widget, Efl.Pack_Grid)
|
||||
class Efl.Ui.Grid (Elm.Widget, Efl.Pack_Grid, Efl.Pack_Engine)
|
||||
{
|
||||
methods {
|
||||
}
|
||||
implements {
|
||||
Eo.Base.constructor;
|
||||
|
||||
|
@ -41,5 +39,9 @@ class Efl.Ui.Grid (Elm.Widget, Efl.Pack_Grid)
|
|||
Efl.Pack_Linear.pack_end;
|
||||
Efl.Pack_Linear.direction.set;
|
||||
Efl.Pack_Linear.direction.get;
|
||||
|
||||
Efl.Pack.layout_engine.get;
|
||||
Efl.Pack.layout_engine.set;
|
||||
Efl.Pack_Engine.layout_do;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue