Moin, I wrote a (not yet finished) patch to filter and search in gengrids. If you like this feature I would step up to implement it for the other grids/lists/...
But there are some questions in current stage: * to allow the user to show a widget with the current searchstring: should i emit a signal or allow him to set a methods to start,hide,delete,update his widgets? * should i add a default indicator? current BUGS: * item not shown after cancel: press w -> scroll -> backspace * Your bug here Any additional ideas I should implement, too? Maybe sort by rating of the compare callback? If you want to test it: the patch includes some addional lines for elementary_test-> Gengrid in filter mode. If you want to test search mode: replace elm_gengrid_filter_set by elm_gengrid_search_set. Regards, Frederik P.S.: Yes. the patch is not ecrustified, but it's not finished yet. -- IRC: playya @ Freenode, Gimpnet xmpp: [email protected] identi.ca: playya
Index: src/lib/Elementary.h.in
===================================================================
--- src/lib/Elementary.h.in (Revision 57300)
+++ src/lib/Elementary.h.in (Arbeitskopie)
@@ -960,6 +960,11 @@
EAPI void elm_gengrid_clear(Evas_Object *obj) EINA_ARG_NONNULL(1);
EAPI Elm_Gengrid_Item *elm_gengrid_selected_item_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
EAPI const Eina_List *elm_gengrid_selected_items_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+ EAPI void elm_gengrid_item_match_func_set(Evas_Object *obj, Eina_Compare_Cb cb) EINA_ARG_NONNULL(1,2);
+ EAPI void elm_gengrid_search_set(Evas_Object *obj, Eina_Bool search) EINA_ARG_NONNULL(1);
+ EAPI void elm_gengrid_search_stop(Evas_Object *obj) EINA_ARG_NONNULL(1);
+ EAPI void elm_gengrid_filter_stop(Evas_Object *obj) EINA_ARG_NONNULL(1);
+ EAPI void elm_gengrid_filter_set(Evas_Object *obj, Eina_Bool filter) EINA_ARG_NONNULL(1);
EAPI Elm_Gengrid_Item *elm_gengrid_item_append(Evas_Object *obj, const Elm_Gengrid_Item_Class *gic, const void *data, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1);
EAPI Elm_Gengrid_Item *elm_gengrid_item_prepend(Evas_Object *obj, const Elm_Gengrid_Item_Class *gic, const void *data, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1);
Index: src/lib/elm_gengrid.c
===================================================================
--- src/lib/elm_gengrid.c (Revision 57300)
+++ src/lib/elm_gengrid.c (Arbeitskopie)
@@ -210,6 +210,7 @@
Ecore_Job *calc_job;
Eina_List *selected;
Elm_Gengrid_Item *last_selected_item;
+ Elm_Gengrid_Item *last_search_item;
double align_x, align_y;
Evas_Coord pan_x, pan_y;
@@ -219,6 +220,12 @@
long count;
int walking;
+ struct
+ {
+ Eina_Compare_Cb func;
+ char* buf;
+ }match;
+
Eina_Bool horizontal : 1;
Eina_Bool on_hold : 1;
Eina_Bool longpressed : 1;
@@ -227,6 +234,8 @@
Eina_Bool wasselected : 1;
Eina_Bool always_select : 1;
Eina_Bool clear_me : 1;
+ Eina_Bool search : 1;
+ Eina_Bool filter : 1;
};
#define ELM_GENGRID_ITEM_FROM_INLIST(item) \
@@ -240,6 +249,7 @@
static const char *widtype = NULL;
static void _item_hilight(Elm_Gengrid_Item *item);
+static void _item_unhilight(Elm_Gengrid_Item *item);
static void _item_unrealize(Elm_Gengrid_Item *item);
static void _item_select(Elm_Gengrid_Item *item);
static void _item_unselect(Elm_Gengrid_Item *item);
@@ -262,6 +272,12 @@
static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
+static void _search_next(Evas_Object *obj, Eina_Bool cont);
+static void _search_prev(Evas_Object *obj);
+static void _search_finish(Evas_Object *obj);
+static void _filter_finish(Evas_Object *obj);
+static void _filter(Evas_Object *obj);
+static Eina_Bool _is_filtered(Elm_Gengrid_Item *i);
static Eina_Bool
_event_hook(Evas_Object *obj,
@@ -294,7 +310,13 @@
if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
{
- if ((wd->horizontal) &&
+ if(wd->match.buf && wd->search)
+ {
+ _search_prev(obj);
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ return EINA_TRUE;
+ }
+ else if ((wd->horizontal) &&
(((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
(_item_multi_select_up(wd)))
|| (_item_single_select_up(wd))))
@@ -315,7 +337,13 @@
}
else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
{
- if ((wd->horizontal) &&
+ if(wd->match.buf && wd->search)
+ {
+ _search_next(obj, EINA_TRUE);
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ return EINA_TRUE;
+ }
+ else if ((wd->horizontal) &&
(((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
(_item_multi_select_down(wd)))
|| (_item_single_select_down(wd))))
@@ -336,7 +364,13 @@
}
else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
{
- if ((wd->horizontal) &&
+ if(wd->match.buf && wd->search)
+ {
+ _search_prev(obj);
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ return EINA_TRUE;
+ }
+ else if ((wd->horizontal) &&
(((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
(_item_multi_select_left(wd)))
|| (_item_single_select_left(wd))))
@@ -357,7 +391,13 @@
}
else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
{
- if ((wd->horizontal) &&
+ if(wd->match.buf && wd->search)
+ {
+ _search_next(obj, EINA_TRUE);
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ return EINA_TRUE;
+ }
+ else if ((wd->horizontal) &&
(((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
(_item_multi_select_right(wd)))
|| (_item_single_select_right(wd))))
@@ -427,7 +467,12 @@
}
else if (!strcmp(ev->keyname, "Escape"))
{
- if (!_deselect_all_items(wd)) return EINA_FALSE;
+ if(wd->search && wd->match.buf)
+ _search_finish(obj);
+ else if(wd->filter && wd->match.buf)
+ _filter_finish(obj);
+ else
+ if (!_deselect_all_items(wd)) return EINA_FALSE;
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
}
@@ -436,6 +481,51 @@
item = elm_gengrid_selected_item_get(obj);
evas_object_smart_callback_call(item->wd->self, "clicked", item);
}
+ else if(((wd->search || wd->filter) && (strlen(ev->key)) == 1))
+ {
+ int len = 0;
+ char* buf = wd->match.buf;
+ if(buf)
+ len = strlen(buf);
+ wd->match.buf = calloc(len + 1 + 1, sizeof(char));
+ if(!wd->match.buf)
+ return EINA_FALSE;
+ if(buf)
+ {
+ memcpy(wd->match.buf, buf, len);
+ free(buf);
+ }
+ wd->match.buf[len] = ev->keyname[0];
+
+ if(wd->search)
+ _search_next(obj,EINA_FALSE);
+ else if(wd->filter)
+ _filter(obj);
+ }
+ else if((wd->search || wd->filter) && wd->match.buf && !strcmp(ev->keyname, "BackSpace"))
+ {
+ if(strlen(wd->match.buf) == 1)
+ {
+ free(wd->match.buf);
+ wd->match.buf = NULL;
+ if(wd->search)
+ _search_finish(obj);
+ else
+ _filter_finish(obj);
+ }
+ else
+ {
+ int len = strlen(wd->match.buf);
+ wd->match.buf[len-1] = '\0';
+ if(wd->search)
+ _search_next(obj, EINA_FALSE);
+ else
+ _filter(obj);
+
+ }
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ return EINA_TRUE;
+ }
else return EINA_FALSE;
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
@@ -698,6 +788,8 @@
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
+ if(wd->match.buf)
+ free(wd->match.buf);
free(wd);
}
@@ -938,13 +1030,22 @@
item->hilighted = EINA_TRUE;
}
+
static void
+_item_unhilight(Elm_Gengrid_Item *item)
+{
+ if ( (item->delete_me) || (item->selected)) return;
+ edje_object_signal_emit(item->base.view, "elm,state,unselected", "elm");
+ item->hilighted = EINA_FALSE;
+}
+static void
_item_realize(Elm_Gengrid_Item *item)
{
char buf[1024];
char style[1024];
if ((item->realized) || (item->delete_me)) return;
+ Widget_Data *wd = item->wd;
item->base.view = edje_object_add(evas_object_evas_get(item->wd->self));
edje_object_scale_set(item->base.view, elm_widget_scale_get(item->wd->self) *
_elm_config->scale);
@@ -1172,12 +1273,15 @@
if (ELM_RECTS_INTERSECT(x, y, item->wd->item_width, item->wd->item_height,
cvx, cvy, cvw, cvh))
{
- _item_realize(item);
- if (!was_realized)
- evas_object_smart_callback_call(item->wd->self, "realized", item);
- evas_object_move(item->base.view, x, y);
- evas_object_resize(item->base.view, item->wd->item_width,
- item->wd->item_height);
+ if(!_is_filtered(item))
+ {
+ _item_realize(item);
+ if (!was_realized)
+ evas_object_smart_callback_call(item->wd->self, "realized", item);
+ evas_object_move(item->base.view, x, y);
+ evas_object_resize(item->base.view, item->wd->item_width,
+ item->wd->item_height);
+ }
}
else
{
@@ -1517,6 +1621,155 @@
evas_object_smart_callback_call(data, "scroll", NULL);
}
+static void
+_search_next(Evas_Object *obj, Eina_Bool cont)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Gengrid_Item *item = wd->last_search_item;
+ if(cont)
+ {
+ item = elm_gengrid_item_next_get(item);
+ }
+ else
+ item = elm_gengrid_first_item_get(obj);
+
+ if(!item)
+ return;
+
+ for(;item;item=elm_gengrid_item_next_get(item))
+ {
+ if(!wd->match.func(item->base.data, wd->match.buf))
+ {
+ elm_gengrid_item_bring_in(item);
+ _item_hilight(item);
+ if(wd->last_search_item)
+ _item_unhilight(wd->last_search_item);
+ wd->last_search_item = item;
+ return;
+ }
+ }
+ item = elm_gengrid_first_item_get(obj);
+ for(;item != wd->last_search_item; item =elm_gengrid_item_next_get(item))
+ {
+ if(!wd->match.func(item->base.data, wd->match.buf))
+ {
+ elm_gengrid_item_bring_in(item);
+ _item_hilight(item);
+ if(wd->last_search_item)
+ _item_unhilight(wd->last_search_item);
+ wd->last_search_item = item;
+ return;
+ }
+ }
+}
+
+static void
+_search_prev(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Gengrid_Item *item = wd->last_search_item;
+ item = elm_gengrid_item_prev_get(item);
+
+ if(!item)
+ return;
+
+ for(;item;item=elm_gengrid_item_prev_get(item))
+ {
+ if(!wd->match.func(item->base.data, wd->match.buf))
+ {
+ elm_gengrid_item_bring_in(item);
+ _item_hilight(item);
+ if(wd->last_search_item)
+ _item_unhilight(wd->last_search_item);
+ wd->last_search_item = item;
+ return;
+ }
+ }
+
+ item = elm_gengrid_last_item_get(obj);
+ for(;item != wd->last_search_item; item = elm_gengrid_item_prev_get(item))
+ {
+ if(!wd->match.func(item->base.data, wd->match.buf))
+ {
+ elm_gengrid_item_bring_in(item);
+ _item_hilight(item);
+ if(wd->last_search_item)
+ _item_unhilight(wd->last_search_item);
+ wd->last_search_item = item;
+ return;
+ }
+ }
+}
+
+static void
+_search_finish(Evas_Object *obj)
+{
+ Widget_Data *data = elm_widget_data_get(obj);
+ Elm_Gengrid_Item *item;
+ data->last_search_item = NULL;
+ if(data->match.buf)
+ {
+ free(data->match.buf);
+ data->match.buf = NULL;
+ }
+}
+
+static void
+_filter_finish(Evas_Object *obj)
+{
+ Widget_Data *data = elm_widget_data_get(obj);
+ Elm_Gengrid_Item *item;
+ Evas_Object * o;
+ data->last_search_item = NULL;
+ item = elm_gengrid_first_item_get(obj);
+
+ if(data->match.buf)
+ {
+ free(data->match.buf);
+ data->match.buf = NULL;
+ }
+ printf("filter finished\n");
+
+ for(;item;item = elm_gengrid_item_next_get(item))
+ {
+ o = item->base.view;
+ evas_object_show(o);
+ }
+}
+
+static void
+_filter(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Gengrid_Item *item;
+ Evas_Object * o;
+ wd->last_search_item = NULL;
+ item = elm_gengrid_first_item_get(obj);
+ for(;item;item=elm_gengrid_item_next_get(item))
+ {
+ o = item->base.view;
+ Eina_Bool was_realized = item->realized;
+ if(!wd->match.func(item->base.data, wd->match.buf))
+ {
+ evas_object_show(o);
+ }
+ else
+ {
+ evas_object_hide(o);
+ }
+ }
+ evas_object_show(obj);
+}
+
+static Eina_Bool
+_is_filtered(Elm_Gengrid_Item *i)
+{
+ Widget_Data *wd = i->wd;
+ if(!wd->filter) return EINA_FALSE;
+ if(!wd->match.buf) return EINA_FALSE;
+ return (wd->match.func(i->base.data, wd->match.buf)) == 0 ? EINA_FALSE : EINA_TRUE;
+}
+
/**
* Add a new Gengrid object.
*
@@ -1714,6 +1967,66 @@
}
/**
+ * TODO: write docs
+ */
+EAPI void elm_gengrid_item_match_func_set(Evas_Object *obj,
+ Eina_Compare_Cb cb)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ wd->match.func = cb;
+}
+
+/**
+ * TODO: write docs
+ */
+EAPI void
+elm_gengrid_search_set(Evas_Object *obj,
+ Eina_Bool search)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if(!wd->filter && search)
+ {
+ wd->search = EINA_TRUE;
+ }
+ else
+ wd->search = EINA_FALSE;
+}
+
+EAPI void
+elm_gengrid_search_stop(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ _search_finish(obj);
+
+}
+
+/**
+ * TODO: write docs
+ */
+EAPI void
+elm_gengrid_filter_set(Evas_Object *obj,
+ Eina_Bool filter)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if(!wd->search && filter)
+ {
+ wd->filter = EINA_TRUE;
+ }
+ else
+ wd->filter = EINA_FALSE;
+}
+
+EAPI void
+elm_gengrid_filter_stop(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ _filter_finish(obj);
+}
+
+/**
* Add item to the end of the Gengrid.
*
* @param obj The Gengrid object.
Index: src/bin/test_gengrid.c
===================================================================
--- src/bin/test_gengrid.c (Revision 57300)
+++ src/bin/test_gengrid.c (Arbeitskopie)
@@ -141,6 +141,16 @@
printf("sel item data [%p] on grid obj [%p], pointer [%p]\n", data, obj, event_info);
}
+static int
+_compare_item(void* a1, void* a2)
+{
+ char* s = (char*)a2;
+ Testitem *ti = (Testitem*)a1;
+ printf("comparing %s == %s\n", s, ti->path);
+ char* p = strstr(ti->path, s);
+ return p == NULL;
+}
+
void
test_gengrid(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
@@ -162,6 +172,8 @@
elm_gengrid_item_size_set(grid, 150, 150);
elm_gengrid_horizontal_set(grid, EINA_FALSE);
elm_gengrid_multi_select_set(grid, EINA_TRUE);
+ elm_gengrid_filter_set(grid, EINA_TRUE);
+ elm_gengrid_item_match_func_set(grid, _compare_item);
evas_object_smart_callback_add(grid, "selected", grid_selected, NULL);
evas_object_smart_callback_add(grid, "clicked", grid_clicked, NULL);
evas_object_smart_callback_add(grid, "longpressed", grid_longpress, NULL);
signature.asc
Description: Digital signature
------------------------------------------------------------------------------ Free Software Download: Index, Search & Analyze Logs and other IT data in Real-Time with Splunk. Collect, index and harness all the fast moving IT data generated by your applications, servers and devices whether physical, virtual or in the cloud. Deliver compliance at lower cost and gain new business insights. http://p.sf.net/sfu/splunk-dev2dev
_______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
