okra pushed a commit to branch master. http://git.enlightenment.org/core/enlightenment.git/commit/?id=57f854bc594c3978792a3cf323f9858d5f814f52
commit 57f854bc594c3978792a3cf323f9858d5f814f52 Author: Stephen okra Houston <smhousto...@gmail.com> Date: Tue Nov 22 21:17:22 2016 -0600 Luncher: Add the second gadget to luncher: Luncher Grid. Use this gadget on your desktop for a grid of icons to be used to launch applications. The grid is simply a launcher and doesn't have all of the features that the bar has such as iconify, taskbar, styles, etc... Please make sure to update your efl with this to get the related theme updates. --- src/modules/Makefile_luncher.mk | 1 + src/modules/luncher/bar.c | 18 +- src/modules/luncher/grid.c | 789 ++++++++++++++++++++++++++++++++++++++++ src/modules/luncher/luncher.h | 4 + src/modules/luncher/mod.c | 2 + 5 files changed, 806 insertions(+), 8 deletions(-) diff --git a/src/modules/Makefile_luncher.mk b/src/modules/Makefile_luncher.mk index b8fa862..f7bcb63 100644 --- a/src/modules/Makefile_luncher.mk +++ b/src/modules/Makefile_luncher.mk @@ -15,6 +15,7 @@ src_modules_luncher_module_la_LDFLAGS = $(MOD_LDFLAGS) src_modules_luncher_module_la_SOURCES = src/modules/luncher/mod.c \ src/modules/luncher/luncher.h \ src/modules/luncher/bar.c \ + src/modules/luncher/grid.c \ src/modules/luncher/config.c PHONIES += luncher install-luncher diff --git a/src/modules/luncher/bar.c b/src/modules/luncher/bar.c index cb5a5cf..5f34708 100644 --- a/src/modules/luncher/bar.c +++ b/src/modules/luncher/bar.c @@ -918,7 +918,8 @@ _bar_icon_add(Instance *inst, Efreet_Desktop *desktop, E_Client *non_desktop_cli snprintf(ori, sizeof(ori), "e,state,off,%s", _bar_location_get(inst)); elm_layout_signal_emit(ic->o_layout, ori, "e"); msg = alloca(sizeof(Edje_Message_Int_Set)); - msg->str = strdup(inst->cfg->style); + if (inst->cfg->style) + msg->str = strdup(inst->cfg->style); edje_object_message_send(elm_layout_edje_get(ic->o_layout), EDJE_MESSAGE_STRING, 1, msg); ic->o_icon = elm_icon_add(ic->o_layout); @@ -1074,9 +1075,8 @@ _bar_cb_client_remove(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Clie { Icon *ic = NULL; - if (ev->ec) - ic = _bar_icon_match(inst, ev->ec); - + if (!inst->bar) continue; + if (ev->ec) ic = _bar_icon_match(inst, ev->ec); if (ic) { if (ic->starting) elm_layout_signal_emit(ic->o_layout, "e,state,started", "e"); @@ -1117,6 +1117,7 @@ _bar_cb_exec_del(void *data EINA_UNUSED, int type EINA_UNUSED, E_Exec_Instance * { Icon *ic = NULL; + if (!inst->bar) continue; if (ex->desktop) { ic = eina_hash_find(inst->icons_desktop_hash, ex->desktop->orig_path); @@ -1181,8 +1182,8 @@ _bar_cb_exec_client_prop(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_C Icon *ic = NULL; char ori[32]; + if (!inst->bar) continue; ic = _bar_icon_match(inst, ev->ec); - if (skip && !ic) continue; if (!skip) { @@ -1275,9 +1276,8 @@ _bar_cb_exec_new(void *data EINA_UNUSED, int type, E_Exec_Instance *ex) Icon *ic = NULL; char ori[32]; - if (ec) - ic = _bar_icon_match(inst, ec); - + if (!inst->bar) continue; + if (ec) ic = _bar_icon_match(inst, ec); if (ic) { if (skip) continue; @@ -1519,6 +1519,7 @@ _bar_cb_update_icons(EINA_UNUSED void *data, EINA_UNUSED int ev_type, EINA_UNUSE EINA_LIST_FOREACH(luncher_instances, l, inst) { + if (!inst->bar) continue; if (inst->resize_job) return ECORE_CALLBACK_RENEW; inst->resize_job = ecore_job_add(_bar_resize_job, inst); } @@ -1922,6 +1923,7 @@ bar_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient EINA_UNUSED *id = inst->cfg->id; inst->inside = EINA_FALSE; inst->effect = EINA_FALSE; + inst->bar = EINA_TRUE; inst->icons_desktop_hash = eina_hash_string_superfast_new(NULL); inst->icons_clients_hash = eina_hash_pointer_new(NULL); inst->o_main = elm_layout_add(parent); diff --git a/src/modules/luncher/grid.c b/src/modules/luncher/grid.c new file mode 100644 index 0000000..861610f --- /dev/null +++ b/src/modules/luncher/grid.c @@ -0,0 +1,789 @@ +#include "luncher.h" +static Eina_List *handlers; +static Elm_Gengrid_Item_Class _grid_icon_class; +static void _grid_resize_job(void *data); + +static void +_grid_aspect(Instance *inst) +{ + Evas_Coord w, h, square, root, cell, size; + + evas_object_size_hint_aspect_set(inst->o_main, EVAS_ASPECT_CONTROL_BOTH, 1, 1); + if (!eina_list_count(inst->icons)) + return; + evas_object_geometry_get(inst->o_main, 0, 0, &w, &h); + size = 0; + if ((w + h) > 1) + { + square = w + h; + size = floor((square / eina_list_count(inst->icons))); + } + inst->size = size; + elm_gengrid_item_size_set(inst->o_icon_con, size, size); +} + +static Eina_Bool +_grid_check_modifiers(Evas_Modifier *modifiers) +{ + if ((evas_key_modifier_is_set(modifiers, "Alt")) || + (evas_key_modifier_is_set(modifiers, "Control")) || + (evas_key_modifier_is_set(modifiers, "Shift"))) + return EINA_TRUE; + return EINA_FALSE; +} + +static Evas_Object * +_grid_gadget_configure(Evas_Object *g) +{ + if (!luncher_config) return NULL; + if (luncher_config->config_dialog) return NULL; + Instance *inst = evas_object_data_get(g, "instance"); + return config_luncher(e_zone_current_get(), inst, EINA_TRUE); +} + +static void +_grid_instance_watch(void *data, E_Exec_Instance *ex, E_Exec_Watch_Type type) +{ + Icon *ic = data; + + switch (type) + { + case E_EXEC_WATCH_STARTED: + if (ic->starting) elm_layout_signal_emit(ic->o_layout, "e,state,started", "e"); + ic->starting = EINA_FALSE; + break; + default: + break; + } +} + +static void +_grid_icon_del(Instance *inst, Icon *ic) +{ + inst->icons = eina_list_remove(inst->icons, ic); + evas_object_del(ic->o_icon); + evas_object_del(ic->o_overlay); + evas_object_del(ic->o_layout); + if (ic->desktop) + efreet_desktop_unref(ic->desktop); + eina_stringshare_del(ic->icon); + eina_stringshare_del(ic->key); + if (ic->exec) + e_exec_instance_watcher_del(ic->exec, _grid_instance_watch, ic); + ic->exec = NULL; + _grid_aspect(inst); + E_FREE(ic); +} + +static void +_grid_icon_drag_done(E_Drag *drag, int dropped) +{ + Instance *inst = e_object_data_get(E_OBJECT(drag)); + + efreet_desktop_unref(drag->data); + if (!inst) return; + evas_object_smart_callback_call(e_gadget_site_get(inst->o_main), "gadget_site_unlocked", NULL); + if (!dropped) + grid_recalculate(inst); +} + +static void +_grid_icon_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data) +{ + Icon *ic = data; + Evas_Event_Mouse_Move *ev = event_data; + int dx, dy; + + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; + if (_grid_check_modifiers(ev->modifiers)) return; + + if (!ic->drag.start) return; + + dx = ev->cur.output.x - ic->drag.x; + dy = ev->cur.output.y - ic->drag.y; + if (((dx * dx) + (dy * dy)) > + (e_config->drag_resist * e_config->drag_resist)) + { + E_Drag *d; + Evas_Object *o; + Evas_Coord x, y, w, h; + unsigned int size; + const char *drag_types[] = { "enlightenment/desktop" }; + + ic->drag.dnd = 1; + ic->drag.start = 0; + + evas_object_geometry_get(ic->o_icon, &x, &y, &w, &h); + d = e_drag_new(x, y, drag_types, 1, + ic->desktop, -1, NULL, _grid_icon_drag_done); + d->button_mask = evas_pointer_button_down_mask_get(e_comp->evas); + efreet_desktop_ref(ic->desktop); + size = MAX(w, h); + o = e_util_desktop_icon_add(ic->desktop, size, e_drag_evas_get(d)); + e_drag_object_set(d, o); + + e_drag_resize(d, w, h); + e_drag_start(d, ic->drag.x, ic->drag.y); + e_object_data_set(E_OBJECT(d), ic->inst); + if (ic->in_order) + e_order_remove(ic->inst->order, ic->desktop); + } +} + +static Eina_Bool +_grid_drag_timer(void *data) +{ + Icon *ic = data; + + ic->drag_timer = NULL; + ic->drag.start = 1; + evas_object_smart_callback_call(e_gadget_site_get(ic->inst->o_main), "gadget_site_locked", NULL); + return EINA_FALSE; +} + +static void +_grid_icon_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data) +{ + Icon *ic = data; + Evas_Event_Mouse_Up *ev = event_data; + + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; + if (_grid_check_modifiers(ev->modifiers)) return; + + if (ev->button == 1) + { + ic->drag.x = ev->output.x; + ic->drag.y = ev->output.y; + E_FREE_FUNC(ic->drag_timer, ecore_timer_del); + ic->drag_timer = ecore_timer_add(.35, _grid_drag_timer, ic); + } + if (ev->button == 3) + { + e_gadget_configure(ic->inst->o_main); + } +} + +static void +_grid_icon_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data) +{ + Icon *ic = data; + Evas_Event_Mouse_Up *ev = event_data; + + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; + if (_grid_check_modifiers(ev->modifiers)) return; + + if (ev->button == 1) + { + E_FREE_FUNC(ic->drag_timer, ecore_timer_del); + if (ic->drag.dnd) + { + ic->drag.start = 0; + ic->drag.dnd = 0; + return; + } + } + if (ev->button == 1 && ic->desktop) + { + if (ic->desktop->type == EFREET_DESKTOP_TYPE_APPLICATION) + { + E_Exec_Instance *ex; + + ex = e_exec(e_zone_current_get(), ic->desktop, NULL, NULL, "luncher"); + ic->exec = ex; + e_exec_instance_watcher_add(ex, _grid_instance_watch, ic); + if (!ic->starting) elm_layout_signal_emit(ic->o_layout, "e,state,starting", "e"); + ic->starting = EINA_TRUE; + } + else if (ic->desktop->type == EFREET_DESKTOP_TYPE_LINK) + { + if (!strncasecmp(ic->desktop->url, "file:", 5)) + { + E_Action *act; + + act = e_action_find("fileman"); + if (act) + act->func.go(NULL, ic->desktop->url + 5); + } + } + } +} + +static void +_grid_icon_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_data) +{ + Icon *ic = data; + Evas_Event_Mouse_In *ev = event_data; + + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; + if (_grid_check_modifiers(ev->modifiers)) return; + + evas_object_raise(ic->o_layout); + elm_object_tooltip_show(obj); + ic->active = EINA_TRUE; + elm_layout_signal_emit(ic->o_layout, "e,state,focused", "e"); +} + +static void +_grid_icon_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_data EINA_UNUSED) +{ + Icon *ic = data; + + elm_object_tooltip_hide(obj); + elm_layout_signal_emit(ic->o_layout, "e,state,unfocused", "e"); +} + +static Evas_Object * +_gengrid_icon_get(void *data, Evas_Object *obj, + const char *part) +{ + Icon *ic = data; + if (strcmp(part, "elm.swallow.icon")) + return NULL; + return ic->o_layout; +} + +static Icon * +_grid_icon_add(Instance *inst, Efreet_Desktop *desktop) +{ + const char *path = NULL, *k = NULL; + char buf[4096]; + int len = 0; + Icon *ic; + + ic = E_NEW(Icon, 1); + if (desktop) + efreet_desktop_ref(desktop); + ic->desktop = desktop; + ic->inst = inst; + ic->preview = NULL; + ic->preview_box = NULL; + ic->mouse_in_timer = NULL; + ic->mouse_out_timer = NULL; + ic->active = EINA_FALSE; + ic->starting = EINA_FALSE; + ic->exec = NULL; + + ic->o_layout = elm_layout_add(inst->o_icon_con); + e_theme_edje_object_set(ic->o_layout, "e/gadget/luncher/icon", + "e/gadget/luncher/icon"); + E_FILL(ic->o_layout); + evas_object_show(ic->o_layout); + + ic->o_icon = elm_icon_add(ic->o_layout); + E_EXPAND(ic->o_icon); + + ic->o_overlay = elm_icon_add(ic->o_layout); + E_EXPAND(ic->o_overlay); + + if (!desktop->icon) + path = NULL; + else if (strncmp(desktop->icon, "/", 1) && !ecore_file_exists(desktop->icon)) + { + path = efreet_icon_path_find(e_config->icon_theme, desktop->icon, inst->size); + if (!path) + { + if (e_util_strcmp(e_config->icon_theme, "hicolor")) + path = efreet_icon_path_find("hicolor", desktop->icon, inst->size); + } + } + else if (ecore_file_exists(desktop->icon)) + { + path = desktop->icon; + } + if (!path) + { + snprintf(buf, sizeof(buf), "e/icons/%s", desktop->icon); + if (eina_list_count(e_theme_collection_items_find("base/theme/icons", buf))) + { + path = e_theme_edje_file_get("base/theme/icons", buf); + k = buf; + } + else + { + path = e_theme_edje_file_get("base/theme/icons", "e/icons/unknown"); + k = "e/icons/unknown"; + } + if (path && desktop->icon && !k) + { + len = strlen(desktop->icon); + if ((len > 4) && (!strcasecmp(desktop->icon + len - 4, ".edj"))) + k = "icon"; + } + } + elm_image_file_set(ic->o_icon, path, k); + elm_object_tooltip_text_set(ic->o_icon, desktop->name); + elm_object_tooltip_orient_set(ic->o_icon, ELM_TOOLTIP_ORIENT_CENTER); + elm_object_tooltip_style_set(ic->o_icon, "luncher"); + evas_object_size_hint_aspect_set(ic->o_icon, EVAS_ASPECT_CONTROL_BOTH, 1, 1); + elm_layout_content_set(ic->o_layout, "e.swallow.icon", ic->o_icon); + evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_UP, + _grid_icon_mouse_up, ic); + evas_object_event_callback_priority_add(ic->o_icon, EVAS_CALLBACK_MOUSE_DOWN, 0, + _grid_icon_mouse_down, ic); + evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_MOVE, + _grid_icon_mouse_move, ic); + evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_IN, + _grid_icon_mouse_in, ic); + evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_OUT, + _grid_icon_mouse_out, ic); + evas_object_show(ic->o_icon); + + elm_image_file_set(ic->o_overlay, path, k); + evas_object_size_hint_aspect_set(ic->o_overlay, EVAS_ASPECT_CONTROL_BOTH, 1, 1); + elm_layout_content_set(ic->o_layout, "e.swallow.overlay", ic->o_overlay); + evas_object_show(ic->o_overlay); + + elm_layout_sizing_eval(ic->o_layout); + + elm_gengrid_item_append(inst->o_icon_con, &_grid_icon_class, ic, NULL, NULL); + _grid_aspect(inst); + + return ic; +} + +static void +_grid_empty(Instance *inst) +{ + if (inst->icons) + { + Icon *ic; + Eina_List *l; + + elm_gengrid_clear(inst->o_icon_con); + EINA_LIST_FOREACH(inst->icons, l, ic) + _grid_icon_del(inst, ic); + eina_list_free(inst->icons); + inst->icons = NULL; + } +} + +static void +_grid_fill(Instance *inst) +{ + Icon *ic; + + if (inst->order) + { + Efreet_Desktop *desktop; + Eina_List *list; + + EINA_LIST_FOREACH(inst->order->desktops, list, desktop) + { + ic = _grid_icon_add(inst, desktop); + ic->in_order = EINA_TRUE; + inst->icons = eina_list_append(inst->icons, ic); + } + } +} + +static void +_grid_resize_job(void *data) +{ + Instance *inst = data; + Eina_List *l; + Icon *ic; + + if (inst) + { + elm_layout_sizing_eval(inst->o_main); + _grid_aspect(inst); + EINA_LIST_FOREACH(inst->icons, l, ic) + { + const char *path = NULL, *key = NULL; + int len = 0; + + if (ic->desktop) + { + if (!ic->desktop->icon) + path = NULL; + else if (strncmp(ic->desktop->icon, "/", 1) && !ecore_file_exists(ic->desktop->icon)) + { + path = efreet_icon_path_find(e_config->icon_theme, ic->desktop->icon, inst->size); + if (!path) + { + if (e_util_strcmp(e_config->icon_theme, "hicolor")) + path = efreet_icon_path_find("hicolor", ic->desktop->icon, inst->size); + } + } + else if (ecore_file_exists(ic->desktop->icon)) + { + path = ic->desktop->icon; + } + if (!path) + { + elm_image_file_set(ic->o_icon, e_theme_edje_file_get("base/theme/icons", "e/icons/unknown"), + "e/icons/unknown"); + elm_image_file_set(ic->o_overlay, e_theme_edje_file_get("base/theme/icons", "e/icons/unknown"), + "e/icons/unknown"); + } + if (path && ic->desktop->icon) + { + len = strlen(ic->desktop->icon); + if ((len > 4) && (!strcasecmp(ic->desktop->icon + len - 4, ".edj"))) + key = "icon"; + + elm_image_file_set(ic->o_icon, path, key); + elm_image_file_set(ic->o_overlay, path, key); + } + } + else if (ic->icon) + { + if (strncmp(ic->icon, "/", 1) && !ecore_file_exists(ic->icon)) + { + path = efreet_icon_path_find(e_config->icon_theme, ic->icon, inst->size); + if (!path) + { + if (e_util_strcmp(e_config->icon_theme, "hicolor")) + path = efreet_icon_path_find("hicolor", ic->icon, inst->size); + } + } + else if (ecore_file_exists(ic->icon)) + { + path = ic->icon; + } + if (!path) + { + elm_image_file_set(ic->o_icon, e_theme_edje_file_get("base/theme/icons", "e/icons/unknown"), + "e/icons/unknown"); + elm_image_file_set(ic->o_overlay, e_theme_edje_file_get("base/theme/icons", "e/icons/unknown"), + "e/icons/unknown"); + } + else + { + elm_image_file_set(ic->o_icon, path, ic->key); + elm_image_file_set(ic->o_overlay, path, ic->key); + } + } + else + { + elm_image_file_set(ic->o_icon, e_theme_edje_file_get("base/theme/icons", "e/icons/unknown"), + "e/icons/unknown"); + elm_image_file_set(ic->o_overlay, e_theme_edje_file_get("base/theme/icons", "e/icons/unknown"), + "e/icons/unknown"); + } + } + inst->resize_job = NULL; + } +} + +static Eina_Bool +_grid_cb_update_icons(EINA_UNUSED void *data, EINA_UNUSED int ev_type, EINA_UNUSED void *ev) +{ + Instance *inst = NULL; + Eina_List *l = NULL; + + EINA_LIST_FOREACH(luncher_instances, l, inst) + { + if (inst->bar) continue; + if (inst->resize_job) return ECORE_CALLBACK_RENEW; + inst->resize_job = ecore_job_add(_grid_resize_job, inst); + } + return ECORE_CALLBACK_PASS_ON; +} + +static void +_grid_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data EINA_UNUSED) +{ + Instance *inst = data; + + if (inst->resize_job) return; + inst->resize_job = ecore_job_add(_grid_resize_job, inst); +} + +static void +_grid_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data EINA_UNUSED) +{ + Instance *inst = data; + + e_object_del(E_OBJECT(inst->order)); + E_FREE_FUNC(inst->drop_handler, evas_object_del); + luncher_instances = eina_list_remove(luncher_instances, inst); + free(inst); +} + +static void +_grid_drop_drop(void *data, const char *type, void *event_data) +{ + Instance *inst = data; + E_Event_Dnd_Drop *ev = event_data; + Efreet_Desktop *desktop = NULL; + Eina_List *l = NULL; + Icon *ic = NULL; + + evas_object_del(inst->place_holder); + inst->place_holder = NULL; + if (!strcmp(type, "enlightenment/desktop")) + desktop = ev->data; + else if (!strcmp(type, "enlightenment/border")) + { + E_Client *ec; + + ec = ev->data; + desktop = ec->desktop; + if (!desktop) + { + desktop = e_desktop_client_create(ec); + efreet_desktop_save(desktop); + e_desktop_edit(desktop); + } + } + else if (!strcmp(type, "text/uri-list")) + l = ev->data; + + ic = inst->drop_before; + if (ic) + { + if (desktop) + e_order_prepend_relative(inst->order, desktop, ic->desktop); + else + e_order_files_prepend_relative(inst->order, l, ic->desktop); + } + else + { + if (desktop) + e_order_append(inst->order, desktop); + else + e_order_files_append(inst->order, l); + } +} + +static void +_grid_drop_leave(void *data, const char *type EINA_UNUSED, void *event_data EINA_UNUSED) +{ + Instance *inst = data; + + inst->inside = EINA_FALSE; + evas_object_del(inst->place_holder); + inst->place_holder = NULL; +} + +static void +_grid_drop_move(void *data, const char *type EINA_UNUSED, void *event_data) +{ + Instance *inst = data; + E_Event_Dnd_Move *ev = event_data; + Evas_Coord x = ev->x, y = ev->y; + Eina_List *l; + Icon *ic; + + if (!inst->inside) + return; + + EINA_LIST_FOREACH(inst->icons, l, ic) + { + Evas_Coord dx, dy, dw, dh; + + if (!ic->in_order) continue; + evas_object_geometry_get(ic->o_layout, &dx, &dy, &dw, &dh); + if (E_INSIDE(x, y, dx, dy, dw, dh)) + inst->drop_before = ic; + } + if (inst->drop_before) + elm_gengrid_item_insert_before(inst->o_icon_con, &_grid_icon_class, inst->place_holder, inst->drop_before->o_layout, NULL, NULL); +} + +static void +_grid_drop_enter(void *data, const char *type EINA_UNUSED, void *event_data EINA_UNUSED) +{ + Instance *inst = data; + + inst->inside = EINA_TRUE; + inst->place_holder = evas_object_rectangle_add(evas_object_evas_get(inst->o_icon_con)); + evas_object_color_set(inst->place_holder, 0, 0, 0, 0); + evas_object_size_hint_min_set(inst->place_holder, inst->size, inst->size); + evas_object_size_hint_max_set(inst->place_holder, inst->size, inst->size); + evas_object_show(inst->place_holder); +} + +static void +_grid_removed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_data) +{ + Instance *inst = data; + char buf[4096]; + + if (inst->o_main != event_data) return; + if (e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s", inst->cfg->dir) >= sizeof(buf)) + return; + + luncher_config->items = eina_list_remove(luncher_config->items, inst->cfg); + eina_stringshare_del(inst->cfg->dir); + E_FREE(inst->cfg); +} + +static void +_grid_anchor_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Instance *inst = data; + + if (inst && inst->o_icon_con) + { + grid_recalculate(inst); + } +} + +static void +_grid_order_update(void *data, E_Order *eo EINA_UNUSED) +{ + Instance *inst = data; + + if (inst && inst->o_icon_con) + { + grid_recalculate(inst); + } +} + +static void +_grid_created_cb(void *data, Evas_Object *obj, void *event_data EINA_UNUSED) +{ + Instance *inst = data; + char buf[4096]; + const char *drop[] = { "enlightenment/desktop", "enlightenment/border", "text/uri-list" }; + + inst->o_icon_con = elm_gengrid_add(inst->o_main); + elm_object_style_set(inst->o_icon_con, "no_inset_shadow"); + elm_gengrid_align_set(inst->o_icon_con, 0.5, 0.5); + elm_gengrid_select_mode_set(inst->o_icon_con, ELM_OBJECT_SELECT_MODE_NONE); + E_FILL(inst->o_icon_con); + elm_layout_content_set(inst->o_main, "e.swallow.grid", inst->o_icon_con); + evas_object_show(inst->o_icon_con); + + evas_object_data_set(inst->o_main, "instance", inst); + evas_object_data_set(inst->o_icon_con, "instance", inst); + + e_gadget_configure_cb_set(inst->o_main, _grid_gadget_configure); + evas_object_smart_callback_del_full(obj, "gadget_created", _grid_created_cb, data); + + if (!inst->cfg->dir) + inst->cfg->dir = eina_stringshare_add("default"); + if (inst->cfg->dir[0] != '/') + e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s/.order", + inst->cfg->dir); + else + eina_strlcpy(buf, inst->cfg->dir, sizeof(buf)); + + inst->order = e_order_new(buf); + e_order_update_callback_set(inst->order, _grid_order_update, inst); + + _grid_fill(inst); + + inst->drop_handler = + e_gadget_drop_handler_add(inst->o_main, inst, + _grid_drop_enter, _grid_drop_move, + _grid_drop_leave, _grid_drop_drop, + drop, 3); + elm_layout_content_set(inst->o_main, "e.swallow.drop", inst->drop_handler); + evas_object_show(inst->drop_handler); + + evas_object_event_callback_add(inst->o_main, EVAS_CALLBACK_RESIZE, _grid_resize, inst); + _grid_aspect(inst); +} + +static Config_Item * +_conf_item_get(int *id) +{ + Config_Item *ci; + Eina_List *l; + + if (*id > 0) + { + EINA_LIST_FOREACH(luncher_config->items, l, ci) + if (*id == ci->id) return ci; + } + + ci = E_NEW(Config_Item, 1); + + if (*id != -1) + ci->id = eina_list_count(luncher_config->items)+1; + else + ci->id = -1; + ci->dir = eina_stringshare_add("default"); + ci->style = NULL; + luncher_config->items = eina_list_append(luncher_config->items, ci); + + return ci; +} + +static void +_grid_recalculate_job(void *data) +{ + Instance *inst = data; + + if (inst) + { + if (inst->o_icon_con) + { + _grid_empty(inst); + _grid_fill(inst); + } + inst->recalc_job = NULL; + } +} + +EINTERN void +grid_recalculate(Instance *inst) +{ + E_FREE_FUNC(inst->recalc_job, ecore_job_del); + inst->recalc_job = ecore_job_add(_grid_recalculate_job, inst); +} + +EINTERN void +grid_reorder(Instance *inst) +{ + char buf[4096]; + + if (inst) + { + E_FREE_FUNC(inst->recalc_job, ecore_job_del); + _grid_empty(inst); + if (!inst->cfg->dir) + inst->cfg->dir = eina_stringshare_add("default"); + if (inst->cfg->dir[0] != '/') + e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s/.order", + inst->cfg->dir); + else + eina_strlcpy(buf, inst->cfg->dir, sizeof(buf)); + e_object_del(E_OBJECT(inst->order)); + inst->order = e_order_new(buf); + e_order_update_callback_set(inst->order, _grid_order_update, inst); + _grid_fill(inst); + } +} + +EINTERN Evas_Object * +grid_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient EINA_UNUSED) +{ + Instance *inst; + + inst = E_NEW(Instance, 1); + inst->size = 0; + inst->resize_job = NULL; + inst->cfg = _conf_item_get(id); + *id = inst->cfg->id; + inst->inside = EINA_FALSE; + inst->bar = EINA_FALSE; + + _grid_icon_class.item_style = "luncher"; + _grid_icon_class.func.text_get = NULL; + _grid_icon_class.func.content_get = _gengrid_icon_get; + _grid_icon_class.func.state_get = NULL; + _grid_icon_class.func.del = NULL; + + inst->o_main = elm_layout_add(parent); + e_theme_edje_object_set(inst->o_main, "e/gadget/luncher/grid", + "e/gadget/luncher/grid"); + evas_object_event_callback_add(inst->o_main, EVAS_CALLBACK_DEL, _grid_del, inst); + evas_object_smart_callback_add(parent, "gadget_created", _grid_created_cb, inst); + evas_object_smart_callback_add(parent, "gadget_site_anchor", _grid_anchor_changed_cb, inst); + evas_object_smart_callback_add(parent, "gadget_removed", _grid_removed_cb, inst); + evas_object_show(inst->o_main); + + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIG_ICON_THEME, + _grid_cb_update_icons, NULL); + E_LIST_HANDLER_APPEND(handlers, EFREET_EVENT_ICON_CACHE_UPDATE, + _grid_cb_update_icons, NULL); + + if (inst->cfg->id < 0) return inst->o_main; + luncher_instances = eina_list_append(luncher_instances, inst); + + return inst->o_main; +} diff --git a/src/modules/luncher/luncher.h b/src/modules/luncher/luncher.h index 5ebe643..e125d04 100644 --- a/src/modules/luncher/luncher.h +++ b/src/modules/luncher/luncher.h @@ -46,6 +46,7 @@ struct _Instance Ecore_Job *resize_job; Ecore_Job *recalc_job; E_Comp_Object_Mover *iconify_provider; + Eina_Bool bar; Eina_Bool inside; Eina_Bool effect; Config_Item *cfg; @@ -84,6 +85,9 @@ EINTERN Evas_Object *config_luncher(E_Zone *zone, Instance *inst, Eina_Bool bar) EINTERN Evas_Object *bar_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient); EINTERN void bar_reorder(Instance *inst); EINTERN void bar_recalculate(Instance *inst); +EINTERN Evas_Object *grid_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient); +EINTERN void grid_reorder(Instance *inst); +EINTERN void grid_recalculate(Instance *inst); extern Config *luncher_config; extern Eina_List *luncher_instances; diff --git a/src/modules/luncher/mod.c b/src/modules/luncher/mod.c index 558e898..fa1922c 100644 --- a/src/modules/luncher/mod.c +++ b/src/modules/luncher/mod.c @@ -38,6 +38,7 @@ luncher_init(void) luncher_config->items = eina_list_append(luncher_config->items, ci); } e_gadget_type_add("Luncher Bar", bar_create, NULL); + e_gadget_type_add("Luncher Grid", grid_create, NULL); } EINTERN void @@ -58,6 +59,7 @@ luncher_shutdown(void) E_CONFIG_DD_FREE(conf_item_edd); e_gadget_type_del("Luncher Bar"); + e_gadget_type_del("Luncher Grid"); } E_API E_Module_Api e_modapi = --