80cddb865eaaf1598ae921c006f31278bbb00d69
[framework/uifw/e17.git] / src / modules / gadman / e_mod_gadman.c
1 #include <e.h>
2 #include "e_mod_main.h"
3 #include "e_mod_gadman.h"
4 #include "e_mod_config.h"
5
6 /* local protos */
7 static void _attach_menu(void *data, E_Gadcon_Client *gcc, E_Menu *menu);
8 static void _save_widget_position(E_Gadcon_Client *gcc);
9 static void _apply_widget_position(E_Gadcon_Client *gcc);
10 static char *_get_bind_text(const char* action);
11 static void _on_menu_layer(E_Gadcon_Client *gcc, Gadman_Layer_Type layer);
12 static E_Gadcon_Client *_gadman_gadget_add(const E_Gadcon_Client_Class *cc, Gadman_Layer_Type layer, E_Config_Gadcon_Client *src_cf);
13
14 static Evas_Object* _create_mover(E_Gadcon *gc);
15 static Evas_Object* _get_mover(E_Gadcon_Client *gcc);
16 static E_Gadcon* _gadman_gadcon_new(const char* name, Gadman_Layer_Type layer, E_Zone *zone, E_Gadcon_Location * loc);
17
18 static void on_shape_change(void *data, E_Container_Shape *es, E_Container_Shape_Change ch);
19
20 static void on_top(void *data, Evas_Object *o, const char *em, const char *src);
21 static void on_right(void *data, Evas_Object *o, const char *em, const char *src);
22 static void on_down(void *data, Evas_Object *o, const char *em, const char *src);
23 static void on_left(void *data, Evas_Object *o, const char *em, const char *src);
24 static void on_move(void *data, Evas_Object *o, const char *em, const char *src);
25
26 static void on_frame_click(void *data, Evas *e, Evas_Object *obj, void *event_info);
27 static void on_bg_click(void *data, Evas_Object *o, const char *em, const char *src);
28 static void on_hide_stop(void *data __UNUSED__, Evas_Object *o __UNUSED__,
29                          const char *em __UNUSED__, const char *src __UNUSED__);
30
31 static void on_menu_style_plain(void *data, E_Menu *m, E_Menu_Item *mi);
32 static void on_menu_style_inset(void *data, E_Menu *m, E_Menu_Item *mi);
33 static void on_menu_style_float(void *data, E_Menu *m, E_Menu_Item *mi);
34 static void on_menu_style_horiz(void *data, E_Menu *m, E_Menu_Item *mi);
35 static void on_menu_style_vert(void *data, E_Menu *m, E_Menu_Item *mi);
36 static void on_menu_layer_bg(void *data, E_Menu *m, E_Menu_Item *mi);
37 static void on_menu_layer_top(void *data, E_Menu *m, E_Menu_Item *mi);
38 static void on_menu_delete(void *data, E_Menu *m, E_Menu_Item *mi);
39 static void on_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi);
40 static void on_menu_add(void *data, E_Menu *m, E_Menu_Item *mi);
41
42 static int _e_gadman_client_add (void *data __UNUSED__, const E_Gadcon_Client_Class *cc);
43 static void _e_gadman_client_remove (void *data __UNUSED__, E_Gadcon_Client *gcc);
44
45 E_Gadcon_Client *current = NULL;
46 Manager *Man = NULL;
47 static E_Gadcon_Location *location = NULL;
48
49 /* Implementation */
50 void
51 gadman_init(E_Module *m)
52 {
53    const Eina_List *l;
54    E_Zone *zone;
55
56    /* Create Manager */
57    Man = calloc(1, sizeof(Manager));
58    if (!Man) return;
59
60    Man->module = m;
61    Man->container = e_container_current_get(e_manager_current_get());
62    Man->width = Man->container->w;
63    Man->height = Man->container->h;
64
65    /* Check if composite is enable */
66    if (ecore_x_screen_is_composited(0) || e_config->use_composite)
67      Man->use_composite = 1;
68
69    /* with this we can trap screen resolution change (a better way?)*/
70    e_container_shape_change_callback_add(Man->container, on_shape_change, NULL);
71
72    /* create and register "desktop" location */
73    location = e_gadcon_location_new("Desktop", E_GADCON_SITE_DESKTOP, 
74                                     _e_gadman_client_add, NULL, 
75                                     _e_gadman_client_remove, NULL);
76    e_gadcon_location_set_icon_name(location, "preferences-desktop");
77    e_gadcon_location_register(location);
78
79    /* iterating through zones - and making gadmans on each */
80    EINA_LIST_FOREACH(Man->container->zones, l, zone)
81      {
82         const char *layer_name[] = {"gadman", "gadman_top"};
83         unsigned int layer;
84
85         for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
86           {
87              E_Gadcon *gc;
88
89              gc = _gadman_gadcon_new(layer_name[layer], layer, zone, location);
90              Man->gadcons[layer] = eina_list_append(Man->gadcons[layer], gc);
91           }
92      }
93 }
94
95 void
96 gadman_shutdown(void)
97 {
98    E_Gadcon *gc;
99    unsigned int layer;
100
101    e_gadcon_location_unregister(location);
102    e_container_shape_change_callback_del(Man->container, on_shape_change, NULL);
103
104    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
105      {
106         EINA_LIST_FREE(Man->gadcons[layer], gc)
107           {
108              e_gadcon_unpopulate(gc);
109              e_gadcon_custom_del(gc);
110
111              /* free gadcons */
112              e_config->gadcons = eina_list_remove(e_config->gadcons, gc);
113              eina_stringshare_del(gc->name);
114
115              if (gc->config_dialog) e_object_del(E_OBJECT(gc->config_dialog));
116           }
117
118         evas_object_del(Man->movers[layer]);
119      }
120
121    if (Man->icon_name) eina_stringshare_del(Man->icon_name);
122
123    /* free manager */
124    if (Man->top_ee)
125      {
126         e_canvas_del(Man->top_ee);
127         //ecore_evas_free(Man->top_ee);
128      }
129    free(Man);
130    Man = NULL;
131 }
132
133 void
134 gadman_populate_class(void *data, E_Gadcon *gc, const E_Gadcon_Client_Class *cc)
135 {
136    Gadman_Layer_Type layer = (Gadman_Layer_Type)(long)data;
137    const Eina_List *l, *ll;
138    E_Config_Gadcon_Client *cf_gcc;
139    E_Gadcon_Client *gcc = NULL;
140
141    EINA_LIST_FOREACH(gc->cf->clients, l, cf_gcc)
142      {
143         if (cf_gcc->name && cc->name && !strcmp(cf_gcc->name, cc->name) && (gc->cf->zone == gc->zone->num))
144           {
145              EINA_LIST_FOREACH(Man->gadgets[layer], ll, gcc) 
146                {
147                   if ((gcc->cf) && (gcc->cf->id) && (cf_gcc->id))
148                     if (gcc->cf->id == cf_gcc->id) break;
149                }
150              if (!gcc) gadman_gadget_place(cf_gcc, layer, gc->zone);
151           }
152      }
153 }
154
155 E_Gadcon *
156 gadman_gadcon_get(const E_Zone *zone, Gadman_Layer_Type layer)
157 {
158    const Eina_List *l;
159    E_Gadcon *gc;
160
161    EINA_LIST_FOREACH(Man->gadcons[layer], l, gc)
162      if (gc->zone == zone) return gc;
163    return NULL;
164 }
165
166 E_Gadcon_Client *
167 gadman_gadget_place(E_Config_Gadcon_Client *cf, Gadman_Layer_Type layer, E_Zone *zone)
168 {
169    const Eina_List *l;
170    E_Gadcon *gc;
171    E_Gadcon_Client *gcc;
172    E_Gadcon_Client_Class *cc = NULL;
173
174    if (!cf->name) return NULL;
175
176    gc = gadman_gadcon_get(zone, layer);
177
178    /* Find provider */
179    EINA_LIST_FOREACH(e_gadcon_provider_list(), l, cc)
180      {
181         if (!strcmp(cc->name, cf->name))
182           break;
183         else
184           cc = NULL;
185      }
186    if (!cc) return NULL;
187
188    /* init Gadcon_Client */
189    gcc = cc->func.init(gc, cf->name, cf->id, cc->default_style);
190    if (!gcc) return NULL;
191    gcc->cf = cf;
192    gcc->client_class = cc;
193
194    Man->gadgets[layer] = eina_list_append(Man->gadgets[layer], gcc);
195
196    //printf("Place Gadget %s (style: %s id: %s) (gadcon: %s)\n", gcc->name, cf->style, cf->id, gc->name);
197
198    /* create frame */
199    gcc->o_frame = edje_object_add(gc->evas);
200    e_theme_edje_object_set(gcc->o_frame, "base/theme/gadman", "e/gadman/frame");
201
202    if ((cf->style) && (!strcmp(cf->style, E_GADCON_CLIENT_STYLE_INSET)))
203      edje_object_signal_emit(gcc->o_frame, "e,state,visibility,inset", "e");
204    else
205      edje_object_signal_emit(gcc->o_frame, "e,state,visibility,plain", "e");
206
207    /* swallow the client inside the frame */
208    edje_object_part_swallow(gcc->o_frame, "e.swallow.content", gcc->o_base);
209    evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_DOWN, 
210                                   on_frame_click, gcc);
211
212    /* Call the client orientation function */
213    if (cc->func.orient)
214      cc->func.orient(gcc, gcc->cf->orient);
215
216    _apply_widget_position(gcc);
217
218    if (gcc->gadcon->id == ID_GADMAN_LAYER_TOP)
219      edje_object_signal_emit(gcc->o_frame, "e,state,visibility,hide", "e");
220
221    evas_object_show(gcc->o_frame);
222
223    return gcc;
224 }
225
226 E_Gadcon_Client *
227 gadman_gadget_add(const E_Gadcon_Client_Class *cc, Gadman_Layer_Type layer)
228 {
229   return _gadman_gadget_add(cc, layer, NULL);
230 }
231
232 static E_Gadcon_Client *
233 _gadman_gadget_add(const E_Gadcon_Client_Class *cc, Gadman_Layer_Type layer, E_Config_Gadcon_Client *src_cf)
234 {
235    E_Config_Gadcon_Client *cf = NULL;
236    E_Gadcon_Client *gcc = NULL;
237    E_Gadcon *gc;
238    int w, h;
239
240    gc = gadman_gadcon_get(e_util_zone_current_get(e_manager_current_get()), 
241                           layer);
242
243    /* Create Config_Gadcon_Client */
244    cf = e_gadcon_client_config_new(gc, cc->name);
245    if (cf) 
246      {
247        if (!src_cf)
248          {
249            cf->style = eina_stringshare_add(cc->default_style);
250            cf->geom.pos_x = DEFAULT_POS_X;
251            cf->geom.pos_y = DEFAULT_POS_Y;
252            cf->geom.size_w = DEFAULT_SIZE_W;
253            cf->geom.size_h = DEFAULT_SIZE_H;
254          }
255        else
256          {
257            cf->style = eina_stringshare_add(src_cf->style);
258            cf->geom.pos_x = src_cf->geom.pos_x;
259            cf->geom.pos_y = src_cf->geom.pos_y;
260            cf->geom.size_w = src_cf->geom.size_w;
261            cf->geom.size_h = src_cf->geom.size_h;
262          }
263      }
264
265    /* Place the new gadget */
266    if (cf)
267      gcc = gadman_gadget_place(cf, layer, gc->zone);
268    if (!gcc) return NULL;
269
270    /* Respect Aspect */
271    evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
272    if (gcc->aspect.w && gcc->aspect.h)
273      {
274         if (gcc->aspect.w > gcc->aspect.h)
275           w = ((float)h / (float)gcc->aspect.h) * (gcc->aspect.w);
276         else
277           h =  ((float)w / (float)gcc->aspect.w) * (gcc->aspect.h);
278         if (h < gcc->min.h) h =  gcc->min.h;
279         if (w < gcc->min.w) w =  gcc->min.w;
280         evas_object_resize(gcc->o_frame, w, h);
281      }
282
283    return gcc;
284 }
285
286 void
287 gadman_gadget_del(E_Gadcon_Client *gcc)
288 {
289    Gadman_Layer_Type layer = gcc->gadcon->id - ID_GADMAN_LAYER_BASE;
290    Man->gadgets[layer] = eina_list_remove(Man->gadgets[layer], gcc);
291
292 //   edje_object_part_unswallow(gcc->o_frame, gcc->o_base);
293
294    if (gcc->cf) e_gadcon_client_config_del(gcc->gadcon->cf, gcc->cf);
295    gcc->cf = NULL;
296    e_object_del(E_OBJECT(gcc));
297    current = NULL;
298 }
299
300 void
301 gadman_gadget_edit_start(E_Gadcon_Client *gcc)
302 {
303    E_Gadcon *gc;
304    Evas_Object *mover;
305    int x, y, w, h;
306
307    current = gcc;
308
309    gc = gcc->gadcon;
310    gc->editing = 1;
311
312    /* Move/resize the correct mover */
313    evas_object_geometry_get(gcc->o_frame, &x, &y, &w, &h);
314    mover = _get_mover(gcc);
315
316    evas_object_move(mover, x, y);
317    evas_object_resize(mover, w, h);
318    evas_object_raise(mover);
319    evas_object_show(mover);
320 }
321
322 void
323 gadman_gadget_edit_end(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
324 {
325    unsigned int layer;
326
327    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
328      {
329         const Eina_List *l;
330         E_Gadcon *gc;
331
332         evas_object_hide(Man->movers[layer]);
333
334         EINA_LIST_FOREACH(Man->gadcons[layer], l, gc)
335           gc->editing = 0;
336      }
337
338    if (current) _save_widget_position(current);
339 }
340
341 void
342 gadman_gadgets_show(void)
343 {
344    const Eina_List *l;
345    E_Gadcon_Client *gcc;
346
347    Man->visible = 1;
348    ecore_evas_show(Man->top_ee);
349    if (Man->conf->bg_type == BG_STD)
350      {
351         if (Man->conf->anim_bg)
352           edje_object_signal_emit(Man->full_bg,
353                                  "e,state,visibility,show", "e");
354         else
355           edje_object_signal_emit(Man->full_bg,
356                                   "e,state,visibility,show,now", "e");
357      }
358    else
359      {
360         if (Man->conf->anim_bg)
361           edje_object_signal_emit(Man->full_bg,
362                                  "e,state,visibility,show,custom", "e");
363         else
364           edje_object_signal_emit(Man->full_bg,
365                                  "e,state,visibility,show,custom,now", "e");
366      }
367
368    /* Showing top gadgets */
369    EINA_LIST_FOREACH(Man->gadgets[GADMAN_LAYER_TOP], l, gcc)
370      {
371         if (Man->conf->anim_gad)
372           edje_object_signal_emit(gcc->o_frame,
373                                   "e,state,visibility,show", "e");
374         else
375           edje_object_signal_emit(gcc->o_frame,
376                                   "e,state,visibility,show,now", "e");
377      }
378 }
379
380 void
381 gadman_gadgets_hide(void)
382 {
383    const Eina_List *l;
384    E_Gadcon_Client *gcc;
385
386    Man->visible = 0;
387
388    if (Man->conf->bg_type == BG_STD)
389      {
390         if (Man->conf->anim_bg)
391              edje_object_signal_emit(Man->full_bg,
392                                      "e,state,visibility,hide", "e");
393         else
394              edje_object_signal_emit(Man->full_bg,
395                                      "e,state,visibility,hide", "e");
396      }
397    else
398      {
399         if (Man->conf->anim_bg)
400           edje_object_signal_emit(Man->full_bg,
401                                   "e,state,visibility,hide,custom", "e");
402         else
403           edje_object_signal_emit(Man->full_bg,
404                                   "e,state,visibility,hide,custom,now", "e");
405      }
406
407    /* Hiding top gadgets */
408    EINA_LIST_FOREACH(Man->gadgets[GADMAN_LAYER_TOP], l, gcc)
409      {
410         if (Man->conf->anim_gad)
411           edje_object_signal_emit(gcc->o_frame,
412                                   "e,state,visibility,hide", "e");
413         else
414           edje_object_signal_emit(gcc->o_frame,
415                                   "e,state,visibility,hide,now", "e");
416      }
417 }
418
419 void
420 gadman_gadgets_toggle(void)
421 {
422    if (Man->visible)
423      gadman_gadgets_hide();
424    else
425      gadman_gadgets_show();
426 }
427
428 void
429 gadman_update_bg(void)
430 {
431    Evas_Object *obj;
432    const char *ext;
433
434    obj = edje_object_part_swallow_get(Man->full_bg, "e.swallow.bg");
435    if (obj)
436      {
437         edje_object_part_unswallow(Man->full_bg, obj);
438         evas_object_del(obj);
439      }
440
441    switch (Man->conf->bg_type)
442      {
443         case BG_STD:
444         case BG_TRANS:
445           break;
446         case BG_COLOR:
447           obj = evas_object_rectangle_add(Man->gc_top->evas);
448           evas_object_color_set(obj, Man->conf->color_r, Man->conf->color_g,
449                                 Man->conf->color_b, 200);
450           edje_object_part_swallow(Man->full_bg, "e.swallow.bg", obj);
451           break;
452         case BG_CUSTOM:
453           ext = strrchr(Man->conf->custom_bg, '.');
454           if (!strcmp(ext, ".edj") || !strcmp(ext, ".EDJ"))
455             {
456                 //THIS IS FOR E17 backgrounds
457                 obj = edje_object_add(Man->gc_top->evas);
458                 edje_object_file_set(obj, Man->conf->custom_bg,
459                                      "e/desktop/background");
460             }
461           else
462             {
463                 //THIS IS FOR A NORMAL IMAGE
464                 obj = evas_object_image_add(Man->gc_top->evas);
465                 evas_object_image_file_set(obj, Man->conf->custom_bg, NULL);
466                 evas_object_image_fill_set(obj, 0, 0, Man->container->w,
467                                            Man->container->h);
468             }
469           edje_object_part_swallow(Man->full_bg, "e.swallow.bg", obj);
470           break;
471         default:
472           break;
473      }
474 }
475
476 /* Internals */
477 static E_Gadcon*
478 _gadman_gadcon_new(const char* name, Gadman_Layer_Type layer, E_Zone *zone, E_Gadcon_Location * loc)
479 {
480    const Eina_List *l;
481    E_Gadcon *gc;
482    E_Config_Gadcon *cg;
483
484    /* Create Gadcon */
485    gc = E_OBJECT_ALLOC(E_Gadcon, E_GADCON_TYPE, NULL);
486    if (!gc) return NULL;
487
488    gc->name = eina_stringshare_add(name);
489    gc->layout_policy = E_GADCON_LAYOUT_POLICY_PANEL;
490    gc->orient = E_GADCON_ORIENT_FLOAT;
491    gc->location = loc;
492
493    /* Create ecore fullscreen window */
494    if (layer > GADMAN_LAYER_BG)
495      {
496         if (!Man->top_ee)
497           {
498              Man->top_ee = e_canvas_new(Man->container->win, 0, 0, 0, 0, 1, 1,
499                                         &(Man->top_win));
500           }
501
502         if (Man->use_composite)
503           {
504              ecore_evas_alpha_set(Man->top_ee, 1);
505              Man->top_win = ecore_evas_software_x11_window_get(Man->top_ee);
506              ecore_x_window_shape_rectangle_set(Man->top_win, 0, 0,
507                                                 Man->width, Man->height);
508           }
509         else
510           ecore_evas_shaped_set(Man->top_ee, 1);
511
512         e_canvas_add(Man->top_ee); //??
513         e_container_window_raise(Man->container, Man->top_win, 250);
514
515         ecore_evas_move_resize(Man->top_ee, 0, 0, Man->width, Man->height);
516         ecore_evas_hide(Man->top_ee);
517
518         gc->evas = ecore_evas_get(Man->top_ee);
519         e_gadcon_ecore_evas_set(gc, Man->top_ee);
520
521         /* create full background object */
522         Man->full_bg = edje_object_add(gc->evas);
523         e_theme_edje_object_set(Man->full_bg, "base/theme/gadman",
524                                 "e/gadman/full_bg");
525         edje_object_signal_callback_add(Man->full_bg, "mouse,down,*",
526                                         "grabber", on_bg_click, NULL);
527         edje_object_signal_callback_add(Man->full_bg, "e,action,hide,stop",
528                                         "", on_hide_stop, NULL);
529         
530         evas_object_move(Man->full_bg, 0, 0);
531         evas_object_resize(Man->full_bg, Man->width, Man->height);
532         evas_object_show(Man->full_bg);
533      }
534    /* ... or use the e background window */
535    else
536      {
537         gc->evas = Man->container->bg_evas;
538         e_gadcon_ecore_evas_set(gc, Man->container->bg_ecore_evas);
539         e_gadcon_xdnd_window_set(gc, Man->container->bg_win);
540         e_gadcon_dnd_window_set(gc, Man->container->event_win);
541         e_drop_xdnd_register_set(Man->container->bg_win, 1);
542      }
543
544    e_gadcon_zone_set(gc, zone);
545    e_gadcon_util_menu_attach_func_set(gc, _attach_menu, NULL);
546    e_gadcon_populate_callback_set(gc, gadman_populate_class, (void*)layer);
547
548    gc->id = ID_GADMAN_LAYER_BASE + layer;
549    gc->edje.o_parent = NULL;
550    gc->edje.swallow_name = NULL;
551    gc->shelf = NULL;
552    gc->toolbar = NULL;
553    gc->editing = 0;
554    gc->o_container = NULL;
555    gc->frame_request.func = NULL;
556    gc->resize_request.func = NULL;
557    gc->min_size_request.func = NULL;
558
559    /* Search for existing gadcon config */
560    gc->cf = NULL;
561    EINA_LIST_FOREACH(e_config->gadcons, l, cg)
562      {
563         if ((!strcmp(cg->name, name)) && (cg->zone == zone->num))
564           {
565              gc->cf = cg;
566              break;
567           }
568      }
569
570    /* ... or create a new one */
571    if (!gc->cf)
572      {
573         gc->cf = E_NEW(E_Config_Gadcon, 1);
574         gc->cf->name = eina_stringshare_add(name);
575         gc->cf->id = gc->id;
576         gc->cf->zone = zone->num;
577         gc->cf->clients = NULL;
578         e_config->gadcons = eina_list_append(e_config->gadcons, gc->cf);
579         e_config_save_queue();
580      }
581
582    e_gadcon_custom_new(gc);
583
584    if (!Man->movers[layer])
585      Man->movers[layer] = _create_mover(gc);
586
587    /* Assigning top gadcon - needed in gadman_update_bg() */
588    if ((layer > GADMAN_LAYER_BG) && !Man->gc_top)
589      Man->gc_top = gc;
590
591    return gc;
592 }
593
594 static Evas_Object *
595 _create_mover(E_Gadcon *gc)
596 {
597    Evas_Object *mover;
598
599    /* create mover object */
600    mover = edje_object_add(gc->evas);
601    e_theme_edje_object_set(mover, "base/theme/gadman", "e/gadman/control");
602
603    edje_object_signal_callback_add(mover, "e,action,move,start", "",
604                                    on_move, (void*)DRAG_START);
605    edje_object_signal_callback_add(mover, "e,action,move,stop", "",
606                                    on_move, (void*)DRAG_STOP);
607    edje_object_signal_callback_add(mover, "e,action,move,go", "",
608                                    on_move, (void*)DRAG_MOVE);
609    edje_object_signal_callback_add(mover, "mouse,down,3", "overlay",
610                                    gadman_gadget_edit_end, NULL);
611
612    edje_object_signal_callback_add(mover, "e,action,resize,left,start", "",
613                                    on_left, (void*)DRAG_START);
614    edje_object_signal_callback_add(mover, "e,action,resize,left,stop", "",
615                                    on_left, (void*)DRAG_STOP);
616    edje_object_signal_callback_add(mover, "e,action,resize,left,go", "",
617                                    on_left, (void*)DRAG_MOVE);
618    edje_object_signal_callback_add(mover, "e,action,resize,down,start", "",
619                                    on_down, (void*)DRAG_START);
620    edje_object_signal_callback_add(mover, "e,action,resize,down,stop", "",
621                                    on_down, (void*)DRAG_STOP);
622    edje_object_signal_callback_add(mover, "e,action,resize,down,go", "",
623                                    on_down, (void*)DRAG_MOVE);
624    edje_object_signal_callback_add(mover, "e,action,resize,right,start", "",
625                                    on_right, (void*)DRAG_START);
626    edje_object_signal_callback_add(mover, "e,action,resize,right,stop", "",
627                                    on_right, (void*)DRAG_STOP);
628    edje_object_signal_callback_add(mover, "e,action,resize,right,go", "",
629                                    on_right, (void*)DRAG_MOVE);
630    edje_object_signal_callback_add(mover, "e,action,resize,up,start", "",
631                                    on_top, (void*)DRAG_START);
632    edje_object_signal_callback_add(mover, "e,action,resize,up,stop", "",
633                                    on_top, (void*)DRAG_STOP);
634    edje_object_signal_callback_add(mover, "e,action,resize,up,go", "",
635                                    on_top, (void*)DRAG_MOVE);
636
637    evas_object_move(mover, 20, 30);
638    evas_object_resize(mover, 100, 100);
639    evas_object_hide(mover);
640
641    return mover;
642 }
643
644 static Evas_Object *
645 _get_mover(E_Gadcon_Client *gcc)
646 {
647    return Man->movers[gcc->gadcon->id - ID_GADMAN_LAYER_BASE];
648 }
649
650 static void
651 _save_widget_position(E_Gadcon_Client *gcc)
652 {
653    int x, y, w, h;
654
655    evas_object_geometry_get(gcc->o_frame, &x, &y, &w, &h);
656    current->cf->geom.pos_x = (double)x / (double)Man->width;
657    current->cf->geom.pos_y = (double)y / (double)Man->height;
658    current->cf->geom.size_w = (double)w / (double)Man->width;;
659    current->cf->geom.size_h = (double)h / (double)Man->height;
660
661    e_config_save_queue();
662 }
663
664 static void
665 _apply_widget_position(E_Gadcon_Client *gcc)
666 {
667    int x, y, w, h;
668    E_Zone *zone;
669
670    x = gcc->cf->geom.pos_x * Man->width;
671    y = gcc->cf->geom.pos_y * Man->height;
672    w = gcc->cf->geom.size_w * Man->width;
673    h = gcc->cf->geom.size_h * Man->height;
674
675    /* Obtain zone from parent gadcon */
676    zone = gcc->gadcon->zone;
677
678    /* Respect min sizes */
679    if (h < gcc->min.h) h = gcc->min.h;
680    if (w < gcc->min.w) w = gcc->min.w;
681    if (h < 1) h = 100;
682    if (w < 1) w = 100;
683
684    /* Respect zone marigin */
685    if (x < zone->x) x = zone->x;
686    if (y < zone->y) y = zone->y;
687    if (x > (zone->x + zone->w)) x = zone->x;
688    if (y > (zone->y + zone->h)) y = zone->y;
689
690    if ((y + h) > (zone->y + zone->h + MIN_VISIBLE_MARIGIN)) 
691      h = ((zone->y + zone->h + MIN_VISIBLE_MARIGIN) - y);
692    if ((x + w) > (zone->x + zone->w + MIN_VISIBLE_MARIGIN)) 
693      w = ((zone->x + zone->w + MIN_VISIBLE_MARIGIN) - x);
694
695    evas_object_move(gcc->o_frame, x, y);
696    evas_object_resize(gcc->o_frame, w, h);
697 }
698
699 static void
700 _attach_menu(void *data __UNUSED__, E_Gadcon_Client *gcc, E_Menu *menu)
701 {
702    E_Menu *mn;
703    E_Menu_Item *mi;
704    char buf[128];
705    char *key;
706
707    //printf("Attach menu (gcc: %x id: %s) [%s]\n", gcc, gcc->cf->id, gcc->cf->style);
708    if (!gcc) return;
709
710    if (e_menu_item_nth(menu, 0))
711      {
712         mi = e_menu_item_new(menu);
713         e_menu_item_separator_set(mi, 1);
714      }
715
716    /* Move / resize*/
717    mi = e_menu_item_new(menu);
718    e_menu_item_label_set(mi, _("Begin move/resize"));
719    e_util_menu_item_theme_icon_set(mi, "transform-scale");
720    e_menu_item_callback_set(mi, on_menu_edit, gcc);
721
722
723    /* plain / inset */
724    if (!gcc->cf->style)
725      gcc->cf->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_INSET);
726
727    mn = e_menu_new();
728    mi = e_menu_item_new(mn);
729    e_menu_item_label_set(mi, _("Plain"));
730    e_menu_item_radio_set(mi, 1);
731    e_menu_item_radio_group_set(mi, 1);
732    if (!strcmp(gcc->cf->style, E_GADCON_CLIENT_STYLE_PLAIN))
733      e_menu_item_toggle_set(mi, 1);
734    e_menu_item_callback_set(mi, on_menu_style_plain, gcc);
735
736    mi = e_menu_item_new(mn);
737    e_menu_item_label_set(mi, _("Inset"));
738    e_menu_item_radio_set(mi, 1);
739    e_menu_item_radio_group_set(mi, 1);
740    if (!strcmp(gcc->cf->style, E_GADCON_CLIENT_STYLE_INSET))
741      e_menu_item_toggle_set(mi, 1);
742    e_menu_item_callback_set(mi, on_menu_style_inset, gcc);
743
744    mi = e_menu_item_new(mn);
745    e_menu_item_separator_set(mi, 1);
746
747    /* orient */
748    mi = e_menu_item_new(mn);
749    e_menu_item_label_set(mi, _("Free"));
750    e_menu_item_radio_set(mi, 1);
751    e_menu_item_radio_group_set(mi, 2);
752    if (gcc->cf->orient == E_GADCON_ORIENT_FLOAT)
753      e_menu_item_toggle_set(mi, 1);
754    e_menu_item_callback_set(mi, on_menu_style_float, gcc);
755
756    mi = e_menu_item_new(mn);
757    e_menu_item_label_set(mi, _("Horizontal"));
758    e_menu_item_radio_set(mi, 1);
759    e_menu_item_radio_group_set(mi, 2);
760    if (gcc->cf->orient == E_GADCON_ORIENT_HORIZ)
761      e_menu_item_toggle_set(mi, 1);
762    e_menu_item_callback_set(mi, on_menu_style_horiz, gcc);
763
764    mi = e_menu_item_new(mn);
765    e_menu_item_label_set(mi, _("Vertical"));
766    e_menu_item_radio_set(mi, 1);
767    e_menu_item_radio_group_set(mi, 2);
768    if (gcc->cf->orient == E_GADCON_ORIENT_VERT)
769      e_menu_item_toggle_set(mi, 1);
770    e_menu_item_callback_set(mi, on_menu_style_vert, gcc);
771
772    mi = e_menu_item_new(menu);
773    e_menu_item_label_set(mi, _("Appearance"));
774    e_util_menu_item_theme_icon_set(mi, "preferences-look");
775    e_menu_item_submenu_set(mi, mn);
776    e_object_del(E_OBJECT(mn));
777
778    /* bg / ontop */
779    mn = e_menu_new();
780    mi = e_menu_item_new(mn);
781    e_menu_item_label_set(mi, _("Always on desktop"));
782    e_menu_item_radio_set(mi, 1);
783    e_menu_item_radio_group_set(mi, 2);
784    if (gcc->gadcon->id == ID_GADMAN_LAYER_BG)
785      e_menu_item_toggle_set(mi, 1);
786    e_menu_item_callback_set(mi, on_menu_layer_bg, gcc);
787
788    mi = e_menu_item_new(mn);
789    key = _get_bind_text("gadman_toggle");
790    snprintf(buf, sizeof(buf), "%s %s",
791             _("On top pressing"), key);
792    free(key);
793    e_menu_item_label_set(mi, buf);
794    e_menu_item_radio_set(mi, 1);
795    e_menu_item_radio_group_set(mi, 2);
796    if (gcc->gadcon->id == ID_GADMAN_LAYER_TOP)
797      e_menu_item_toggle_set(mi, 1);
798    e_menu_item_callback_set(mi, on_menu_layer_top, gcc);
799
800    mi = e_menu_item_new(menu);
801    e_menu_item_label_set(mi, _("Behavior"));
802    e_util_menu_item_theme_icon_set(mi, "preferences-look");
803    e_menu_item_submenu_set(mi, mn);
804    e_object_del(E_OBJECT(mn));
805
806    mi = e_menu_item_new(menu);
807    e_menu_item_separator_set(mi, 1);
808
809    e_gadcon_client_add_location_menu(gcc, menu);
810
811    /* Remove this gadgets */
812    mi = e_menu_item_new(menu);
813    e_menu_item_label_set(mi, _("Remove"));
814    e_util_menu_item_theme_icon_set(mi, "list-remove");
815    e_menu_item_callback_set(mi, on_menu_delete, gcc);
816
817    /* Add other gadgets */
818    mi = e_menu_item_new(menu);
819    e_menu_item_separator_set(mi, 1);
820
821    mi = e_menu_item_new(menu);
822    e_menu_item_label_set(mi, _("Add other gadgets"));
823    e_util_menu_item_theme_icon_set(mi, "list-add");
824    e_menu_item_callback_set(mi, on_menu_add, gcc);
825 }
826
827 static char *
828 _get_bind_text(const char* action)
829 {
830    E_Binding_Key *bind;
831    char b[256] = "";
832
833    bind = e_bindings_key_get(action);   
834    if ((bind) && (bind->key))
835      {
836         if ((bind->mod) & (E_BINDING_MODIFIER_CTRL))
837           strcat(b, _("CTRL"));
838
839         if ((bind->mod) & (E_BINDING_MODIFIER_ALT))
840           {
841              if (b[0]) strcat(b, " + ");
842              strcat(b, _("ALT"));
843           }
844
845         if ((bind->mod) & (E_BINDING_MODIFIER_SHIFT))
846           {
847              if (b[0]) strcat(b, " + ");
848              strcat(b, _("SHIFT"));
849           }
850
851         if ((bind->mod) & (E_BINDING_MODIFIER_WIN))
852           {
853              if (b[0]) strcat(b, " + ");
854              strcat(b, _("WIN"));
855           }
856
857         if ((bind->key) && (bind->key[0]))
858           {
859              char *l;
860
861              if (b[0]) strcat(b, " + ");
862              l = strdup(bind->key);
863              l[0] = (char)toupper(bind->key[0]);
864              strcat(b, l);
865              free(l);
866           }
867         return strdup(b);
868      }
869    return strdup("(You must define a binding)");
870 }
871
872 /* Callbacks */
873 static void
874 on_shape_change(void *data __UNUSED__, E_Container_Shape *es, E_Container_Shape_Change ch __UNUSED__)
875 {
876    const Eina_List *l, *g;
877    E_Gadcon *gc;
878    E_Config_Gadcon_Client *cf_gcc;
879    E_Container  *con;
880    unsigned int layer;
881
882    con = e_container_shape_container_get(es);
883    if ((con->w == Man->width) && (con->h == Man->height)) return;
884
885    /* The screen size is changed */
886    Man->width = con->w;
887    Man->height = con->h;
888
889    /* ReStart gadgets */
890
891    for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
892      {
893         EINA_LIST_FOREACH(Man->gadcons[layer], g, gc)
894           {
895              e_gadcon_unpopulate(gc);
896              EINA_LIST_FOREACH(gc->cf->clients, l, cf_gcc)
897                gadman_gadget_place(cf_gcc, layer, gc->zone);
898           }
899      }
900 }
901
902 static void
903 on_menu_style_plain(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
904 {
905    E_Gadcon_Client *gcc;
906
907    gcc = current;
908    if (gcc->style) eina_stringshare_del(gcc->style);
909    gcc->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_PLAIN);
910
911    if (gcc->cf->style) eina_stringshare_del(gcc->cf->style);
912    gcc->cf->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_PLAIN);
913
914    edje_object_signal_emit(gcc->o_frame, "e,state,visibility,plain", "e");
915
916    e_config_save_queue();
917 }
918
919 static void
920 on_menu_style_inset(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
921 {
922    E_Gadcon_Client *gcc;
923
924    gcc = current;
925
926    if (gcc->style) eina_stringshare_del(gcc->style);
927    gcc->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_INSET);
928
929    if (gcc->cf->style) eina_stringshare_del(gcc->cf->style);
930    gcc->cf->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_INSET);
931
932    edje_object_signal_emit(gcc->o_frame, "e,state,visibility,inset", "e");
933
934    e_config_save_queue();
935 }
936
937 static void
938 _menu_style_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient)
939 {
940    int w, h;
941    gcc->cf->orient = orient;
942
943    if (gcc->client_class->func.orient)
944        gcc->client_class->func.orient(gcc, orient);
945
946    if (orient == E_GADCON_ORIENT_VERT)
947    {
948       w = DEFAULT_SIZE_W * Man->width;
949       if (w < gcc->min.w) w = gcc->min.w;
950       
951       if (gcc->aspect.w && gcc->aspect.h)
952          h = ((float)gcc->aspect.h / (float)gcc->aspect.w) * w;
953       else
954       {
955          h = DEFAULT_SIZE_H * Man->height;
956          if (h < gcc->min.h) h = gcc->min.h;
957       }
958    }
959    else
960    {
961       h = DEFAULT_SIZE_H * Man->height;
962       if (h < gcc->min.h) h = gcc->min.h;
963       
964       if (gcc->aspect.w && gcc->aspect.h)
965          w = ((float)gcc->aspect.w / (float)gcc->aspect.h) * h;
966       else
967       {
968          w = DEFAULT_SIZE_W * Man->width;
969          if (w < gcc->min.w) w = gcc->min.w;
970       }
971    }
972
973    evas_object_resize(gcc->o_frame, w, h);
974    _save_widget_position(gcc);
975 }
976
977 static void
978 on_menu_style_float(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
979 {
980    _menu_style_orient(data, E_GADCON_ORIENT_FLOAT);
981 }
982
983 static void
984 on_menu_style_horiz(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
985 {
986    _menu_style_orient(data, E_GADCON_ORIENT_HORIZ);
987 }
988
989 static void
990 on_menu_style_vert(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
991 {
992    _menu_style_orient(data, E_GADCON_ORIENT_VERT);
993 }
994
995 static void 
996 _on_menu_layer(E_Gadcon_Client *gcc, Gadman_Layer_Type layer)
997 {
998   const E_Gadcon_Client_Class *cc;  
999
1000   E_Gadcon_Client *new_gcc;
1001   E_Config_Gadcon_Client *cf;
1002
1003   cc = gcc->client_class;
1004   cf = gcc->cf;
1005   
1006   new_gcc = _gadman_gadget_add(cc, layer, cf);
1007   gadman_gadget_del(gcc);
1008   current = new_gcc;
1009   
1010   e_config_save_queue();
1011 }
1012
1013 static void
1014 on_menu_layer_bg(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1015 {
1016   _on_menu_layer(data, GADMAN_LAYER_BG);
1017 }
1018
1019 static void
1020 on_menu_layer_top(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1021 {
1022   _on_menu_layer(data, GADMAN_LAYER_TOP);
1023   gadman_gadgets_show();
1024 }
1025
1026 static void
1027 on_menu_edit(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1028 {
1029    gadman_gadget_edit_start(data);
1030 }
1031
1032 static void
1033 on_menu_add(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
1034 {
1035    if (Man->visible)
1036      gadman_gadgets_hide();
1037    e_configure_registry_call("extensions/gadman", m->zone->container, NULL);
1038 }
1039
1040 static void
1041 on_menu_delete(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1042 {
1043    gadman_gadget_del(data);
1044    e_config_save_queue();
1045 }
1046
1047 static void
1048 on_frame_click(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1049 {
1050    Evas_Event_Mouse_Down *ev;
1051    E_Gadcon_Client *gcc;
1052
1053    ev = event_info;
1054
1055    gcc = data;
1056
1057    if (gcc->gadcon->editing) gadman_gadget_edit_end(NULL, NULL, NULL, NULL);
1058
1059    current = gcc;
1060
1061    if (ev->button == 5)
1062      {
1063         E_Menu *m;
1064         int cx, cy, cw, ch;
1065
1066         m = e_menu_new();
1067         m = e_gadcon_client_util_menu_items_append(gcc, m, 0);
1068         gcc->menu = m;
1069         e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &cx, &cy, &cw, &ch);
1070         e_menu_activate_mouse(m,
1071                               e_util_zone_current_get(e_manager_current_get()),
1072                               cx + ev->output.x, cy + ev->output.y, 1, 1,
1073                               E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
1074      }
1075 }
1076
1077 static void
1078 on_top(void *data, Evas_Object *o __UNUSED__, const char *em __UNUSED__, const char *src __UNUSED__)
1079 {
1080    static int ox, oy, ow, oh; //Object coord
1081    static int dy;             //Mouse offset
1082    int mx, my;                //Mouse coord
1083    int action = (int)(long)data;
1084    Evas_Object *mover;
1085
1086    mover = _get_mover(current);
1087
1088    if (action == DRAG_START)
1089      {
1090         current->resizing = 1;
1091         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1092         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1093         dy = my - oy;
1094      }
1095    else if (action == DRAG_STOP)
1096      {
1097         current->resizing = 0;
1098         dy = 0;
1099         _save_widget_position(current);
1100      }
1101    else if ((action == DRAG_MOVE) && current->resizing)
1102      {
1103         int h;
1104
1105         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1106
1107         h = oy + oh + dy - my;
1108
1109         if (h < current->min.h)
1110           {
1111              my -= current->min.h - h;
1112              h = current->min.h;
1113           }
1114         /* don't go out of the screen */
1115         if (my < dy)
1116           {
1117              h += my - dy;
1118              my = dy;
1119           }
1120
1121         evas_object_resize(mover, ow, h);
1122         evas_object_move(mover, ox, my - dy);
1123
1124         evas_object_resize(current->o_frame, ow, h);
1125         evas_object_move(current->o_frame, ox, my - dy);
1126      }
1127 }
1128
1129 static void
1130 on_right(void *data, Evas_Object *o __UNUSED__, const char *em __UNUSED__, const char *src __UNUSED__)
1131 {
1132    Evas_Object *mover;
1133    static int ox, oy, ow, oh; //Object coord
1134    static int dx;             //Mouse offset
1135    int mx, my;                //Mouse coord
1136    int action;
1137
1138    mover = _get_mover(current);
1139
1140    action = (int)(long)data;
1141    if (action == DRAG_START)
1142      {
1143         current->resizing = 1;
1144         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1145         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1146         dx = mx - ow;
1147      }
1148    else if (action == DRAG_STOP)
1149      {
1150         current->resizing = 0;
1151         dx = 0;
1152         _save_widget_position(current);
1153      }
1154    else if ((action == DRAG_MOVE) && current->resizing)
1155      {
1156         int w;
1157
1158         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1159         w = mx - dx;
1160
1161         if (w < current->min.w) w = current->min.w;
1162         /* don't go out of the screen */
1163         if (w > (Man->width - ox)) w = Man->width - ox;
1164
1165         evas_object_resize(mover, w, oh);
1166         evas_object_resize(current->o_frame, w, oh);
1167      }
1168 }
1169
1170 static void
1171 on_down(void *data, Evas_Object *o __UNUSED__, const char *em __UNUSED__, const char *src __UNUSED__)
1172 {
1173    Evas_Object *mover;
1174    static int ox, oy, ow, oh; //Object coord
1175    static int dy;             //Mouse offset
1176    int mx, my;                //Mouse coord
1177    int action;
1178
1179    action = (int)(long)data;
1180    mover = _get_mover(current);
1181
1182    if (action == DRAG_START)
1183      {
1184         current->resizing = 1;
1185         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1186         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1187         dy = my - oh;
1188      }
1189    else if (action == DRAG_STOP)
1190      {
1191         current->resizing = 0;
1192         dy = 0;
1193         _save_widget_position(current);
1194      }
1195    else if ((action == DRAG_MOVE) && current->resizing)
1196      {
1197         int h;
1198
1199         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1200         h = my - dy;
1201
1202         if (h < current->min.h) h = current->min.h;
1203         /* don't go out of the screen */
1204         if (h > (Man->height - oy)) h = Man->height - oy;
1205
1206         evas_object_resize(mover, ow, h);
1207         evas_object_resize(current->o_frame, ow, h);
1208      }
1209 }
1210
1211 static void
1212 on_left(void *data, Evas_Object *o __UNUSED__, const char *em __UNUSED__, const char *src __UNUSED__)
1213 {
1214    Evas_Object *mover;
1215    static int ox, oy, ow, oh; //Object coord
1216    static int dx;             //Mouse offset
1217    int mx, my;                //Mouse coord
1218    int action;
1219
1220    action = (int)(long)data;
1221    mover = _get_mover(current);
1222
1223    if (action == DRAG_START)
1224      {
1225         current->resizing = 1;
1226         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1227         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1228         dx = mx - ox;
1229      }
1230    else if (action == DRAG_STOP)
1231      {
1232         current->resizing = 0;
1233         dx = 0;
1234         _save_widget_position(current);
1235      }
1236    else if ((action == DRAG_MOVE) && current->resizing)
1237      {
1238         int w;
1239
1240         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1241
1242         w = ox + ow + dx - mx;
1243
1244         if (w < current->min.w)
1245           {
1246              mx -= current->min.w - w;
1247              w = current->min.w;
1248           }
1249         /* don't go out of the screen */
1250         if (mx < dx)
1251           {
1252              w += mx - dx;
1253              mx = dx;
1254           }
1255
1256         evas_object_resize(mover, w, oh);
1257         evas_object_move(mover, mx - dx, oy);
1258
1259         evas_object_resize(current->o_frame, w, oh);
1260         evas_object_move(current->o_frame, mx - dx, oy);
1261      }
1262 }
1263
1264 static void
1265 on_move(void *data, Evas_Object *o __UNUSED__, const char *em __UNUSED__, const char *src __UNUSED__)
1266 {
1267    Evas_Object *mover;
1268    static int dx, dy;  //Offset of mouse pointer inside the mover
1269    static int ox, oy;  //Starting object position
1270    static int ow, oh;  //Starting object size
1271    int mx, my;         //Mouse coord
1272    int action;
1273
1274    action = (int)(long)data;
1275    mover = _get_mover(current);
1276
1277    /* DRAG_START */
1278    if (action == DRAG_START)
1279      {
1280         current->moving = 1;
1281         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1282         evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
1283
1284         dx = mx - ox;
1285         dy = my - oy;
1286
1287         return;
1288      }
1289
1290    /* DRAG_STOP */
1291    if (action == DRAG_STOP)
1292      {
1293         E_Config_Gadcon_Client *cf;
1294         E_Zone *dst_zone = NULL;
1295         E_Gadcon *dst_gadcon;
1296         int gx, gy;
1297
1298         current->moving = 0;
1299         dx = dy = 0;
1300
1301         /* checking if zone was changed for dragged gadget */
1302         evas_object_geometry_get(current->o_frame, &gx, &gy, NULL, NULL);
1303         dst_zone = e_container_zone_at_point_get(e_container_current_get(e_manager_current_get()), gx, gy);
1304         if (dst_zone && (current->gadcon->zone != dst_zone))
1305           {
1306              unsigned int layer = current->gadcon->id - ID_GADMAN_LAYER_BASE;
1307              cf = current->cf;
1308
1309              current->gadcon->cf->clients = eina_list_remove(current->gadcon->cf->clients, cf);
1310              dst_gadcon = gadman_gadcon_get(dst_zone, layer);
1311              if (dst_gadcon)
1312                {
1313                   dst_gadcon->cf->clients = eina_list_append(dst_gadcon->cf->clients, cf);
1314                   e_config_save_queue();
1315                }
1316           }
1317         else
1318           _save_widget_position(current);
1319         return;
1320      }
1321
1322    /* DRAG_MOVE */
1323    if ((action == DRAG_MOVE) && current->moving)
1324      {
1325         int x, y;
1326
1327         evas_pointer_output_xy_get(current->gadcon->evas, &mx, &my);
1328
1329         x = mx - dx;
1330         y = my - dy;
1331
1332         /* don't go out of the screen */
1333         if (x < 0) x = 0;
1334         if (x > (Man->width - ow)) x = Man->width - ow;
1335         if (y < 0) y = 0;
1336         if (y > (Man->height - oh)) y = Man->height - oh;
1337
1338         evas_object_move(current->o_frame, x , y);
1339         evas_object_move(mover, x, y);
1340         evas_object_raise(current->o_frame);
1341         evas_object_raise(mover);
1342      }
1343 }
1344
1345 static void
1346 on_bg_click(void *data __UNUSED__, Evas_Object *o __UNUSED__, const char *em __UNUSED__, const char *src __UNUSED__)
1347 {
1348    gadman_gadgets_hide();
1349 }
1350
1351 static void
1352 on_hide_stop(void *data __UNUSED__, Evas_Object *o __UNUSED__, const char *em __UNUSED__, const char *src __UNUSED__)
1353 {
1354    ecore_evas_hide(Man->top_ee);
1355 }
1356
1357 static int 
1358 _e_gadman_client_add(void *data __UNUSED__, const E_Gadcon_Client_Class *cc)
1359 {
1360    return !!gadman_gadget_add(cc, GADMAN_LAYER_BG);
1361 }
1362
1363 static void 
1364 _e_gadman_client_remove(void *data __UNUSED__, E_Gadcon_Client *gcc)
1365 {
1366    gadman_gadget_del(gcc);
1367 }