410 lines
10 KiB
C
410 lines
10 KiB
C
#include "e_wizard.h"
|
|
#include "e_wizard_priv.h"
|
|
|
|
static void _wizard_next_eval(void);
|
|
static Evas_Object *_wizard_main_new(E_Zone *zone);
|
|
static Evas_Object *_wizard_extra_new(E_Zone *zone);
|
|
static Eina_Bool _wizard_cb_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
|
static void _wizard_cb_next(void *data, Evas_Object *obj, const char *emission, const char *source);
|
|
|
|
static Eina_Bool _wizard_check_xdg(void);
|
|
static void _wizard_next_xdg(void);
|
|
static Eina_Bool _wizard_cb_next_page(void *data);
|
|
static Eina_Bool _wizard_cb_desktops_update(void *data, int ev_type, void *ev);
|
|
static Eina_Bool _wizard_cb_icons_update(void *data, int ev_type, void *ev);
|
|
|
|
static Evas_Object *pop = NULL;
|
|
static Eina_List *pops = NULL;
|
|
static Evas_Object *o_bg = NULL;
|
|
static Evas_Object *o_content = NULL;
|
|
static Evas_Object *o_box = NULL;
|
|
static E_Wizard_Page *pages = NULL;
|
|
static E_Wizard_Page *curpage = NULL;
|
|
static int next_ok = 1;
|
|
static int next_prev = 0;
|
|
static int next_can = 0;
|
|
|
|
static Eina_List *handlers = NULL;
|
|
static Eina_Bool got_desktops = EINA_FALSE;
|
|
static Eina_Bool got_icons = EINA_FALSE;
|
|
static Eina_Bool xdg_error = EINA_FALSE;
|
|
static Eina_Bool need_xdg_desktops = EINA_FALSE;
|
|
static Eina_Bool need_xdg_icons = EINA_FALSE;
|
|
|
|
static Ecore_Timer *next_timer = NULL;
|
|
|
|
EINTERN int
|
|
wizard_init(void)
|
|
{
|
|
E_Zone *zone;
|
|
const Eina_List *l;
|
|
|
|
EINA_LIST_FOREACH(e_comp->zones, l, zone)
|
|
{
|
|
if (!pop)
|
|
pop = _wizard_main_new(zone);
|
|
else
|
|
pops = eina_list_append(pops, _wizard_extra_new(zone));
|
|
}
|
|
|
|
e_comp_grab_input(1, 1);
|
|
|
|
E_LIST_HANDLER_APPEND(handlers, EFREET_EVENT_DESKTOP_CACHE_BUILD,
|
|
_wizard_cb_desktops_update, NULL);
|
|
|
|
E_LIST_HANDLER_APPEND(handlers, EFREET_EVENT_ICON_CACHE_UPDATE,
|
|
_wizard_cb_icons_update, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_DOWN, _wizard_cb_key_down, NULL);
|
|
return 1;
|
|
}
|
|
|
|
EINTERN int
|
|
wizard_shutdown(void)
|
|
{
|
|
E_FREE_FUNC(pop, evas_object_del);
|
|
E_FREE_LIST(pops, evas_object_del);
|
|
|
|
while (pages)
|
|
wizard_page_del(pages);
|
|
|
|
if (next_timer) ecore_timer_del(next_timer);
|
|
next_timer = NULL;
|
|
E_FREE_LIST(handlers, ecore_event_handler_del);
|
|
return 1;
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_go(void)
|
|
{
|
|
if (!curpage)
|
|
curpage = pages;
|
|
if (curpage)
|
|
{
|
|
if (curpage->init) curpage->init(curpage, &need_xdg_desktops, &need_xdg_icons);
|
|
curpage->state++;
|
|
_wizard_next_eval();
|
|
if (_wizard_check_xdg())
|
|
{
|
|
if ((curpage->show) && (!curpage->show(curpage)))
|
|
{
|
|
curpage->state++;
|
|
wizard_next();
|
|
}
|
|
else
|
|
curpage->state++;
|
|
}
|
|
}
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_apply(void)
|
|
{
|
|
E_Wizard_Page *pg;
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(pages), pg)
|
|
if (pg->apply) pg->apply(pg);
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_next(void)
|
|
{
|
|
if (!curpage)
|
|
{
|
|
/* FINISH */
|
|
wizard_apply();
|
|
wizard_shutdown();
|
|
return;
|
|
}
|
|
if (curpage->hide)
|
|
curpage->hide(curpage);
|
|
curpage->state++;
|
|
curpage = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(curpage)->next, E_Wizard_Page);
|
|
if (!curpage)
|
|
{
|
|
wizard_next();
|
|
return;
|
|
}
|
|
fprintf(stderr, "WIZARD PAGE: %s\n", curpage->name);
|
|
wizard_button_next_enable_set(1);
|
|
need_xdg_desktops = EINA_FALSE;
|
|
need_xdg_icons = EINA_FALSE;
|
|
if (curpage->init)
|
|
curpage->init(curpage, &need_xdg_desktops, &need_xdg_icons);
|
|
curpage->state++;
|
|
if (!_wizard_check_xdg()) return;
|
|
|
|
_wizard_next_eval();
|
|
curpage->state++;
|
|
if (curpage->show && curpage->show(curpage)) return;
|
|
wizard_next();
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_page_show(Evas_Object *obj)
|
|
{
|
|
evas_object_del(o_content);
|
|
o_content = obj;
|
|
if (!obj) return;
|
|
elm_box_pack_end(o_box, obj);
|
|
evas_object_show(obj);
|
|
|
|
elm_object_focus_set(obj, 1);
|
|
edje_object_signal_emit(o_bg, "e,action,page,new", "e");
|
|
}
|
|
|
|
EINTERN E_Wizard_Page *
|
|
wizard_page_add(void *handle, const char *name,
|
|
int (*init_cb)(E_Wizard_Page *pg, Eina_Bool *need_xdg_desktops, Eina_Bool *need_xdg_icons),
|
|
int (*shutdown_cb)(E_Wizard_Page *pg),
|
|
int (*show_cb)(E_Wizard_Page *pg),
|
|
int (*hide_cb)(E_Wizard_Page *pg),
|
|
int (*apply_cb)(E_Wizard_Page *pg)
|
|
)
|
|
{
|
|
E_Wizard_Page *pg;
|
|
|
|
pg = E_NEW(E_Wizard_Page, 1);
|
|
if (!pg) return NULL;
|
|
pg->name = eina_stringshare_add(name);
|
|
|
|
pg->handle = handle;
|
|
pg->evas = evas_object_evas_get(pop);
|
|
|
|
pg->init = init_cb;
|
|
pg->shutdown = shutdown_cb;
|
|
pg->show = show_cb;
|
|
pg->hide = hide_cb;
|
|
pg->apply = apply_cb;
|
|
|
|
pages = (E_Wizard_Page*)eina_inlist_append(EINA_INLIST_GET(pages), EINA_INLIST_GET(pg));
|
|
|
|
return pg;
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_page_del(E_Wizard_Page *pg)
|
|
{
|
|
// rare thing.. if we do wizard_next() from a page and we end up finishing
|
|
// ther page seq.. we cant REALLY dlclose... not a problem as wizard runs
|
|
// once only then e restarts itself with final wizard page
|
|
// if (pg->handle) dlclose(pg->handle);
|
|
if (pg->shutdown) pg->shutdown(pg);
|
|
eina_stringshare_del(pg->name);
|
|
pages = (E_Wizard_Page*)eina_inlist_remove(EINA_INLIST_GET(pages), EINA_INLIST_GET(pg));
|
|
free(pg);
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_button_next_enable_set(int enable)
|
|
{
|
|
next_ok = enable;
|
|
_wizard_next_eval();
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_title_set(const char *title)
|
|
{
|
|
edje_object_part_text_set(o_bg, "e.text.title", title);
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_labels_update(void)
|
|
{
|
|
edje_object_part_text_set(o_bg, "e.text.label", _("Next"));
|
|
}
|
|
|
|
EINTERN const char *
|
|
wizard_dir_get(void)
|
|
{
|
|
return e_module_dir_get(wiz_module);
|
|
}
|
|
|
|
EINTERN void
|
|
wizard_xdg_desktops_reset(void)
|
|
{
|
|
if (xdg_error) return;
|
|
got_desktops = EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
_wizard_next_eval(void)
|
|
{
|
|
int ok;
|
|
|
|
ok = next_can;
|
|
if (!next_ok) ok = 0;
|
|
if (next_prev != ok)
|
|
{
|
|
if (ok)
|
|
{
|
|
edje_object_part_text_set(o_bg, "e.text.label", _("Next"));
|
|
edje_object_signal_emit(o_bg, "e,state,next,enable", "e");
|
|
}
|
|
else
|
|
{
|
|
edje_object_part_text_set(o_bg, "e.text.label", _("Please Wait..."));
|
|
edje_object_signal_emit(o_bg, "e,state,next,disable", "e");
|
|
}
|
|
next_prev = ok;
|
|
}
|
|
}
|
|
|
|
static Evas_Object *
|
|
_wizard_main_new(E_Zone *zone)
|
|
{
|
|
o_bg = edje_object_add(e_comp->evas);
|
|
|
|
e_theme_edje_object_set(o_bg, "base/theme/wizard", "e/wizard/main");
|
|
edje_object_part_text_set(o_bg, "e.text.title", _("Welcome to Enlightenment"));
|
|
edje_object_signal_callback_add(o_bg, "e,action,next", "",
|
|
_wizard_cb_next, o_bg);
|
|
evas_object_geometry_set(o_bg, zone->x, zone->y, zone->w, zone->h);
|
|
evas_object_layer_set(o_bg, E_LAYER_POPUP);
|
|
|
|
/* set up next/prev buttons */
|
|
// edje_object_signal_emit(o_bg, "e,state,next,disable", "e");
|
|
wizard_labels_update();
|
|
|
|
o_box = elm_box_add(e_comp->elm);
|
|
edje_object_part_swallow(o_bg, "e.swallow.content", o_box);
|
|
|
|
evas_object_show(o_bg);
|
|
return o_bg;
|
|
}
|
|
|
|
static Evas_Object *
|
|
_wizard_extra_new(E_Zone *zone)
|
|
{
|
|
Evas_Object *o;
|
|
|
|
o = edje_object_add(e_comp->evas);
|
|
e_theme_edje_object_set(o, "base/theme/wizard", "e/wizard/extra");
|
|
evas_object_geometry_set(o, zone->x, zone->y, zone->w, zone->h);
|
|
evas_object_layer_set(o, E_LAYER_POPUP);
|
|
evas_object_show(o);
|
|
return o;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_wizard_cb_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
{
|
|
Ecore_Event_Key *ev = event;
|
|
|
|
if (!o_content) return ECORE_CALLBACK_RENEW;
|
|
if (!strcmp(ev->key, "Tab"))
|
|
{
|
|
if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
|
|
elm_object_focus_next(o_content, ELM_FOCUS_PREVIOUS);
|
|
else
|
|
elm_object_focus_next(o_content, ELM_FOCUS_NEXT);
|
|
}
|
|
else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
|
|
{
|
|
if (next_can)
|
|
wizard_next();
|
|
}
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static void
|
|
_wizard_cb_next(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
|
|
{
|
|
/* TODO: Disable button in theme */
|
|
if (next_can)
|
|
wizard_next();
|
|
}
|
|
|
|
static Eina_Bool
|
|
_wizard_check_xdg(void)
|
|
{
|
|
if ((need_xdg_desktops) && (!got_desktops))
|
|
{
|
|
/* Advance within 15 secs if no xdg event */
|
|
if (!next_timer)
|
|
next_timer = ecore_timer_loop_add(7.0, _wizard_cb_next_page, NULL);
|
|
next_can = 0;
|
|
_wizard_next_eval();
|
|
return 0;
|
|
}
|
|
if ((need_xdg_icons) && (!got_icons))
|
|
{
|
|
char path[PATH_MAX];
|
|
|
|
/* Check if cache already exists */
|
|
snprintf(path, sizeof(path), "%s/efreet/icon_themes_%s.eet",
|
|
efreet_cache_home_get(), efreet_hostname_get());
|
|
if (ecore_file_exists(path))
|
|
{
|
|
got_icons = EINA_TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Advance within 15 secs if no xdg event */
|
|
if (!next_timer)
|
|
next_timer = ecore_timer_loop_add(7.0, _wizard_cb_next_page, NULL);
|
|
next_can = 0;
|
|
_wizard_next_eval();
|
|
return 0;
|
|
}
|
|
}
|
|
next_can = 1;
|
|
need_xdg_desktops = EINA_FALSE;
|
|
need_xdg_icons = EINA_FALSE;
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
_wizard_next_xdg(void)
|
|
{
|
|
need_xdg_desktops = EINA_FALSE;
|
|
need_xdg_icons = EINA_FALSE;
|
|
|
|
if (next_timer) ecore_timer_del(next_timer);
|
|
next_timer = NULL;
|
|
if (curpage->state != E_WIZARD_PAGE_STATE_SHOW)
|
|
{
|
|
if (next_ok) return; // waiting for user
|
|
wizard_next();
|
|
}
|
|
else if ((curpage->show) && (!curpage->show(curpage)))
|
|
{
|
|
curpage->state++;
|
|
wizard_next();
|
|
}
|
|
else
|
|
curpage->state++;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_wizard_cb_next_page(void *data EINA_UNUSED)
|
|
{
|
|
next_timer = NULL;
|
|
_wizard_next_xdg();
|
|
return ECORE_CALLBACK_CANCEL;
|
|
}
|
|
|
|
|
|
static Eina_Bool
|
|
_wizard_cb_desktops_update(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev)
|
|
{
|
|
Efreet_Event_Cache_Update *e;
|
|
|
|
e = ev;
|
|
/* TODO: Tell user he should fix his dbus setup */
|
|
if ((e) && (e->error))
|
|
xdg_error = EINA_TRUE;
|
|
got_desktops = EINA_TRUE;
|
|
if (_wizard_check_xdg() && curpage)
|
|
_wizard_next_xdg();
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_wizard_cb_icons_update(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
|
|
{
|
|
got_icons = EINA_TRUE;
|
|
if (_wizard_check_xdg() && curpage)
|
|
_wizard_next_xdg();
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
}
|