'everything' module: made views pluggable.

- toggle view with ctrl+1 for now. 
- api needs some cleanups
- added option to config page for my preffered quick navigation keys


SVN revision: 41851
This commit is contained in:
Hannes Janetzek 2009-08-17 23:54:16 +00:00
parent f21dc83e4b
commit 1fcfea9a30
10 changed files with 929 additions and 838 deletions

View File

@ -11,6 +11,8 @@
typedef struct _Evry_Plugin Evry_Plugin;
typedef struct _Evry_Item Evry_Item;
typedef struct _Evry_Action Evry_Action;
typedef struct _Evry_State Evry_State;
typedef struct _Evry_View Evry_View;
typedef struct _Evry_App Evry_App;
typedef struct _Plugin_Config Plugin_Config;
@ -50,7 +52,7 @@ struct _Evry_Item
/* store value of fuzzy match with input */
int fuzzy_match;
/* do not set by plugin! */
Evry_Plugin *plugin;
Evas_Object *o_icon;
@ -80,7 +82,8 @@ struct _Evry_Plugin
Eina_Bool browseable;
/* run when plugin is activated. */
/* run when plugin is activated. when return true plugin is added
to the list of current plugins and queried for results */
int (*begin) (Evry_Plugin *p, const Evry_Item *item);
int (*browse) (Evry_Plugin *p, const Evry_Item *item);
@ -88,7 +91,7 @@ struct _Evry_Plugin
/* get candidates matching string, fills 'candidates' list */
int (*fetch) (Evry_Plugin *p, const char *input);
/* run before new query and when hiding 'everything' */
/* run when state is removed in which this plugin is active */
void (*cleanup) (Evry_Plugin *p);
Evas_Object *(*icon_get) (Evry_Plugin *p, const Evry_Item *it, Evas *e);
@ -102,10 +105,6 @@ struct _Evry_Plugin
/* optional: create list of items when shown (e.g. for sorting) */
void (*realize_items) (Evry_Plugin *p, Evas *e);
/* optional: */
Evas_Object *(*show) (Evry_Plugin *p, Evas_Object *swallower, Eina_List *items);
int (*cb_key_down) (Evry_Plugin *p, Ecore_Event_Key *ev);
Eina_List *items;
Evas_Object *(*config_page) (void);
@ -119,6 +118,50 @@ struct _Evry_Plugin
Plugin_Config *config;
};
struct _Evry_State
{
char *input;
/* all available plugins for current state */
Eina_List *plugins;
/* currently active plugins, i.e. those that provide items */
Eina_List *cur_plugins;
/* active plugin */
Evry_Plugin *plugin;
/* selected item */
Evry_Item *sel_item;
/* Eina_List *sel_items; */
/* this is for the case when the current plugin was not selected
manually and a higher priority (async) plugin retrieves
candidates, the higher priority plugin is made current */
Eina_Bool plugin_auto_selected;
Eina_Bool item_auto_selected;
Evry_View *view;
Evas_Object *o_view;
};
struct _Evry_View
{
const char *name;
Evas_Object *(*begin) (Evry_View *v, const Evry_State *s, const Evas_Object *swallow);
int (*cb_key_down) (Evry_View *v, const Ecore_Event_Key *ev);
int (*update) (Evry_View *v, const Evry_State *s);
void (*clear) (Evry_View *v, const Evry_State *s);
void (*cleanup) (Evry_View *v);
const Evry_State *state;
int priority;
};
struct _Evry_Action
{
const char *name;
@ -155,9 +198,18 @@ void evry_plugin_register(Evry_Plugin *p, int priority);
void evry_plugin_unregister(Evry_Plugin *p);
void evry_action_register(Evry_Action *act);
void evry_action_unregister(Evry_Action *act);
void evry_view_register(Evry_View *view, int priority);
void evry_view_unregister(Evry_View *view);
void evry_item_select(const Evry_State *s, Evry_Item *it);
int evry_list_win_show(void);
void evry_list_win_hide(void);
Evry_Item *evry_item_new(Evry_Plugin *p, const char *label, void (*cb_free) (Evry_Item *item));
void evry_item_free(Evry_Item *it);
void evry_item_ref(Evry_Item *it);
void evry_plugin_async_update(Evry_Plugin *plugin, int state);
void evry_clear_input(void);
int evry_icon_theme_set(Evas_Object *obj, const char *icon);

View File

@ -112,6 +112,13 @@ evry_plug_preview_la_LIBADD = @e_libs@
evry_plug_preview_la_LDFLAGS = -no-undefined -module -avoid-version
evry_plug_preview_la_LIBTOOLFLAGS = --tag=disable-static
evry_plug_view_listdir = $(plugindir)
evry_plug_view_list_LTLIBRARIES = evry_plug_view_list.la
evry_plug_view_list_la_SOURCES = evry_plug_view_list.c
evry_plug_view_list_la_LIBADD = @e_libs@
evry_plug_view_list_la_LDFLAGS = -no-undefined -module -avoid-version
evry_plug_view_list_la_LIBTOOLFLAGS = --tag=disable-static
uninstall:
rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE)

