enlightenment/src/modules/everything/evry_view_plugin_tabs.c

379 lines
6.6 KiB
C

#include "e_mod_main.h"
typedef struct _Tab Tab;
struct _Tab
{
Evry_Plugin *plugin;
Evas_Object *o_tab;
int cw, mw;
};
static void _tabs_update(Tab_View *v);
static int
_animator(void *data)
{
Tab_View *v = data;
double da;
double spd = (5.0 / (double)e_config->framerate);
if (spd > 0.9) spd = 0.9;
int wait = 0;
if (v->align != v->align_to)
{
v->align = (v->align * (1.0 - spd)) + (v->align_to * spd);
da = v->align - v->align_to;
if (da < 0.0) da = -da;
if (da < 0.01)
v->align = v->align_to;
else
wait++;
e_box_align_set(v->o_tabs, 1.0 - v->align, 0.5);
}
if (wait) return 1;
v->animator = NULL;
return 0;
}
static void
_tab_scroll_to(Tab_View *v, Evry_Plugin *p, int animate)
{
int n, w, mw, i;
double align;
Eina_List *l;
const Evry_State *s = v->state;
for(i = 0, l = s->cur_plugins; l; l = l->next, i++)
if (l->data == p) break;
n = eina_list_count(s->cur_plugins);
e_box_size_min_get(v->o_tabs, &mw, NULL);
evas_object_geometry_get(v->o_tabs, NULL, NULL, &w, NULL);
if (mw < w)
{
e_box_align_set(v->o_tabs, 0.0, 0.5);
return;
}
if (n > 1)
{
align = (double)i / (double)(n - 1);
if (animate && evry_conf->scroll_animate)
{
v->align_to = align;
if (!v->animator)
v->animator = ecore_animator_add(_animator, v);
}
else
e_box_align_set(v->o_tabs, 1.0 - align, 0.5);
}
else
e_box_align_set(v->o_tabs, 0.0, 0.5);
}
static int
_timer_cb(void *data)
{
Tab_View *v = data;
_tabs_update(v);
v->timer = NULL;
return 0;
}
static void
_tabs_update(Tab_View *v)
{
Eina_List *l, *ll;
Evry_Plugin *p;
const Evry_State *s = v->state;
Tab *tab;
Evas_Coord w, x;
Evas_Object *o;
edje_object_calc_force(v->o_tabs);
evas_object_geometry_get(v->o_tabs, &x, NULL, &w, NULL);
if (!w && !v->timer)
{
v->timer = ecore_timer_add(0.1, _timer_cb, v);
return;
}
/* remove tabs for not active plugins */
e_box_freeze(v->o_tabs);
EINA_LIST_FOREACH(v->tabs, l, tab)
{
e_box_unpack(tab->o_tab);
evas_object_hide(tab->o_tab);
}
/* show/update tabs of active plugins */
EINA_LIST_FOREACH(s->cur_plugins, l, p)
{
EINA_LIST_FOREACH(v->tabs, ll, tab)
if (tab->plugin == p) break;
if (!tab)
{
tab = E_NEW(Tab, 1);
tab->plugin = p;
o = edje_object_add(v->evas);
e_theme_edje_object_set(o, "base/theme/everything",
"e/modules/everything/tab_item");
edje_object_part_text_set(o, "e.text.label", p->label);
tab->o_tab = o;
edje_object_size_min_calc(o, &tab->cw, NULL);
edje_object_size_min_get(o, &tab->mw, NULL);
v->tabs = eina_list_append(v->tabs, tab);
}
if (!tab) continue;
o = tab->o_tab;
evas_object_show(o);
e_box_pack_end(v->o_tabs, o);
if (eina_list_count(s->cur_plugins) == 2)
e_box_pack_options_set(o, 1, 1, 0, 0, 0.0, 0.5,
w/4, 10, w/3, 9999);
else
e_box_pack_options_set(o, 1, 1, 0, 0, 0.0, 0.5,
w/4, 10,
w/3, 9999);
if (s->plugin == p)
edje_object_signal_emit(o, "e,state,selected", "e");
else
edje_object_signal_emit(o, "e,state,unselected", "e");
}
/* if (eina_list_count(s->cur_plugins) == 2)
* {
* v->align = 0;
* e_box_align_set(v->o_tabs, 0.0, 0.5);
* } */
/* else */
if (s->plugin)
_tab_scroll_to(v, s->plugin, 0);
e_box_thaw(v->o_tabs);
}
static void
_tabs_clear(Tab_View *v)
{
Eina_List *l;
Tab *tab;
e_box_freeze(v->o_tabs);
EINA_LIST_FOREACH(v->tabs, l, tab)
{
e_box_unpack(tab->o_tab);
evas_object_hide(tab->o_tab);
}
e_box_thaw(v->o_tabs);
}
static void
_plugin_select(Tab_View *v, Evry_Plugin *p)
{
evry_plugin_select(v->state, p);
_tabs_update(v);
_tab_scroll_to(v, p, 1);
/* _tabs_update(v); */
}
static void
_plugin_next(Tab_View *v)
{
Eina_List *l;
Evry_Plugin *p = NULL;
const Evry_State *s = v->state;
if (!s->plugin) return;
l = eina_list_data_find_list(s->cur_plugins, s->plugin);
if (l && l->next)
p = l->next->data;
else if (s->plugin != s->cur_plugins->data)
p = s->cur_plugins->data;
if (p) _plugin_select(v, p);
}
static void
_plugin_next_by_name(Tab_View *v, const char *key)
{
Eina_List *l;
Evry_Plugin *p, *first = NULL, *next = NULL;
int found = 0;
const Evry_State *s = v->state;
if (!s->plugin) return;
EINA_LIST_FOREACH(s->cur_plugins, l, p)
{
if (p->label && (!strncasecmp(p->label, key, 1)))
{
if (!first) first = p;
if (found && !next)
next = p;
}
if (p == s->plugin) found = 1;
}
if (next)
p = next;
else if (first != s->plugin)
p = first;
else
p = NULL;
if (p) _plugin_select(v, p);
}
static void
_plugin_prev(Tab_View *v)
{
Eina_List *l;
Evry_Plugin *p = NULL;
const Evry_State *s = v->state;
if (!s->plugin) return;
l = eina_list_data_find_list(s->cur_plugins, s->plugin);
if (l && l->prev)
p = l->prev->data;
else
{
l = eina_list_last(s->cur_plugins);
if (s->plugin != l->data)
p = l->data;
}
if (p) _plugin_select(v, p);
}
static int
_tabs_key_down(Tab_View *v, const Ecore_Event_Key *ev)
{
const char *key = ev->key;
if (!strcmp(key, "Next"))
{
_plugin_next(v);
return 1;
}
else if (!strcmp(key, "Prior"))
{
_plugin_prev(v);
return -1;
}
else if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
{
if (!strcmp(key, "Left"))
{
_plugin_prev(v);
return -1;
}
else if (!strcmp(key, "Right"))
{
_plugin_next(v);
return 1;
}
}
else if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
{
if (!strcmp(key, "Left"))
{
_plugin_prev(v);
return -1;
}
else if (!strcmp(key, "Right"))
{
_plugin_next(v);
return 1;
}
else if (ev->compose)
{
_plugin_next_by_name(v, key);
return 1;
}
}
return 0;
}
EAPI Tab_View *
evry_tab_view_new(const Evry_State *s, Evas *e)
{
Tab_View *v;
Evas_Object *o;
v = E_NEW(Tab_View, 1);
v->update = &_tabs_update;
v->clear = &_tabs_clear;
v->key_down = &_tabs_key_down;
v->state = s;
v->evas = e;
o = e_box_add(e);
e_box_orientation_set(o, 1);
e_box_homogenous_set(o, 1);
v->o_tabs = o;
return v;
}
EAPI void
evry_tab_view_free(Tab_View *v)
{
Tab *tab;
EINA_LIST_FREE(v->tabs, tab)
{
e_box_unpack(tab->o_tab);
evas_object_del(tab->o_tab);
E_FREE(tab);
}
evas_object_del(v->o_tabs);
if (v->animator)
ecore_animator_del(v->animator);
if (v->timer)
ecore_timer_del(v->timer);
E_FREE(v);
}