aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/elementary/efl_ui_list.c722
-rw-r--r--src/lib/elementary/efl_ui_list.eo80
-rw-r--r--src/lib/elementary/efl_ui_list_private.h65
-rw-r--r--src/lib/elementary/efl_ui_view.c22
-rw-r--r--src/lib/elementary/efl_ui_view.eo12
-rw-r--r--src/lib/elementary/efl_ui_view_private.h17
6 files changed, 918 insertions, 0 deletions
diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c
new file mode 100644
index 0000000000..1c95143beb
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list.c
@@ -0,0 +1,722 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_PACK_LAYOUT_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#include "efl_ui_list_private.h"
+#include "efl_ui_list.eo.h"
+#include "elm_interface_scrollable.h"
+#include "elm_pan.eo.h"
+
+#define MY_CLASS EFL_UI_LIST_CLASS
+#define MY_CLASS_NAME "Efl.Ui.List"
+
+static void _list_calc(Efl_Ui_List_Pan_Data *pd);
+
+/* Custom Pan Class: overrides pan methods */
+static const Eo_Op_Description custom_pan_op_desc[] = {
+ EO_OP_CLASS_FUNC_OVERRIDE(evas_obj_smart_move, _efl_ui_list_pan_smart_move),
+ EO_OP_CLASS_FUNC_OVERRIDE(evas_obj_smart_resize, _efl_ui_list_pan_smart_resize),
+ EO_OP_CLASS_FUNC_OVERRIDE(evas_obj_smart_calculate, _efl_ui_list_pan_smart_calculate),
+ EO_OP_CLASS_FUNC_OVERRIDE(elm_pan_pos_set, _efl_ui_list_pan_pos_set),
+ EO_OP_CLASS_FUNC_OVERRIDE(elm_pan_pos_get, _efl_ui_list_pan_pos_get),
+ EO_OP_CLASS_FUNC_OVERRIDE(elm_pan_pos_min_get, _efl_ui_list_pan_pos_min_get),
+ EO_OP_CLASS_FUNC_OVERRIDE(elm_pan_pos_max_get, _efl_ui_list_pan_pos_max_get),
+ EO_OP_CLASS_FUNC_OVERRIDE(elm_pan_content_size_get, _efl_ui_list_pan_content_size_get),
+};
+
+static const Eo_Class_Description custom_pan_class_desc = {
+ EO_VERSION, "Efl.Ui.List.Pan", EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(custom_pan_op_desc), NULL,
+ sizeof(Efl_Ui_List_Pan_Data), NULL, NULL
+};
+
+EO_DEFINE_CLASS(_efl_ui_list_custom_pan_class_get, &custom_pan_class_desc,
+ ELM_PAN_CLASS, NULL)
+
+#define PAN_CLASS _efl_ui_list_custom_pan_class_get()
+
+
+/* Custom Layout Class may needs
+static const Eo_Op_Description item_laytout_op_desc[] = {
+ EO_OP_CLASS_FUNC_OVERRIDE(evas_obj_smart_calculate, _efl_ui_list_item_smart_calculate),
+};
+
+static const Eo_Class_Description item_layout_class_desc = {
+ EO_VERSION, "Efl.Ui.List.Item", EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(item_layout_op_desc), NULL,
+ sizeof(Efl_Ui_Layout_Data), NULL, NULL
+};
+
+EO_DEFINE_CLASS(_efl_ui_list_item_layout_class_get, &item_layout_class_desc,
+ EFL_LAYOUT_CLASS, NULL)
+
+#define ITEM_LAYOUT_CLASS _efl_ui_list_item_layout_class_get()
+*/
+
+
+static void
+_list_size_calc(Efl_Ui_List_Data *pd)
+{
+
+}
+
+static void
+_list_changed(Efl_Ui_List_Data *pd)
+{
+ pd->changed = EINA_TRUE;
+ if (pd->calc_job) ecore_job_del(pd->calc_job);
+ pd->calc_job = ecore_job_add(_list_size_calc, pd);
+}
+
+static List_Item *
+_list_item_new(Item_Block block, int index, Efl_Model *child)
+{
+ Efl_Ui_List_Data *pd = block->wd;
+ List_Item *item = ELM_NEW(List_Item);
+ item->index = index;
+ item->block = block;
+ item->my_model = child;
+ block->count++;
+
+ return item;
+}
+
+static void
+_list_item_calc(List_Item *item)
+{
+ if (!item->layout || !item->block) return;
+ Evas_Coord ow = 0, oh =0, mw = -1, mh = -1;
+ Item_Block *block = item->block;
+ Efl_Ui_List_Data *pd = block->wd;
+ Eo *view;
+ Elm_coords_finger_size_adjust(1, &mw, 1, &mh);
+ view = elm_layout_edje_get(item->layout);
+ edje_object_size_min_restricted_calc(view, &mw, &mh, mw, mh);
+ if ((pd->h_scroll == EINA_FALSE) && (mw > pd->w))
+ mw = pd->w;
+
+ oh = item->h;
+ item->w = mw;
+ item->h = mh;
+
+ item->calculated = EINA_TRUE;
+
+ if (block->w < item->w) block->w = item->w;
+ block->h = block->h + item->h - ow;
+ block->changed = EINA_TRUE;
+ //_list_updated();
+}
+
+/**EOLIAN @protected??**/
+static void
+_list_item_unrealize(Eo *obj, Efl_Ui_List_Data *pd, List_Item *item, Eina_Bool calc)
+{
+ /* Caching items or */
+ evas_object_del(item->layout);
+ item->realized = EINA_FALSE;
+}
+
+static void
+_list_item_resized_cb(void *data, Eo_Event *event EINA_UNUSED)
+{
+ List_Item *item = data;
+ Efl_Ui_List_Data *pd;
+ if (!item->layout || !item->block) return;
+ pd = item->block->wd;
+
+ _list_item_calc(item);
+ if (item->calc_once)
+ _list_item_unrealize(pd->obj, item, EINA_TRUE);
+}
+
+static Eo *
+_list_item_layout_create(Eo *obj, List_Item *item, Eina_Stringshare *style)
+{
+ //Eo *layout = eo_add(ELM_LAYOUT_CLASS, obj, elm_object_style_set(style););
+ Eo *layout = eo_add(ELM_LAYOUT_CLASS, obj);
+ elm_object_style_set(style);
+ efl_gfx_position_set(layout, -9999, -9999);
+ return layout;
+}
+
+/**EOLIAN @protected??**/
+static void
+_list_item_realize(Eo *obj, Efl_Ui_List_Data *pd, List_Item *item, int index, Efl_Model *child_model, Eina_Bool calc)
+{
+ if (it->realized || !child_model) return;
+
+ Eina_Stringshare *style = efl_ui_list_item_style_get(obj, child_model, index);
+ item->layout = _layout_create(obj, item, style);
+ //
+ // state update - select, focus, disable
+ // mouse_event add
+
+ pd->event->layout = layout;
+ pd->event->child = child_model;
+ pd->event->index = index;
+ eo_event_callback_call(obj, EFL_UI_LIST_EVENT_REALIZED, pd->event);
+ eo_event_callback_add(item->layout, EVAS_OBJECT_EVENT_RESIZE, _list_item_resized_cb, item);
+}
+
+static void
+_list_item_free(List_Item *item)
+{
+ Efl_Ui_List_Data *pd = item->block->wd;
+ if (item->realized) _list_item_unrealize(pd->obj, pd, item, EINA_FALSE);
+
+ if (item->queued)
+ {
+ pd->queue = eina_list_remove(pd->queue, item);
+ item->queued = EINA_FALSE;
+ }
+ else if (item->prequeued)
+ {
+ pd->prequeue = eina_list_remove(pd->prequeue, item);
+ item->prequeued = EINA_FALSE;
+ }
+ if (!pd->queue && !pd->prequeue)
+ {
+ ecore_idle_enterer_del(pd->queue_idle_enterer);
+ pd->queue_idle_enterer = NULL;
+ }
+
+ item->block->items = eina_list_remove(item->block->items, item);
+ /*
+ * free all item index and states needs;
+ */
+ free(item);
+
+}
+
+static Item_Block
+_list_block_new(Eo* obj, Efl_Ui_List_Data *pd)
+{
+ Item_Block *block = ELM_NEW(Item_Block);
+ block->wd = pd;
+
+ return block;
+}
+
+static void
+_list_block_del(Item_Block *block)
+{
+ Efl_Ui_List_Data *pd = block->wd;
+ List_Item *item;
+ EINA_LIST_FREE(block->items, item)
+ {
+ _list_item_free(item);
+ }
+ pd->item_blocks = eina_list_remove(pd->item_blocks, block);
+ free(block);
+}
+
+static void
+_list_clear(Eo* obj, Efl_Ui_List_Data *pd)
+{
+ Eina_List *l;
+ Item_Block *block;
+ EINA_LIST_FOREACH(pd->block, l, block)
+ {
+ _list_block_del(pd, block);
+ }
+}
+
+static Eina_Bool
+_item_process(Efl_Ui_List_Data *pd, List_Item *item, unsigned index)
+{
+ Evas_Coord ow, oh;
+ if (!item->my_model) return EINA_FALSE;
+ if (pd->homogeneous)
+ {
+ Item_Size *size;
+ if (pd->size_caches)
+ {
+ Eina_Stringshare *style = efl_ui_list_item_style_get(pd->obj, item->my_model, index);
+ size = eina_hash_find(sd->size_caches, style);
+ if (size)
+ {
+ oh = item->h;
+ item->w = size->w;
+ item->h = size->h;
+ item->calculated = EINA_TRUE;
+ item->queued = EINA_FALSE;
+ item->block->h = item->block->h + item->h - oh;
+ item->block->changed;
+ //_list_updated(pd);
+ return EINA_TRUE;
+ }
+ }
+ }
+ item->calc_once = EINA_TRUE;
+ item->queued = EINA_FALSE;
+ _list_item_realize(pd->obj, item, item->my_model, index, EINA_TRUE);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_queue_idle_enterer(void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN(data);
+ Efl_Ui_List_Data *pd = data;
+ List_Item *item;
+ Eina_Bool wakeup;
+ double t0, t1;
+ int n;
+
+ t0 = ecore_time_get();
+ for (n = 0; ((pd->queue) || (pd->prequeue)) && (n < (pd->block_size * 2)); n++)
+ {
+ if (pd->queue)
+ {
+ item = eina_list_data_get(pd->queue);
+ if (!_item_process(pd, item)) break;
+ pd->queue = eina_list_remove_list(pd->queue, sd->queue);
+ }
+ t1 = ecore_time_get();
+ if ((t - t0) > (ecore_animator_frametime_get())) break;
+
+ if (pd->prequeue)
+ {
+ item = eina_list_data_get(pd->prequeue);
+ if (!_item_process(pd, item)) break;
+ pd->prequeue = eina_list_remove_list(pd->prequeue, sd->queue);
+ }
+ t1 = ecore_time_get();
+ /* same as eina_inlist_count > 1 */
+ if ((t - t0) > (ecore_animator_frametime_get())) break;
+ }
+
+ if (wakeup)
+ {
+ // wake up mainloop
+ if (pd->calc_promise) efl_job_cancel(pd->calc_promise, pd->calc_promise);
+ pd->calc_promise = efl_loop_job(ds->calc_promise, pd);
+ eina_promise_then(pd->calc_promise, _list_calc, NULL, pd);
+ }
+
+ return ECORE_CALLBACK_RENEW;
+ return ECORE_CALLBACK_CANCEL;
+}
+
+
+static void
+_list_children_promise_then(Efl_Ui_List_Data *pd, Eina_Accessor **accessor)
+{
+ EINA_SAFETY_ON_NULL_RETURN(pd);
+ EINA_SAFETY_ON_NULL_RETURN(pd->model);
+ Item_Block *block;
+ int index = 0;
+ Eo *child;
+
+ block = _list_block_new(pd);
+ pd->item_blocks = eina_list_append(pd->item_blocks, block);
+
+ EINA_ACCESSOR_FOREACH(*accessor, i, child)
+ {
+ if (block->count == pd->block_size)
+ {
+ block = _list_block_new(pd);
+ pd->item_blocks = eina_list_append(pd->item_blocks, block);
+ }
+ item = _list_item_new(block, block->count, child);
+ b->items = eina_list_append(block->items, item);
+
+ if (pd->show_item =< i)
+ {
+ pd->queue = eina_list_append(pd->queue, item);
+ item->queued = EINA_TRUE;
+ }
+ else
+ {
+ pd->prequeue = eina_list_prepend(pd->prequeue, item);
+ item->prequeued = EINA_TRUE;
+ }
+ }
+
+ ecore_idle_enterer_del(pd->queue_idle_enterer);
+ pd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enterer, pd);
+}
+
+static void
+_list_count_promise_then(Efl_Ui_List_Data *pd, int count)
+{
+ EINA_SAFETY_ON_NULL_RETURN(pd);
+ EINA_SAFETY_ON_NULL_RETURN(pd->model);
+ if (pd->block_size =< 0) return;
+ pd->count = count;
+
+ efl_model_children_slice_get(pd->model, 0, 0, &pd->child_promise);
+ eina_promise_then(pd->child_promise, &_list_children_promise_then, NULL, pd);
+ while (count < index)
+ {
+ int size = ((pd->block_size > (count - index))?
+ (count - index) : pd->block_size);
+ itb = _list_block_new(obj, pd, size);
+ pd->item_blocks = eina_list_append(pd->item_blocks, itb);
+ index += size;
+ }
+
+ pd->count_promise = NULL;
+}
+
+static void
+_list_model_unset(Eo* obj, Efl_Ui_List_Data *pd)
+{
+ if (!pd->model) return;
+
+ _list_clear(obj, pd);
+
+ if (pd->count_promise)
+ {
+ eina_promise_cancel(pd->count_promise);
+ pd->count_promise = NULL;
+ }
+
+ pd->model = NULL;
+}
+
+static void
+_list_calc(Efl_Ui_List_Data *pd)
+{
+
+ evas_object_smart_changed();
+}
+
+EOLIAN void
+_efl_ui_list_homogeneous_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Bool homogeneous)
+{
+ pd->homogeneous = homogeneous;
+}
+
+EOLIAN Eina_Bool
+_efl_ui_list_homogeneous_get(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ return pd->homogeneous;
+}
+
+EOLIAN void
+_efl_ui_list_item_style_set(Eo *obj, Efl_Ui_List_Data *pd, const char* style)
+{
+ pd->style = eina_stringshare_add(style);
+}
+
+EOLIAN Eina_Stringshare *
+_efl_ui_list_item_style_get(Eo *obj, Efl_Ui_List_Data *pd, Efl_Model *model, int index)
+{
+ if (pd->style)
+ return pd->style;
+ else
+ return NULL;
+}
+
+EOLIAN void
+_efl_ui_list_scroll_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_Bool h_scroll, Eina_Bool v_scroll)
+{
+ pd->h_scroll = h_scroll;
+ pd->v_scroll = v_scroll;
+}
+
+EOLIAN void
+_efl_ui_list_eo_base_destructor(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ eo_destructor(eo_super(obj, MY_CLASS));
+}
+EOLIAN static void
+_efl_ui_list_pan_pos_set(Eo *obj, Efl_Ui_List_Pan_Data *pd, Evas_Coord x, Evas_Coord y)
+{
+ Efl_Ui_List_Data *wd = pd->wd;
+
+ if ((x == wd->pan_x) && (y == wd->pan_y)) return;
+ wd->pan_x = x;
+ wd->pan_y = y;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_pos_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *pd, Evas_Coord *x, Evas_Coord *y)
+{
+ if (x) *x = pd->wd->pan_x;
+ if (y) *y = pd->wd->pan_y;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_pos_max_get(Eo *obj, Efl_Ui_List_Pan_Data *pd, Evas_Coord *x, Evas_Coord *y)
+{
+ Evas_Coord ow, oh;
+
+ evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+ ow = pd->wd->min_w - ow;
+ if (ow < 0) ow = 0;
+ oh = pd->wd->min_h - oh;
+ if (oh < 0) oh = 0;
+
+ if (x) *x = ow;
+ if (y) *y = oh;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_pos_min_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *_pd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
+{
+ if (x) *x = 0;
+ if (y) *y = 0;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_content_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Pan_Data *pd, Evas_Coord *w, Evas_Coord *h)
+{
+ if (w) *w = pd->wd->min_w;
+ if (h) *h = pd->wd->min_h;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_smart_move(Eo *obj, Efl_Ui_List_Pan_Data *pd, Evas_Coord _gen_param2 EINA_UNUSED, Evas_Coord _gen_param3 EINA_UNUSED)
+{
+ pd->wd->pan_changed = EINA_TRUE;
+ evas_object_smart_changed(obj);
+ //ELM_SAFE_FREE(psd->wsd->calc_job, ecore_job_del);
+}
+
+static void
+_list_pan_smart_resize_job(void *data)
+{
+ EFL_UI_LIST_PAN_DATA_GET(data, pd);
+
+ elm_layout_sizing_eval(pd->wobj);
+ psd->resize_job = NULL;
+}
+
+EOLIAN static void
+_efl_ui_list_pan_smart_resize(Eo *obj, Efl_Ui_List_Pan_Data *pd, Evas_Coord w, Evas_Coord h)
+{
+ Evas_Coord ow, oh;
+
+ Efl_Ui_List_Data *wd = pd->wd;
+
+ evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+ if ((ow == w) && (oh == h)) return;
+ if ((wd->mode == EFL_UI_LIST_COMPRESS) && (ow != w))
+ {
+ /* fix me later */
+ ecore_job_del(pd->resize_job);
+ pd->resize_job =
+ ecore_job_add(_list_pan_smart_resize_job, obj);
+ }
+ wd->pan_changed = EINA_TRUE;
+ evas_object_smart_changed(obj);
+ //ecore_job_del(sd->calc_job);
+ // if the width changed we may have to resize content if scrollbar went
+ // away or appeared to queue a job to deal with it. it should settle in
+ // the end to a steady-state
+ //if (ow != w)
+ // wd->calc_job = ecore_job_add(_calc_job, pd->wobj);
+ //else
+ // wd->calc_job = NULL;
+}
+
+// ****
+EOLIAN static void
+_efl_ui_list_pan_smart_calculate(Eo *obj, Efl_Ui_List_Pan_Data *pd)
+{
+ Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
+ Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
+ Eina_List *l;
+
+ Efl_Ui_List_Data *wd = pd->wd;
+
+ evas_event_freeze(evas_object_evas_get(obj));
+ {
+ evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
+ evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
+
+ // Item Realize on Pan Position
+ //
+ //
+ //
+ //
+
+ elm_interface_scrollable_content_pos_get(wd->obj, &vx, &vy);
+ elm_interface_scrollable_content_viewport_geometry_get
+ (wd->obj, NULL, NULL, &vw, &vh);
+
+ }
+ evas_event_thaw(evas_object_evas_get(obj));
+ evas_event_thaw_eval(evas_object_evas_get(obj));
+
+ eo_event_callback_call
+ (pd->wobj, ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL);
+}
+// ****
+
+static void
+_evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
+{
+ Efl_Ui_List_Data *pd = d;
+ evas_object_smart_changed(pd->pan_obj);
+}
+
+EOLIAN void
+_efl_ui_list_evas_object_smart_add(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ Efl_Ui_List_Pan_Data *pan_data;
+ Evas_Coord minw, minh;
+ int i;
+
+ evas_obj_smart_add(eo_super(obj, MY_CLASS));
+ elm_widget_sub_object_parent_add(obj);
+
+ pd->obj = obj;
+ pd->size_caches = eina_hash_pointer_new(_size_cache_free);
+ pd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
+ evas_object_smart_member_add(pd->hit_rect, obj);
+ elm_widget_sub_object_add(obj, pd->hit_rect);
+
+ /* common scroller hit rectangle setup */
+ evas_object_color_set(pd->hit_rect, 0, 0, 0, 0);
+ evas_object_show(pd->hit_rect);
+ evas_object_repeat_events_set(pd->hit_rect, EINA_TRUE);
+
+ elm_widget_can_focus_set(obj, EINA_TRUE);
+ elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
+
+ // efl_ui_pack_layout
+ if (!elm_layout_theme_set
+ (obj, "list", "base", elm_widget_style_get(obj)))
+ CRI("Failed to set layout!");
+
+ elm_interface_scrollable_objects_set(obj, wd->resize_obj, pd->hit_rect);
+
+ pd->v_scroll = EINA_TRUE;
+ pd->h_scroll = EINA_FALSE;
+ pd->block_size = MAX_ITEMS_PER_BLOCK;
+
+ // Creating custom pan object
+ pd->pan = eo_add(PAN_CLASS, evas_object_evas_get(obj));
+ pan_data = eo_data_scope_get(pd->pan_obj, PAN_CLASS);
+ eo_data_ref(obj, NULL);
+ pan_data->wobj = obj;
+ pan_data->wsd = pd;
+
+ elm_interface_scrollable_extern_pan_set(obj, pd->pan);
+
+ edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+
+ _mirrored_set(obj, elm_widget_mirrored_get(obj));
+
+ elm_layout_sizing_eval(obj);
+
+ evas_event_callback_add(evas_object_evas_get(obj),
+ EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
+ _evas_viewport_resize_cb, pd);
+}
+
+EOLIAN
+void _efl_ui_list_evas_object_smart_del(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ _list_clear(obj);
+ evas_event_callback_del_full(evas_object_evas_get(obj),
+ EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
+ _evas_viewport_resize_cb, pd);
+ ELM_SAFE_FREE(pd->pan, evas_object_del);
+ ecore_idle_enterer_del(pd->queue_idle_enterer);
+
+ evas_obj_smart_del(eo_super(obj, MY_CLASS));
+}
+
+EOLIAN
+void _efl_ui_list_evas_object_smart_member_add(Eo *obj, Efl_Ui_List_Data *pd, Evas_Object *member)
+{
+ evas_obj_smart_member_add(eo_super(obj, MY_CLASS), member);
+ if (pd->hit_rect)
+ evas_object_raise(pd->hit_rect);
+}
+
+
+EOLIAN
+void _efl_ui_list_evas_object_smart_move(Eo *obj, Efl_Ui_List_Data *pd, Evas_Coord x, Evas_Coord y)
+{
+ evas_obj_smart_move(eo_super(obj, MY_CLASS), x, y);
+ evas_object_move(pd->hit_rect, x, y);
+}
+
+EOLIAN
+void _efl_ui_list_evas_object_smart_resize(Eo *obj, Efl_Ui_List_Data *pd, Evas_Coord w, Evas_Coord h)
+{
+ evas_obj_smart_resize(eo_super(obj, MY_CLASS), w, h);
+ evas_object_resize(pd->hit_rect, w, h);
+ /*
+ if (((pd->queue) || (pd->prequeue)) &&
+ (!pd->queue_idle_enterer) && (w > 0))
+ _requeue_idle_enterer(pd);
+ */
+}
+
+/*
+ * No theme apply exist in Efl.Ui.Object
+EOLIAN
+Eina_Bool _efl_ui_list_elm_widget_theme_apply(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ Eina_Bool int_ret = EINA_FALSE;
+ Eina_List *l;
+ Evas *e = evas_object_evas_get(obj);
+ Efl_Ui_List_Item *it;
+
+ int_ret = elm_obj_widget_theme_apply(eo_super(obj, MY_CLASS));
+ if (!int_ret) return EINA_FALSE;
+
+ evas_event_freeze(e);
+ _item_cache_zero(pd);
+ _mirrored_set(obj, elm_widget_mirrored_get(obj));
+
+ eina_hash_free_buckets(pd->size_caches);
+ pd->min_w = pd->min_h = 0;
+
+ elm_layout_sizing_eval(obj);
+ evas_event_thaw(evas_object_evas_get(obj));
+ evas_event_thaw_eval(evas_object_evas_get(obj));
+
+ return EINA_TRUE;
+}
+*/
+
+
+EOLIAN
+Eina_Bool _efl_ui_list_elm_widget_sub_object_del(Eo *obj, Efl_Ui_List_Data *pd, Evas_Object *sobj)
+{
+ Eina_Bool int_ret = EINA_FALSE;
+
+ /* XXX: hack -- also skipping sizing recalculation on
+ * sub-object-del. list's crazy code paths (like groups and
+ * such) seem to issue a whole lot of deletions and Evas bitches
+ * about too many recalculations */
+ pd->on_sub_del = EINA_TRUE;
+ int_ret = elm_obj_widget_sub_object_del(eo_super(obj, MY_CLASS), sobj);
+ if (!int_ret) return EINA_FALSE;
+
+ pd->on_sub_del = EINA_FALSE;
+ return EINA_TRUE;
+}
+
+EOLIAN
+void _efl_ui_list_efl_ui_view_model_set(Eo *obj, Efl_Ui_List_Data *pd, Efl_Model *model)
+{
+ if (pd->model)
+ _list_model_unset(obj, pd);
+ pd->model = model;
+
+ efl_model_children_count_get(model, &pd->count_promise);
+ eina_promise_then(
+ pd->count_promise, (Eina_Promise_Cb)&_list_count_promise_then, NULL, pd);
+}
+
+EOLIAN
+Efl_Model * _efl_ui_list_efl_ui_view_model_get(Eo *obj, Efl_Ui_List_Data *pd)
+{
+ return pd->model;
+}
diff --git a/src/lib/elementary/efl_ui_list.eo b/src/lib/elementary/efl_ui_list.eo
new file mode 100644
index 0000000000..fd36087f60
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list.eo
@@ -0,0 +1,80 @@
+struct Efl.Ui.List.Item_Event
+{
+ layout: Elm.Layout*;
+ child: Efl.Model*;
+ index: int;
+}
+
+class Efl.Ui.List (Elm.Widget, Efl.Pack, Efl.Pack_Layout, Elm.Interface_Scrollable, Efl.Ui.View)
+{
+ methods {
+ @property homogeneous {
+ set {
+ [[Enable/disable homogeneous mode.
+ ]]
+ }
+ get {
+ [[Get whether the homogeneous mode is enabled.]]
+ }
+ values {
+ homogeneous: bool; [[Assume the items within the genlist are of
+ the same height and width. Default is $false.]]
+ }
+ }
+ @property item_style {
+ set {} get {}
+ values {
+ style: Eina.Stringshare;
+ }
+ }
+ }
+ events {
+ item,realized : Efl.Ui.List.Item_Event*;
+ item,unrealized : Efl.Ui.List.Item_Event*;
+ item,focused : Efl.Ui.List.Item_Event*;
+ item,unfocused : Efl.Ui.List.Item_Event*;
+ item,highlighted : Efl.Ui.List.Item_Event*;
+ item,unhighlighted : Efl.Ui.List.Item_Event*;
+ item,selected : Efl.Ui.List.Item_Event*;
+ item,unselected : Efl.Ui.List.Item_Event*;
+ }
+
+ implements {
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+
+ // Smart obj
+ Evas.Object_Smart.add;
+ Evas.Object_Smart.del;
+ Evas.Object_Smart.move;
+ Evas.Object_Smart.resize;
+ Evas.Object_Smart.calculate;
+
+ // Widget
+ Elm.Widget.theme_apply;
+ Elm.Widget.on_focus;
+ Elm.Widget.focus_direction;
+ Elm.Widget.focus_direction_manager_is;
+ Elm.Widget.focus_next;
+ Elm.Widget.focus_next_manager_is;
+ Elm.Widget.focused_item.get;
+ Elm.Widget.event;
+ Elm.Widget.sub_object_del;
+
+ // Packing interfaces
+ Efl.Pack.pack_padding.get;
+ Efl.Pack.pack_padding.set;
+ Efl.Pack.pack_align.get;
+ Efl.Pack.pack_align.set;
+
+ // Custom layouts
+ Efl.Pack_Layout.layout_update;
+ Efl.Pack_Layout.layout_request;
+ Efl.Pack_Layout.layout_engine.get;
+ Efl.Pack_Layout.layout_engine.set;
+ Efl.Pack_Layout.layout_do;
+
+ Elm.Interface_Scrollable.bounce_allow;
+ Elm.Interface_Scrollable.policy;
+ }
+}
diff --git a/src/lib/elementary/efl_ui_list_private.h b/src/lib/elementary/efl_ui_list_private.h
new file mode 100644
index 0000000000..4bdf105ca9
--- /dev/null
+++ b/src/lib/elementary/efl_ui_list_private.h
@@ -0,0 +1,65 @@
+#ifndef EFL_UI_LIST_PRIVATE_H
+#define EFL_UI_LIST_PRIVATE_H
+
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct _Efl_Ui_List_Data Efl_Ui_List_Data;
+typedef struct _Item_Size Item_Size;
+typedef struct _Item_Block Item_Block;
+typedef struct _Item_Private Item_Private;
+
+struct _Efl_Ui_List_Data
+{
+ Eo *obj;
+ Efl_Model *model;
+ Eina_List *item_blocks;
+ int count;
+ Eina_Promise *count_promise;
+ Eina_Promise *child_promise;
+ Evas_Coord x, y, w, h;
+ Eina_Bool v_scroll: 1;
+ Eina_Bool h_scroll: 1;
+ Eina_Bool homogeneous: 1;
+ Eina_Bool calculated: 1;
+ Eina_Bool changed: 1;
+};
+
+struct _Item_Size
+{
+ Evas_Coord w, h;
+}
+
+struct _Item_Block
+{
+ int count;
+ Evas_Coord x, y, w, h;
+ Efl_Ui_List_Data *wd;
+ Eina_List *items;
+ Eina_Bool calculated: 1;
+ Eina_Bool realized: 1;
+}
+
+struct _Item_Private;
+{
+ int index; // index from the block
+ Evas_Coord x, y; // x, y position from the block
+ Evas_Coord w, h;
+ Item_Block *block;
+ Efl_Ui_List_Data *pd;
+ Eo *layout;
+ Efl_Model *my_model;
+ Eina_Bool queued: 1;
+ Eina_Bool calc_once: 1;
+ Eina_Bool calculated: 1;
+ Eina_Bool realized: 1;
+ Eina_Bool disabled: 1;
+ Eina_Bool selected: 1;
+ Eina_Bool focused: 1;
+};
+
+#endif
diff --git a/src/lib/elementary/efl_ui_view.c b/src/lib/elementary/efl_ui_view.c
new file mode 100644
index 0000000000..40d12e1fa5
--- /dev/null
+++ b/src/lib/elementary/efl_ui_view.c
@@ -0,0 +1,22 @@
+#include "efl_ui_view_private.h"
+
+#define MY_CLASS EFL_UI_VIEW_CLASS
+#define MY_CLASS_NAME "Efl.Ui.View"
+
+static const char SIG_MODEL_CHANGED[] = "model,changed";
+static const Evas_Smart_Cb_Description _smart_callbacks[] = {
+ {SIG_MODEL_CHANGED, ""},
+ {NULL, NULL}
+};
+
+static Eo *
+_efl_ui_view_model_get(Eo* obj, Efl_Ui_View_Data)
+{
+ return pd->model;
+}
+
+static void *
+_efl_ui_view_model_set(Eo* obj, Efl_Ui_View_Data *pd, Eo *model)
+{
+ pd->model = model;
+}
diff --git a/src/lib/elementary/efl_ui_view.eo b/src/lib/elementary/efl_ui_view.eo
new file mode 100644
index 0000000000..cd3a11ea8a
--- /dev/null
+++ b/src/lib/elementary/efl_ui_view.eo
@@ -0,0 +1,12 @@
+interface Efl.Ui.View ()
+{
+ methods {
+ @property model {
+ [[Model that is/will be ]]
+ get {} set {}
+ values {
+ model: Efl.Model*;
+ }
+ }
+ }
+}
diff --git a/src/lib/elementary/efl_ui_view_private.h b/src/lib/elementary/efl_ui_view_private.h
new file mode 100644
index 0000000000..e6a3d32e58
--- /dev/null
+++ b/src/lib/elementary/efl_ui_view_private.h
@@ -0,0 +1,17 @@
+#ifndef EFL_UI_VIEW_PRIVATE_H
+#define EFL_UI_VIEW_PRIVATE_H
+
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct _Efl_Ui_View_Data Efl_Ui_View_Data;
+
+struct _Efl_Ui_View_Data
+{
+ Efl_Model *model;
+};
+#endif