1 #include "luncher.h"
2 static Eina_List *handlers;
3 static Elm_Gengrid_Item_Class _grid_icon_class;
4 static void _grid_resize_job(void *data);
5
6 static void
_grid_aspect(Instance * inst)7 _grid_aspect(Instance *inst)
8 {
9 Evas_Coord w, h, square, size;
10
11 if (!eina_list_count(inst->icons))
12 return;
13 evas_object_geometry_get(inst->o_main, 0, 0, &w, &h);
14 size = 0;
15 if ((w + h) > 1)
16 {
17 square = w + h;
18 size = floor((square / eina_list_count(inst->icons)));
19 }
20 inst->size = size;
21 elm_gengrid_item_size_set(inst->o_icon_con, size, size);
22 }
23
24 static Eina_Bool
_grid_check_modifiers(Evas_Modifier * modifiers)25 _grid_check_modifiers(Evas_Modifier *modifiers)
26 {
27 if ((evas_key_modifier_is_set(modifiers, "Alt")) ||
28 (evas_key_modifier_is_set(modifiers, "Control")) ||
29 (evas_key_modifier_is_set(modifiers, "Shift")))
30 return EINA_TRUE;
31 return EINA_FALSE;
32 }
33
34 static Evas_Object *
_grid_gadget_configure(Evas_Object * g)35 _grid_gadget_configure(Evas_Object *g)
36 {
37 if (!luncher_config) return NULL;
38 if (luncher_config->config_dialog) return NULL;
39 Instance *inst = evas_object_data_get(g, "instance");
40 return config_luncher(e_zone_current_get(), inst, EINA_TRUE);
41 }
42
43 static void
_grid_instance_watch(void * data,E_Exec_Instance * ex EINA_UNUSED,E_Exec_Watch_Type type)44 _grid_instance_watch(void *data, E_Exec_Instance *ex EINA_UNUSED, E_Exec_Watch_Type type)
45 {
46 Icon *ic = data;
47
48 switch (type)
49 {
50 case E_EXEC_WATCH_STARTED:
51 if (ic->starting) elm_layout_signal_emit(ic->o_layout, "e,state,started", "e");
52 ic->starting = EINA_FALSE;
53 break;
54 default:
55 break;
56 }
57 }
58
59 static void
_grid_icon_del(Instance * inst,Icon * ic)60 _grid_icon_del(Instance *inst, Icon *ic)
61 {
62 inst->icons = eina_list_remove(inst->icons, ic);
63 evas_object_del(ic->o_icon);
64 evas_object_del(ic->o_layout);
65 if (ic->desktop)
66 efreet_desktop_unref(ic->desktop);
67 eina_stringshare_del(ic->icon);
68 eina_stringshare_del(ic->key);
69 if (ic->exec)
70 e_exec_instance_watcher_del(ic->exec, _grid_instance_watch, ic);
71 ic->exec = NULL;
72 _grid_aspect(inst);
73 E_FREE(ic);
74 }
75
76 static void
_grid_icon_drag_done(E_Drag * drag,int dropped)77 _grid_icon_drag_done(E_Drag *drag, int dropped)
78 {
79 Instance *inst = e_object_data_get(E_OBJECT(drag));
80
81 efreet_desktop_unref(drag->data);
82 if (!inst) return;
83 evas_object_smart_callback_call(e_gadget_site_get(inst->o_main), "gadget_site_unlocked", NULL);
84 if (!dropped)
85 grid_recalculate(inst);
86 }
87
88 static void
_grid_icon_mouse_move(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_data)89 _grid_icon_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data)
90 {
91 Icon *ic = data;
92 Evas_Event_Mouse_Move *ev = event_data;
93 int dx, dy;
94
95 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
96 if (_grid_check_modifiers(ev->modifiers)) return;
97
98 if (!ic->drag.start) return;
99
100 dx = ev->cur.output.x - ic->drag.x;
101 dy = ev->cur.output.y - ic->drag.y;
102 if (((dx * dx) + (dy * dy)) >
103 (e_config->drag_resist * e_config->drag_resist))
104 {
105 E_Drag *d;
106 Evas_Object *o;
107 Evas_Coord x, y, w, h;
108 unsigned int size;
109 const char *drag_types[] = { "enlightenment/desktop" };
110
111 ic->drag.dnd = 1;
112 ic->drag.start = 0;
113
114 evas_object_geometry_get(ic->o_icon, &x, &y, &w, &h);
115 d = e_drag_new(x, y, drag_types, 1,
116 ic->desktop, -1, NULL, _grid_icon_drag_done);
117 d->button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
118 efreet_desktop_ref(ic->desktop);
119 size = MAX(w, h);
120 o = e_util_desktop_icon_add(ic->desktop, size, e_drag_evas_get(d));
121 e_drag_object_set(d, o);
122
123 e_drag_resize(d, w, h);
124 e_drag_start(d, ic->drag.x, ic->drag.y);
125 e_object_data_set(E_OBJECT(d), ic->inst);
126 if (ic->in_order)
127 e_order_remove(ic->inst->order, ic->desktop);
128 }
129 }
130
131 static Eina_Bool
_grid_drag_timer(void * data)132 _grid_drag_timer(void *data)
133 {
134 Icon *ic = data;
135
136 ic->drag_timer = NULL;
137 ic->drag.start = 1;
138 evas_object_smart_callback_call(e_gadget_site_get(ic->inst->o_main), "gadget_site_locked", NULL);
139 return EINA_FALSE;
140 }
141
142 static void
_grid_icon_mouse_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_data)143 _grid_icon_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data)
144 {
145 Icon *ic = data;
146 Evas_Event_Mouse_Up *ev = event_data;
147
148 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
149 {
150 if (ev->button == 1)
151 {
152 ic->drag.start = 0;
153 ic->drag.dnd = 0;
154 E_FREE_FUNC(ic->mouse_in_timer, ecore_timer_del);
155 E_FREE_FUNC(ic->mouse_out_timer, ecore_timer_del);
156 E_FREE_FUNC(ic->drag_timer, ecore_timer_del);
157 }
158 return;
159 }
160 if (_grid_check_modifiers(ev->modifiers)) return;
161
162 if (ev->button == 1)
163 {
164 ic->drag.x = ev->output.x;
165 ic->drag.y = ev->output.y;
166 E_FREE_FUNC(ic->drag_timer, ecore_timer_del);
167 ic->drag_timer = ecore_timer_loop_add(.35, _grid_drag_timer, ic);
168 }
169 }
170
171 static void
_grid_icon_mouse_up(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_data)172 _grid_icon_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data)
173 {
174 Icon *ic = data;
175 Evas_Event_Mouse_Up *ev = event_data;
176
177 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
178 if (_grid_check_modifiers(ev->modifiers)) return;
179
180 if (ev->button == 1)
181 {
182 E_FREE_FUNC(ic->drag_timer, ecore_timer_del);
183 if (ic->drag.dnd)
184 {
185 ic->drag.start = 0;
186 ic->drag.dnd = 0;
187 return;
188 }
189 }
190 if (ev->button == 1 && ic->desktop)
191 {
192 if (ic->desktop->type == EFREET_DESKTOP_TYPE_APPLICATION)
193 {
194 E_Exec_Instance *ex;
195
196 ex = e_exec(e_zone_current_get(), ic->desktop, NULL, NULL, "luncher");
197 ic->exec = ex;
198 e_exec_instance_watcher_add(ex, _grid_instance_watch, ic);
199 if (!ic->starting) elm_layout_signal_emit(ic->o_layout, "e,state,starting", "e");
200 ic->starting = EINA_TRUE;
201 }
202 else if (ic->desktop->type == EFREET_DESKTOP_TYPE_LINK)
203 {
204 if (!strncasecmp(ic->desktop->url, "file:", 5))
205 {
206 E_Action *act;
207
208 act = e_action_find("fileman");
209 if (act)
210 act->func.go(NULL, ic->desktop->url + 5);
211 }
212 }
213 }
214 }
215
216 static void
_grid_icon_mouse_in(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_data)217 _grid_icon_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_data)
218 {
219 Icon *ic = data;
220 Evas_Event_Mouse_In *ev = event_data;
221
222 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
223 if (_grid_check_modifiers(ev->modifiers)) return;
224
225 evas_object_raise(ic->o_layout);
226 if (!ic->inst->cfg->hide_tooltips)
227 elm_object_tooltip_show(obj);
228 ic->active = EINA_TRUE;
229 elm_layout_signal_emit(ic->o_layout, "e,state,focused", "e");
230 }
231
232 static void
_grid_icon_mouse_out(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_data EINA_UNUSED)233 _grid_icon_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_data EINA_UNUSED)
234 {
235 Icon *ic = data;
236
237 if (!ic->inst->cfg->hide_tooltips)
238 elm_object_tooltip_hide(obj);
239 elm_layout_signal_emit(ic->o_layout, "e,state,unfocused", "e");
240 }
241
242 static Evas_Object *
_gengrid_icon_get(void * data,Evas_Object * obj EINA_UNUSED,const char * part)243 _gengrid_icon_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
244 {
245 Icon *ic = data;
246 if (strcmp(part, "elm.swallow.icon"))
247 return NULL;
248 return ic->o_layout;
249 }
250
251 static void
_grid_icon_file_set(Icon * ic,Efreet_Desktop * desktop)252 _grid_icon_file_set(Icon *ic, Efreet_Desktop *desktop)
253 {
254 const char *path = NULL, *k = NULL;
255 char buf[4096];
256
257 if (desktop)
258 {
259 if (!desktop->icon)
260 path = NULL;
261 else if (strncmp(desktop->icon, "/", 1) && !ecore_file_exists(desktop->icon))
262 {
263 path = efreet_icon_path_find(e_config->icon_theme, desktop->icon, ic->inst->size);
264 if (!path)
265 {
266 if (e_util_strcmp(e_config->icon_theme, "hicolor"))
267 path = efreet_icon_path_find("hicolor", desktop->icon, ic->inst->size);
268 }
269 }
270 else if (ecore_file_exists(desktop->icon))
271 {
272 path = desktop->icon;
273 }
274 if (!path && desktop->icon)
275 {
276 snprintf(buf, sizeof(buf), "e/icons/%s", desktop->icon);
277 if (eina_list_count(e_theme_collection_items_find("base/theme/icons", buf)))
278 {
279 path = e_theme_edje_file_get("base/theme/icons", buf);
280 k = buf;
281 }
282 else
283 {
284 path = e_theme_edje_file_get("base/theme/icons", "e/icons/unknown");
285 k = "e/icons/unknown";
286 }
287 }
288 else if (!path && !desktop->icon)
289 {
290 path = e_theme_edje_file_get("base/theme/icons", "e/icons/unknown");
291 k = "e/icons/unknown";
292 }
293 }
294 else if (ic->icon)
295 {
296 if (strncmp(ic->icon, "/", 1) && !ecore_file_exists(ic->icon))
297 {
298 path = efreet_icon_path_find(e_config->icon_theme, ic->icon, ic->inst->size);
299 if (!path)
300 {
301 if (e_util_strcmp(e_config->icon_theme, "hicolor"))
302 path = efreet_icon_path_find("hicolor", ic->icon, ic->inst->size);
303 }
304 }
305 else if (ecore_file_exists(ic->icon))
306 {
307 path = ic->icon;
308 k = ic->key;
309 }
310 if (!path)
311 {
312 path = e_theme_edje_file_get("base/theme/icons", "e/icons/unknown");
313 k = "e/icons/unknown";
314 }
315 }
316 else
317 {
318 path = e_theme_edje_file_get("base/theme/icons", "e/icons/unknown");
319 k = "e/icons/unknown";
320 }
321 elm_image_file_set(ic->o_icon, path, k);
322 }
323
324 static Icon *
_grid_icon_add(Instance * inst,Efreet_Desktop * desktop)325 _grid_icon_add(Instance *inst, Efreet_Desktop *desktop)
326 {
327 Icon *ic;
328
329 ic = E_NEW(Icon, 1);
330 efreet_desktop_ref(desktop);
331 ic->desktop = desktop;
332 ic->inst = inst;
333 ic->preview = NULL;
334 ic->preview_box = NULL;
335 ic->mouse_in_timer = NULL;
336 ic->mouse_out_timer = NULL;
337 ic->active = EINA_FALSE;
338 ic->starting = EINA_FALSE;
339 ic->exec = NULL;
340
341 ic->o_layout = elm_layout_add(inst->o_icon_con);
342 e_theme_edje_object_set(ic->o_layout, "e/gadget/luncher/icon",
343 "e/gadget/luncher/icon");
344 E_FILL(ic->o_layout);
345 evas_object_show(ic->o_layout);
346
347 ic->o_icon = elm_icon_add(ic->o_layout);
348 E_EXPAND(ic->o_icon);
349
350
351 _grid_icon_file_set(ic, desktop);
352
353 if (!inst->cfg->hide_tooltips)
354 {
355 elm_object_tooltip_text_set(ic->o_icon, desktop->name);
356 elm_object_tooltip_orient_set(ic->o_icon, ELM_TOOLTIP_ORIENT_CENTER);
357 elm_object_tooltip_style_set(ic->o_icon, "luncher");
358 }
359 evas_object_size_hint_aspect_set(ic->o_icon, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
360 elm_layout_content_set(ic->o_layout, "e.swallow.icon", ic->o_icon);
361 evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_UP,
362 _grid_icon_mouse_up, ic);
363 evas_object_event_callback_priority_add(ic->o_icon, EVAS_CALLBACK_MOUSE_DOWN, 0,
364 _grid_icon_mouse_down, ic);
365 evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_MOVE,
366 _grid_icon_mouse_move, ic);
367 evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_IN,
368 _grid_icon_mouse_in, ic);
369 evas_object_event_callback_add(ic->o_icon, EVAS_CALLBACK_MOUSE_OUT,
370 _grid_icon_mouse_out, ic);
371 evas_object_show(ic->o_icon);
372
373 elm_layout_sizing_eval(ic->o_layout);
374
375 elm_gengrid_item_append(inst->o_icon_con, &_grid_icon_class, ic, NULL, NULL);
376 _grid_aspect(inst);
377
378 return ic;
379 }
380
381 static void
_grid_empty(Instance * inst)382 _grid_empty(Instance *inst)
383 {
384 if (inst->icons)
385 {
386 elm_gengrid_clear(inst->o_icon_con);
387 while (inst->icons)
388 _grid_icon_del(inst, eina_list_data_get(inst->icons));
389 inst->icons = NULL;
390 }
391 }
392
393 static void
_grid_fill(Instance * inst)394 _grid_fill(Instance *inst)
395 {
396 Icon *ic;
397
398 if (inst->order)
399 {
400 Efreet_Desktop *desktop;
401 Eina_List *list;
402
403 EINA_LIST_FOREACH(inst->order->desktops, list, desktop)
404 {
405 ic = _grid_icon_add(inst, desktop);
406 ic->in_order = EINA_TRUE;
407 inst->icons = eina_list_append(inst->icons, ic);
408 }
409 }
410 }
411
412 static void
_grid_resize_job(void * data)413 _grid_resize_job(void *data)
414 {
415 Instance *inst = data;
416 Eina_List *l;
417 Icon *ic;
418
419 if (inst)
420 {
421 elm_layout_sizing_eval(inst->o_main);
422 _grid_aspect(inst);
423 EINA_LIST_FOREACH(inst->icons, l, ic)
424 _grid_icon_file_set(ic, ic->desktop);
425 inst->resize_job = NULL;
426 }
427 }
428
429 static Eina_Bool
_grid_cb_update_icons(EINA_UNUSED void * data,EINA_UNUSED int ev_type,EINA_UNUSED void * ev)430 _grid_cb_update_icons(EINA_UNUSED void *data, EINA_UNUSED int ev_type, EINA_UNUSED void *ev)
431 {
432 Instance *inst = NULL;
433 Eina_List *l = NULL;
434
435 EINA_LIST_FOREACH(luncher_instances, l, inst)
436 {
437 if (inst->bar) continue;
438 if (inst->resize_job) return ECORE_CALLBACK_RENEW;
439 inst->resize_job = ecore_job_add(_grid_resize_job, inst);
440 }
441 return ECORE_CALLBACK_PASS_ON;
442 }
443
444 static void
_grid_resize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_data EINA_UNUSED)445 _grid_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_data EINA_UNUSED)
446 {
447 Instance *inst = data;
448
449 if (inst->resize_job) return;
450 inst->resize_job = ecore_job_add(_grid_resize_job, inst);
451 }
452
453 static void
_grid_removed_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_data)454 _grid_removed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_data)
455 {
456 Instance *inst = data;
457 char buf[4096];
458
459 if (inst->o_main != event_data) return;
460 if (e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s", inst->cfg->dir) >= sizeof(buf))
461 return;
462
463 luncher_config->items = eina_list_remove(luncher_config->items, inst->cfg);
464 eina_stringshare_del(inst->cfg->dir);
465 E_FREE(inst->cfg);
466 }
467
468 static void
_grid_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_data EINA_UNUSED)469 _grid_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_data EINA_UNUSED)
470 {
471 Instance *inst = data;
472
473 evas_object_smart_callback_del_full(e_gadget_site_get(obj), "gadget_removed", _grid_removed_cb, inst);
474 e_object_del(E_OBJECT(inst->order));
475 E_FREE_FUNC(inst->drop_handler, evas_object_del);
476 luncher_instances = eina_list_remove(luncher_instances, inst);
477 free(inst);
478 }
479
480 static void
_grid_drop_drop(void * data,const char * type,void * event_data)481 _grid_drop_drop(void *data, const char *type, void *event_data)
482 {
483 Instance *inst = data;
484 E_Event_Dnd_Drop *ev = event_data;
485 Efreet_Desktop *desktop = NULL;
486 Eina_List *l = NULL;
487 Icon *ic = NULL;
488
489 evas_object_del(inst->place_holder);
490 inst->place_holder = NULL;
491 if (!strcmp(type, "enlightenment/desktop"))
492 desktop = ev->data;
493 else if (!strcmp(type, "enlightenment/border"))
494 {
495 E_Client *ec;
496
497 ec = ev->data;
498 desktop = ec->desktop;
499 if (!desktop)
500 {
501 desktop = e_desktop_client_create(ec);
502 efreet_desktop_save(desktop);
503 e_desktop_edit(desktop);
504 }
505 }
506 else if (!strcmp(type, "text/uri-list"))
507 l = ev->data;
508
509 ic = inst->drop_before;
510 if (ic)
511 {
512 if (desktop)
513 e_order_prepend_relative(inst->order, desktop, ic->desktop);
514 else
515 e_order_files_prepend_relative(inst->order, l, ic->desktop);
516 }
517 else
518 {
519 if (desktop)
520 e_order_append(inst->order, desktop);
521 else
522 e_order_files_append(inst->order, l);
523 }
524 }
525
526 static void
_grid_drop_leave(void * data,const char * type EINA_UNUSED,void * event_data EINA_UNUSED)527 _grid_drop_leave(void *data, const char *type EINA_UNUSED, void *event_data EINA_UNUSED)
528 {
529 Instance *inst = data;
530
531 inst->inside = EINA_FALSE;
532 evas_object_del(inst->place_holder);
533 inst->place_holder = NULL;
534 }
535
536 static void
_grid_drop_move(void * data,const char * type EINA_UNUSED,void * event_data)537 _grid_drop_move(void *data, const char *type EINA_UNUSED, void *event_data)
538 {
539 Instance *inst = data;
540 E_Event_Dnd_Move *ev = event_data;
541 Evas_Coord x = ev->x, y = ev->y;
542 Eina_List *l;
543 Icon *ic;
544
545 if (!inst->inside)
546 return;
547
548 EINA_LIST_FOREACH(inst->icons, l, ic)
549 {
550 Evas_Coord dx, dy, dw, dh;
551
552 if (!ic->in_order) continue;
553 evas_object_geometry_get(ic->o_layout, &dx, &dy, &dw, &dh);
554 if (E_INSIDE(x, y, dx, dy, dw, dh))
555 inst->drop_before = ic;
556 }
557 if (inst->drop_before)
558 elm_gengrid_item_insert_before(inst->o_icon_con, &_grid_icon_class, inst->place_holder, inst->drop_before->o_layout, NULL, NULL);
559 }
560
561 static void
_grid_drop_enter(void * data,const char * type EINA_UNUSED,void * event_data EINA_UNUSED)562 _grid_drop_enter(void *data, const char *type EINA_UNUSED, void *event_data EINA_UNUSED)
563 {
564 Instance *inst = data;
565
566 inst->inside = EINA_TRUE;
567 inst->place_holder = evas_object_rectangle_add(evas_object_evas_get(inst->o_icon_con));
568 evas_object_color_set(inst->place_holder, 0, 0, 0, 0);
569 evas_object_size_hint_min_set(inst->place_holder, inst->size, inst->size);
570 evas_object_size_hint_max_set(inst->place_holder, inst->size, inst->size);
571 evas_object_show(inst->place_holder);
572 }
573
574 static void
_grid_anchor_changed_cb(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)575 _grid_anchor_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
576 {
577 Instance *inst = data;
578
579 if (inst && inst->o_icon_con)
580 {
581 grid_recalculate(inst);
582 }
583 }
584
585 static void
_grid_order_update(void * data,E_Order * eo EINA_UNUSED)586 _grid_order_update(void *data, E_Order *eo EINA_UNUSED)
587 {
588 Instance *inst = data;
589
590 if (inst && inst->o_icon_con)
591 {
592 grid_recalculate(inst);
593 }
594 }
595
596 static void
_grid_created_cb(void * data,Evas_Object * obj,void * event_data EINA_UNUSED)597 _grid_created_cb(void *data, Evas_Object *obj, void *event_data EINA_UNUSED)
598 {
599 Instance *inst = data;
600 char buf[4096];
601 const char *drop[] = { "enlightenment/desktop", "enlightenment/border", "text/uri-list" };
602
603 inst->o_icon_con = elm_gengrid_add(inst->o_main);
604 elm_object_style_set(inst->o_icon_con, "no_inset_shadow");
605 elm_gengrid_align_set(inst->o_icon_con, 0.5, 0.5);
606 elm_gengrid_select_mode_set(inst->o_icon_con, ELM_OBJECT_SELECT_MODE_NONE);
607 E_FILL(inst->o_icon_con);
608 elm_layout_content_set(inst->o_main, "e.swallow.grid", inst->o_icon_con);
609 evas_object_show(inst->o_icon_con);
610
611 evas_object_data_set(inst->o_main, "instance", inst);
612 evas_object_data_set(inst->o_icon_con, "instance", inst);
613
614 e_gadget_configure_cb_set(inst->o_main, _grid_gadget_configure);
615 evas_object_smart_callback_del_full(obj, "gadget_created", _grid_created_cb, data);
616
617 if (!inst->cfg->dir)
618 inst->cfg->dir = eina_stringshare_add("default");
619 if (inst->cfg->dir[0] != '/')
620 e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s/.order",
621 inst->cfg->dir);
622 else
623 eina_strlcpy(buf, inst->cfg->dir, sizeof(buf));
624
625 inst->order = e_order_new(buf);
626 e_order_update_callback_set(inst->order, _grid_order_update, inst);
627
628 _grid_fill(inst);
629
630 inst->drop_handler =
631 e_gadget_drop_handler_add(inst->o_main, inst,
632 _grid_drop_enter, _grid_drop_move,
633 _grid_drop_leave, _grid_drop_drop,
634 drop, 3);
635 elm_layout_content_set(inst->o_main, "e.swallow.drop", inst->drop_handler);
636 evas_object_show(inst->drop_handler);
637
638 evas_object_event_callback_add(inst->o_main, EVAS_CALLBACK_RESIZE, _grid_resize, inst);
639 _grid_aspect(inst);
640 }
641
642 static Config_Item *
_conf_item_get(int * id)643 _conf_item_get(int *id)
644 {
645 Config_Item *ci;
646 Eina_List *l;
647
648 if (*id > 0)
649 {
650 EINA_LIST_FOREACH(luncher_config->items, l, ci)
651 if (*id == ci->id) return ci;
652 }
653
654 ci = E_NEW(Config_Item, 1);
655
656 if (*id != -1)
657 ci->id = eina_list_count(luncher_config->items)+1;
658 else
659 ci->id = -1;
660 ci->dir = eina_stringshare_add("default");
661 luncher_config->items = eina_list_append(luncher_config->items, ci);
662
663 return ci;
664 }
665
666 static void
_grid_recalculate_job(void * data)667 _grid_recalculate_job(void *data)
668 {
669 Instance *inst = data;
670
671 if (inst)
672 {
673 if (inst->o_icon_con)
674 {
675 _grid_empty(inst);
676 _grid_fill(inst);
677 }
678 inst->recalc_job = NULL;
679 }
680 }
681
682 EINTERN void
grid_recalculate(Instance * inst)683 grid_recalculate(Instance *inst)
684 {
685 E_FREE_FUNC(inst->recalc_job, ecore_job_del);
686 inst->recalc_job = ecore_job_add(_grid_recalculate_job, inst);
687 }
688
689 EINTERN void
grid_reorder(Instance * inst)690 grid_reorder(Instance *inst)
691 {
692 char buf[4096];
693
694 if (inst)
695 {
696 E_FREE_FUNC(inst->recalc_job, ecore_job_del);
697 _grid_empty(inst);
698 if (!inst->cfg->dir)
699 inst->cfg->dir = eina_stringshare_add("default");
700 if (inst->cfg->dir[0] != '/')
701 e_user_dir_snprintf(buf, sizeof(buf), "applications/bar/%s/.order",
702 inst->cfg->dir);
703 else
704 eina_strlcpy(buf, inst->cfg->dir, sizeof(buf));
705 e_object_del(E_OBJECT(inst->order));
706 inst->order = e_order_new(buf);
707 e_order_update_callback_set(inst->order, _grid_order_update, inst);
708 _grid_fill(inst);
709 }
710 }
711
712 EINTERN Evas_Object *
grid_create(Evas_Object * parent,int * id,E_Gadget_Site_Orient orient)713 grid_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient)
714 {
715 Instance *inst;
716
717 if (orient) return NULL;
718 if (e_gadget_site_is_desklock(parent)) return NULL;
719 inst = E_NEW(Instance, 1);
720 inst->size = 0;
721 inst->resize_job = NULL;
722 inst->cfg = _conf_item_get(id);
723 *id = inst->cfg->id;
724 inst->inside = EINA_FALSE;
725 inst->bar = EINA_FALSE;
726
727 if (!inst->cfg->preview_size)
728 inst->cfg->preview_size = 64;
729
730 _grid_icon_class.item_style = "luncher";
731 _grid_icon_class.func.text_get = NULL;
732 _grid_icon_class.func.content_get = _gengrid_icon_get;
733 _grid_icon_class.func.state_get = NULL;
734 _grid_icon_class.func.del = NULL;
735
736 inst->o_main = elm_layout_add(parent);
737 e_theme_edje_object_set(inst->o_main, "e/gadget/luncher/grid",
738 "e/gadget/luncher/grid");
739 evas_object_event_callback_add(inst->o_main, EVAS_CALLBACK_DEL, _grid_del, inst);
740 evas_object_smart_callback_add(parent, "gadget_created", _grid_created_cb, inst);
741 evas_object_smart_callback_add(parent, "gadget_site_anchor", _grid_anchor_changed_cb, inst);
742 evas_object_smart_callback_add(parent, "gadget_removed", _grid_removed_cb, inst);
743 evas_object_show(inst->o_main);
744
745 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIG_ICON_THEME,
746 _grid_cb_update_icons, NULL);
747 E_LIST_HANDLER_APPEND(handlers, EFREET_EVENT_ICON_CACHE_UPDATE,
748 _grid_cb_update_icons, NULL);
749
750 if (inst->cfg->id < 0) return inst->o_main;
751 luncher_instances = eina_list_append(luncher_instances, inst);
752
753 return inst->o_main;
754 }
755