enlightenment/src/modules/everything/evry_plug_view_list.c

454 lines
8.5 KiB
C

#include "Evry.h"
typedef struct _List_View List_View;
struct _List_View
{
Evry_View view;
Evas *evas;
const Evry_State *state;
Evas_Object *o_list;
Eina_List *items;
Ecore_Idler *item_idler;
double scroll_align_to;
double scroll_align;
/* int ev_last_is_mouse;
* Evry_Item *item_mouseover; */
/* Ecore_Timer *scroll_timer; */
/* Ecore_Animator *scroll_animator; */
};
static Evry_View *view = NULL;
static void
_list_clear(const Evry_View *view)
{
List_View *v = (List_View *) view;
Evry_Item *it;
if (v->item_idler)
{
ecore_idler_del(v->item_idler);
v->item_idler = NULL;
}
/* if (v->scroll_timer)
* {
* ecore_timer_del(v->scroll_timer);
* v->scroll_timer = NULL;
* }
*
* if (v->scroll_animator)
* {
* ecore_animator_del(v->scroll_animator);
* v->scroll_animator = NULL;
* } */
/* v->scroll_align = 0; */
if (!v->items) return;
evas_event_freeze(v->evas);
e_box_freeze(v->o_list);
EINA_LIST_FREE(v->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(v->o_list);
evas_event_thaw(v->evas);
}
static void
_list_scroll_to(List_View *v, const Evry_Item *it)
{
int n, h, mh, i = 0;
Eina_List *l;
if (!it) return;
for(l = v->items; l; l = l->next, i++)
if (l->data == it) break;
n = eina_list_count(v->items);
/* fixme how to get size of part, set in theme ?*/
e_box_min_size_get(v->o_list, NULL, &mh);
evas_object_geometry_get(v->o_list, NULL, NULL, NULL, &h);
if (mh <= h)
{
e_box_align_set(v->o_list, 0.5, 0.0);
return;
}
if (n > 6)
{
v->scroll_align_to = (double)i / (double)(n - 1);
{
v->scroll_align = v->scroll_align_to;
e_box_align_set(v->o_list, 0.5, 1.0 - v->scroll_align);
}
}
else
e_box_align_set(v->o_list, 0.5, 0.0);
}
static int
_list_item_idler(void *data)
{
List_View *v = data;
Evry_Plugin *p = v->state->plugin;
Eina_List *l;
Evry_Item *it;
int cnt = 5;
if (!v->item_idler) return 0;
if (!p->icon_get) goto end;
e_box_freeze(v->o_list);
EINA_LIST_FOREACH(v->items, l, it)
{
if (it->o_icon) continue;
it->o_icon = p->icon_get(p, it, v->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(v->o_list);
if (cnt == 0) return 1;
end:
v->item_idler = NULL;
return 0;
}
static int
_list_update(const Evry_View *view)
{
List_View *v = (List_View *) view;
Evry_Item *it;
Eina_List *l;
int mw = -1, mh;
Evas_Object *o;
int divider = 1;
_list_clear(view);
if (!v->state->plugin)
return 1;
evas_event_freeze(v->evas);
e_box_freeze(v->o_list);
EINA_LIST_FOREACH(v->state->plugin->items, l, it)
{
o = it->o_bg;
if (!o)
{
o = edje_object_add(v->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);
}
if (mw < 0) edje_object_size_min_get(o, &mw, &mh);
e_box_pack_end(v->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 (divider)
{
edje_object_signal_emit(it->o_bg, "e,state,odd", "e");
divider = 0;
}
else
{
edje_object_signal_emit(it->o_bg, "e,state,even", "e");
divider = 1;
}
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 == v->state->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);
v->items = eina_list_append(v->items, it);
}
e_box_thaw(v->o_list);
evas_event_thaw(v->evas);
_list_scroll_to(v, v->state->sel_item);
v->item_idler = ecore_idler_add(_list_item_idler, v);
return 1;
}
static void
_list_item_sel(List_View *v, const Evry_Item *it)
{
if (v->state->sel_item)
{
Evry_Item *it2 = v->state->sel_item;
if (it == it2) return;
if (it2->o_bg)
edje_object_signal_emit(it2->o_bg, "e,state,unselected", "e");
if (it2->o_icon)
edje_object_signal_emit(it2->o_icon, "e,state,unselected", "e");
}
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(v, it);
}
static void
_list_item_next(List_View *v)
{
Eina_List *l;
Evry_Item *it;
EINA_LIST_FOREACH (v->items, l, it)
{
if (it != v->state->sel_item) continue;
if (l->next)
{
it = l->next->data;
_list_item_sel(v, it);
evry_item_select(v->state, it);
}
break;
}
}
static void
_list_item_prev(List_View *v)
{
Eina_List *l;
Evry_Item *it;
EINA_LIST_FOREACH (v->items, l, it)
{
if (it != v->state->sel_item) continue;
if (l->prev)
{
it = l->prev->data;
_list_item_sel(v, it);
evry_item_select(v->state, it);
return;
}
break;
}
evry_list_win_hide();
}
static void
_list_item_first(List_View *v)
{
Evry_Item *it;
if (!v->items) return;
it = v->items->data;
_list_item_sel(v, it);
evry_item_select(v->state, it);
}
static void
_list_item_last(List_View *v)
{
Evry_Item *it;
if (!v->items) return;
it = eina_list_last(v->items)->data;
_list_item_sel(v, it);
evry_item_select(v->state, it);
}
static int
_cb_key_down(const Evry_View *view, const Ecore_Event_Key *ev)
{
List_View *v = (List_View *) view;
const char *key = ev->key;
if (!strcmp(key, "Up"))
_list_item_prev(v);
else if (!strcmp(key, "Down"))
_list_item_next(v);
else if (!strcmp(key, "End"))
_list_item_last(v);
else if (!strcmp(key, "Home"))
_list_item_first(v);
else return 0;
return 1;
}
static Evas_Object *
_list_object(const Evry_View *view)
{
return ((List_View*) view)->o_list;
}
static Evry_View *
_create(const Evry_View *view, const Evry_State *s, const Evas_Object *swallow)
{
List_View *v;
v = E_NEW(List_View, 1);
v->view = *view;
v->evas = evas_object_evas_get(swallow);
v->state = s;
v->o_list = e_box_add(v->evas);
e_box_orientation_set(v->o_list, 0);
e_box_homogenous_set(v->o_list, 1);
return &v->view;
}
static void
_destroy(const Evry_View *view)
{
List_View *v = (List_View *) view;
_list_clear(view);
evas_object_del(v->o_list);
E_FREE(v);
}
static Eina_Bool
_init(void)
{
view = E_NEW(Evry_View, 1);
view->id = view;
view->name = "List View";
view->create = &_create;
view->destroy = &_destroy;
view->object = &_list_object;
view->update = &_list_update;
view->clear = &_list_clear;
view->cb_key_down = &_cb_key_down;
evry_view_register(view, 1);
return EINA_TRUE;
}
static void
_shutdown(void)
{
evry_view_unregister(view);
E_FREE(view);
}
EINA_MODULE_INIT(_init);
EINA_MODULE_SHUTDOWN(_shutdown);
/* static int
* _list_scroll_timer(void *data __UNUSED__)
* {
* if (v->scroll_animator)
* {
* double spd;
* spd = evry_conf->scroll_speed;
* v->scroll_align = (v->scroll_align * (1.0 - spd)) +
* (v->scroll_align_to * spd);
* return 1;
* }
* v->scroll_timer = NULL;
* return 0;
* }
*
* static int
* _list_animator(void *data __UNUSED__)
* {
* double da;
* Eina_Bool scroll_to = 1;
*
* da = v->scroll_align - v->scroll_align_to;
* if (da < 0.0) da = -da;
* if (da < 0.01)
* {
* v->scroll_align = v->scroll_align_to;
* scroll_to = 0;
* }
* e_box_align_set(v->o_list, 0.5, 1.0 - v->scroll_align);
* if (scroll_to) return 1;
* v->scroll_animator = NULL;
* return 0;
* } */
/* if (evry_conf->scroll_animate)
* {
* if (!v->scroll_timer)
* v->scroll_timer = ecore_timer_add(0.01, _list_scroll_timer, NULL);
* if (!v->scroll_animator)
* v->scroll_animator = ecore_animator_add(_list_animator, NULL);
* }
* else */