View File

@ -51,7 +51,7 @@ e_modapi_init(E_Module *m)
char buf[4096], dir[4096];
char *file;
E_Action *act;
snprintf(buf, sizeof(buf), "%s/.e/e/config/%s/module.everything",
e_user_homedir_get(), e_config_profile_get());
ecore_file_mkdir(buf);
@ -81,6 +81,7 @@ e_modapi_init(E_Module *m)
E_CONFIG_VAL(D, T, scroll_speed, DOUBLE);
E_CONFIG_VAL(D, T, hide_input, INT);
E_CONFIG_VAL(D, T, hide_list, INT);
E_CONFIG_VAL(D, T, quick_nav, INT);
E_CONFIG_LIST(D, T, plugins_conf, conf_item_edd);
#undef T
#undef D
@ -98,6 +99,7 @@ e_modapi_init(E_Module *m)
evry_conf->scroll_speed = 0.08;
evry_conf->hide_input = 0;
evry_conf->hide_list = 1;
evry_conf->quick_nav = 1;
}
/* search for plugins */
@ -125,14 +127,14 @@ e_modapi_init(E_Module *m)
NULL, NULL, 0);
evry_conf->action_show = act;
}
maug = e_int_menus_menu_augmentation_add("main/1", _e_mod_menu_add, NULL, NULL, NULL);
e_configure_registry_category_add("extensions", 80, _("Extensions"), NULL, "preferences-extensions");
e_configure_registry_item_add("extensions/run_everything", 40, _("Run Everything"), NULL, "system-run", evry_config_dialog);
evry_init();
e_module_delayed_set(m, 1);
return m;
@ -206,8 +208,6 @@ _e_mod_action_exebuf_cb(E_Object *obj, const char *params __UNUSED__)
}
if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
printf("zone %d %d\n", zone->x, zone->y);
if (zone) evry_show(zone);
}
@ -309,3 +309,31 @@ evry_action_unregister(Evry_Action *action)
evry_conf->actions = eina_list_remove(evry_conf->actions, action);
/* cleanup */
}
static int
_evry_cb_view_sort(const void *data1, const void *data2)
{
const Evry_View *v1 = data1;
const Evry_View *v2 = data2;
return v1->priority - v2->priority;
}
EAPI void
evry_view_register(Evry_View *view, int priority)
{
view->priority = priority;
evry_conf->views = eina_list_append(evry_conf->views, view);
evry_conf->views = eina_list_sort(evry_conf->views,
eina_list_count(evry_conf->views),
_evry_cb_view_sort);
}
EAPI void
evry_view_unregister(Evry_View *view)
{
evry_conf->views = eina_list_remove(evry_conf->views, view);
}

View File

