jackdanielz pushed a commit to branch master. http://git.enlightenment.org/tools/erigo.git/commit/?id=3ea7f48d39ed6af8c8be02679a14aa514286c0d5
commit 3ea7f48d39ed6af8c8be02679a14aa514286c0d5 Author: Daniel Zaoui <daniel.za...@samsung.com> Date: Wed Nov 4 15:39:55 2015 +0200 Objects tree: refactoring --- src/bin/gui/editor.c | 39 +++--- src/bin/gui/egui_logic.c | 13 -- src/bin/gui/objtree.c | 307 ++++++++++++++++++----------------------------- src/bin/gui/objtree.h | 6 +- 4 files changed, 139 insertions(+), 226 deletions(-) diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c index d4262e4..c0691fe 100644 --- a/src/bin/gui/editor.c +++ b/src/bin/gui/editor.c @@ -176,7 +176,7 @@ widget_name_change(Gui_Widget *wdg, const char *str) } const Gui_Widget *sel = gui_context_data_get(ctx, SELECTED_WDG); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(sel); return EINA_TRUE; @@ -1920,7 +1920,7 @@ end: { _wdg_parent_win_reload(new_wdg); _editor_wdg_selected_set(new_wdg); - objtree_build(wdg_context_get(new_wdg)); + objtree_build(); objtree_item_selected_set(new_wdg); } @@ -2415,7 +2415,7 @@ _dragdone_post_cb(Eina_Bool accept) _wdg_parent_win_reload(wdg); _editor_wdg_selected_set(wdg); - objtree_build(wdg_context_get(wdg)); + objtree_build(); objtree_item_selected_set(wdg); /* If dropping memento, make obj visible */ @@ -2734,7 +2734,7 @@ _update_widget_on_undoredo(Eid *wdg_id, Eina_Bool state) wdg = wdg_get(wdg_id); if (wdg) parent = wdg_main_wdg_get(wdg); if (parent) _wdg_parent_win_reload(parent); - objtree_build(_active_context_get()); + objtree_build(); objtree_item_selected_set(wdg ? wdg : parent); _editor_wdg_selected_set(wdg ? wdg : parent); proplayout_build(wdg ? wdg : parent); @@ -2796,7 +2796,7 @@ __undo_no_update(const Gui_Context *ctx) else { _wdg_parent_win_reload(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); } if (op_desc) @@ -3020,7 +3020,7 @@ _editor_redo(const Gui_Context *ctx) else { _wdg_parent_win_reload(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); } if (op_desc) @@ -3200,7 +3200,7 @@ _editor_undo_redo_post(const Memento *memento) proplayout_view_switch(CONTENT_TYPE); _wdg_parent_win_reload(memento_wdg); _editor_wdg_selected_set(memento_wdg); - objtree_build(wdg_context_get(memento_wdg)); + objtree_build(); objtree_item_selected_set(memento_wdg); break; } @@ -3221,7 +3221,7 @@ _editor_undo_redo_post(const Memento *memento) { _wdg_parent_win_reload(memento_wdg); _editor_wdg_selected_set(memento_wdg); - objtree_build(wdg_context_get(memento_wdg)); + objtree_build(); objtree_item_selected_set(memento_wdg); } break; @@ -3272,7 +3272,7 @@ _editor_ctx_call(const Gui_Context *ctx) * So need to hide border. */ _editor_wdg_selected_set(NULL); proplayout_build(NULL); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(NULL); return EINA_TRUE; @@ -3301,7 +3301,7 @@ _editor_selected_wdg_del_cb() /* Set selected widget: t.e. if I delete button, box will be selected after. * If I delete window, main item will be selected. */ - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(parent_wdg); _editor_wdg_selected_set(parent_wdg); context_memento_finalize(ctx); @@ -3542,7 +3542,7 @@ _prop_update_from_propview(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Descr _wdg_parent_win_reload(wdg); proplayout_build(NULL); _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); } else @@ -3589,7 +3589,7 @@ _drop_property_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) _wdg_parent_win_reload(wdg); proplayout_build(NULL); _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); } } @@ -3651,7 +3651,6 @@ _field_update_from_itemview(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Desc const Eo_Class *kl = eo_class_get(obj); const Op_Desc *op; const Gui_Widget *wdg = _editor_wdg_selected_get(); - const Gui_Context *ctx = _active_context_get(); const Item_Container_Item *wit; Item_Container_Item *new_wit; const Gui_Widget_Property *prop, *new_prop; @@ -3702,7 +3701,7 @@ _field_update_from_itemview(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Desc _wdg_parent_win_reload(wdg); proplayout_build(NULL); _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); itemview_item_selected_set(new_wit); } @@ -3922,7 +3921,7 @@ _itemview_item_do_(unsigned int type) _wdg_parent_win_reload(wdg); proplayout_build(NULL); _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); itemview_item_selected_set(it); } @@ -3969,7 +3968,7 @@ _content_del_from_propview(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Descr /* Reload window when unpacking something. */ _wdg_parent_win_reload(wdg); _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); context_memento_finalize(ctx); @@ -4007,7 +4006,7 @@ _content_reorder_from_propview(void *data, Eo *obj EINA_UNUSED, const Eo_Event_D _wdg_parent_win_reload(wdg); /* Update propview. */ _editor_wdg_selected_set(wdg); - objtree_build(wdg_context_get(wdg)); + objtree_build(); objtree_item_selected_set(wdg); } obj_container_unref(_old_container); @@ -4137,7 +4136,7 @@ _content_change_from_propview(void *data EINA_UNUSED, Eo *obj, const Eo_Event_De _wdg_parent_win_reload(wdg); _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); } @@ -4166,7 +4165,7 @@ _content_change_from_propview(void *data EINA_UNUSED, Eo *obj, const Eo_Event_De * Check ToDo. */ _wdg_parent_win_reload(wdg); _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); } } @@ -4234,7 +4233,7 @@ _content_change_from_propview(void *data EINA_UNUSED, Eo *obj, const Eo_Event_De _wdg_parent_win_reload(wdg); /* Update propview. */ _editor_wdg_selected_set(wdg); - objtree_build(ctx); + objtree_build(); objtree_item_selected_set(wdg); } } diff --git a/src/bin/gui/egui_logic.c b/src/bin/gui/egui_logic.c index 7d93968..ba44343 100644 --- a/src/bin/gui/egui_logic.c +++ b/src/bin/gui/egui_logic.c @@ -754,17 +754,6 @@ _factory_tt_mouse_down(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Descripti return EO_CALLBACK_CONTINUE; } -/* Filter function to be called, when Filter entry is changed. */ -static void -_objtree_filter_entry_changed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - const char *str = elm_entry_entry_get(obj); - //Trim from left - while (*str == ' ') str++; - if (!strlen(str)) objtree_filtering_reset(); - objtree_build(_active_context_get()); -} - static void _key_binding_save_cb(void *data) { @@ -864,8 +853,6 @@ egui_start(const char *filename) key_binding_new(_key_binding_save_cb, (void *) (intptr_t) ITEM_SAVE, "ctrl", "s", NULL); key_binding_new(_key_binding_save_cb, (void *) (intptr_t) ITEM_SAVEAS, "shift", "ctrl", "s", NULL); - evas_object_smart_callback_add(g_main_wdgs->main_win->objtree_filter_entry, "changed,user", _objtree_filter_entry_changed_cb, NULL); - /* Toolbar */ Eo *menu; elm_toolbar_item_selected_set(g_main_wdgs->main_win->toolbar_project_it, EINA_FALSE); diff --git a/src/bin/gui/objtree.c b/src/bin/gui/objtree.c index ff05af5..33e3484 100644 --- a/src/bin/gui/objtree.c +++ b/src/bin/gui/objtree.c @@ -4,32 +4,21 @@ #include "objtree.h" #include "egui_layout.h" -static Eo *lst = NULL; +static Eo *lst = NULL, *filter_entry = NULL; /*List to keep filtered widgets. * Cleared each time when objtree is built. */ -static Eina_List *filter_list = NULL; -static const Gui_Context *active_ctx = NULL; +static const Gui_Context *_active_ctx = NULL; static ObjTreeViewCbs *_view_cbs = NULL; static Elm_Genlist_Item_Class *_itc = NULL; -/* Hash table to keep track of which items are oppened and which not */ -static Eina_Hash *_openned_items_set = NULL; +/* List to keep track of which items have been open by the user */ +static const char *_filter = NULL; #define DATA_ITEM "_objtree_item" -static const char * -_objtree_filter_entry_string_get() -{ - Egui_Layout_Widgets *g = egui_layout_gui_get(); - const char *str = elm_entry_entry_get(g->main_win->objtree_filter_entry); - //Trim from left - while (*str == ' ') str++; - return strlen(str) ? str : NULL; -} - static char * _item_label_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part) { @@ -81,90 +70,47 @@ _contract_request_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *e elm_genlist_item_expanded_set(glit, EINA_FALSE); } -static void -_item_expand(Gui_Widget *wdg, Elm_Object_Item *parent) +static Elm_Object_Item * +_item_realize(Eid *eid) { - Elm_Genlist_Item_Type type; - - Eid *wid; - Elm_Object_Item *nitem; - Eina_List *w_list = NULL; - const Eina_List *l; - - if (wdg) eina_hash_set(_openned_items_set, wdg_name_get(wdg), (void *) 1); - - /* if wdg == NULL, this is root item, so add items for windows; - * or add items for child widgets and content. */ - if (wdg) + if (eid_is_dummy(eid) || !eid_exists(eid)) return NULL; + Gui_Widget *wdg = wdg_get(eid); + Elm_Object_Item *item = wdg_data_get(wdg, DATA_ITEM); + Elm_Object_Item *parent_item = NULL; + if (item) return item; + + Gui_Widget *parent = (Gui_Widget *)wdg_parent_get(wdg); + if (parent) { - /* clone children list */ - w_list = eina_list_clone(wdg_children_list_get(wdg)); - - /* If widget is container, and content widget is already in w_list, - * move it at the end. - * So content objects in objtree will be ordered as they are in container. */ - if (IS_CONTAINER(wdg)) - { - Object_Container_Item *ci; - EINA_LIST_FOREACH(wdg_obj_container_contents_list_get(wdg), l, ci) - { - Eid *i_eid = obj_container_item_eid_get(ci); - Eina_List *l_data = NULL; - if ((l_data = eina_list_data_find_list(w_list, i_eid))) - { - w_list = eina_list_demote_list(w_list, l_data); - } - else - { - w_list = eina_list_append(w_list, i_eid); - } - } - } + parent_item = _item_realize(wdg_eid_get(parent)); + if (parent_item) elm_genlist_item_expanded_set(parent_item, EINA_TRUE); } - else + + item = wdg_data_get(wdg, DATA_ITEM); + if (!item) { - w_list = eina_list_clone(gui_context_main_widgets_get(active_ctx)); + if (!parent || parent_item) + item = elm_genlist_item_append(lst, _itc, wdg, parent_item, + (_wdg_has_real_children(wdg)) ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE, + _view_cbs->item_selection_cb_func, NULL); + wdg_data_set(wdg, DATA_ITEM, item); } - /* If filter_entry in not empty, we are in filter mode*/ - const char *filter_str = _objtree_filter_entry_string_get(); + return item; +} + +static void +_item_expand(Gui_Widget *wdg) +{ + Eid *wid; + const Eina_List *itr; + /* Addind child's items into objtree view. */ - EINA_LIST_FOREACH(w_list, l, wid) + EINA_LIST_FOREACH(wdg_children_list_get(wdg), itr, wid) { - Eina_Bool filtered = EINA_FALSE; - Gui_Widget *w = wdg_get(wid); - if (eid_is_dummy(wid) || !w) continue; - /* This condition is needed to add items when filtering by typing. */ - if (filter_list) - { - if (!eina_list_data_find(filter_list, w)) continue; - filtered = EINA_TRUE; - filter_list = eina_list_remove(filter_list, w); - } - /* This condition is needed to filter items when expand/contract items. */ - else - { - if (filter_str && strstr(wdg_name_get(w), filter_str)) - { - filtered = EINA_TRUE; - } - } - - const char *wdgname = wdg_name_get(w); - type = (_wdg_has_real_children(w)) ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE; - if (!filter_str || (filter_str && filtered)) - { - nitem = elm_genlist_item_append(lst, _itc, w, parent, - type, _view_cbs->item_selection_cb_func, NULL); - wdg_data_set(w, DATA_ITEM, nitem); - - /* Expand item if it is in _opened_hash or if item meets filter condition. */ - if ((eina_hash_find(_openned_items_set, wdgname)) || - (filter_str && filtered)) - elm_genlist_item_expanded_set(nitem, EINA_TRUE); - } + if (!_filter || strstr(eid_name_get(wid), _filter)) + _item_realize(wid); } - eina_list_free(w_list); } static void @@ -172,17 +118,13 @@ _expanded_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_inf { Elm_Object_Item *glit = event_info; Gui_Widget *wdg = elm_object_item_data_get(glit); - _item_expand(wdg, glit); + _item_expand(wdg); } static void _contracted_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info) { Elm_Object_Item *glit = event_info; - - Gui_Widget *wdg = elm_object_item_data_get(glit); - if (wdg) eina_hash_del(_openned_items_set, wdg_name_get(wdg), NULL); - elm_genlist_item_subitems_clear(glit); } @@ -199,6 +141,62 @@ ObjTreeViewCbs *objtree_cbs_get() return _view_cbs; } +/* + * TRUE: item exists + * FALSE: item doesn't exist anymore + */ +static Eina_Bool +_useless_items_check(Eid *wid) +{ + const Eina_List *itr; + Eid *child; + Gui_Widget *wdg = wdg_get(wid); + Elm_Object_Item *item = wdg_data_get(wdg, DATA_ITEM); + Eina_Bool child_exists = EINA_FALSE; + if (!item) return EINA_FALSE; + + EINA_LIST_FOREACH(wdg_children_list_get(wdg), itr, child) + { + child_exists |= _useless_items_check(child); + } + + if (!child_exists && (_filter && !strstr(eid_name_get(wid), _filter))) + { + objtree_item_remove(wdg); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +/* Filter function to be called, when Filter entry is changed. */ +static void +_filter_entry_changed_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + const char *str = elm_entry_entry_get(filter_entry); + //Trim from left + while (*str == ' ') str++; + _filter = strlen(str) ? str : NULL; + if (_filter) + { + const Eina_List *itr; + Eid *eid; + /* Delete recursively the widgets that don't match anymore the filter */ + EINA_LIST_FOREACH(gui_context_main_widgets_get(_active_ctx), itr, eid) + { + _useless_items_check(eid); + } + /* Create the items that fit the filter */ + EINA_LIST_FOREACH(gui_context_wdg_list_get(_active_ctx), itr, eid) + { + if (strstr(eid_name_get(eid), _filter)) + _item_realize(eid); + } + } + else + objtree_build(); +} + /** Assign visible list to logical one. * (Assign place where logical list will be displayed.) * */ @@ -207,6 +205,10 @@ objtree_init() { Egui_Layout_Widgets *g = egui_layout_gui_get(); lst = g->main_win->objtree_list; + filter_entry = g->main_win->objtree_filter_entry; + evas_object_smart_callback_add(filter_entry, + "changed,user", _filter_entry_changed_cb, NULL); + if (!_itc) { @@ -218,11 +220,6 @@ objtree_init() _itc->func.del = _item_del_cb; } - if (!_openned_items_set) - { - _openned_items_set = eina_hash_string_superfast_new(NULL); - } - evas_object_smart_callback_add(lst, "expand,request", _expand_request_cb, lst); evas_object_smart_callback_add(lst, "contract,request", _contract_request_cb, lst); evas_object_smart_callback_add(lst, "expanded", _expanded_cb, lst); @@ -235,19 +232,6 @@ objtree_shutdown() elm_genlist_clear(lst); lst = NULL; if (_itc) elm_genlist_item_class_free(_itc); - if (_openned_items_set) eina_hash_free(_openned_items_set); - _openned_items_set = NULL; -} - -/* Clear filter field and expanded item's hash*/ -void -objtree_filtering_reset() -{ - Egui_Layout_Widgets *g = egui_layout_gui_get(); - eo_do(g->main_win->objtree_filter_entry, elm_obj_layout_text_set(NULL, NULL)); - /* There is no function, that clears hash, so recreate it. */ - if (_openned_items_set) eina_hash_free(_openned_items_set); - _openned_items_set = eina_hash_string_superfast_new(NULL); } /* Set list's item, which corresponds to wdg, selected. @@ -256,28 +240,10 @@ void objtree_item_selected_set(const Gui_Widget *wdg) { Elm_Object_Item *item = NULL; - - /* If filter was active, need to drop filter and clear open items hash. */ - if (_objtree_filter_entry_string_get()) - { - ERR("strange but we are here"); - objtree_filtering_reset(); - elm_genlist_clear(lst); - _item_expand(NULL, NULL); - } - if (!wdg) return; - - Eina_List *chain = eina_list_append(NULL, wdg); - while ((wdg = wdg_parent_get(wdg))) - { - chain = eina_list_prepend(chain, wdg); - } - EINA_LIST_FREE(chain, wdg) - { - item = wdg_data_get(wdg, DATA_ITEM); - elm_genlist_item_expanded_set(item, EINA_TRUE); - } + _filter = NULL; + item = _item_realize(wdg_eid_get(wdg)); + if (!item) return; elm_genlist_item_bring_in(item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); elm_genlist_item_selected_set(item, EINA_TRUE); } @@ -286,61 +252,19 @@ objtree_item_selected_set(const Gui_Widget *wdg) * In cases like: repacking object, undo/redo. * */ void -objtree_build(const Gui_Context *ctx) +objtree_build() { - elm_genlist_clear(lst); - - Eid *wid; - Eina_Bool can_merge = EINA_TRUE; - const Eina_List *itr; - Eina_List *tmp_list = NULL; - - const char *filter_str = _objtree_filter_entry_string_get(); - /* Cleate list of widgets, whose names contain filter str. - * Parents of these widgets are also in this list. */ - if (filter_str) + if (_filter) _filter_entry_changed_cb(NULL, NULL, NULL); + else { - Eina_List *wdg_lst = wdg_lst_get(ctx); - EINA_LIST_FOREACH(wdg_lst, itr, wid) + const Eina_List *itr; + Eid *eid; + EINA_LIST_FOREACH(gui_context_main_widgets_get(_active_ctx), itr, eid) { - can_merge = EINA_TRUE; - const Gui_Widget *wdg = wdg_get(wid), *wdg_parent; - if (!wdg) continue; - const char *wdg_name = wdg_name_get(wdg); - if (strstr(wdg_name, filter_str)) - { - if (!eina_list_data_find(filter_list, wdg)) - tmp_list = eina_list_append(tmp_list, wdg); - - while (wdg) - { - if (IS_MAIN(wdg)) break; - wdg_parent = wdg_parent_get(wdg); - if (!IS_MAIN(wdg) && !wdg_parent) - { - can_merge = EINA_FALSE; - break; - } - wdg_name = wdg_name_get(wdg_parent); - if (!eina_list_data_find(filter_list, wdg_parent)) - tmp_list = eina_list_append(tmp_list, wdg_parent); - wdg = wdg_parent; - } - } - if (can_merge) - { - Eina_List *llst = eina_list_merge(filter_list, tmp_list); - filter_list = eina_list_clone(llst); - } - else - { - eina_list_free(tmp_list); - } - tmp_list = NULL; + if (eid_is_dummy(eid) || !eid_exists(eid)) continue; + _item_realize(eid); } } - - _item_expand(NULL, NULL); } /* Remove an item */ @@ -348,8 +272,15 @@ void objtree_item_remove(const Gui_Widget *wdg) { if (!wdg) return; - Elm_Object_Item *it = wdg_data_get(wdg, DATA_ITEM); - if (it) elm_object_item_del(it); + Elm_Object_Item *sel_item = elm_genlist_selected_item_get(lst); + Elm_Object_Item *item = wdg_data_get(wdg, DATA_ITEM); + if (sel_item == item) + { + sel_item = elm_genlist_item_prev_get(item); + if (!sel_item) sel_item = elm_genlist_item_parent_get(item); + if (sel_item) elm_genlist_item_selected_set(sel_item, EINA_TRUE); + } + if (item) elm_object_item_del(item); } /* Assign context to objtree view. @@ -357,8 +288,8 @@ objtree_item_remove(const Gui_Widget *wdg) void objtree_context_set(const Gui_Context *ctx) { - active_ctx = ctx; + _active_ctx = ctx; if (!ctx) return; - objtree_build(ctx); + objtree_build(); } diff --git a/src/bin/gui/objtree.h b/src/bin/gui/objtree.h index 389e45c..d5e8cd2 100644 --- a/src/bin/gui/objtree.h +++ b/src/bin/gui/objtree.h @@ -31,11 +31,7 @@ objtree_context_set(const Gui_Context *ctx); /* Currentrly func is used to invoke building of objtree * when filter string is changed. */ void -objtree_build(const Gui_Context *ctx); - -/* Clear filter field and expanded item's hash*/ -void -objtree_filtering_reset(); +objtree_build(void); /* Set list's item, which corresponds to wdg, selected. * (Called when click on widget in layout.)*/ --