/* * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #include "e.h" #include "e_mod_main.h" /* TODO List: * * should support proper resize and move handles in the edje. * */ /* module private routines */ static Pager *_pager_init(E_Module *m); static void _pager_shutdown(Pager *e); static E_Menu *_pager_config_menu_new(Pager *e); static void _pager_config_menu_del(Pager *e, E_Menu *m); static void _pager_cb_down(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _pager_cb_up(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _pager_cb_move(void *data, Evas *e, Evas_Object *obj, void *event_info); static int _pager_cb_event_container_resize(void *data, int type, void *event); static int _pager_cb_event_border_events(void *data, int type, void *event); static void _pager_reconfigure(Pager *e); static void _pager_refresh(Pager *e); #define PAGER_MIN_W 10 #define PAGER_MIN_H 7 /* public module routines. all modules must have these */ void * init(E_Module *m) { Pager *e; /* check module api version */ if (m->api->version < E_MODULE_API_VERSION) { e_error_dialog_show("Module API Error", "Error initializing Module: Pager\n" "It requires a minimum module API version of: %i.\n" "The module API advertized by Enlightenment is: %i.\n" "Aborting module.", E_MODULE_API_VERSION, m->api->version); return NULL; } /* actually init pager */ e = _pager_init(m); m->config_menu = _pager_config_menu_new(e); return e; } int shutdown(E_Module *m) { Pager *e; e = m->data; if (e) { if (m->config_menu) { _pager_config_menu_del(e, m->config_menu); m->config_menu = NULL; } _pager_shutdown(e); } return 1; } int save(E_Module *m) { Pager *e; e = m->data; e_config_domain_save("module.pager", e->conf_edd, e->conf); return 1; } int info(E_Module *m) { char buf[4096]; m->label = strdup("Pager"); snprintf(buf, sizeof(buf), "%s/module_icon.png", e_module_dir_get(m)); m->icon_file = strdup(buf); return 1; } int about(E_Module *m) { e_error_dialog_show("Enlightenment Pager Module", "A pager module to navigate E17 desktops."); return 1; } /* module private routines */ static Pager * _pager_init(E_Module *m) { Pager *e; Evas_List *managers, *l, *l2; Evas_Object *o; e = calloc(1, sizeof(Pager)); if (!e) return NULL; e->conf_edd = E_CONFIG_DD_NEW("Pager_Config", Config); #undef T #undef D #define T Config #define D e->conf_edd E_CONFIG_VAL(D, T, width, INT); E_CONFIG_VAL(D, T, height, INT); E_CONFIG_VAL(D, T, x, DOUBLE); E_CONFIG_VAL(D, T, y, DOUBLE); e->conf = e_config_domain_load("module.pager", e->conf_edd); if (!e->conf) { e->conf = E_NEW(Config, 1); e->conf->width = 50; e->conf->height = 30; e->conf->x = 0.0; e->conf->y = 0.0; } E_CONFIG_LIMIT(e->conf->x, 0.0, 1.0); E_CONFIG_LIMIT(e->conf->y, 0.0, 1.0); E_CONFIG_LIMIT(e->conf->width, PAGER_MIN_W, 1000); E_CONFIG_LIMIT(e->conf->height, PAGER_MIN_H, 1000); managers = e_manager_list(); for (l = managers; l; l = l->next) { E_Manager *man; man = l->data; for (l2 = man->containers; l2; l2 = l2->next) { E_Container *con; con = l2->data; e->con = con; e->evas = con->bg_evas; } } o = evas_object_rectangle_add(e->evas); e->base = o; evas_object_color_set(o, 128, 128, 128, 0); evas_object_pass_events_set(o, 0); evas_object_repeat_events_set(o, 0); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _pager_cb_down, e); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _pager_cb_up, e); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _pager_cb_move, e); evas_object_show(o); o = edje_object_add(e->evas); e->screen = o; edje_object_file_set(o, /* FIXME: "default.eet" needs to come from conf */ e_path_find(path_themes, "default.eet"), "modules/pager/screen"); evas_object_show(o); e->ev_handler_container_resize = ecore_event_handler_add(E_EVENT_CONTAINER_RESIZE, _pager_cb_event_container_resize, e); e->ev_handler_border_resize = ecore_event_handler_add(E_EVENT_BORDER_RESIZE, _pager_cb_event_border_events, e); e->ev_handler_border_move = ecore_event_handler_add(E_EVENT_BORDER_MOVE, _pager_cb_event_border_events, e); e->ev_handler_border_add = ecore_event_handler_add(E_EVENT_BORDER_ADD, _pager_cb_event_border_events, e); e->ev_handler_border_remove = ecore_event_handler_add(E_EVENT_BORDER_REMOVE, _pager_cb_event_border_events, e); e->ev_handler_border_hide = ecore_event_handler_add(E_EVENT_BORDER_HIDE, _pager_cb_event_border_events, e); e->ev_handler_border_show = ecore_event_handler_add(E_EVENT_BORDER_SHOW, _pager_cb_event_border_events, e); e->ev_handler_border_desk_set = ecore_event_handler_add(E_EVENT_BORDER_DESK_SET, _pager_cb_event_border_events, e); _pager_reconfigure(e); return e; } static void _pager_shutdown(Pager *e) { free(e->conf); E_CONFIG_DD_FREE(e->conf_edd); evas_object_del(e->base); evas_object_free(e->base); evas_object_del(e->screen); evas_object_free(e->screen); while(e->desks) { evas_object_del(e->desks->data); evas_object_free(e->desks->data); e->desks = evas_list_remove_list(e->desks, e->desks); } while(e->wins) { evas_object_del(e->wins->data); evas_object_free(e->wins->data); e->wins = evas_list_remove_list(e->wins, e->wins); } ecore_event_handler_del(e->ev_handler_container_resize); ecore_event_handler_del(e->ev_handler_border_move); ecore_event_handler_del(e->ev_handler_border_add); ecore_event_handler_del(e->ev_handler_border_remove); ecore_event_handler_del(e->ev_handler_border_hide); ecore_event_handler_del(e->ev_handler_border_show); ecore_event_handler_del(e->ev_handler_border_desk_set); free(e); } static E_Menu * _pager_config_menu_new(Pager *e) { E_Menu *mn; E_Menu_Item *mi; mn = e_menu_new(); mi = e_menu_item_new(mn); e_menu_item_label_set(mi, "(Unused)"); e->config_menu = mn; return mn; } static void _pager_config_menu_del(Pager *e, E_Menu *m) { e_object_del(E_OBJECT(m)); } static void _pager_reconfigure(Pager *e) { Evas_Coord ww, hh; E_Zone *zone; int xcount, ycount; evas_output_viewport_get(e->evas, NULL, NULL, &ww, &hh); e->fx = e->conf->x * (ww - e->conf->width); e->fy = e->conf->y * (hh - e->conf->height); e->fw = e->conf->width; e->fh = e->conf->height; zone = e_zone_current_get(e->con); e_zone_desk_count_get(zone, &xcount, &ycount); e->tw = e->fw * xcount; e->th = e->fh * ycount; _pager_refresh(e); } static void _pager_refresh(Pager *e) { E_Zone *zone; E_Desk *desk, *current; E_Border *border; Evas_List *clients, *desks, *wins; Evas_Object *desk_obj, *win_obj; int desks_x, desks_y, x, y, top, toptmp; Evas_Coord px, py, ww, hh; double scalex, scaley; zone = e_zone_current_get(e->con); e_zone_desk_count_get(zone, &desks_x, &desks_y); evas_object_resize(e->base, e->fw * desks_x, e->fh * desks_y); evas_object_move(e->base, e->fx, e->fy); evas_output_viewport_get(e->evas, NULL, NULL, &ww, &hh); scalex = (double) e->fw / ww; scaley = (double) e->fh / hh; evas_object_resize(e->screen, e->fw, e->fh); desks = e->desks; wins = e->wins; current = e_desk_current_get(zone); for (x = 0; x < desks_x; x++) for (y = 0; y < desks_y; y++) { desk = e_desk_at_xy_get(zone, x, y); px = e->fx + (x * e->fw); py = e->fy + (y * e->fh); if (desks) { desk_obj = (Evas_Object *) desks->data; /* re-use the objects if possible */ desks = desks->next; } else { desk_obj = edje_object_add(e->evas); edje_object_file_set(desk_obj, /* FIXME: "default.eet" needs to come from conf */ e_path_find(path_themes, "default.eet"), "modules/pager/desk"); evas_object_pass_events_set(desk_obj, 1); e->desks = evas_list_append(e->desks, desk_obj); } evas_object_resize(desk_obj, e->fw, e->fh); evas_object_move(desk_obj, px, py); evas_object_show(desk_obj); top = evas_object_layer_get(desk_obj); clients = desk->clients; while (clients) { Evas_Coord winx, winy, winw, winh; border = (E_Border *) clients->data; if (border->iconic) { clients = clients->next; continue; } winx = (Evas_Coord) ((double) border->x) * scalex; winy = (Evas_Coord) ((double) border->y) * scaley; winw = (Evas_Coord) ((double) border->w) * scalex; winh = (Evas_Coord) ((double) border->h) * scaley; if (wins) { win_obj = (Evas_Object *) wins->data; wins = wins->next; } else { win_obj = edje_object_add(e->evas); edje_object_file_set(win_obj, /* FIXME: "default.eet" needs to come from conf */ e_path_find(path_themes, "default.eet"), "modules/pager/window"); evas_object_pass_events_set(win_obj, 1); e->wins = evas_list_append(e->wins, win_obj); } evas_object_resize(win_obj, winw, winh); evas_object_move(win_obj, px + winx, py + winy); evas_object_show(win_obj); toptmp = evas_object_layer_get(win_obj); if (toptmp > top) top = toptmp; clients = clients->next; } if (desk == current) { evas_object_move(e->screen, px, py); evas_object_layer_set(e->screen, top + 1); } } /* hide objects not needed; */ while (desks) { desk_obj = (Evas_Object *) desks->data; evas_object_hide(desk_obj); desks = desks->next; } while (wins) { win_obj = (Evas_Object *) wins->data; evas_object_hide(win_obj); wins = wins->next; } } static void _pager_cb_down(void *data, Evas *e, Evas_Object *obj, void *event_info) { Evas_Event_Mouse_Down *ev; Pager *p; ev = event_info; p = data; if (ev->button == 3) { e_menu_activate_mouse(p->config_menu, e_zone_current_get(p->con), ev->output.x, ev->output.y, 1, 1, E_MENU_POP_DIRECTION_DOWN); e_util_container_fake_mouse_up_all_later(p->con); } else if (ev->button == 2) { p->resize = 1; } else if (ev->button == 1) { p->move = 1; } evas_pointer_canvas_xy_get(p->evas, &p->xx, &p->yy); p->clickhackx = p->xx; p->clickhacky = p->yy; } static void _pager_cb_up(void *data, Evas *e, Evas_Object *obj, void *event_info) { Evas_Event_Mouse_Up *ev; Pager *p; Evas_Coord xx, yy, ww, hh; ev = event_info; p = data; evas_output_viewport_get(p->evas, NULL, NULL, &ww, &hh); /* if we clicked, not moved - FIXME, this is a hack */ if (p->move && (p->xx == p->clickhackx) && (p->yy == p->clickhacky)) { int x, y, w, h, xcount, ycount, cx, cy; E_Zone *zone; E_Desk *desk; zone = e_zone_current_get(p->con); e_zone_desk_count_get(zone, &xcount, &ycount); evas_pointer_canvas_xy_get(e, &cx, &cy); w = p->fw; h = p->fh; for (x = 0; x < xcount; x++) for (y = 0; y < ycount; y++) { int left, right, top, bottom; left = p->fx + x * w; right = left + w; top = p->fy + y * h; bottom = top + h; if (left <= cx && cx < right && top <= cy && cy < bottom) { desk = e_desk_at_xy_get(zone, x, y); e_desk_show(desk); evas_object_move(p->screen, left, top); } } } p->move = 0; p->resize = 0; p->conf->width = p->fw; p->conf->height = p->fh; p->conf->x = (double)p->fx / (double)(ww - p->fw); p->conf->y = (double)p->fy / (double)(hh - p->fh); e_config_save_queue(); } static void _pager_cb_move(void *data, Evas *e, Evas_Object *obj, void *event_info) { Evas_Event_Mouse_Move *ev; Pager *p; Evas_Coord cx, cy, sw, sh, tw, th; E_Zone *zone; int xcount, ycount; evas_pointer_canvas_xy_get(e, &cx, &cy); evas_output_viewport_get(e, NULL, NULL, &sw, &sh); ev = event_info; p = data; zone = e_zone_current_get(p->con); e_zone_desk_count_get(zone, &xcount, &ycount); /* note that these are not the same as p->tw, as that could be slightly larger (rounding etc) these will vie exactly the right result */ tw = p->fw * xcount; th = p->fh * ycount; if (p->move) { p->fx += cx - p->xx; p->fy += cy - p->yy; if (p->fx < 0) p->fx = 0; if (p->fy < 0) p->fy = 0; if (p->fx + tw > sw) p->fx = sw - tw; if (p->fy + th > sh) p->fy = sh - th; _pager_refresh(p); } else if (p->resize) { Evas_Coord dx, dy; E_Zone *zone; int xcount, ycount; zone = e_zone_current_get(p->con); e_zone_desk_count_get(zone, &xcount, &ycount); dx = cx - p->xx; dy = cy - p->yy; p->tw += dx; p->th += dy; p->fw = p->tw / xcount; p->fh = p->th / ycount; if (p->fw < PAGER_MIN_W) p->fw = PAGER_MIN_W; if (p->fh < PAGER_MIN_H) p->fh = PAGER_MIN_H; if (p->fx + p->tw > sw) { p->tw = sw - p->fx; p->fw = p->tw / xcount; } if (p->fy + p->th > sh) { p->th = sh - p->fy; p->fh = p->th / ycount; } _pager_refresh(p); } p->xx = ev->cur.canvas.x; p->yy = ev->cur.canvas.y; } static int _pager_cb_event_container_resize(void *data, int type, void *event) { Pager *e; e = data; _pager_reconfigure(e); return 1; } static int _pager_cb_event_border_events(void *data, int type, void *event) { Pager *e; e = data; _pager_refresh(e); return 1; }