@ -22,12 +22,15 @@ struct _Config
int hide_input;
int hide_list;
int quick_nav;
Eina_Hash *key_bindings;
/**/
Eina_List *plugins;
Eina_List *actions;
Eina_List *views;
Eina_Hash *history;
E_Action *action_show;

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,8 @@ struct _E_Config_Dialog_Data
int hide_input;
int hide_list;
int quick_nav;
int width, height;
int scroll_animate;
@ -62,6 +64,7 @@ _fill_data(E_Config_Dialog_Data *cfdata)
* cfdata->width = evry_conf->width; */
cfdata->hide_list = evry_conf->hide_list;
cfdata->hide_input = evry_conf->hide_input;
cfdata->quick_nav = evry_conf->quick_nav;
EINA_LIST_FOREACH(evry_conf->plugins, l, p)
if (p->type == type_subject)
@ -108,7 +111,7 @@ _basic_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
* evry_conf->scroll_animate = cfdata->scroll_animate; */
evry_conf->hide_input = cfdata->hide_input;
evry_conf->hide_list = cfdata->hide_list;
evry_conf->quick_nav = cfdata->quick_nav;
evry_conf->plugins = eina_list_sort(evry_conf->plugins,
eina_list_count(evry_conf->plugins),
_evry_cb_plugin_sort);
@ -202,8 +205,13 @@ _basic_create_widgets(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dial
ob = e_widget_check_add(evas, _("Hide list"),
&(cfdata->hide_list));
e_widget_framelist_object_append(of, ob);
ob = e_widget_check_add(evas, _("Quick Navigation (ALT + h,j,k,l,n,p,m,i)"),
&(cfdata->quick_nav));
e_widget_framelist_object_append(of, ob);
e_widget_list_object_append(o, of, 1, 1, 0.5);
/* ob = e_widget_label_add(evas, _("Popup Width"));
* e_widget_framelist_object_append(of, ob);
* ob = e_widget_slider_add(evas, 1, 0, _("%1.0f"),

View File

@ -3,7 +3,7 @@
static Evry_Plugin *p;
/* TODO handle border remove events */
/* XXX handle border remove events */
static void
_cleanup(Evry_Plugin *p)

View File

@ -254,7 +254,6 @@ _fetch(Evry_Plugin *p, const char *input)
/* input is command ? */
if (input)
{
/* XXX free s->items? */
if (!strncmp(input, "/", 1))
{
if (s->command) return 1;
@ -266,7 +265,6 @@ _fetch(Evry_Plugin *p, const char *input)
s->cur = p->items;
s->command = EINA_TRUE;
return 1;
}
else if (!strncmp(input, "..", 2))
{
@ -287,7 +285,7 @@ _fetch(Evry_Plugin *p, const char *input)
tmp = strdup(dir);
snprintf(dir, (end - dir) + 1, "%s", tmp);
it = evry_item_new(p, dir, NULL);
if (!it) return 0; /* free stuff !!!*/
if (!it) break;
it->uri = eina_stringshare_add(dir);
it->priority = prio;
p->items = eina_list_append(p->items, it);
@ -303,7 +301,6 @@ _fetch(Evry_Plugin *p, const char *input)
p->items = eina_list_append(p->items, it);
s->cur = p->items;
s->command = EINA_TRUE;
return 1;
}
}
@ -322,7 +319,7 @@ _fetch(Evry_Plugin *p, const char *input)
{
int match;
if ((match = evry_fuzzy_match(it->label, input)))
it->priority = match;
it->fuzzy_match = match;
else
it = NULL;
}

View File

@ -1,16 +1,16 @@
#include "Evry.h"
static Evry_Plugin *p1;
static Evry_View *view = NULL;
static Evas_Object *o_thumb[5];
static const Evry_Item *cur_item = NULL;
static Evas_Object *o_main = NULL;
static Evas_Object *o_swallow = NULL;
static Eina_List *cur_items = NULL;
static int
_check_item(const Evry_Item *it)
{
if (!it) return 0;
if (strcmp(it->plugin->type_out, "FILE")) return 0;
if (!it->uri || !it->mime) return 0;
@ -38,7 +38,7 @@ _cb_preview_thumb_gen(void *data, Evas_Object *obj, void *event_info)
void
_show_item(const Evry_Item *it, int dir)
{
int w, h, x, y;
int w, h;
if (o_thumb[1 + dir])
{
@ -67,7 +67,8 @@ _show_item(const Evry_Item *it, int dir)
o_thumb[1] = e_thumb_icon_add(evas_object_evas_get(o_main));
e_thumb_icon_file_set(o_thumb[1], it->uri, NULL);
evas_object_smart_callback_add(o_thumb[1], "e_thumb_gen", _cb_preview_thumb_gen, NULL);
evas_object_geometry_get(o_main, &x, &y, &w, &h);
/* evas_object_geometry_get(o_main, &x, &y, &w, &h); */
edje_object_part_geometry_get(o_main, "e.swallow.icon2", NULL, NULL, &w, &h);
e_thumb_icon_size_set(o_thumb[1], w, h);
e_thumb_icon_begin(o_thumb[1]);
@ -80,36 +81,16 @@ _show_item(const Evry_Item *it, int dir)
}
}
static Evas_Object *
_show(Evry_Plugin *p, Evas_Object *swallow, Eina_List *items)
{
int w, h, x, y;
o_main = edje_object_add(evas_object_evas_get(swallow));
e_theme_edje_object_set(o_main, "base/theme/everything",
"e/widgets/everything/preview");
edje_object_part_geometry_get(swallow, "e.swallow.list", &x, &y, &w, &h);
edje_extern_object_min_size_set(o_main, w * 3, 100);
evas_object_resize(o_main, w * 3, h);
if (!o_main) return NULL;
o_swallow = swallow;
_show_item(cur_item, 0);
cur_items = items;
return o_main;
}
static int
_cb_key_down(Evry_Plugin *p, Ecore_Event_Key *ev)
_cb_key_down(Evry_View *v, const Ecore_Event_Key *ev)
{
Eina_List *l, *ll;
const Evry_Item *found = NULL, *it;
Eina_List *l, *ll, *cur_items;
Evry_Item *found = NULL, *it, *cur_item;
if (!strcmp(ev->key, "Right") ||
!strcmp(ev->key, "Down"))
cur_items = view->state->plugin->items;
cur_item = view->state->sel_item;
if (!strcmp(ev->key, "Down"))
{
l = eina_list_data_find_list(cur_items, cur_item);
@ -135,12 +116,11 @@ _cb_key_down(Evry_Plugin *p, Ecore_Event_Key *ev)
if (found && (found != cur_item))
{
_show_item(found, 1);
cur_item = found;
evry_item_select(view->state, found);
}
return 1;
}
else if (!strcmp(ev->key, "Left") ||
!strcmp(ev->key, "Up"))
else if (!strcmp(ev->key, "Up"))
{
EINA_LIST_FOREACH(cur_items, ll, it)
{
@ -161,7 +141,7 @@ _cb_key_down(Evry_Plugin *p, Ecore_Event_Key *ev)
if (found && (found != cur_item))
{
_show_item(found, -1);
cur_item = found;
evry_item_select(view->state, found);
}
return 1;
}
@ -169,61 +149,102 @@ _cb_key_down(Evry_Plugin *p, Ecore_Event_Key *ev)
return 0;
}
static int
_begin(Evry_Plugin *p, const Evry_Item *it)
{
if (_check_item(it))
{
cur_item = it;
return 1;
}
return 0;
}
static void
_cleanup(Evry_Plugin *p)
_clear(Evry_View *v, const Evry_State *s)
{
if (o_thumb[0]) evas_object_del(o_thumb[0]);
if (o_thumb[1]) evas_object_del(o_thumb[1]);
if (o_thumb[2]) evas_object_del(o_thumb[2]);
if (o_main) evas_object_del(o_main);
o_thumb[0] = NULL;
o_thumb[1] = NULL;
o_thumb[2] = NULL;
}
static void
_cleanup(Evry_View *v)
{
_clear(v, NULL);
if (o_main) evas_object_del(o_main);
o_main = NULL;
cur_items = NULL;
}
static int
_action(Evry_Plugin *p, const Evry_Item *it, const char *input __UNUSED__)
static Evry_Item *
_find_first(const Evry_State *s)
{
return 0;
Eina_List *l;
Evry_Item *it, *found = NULL;
if (_check_item(s->sel_item))
return s->sel_item;
EINA_LIST_FOREACH(s->plugin->items, l, it)
{
if (!_check_item(it)) continue;
found = it;
break;
}
return found;
}
static int
_fetch(Evry_Plugin *p, const char *input __UNUSED__)
_update(Evry_View *v, const Evry_State *s)
{
Evry_Item *it;
v->state = s;
it = _find_first(s);
if (!it) return 0;
_show_item(it, 0);
evry_item_select(view->state, it);
return 1;
}
static Evas_Object *
_begin(Evry_View *v, const Evry_State *s, const Evas_Object *swallow)
{
int w, h, x, y;
Evry_Item *it;
if (!(it = _find_first(s))) return NULL;
o_main = edje_object_add(evas_object_evas_get(swallow));
e_theme_edje_object_set(o_main, "base/theme/everything",
"e/widgets/everything/preview");
edje_object_part_geometry_get(swallow, "e.swallow.list", &x, &y, &w, &h);
edje_extern_object_min_size_set(o_main, w * 3, 100);
evas_object_resize(o_main, w * 3, h);
if (!o_main) return NULL;
view->state = s;
_show_item(it, 0);
return o_main;
}
static Eina_Bool
_init(void)
{
p1 = E_NEW(Evry_Plugin, 1);
p1->name = "Preview";
p1->type = type_action;
p1->type_in = "FILE";
p1->type_out = "NONE";
p1->icon = "preferences-desktop-wallpaper";
p1->need_query = 0;
p1->async_query = 1;
p1->begin = &_begin;
p1->fetch = &_fetch;
p1->show = &_show;
p1->cb_key_down = &_cb_key_down;
p1->action = &_action;
p1->cleanup = &_cleanup;
evry_plugin_register(p1, 3);
view = E_NEW(Evry_View, 1);
view->name = "Image Preview";
view->begin = &_begin;
view->update = &_update;
view->clear = &_clear;
view->cb_key_down = &_cb_key_down;
view->cleanup = &_cleanup;
evry_view_register(view, 2);
return EINA_TRUE;
}
@ -231,8 +252,8 @@ _init(void)
static void
_shutdown(void)
{
evry_plugin_unregister(p1);
E_FREE(p1);
evry_view_unregister(view);
E_FREE(view);
}

View File

@ -0,0 +1,458 @@
#include "Evry.h"
typedef struct _List_View List_View;
struct _List_View
{
Evas *evas;
Evas_Object *o_list;
int ev_last_is_mouse;
Evry_Item *item_mouseover;
Ecore_Animator *scroll_animator;
Ecore_Timer *scroll_timer;
double scroll_align_to;
double scroll_align;
Ecore_Idler *item_idler;
Eina_List *items;
};
static void _list_item_next(const Evry_State *s);
static void _list_item_prev(const Evry_State *s);
static void _list_item_first(const Evry_State *s);
static void _list_item_last(const Evry_State *s);
static void _list_scroll_to(Evry_Item *it);
/* static int _list_animator(void *data);
* static int _list_scroll_timer(void *data); */
static int _list_item_idler(void *data);
static void _list_clear_list(const Evry_State *s);
static Evry_View *view = NULL;
static List_View *list = NULL;
static void
_list_show_items(const Evry_State *s, Evry_Plugin *p)
{
Evry_Item *it;
Eina_List *l;
int mw, mh, h;
Evas_Object *o;
_list_clear_list(s);
if (!p) return;
if (list->scroll_timer)
{
ecore_timer_del(list->scroll_timer);
list->scroll_timer = NULL;
}
if (list->scroll_animator)
{
ecore_animator_del(list->scroll_animator);
list->scroll_animator = NULL;
}
list->scroll_align = 0;
evas_event_freeze(list->evas);
e_box_freeze(list->o_list);
EINA_LIST_FOREACH(p->items, l, it)
{
o = it->o_bg;
if (!o)
{
o = edje_object_add(list->evas);
it->o_bg = o;
e_theme_edje_object_set(o, "base/theme/everything",
"e/widgets/everything/item");
edje_object_part_text_set(o, "e.text.title", it->label);
/* evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN,
* _evry_cb_item_mouse_in, it);
* evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT,
* _evry_cb_item_mouse_out, it); */
}
edje_object_size_min_calc(o, &mw, &mh);
e_box_pack_end(list->o_list, o);
e_box_pack_options_set(o, 1, 1, 1, 0, 0.5, 0.5, mw, mh, 9999, mh);
evas_object_show(o);
if (it->o_icon && edje_object_part_exists(o, "e.swallow.icons"))
{
edje_object_part_swallow(o, "e.swallow.icons", it->o_icon);
evas_object_show(it->o_icon);
}
if (it == s->sel_item)
{
edje_object_signal_emit(it->o_bg, "e,state,selected", "e");
if (it->o_icon)
edje_object_signal_emit(it->o_icon, "e,state,selected", "e");
if (it->browseable)
edje_object_signal_emit(it->o_bg, "e,state,arrow_show", "e");
}
else
{
edje_object_signal_emit(it->o_bg, "e,state,unselected", "e");
}
evry_item_ref(it);
list->items = eina_list_append(list->items, it);
}
e_box_thaw(list->o_list);
list->item_idler = ecore_idler_add(_list_item_idler, p);
e_box_min_size_get(list->o_list, NULL, &mh);
evas_object_geometry_get(list->o_list, NULL, NULL, NULL, &h);
if (mh <= h)
e_box_align_set(list->o_list, 0.5, 0.0);
else
e_box_align_set(list->o_list, 0.5, 1.0);
evas_event_thaw(list->evas);
_list_scroll_to(s->sel_item);
}
static void
_list_clear_list(const Evry_State *s)
{
Evry_Item *it;
if (list->item_idler)
{
ecore_idler_del(list->item_idler);
list->item_idler = NULL;
}
if (list->items)
{
evas_event_freeze(list->evas);
e_box_freeze(list->o_list);
EINA_LIST_FREE(list->items, it)
{
if (it->o_bg)
{
e_box_unpack(it->o_bg);
evas_object_hide(it->o_bg);
}
if (it->o_icon)
evas_object_hide(it->o_icon);
evry_item_free(it);
}
}
e_box_thaw(list->o_list);
evas_event_thaw(list->evas);
/* } */
}
static int
_list_item_idler(void *data)
{
Evry_Plugin *p = data;
int cnt = 5;
Eina_List *l;
Evry_Item *it;
if (!list->item_idler) return 0;
if (!p->icon_get) goto end;
e_box_freeze(list->o_list);
EINA_LIST_FOREACH(list->items, l, it)
{
if (it->o_icon) continue;
it->o_icon = p->icon_get(p, it, list->evas);
if (it->o_icon)
{
edje_object_part_swallow(it->o_bg, "e.swallow.icons", it->o_icon);
evas_object_show(it->o_icon);
cnt--;
}
if (cnt == 0) break;
}
e_box_thaw(list->o_list);
if (cnt == 0) return 1;
end:
list->item_idler = NULL;
return 0;
}
/* static int
* _list_scroll_timer(void *data __UNUSED__)
* {
* if (list->scroll_animator)
* {
* double spd;
* spd = evry_conf->scroll_speed;
* list->scroll_align = (list->scroll_align * (1.0 - spd)) +
* (list->scroll_align_to * spd);
* return 1;
* }
* list->scroll_timer = NULL;
* return 0;
* }
*
* static int
* _list_animator(void *data __UNUSED__)
* {
* double da;
* Eina_Bool scroll_to = 1;
*
* da = list->scroll_align - list->scroll_align_to;
* if (da < 0.0) da = -da;
* if (da < 0.01)
* {
* list->scroll_align = list->scroll_align_to;
* scroll_to = 0;
* }
* e_box_align_set(list->o_list, 0.5, 1.0 - list->scroll_align);
* if (scroll_to) return 1;
* list->scroll_animator = NULL;
* return 0;
* } */
static void
_list_item_desel(const Evry_State *s, Evry_Item *it)
{
if (s->sel_item)
{
it = s->sel_item;
if (it->o_bg)
edje_object_signal_emit(it->o_bg, "e,state,unselected", "e");
if (it->o_icon)
edje_object_signal_emit(it->o_icon, "e,state,unselected", "e");
}
}
static void
_list_item_sel(const Evry_State *s, Evry_Item *it)
{
if (s->sel_item == it) return;
_list_item_desel(s, NULL);
if (it->o_bg)
edje_object_signal_emit(it->o_bg, "e,state,selected", "e");
if (it->o_icon)
edje_object_signal_emit(it->o_icon, "e,state,selected", "e");
if (it->browseable)
edje_object_signal_emit(it->o_bg, "e,state,arrow_show", "e");
_list_scroll_to(it);
evry_item_select(s, it);
}
static void
_list_scroll_to(Evry_Item *it)
{
int n, h, mh, i = 0;
Eina_List *l;
if (!it) return;
for(l = list->items; l; l = l->next, i++)
if (l->data == it) break;
n = eina_list_count(list->items);
e_box_min_size_get(list->o_list, NULL, &mh);
evas_object_geometry_get(list->o_list, NULL, NULL, NULL, &h);
if (i >= n || mh <= h)
{
e_box_align_set(list->o_list, 0.5, 0.0);
return;
}
if (n > 1)
{
list->scroll_align_to = (double)i / (double)(n - 1);
/* if (evry_conf->scroll_animate)
* {
* if (!list->scroll_timer)
* list->scroll_timer = ecore_timer_add(0.01, _list_scroll_timer, NULL);
* if (!list->scroll_animator)
* list->scroll_animator = ecore_animator_add(_list_animator, NULL);
* }
* else */
{
list->scroll_align = list->scroll_align_to;
e_box_align_set(list->o_list, 0.5, 1.0 - list->scroll_align);
}
}
else
e_box_align_set(list->o_list, 0.5, 1.0);
}
static void
_list_item_next(const Evry_State *s)
{
Eina_List *l;
Evry_Item *it;
if (!list->items) return;
EINA_LIST_FOREACH (list->items, l, it)
{
if (it == s->sel_item)
{
if (l->next)
{
_list_item_sel(s, l->next->data);
}
break;
}
}
}
static void
_list_item_prev(const Evry_State *s)
{
Eina_List *l;
Evry_Item *it;
if (!list->items) return;
if (!s->sel_item) return;
EINA_LIST_FOREACH (list->items, l, it)
{
if (it == s->sel_item)
{
if (l->prev)
{
_list_item_sel(s, l->prev->data);
return;
}
break;
}
}
evry_list_win_hide();
}
static void
_list_item_first(const Evry_State *s)
{
if (!list->items) return;
_list_item_sel(s, list->items->data);
}
static void
_list_item_last(const Evry_State *s)
{
if (!list->items) return;
_list_item_sel(s, eina_list_last(list->items)->data);
}
static int
_cb_key_down(Evry_View *v, const Ecore_Event_Key *ev)
{
const char *key = ev->key;
if (!strcmp(key, "Up"))
_list_item_prev(v->state);
else if (!strcmp(key, "Down"))
_list_item_next(v->state);
else if (!strcmp(key, "End"))
_list_item_last(v->state);
else if (!strcmp(key, "Home"))
_list_item_first(v->state);
else return 0;
return 1;
}
static Evas_Object *
_begin(Evry_View *v, const Evry_State *s, const Evas_Object *swallow)
{
Evas_Object *o;
list->evas = evas_object_evas_get(swallow);
o = e_box_add(list->evas);
list->o_list = o;
e_box_orientation_set(o, 0);
e_box_homogenous_set(o, 1);
return o;
}
static void
_cleanup(Evry_View *v)
{
if (list->scroll_timer)
ecore_timer_del(list->scroll_timer);
if (list->scroll_animator)
ecore_animator_del(list->scroll_animator);
if (list->item_idler)
ecore_idler_del(list->item_idler);
evas_object_del(list->o_list);
}
static void
_clear(Evry_View *v, const Evry_State *s)
{
_list_clear_list(s);
}
static int
_update(Evry_View *v, const Evry_State *s)
{
v->state = s;
_list_show_items(s, s->plugin);
return 1;
}
static Eina_Bool
_init(void)
{
view = E_NEW(Evry_View, 1);
view->name = "List View";
view->begin = &_begin;
view->update = &_update;
view->clear = &_clear;
view->cb_key_down = &_cb_key_down;
view->cleanup = &_cleanup;
evry_view_register(view, 1);
list = E_NEW(List_View, 1);
return EINA_TRUE;
}
static void
_shutdown(void)
{
evry_view_unregister(view);
E_FREE(view);
E_FREE(list);
}
EINA_MODULE_INIT(_init);
EINA_MODULE_SHUTDOWN(_shutdown);