forked from enlightenment/enlightenment
3027 lines
65 KiB
C
3027 lines
65 KiB
C
#include "e.h"
|
|
#include "e_mod_main.h"
|
|
|
|
/* TODO
|
|
* - keybinding configuration
|
|
*/
|
|
|
|
#define DRAG_OFF_WINDOW
|
|
|
|
#define INPUTLEN 256
|
|
#define MATCH_LAG 0.15
|
|
#define INITIAL_MATCH_LAG 0.3
|
|
|
|
#if defined (CHECK_TIME) || defined (CHECK_REFS)
|
|
#undef DBG
|
|
#define DBG(...) ERR(__VA_ARGS__)
|
|
#else
|
|
#undef DBG
|
|
#define DBG(...)
|
|
#endif
|
|
|
|
static void _evry_matches_update(Evry_Selector *sel, int async);
|
|
static void _evry_plugin_action(Evry_Selector *sel, int finished);
|
|
static void _evry_plugin_select(Evry_State *s, Evry_Plugin *p);
|
|
static void _evry_plugin_list_insert(Evry_State *s, Evry_Plugin *p);
|
|
static int _evry_backspace(Evry_Selector *sel);
|
|
static void _evry_update(Evry_Selector *sel, int fetch);
|
|
static void _evry_update_text_label(Evry_State *s);
|
|
static int _evry_clear(Evry_Selector *sel);
|
|
static Eina_Bool _evry_cb_update_timer(void *data);
|
|
|
|
static Evry_State *_evry_state_new(Evry_Selector *sel, Eina_List *plugins);
|
|
static void _evry_state_pop(Evry_Selector *sel, int immediate);
|
|
static void _evry_state_clear(Evry_Window *win);
|
|
|
|
static Evry_Selector *_evry_selector_new(Evry_Window *win, int type);
|
|
static void _evry_selector_free(Evry_Selector *sel);
|
|
static void _evry_selector_activate(Evry_Selector *sel, int slide);
|
|
static void _evry_selector_update(Evry_Selector *sel);
|
|
static int _evry_selector_plugins_get(Evry_Selector *sel, Evry_Item *it, const char *plugin_name);
|
|
static void _evry_selector_update_actions(Evry_Selector *sel);
|
|
static void _evry_selector_item_update(Evry_Selector *sel);
|
|
static void _evry_selector_item_clear(Evry_Selector *sel);
|
|
static void _evry_selector_label_set(Evry_Selector *sel, const char *part, const char *label);
|
|
static void _evry_selector_signal_emit(Evry_Selector *sel, const char *msg);
|
|
static int _evry_selectors_shift(Evry_Window *win, int dir);
|
|
static int _evry_selectors_switch(Evry_Window *win, int dir);
|
|
|
|
static Evry_Window *_evry_window_new(E_Zone *zone, E_Zone_Edge edge);
|
|
static void _evry_window_free(Evry_Window *win);
|
|
static void _evry_list_win_show(Evry_Window *win);
|
|
static void _evry_list_win_hide(Evry_Window *win);
|
|
static void _evry_list_win_update(Evry_State *s);
|
|
|
|
static int _evry_view_create(Evry_State *s);
|
|
static void _evry_view_clear(Evry_State *s);
|
|
static int _evry_view_update(Evry_Window *win, Evry_State *s);
|
|
static int _evry_view_key_press(Evry_State *s, Ecore_Event_Key *ev);
|
|
static void _evry_view_show(Evry_Window *win, Evry_View *v, int slide);
|
|
static void _evry_view_hide(Evry_Window *win, Evry_View *v, int slide);
|
|
|
|
|
|
static void _evry_item_desel(Evry_State *s);
|
|
static void _evry_item_sel(Evry_State *s, Evry_Item *it);
|
|
|
|
static Eina_Bool _evry_cb_key_down(void *data, int type, void *event);
|
|
static Eina_Bool _evry_cb_selection_notify(void *data, int type, void *event);
|
|
static Eina_Bool _evry_cb_mouse(void *data, int type, void *event);
|
|
|
|
static Eina_List *windows = NULL;
|
|
|
|
#ifdef CHECK_TIME
|
|
double _evry_time;
|
|
#endif
|
|
|
|
#ifdef CHECK_REFS
|
|
static int _item_cnt = 0;
|
|
Eina_List *_refd = NULL;
|
|
#endif
|
|
|
|
#define SUBJ_SEL win->selectors[0]
|
|
#define ACTN_SEL win->selectors[1]
|
|
#define OBJ_SEL win->selectors[2]
|
|
#define CUR_SEL win->selector
|
|
|
|
int
|
|
evry_init(void)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
evry_shutdown(void)
|
|
{
|
|
while(windows)
|
|
evry_hide(windows->data, 0);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
_evry_aggregator_fetch(Evry_State *s)
|
|
{
|
|
Eina_List *l;
|
|
|
|
if (!s)
|
|
{
|
|
ERR("no state");
|
|
return 0;
|
|
}
|
|
|
|
if (s->aggregator->fetch(s->aggregator, s->input))
|
|
{
|
|
l = eina_list_data_find_list(s->cur_plugins, s->aggregator);
|
|
|
|
if (l && l->prev)
|
|
s->cur_plugins = eina_list_promote_list(s->cur_plugins, l);
|
|
else if (!l)
|
|
s->cur_plugins = eina_list_prepend(s->cur_plugins, s->aggregator);
|
|
}
|
|
else
|
|
{
|
|
s->cur_plugins = eina_list_remove(s->cur_plugins, s->aggregator);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_evry_cb_item_changed(__UNUSED__ void *data, __UNUSED__ int type, void *event)
|
|
{
|
|
Evry_Event_Item_Changed *ev = event;
|
|
Evry_Selector *sel;
|
|
Evry_Item *it = ev->item;
|
|
|
|
if (!it || !it->plugin || !it->plugin->state)
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
sel = it->plugin->state->selector;
|
|
|
|
if (sel->state && sel->state->cur_item == it)
|
|
{
|
|
_evry_selector_update(sel);
|
|
}
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
|
|
Evry_Window *
|
|
evry_show(E_Zone *zone, E_Zone_Edge edge, const char *params)
|
|
{
|
|
Evry_Window *win;
|
|
Evry_Selector *sel;
|
|
|
|
#ifdef CHECK_TIME
|
|
_evry_time = ecore_time_get();
|
|
DBG("_____evry_show______");
|
|
#endif
|
|
|
|
E_OBJECT_CHECK_RETURN(zone, 0);
|
|
E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, 0);
|
|
|
|
if (!(win = _evry_window_new(zone, edge)))
|
|
return NULL;
|
|
|
|
e_win_layer_set(win->ewin, 255);
|
|
ecore_x_netwm_window_type_set(win->ewin->evas_win,
|
|
ECORE_X_WINDOW_TYPE_UTILITY);
|
|
|
|
ecore_evas_name_class_set(win->ewin->ecore_evas, "E", "everything");
|
|
ecore_evas_show(win->ewin->ecore_evas);
|
|
|
|
if (e_grabinput_get(win->ewin->evas_win, 0, win->ewin->evas_win))
|
|
win->grab = 1;
|
|
else
|
|
ERR("could not acquire grab");
|
|
|
|
evry_history_load();
|
|
|
|
if (params)
|
|
win->plugin_dedicated = EINA_TRUE;
|
|
|
|
win->sel_list = E_NEW(Evry_Selector*, 4);
|
|
win->sel_list[3] = NULL;
|
|
win->selectors = win->sel_list;
|
|
_evry_selector_new(win, EVRY_PLUGIN_SUBJECT);
|
|
_evry_selector_new(win, EVRY_PLUGIN_ACTION);
|
|
_evry_selector_new(win, EVRY_PLUGIN_OBJECT);
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_EVENT_KEY_DOWN,
|
|
_evry_cb_key_down, win));
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_X_EVENT_SELECTION_NOTIFY,
|
|
_evry_cb_selection_notify, win));
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, evry_event_handler_add
|
|
(EVRY_EVENT_ITEM_CHANGED,
|
|
_evry_cb_item_changed, win));
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_EVENT_MOUSE_BUTTON_DOWN,
|
|
_evry_cb_mouse, win));
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_EVENT_MOUSE_BUTTON_UP,
|
|
_evry_cb_mouse, win));
|
|
#if 0
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_EVENT_MOUSE_MOVE,
|
|
_evry_cb_mouse, win));
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_EVENT_MOUSE_WHEEL,
|
|
_evry_cb_mouse, win));
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_X_EVENT_MOUSE_IN,
|
|
_evry_cb_mouse_in, win));
|
|
|
|
win->handlers = eina_list_append
|
|
(win->handlers, ecore_event_handler_add
|
|
(ECORE_X_EVENT_MOUSE_OUT,
|
|
_evry_cb_mouse_out, win));
|
|
#endif
|
|
_evry_selector_plugins_get(SUBJ_SEL, NULL, params);
|
|
_evry_selector_update(SUBJ_SEL);
|
|
|
|
windows = eina_list_append(windows, win);
|
|
|
|
if (!evry_conf->hide_list || edge)
|
|
{
|
|
_evry_selector_activate(SUBJ_SEL, 0);
|
|
sel = CUR_SEL;
|
|
|
|
if (sel && sel->state && evry_conf->views)
|
|
{
|
|
if (evry_conf->first_run)
|
|
{
|
|
evry_view_toggle(sel->state, "?");
|
|
evry_conf->first_run = EINA_FALSE;
|
|
}
|
|
|
|
edje_object_signal_emit(win->o_main, "list:e,state,list_show", "e");
|
|
edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e");
|
|
win->visible = EINA_TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_evry_selector_activate(SUBJ_SEL, 0);
|
|
}
|
|
|
|
return win;
|
|
}
|
|
|
|
void
|
|
evry_hide(Evry_Window *win, int clear)
|
|
{
|
|
Ecore_Event_Handler *ev;
|
|
int i;
|
|
|
|
if (!win) return;
|
|
|
|
_evry_state_clear(win);
|
|
|
|
if ((clear && CUR_SEL) &&
|
|
((eina_list_count((SUBJ_SEL)->states) > 1) ||
|
|
(CUR_SEL != SUBJ_SEL) ||
|
|
(((CUR_SEL)->state) &&
|
|
((CUR_SEL)->state->input[0]))))
|
|
{
|
|
int slide = 0;
|
|
Evry_Selector *sel;
|
|
Evry_State *s;
|
|
|
|
if (CUR_SEL != SUBJ_SEL)
|
|
{
|
|
if (CUR_SEL == ACTN_SEL)
|
|
_evry_selectors_switch(win, -1);
|
|
else if (CUR_SEL == OBJ_SEL)
|
|
_evry_selectors_switch(win, 1);
|
|
}
|
|
|
|
/* just to be sure */
|
|
CUR_SEL = SUBJ_SEL;
|
|
|
|
while ((CUR_SEL)->states->next)
|
|
{
|
|
slide = SLIDE_RIGHT;
|
|
_evry_state_pop(CUR_SEL, 1);
|
|
}
|
|
|
|
sel = CUR_SEL;
|
|
s = sel->state;
|
|
_evry_clear(sel);
|
|
_evry_clear(sel);
|
|
|
|
_evry_aggregator_fetch(s);
|
|
_evry_selector_update(sel);
|
|
_evry_update_text_label(s);
|
|
_evry_view_show(win, s->view, slide);
|
|
s->view->update(s->view);
|
|
|
|
return;
|
|
}
|
|
|
|
if (_evry_selectors_shift(win, -1))
|
|
{
|
|
return;
|
|
}
|
|
|
|
win->visible = EINA_FALSE;
|
|
|
|
for (i = 0; win->sel_list[i]; i++)
|
|
_evry_selector_free(win->sel_list[i]);
|
|
|
|
E_FREE(win->sel_list);
|
|
|
|
EINA_LIST_FREE(win->handlers, ev)
|
|
ecore_event_handler_del(ev);
|
|
|
|
if (win->grab)
|
|
e_grabinput_release(win->ewin->evas_win,
|
|
win->ewin->evas_win);
|
|
|
|
windows = eina_list_remove(windows, win);
|
|
|
|
_evry_window_free(win);
|
|
|
|
evry_history_unload();
|
|
|
|
#ifdef CHECK_REFS
|
|
Evry_Item *_it;
|
|
int _cnt = eina_list_count(_refd);
|
|
Eina_List *_l;
|
|
printf("__________________________");
|
|
EINA_LIST_FOREACH(_refd, _l, _it)
|
|
printf("%d %s\n", _it->ref, _it->label);
|
|
printf("sum: %d", _cnt);
|
|
#endif
|
|
}
|
|
|
|
static int
|
|
_evry_selectors_shift(Evry_Window *win, int dir)
|
|
{
|
|
if ((dir > 0) && (win->level == 0))
|
|
{
|
|
void *new_sel;
|
|
Evry_Selector *sel;
|
|
Evry_State *s;
|
|
int i;
|
|
|
|
for (i = 1; i < 3; i++)
|
|
_evry_selector_item_clear(win->selectors[i]);
|
|
|
|
if (!(new_sel = realloc(win->sel_list, sizeof(Evry_Selector*) * 6)))
|
|
return 0;
|
|
|
|
win->sel_list = new_sel;
|
|
|
|
edje_object_signal_emit(win->o_main,
|
|
"e,state,object_selector_hide", "e");
|
|
|
|
win->sel_list[5] = NULL;
|
|
win->selectors = win->sel_list + 2;
|
|
_evry_selector_new(win, EVRY_PLUGIN_ACTION);
|
|
_evry_selector_new(win, EVRY_PLUGIN_OBJECT);
|
|
|
|
CUR_SEL = SUBJ_SEL;
|
|
sel = CUR_SEL;
|
|
|
|
_evry_selector_signal_emit(sel, "e,state,selected");
|
|
|
|
_evry_selector_item_update(SUBJ_SEL);
|
|
_evry_selector_item_update(ACTN_SEL);
|
|
_evry_selector_item_update(OBJ_SEL);
|
|
|
|
/* was checked before. anyway */
|
|
if ((s = sel->state) && (s->cur_item))
|
|
_evry_selector_update_actions(sel);
|
|
|
|
win->level++;
|
|
|
|
return 1;
|
|
}
|
|
else if ((dir < 0) && (win->level > 0))
|
|
{
|
|
_evry_selector_item_clear(SUBJ_SEL);
|
|
_evry_selector_free(ACTN_SEL);
|
|
_evry_selector_free(OBJ_SEL);
|
|
|
|
win->selectors = win->sel_list;
|
|
win->sel_list[3] = NULL;
|
|
CUR_SEL = NULL;
|
|
|
|
edje_object_signal_emit(win->o_main,
|
|
"e,state,object_selector_show", "e");
|
|
_evry_selector_item_update(SUBJ_SEL);
|
|
_evry_selector_item_update(ACTN_SEL);
|
|
_evry_selector_item_update(OBJ_SEL);
|
|
_evry_selector_activate(OBJ_SEL, 0);
|
|
|
|
win->level = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
Evry_Item *
|
|
evry_item_new(Evry_Item *base, Evry_Plugin *p, const char *label,
|
|
Evas_Object *(*icon_get) (Evry_Item *it, Evas *e),
|
|
void (*cb_free) (Evry_Item *item))
|
|
{
|
|
Evry_Item *it;
|
|
if (base)
|
|
{
|
|
it = base;
|
|
}
|
|
else
|
|
{
|
|
it = E_NEW(Evry_Item, 1);
|
|
if (!it) return NULL;
|
|
}
|
|
|
|
if (p && EVRY_ITEM(p)->subtype)
|
|
it->type = EVRY_ITEM(p)->subtype;
|
|
|
|
it->plugin = p;
|
|
|
|
if (label) it->label = eina_stringshare_add(label);
|
|
it->free = cb_free;
|
|
it->icon_get = icon_get;
|
|
|
|
it->ref = 1;
|
|
|
|
#ifdef CHECK_REFS
|
|
_item_cnt++;
|
|
_refd = eina_list_append(_refd, it);
|
|
#endif
|
|
#ifdef PRINT_REFS
|
|
printf("%d, %d\t new : %s\n", it->ref, _item_cnt, it->label);
|
|
#endif
|
|
return it;
|
|
}
|
|
|
|
void
|
|
evry_item_free(Evry_Item *it)
|
|
{
|
|
if (!it) return;
|
|
|
|
it->ref--;
|
|
|
|
#ifdef PRINT_REFS
|
|
printf("%d, %d\t unref: %s\n", it->ref, _item_cnt - 1, it->label);
|
|
#endif
|
|
|
|
if (it->ref > 0) return;
|
|
|
|
#ifdef CHECK_REFS
|
|
_item_cnt--;
|
|
_refd = eina_list_remove(_refd, it);
|
|
#endif
|
|
|
|
IF_RELEASE(it->label);
|
|
IF_RELEASE(it->id);
|
|
IF_RELEASE(it->context);
|
|
IF_RELEASE(it->detail);
|
|
IF_RELEASE(it->icon);
|
|
|
|
if (it->free)
|
|
it->free(it);
|
|
else
|
|
E_FREE(it);
|
|
}
|
|
|
|
void
|
|
evry_item_ref(Evry_Item *it)
|
|
{
|
|
it->ref++;
|
|
#ifdef PRINT_REFS
|
|
printf("%d, %d\t ref : %s\n", it->ref, _item_cnt, it->label);
|
|
#endif
|
|
|
|
}
|
|
|
|
static int
|
|
_evry_selector_update_actions_do(Evry_Selector *sel)
|
|
{
|
|
Evry_State *s;
|
|
Evry_Window *win = sel->win;
|
|
|
|
if (sel->action_timer)
|
|
{
|
|
ecore_timer_del(sel->action_timer);
|
|
sel->action_timer = NULL;
|
|
}
|
|
|
|
if ((s = (SUBJ_SEL)->state))
|
|
_evry_selector_plugins_get(sel, s->cur_item, NULL);
|
|
|
|
_evry_selector_update(sel);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_evry_timer_cb_actions_get(void *data)
|
|
{
|
|
Evry_Selector *sel = data;
|
|
Evry_Window *win = sel->win;
|
|
Evry_State *s;
|
|
|
|
_evry_selector_update_actions_do(sel);
|
|
|
|
if ((CUR_SEL == sel) && (s = sel->state))
|
|
{
|
|
if (_evry_view_update(win, s))
|
|
_evry_view_show(win, s->view, 0);
|
|
}
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
}
|
|
|
|
static void
|
|
_evry_selector_update_actions(Evry_Selector *sel)
|
|
{
|
|
if (sel->action_timer)
|
|
ecore_timer_del(sel->action_timer);
|
|
|
|
sel->action_timer = ecore_timer_add(0.1, _evry_timer_cb_actions_get, sel);
|
|
}
|
|
|
|
void
|
|
evry_item_select(const Evry_State *state, Evry_Item *it)
|
|
{
|
|
Evry_State *s = (Evry_State *)state;
|
|
Evry_Selector *sel;
|
|
Evry_Window *win;
|
|
|
|
if ((!s) || (s->delete_me))
|
|
return;
|
|
|
|
sel = s->selector;
|
|
win = sel->win;
|
|
|
|
s->plugin_auto_selected = EINA_FALSE;
|
|
s->item_auto_selected = EINA_FALSE;
|
|
|
|
_evry_item_sel(s, it);
|
|
|
|
if (s == sel->state)
|
|
{
|
|
_evry_selector_update(sel);
|
|
|
|
if (CUR_SEL == SUBJ_SEL)
|
|
_evry_selector_update_actions(ACTN_SEL);
|
|
|
|
if (CUR_SEL == ACTN_SEL)
|
|
{
|
|
while (OBJ_SEL->state)
|
|
_evry_state_pop(OBJ_SEL, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
evry_item_mark(const Evry_State *state, Evry_Item *it, Eina_Bool mark)
|
|
{
|
|
Evry_State *s = (Evry_State *)state;
|
|
|
|
if ((!s) || (s->delete_me))
|
|
return;
|
|
|
|
if (mark && !it->marked)
|
|
{
|
|
it->marked = EINA_TRUE;
|
|
s->sel_items = eina_list_append(s->sel_items, it);
|
|
}
|
|
else if (it->marked)
|
|
{
|
|
it->marked = EINA_FALSE;
|
|
s->sel_items = eina_list_remove(s->sel_items, it);
|
|
}
|
|
}
|
|
|
|
void
|
|
evry_plugin_update(Evry_Plugin *p, int action)
|
|
{
|
|
Evry_State *s;
|
|
Evry_Selector *sel;
|
|
Evry_Window *win;
|
|
|
|
if (!(s = p->state) || (s->delete_me))
|
|
return;
|
|
|
|
if (!(sel = s->selector))
|
|
return;
|
|
|
|
if (!(win = sel->win))
|
|
return;
|
|
|
|
if (sel->state->request != p->request)
|
|
return;
|
|
|
|
DBG("update %d %d %s", s->request, p->request, p->name);
|
|
|
|
if (action == EVRY_UPDATE_ADD)
|
|
{
|
|
/* clear marked items */
|
|
if (s->sel_items)
|
|
{
|
|
eina_list_free(s->sel_items);
|
|
s->sel_items = NULL;
|
|
}
|
|
|
|
if ((!p->items) && (!s->trigger_active))
|
|
{
|
|
/* remove plugin */
|
|
if (!(eina_list_data_find(s->cur_plugins, p)))
|
|
return;
|
|
|
|
s->cur_plugins = eina_list_remove(s->cur_plugins, p);
|
|
|
|
if (p == s->plugin)
|
|
_evry_plugin_select(s, NULL);
|
|
}
|
|
else
|
|
{
|
|
/* add plugin to current plugins*/
|
|
_evry_plugin_list_insert(s, p);
|
|
}
|
|
|
|
_evry_aggregator_fetch(s);
|
|
|
|
/* select first plugin */
|
|
if ((!s->plugin) || (s->plugin_auto_selected) ||
|
|
!(eina_list_data_find(s->cur_plugins, s->plugin)))
|
|
{
|
|
_evry_plugin_select(s, NULL);
|
|
}
|
|
|
|
if ((s->plugin && (sel->state == s)) &&
|
|
/* plugin is current */
|
|
((s->plugin == p) ||
|
|
/* plugin items are shown in aggregator */
|
|
((s->plugin == s->aggregator) && p->config->aggregate)))
|
|
{
|
|
_evry_selector_update(sel);
|
|
|
|
if (_evry_view_update(win, s))
|
|
/* XXX when there is a case where view disappears
|
|
check this one! is swallow always visible ? */
|
|
_evry_view_show(win, s->view, 0);
|
|
}
|
|
|
|
/* switch back to subject selector when no current items */
|
|
if ((sel == SUBJ_SEL) &&
|
|
(!(s->plugin) || !(s->plugin->items)) &&
|
|
(CUR_SEL == ACTN_SEL))
|
|
{
|
|
_evry_selectors_switch(win, -1);
|
|
_evry_clear(SUBJ_SEL);
|
|
}
|
|
}
|
|
else if (action == EVRY_UPDATE_REFRESH)
|
|
{
|
|
_evry_view_clear(s);
|
|
_evry_view_update(win, s);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_evry_list_win_show(Evry_Window *win)
|
|
{
|
|
if (win->visible) return;
|
|
|
|
win->visible = EINA_TRUE;
|
|
_evry_list_win_update((CUR_SEL)->state);
|
|
|
|
edje_object_signal_emit(win->o_main, "list:e,state,list_show", "e");
|
|
edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e");
|
|
}
|
|
|
|
static void
|
|
_evry_list_win_hide(Evry_Window *win)
|
|
{
|
|
Evry_Selector *sel = CUR_SEL;
|
|
|
|
if (!win->visible)
|
|
return;
|
|
|
|
if (!evry_conf->hide_list)
|
|
return;
|
|
|
|
if (sel->state)
|
|
_evry_view_clear(sel->state);
|
|
|
|
win->visible = EINA_FALSE;
|
|
edje_object_signal_emit(win->o_main, "list:e,state,list_hide", "e");
|
|
|
|
if (evry_conf->hide_input && (!(sel->state) || (sel->state->input[0])))
|
|
edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e");
|
|
}
|
|
|
|
static void
|
|
_evry_cb_win_delete(E_Win *ewin)
|
|
{
|
|
Evry_Window *win = ewin->data;
|
|
evry_hide(win, 0);
|
|
}
|
|
|
|
static void
|
|
_evry_cb_win_move(E_Win *ewin __UNUSED__)
|
|
{
|
|
/* Evry_Window *win = ewin->data; */
|
|
/* evas_object_resize(win->o_main, ewin->w, ewin->h); */
|
|
/* if (win->input_window)
|
|
* ecore_x_window_move(win->input_window, win->ewin->x, win->ewin->y); */
|
|
}
|
|
|
|
static void
|
|
_evry_cb_win_resize(E_Win *ewin)
|
|
{
|
|
Evry_Window *win = ewin->data;
|
|
evas_object_resize(win->o_main, ewin->w, ewin->h);
|
|
}
|
|
|
|
static Evry_Window *
|
|
_evry_window_new(E_Zone *zone, E_Zone_Edge edge)
|
|
{
|
|
int x, y, mw, mh, h, w;
|
|
Evry_Window *win;
|
|
Evas_Object *o;
|
|
const char *tmp;
|
|
int offset_s = 0;
|
|
const char *shape_option;
|
|
|
|
win = E_NEW(Evry_Window, 1);
|
|
win->ewin = e_win_new(zone->container);
|
|
e_win_borderless_set(win->ewin, 1);
|
|
e_win_no_remember_set(win->ewin, 1);
|
|
e_win_placed_set(win->ewin, 1);
|
|
ecore_evas_override_set(win->ewin->ecore_evas, 1);
|
|
win->evas = e_win_evas_get(win->ewin);
|
|
win->zone = zone;
|
|
win->ewin->data = win;
|
|
|
|
o = edje_object_add(win->evas);
|
|
win->o_main = o;
|
|
e_theme_edje_object_set(o, "base/theme/modules/everything",
|
|
"e/modules/everything/main");
|
|
|
|
if ((shape_option = edje_object_data_get(o, "shaped")) &&
|
|
(!strcmp(shape_option, "1")))
|
|
{
|
|
win->shaped = EINA_TRUE;
|
|
|
|
if (e_config->use_composite)
|
|
{
|
|
ecore_evas_alpha_set(win->ewin->ecore_evas, 1);
|
|
win->ewin->evas_win = ecore_evas_software_x11_window_get(win->ewin->ecore_evas);
|
|
edje_object_signal_emit(o, "e,state,composited", "e");
|
|
edje_object_signal_emit(o, "list:e,state,composited", "e");
|
|
edje_object_message_signal_process(o);
|
|
edje_object_calc_force(o);
|
|
|
|
tmp = edje_object_data_get(o, "shadow_offset");
|
|
offset_s = tmp ? atoi(tmp) : 0;
|
|
}
|
|
else
|
|
ecore_evas_shaped_set(win->ewin->ecore_evas, 1);
|
|
}
|
|
|
|
edje_object_size_min_calc(o, &mw, &mh);
|
|
|
|
if (edge == E_ZONE_EDGE_NONE)
|
|
{
|
|
w = evry_conf->width;
|
|
h = evry_conf->height;
|
|
}
|
|
else
|
|
{
|
|
w = evry_conf->edge_width;
|
|
h = evry_conf->edge_height;
|
|
}
|
|
e_win_size_min_set(win->ewin, mw, mh);
|
|
|
|
evry_conf->min_w = mw;
|
|
if (w > mw) mw = w;
|
|
|
|
evry_conf->min_h = mh;
|
|
if (h > mh) mh = h;
|
|
|
|
if (edge == E_ZONE_EDGE_NONE)
|
|
{
|
|
mw += offset_s*2;
|
|
mh += offset_s*2;
|
|
|
|
x = (zone->x + (zone->w * evry_conf->rel_x)) - (mw / 2);
|
|
y = (zone->y + (zone->h * evry_conf->rel_y)) - (mh / 2);
|
|
}
|
|
else
|
|
{
|
|
int to_side = 0;
|
|
|
|
switch (edge)
|
|
{
|
|
case E_ZONE_EDGE_TOP_LEFT:
|
|
x = to_side - offset_s;
|
|
y = to_side - offset_s;
|
|
break;
|
|
case E_ZONE_EDGE_TOP_RIGHT:
|
|
x = zone->w - (mw + offset_s + to_side);
|
|
y = to_side - offset_s;
|
|
break;
|
|
case E_ZONE_EDGE_BOTTOM_RIGHT:
|
|
x = zone->w - (mw + offset_s + to_side);
|
|
y = zone->h - (mh + offset_s + to_side);
|
|
break;
|
|
case E_ZONE_EDGE_BOTTOM_LEFT:
|
|
x = to_side - offset_s;
|
|
y = zone->h - (mh + offset_s + to_side);
|
|
break;
|
|
|
|
default:
|
|
mw += offset_s*2;
|
|
mh += offset_s*2;
|
|
x = (zone->w * evry_conf->rel_x) - (mw / 2);
|
|
y = (zone->h * evry_conf->rel_y) - (mh / 2);
|
|
break;
|
|
}
|
|
|
|
x += zone->x;
|
|
y += zone->y;
|
|
|
|
mw += offset_s*2;
|
|
mh += offset_s*2;
|
|
}
|
|
|
|
e_win_move_resize(win->ewin, x, y, mw, mh);
|
|
win->ewin->w = mw;
|
|
win->ewin->h = mh;
|
|
|
|
o = win->o_main;
|
|
evas_object_move(o, 0, 0);
|
|
evas_object_resize(o, mw, mh);
|
|
evas_object_show(o);
|
|
|
|
evas_event_feed_mouse_in(win->evas, ecore_x_current_time_get(), NULL);
|
|
evas_event_feed_mouse_move(win->evas, -1000000, -1000000,
|
|
ecore_x_current_time_get(), NULL);
|
|
|
|
e_win_delete_callback_set(win->ewin, _evry_cb_win_delete);
|
|
e_win_resize_callback_set(win->ewin, _evry_cb_win_resize);
|
|
e_win_move_callback_set(win->ewin, _evry_cb_win_move);
|
|
|
|
return win;
|
|
}
|
|
|
|
#if 0
|
|
static void
|
|
_evry_cb_drag_finished(E_Drag *drag, int dropped)
|
|
{
|
|
E_FREE(drag->data);
|
|
}
|
|
#endif
|
|
|
|
static Eina_Bool
|
|
_evry_cb_mouse(void *data, int type, void *event)
|
|
{
|
|
Ecore_Event_Mouse_Button *ev;
|
|
Evry_Window *win = data;
|
|
E_Win *w;
|
|
|
|
ev = event;
|
|
|
|
if (!win->grab)
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if (ev->event_window != win->ewin->evas_win)
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
w = win->ewin;
|
|
|
|
#if 0
|
|
if (type == ECORE_EVENT_MOUSE_MOVE)
|
|
{
|
|
Ecore_Event_Mouse_Move *ev = event;
|
|
Evry_State *s;
|
|
|
|
if ((win->mouse_button == 3) &&
|
|
(s = (CUR_SEL)->state) && (s->cur_item) &&
|
|
(CHECK_TYPE(s->cur_item, EVRY_TYPE_FILE)) &&
|
|
(!E_INSIDE(ev->x, ev->y,
|
|
win->zone->x,
|
|
win->zone->y,
|
|
w->w, w->h)))
|
|
{
|
|
const char *drag_types[] = { "text/uri-list" };
|
|
E_Drag *d;
|
|
Evas_Object *o;
|
|
const char *uri;
|
|
int s_len, sel_length = 0;
|
|
char *tmp, *sel = NULL;
|
|
|
|
GET_FILE(file, s->cur_item);
|
|
|
|
if (!(uri = evry_file_url_get(file)))
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
s_len = strlen(uri);
|
|
if (!(tmp = realloc(sel, sel_length + s_len + 2 + 1)))
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
sel = tmp;
|
|
memcpy(sel + sel_length, uri, s_len);
|
|
memcpy(sel + sel_length + s_len, "\r\n", 2);
|
|
sel_length += s_len + 2;
|
|
|
|
d = e_drag_new(e_container_current_get(e_manager_current_get()),
|
|
ev->x, ev->y,
|
|
drag_types, 1, sel, sel_length, NULL,
|
|
_evry_cb_drag_finished);
|
|
e_drag_resize(d, 128, 128);
|
|
o = evry_util_icon_get(s->cur_item, e_drag_evas_get(d));
|
|
e_drag_object_set(d, o);
|
|
e_drag_xdnd_start(d, ev->x, ev->y);
|
|
|
|
evry_hide(win, 0);
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
}
|
|
else if (type == ECORE_EVENT_MOUSE_WHEEL)
|
|
{
|
|
Ecore_Event_Mouse_Wheel *ev = event;
|
|
}
|
|
else
|
|
#endif
|
|
if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
|
|
{
|
|
win->mouse_out = 0;
|
|
|
|
if (!E_INSIDE(ev->x, ev->y, 0, 0, w->w, w->h))
|
|
{
|
|
win->mouse_out = 1;
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
|
|
win->mouse_button = ev->buttons;
|
|
}
|
|
else if (type == ECORE_EVENT_MOUSE_BUTTON_UP)
|
|
{
|
|
win->mouse_button = 0;
|
|
|
|
if (win->mouse_out &&
|
|
!E_INSIDE(ev->x, ev->y, 0, 0, w->w, w->h))
|
|
{
|
|
evry_hide(win, 0);
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
}
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
|
|
static void
|
|
_evry_window_free(Evry_Window *win)
|
|
{
|
|
if (win->ewin->border)
|
|
ecore_x_window_hide(win->ewin->border->win);
|
|
else
|
|
ecore_x_window_hide(win->ewin->evas_win);
|
|
|
|
evas_event_freeze(win->evas);
|
|
evas_object_del(win->o_main);
|
|
e_object_del(E_OBJECT(win->ewin));
|
|
E_FREE(win);
|
|
}
|
|
|
|
static void
|
|
_evry_selector_cb_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
|
|
{
|
|
Evas_Event_Mouse_Down *ev = event_info;
|
|
Evry_Selector *sel = data;
|
|
|
|
if (ev->button == 1)
|
|
{
|
|
if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
|
|
evry_plugin_action(sel->win, 1);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_evry_selector_cb_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
|
|
{
|
|
Evas_Event_Mouse_Wheel *ev = event_info;
|
|
Evry_Selector *sel = data;
|
|
Evry_Window *win = sel->win;
|
|
|
|
if (ev->z > 0)
|
|
{
|
|
/* FIXME dont loose selector 2 state until state 0 changed: */
|
|
if (CUR_SEL != OBJ_SEL)
|
|
_evry_selectors_switch(sel->win, 1);
|
|
}
|
|
else if (ev->z < 0)
|
|
{
|
|
_evry_selectors_switch(sel->win, -1);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_evry_selector_cb_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
|
|
{
|
|
Evas_Event_Mouse_Up *ev = event_info;
|
|
Evry_Selector *sel = data;
|
|
Evry_Window *win = sel->win;
|
|
|
|
if (sel == CUR_SEL)
|
|
return;
|
|
|
|
if (ev->button == 3)
|
|
{
|
|
evry_plugin_action(win, 0);
|
|
}
|
|
else if (ev->button == 1)
|
|
{
|
|
if (sel == SUBJ_SEL)
|
|
{
|
|
if (CUR_SEL == ACTN_SEL)
|
|
_evry_selectors_switch(win, -1);
|
|
else
|
|
_evry_selectors_switch(win, 1);
|
|
}
|
|
|
|
else if (sel == ACTN_SEL)
|
|
{
|
|
if (CUR_SEL == SUBJ_SEL)
|
|
_evry_selectors_switch(win, 1);
|
|
else
|
|
_evry_selectors_switch(win, -1);
|
|
}
|
|
else if (sel == OBJ_SEL)
|
|
{
|
|
if (CUR_SEL == ACTN_SEL)
|
|
_evry_selectors_switch(win, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Evry_Selector *
|
|
_evry_selector_new(Evry_Window *win, int type)
|
|
{
|
|
Plugin_Config *pc;
|
|
Eina_List *l, *pcs = NULL;
|
|
Evry_Selector *sel = E_NEW(Evry_Selector, 1);
|
|
Evas_Object *o = NULL;
|
|
|
|
sel->aggregator = evry_aggregator_new(win, type);
|
|
|
|
if (type == EVRY_PLUGIN_SUBJECT)
|
|
{
|
|
pcs = evry_conf->conf_subjects;
|
|
sel->edje_part = "subject_selector";
|
|
}
|
|
else if (type == EVRY_PLUGIN_ACTION)
|
|
{
|
|
pcs = evry_conf->conf_actions;
|
|
sel->edje_part = "action_selector";
|
|
}
|
|
else if (type == EVRY_PLUGIN_OBJECT)
|
|
{
|
|
pcs = evry_conf->conf_objects;
|
|
sel->edje_part = "object_selector";
|
|
}
|
|
|
|
if ((o = edje_object_part_swallow_get(win->o_main, sel->edje_part)))
|
|
{
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
|
|
_evry_selector_cb_down, sel);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
|
|
_evry_selector_cb_up, sel);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL,
|
|
_evry_selector_cb_wheel, sel);
|
|
}
|
|
|
|
EINA_LIST_FOREACH(pcs, l, pc)
|
|
{
|
|
if (!pc->enabled && !win->plugin_dedicated) continue;
|
|
if (!pc->plugin) continue;
|
|
if (pc->plugin == sel->aggregator) continue;
|
|
sel->plugins = eina_list_append(sel->plugins, pc->plugin);
|
|
}
|
|
|
|
win->selectors[type] = sel;
|
|
sel->win = win;
|
|
|
|
return sel;
|
|
}
|
|
|
|
static void
|
|
_evry_selector_free(Evry_Selector *sel)
|
|
{
|
|
Evry_Window *win = sel->win;
|
|
|
|
_evry_selector_item_clear(sel);
|
|
|
|
if (win->visible && (sel == CUR_SEL))
|
|
_evry_view_clear(sel->state);
|
|
|
|
while (sel->states)
|
|
_evry_state_pop(sel, 1);
|
|
|
|
EVRY_PLUGIN_FREE(sel->aggregator);
|
|
|
|
if (sel->plugins) eina_list_free(sel->plugins);
|
|
|
|
if (sel->update_timer)
|
|
ecore_timer_del(sel->update_timer);
|
|
|
|
if (sel->action_timer)
|
|
ecore_timer_del(sel->action_timer);
|
|
|
|
E_FREE(sel);
|
|
}
|
|
|
|
static void
|
|
_evry_selector_signal_emit(Evry_Selector *sel, const char *msg)
|
|
{
|
|
Evry_Window *win = sel->win;
|
|
char buf[128];
|
|
snprintf(buf, sizeof(buf), "%s:%s", sel->edje_part, msg);
|
|
edje_object_signal_emit(win->o_main, buf, "e");
|
|
}
|
|
|
|
static void
|
|
_evry_selector_label_set(Evry_Selector *sel, const char *part, const char *label)
|
|
{
|
|
Evry_Window *win = sel->win;
|
|
char buf[128];
|
|
snprintf(buf, sizeof(buf), "%s:%s", sel->edje_part, part);
|
|
edje_object_part_text_set(win->o_main, buf, label);
|
|
}
|
|
|
|
static void
|
|
_evry_selector_activate(Evry_Selector *sel, int slide)
|
|
{
|
|
Evry_Window *win = sel->win;
|
|
Evry_State *s;
|
|
|
|
if (CUR_SEL)
|
|
{
|
|
Evry_Selector *cur = CUR_SEL;
|
|
_evry_selector_signal_emit(cur, "e,state,unselected");
|
|
|
|
if (cur->state && cur->state->view)
|
|
_evry_view_hide(win, cur->state->view, slide);
|
|
|
|
if (!slide && evry_conf->hide_list)
|
|
_evry_list_win_hide(win);
|
|
}
|
|
|
|
if (!sel)
|
|
{
|
|
ERR("selector == NULL");
|
|
return;
|
|
}
|
|
|
|
CUR_SEL = sel;
|
|
|
|
_evry_selector_signal_emit(sel, "e,state,selected");
|
|
|
|
/* do delayed actions fetch now */
|
|
if (sel->action_timer)
|
|
_evry_selector_update_actions_do(sel);
|
|
|
|
if ((s = sel->state))
|
|
{
|
|
_evry_update_text_label(s);
|
|
|
|
if (s->cur_item)
|
|
_evry_selector_label_set(sel, "e.text.plugin",
|
|
EVRY_ITEM(s->cur_item->plugin)->label);
|
|
|
|
if (_evry_view_create(s))
|
|
{
|
|
_evry_view_show(win, s->view, slide);
|
|
s->view->update(s->view);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
_evry_selector_thumb_gen(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
|
{
|
|
Evas_Coord w, h;
|
|
Evry_Selector *sel = data;
|
|
Evry_Window *win = sel->win;
|
|
char buf[64];
|
|
|
|
if (sel->o_icon)
|
|
{
|
|
evas_object_del(sel->o_icon);
|
|
sel->o_icon = NULL;
|
|
}
|
|
|
|
e_icon_size_get(sel->o_thumb, &w, &h);
|
|
edje_extern_object_aspect_set(sel->o_thumb, EDJE_ASPECT_CONTROL_BOTH, w, h);
|
|
|
|
snprintf(buf, sizeof(buf), "%s:e.swallow.thumb", sel->edje_part);
|
|
edje_object_part_swallow(win->o_main, buf, sel->o_thumb);
|
|
|
|
evas_object_show(sel->o_thumb);
|
|
_evry_selector_signal_emit(sel, "e,action,thumb,show");
|
|
/* edje_object_signal_emit(sel->o_main, "e,action,thumb,show", "e"); */
|
|
sel->do_thumb = EINA_FALSE;
|
|
}
|
|
|
|
static int
|
|
_evry_selector_thumb(Evry_Selector *sel, const Evry_Item *it)
|
|
{
|
|
Evry_Window *win = sel->win;
|
|
char *suffix = NULL;
|
|
|
|
if (sel->do_thumb)
|
|
e_thumb_icon_end(sel->o_thumb);
|
|
|
|
if (sel->o_thumb)
|
|
evas_object_del(sel->o_thumb);
|
|
sel->o_thumb = NULL;
|
|
|
|
if (it->type != EVRY_TYPE_FILE) return 0;
|
|
|
|
GET_FILE(file, it);
|
|
|
|
if (!file->mime)
|
|
return 0;
|
|
|
|
if (!(evry_file_path_get(file)))
|
|
return 0;
|
|
|
|
if ((!strncmp(file->mime, "image/", 6)) ||
|
|
((suffix = strrchr(file->path, '.')) && (!strncmp(suffix, ".edj", 4))))
|
|
{
|
|
sel->o_thumb = e_thumb_icon_add(win->evas);
|
|
e_thumb_icon_size_set(sel->o_thumb, 128, 128);
|
|
evas_object_smart_callback_add(sel->o_thumb, "e_thumb_gen",
|
|
_evry_selector_thumb_gen, sel);
|
|
if (suffix)
|
|
{
|
|
e_thumb_icon_file_set(sel->o_thumb, file->path, "e/desktop/background");
|
|
e_thumb_icon_size_set(sel->o_thumb, 128, 80);
|
|
}
|
|
else
|
|
e_thumb_icon_file_set(sel->o_thumb, file->path, NULL);
|
|
|
|
e_thumb_icon_begin(sel->o_thumb);
|
|
sel->do_thumb = EINA_TRUE;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
_evry_selector_item_clear(Evry_Selector *sel)
|
|
{
|
|
if (sel->o_icon)
|
|
{
|
|
evas_object_del(sel->o_icon);
|
|
sel->o_icon = NULL;
|
|
}
|
|
|
|
if (sel->o_thumb)
|
|
{
|
|
if (sel->do_thumb)
|
|
e_thumb_icon_end(sel->o_thumb);
|
|
|
|
evas_object_del(sel->o_thumb);
|
|
sel->o_thumb = NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_evry_selector_item_update(Evry_Selector *sel)
|
|
{
|
|
Evry_State *s = sel->state;
|
|
Evry_Item *it = NULL;
|
|
Evas_Object *o = NULL;
|
|
Evry_Window *win = sel->win;
|
|
|
|
_evry_selector_item_clear(sel);
|
|
|
|
if ((!s) || !(s->cur_item))
|
|
{
|
|
/* no items for this state - clear selector */
|
|
_evry_selector_label_set(sel, "e.text.label","");
|
|
|
|
if (sel == CUR_SEL && s && s->plugin)
|
|
_evry_selector_label_set(sel, "e.text.plugin",
|
|
EVRY_ITEM(s->plugin)->label);
|
|
else
|
|
_evry_selector_label_set(sel, "e.text.plugin", "");
|
|
|
|
if (!s) return;
|
|
}
|
|
|
|
if ((it = s->cur_item))
|
|
{
|
|
_evry_selector_label_set(sel, "e.text.label", it->label);
|
|
_evry_selector_label_set(sel, "e.text.plugin",
|
|
EVRY_ITEM(it->plugin)->label);
|
|
|
|
if (!_evry_selector_thumb(sel, it))
|
|
{
|
|
o = evry_util_icon_get(it, win->evas);
|
|
|
|
if ((!o) && it->plugin)
|
|
o = evry_util_icon_get(EVRY_ITEM(it->plugin), win->evas);
|
|
}
|
|
}
|
|
|
|
if ((!o) && (s->plugin && (EVRY_ITEM(s->plugin)->icon)))
|
|
{
|
|
o = evry_icon_theme_get(EVRY_ITEM(s->plugin)->icon, win->evas);
|
|
}
|
|
|
|
if (o)
|
|
{
|
|
char buf[64];
|
|
snprintf(buf, sizeof(buf), "%s:e.swallow.icons", sel->edje_part);
|
|
edje_object_part_swallow(win->o_main, buf, o);
|
|
evas_object_show(o);
|
|
sel->o_icon = o;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_evry_selector_update(Evry_Selector *sel)
|
|
{
|
|
Evry_State *s = sel->state;
|
|
Evry_Item *it = NULL;
|
|
Eina_Bool item_changed = EINA_FALSE;
|
|
Evry_Window *win = sel->win;
|
|
|
|
DBG("%p", sel);
|
|
|
|
if (!s)
|
|
{
|
|
_evry_selector_item_update(sel);
|
|
return;
|
|
}
|
|
|
|
if ((it = s->cur_item))
|
|
{
|
|
if (!s->plugin || !eina_list_data_find_list(s->plugin->items, it))
|
|
{
|
|
_evry_item_desel(s);
|
|
item_changed = EINA_TRUE;
|
|
}
|
|
}
|
|
|
|
/* get first item */
|
|
if (s->plugin && ((!s->cur_item) || s->item_auto_selected))
|
|
{
|
|
it = eina_list_data_get(s->plugin->items);
|
|
s->item_auto_selected = EINA_TRUE;
|
|
if (!s->cur_plugins || (it != s->cur_item))
|
|
item_changed = EINA_TRUE;
|
|
|
|
_evry_item_sel(s, it);
|
|
}
|
|
|
|
_evry_selector_item_update(sel);
|
|
|
|
if ((sel == SUBJ_SEL) && (item_changed))
|
|
_evry_selector_update_actions(ACTN_SEL);
|
|
}
|
|
|
|
static void
|
|
_evry_list_win_update(Evry_State *s)
|
|
{
|
|
Evry_Window *win = s->selector->win;
|
|
|
|
if (s != (CUR_SEL)->state) return;
|
|
if (!win->visible) return;
|
|
|
|
if (_evry_view_update(win, s))
|
|
_evry_view_show(win, s->view, 0);
|
|
}
|
|
|
|
static int
|
|
_evry_selector_plugins_get(Evry_Selector *sel, Evry_Item *it, const char *plugin_name)
|
|
{
|
|
Eina_List *l, *plugins = NULL;
|
|
Evry_Plugin *p, *pp;
|
|
Evry_Window *win = sel->win;
|
|
Evry_Action *act = NULL;
|
|
|
|
while (sel->state)
|
|
_evry_state_pop(sel, 1);
|
|
|
|
if ((sel != SUBJ_SEL) && (!it))
|
|
return 0;
|
|
|
|
if (it && CHECK_TYPE(it, EVRY_TYPE_ACTION))
|
|
act = (Evry_Action *)it;
|
|
|
|
EINA_LIST_FOREACH(sel->plugins, l, p)
|
|
{
|
|
if (plugin_name && strcmp(plugin_name, p->name))
|
|
continue;
|
|
|
|
if (act && (!CHECK_SUBTYPE(p, act->it2.type)))
|
|
continue;
|
|
|
|
if (p->begin && (pp = p->begin(p, it)))
|
|
plugins = eina_list_append(plugins, pp);
|
|
}
|
|
|
|
_evry_state_new(sel, plugins);
|
|
|
|
if (plugins)
|
|
_evry_matches_update(sel, 1);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static Evry_State *
|
|
_evry_state_new(Evry_Selector *sel, Eina_List *plugins)
|
|
{
|
|
Evry_State *s = E_NEW(Evry_State, 1);
|
|
Eina_List *l;
|
|
Evry_Plugin *p;
|
|
|
|
if (!s) return NULL;
|
|
|
|
s->inp = malloc(INPUTLEN);
|
|
s->inp[0] = 0;
|
|
s->input = s->inp;
|
|
s->plugins = plugins;
|
|
s->selector = sel;
|
|
|
|
sel->states = eina_list_prepend(sel->states, s);
|
|
sel->state = s;
|
|
|
|
p = sel->aggregator->begin(sel->aggregator, NULL);
|
|
s->plugins = eina_list_append(s->plugins, p);
|
|
s->aggregator = p;
|
|
|
|
EINA_LIST_FOREACH(s->plugins, l, p)
|
|
p->state = s;
|
|
|
|
return s;
|
|
}
|
|
|
|
static void
|
|
_evry_state_pop(Evry_Selector *sel, int immediate)
|
|
{
|
|
Evry_Plugin *p;
|
|
Evry_State *prev;
|
|
Evry_Window *win = sel->win;
|
|
Evry_State *s = sel->state;
|
|
|
|
_evry_item_desel(s);
|
|
|
|
if (sel->update_timer)
|
|
{
|
|
ecore_timer_del(sel->update_timer);
|
|
sel->update_timer = NULL;
|
|
}
|
|
|
|
if (sel->action_timer)
|
|
{
|
|
ecore_timer_del(sel->action_timer);
|
|
sel->action_timer = NULL;
|
|
}
|
|
|
|
if (s->view)
|
|
{
|
|
if (immediate)
|
|
{
|
|
s->view->destroy(s->view);
|
|
}
|
|
else
|
|
{
|
|
_evry_view_hide(win, s->view, SLIDE_RIGHT);
|
|
/* XXX delay free state? is it possible that
|
|
view can receive events here? */
|
|
s->delete_me = EINA_TRUE;
|
|
}
|
|
}
|
|
|
|
if (s->sel_items)
|
|
eina_list_free(s->sel_items);
|
|
|
|
sel->states = eina_list_remove_list(sel->states, sel->states);
|
|
prev = eina_list_data_get(sel->states);
|
|
|
|
EINA_LIST_FREE(s->plugins, p)
|
|
{
|
|
/* skip non top-level plugins */
|
|
if (prev && eina_list_data_find(prev->plugins, p))
|
|
{
|
|
p->state = prev;
|
|
continue;
|
|
}
|
|
EVRY_ITEM_FREE(p);
|
|
}
|
|
|
|
if (!s->delete_me)
|
|
{
|
|
E_FREE(s->inp);
|
|
E_FREE(s);
|
|
}
|
|
|
|
sel->state = prev;
|
|
}
|
|
|
|
int
|
|
evry_state_push(Evry_Selector *sel, Eina_List *plugins)
|
|
{
|
|
Evry_State *s, *new_state;
|
|
Eina_List *l;
|
|
Evry_Plugin *p;
|
|
Evry_View *view = NULL;
|
|
Evry_Window *win = sel->win;
|
|
|
|
s = sel->state;
|
|
|
|
if (!(new_state = _evry_state_new(sel, plugins)))
|
|
{
|
|
DBG("no new state");
|
|
return 0;
|
|
}
|
|
|
|
EINA_LIST_FOREACH(plugins, l, p)
|
|
p->state = new_state;
|
|
|
|
if (s && s->view)
|
|
{
|
|
_evry_view_hide(win, s->view, SLIDE_LEFT);
|
|
view = s->view;
|
|
}
|
|
|
|
_evry_matches_update(sel, 1);
|
|
s = new_state;
|
|
|
|
_evry_selector_update(sel);
|
|
|
|
if (view && win->visible)
|
|
{
|
|
s->view = view->create(view, s, win->o_main);
|
|
if (s->view)
|
|
{
|
|
s->view->state = s;
|
|
_evry_view_show(win, s->view, SLIDE_LEFT);
|
|
s->view->update(s->view);
|
|
}
|
|
}
|
|
|
|
_evry_update_text_label(sel->state);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
evry_browse_item(Evry_Item *it)
|
|
{
|
|
Evry_State *s, *new_state;
|
|
Evry_Selector *sel;
|
|
Eina_List *l, *plugins = NULL;
|
|
Evry_Plugin *p, *pp, *pref = NULL;
|
|
Evry_View *view = NULL;
|
|
int browse_aggregator = 0;
|
|
Evry_Window *win;
|
|
|
|
if (!(it) || !(it->plugin) || !(it->browseable))
|
|
{
|
|
DBG("no item");
|
|
return 0;
|
|
}
|
|
|
|
if (!(s = it->plugin->state))
|
|
{
|
|
DBG("no state");
|
|
return 0;
|
|
}
|
|
|
|
sel = s->selector;
|
|
win = sel->win;
|
|
|
|
/* aggregator */
|
|
if (CHECK_TYPE(it, EVRY_TYPE_PLUGIN))
|
|
{
|
|
browse_aggregator = 1;
|
|
plugins = eina_list_append(plugins, it);
|
|
}
|
|
else
|
|
{
|
|
if ((it->plugin->browse) &&
|
|
(pp = it->plugin->browse(it->plugin, it)))
|
|
{
|
|
plugins = eina_list_append(plugins, pp);
|
|
pref = pp;
|
|
}
|
|
|
|
EINA_LIST_FOREACH(sel->plugins, l, p)
|
|
{
|
|
if (!p->browse)
|
|
continue;
|
|
|
|
if ((pref) && (!strcmp(p->name, pref->name)))
|
|
continue;
|
|
|
|
if ((pp = p->browse(p, it)))
|
|
plugins = eina_list_append(plugins, pp);
|
|
}
|
|
}
|
|
|
|
if (!(plugins))
|
|
{
|
|
DBG("no plugins");
|
|
return 0;
|
|
}
|
|
|
|
if (!(new_state = _evry_state_new(sel, plugins)))
|
|
{
|
|
DBG("no new state");
|
|
return 0;
|
|
}
|
|
|
|
if (s->view)
|
|
{
|
|
_evry_view_hide(win, s->view, SLIDE_LEFT);
|
|
view = s->view;
|
|
}
|
|
|
|
if (browse_aggregator)
|
|
{
|
|
it->hi = NULL;
|
|
|
|
if (!EVRY_PLUGIN(it)->items)
|
|
{
|
|
evry_history_item_add(it, NULL, s->input);
|
|
s = new_state;
|
|
EVRY_PLUGIN(it)->state = s;
|
|
_evry_matches_update(sel, 1);
|
|
}
|
|
else
|
|
{
|
|
evry_history_item_add(it, NULL, NULL);
|
|
strncpy(new_state->input, s->input, INPUTLEN);
|
|
s = new_state;
|
|
EVRY_PLUGIN(it)->state = s;
|
|
s->cur_plugins = eina_list_append(s->cur_plugins, it);
|
|
}
|
|
|
|
_evry_plugin_select(s, EVRY_PLUGIN(it));
|
|
}
|
|
else
|
|
{
|
|
if (it->plugin->history)
|
|
evry_history_item_add(it, NULL, s->input);
|
|
|
|
_evry_matches_update(sel, 1);
|
|
s = new_state;
|
|
_evry_plugin_select(s, pref);
|
|
}
|
|
|
|
_evry_selector_update(sel);
|
|
|
|
if (view && win->visible)
|
|
{
|
|
s->view = view->create(view, s, win->o_main);
|
|
if (s->view)
|
|
{
|
|
s->view->state = s;
|
|
_evry_view_show(win, s->view, SLIDE_LEFT);
|
|
s->view->update(s->view);
|
|
}
|
|
}
|
|
|
|
_evry_update_text_label(sel->state);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
evry_browse_back(Evry_Selector *sel)
|
|
{
|
|
Evry_Window *win = sel->win;
|
|
|
|
if (!sel) sel = CUR_SEL;
|
|
|
|
Evry_State *s = sel->state;
|
|
|
|
DBG("%p", sel);
|
|
|
|
if (!s || !sel->states->next)
|
|
return 0;
|
|
|
|
_evry_state_pop(sel, 0);
|
|
|
|
s = sel->state;
|
|
/* _evry_aggregator_fetch(s); */
|
|
_evry_selector_update(sel);
|
|
if (sel == SUBJ_SEL)
|
|
_evry_selector_update_actions(ACTN_SEL);
|
|
_evry_update_text_label(s);
|
|
_evry_view_show(win, s->view, SLIDE_RIGHT);
|
|
s->view->update(s->view);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
evry_selectors_switch(Evry_Window *win, int dir, int slide)
|
|
{
|
|
Evry_State *s = (CUR_SEL)->state;
|
|
|
|
if ((CUR_SEL)->update_timer)
|
|
{
|
|
if ((CUR_SEL == SUBJ_SEL) || (CUR_SEL == ACTN_SEL))
|
|
{
|
|
_evry_matches_update(CUR_SEL, 0);
|
|
_evry_selector_update(CUR_SEL);
|
|
}
|
|
}
|
|
|
|
if (CUR_SEL != SUBJ_SEL && dir == 0)
|
|
{
|
|
edje_object_signal_emit(win->o_main, "e,state,object_selector_hide", "e");
|
|
_evry_selector_activate(SUBJ_SEL, (slide * SLIDE_RIGHT));
|
|
return 1;
|
|
}
|
|
if (CUR_SEL == SUBJ_SEL && dir > 0)
|
|
{
|
|
if (s->cur_item)
|
|
{
|
|
_evry_selector_activate(ACTN_SEL, slide * SLIDE_LEFT);
|
|
return 1;
|
|
}
|
|
}
|
|
else if (CUR_SEL == ACTN_SEL && dir > 0)
|
|
{
|
|
Evry_Item *it;
|
|
|
|
if (!s || !(it = s->cur_item) || !(CHECK_TYPE(it, EVRY_TYPE_ACTION)))
|
|
return 0;
|
|
|
|
GET_ACTION(act,it);
|
|
if (!act->it2.type)
|
|
return 0;
|
|
|
|
_evry_selector_plugins_get(OBJ_SEL, it, NULL);
|
|
_evry_selector_update(OBJ_SEL);
|
|
edje_object_signal_emit(win->o_main, "e,state,object_selector_show", "e");
|
|
|
|
_evry_selector_activate(OBJ_SEL, (slide * SLIDE_LEFT));
|
|
return 1;
|
|
}
|
|
else if (CUR_SEL == ACTN_SEL && dir < 0)
|
|
{
|
|
_evry_selector_activate(SUBJ_SEL, (slide * SLIDE_RIGHT));
|
|
edje_object_signal_emit(win->o_main, "e,state,object_selector_hide", "e");
|
|
return 1;
|
|
}
|
|
else if (CUR_SEL == OBJ_SEL && dir < 0)
|
|
{
|
|
_evry_selector_activate(ACTN_SEL, (slide * SLIDE_RIGHT));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
_evry_selectors_switch(Evry_Window *win, int dir)
|
|
{
|
|
return evry_selectors_switch(win, dir, 0);
|
|
}
|
|
|
|
static int
|
|
_evry_input_complete(Evry_State *s)
|
|
{
|
|
int action = 0;
|
|
char *input = NULL;
|
|
Evry_Item *it = s->cur_item;
|
|
Evry_Window *win = s->selector->win;
|
|
|
|
if (!it) return 0;
|
|
|
|
evry_item_ref(it);
|
|
|
|
s->item_auto_selected = EINA_FALSE;
|
|
|
|
if (it->plugin->complete)
|
|
action = it->plugin->complete(it->plugin, it, &input);
|
|
else
|
|
evry_browse_item(it);
|
|
|
|
if (input && action == EVRY_COMPLETE_INPUT)
|
|
{
|
|
strncpy(s->input, input, INPUTLEN - 1);
|
|
_evry_update_text_label(s);
|
|
_evry_cb_update_timer(CUR_SEL);
|
|
evry_item_select(s, it);
|
|
}
|
|
|
|
evry_item_free(it);
|
|
E_FREE(input);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
_evry_cheat_history(Evry_State *s, int promote, int delete)
|
|
{
|
|
|
|
History_Entry *he;
|
|
History_Item *hi;
|
|
History_Types *ht;
|
|
Eina_List *l, *ll;
|
|
Evry_Item *it = s->cur_item;
|
|
|
|
if (!it) return 0;
|
|
|
|
if (!(ht = evry_history_types_get(it->type)))
|
|
return 1;
|
|
|
|
if (!(he = eina_hash_find(ht->types, (it->id ? it->id : it->label))))
|
|
return 1;
|
|
|
|
EINA_LIST_FOREACH_SAFE(he->items, l, ll, hi)
|
|
{
|
|
if (hi->plugin != it->plugin->name)
|
|
continue;
|
|
|
|
if (delete)
|
|
{
|
|
if (hi->input)
|
|
eina_stringshare_del(hi->input);
|
|
if (hi->plugin)
|
|
eina_stringshare_del(hi->plugin);
|
|
if (hi->context)
|
|
eina_stringshare_del(hi->context);
|
|
E_FREE(hi);
|
|
|
|
he->items = eina_list_remove_list(he->items, l);
|
|
}
|
|
else if (promote)
|
|
{
|
|
hi->count += 5;
|
|
hi->last_used = ecore_time_unix_get();
|
|
}
|
|
else /* demote */
|
|
{
|
|
hi->count -= 5;
|
|
if (hi->count < 0) hi->count = 1;
|
|
}
|
|
}
|
|
if (s->plugin == s->aggregator)
|
|
_evry_aggregator_fetch(s);
|
|
if (s->view)
|
|
s->view->update(s->view);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_evry_cb_key_down(void *data, int type __UNUSED__, void *event)
|
|
{
|
|
Ecore_Event_Key *ev = event;
|
|
Evry_State *s;
|
|
Evry_Selector *sel;
|
|
Evry_Window *win = data;
|
|
const char *old;
|
|
|
|
if (ev->event_window != win->ewin->evas_win)
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if (!strcmp(ev->key, "Escape"))
|
|
{
|
|
evry_hide(win, 0);
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
#ifdef DRAG_OFF_WINDOW
|
|
else if (win->grab && !strcmp(ev->key, "F1"))
|
|
{
|
|
E_Win *ewin = win->ewin;
|
|
|
|
e_grabinput_release(ewin->evas_win, ewin->evas_win);
|
|
if (!win->shaped)
|
|
e_win_borderless_set(ewin, 0);
|
|
ecore_evas_lower(ewin->ecore_evas);
|
|
ewin->border = e_border_new(ewin->container, ewin->evas_win, 1, 1);
|
|
// dont need this - special stuff - here it is needed
|
|
ewin->border->ignore_first_unmap = 1;
|
|
ewin->border->internal = 1;
|
|
ewin->border->internal_ecore_evas = ewin->ecore_evas;
|
|
ewin->border->internal_no_remember = 1;
|
|
e_border_show(ewin->border);
|
|
|
|
win->grab = 0;
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
#endif
|
|
else if (ev->modifiers)
|
|
{
|
|
Eina_List *l;
|
|
E_Config_Binding_Key *bind;
|
|
E_Binding_Modifier mod;
|
|
|
|
for (l = e_config->key_bindings; l; l = l->next)
|
|
{
|
|
bind = l->data;
|
|
|
|
if (bind->action && strcmp(bind->action, "everything")) continue;
|
|
|
|
mod = 0;
|
|
|
|
if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
|
|
mod |= E_BINDING_MODIFIER_SHIFT;
|
|
if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
|
|
mod |= E_BINDING_MODIFIER_CTRL;
|
|
if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
|
|
mod |= E_BINDING_MODIFIER_ALT;
|
|
if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
|
|
mod |= E_BINDING_MODIFIER_WIN;
|
|
|
|
if (!(bind->key && (!strcmp(bind->key, ev->keyname)) &&
|
|
(((unsigned int)bind->modifiers == mod) || (bind->any_mod))))
|
|
continue;
|
|
|
|
if (win->level > 0)
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
if (!(bind->params) && (CUR_SEL == OBJ_SEL) &&
|
|
((CUR_SEL)->state && (CUR_SEL)->state->cur_item))
|
|
{
|
|
_evry_selectors_shift(win, 1);
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
|
|
evry_hide(win, 1);
|
|
|
|
#if 0 /* FIXME this causes segv when triggering a plugin keybinding twice */
|
|
if (win && CUR_SEL && bind->params)
|
|
{
|
|
Eina_List *ll;
|
|
Evry_Plugin *p;
|
|
|
|
EINA_LIST_FOREACH((SUBJ_SEL)->plugins, ll, p)
|
|
if (!strcmp(bind->params, p->name)) break;
|
|
|
|
if (p)
|
|
{
|
|
_evry_plugin_select((CUR_SEL)->state, p);
|
|
_evry_selector_update(CUR_SEL);
|
|
_evry_view_update(win, (CUR_SEL)->state);
|
|
}
|
|
}
|
|
#endif
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
}
|
|
|
|
old = ev->key;
|
|
win->request_selection = EINA_FALSE;
|
|
|
|
if (!strcmp(ev->key, "KP_Enter"))
|
|
{
|
|
ev->key = "Return";
|
|
}
|
|
else if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
|
|
{
|
|
if (!strcmp(ev->key, "Tab"))
|
|
{
|
|
ev->key = "Down";
|
|
}
|
|
else if (!strcmp(ev->key, "ISO_Left_Tab") || (!strcmp(ev->key, "Tab") &&
|
|
(ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)))
|
|
{
|
|
ev->key = "Up";
|
|
ev->modifiers = 0;
|
|
}
|
|
else if (!strcmp(ev->key, "q"))
|
|
{
|
|
evry_hide(win, 0);
|
|
return 1;
|
|
}
|
|
else if (!strcmp(ev->key, "w"))
|
|
{
|
|
ev->key = "Return";
|
|
ev->modifiers = 0;
|
|
}
|
|
else if (evry_conf->quick_nav == 1)
|
|
{
|
|
if (!strcmp(ev->key, "k") || (!strcmp(ev->key, "K")))
|
|
ev->key = "Up";
|
|
else if (!strcmp(ev->key, "j") || (!strcmp(ev->key, "J")))
|
|
ev->key = "Down";
|
|
else if (!strcmp(ev->key, "n") || (!strcmp(ev->key, "N")))
|
|
ev->key = "Next";
|
|
else if (!strcmp(ev->key, "p") || (!strcmp(ev->key, "P")))
|
|
ev->key = "Prior";
|
|
else if (!strcmp(ev->key, "l") || (!strcmp(ev->key, "L")))
|
|
ev->key = "Right";
|
|
else if (!strcmp(ev->key, "h") || (!strcmp(ev->key, "H")))
|
|
ev->key = "Left";
|
|
else if (!strcmp(ev->key, "i") || (!strcmp(ev->key, "I")))
|
|
ev->key = "Tab";
|
|
else if (!strcmp(ev->key, "m") || (!strcmp(ev->key, "M")))
|
|
ev->key = "Return";
|
|
}
|
|
else if (evry_conf->quick_nav == 3)
|
|
{
|
|
if (!strcmp(ev->key, "p") || (!strcmp(ev->key, "P")))
|
|
ev->key = "Up";
|
|
else if (!strcmp(ev->key, "n") || (!strcmp(ev->key, "N")))
|
|
ev->key = "Down";
|
|
else if (!strcmp(ev->key, "f") || (!strcmp(ev->key, "F")))
|
|
ev->key = "Right";
|
|
else if (!strcmp(ev->key, "b") || (!strcmp(ev->key, "B")))
|
|
ev->key = "Left";
|
|
else if (!strcmp(ev->key, "i") || (!strcmp(ev->key, "I")))
|
|
ev->key = "Tab";
|
|
else if (!strcmp(ev->key, "m") || (!strcmp(ev->key, "M")))
|
|
ev->key = "Return";
|
|
}
|
|
}
|
|
|
|
if (!win || !(sel = CUR_SEL))
|
|
goto end;
|
|
|
|
if (!strcmp(ev->key, "Tab") &&
|
|
!((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) ||
|
|
(ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)))
|
|
{
|
|
if (!_evry_selectors_switch(win, 1))
|
|
_evry_selectors_switch(win, 0);
|
|
goto end;
|
|
}
|
|
|
|
if (!(s = sel->state))
|
|
goto end;
|
|
|
|
if (!win->visible && (!strcmp(ev->key, "Down")))
|
|
{
|
|
_evry_list_win_show(win);
|
|
goto end;
|
|
}
|
|
else if ((!strcmp(ev->key, "ISO_Left_Tab") ||
|
|
(((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) ||
|
|
(ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)) &&
|
|
(!strcmp(ev->key, "Tab")))))
|
|
{
|
|
_evry_input_complete(s);
|
|
goto end;
|
|
}
|
|
else if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
|
|
(!strcmp(ev->key, "Delete") || !strcmp(ev->key, "Insert")))
|
|
{
|
|
int delete = (!strcmp(ev->key, "Delete") &&
|
|
(ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT));
|
|
int promote = (!strcmp(ev->key, "Insert"));
|
|
|
|
_evry_cheat_history(s, promote, delete);
|
|
goto end;
|
|
}
|
|
else if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
|
|
{
|
|
if (!strcmp(ev->key, "u"))
|
|
{
|
|
if (!_evry_clear(sel))
|
|
evry_browse_back(sel);
|
|
goto end;
|
|
}
|
|
else if (!strcmp(ev->key, "1"))
|
|
evry_view_toggle(s, NULL);
|
|
else if (!strcmp(ev->key, "Return"))
|
|
_evry_plugin_action(sel, 0);
|
|
else if (!strcmp(ev->key, "v"))
|
|
{
|
|
win->request_selection = EINA_TRUE;
|
|
ecore_x_selection_primary_request
|
|
(win->ewin->evas_win, ECORE_X_SELECTION_TARGET_UTF8_STRING);
|
|
}
|
|
else
|
|
{
|
|
_evry_view_key_press(s, ev);
|
|
}
|
|
goto end;
|
|
}
|
|
if ((s->plugin && s->plugin->cb_key_down) &&
|
|
(s->plugin->cb_key_down(s->plugin, ev)))
|
|
{
|
|
/* let plugin intercept keypress */
|
|
goto end;
|
|
}
|
|
else if (_evry_view_key_press(s, ev))
|
|
{
|
|
/* let view intercept keypress */
|
|
goto end;
|
|
}
|
|
else if (!strcmp(ev->key, "Right"))
|
|
{
|
|
if (!evry_browse_item(sel->state->cur_item))
|
|
evry_selectors_switch(win, 1, EINA_TRUE);
|
|
}
|
|
else if (!strcmp(ev->key, "Left"))
|
|
{
|
|
if (!evry_browse_back(sel))
|
|
evry_selectors_switch(win, -1, EINA_TRUE);
|
|
}
|
|
else if (!strcmp(ev->key, "Return"))
|
|
{
|
|
if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
|
|
{
|
|
_evry_plugin_action(sel, 0);
|
|
}
|
|
else if (s->cur_item && s->cur_item->browseable)
|
|
{
|
|
evry_browse_item(sel->state->cur_item);
|
|
}
|
|
else
|
|
{
|
|
_evry_plugin_action(sel, 1);
|
|
}
|
|
}
|
|
else if (!strcmp(ev->key, "BackSpace"))
|
|
{
|
|
if (!_evry_backspace(sel))
|
|
evry_browse_back(sel);
|
|
}
|
|
else if ((ev->compose && !(ev->modifiers & ECORE_EVENT_MODIFIER_ALT)))
|
|
{
|
|
unsigned int len = strlen(s->inp);
|
|
|
|
if (len == 0 && (evry_view_toggle(s, ev->compose)))
|
|
goto end;
|
|
|
|
if (len < (INPUTLEN - strlen(ev->compose)))
|
|
{
|
|
strcat(s->inp, ev->compose);
|
|
|
|
_evry_update(sel, 1);
|
|
}
|
|
}
|
|
|
|
end:
|
|
ev->key = old;
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
|
|
static int
|
|
_evry_backspace(Evry_Selector *sel)
|
|
{
|
|
Evry_State *s = sel->state;
|
|
int len, val, pos;
|
|
|
|
if (!(len = strlen(s->inp)))
|
|
return 0;
|
|
|
|
pos = evas_string_char_prev_get(s->inp, len, &val);
|
|
if ((pos < len) && (pos >= 0))
|
|
{
|
|
val = *(s->inp + pos);
|
|
|
|
s->inp[pos] = 0;
|
|
|
|
if (s->trigger_active && s->inp[0] != 0)
|
|
s->input = s->inp + 1;
|
|
else
|
|
s->input = s->inp;
|
|
|
|
if (pos == 0)
|
|
s->trigger_active = EINA_FALSE;
|
|
|
|
if ((pos == 0) || !isspace(val))
|
|
_evry_update(sel, 1);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
_evry_update_text_label(Evry_State *s)
|
|
{
|
|
Evry_Window *win = s->selector->win;
|
|
|
|
if (!win->visible && evry_conf->hide_input)
|
|
{
|
|
if (strlen(s->inp) > 0)
|
|
edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e");
|
|
else
|
|
edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e");
|
|
}
|
|
|
|
edje_object_part_text_set(win->o_main, "list:e.text.label", s->inp);
|
|
}
|
|
|
|
static void
|
|
_evry_update(Evry_Selector *sel, int fetch)
|
|
{
|
|
Evry_State *s = sel->state;
|
|
Evry_Window *win = sel->win;
|
|
|
|
_evry_update_text_label(s);
|
|
|
|
if (fetch)
|
|
{
|
|
if (sel->update_timer)
|
|
ecore_timer_del(sel->update_timer);
|
|
|
|
sel->update_timer =
|
|
ecore_timer_add(MATCH_LAG, _evry_cb_update_timer, sel);
|
|
|
|
edje_object_signal_emit(win->o_main, "list:e,signal,update", "e");
|
|
}
|
|
}
|
|
|
|
static Eina_Bool
|
|
_evry_cb_update_timer(void *data)
|
|
{
|
|
Evry_Selector *sel = data;
|
|
|
|
_evry_matches_update(sel, 1);
|
|
_evry_selector_update(sel);
|
|
_evry_list_win_update(sel->state);
|
|
sel->update_timer = NULL;
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
}
|
|
|
|
static int
|
|
_evry_clear(Evry_Selector *sel)
|
|
{
|
|
Evry_State *s = sel->state;
|
|
Evry_Window *win = sel->win;
|
|
|
|
if (!(s->inp) || (s->inp[0] == 0))
|
|
return 0;
|
|
|
|
if (s->trigger_active && s->inp[1] != 0)
|
|
{
|
|
s->inp[1] = 0;
|
|
s->input = s->inp + 1;
|
|
}
|
|
else
|
|
{
|
|
s->inp[0] = 0;
|
|
s->input = s->inp;
|
|
s->trigger_active = EINA_FALSE;
|
|
}
|
|
|
|
_evry_update(sel, 1);
|
|
|
|
if (!win->visible && evry_conf->hide_input)
|
|
edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e");
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
_evry_cb_free_action_performed(void *data __UNUSED__, void *event)
|
|
{
|
|
Evry_Event_Action_Performed *ev = event;
|
|
|
|
if (ev->it1)
|
|
EVRY_ITEM_FREE(ev->it1);
|
|
if (ev->it2)
|
|
EVRY_ITEM_FREE(ev->it2);
|
|
|
|
IF_RELEASE(ev->action);
|
|
|
|
E_FREE(ev);
|
|
}
|
|
|
|
static int
|
|
_evry_action_do(Evry_Action *act)
|
|
{
|
|
Evry_Event_Action_Performed *ev;
|
|
int ret;
|
|
|
|
if ((ret = act->action(act)))
|
|
{
|
|
ev = E_NEW(Evry_Event_Action_Performed, 1);
|
|
ev->action = eina_stringshare_ref(act->name);
|
|
ev->it1 = act->it1.item;
|
|
ev->it2 = act->it2.item;
|
|
|
|
if (ev->it1)
|
|
EVRY_ITEM_REF(ev->it1);
|
|
if (ev->it2)
|
|
EVRY_ITEM_REF(ev->it2);
|
|
|
|
ecore_event_add(_evry_events[EVRY_EVENT_ACTION_PERFORMED], ev,
|
|
_evry_cb_free_action_performed, NULL);
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
evry_plugin_action(Evry_Window *win, int finished)
|
|
{
|
|
_evry_plugin_action(CUR_SEL, finished);
|
|
}
|
|
|
|
static void
|
|
_evry_plugin_action(Evry_Selector *sel, int finished)
|
|
{
|
|
Evry_State *s_subj, *s_act, *s_obj = NULL;
|
|
Evry_Item *it, *it_subj, *it_act, *it_obj = NULL;
|
|
Evry_Window *win = sel->win;
|
|
Eina_List *l;
|
|
int ret = 0;
|
|
|
|
if ((SUBJ_SEL)->update_timer)
|
|
{
|
|
_evry_matches_update(SUBJ_SEL, 0);
|
|
_evry_selector_update(SUBJ_SEL);
|
|
}
|
|
|
|
/* do delayed fetch actions now */
|
|
if ((ACTN_SEL)->action_timer)
|
|
_evry_selector_update_actions_do(ACTN_SEL);
|
|
|
|
if (!(s_subj = (SUBJ_SEL)->state))
|
|
return;
|
|
|
|
if (!(it_subj = s_subj->cur_item))
|
|
return;
|
|
|
|
if ((CUR_SEL == SUBJ_SEL) && (ACTN_SEL)->update_timer)
|
|
{
|
|
/* _evry_selector_actions_get(it_subj); */
|
|
_evry_selector_plugins_get(ACTN_SEL, it_subj, NULL);
|
|
|
|
if (!(ACTN_SEL)->state)
|
|
return;
|
|
|
|
_evry_selector_update(ACTN_SEL);
|
|
}
|
|
|
|
if (!(s_act = (ACTN_SEL)->state))
|
|
return;
|
|
|
|
if (!(it_act = s_act->cur_item))
|
|
return;
|
|
|
|
if (CHECK_TYPE(it_act, EVRY_TYPE_ACTION) ||
|
|
CHECK_SUBTYPE(it_act, EVRY_TYPE_ACTION))
|
|
{
|
|
GET_ACTION(act, it_act);
|
|
|
|
if (!act->action)
|
|
return;
|
|
|
|
/* get object item for action, when required */
|
|
if (act->it2.type)
|
|
{
|
|
/* check if object is provided */
|
|
if ((s_obj = (OBJ_SEL)->state) && (!s_obj->delete_me))
|
|
{
|
|
it_obj = s_obj->cur_item;
|
|
}
|
|
|
|
if (!it_obj)
|
|
{
|
|
if (SUBJ_SEL == CUR_SEL)
|
|
_evry_selectors_switch(win, 1);
|
|
if (ACTN_SEL == CUR_SEL)
|
|
_evry_selectors_switch(win, 1);
|
|
return;
|
|
}
|
|
|
|
act->it2.item = it_obj;
|
|
}
|
|
|
|
if (s_obj && s_obj->sel_items && !(act->it2.accept_list))
|
|
{
|
|
if (!(act->it1.item && CHECK_TYPE(act->it1.item, EVRY_TYPE_PLUGIN)))
|
|
act->it1.item = it_subj;
|
|
|
|
EINA_LIST_FOREACH(s_obj->sel_items, l, it)
|
|
{
|
|
if (it->type != act->it2.type)
|
|
continue;
|
|
act->it2.item = it;
|
|
|
|
_evry_action_do(act);
|
|
}
|
|
}
|
|
else if (s_subj->sel_items && !(act->it1.accept_list))
|
|
{
|
|
EINA_LIST_FOREACH(s_subj->sel_items, l, it)
|
|
{
|
|
if (it->type != act->it1.type)
|
|
continue;
|
|
act->it1.item = it;
|
|
|
|
_evry_action_do(act);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!(act->it1.item && CHECK_TYPE(act->it1.item, EVRY_TYPE_PLUGIN)))
|
|
{
|
|
act->it1.item = it_subj;
|
|
act->it1.items = s_subj->sel_items;
|
|
}
|
|
|
|
if (s_obj)
|
|
act->it2.items = s_obj->sel_items;
|
|
|
|
ret = _evry_action_do(act);
|
|
|
|
if (ret == EVRY_ACTION_OTHER)
|
|
return;
|
|
}
|
|
}
|
|
else return;
|
|
|
|
if (s_subj && it_subj && it_subj->plugin->history)
|
|
evry_history_item_add(it_subj, NULL, s_subj->input);
|
|
|
|
if (s_act && it_act && it_act->plugin->history)
|
|
evry_history_item_add(it_act, it_subj->context, s_act->input);
|
|
|
|
if (s_obj && it_obj && it_obj->plugin->history)
|
|
evry_history_item_add(it_obj, it_act->context, s_obj->input);
|
|
|
|
if (ret == EVRY_ACTION_CONTINUE)
|
|
return;
|
|
|
|
if (ret == EVRY_ACTION_CLEAR)
|
|
{
|
|
_evry_clear(CUR_SEL);
|
|
}
|
|
else if ((finished) && win->grab)
|
|
{
|
|
evry_hide(win, 0);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
_evry_view_show(Evry_Window *win, Evry_View *v, int slide)
|
|
{
|
|
if (!v) return;
|
|
|
|
if (v->o_bar)
|
|
{
|
|
edje_object_part_swallow(win->o_main, "list:e.swallow.bar", v->o_bar);
|
|
evas_object_show(v->o_bar);
|
|
}
|
|
|
|
if (!v->o_list)
|
|
return;
|
|
|
|
if (slide == SLIDE_LEFT)
|
|
{
|
|
edje_object_part_swallow(win->o_main, "list:e.swallow.list2", v->o_list);
|
|
evas_object_show(v->o_list);
|
|
|
|
edje_object_signal_emit(win->o_main, "list:e,action,slide,left", "e");
|
|
edje_object_signal_emit(v->o_list, "e,action,show,list", "e");
|
|
}
|
|
else if (slide == SLIDE_RIGHT)
|
|
{
|
|
edje_object_part_swallow(win->o_main, "list:e.swallow.list", v->o_list);
|
|
evas_object_show(v->o_list);
|
|
|
|
edje_object_signal_emit(win->o_main, "list:e,action,slide,right", "e");
|
|
edje_object_signal_emit(v->o_list, "e,action,show,list", "e");
|
|
}
|
|
else
|
|
{
|
|
edje_object_part_swallow(win->o_main, "list:e.swallow.list", v->o_list);
|
|
evas_object_show(v->o_list);
|
|
|
|
edje_object_signal_emit(win->o_main, "list:e,action,slide,default", "e");
|
|
edje_object_signal_emit(v->o_list, "e,action,show,list", "e");
|
|
}
|
|
}
|
|
|
|
static Eina_Bool
|
|
_clear_timer(void *data)
|
|
{
|
|
_evry_state_clear(data);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
}
|
|
|
|
static void
|
|
_evry_state_clear(Evry_Window *win)
|
|
{
|
|
Evry_State *s;
|
|
Evry_View *v;
|
|
|
|
if (!win->state_clearing)
|
|
return;
|
|
|
|
s = win->state_clearing;
|
|
win->state_clearing = NULL;
|
|
|
|
ecore_timer_del(s->clear_timer);
|
|
s->clear_timer = NULL;
|
|
|
|
if (s->delete_me)
|
|
{
|
|
if (s->view)
|
|
s->view->destroy(s->view);
|
|
s->clear_timer = NULL;
|
|
E_FREE(s->inp);
|
|
E_FREE(s);
|
|
}
|
|
else if ((v = s->view))
|
|
{
|
|
v->clear(v);
|
|
|
|
if (v->o_list)
|
|
{
|
|
edje_object_part_unswallow(win->o_main, v->o_list);
|
|
evas_object_hide(v->o_list);
|
|
}
|
|
}
|
|
|
|
/* replay mouse down to allow direct sliding back */
|
|
if (win->mouse_button)
|
|
evas_event_feed_mouse_down(win->evas, win->mouse_button, 0, 0, NULL);
|
|
}
|
|
|
|
static void
|
|
_evry_view_hide(Evry_Window *win, Evry_View *v, int slide)
|
|
{
|
|
_evry_state_clear(win);
|
|
|
|
if (!v) return;
|
|
|
|
if (slide && v->o_list)
|
|
{
|
|
evas_object_hide(v->o_list);
|
|
edje_object_part_unswallow(win->o_main, v->o_list);
|
|
|
|
if (slide == SLIDE_RIGHT)
|
|
{
|
|
edje_object_part_swallow(win->o_main, "list:e.swallow.list2",
|
|
v->o_list);
|
|
|
|
win->state_clearing = v->state;
|
|
}
|
|
else /* if (slide == SLIDE_LEFT) */
|
|
{
|
|
edje_object_part_swallow(win->o_main, "list:e.swallow.list",
|
|
v->o_list);
|
|
win->state_clearing = v->state;
|
|
}
|
|
|
|
evas_object_show(v->o_list);
|
|
edje_object_signal_emit(v->o_list, "e,action,hide,list", "e");
|
|
/* FIXME get signal from theme when anim finished */
|
|
v->state->clear_timer = ecore_timer_add(0.5, _clear_timer, win);
|
|
|
|
if (v->o_bar)
|
|
{
|
|
edje_object_part_unswallow(win->o_main, v->o_bar);
|
|
evas_object_hide(v->o_bar);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
v->clear(v);
|
|
|
|
if (v->o_list)
|
|
{
|
|
edje_object_part_unswallow(win->o_main, v->o_list);
|
|
evas_object_hide(v->o_list);
|
|
}
|
|
|
|
if (v->o_bar)
|
|
{
|
|
edje_object_part_unswallow(win->o_main, v->o_bar);
|
|
evas_object_hide(v->o_bar);
|
|
}
|
|
}
|
|
|
|
static int
|
|
_evry_view_create(Evry_State *s)
|
|
{
|
|
Evry_View *view;
|
|
|
|
if (s->view)
|
|
return 1;
|
|
|
|
if (s->plugin && s->plugin->view)
|
|
view = s->plugin->view;
|
|
else
|
|
view = eina_list_data_get(evry_conf->views);
|
|
|
|
s->view = view->create(view, s, s->selector->win->o_main);
|
|
|
|
if (s->view)
|
|
{
|
|
s->view->state = s;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int
|
|
_evry_view_update(Evry_Window *win, Evry_State *s)
|
|
{
|
|
if (!win->visible) return 0;
|
|
/* TODO check this again !!!!*/
|
|
if (s->view)
|
|
{
|
|
s->view->update(s->view);
|
|
return 0;
|
|
}
|
|
|
|
if (_evry_view_create(s))
|
|
{
|
|
s->view->update(s->view);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
_evry_view_clear(Evry_State *s)
|
|
{
|
|
if (!s || !s->view) return;
|
|
|
|
s->view->clear(s->view);
|
|
}
|
|
|
|
static int
|
|
_evry_view_key_press(Evry_State *s, Ecore_Event_Key *ev)
|
|
{
|
|
if (!s || !s->view || !s->view->cb_key_down) return 0;
|
|
|
|
return s->view->cb_key_down(s->view, ev);
|
|
}
|
|
|
|
int
|
|
evry_view_toggle(Evry_State *s, const char *trigger)
|
|
{
|
|
Evry_View *view, *v = NULL;
|
|
Eina_List *l, *ll;
|
|
Eina_Bool triggered = FALSE;
|
|
Evry_Window *win = s->selector->win;
|
|
|
|
if (trigger)
|
|
{
|
|
EINA_LIST_FOREACH(evry_conf->views, ll, view)
|
|
{
|
|
if (view->trigger && !strncmp(trigger, view->trigger, 1) &&
|
|
(!s->view || (view->id != s->view->id)) &&
|
|
(v = view->create(view, s, win->o_main)))
|
|
{
|
|
triggered = EINA_TRUE;
|
|
goto found;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (s->view)
|
|
l = eina_list_data_find_list(evry_conf->views, s->view->id);
|
|
else
|
|
{
|
|
view = evry_conf->views->data;
|
|
v = view->create(view, s, win->o_main);
|
|
goto found;
|
|
}
|
|
|
|
if (l && l->next)
|
|
l = l->next;
|
|
else
|
|
l = evry_conf->views;
|
|
|
|
EINA_LIST_FOREACH(l, ll, view)
|
|
{
|
|
if ((!view->trigger) &&
|
|
((!s->view || (view->id != s->view->id)) &&
|
|
(v = view->create(view, s, win->o_main))))
|
|
goto found;
|
|
}
|
|
}
|
|
|
|
found:
|
|
if (!v) return 0;
|
|
|
|
_evry_list_win_show(win);
|
|
|
|
if (s->view)
|
|
{
|
|
_evry_view_hide(win, s->view, 0);
|
|
s->view->destroy(s->view);
|
|
}
|
|
|
|
s->view = v;
|
|
s->view->state = s;
|
|
_evry_view_show(win, s->view, 0);
|
|
view->update(s->view);
|
|
|
|
return triggered;
|
|
}
|
|
|
|
static void
|
|
_evry_matches_update(Evry_Selector *sel, int async)
|
|
{
|
|
Evry_State *s = sel->state;
|
|
Evry_Plugin *p;
|
|
Eina_List *l;
|
|
Evry_Item *it;
|
|
Evry_Window *win = sel->win;
|
|
const char *input = NULL;
|
|
int len_inp = 0;
|
|
|
|
s->changed = 1;
|
|
s->request++;
|
|
|
|
#ifdef CHECK_TIME
|
|
DBG("matches update %f", ecore_time_get() - _evry_time);
|
|
#endif
|
|
|
|
if (sel->update_timer)
|
|
{
|
|
ecore_timer_del(sel->update_timer);
|
|
sel->update_timer = NULL;
|
|
}
|
|
|
|
if (s->sel_items)
|
|
{
|
|
eina_list_free(s->sel_items);
|
|
s->sel_items = NULL;
|
|
}
|
|
|
|
if (s->inp[0])
|
|
{
|
|
len_inp = strlen(s->inp);
|
|
input = s->inp;
|
|
}
|
|
|
|
/* use current plugins */
|
|
if (s->trigger_active)
|
|
{
|
|
s->plugin_auto_selected = EINA_FALSE;
|
|
|
|
EINA_LIST_FOREACH(s->cur_plugins, l, p)
|
|
{
|
|
p->request = s->request;
|
|
p->fetch(p, s->input);
|
|
}
|
|
goto found;
|
|
}
|
|
|
|
EINA_LIST_FREE(s->cur_plugins, p);
|
|
|
|
/* check if input matches plugin trigger */
|
|
if (input)
|
|
{
|
|
int len_trigger = 0;
|
|
|
|
EINA_LIST_FOREACH(s->plugins, l, p)
|
|
{
|
|
if (!p->config->trigger) continue;
|
|
int len = strlen(p->config->trigger);
|
|
|
|
if (len_trigger && len != len_trigger)
|
|
continue;
|
|
|
|
if ((len_inp >= len) &&
|
|
(!strncmp(s->inp, p->config->trigger, len)))
|
|
{
|
|
len_trigger = len;
|
|
s->cur_plugins = eina_list_append(s->cur_plugins, p);
|
|
p->request = s->request;
|
|
if(len_inp == len)
|
|
p->fetch(p, NULL);
|
|
else
|
|
p->fetch(p, s->input + len);
|
|
}
|
|
}
|
|
if (s->cur_plugins)
|
|
{
|
|
s->trigger_active = EINA_TRUE;
|
|
/* replace trigger with indicator */
|
|
if (len_trigger > 1)
|
|
{
|
|
s->inp[0] = ':';
|
|
|
|
if (s->inp + len_trigger)
|
|
strcpy(s->inp + 1, s->inp + len_trigger);
|
|
else
|
|
s->inp[1] = 0;
|
|
}
|
|
s->input = s->inp + 1;
|
|
_evry_update_text_label(s);
|
|
|
|
goto found;
|
|
}
|
|
}
|
|
|
|
/* query all other plugins for this state */
|
|
EINA_LIST_FOREACH(s->plugins, l, p)
|
|
{
|
|
p->request = s->request;
|
|
|
|
if (p == s->aggregator)
|
|
goto next;
|
|
|
|
/* dont wait for async plugin. use their current items */
|
|
if (!async && p->async_fetch && p->items)
|
|
{
|
|
s->cur_plugins = eina_list_append(s->cur_plugins, p);
|
|
goto next;
|
|
}
|
|
|
|
if (!((sel->states->next) ||
|
|
((CUR_SEL == SUBJ_SEL) &&
|
|
(win->plugin_dedicated))))
|
|
{
|
|
/* skip plugins in toplevel which trigger-only */
|
|
if ((sel == SUBJ_SEL) &&
|
|
(p->config->top_level) &&
|
|
(p->config->trigger_only))
|
|
goto next;
|
|
|
|
/* skip non-toplevel plugins when input < min_query */
|
|
if ((!p->config->top_level) &&
|
|
(p->config->min_query > len_inp))
|
|
goto next;
|
|
}
|
|
|
|
if (p->fetch(p, input))
|
|
{
|
|
#ifdef CHECK_TIME
|
|
DBG("fetch %s %f", p->name, ecore_time_get() - _evry_time);
|
|
#endif
|
|
s->cur_plugins = eina_list_append(s->cur_plugins, p);
|
|
continue;
|
|
}
|
|
|
|
next:
|
|
if (s->plugin == p)
|
|
s->plugin = NULL;
|
|
}
|
|
|
|
found:
|
|
_evry_aggregator_fetch(s);
|
|
|
|
if (s->plugin_auto_selected)
|
|
s->plugin = NULL;
|
|
|
|
_evry_plugin_select(s, s->plugin);
|
|
|
|
if (!s->plugin)
|
|
return;
|
|
|
|
EINA_LIST_FOREACH(s->plugin->items, l, it)
|
|
if (it->marked)
|
|
s->sel_items = eina_list_append(s->sel_items, it);
|
|
}
|
|
|
|
static void
|
|
_evry_item_desel(Evry_State *s)
|
|
{
|
|
Evry_Item *it = s->cur_item;
|
|
|
|
if (it)
|
|
{
|
|
it->selected = EINA_FALSE;
|
|
evry_item_free(it);
|
|
}
|
|
|
|
s->cur_item = NULL;
|
|
}
|
|
|
|
static void
|
|
_evry_item_sel(Evry_State *s, Evry_Item *it)
|
|
{
|
|
if (s->cur_item == it) return;
|
|
|
|
_evry_item_desel(s);
|
|
|
|
evry_item_ref(it);
|
|
it->selected = EINA_TRUE;
|
|
|
|
s->cur_item = it;
|
|
}
|
|
|
|
static void
|
|
_evry_plugin_select(Evry_State *s, Evry_Plugin *p)
|
|
{
|
|
if (!s) return;
|
|
|
|
if (p)
|
|
{
|
|
s->plugin_auto_selected = EINA_FALSE;
|
|
}
|
|
else
|
|
{
|
|
p = eina_list_data_get(s->cur_plugins);
|
|
s->plugin_auto_selected = EINA_TRUE;
|
|
}
|
|
|
|
s->plugin = p;
|
|
|
|
if ((s->view && s->plugin && s->plugin->view) &&
|
|
(s->view->name != s->plugin->view->name))
|
|
{
|
|
s->view->destroy(s->view);
|
|
s->view = NULL;
|
|
if (_evry_view_create(s))
|
|
{
|
|
_evry_view_show(s->selector->win, s->view, 0);
|
|
s->view->update(s->view);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
static void
|
|
_evry_cb_free_plugin_selected(void *data __UNUSED__, void *event)
|
|
{
|
|
Evry_Event_Item_Selected *ev = event;
|
|
|
|
evry_item_free(ev->item);
|
|
E_FREE(ev);
|
|
}
|
|
|
|
void
|
|
evry_plugin_select(Evry_Plugin *p)
|
|
{
|
|
Evry_Event_Item_Selected *ev;
|
|
|
|
if (!p) return;
|
|
|
|
if (!p->state)
|
|
{
|
|
ERR("no state!");
|
|
return;
|
|
}
|
|
|
|
_evry_plugin_select(p->state, p);
|
|
_evry_selector_update(p->state->selector);
|
|
|
|
ev = E_NEW(Evry_Event_Item_Selected, 1);
|
|
ev->item = EVRY_ITEM(p);
|
|
EVRY_ITEM_REF(p);
|
|
ecore_event_add(_evry_events[EVRY_EVENT_PLUGIN_SELECTED], ev,
|
|
_evry_cb_free_plugin_selected, NULL);
|
|
}
|
|
|
|
static void
|
|
_evry_plugin_list_insert(Evry_State *s, Evry_Plugin *p)
|
|
{
|
|
Eina_List *l;
|
|
Evry_Plugin *p2;
|
|
|
|
EINA_LIST_FOREACH(s->cur_plugins, l, p2)
|
|
{
|
|
if (p == p2)
|
|
return;
|
|
|
|
if (p->config->priority < p2->config->priority)
|
|
break;
|
|
}
|
|
|
|
if (l)
|
|
s->cur_plugins = eina_list_prepend_relative_list(s->cur_plugins, p, l);
|
|
else
|
|
s->cur_plugins = eina_list_append(s->cur_plugins, p);
|
|
}
|
|
|
|
static Eina_Bool
|
|
_evry_cb_selection_notify(void *data, int type __UNUSED__, void *event)
|
|
{
|
|
Ecore_X_Event_Selection_Notify *ev;
|
|
Evry_Window *win = data;
|
|
Evry_State *s = (CUR_SEL)->state;
|
|
|
|
if (!s || (data != win)) return ECORE_CALLBACK_PASS_ON;
|
|
if (!win->request_selection) return ECORE_CALLBACK_PASS_ON;
|
|
|
|
win->request_selection = EINA_FALSE;
|
|
|
|
ev = event;
|
|
if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
|
|
(ev->selection == ECORE_X_SELECTION_PRIMARY))
|
|
{
|
|
if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0)
|
|
{
|
|
Ecore_X_Selection_Data_Text *text_data;
|
|
|
|
text_data = ev->data;
|
|
|
|
strncat(s->input, text_data->text, (INPUTLEN - strlen(s->input)) - 1);
|
|
_evry_update(CUR_SEL, 1);
|
|
}
|
|
}
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|