1 #include "e.h"
2
3 #define DEFAULT_LAYER E_LAYER_CLIENT_ABOVE
4 #define E_BRYCE_TYPE 0xE31338
5
6 static unsigned int bryce_version = 2;
7
8 typedef struct Bryce
9 {
10 E_Object *e_obj_inherit;
11 Eina_Stringshare *name;
12
13 Evas_Object *bryce;
14 Evas_Object *events;
15 Evas_Object *layout;
16 Evas_Object *site;
17 Evas_Object *scroller;
18 Evas_Object *autohide_event;
19 Eina_List *zone_obstacles;
20 Eina_List *spacers;
21
22 Evas_Object *parent; //comp_object is not an elm widget
23 Eina_Stringshare *style;
24 int size;
25 int x, y;
26 int last_w, last_h;
27 int autohide_size;
28 E_Layer layer;
29 unsigned int zone;
30 E_Gadget_Site_Orient orient;
31 E_Gadget_Site_Anchor anchor;
32
33 Ecore_Job *calc_job;
34 Ecore_Timer *save_timer;
35 Ecore_Timer *autohide_timer;
36 unsigned int autohide_blocked;
37 Eina_List *popups;
38 void *event_info;
39 unsigned int last_timestamp;
40
41 E_Menu *menu;
42
43 /* config: do not bitfield! */
44 Eina_Bool autosize;
45 Eina_Bool autohide;
46 unsigned int version;
47
48 Eina_Bool hidden E_BITFIELD;
49 Eina_Bool animating E_BITFIELD;
50 Eina_Bool mouse_in E_BITFIELD;
51 Eina_Bool noshadow E_BITFIELD;
52 Eina_Bool size_changed E_BITFIELD;
53 Eina_Bool editing E_BITFIELD;
54 } Bryce;
55
56 typedef struct Bryces
57 {
58 Eina_List *bryces;
59 } Bryces;
60
61 static E_Config_DD *edd_bryces;
62 static E_Config_DD *edd_bryce;
63 static Bryces *bryces;
64 static E_Action *resize_act;
65 static Eina_List *handlers;
66
67
68 static void _bryce_menu(Bryce *b, Evas_Object *g);
69
70 #define BRYCE_GET(obj) \
71 Bryce *b; \
72 b = evas_object_data_get((obj), "__bryce"); \
73 if (!b) abort()
74
75 static void
_bryce_obstacle_del(void * obs)76 _bryce_obstacle_del(void *obs)
77 {
78 Bryce *b = e_object_data_get(obs);
79
80 b->zone_obstacles = eina_list_remove(b->zone_obstacles, obs);
81 }
82
83 static void
_bryce_autohide_end(void * data,E_Efx_Map_Data * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED)84 _bryce_autohide_end(void *data, E_Efx_Map_Data *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
85 {
86 Bryce *b = data;
87
88 b->animating = 0;
89 }
90
91 static void
_bryce_autohide_coords(Bryce * b,int * x,int * y)92 _bryce_autohide_coords(Bryce *b, int *x, int *y)
93 {
94 int ox, oy, ow, oh;
95 E_Gadget_Site_Anchor an;
96
97 if (b->parent == e_comp->elm)
98 {
99 E_Zone *zone;
100
101 zone = e_comp_zone_number_get(b->zone);
102 ox = zone->x, oy = zone->y, ow = zone->w, oh = zone->h;
103 }
104 else
105 evas_object_geometry_get(b->parent, &ox, &oy, &ow, &oh);
106 an = e_gadget_site_anchor_get(b->site);
107
108 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
109 {
110 *x = b->x;
111
112 if (an & E_GADGET_SITE_ANCHOR_TOP)
113 *y = oy - lround(e_scale * b->size) + lround(e_scale * b->autohide_size);
114 if (an & E_GADGET_SITE_ANCHOR_BOTTOM)
115 *y = oy + oh - lround(e_scale * b->autohide_size);
116 }
117 else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL)
118 {
119 *y = b->y;
120
121 if (an & E_GADGET_SITE_ANCHOR_LEFT)
122 *x = ox - lround(e_scale * b->size) + lround(e_scale * b->autohide_size);
123 if (an & E_GADGET_SITE_ANCHOR_RIGHT)
124 *x = ox + ow - lround(e_scale * b->autohide_size);
125 }
126 }
127
128 static void
_bryce_position(Bryce * b,int w,int h,int * nx,int * ny)129 _bryce_position(Bryce *b, int w, int h, int *nx, int *ny)
130 {
131 int ox, oy, ow, oh;
132 int x, y;
133 E_Gadget_Site_Anchor an;
134
135 if (b->parent == e_comp->elm)
136 {
137 E_Zone *zone;
138
139 zone = e_comp_zone_number_get(b->zone);
140 ox = zone->x, oy = zone->y, ow = zone->w, oh = zone->h;
141 if (starting)
142 {
143 E_Zone *zone2;
144
145 zone2 = e_comp_object_util_zone_get(b->bryce);
146 if (zone != zone2)
147 evas_object_move(b->bryce, ox, oy);
148 }
149 }
150 else
151 evas_object_geometry_get(b->parent, &ox, &oy, &ow, &oh);
152 x = ox + (ow - w) / 2;
153 x = E_CLAMP(x, ox, ox + ow / 2);
154 y = oy + (oh - h) / 2;
155 y = E_CLAMP(y, oy, oy + oh / 2);
156 an = e_gadget_site_anchor_get(b->site);
157 if (an & E_GADGET_SITE_ANCHOR_LEFT)
158 x = ox;
159 if (an & E_GADGET_SITE_ANCHOR_TOP)
160 y = oy;
161 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
162 {
163 if (an & E_GADGET_SITE_ANCHOR_RIGHT)
164 x = ox + ow - w;
165 if (an & E_GADGET_SITE_ANCHOR_BOTTOM)
166 y = oy + oh - lround(e_scale * b->size);
167 if (!b->autosize)
168 x = ox;
169 }
170 else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL)
171 {
172 if (an & E_GADGET_SITE_ANCHOR_RIGHT)
173 x = ox + ow - lround(e_scale * b->size);
174 if (an & E_GADGET_SITE_ANCHOR_BOTTOM)
175 y = oy + oh - h;
176 if (!b->autosize)
177 y = oy;
178 }
179 b->x = x, b->y = y;
180 if (b->animating)
181 {
182 if (b->hidden)
183 {
184 _bryce_autohide_coords(b, &x, &y);
185 e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), 0.5, _bryce_autohide_end, b);
186 }
187 else
188 e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), 0.5, _bryce_autohide_end, b);
189 }
190 else if (b->hidden)
191 _bryce_autohide_coords(b, &x, &y);
192
193 if (nx && ny)
194 *nx = x, *ny = y;
195 else
196 evas_object_move(b->bryce, x, y);
197 }
198
199 static void
_bryce_autosize(Bryce * b)200 _bryce_autosize(Bryce *b)
201 {
202 int lw, lh, sw, sh, maxw, maxh, x, y, w, h;
203
204 E_FREE_FUNC(b->calc_job, ecore_job_del);
205 if (!b->autosize)
206 {
207 if (b->parent == e_comp->elm)
208 {
209 w = e_comp_zone_number_get(b->zone)->w;
210 if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL)
211 e_zone_useful_geometry_get(e_comp_zone_number_get(b->zone), NULL, NULL, NULL, &h);
212 else
213 h = e_comp_zone_number_get(b->zone)->h;
214 }
215 else
216 evas_object_geometry_get(b->parent, NULL, NULL, &w, &h);
217 if (b->size_changed)
218 elm_object_content_unset(b->scroller);
219 _bryce_position(b, w, h, &x, &y);
220 evas_object_move(b->bryce, x, y);
221 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
222 e_efx_resize(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), w, lround(b->size * e_scale), 0.1, NULL, NULL);
223 else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL)
224 e_efx_resize(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), lround(b->size * e_scale), h, 0.1, NULL, NULL);
225 evas_object_smart_need_recalculate_set(b->site, 1);
226 evas_object_size_hint_min_set(b->site, -1, -1);
227 if (b->size_changed)
228 elm_object_content_set(b->scroller, b->site);
229 b->size_changed = 0;
230 return;
231 }
232 if (b->parent == e_comp->elm) //screen-based bryce
233 {
234 E_Zone *zone;
235
236 zone = e_comp_zone_number_get(b->zone);
237 if (zone)
238 {
239 maxw = zone->w;
240 if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL)
241 e_zone_useful_geometry_get(e_comp_zone_number_get(b->zone), NULL, NULL, NULL, &maxh);
242 else
243 maxh = zone->h;
244 }
245 else return;
246 }
247 else
248 evas_object_geometry_get(b->parent, NULL, NULL, &maxw, &maxh);
249 do
250 {
251 if (b->size_changed)
252 {
253 evas_object_geometry_get(b->bryce, NULL, NULL, &w, &h);
254 elm_object_content_unset(b->scroller);
255 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
256 {
257 if (!h) h = 1;
258 evas_object_resize(b->bryce, w * lround(b->size * e_scale) / h, lround(b->size * e_scale));
259 evas_object_resize(b->site, w * lround(b->size * e_scale) / h, lround(b->size * e_scale));
260 }
261 else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL)
262 {
263 if (!w) w = 1;
264 evas_object_resize(b->bryce, lround(b->size * e_scale), h * lround(b->size * e_scale) / w);
265 evas_object_resize(b->site, lround(b->size * e_scale), h * lround(b->size * e_scale) / w);
266 }
267 evas_object_smart_need_recalculate_set(b->site, 1);
268 evas_object_size_hint_min_set(b->site, -1, -1);
269 evas_object_smart_calculate(b->site);
270 elm_object_content_set(b->scroller, b->site);
271 }
272 evas_object_size_hint_min_get(b->site, &sw, &sh);
273 if ((!sw) && (!sh)) b->size_changed = 1;
274 }
275 while ((!sw) && (!sh));
276 edje_object_size_min_calc(elm_layout_edje_get(b->layout), &lw, &lh);
277 _bryce_position(b, lw + sw, lh + sh, &x, &y);
278 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
279 w = MIN(MAX(lw + sw, lround(b->size * e_scale)), maxw), h = lround(b->size * e_scale);
280 else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL)
281 w = lround(b->size * e_scale), h = MIN(MAX(lh + sh, lround(b->size * e_scale)), maxh);
282 evas_object_move(b->bryce, x, y);
283 e_efx_resize(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), w, h, 0.1, NULL, NULL);
284 b->size_changed = 0;
285 }
286
287 static Eina_Bool
_bryce_autohide_timeout(Bryce * b)288 _bryce_autohide_timeout(Bryce *b)
289 {
290 int x = 0, y = 0;
291
292 b->autohide_timer = NULL;
293 b->hidden = b->animating = 1;
294 _bryce_autohide_coords(b, &x, &y);
295 e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), 0.5, _bryce_autohide_end, b);
296 return EINA_FALSE;
297 }
298
299 static void
_bryce_autohide_moveresize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)300 _bryce_autohide_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
301 {
302 Bryce *b = data;
303 int x, y, w, h;
304
305 evas_object_geometry_get(obj, &x, &y, &w, &h);
306 evas_object_geometry_set(b->autohide_event, x, y, w, h);
307 }
308
309 static void
_bryce_autohide_show(Bryce * b)310 _bryce_autohide_show(Bryce *b)
311 {
312 E_FREE_FUNC(b->autohide_timer, ecore_timer_del);
313 if (b->animating && (!b->hidden)) return;
314 e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(b->x, b->y), 0.5, _bryce_autohide_end, b);
315 b->animating = 1;
316 b->hidden = 0;
317 }
318
319 static void
_bryce_autohide_hide(Bryce * b)320 _bryce_autohide_hide(Bryce *b)
321 {
322 if (b->autohide_blocked) return;
323 if (b->autohide_timer)
324 ecore_timer_loop_reset(b->autohide_timer);
325 else
326 b->autohide_timer = ecore_timer_loop_add(1.0, (Ecore_Task_Cb)_bryce_autohide_timeout, b);
327 }
328
329 static void
_bryce_autohide_mouse_out(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)330 _bryce_autohide_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
331 {
332 Bryce *b = data;
333
334 _bryce_autohide_hide(b);
335 b->mouse_in = 0;
336 }
337
338 static void
_bryce_autohide_mouse_in(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)339 _bryce_autohide_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
340 {
341 Bryce *b = data;
342
343 b->mouse_in = 1;
344 _bryce_autohide_show(b);
345 }
346
347 static void
_bryce_autohide_setup(Bryce * b)348 _bryce_autohide_setup(Bryce *b)
349 {
350 int x, y, w, h;
351
352 if (!b->autohide) return;
353 b->autohide_event = evas_object_rectangle_add(evas_object_evas_get(b->bryce));
354 evas_object_geometry_get(b->bryce, &x, &y, &w, &h);
355 evas_object_geometry_set(b->autohide_event, x, y, w, h);
356 evas_object_color_set(b->autohide_event, 0, 0, 0, 0);
357 evas_object_repeat_events_set(b->autohide_event, 1);
358 evas_object_layer_set(b->autohide_event, b->layer + 1);
359 evas_object_show(b->autohide_event);
360 evas_object_event_callback_add(b->autohide_event, EVAS_CALLBACK_MOUSE_IN, _bryce_autohide_mouse_in, b);
361 evas_object_event_callback_add(b->autohide_event, EVAS_CALLBACK_MOUSE_OUT, _bryce_autohide_mouse_out, b);
362 evas_object_event_callback_add(b->bryce, EVAS_CALLBACK_MOVE, _bryce_autohide_moveresize, b);
363 evas_object_event_callback_add(b->bryce, EVAS_CALLBACK_RESIZE, _bryce_autohide_moveresize, b);
364 ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
365 if (!E_INSIDE(x, y, b->x, b->y, w, h))
366 _bryce_autohide_hide(b);
367 }
368
369 static void
_bryce_style(Evas_Object * site,Eina_Stringshare * name,Evas_Object * g)370 _bryce_style(Evas_Object *site, Eina_Stringshare *name, Evas_Object *g)
371 {
372 Evas_Object *ly, *prev;
373 char buf[1024];
374
375 BRYCE_GET(site);
376
377 ly = elm_layout_add(b->site);
378 snprintf(buf, sizeof(buf), "e/bryce/%s/%s", b->style ?: "default", name ?: "plain");
379 if (!e_theme_edje_object_set(ly, NULL, buf))
380 {
381 evas_object_del(ly);
382 return;
383 }
384 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
385 elm_layout_signal_emit(ly, "e,state,orient,horizontal", "e");
386 else
387 elm_layout_signal_emit(ly, "e,state,orient,vertical", "e");
388 edje_object_message_signal_process(elm_layout_edje_get(ly));
389 prev = e_gadget_util_layout_style_init(g, ly);
390 elm_object_part_content_set(ly, "e.swallow.content", g);
391 evas_object_smart_callback_call(g, "gadget_reparent", ly);
392 evas_object_del(prev);
393 }
394
395 static void
_bryce_site_hints(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)396 _bryce_site_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
397 {
398 Bryce *b = data;
399 int w, h;
400
401 evas_object_size_hint_min_get(obj, &w, &h);
402 if ((w < 0) || (h < 0)) return;
403 if (b->autosize && (!b->calc_job))
404 b->calc_job = ecore_job_add((Ecore_Cb)_bryce_autosize, b);
405 }
406
407 static E_Comp_Object_Type
_bryce_shadow_type(const Bryce * b)408 _bryce_shadow_type(const Bryce *b)
409 {
410 if ((b->layer == E_LAYER_DESKTOP_TOP) || b->noshadow)
411 return E_COMP_OBJECT_TYPE_NONE;
412 return E_COMP_OBJECT_TYPE_POPUP;
413 }
414
415 static void
_bryce_restack(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)416 _bryce_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
417 {
418 Bryce *b = data;
419 E_Layer layer;
420
421 layer = evas_object_layer_get(obj);
422 if (layer > DEFAULT_LAYER) return;
423 b->layer = layer;
424 if ((!b->noshadow) && (layer != b->layer))
425 e_comp_object_util_type_set(b->bryce, _bryce_shadow_type(b));
426 }
427
428 static Eina_Bool
_bryce_moveresize_save(void * data)429 _bryce_moveresize_save(void *data)
430 {
431 Bryce *b = data;
432 int w, h;
433 int size;
434
435 b->save_timer = NULL;
436 evas_object_geometry_get(b->bryce, NULL, NULL, &w, &h);
437 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
438 size = h;
439 else
440 size = w;
441 size = lround(size / e_scale);
442 if (b->size == size) return EINA_FALSE;
443 e_config_save_queue();
444 b->size = size;
445 return EINA_FALSE;
446 }
447
448 static void
_bryce_zone_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)449 _bryce_zone_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
450 {
451 Bryce *b = data;
452 e_object_del(E_OBJECT(b->e_obj_inherit));
453 }
454
455 static void
_bryce_zone_moveresize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)456 _bryce_zone_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
457 {
458 Bryce *b = data;
459 if (!b->calc_job)
460 b->calc_job = ecore_job_add((Ecore_Cb)_bryce_autosize, b);
461 }
462
463 static void
_bryce_zone_setup(Bryce * b)464 _bryce_zone_setup(Bryce *b)
465 {
466 Evas_Object *zone_clip;
467
468 zone_clip = evas_object_clip_get(b->bryce);
469 if (zone_clip)
470 {
471 evas_object_event_callback_del_full(zone_clip, EVAS_CALLBACK_DEL, _bryce_zone_del, b);
472 evas_object_event_callback_del_full(zone_clip, EVAS_CALLBACK_MOVE, _bryce_zone_moveresize, b);
473 evas_object_event_callback_del_full(zone_clip, EVAS_CALLBACK_RESIZE, _bryce_zone_moveresize, b);
474 }
475 zone_clip = e_comp_zone_number_get(b->zone)->bg_clip_object;
476 evas_object_clip_set(b->bryce, zone_clip);
477 evas_object_event_callback_add(zone_clip, EVAS_CALLBACK_DEL, _bryce_zone_del, b);
478 evas_object_event_callback_add(zone_clip, EVAS_CALLBACK_MOVE, _bryce_zone_moveresize, b);
479 evas_object_event_callback_add(zone_clip, EVAS_CALLBACK_RESIZE, _bryce_zone_moveresize, b);
480 }
481
482 static void
_bryce_rename(Bryce * b,int num)483 _bryce_rename(Bryce *b, int num)
484 {
485 char buf[1024], buf2[1024], *name, *p;
486
487 name = strdup(b->name);
488 if (b->version >= 2)
489 {
490 p = strrchr(name, '_');
491 p[0] = 0;
492 }
493 snprintf(buf, sizeof(buf), "__bryce%s", name);
494 snprintf(buf2, sizeof(buf2), "__bryce%s_%d", name, num);
495 e_gadget_site_rename(buf, buf2);
496 if (b->version >= 2)
497 {
498 snprintf(buf, sizeof(buf), "%s_%u", name, num);
499 eina_stringshare_replace(&b->name, buf);
500 }
501 free(name);
502 }
503
504 static void
_bryce_moveresize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)505 _bryce_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
506 {
507 Bryce *b = data;
508 int x, y, w, h;
509 E_Zone *zone;
510 int size;
511
512 evas_object_geometry_get(obj, &x, &y, &w, &h);
513 evas_object_geometry_set(b->events, x, y, w, h);
514 if (b->autohide)
515 {
516 E_FREE_LIST(b->zone_obstacles, e_object_del);
517 return;
518 }
519 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
520 size = h;
521 else
522 size = w;
523 if (((b->orient == E_GADGET_SITE_ORIENT_VERTICAL) && (w != b->last_w)) ||
524 ((b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) && (h != b->last_h)))
525 {
526 evas_object_smart_need_recalculate_set(b->site, 1);
527 evas_object_size_hint_min_set(b->site, -1, -1);
528 }
529 b->last_w = w, b->last_h = h;
530
531 if (size && (b->size != size))
532 {
533 if (b->save_timer)
534 ecore_timer_loop_reset(b->save_timer);
535 else
536 b->save_timer = ecore_timer_loop_add(0.5, _bryce_moveresize_save, b);
537 }
538
539 if (starting) return;
540 zone = e_comp_object_util_zone_get(obj);
541 if (zone)
542 {
543 Eina_Bool vertical = b->orient == E_GADGET_SITE_ORIENT_VERTICAL;
544 if (b->zone_obstacles)
545 {
546 Eina_List *l;
547 E_Zone_Obstacle *obs;
548
549 EINA_LIST_FOREACH(b->zone_obstacles, l, obs)
550 e_zone_obstacle_modify(obs, &(Eina_Rectangle){b->x, b->y, w, h}, vertical);
551 }
552 else
553 {
554 void *obs;
555
556 obs = e_zone_obstacle_add(e_comp_object_util_zone_get(obj), NULL,
557 &(Eina_Rectangle){b->x, b->y, w, h}, vertical);
558 e_object_data_set(obs, b);
559 E_OBJECT_DEL_SET(obs, _bryce_obstacle_del);
560 b->zone_obstacles = eina_list_append(b->zone_obstacles, obs);
561 }
562 }
563 else
564 {
565 /* determine "closest" zone:
566 * calculate size of rect between bryce and zone
567 * smallest rect = closest zone
568 */
569 Eina_List *l;
570 E_Zone *lz;
571 size = 0;
572
573 E_FREE_LIST(b->zone_obstacles, e_object_del);
574 EINA_LIST_FOREACH(e_comp->zones, l, lz)
575 {
576 int cw, ch;
577
578 if (x < lz->x)
579 cw = lz->x + lz->w - x;
580 else
581 cw = x + w - lz->x;
582 if (y < lz->y)
583 ch = lz->y + lz->h - y;
584 else
585 ch = y + h - lz->y;
586 if (size >= cw * ch) continue;
587 size = cw * ch;
588 zone = lz;
589 }
590 }
591 if (!zone) return;
592 if (b->zone == zone->num) return;
593 e_config_save_queue();
594 _bryce_rename(b, zone->num);
595 b->zone = zone->num;
596 _bryce_zone_setup(b);
597 _bryce_autosize(b);
598 }
599
600 static void
_bryce_mouse_wheel(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)601 _bryce_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
602 {
603 Bryce *b = data;
604 Evas_Event_Mouse_Wheel *ev = event_info;
605
606 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
607 if (e_bindings_wheel_evas_event_handle(E_BINDING_CONTEXT_ANY, b->e_obj_inherit, ev))
608 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
609 }
610
611 static void
_bryce_popup_hide(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)612 _bryce_popup_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
613 {
614 Bryce *b = data;
615
616 b->autohide_blocked--;
617 b->popups = eina_list_remove(b->popups, obj);
618 if (!b->autohide) return;
619 if (!b->mouse_in)
620 _bryce_autohide_hide(b);
621 }
622
623 static void
_bryce_popup(Bryce * b,Evas_Object * popup)624 _bryce_popup(Bryce *b, Evas_Object *popup)
625 {
626 evas_object_event_callback_add(popup, EVAS_CALLBACK_HIDE, _bryce_popup_hide, b);
627 b->autohide_blocked++;
628 b->popups = eina_list_append(b->popups, popup);
629 if (b->autohide)
630 _bryce_autohide_show(b);
631 }
632
633 static void
_bryce_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)634 _bryce_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
635 {
636 Bryce *b = data;
637 Evas_Object *p;
638 Evas_Object *zone_clip;
639 void *obs;
640
641 if (b->menu)
642 {
643 e_menu_deactivate(b->menu);
644 e_object_del(E_OBJECT(b->menu));
645 b->menu = NULL;
646 }
647 EINA_LIST_FREE(b->zone_obstacles, obs)
648 {
649 E_OBJECT_DEL_SET(obs, NULL);
650 e_object_del(obs);
651 }
652 evas_object_del(b->autohide_event);
653 E_FREE_FUNC(b->events, evas_object_del);
654 E_FREE_FUNC(b->calc_job, ecore_job_del);
655 E_FREE_FUNC(b->autohide_timer, ecore_timer_del);
656 ecore_timer_del(b->save_timer);
657 EINA_LIST_FREE(b->popups, p)
658 evas_object_event_callback_del(p, EVAS_CALLBACK_HIDE, _bryce_popup_hide);
659 zone_clip = evas_object_clip_get(b->bryce);
660 if (zone_clip)
661 {
662 evas_object_event_callback_del_full(zone_clip, EVAS_CALLBACK_DEL, _bryce_zone_del, b);
663 evas_object_event_callback_del_full(zone_clip, EVAS_CALLBACK_MOVE, _bryce_zone_moveresize, b);
664 evas_object_event_callback_del_full(zone_clip, EVAS_CALLBACK_RESIZE, _bryce_zone_moveresize, b);
665 }
666 E_FREE(b->e_obj_inherit);
667 b->bryce = NULL;
668 b->site = NULL;
669 }
670
671 static void
_bryce_object_free(E_Object * eobj)672 _bryce_object_free(E_Object *eobj)
673 {
674 Bryce *b = e_object_data_get(eobj);
675 evas_object_hide(b->bryce);
676 evas_object_del(b->bryce);
677 }
678
679 static void
_bryce_style_menu(void * data,Evas_Object * obj EINA_UNUSED,void * event_info)680 _bryce_style_menu(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
681 {
682 Bryce *b = data;
683 char buf[1024];
684
685 snprintf(buf, sizeof(buf), "e/bryce/%s", b->style ?: "default");
686 e_object_data_set(event_info, e_theme_collection_items_find(NULL, buf));
687 }
688
689 static void
_bryce_gadgets_menu_close(void * data,Evas_Object * obj)690 _bryce_gadgets_menu_close(void *data, Evas_Object *obj)
691 {
692 Bryce *b = data;
693
694 b->autohide_blocked--;
695 b->editing = 0;
696 evas_object_layer_set(b->bryce, b->layer);
697 evas_object_hide(obj);
698 evas_object_del(obj);
699 if (b->autohide && (!b->mouse_in))
700 _bryce_autohide_hide(b);
701 }
702
703 static void
_bryce_gadgets_menu(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)704 _bryce_gadgets_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
705 {
706 Bryce *b = data;
707 Evas_Object *comp_object;
708
709 b->autohide_blocked++;
710 b->editing = 1;
711 comp_object = e_gadget_site_edit(b->site);
712 evas_object_layer_set(b->bryce, E_LAYER_POPUP);
713 e_comp_object_util_autoclose(comp_object, _bryce_gadgets_menu_close, e_comp_object_util_autoclose_on_escape, b);
714 }
715
716 static void
_bryce_autosize_menu(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)717 _bryce_autosize_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
718 {
719 Bryce *b = data;
720
721 e_bryce_autosize_set(b->bryce, !b->autosize);
722 }
723
724 static void
_bryce_autohide_menu(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)725 _bryce_autohide_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
726 {
727 Bryce *b = data;
728
729 e_bryce_autohide_set(b->bryce, !b->autohide);
730 }
731
732 static void
_bryce_remove_menu(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)733 _bryce_remove_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
734 {
735 Bryce *b = data;
736 bryces->bryces = eina_list_remove(bryces->bryces, data);
737 e_gadget_site_del(b->site);
738 eina_stringshare_del(b->name);
739 eina_stringshare_del(b->style);
740 evas_object_hide(b->bryce);
741 evas_object_del(b->bryce);
742 e_config_save_queue();
743 }
744
745 static void
_bryce_wizard_menu(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)746 _bryce_wizard_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
747 {
748 Bryce *b = data;
749 Evas_Object *editor;
750
751 editor = e_bryce_edit(b->bryce);
752 _bryce_popup(b, editor);
753 }
754
755 static void
_bryce_gadget_settings_menu(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)756 _bryce_gadget_settings_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
757 {
758 Evas_Object *g = data;
759 e_gadget_configure(g);
760 }
761
762 static void
_bryce_gadget_remove_menu(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)763 _bryce_gadget_remove_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
764 {
765 Evas_Object *g = data;
766 e_gadget_del(g);
767 e_config_save_queue();
768 }
769
770 static void
_bryce_menu_post_cb(void * data,E_Menu * m)771 _bryce_menu_post_cb(void *data, E_Menu *m)
772 {
773 Bryce *b = data;
774 if (b->menu != m) return;
775 b->menu = NULL;
776 }
777
778 static void
_bryce_menu_populate(Bryce * b,E_Menu * m,Evas_Object * g)779 _bryce_menu_populate(Bryce *b, E_Menu *m, Evas_Object *g)
780 {
781 E_Menu_Item *mi;
782 const char *s = NULL;
783
784 if (g) s = e_gadget_type_get(g);
785 if (s) e_menu_title_set(m, e_gadget_type_get(g));
786 else e_menu_title_set(m, _("Gadget Bar"));
787
788 if (g)
789 {
790 mi = e_menu_item_new(m);
791 e_menu_item_label_set(mi, _("Settings"));
792 e_util_menu_item_theme_icon_set(mi, "preferences-system");
793 e_menu_item_callback_set(mi, _bryce_gadget_settings_menu, g);
794
795 mi = e_menu_item_new(m);
796 e_menu_item_label_set(mi, _("Delete"));
797 e_util_menu_item_theme_icon_set(mi, "list-remove");
798 e_menu_item_callback_set(mi, _bryce_gadget_remove_menu, g);
799
800 e_gadget_menu_populate(g, m);
801
802 mi = e_menu_item_new(m);
803 e_menu_item_separator_set(mi, 1);
804 }
805
806 mi = e_menu_item_new(m);
807 e_menu_item_label_set(mi, _("Autosize"));
808 e_menu_item_check_set(mi, 1);
809 e_menu_item_toggle_set(mi, b->autosize);
810 e_menu_item_callback_set(mi, _bryce_autosize_menu, b);
811
812 mi = e_menu_item_new(m);
813 e_menu_item_label_set(mi, _("Autohide"));
814 e_menu_item_check_set(mi, 1);
815 e_menu_item_toggle_set(mi, b->autohide);
816 e_menu_item_callback_set(mi, _bryce_autohide_menu, b);
817
818 mi = e_menu_item_new(m);
819 e_menu_item_label_set(mi, _("Bar Settings"));
820 e_menu_item_callback_set(mi, _bryce_wizard_menu, b);
821
822 mi = e_menu_item_new(m);
823 e_menu_item_label_set(mi, _("Add Gadget"));
824 e_menu_item_callback_set(mi, _bryce_gadgets_menu, b);
825
826 mi = e_menu_item_new(m);
827 e_menu_item_label_set(mi, _("Delete Bar"));
828 e_util_menu_item_theme_icon_set(mi, "list-remove");
829 e_menu_item_callback_set(mi, _bryce_remove_menu, b);
830
831 if (b->menu)
832 {
833 e_menu_deactivate(b->menu);
834 e_object_del(E_OBJECT(b->menu));
835 }
836 b->menu = m;
837 e_menu_post_deactivate_callback_set(m, _bryce_menu_post_cb, b);
838 }
839
840 static void
_bryce_owner_menu(void * data,Evas_Object * obj EINA_UNUSED,void * event_info)841 _bryce_owner_menu(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
842 {
843 Bryce *b = data;
844 E_Menu_Item *mi = event_info;
845 E_Menu *subm;
846
847 e_menu_item_label_set(mi, _("Gadget Bar"));
848
849 subm = e_menu_new();
850 e_menu_hold_mode_set(subm, EINA_FALSE);
851 e_menu_item_submenu_set(mi, subm);
852 e_object_unref(E_OBJECT(subm));
853
854 _bryce_menu_populate(b, subm, NULL);
855 }
856
857 static void
_bryce_gadget_popup(void * data,Evas_Object * obj EINA_UNUSED,void * event_info)858 _bryce_gadget_popup(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
859 {
860 _bryce_popup(data, event_info);
861 }
862
863 static void
_bryce_gadget_locked(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)864 _bryce_gadget_locked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
865 {
866 Bryce *b = data;
867
868 b->autohide_blocked++;
869 if (b->autohide)
870 _bryce_autohide_show(b);
871 }
872
873 static void
_bryce_gadget_unlocked(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)874 _bryce_gadget_unlocked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
875 {
876 Bryce *b = data;
877
878 b->autohide_blocked--;
879 if (b->autohide && (!b->mouse_in))
880 _bryce_autohide_hide(b);
881 }
882
883 static void
_bryce_site_anchor(void * data,Evas_Object * obj,void * event_info EINA_UNUSED)884 _bryce_site_anchor(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
885 {
886 Bryce *b = data;
887
888 e_bryce_orient(b->bryce, e_gadget_site_orient_get(obj), e_gadget_site_anchor_get(obj));
889 }
890
891 static void
_bryce_gadget_size_request(void * data,Evas_Object * obj EINA_UNUSED,void * event_info)892 _bryce_gadget_size_request(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
893 {
894 Evas_Coord_Size *size = event_info;
895 Bryce *b = data;
896
897 edje_object_part_geometry_get(elm_layout_edje_get(b->layout), "e.swallow.content", NULL, NULL, &size->w, &size->h);
898 }
899
900 static void
_bryce_context(Evas_Object * site,Evas_Object * g,unsigned int timestamp)901 _bryce_context(Evas_Object *site, Evas_Object *g, unsigned int timestamp)
902 {
903 Bryce *b = evas_object_data_get(site, "__bryce");
904 if (b)
905 {
906 b->last_timestamp = timestamp;
907 _bryce_menu(b, g);
908 }
909 }
910
911 static void
_bryce_context_cancel(Evas_Object * site,Evas_Object * g EINA_UNUSED,unsigned int timestamp)912 _bryce_context_cancel(Evas_Object *site, Evas_Object *g EINA_UNUSED, unsigned int timestamp)
913 {
914 Bryce *b = evas_object_data_get(site, "__bryce");
915 if (b)
916 {
917 b->last_timestamp = timestamp;
918 if (b->menu)
919 {
920 e_menu_deactivate(b->menu);
921 e_object_del(E_OBJECT(b->menu));
922 b->menu = NULL;
923 }
924 }
925 }
926
927 static void
_bryce_orient(Bryce * b)928 _bryce_orient(Bryce *b)
929 {
930 char buf[1024];
931
932 evas_object_del(b->site);
933
934 snprintf(buf, sizeof(buf), "__bryce%s", b->name);
935 b->site = e_gadget_site_add(b->orient, buf);
936 E_EXPAND(b->site);
937 E_FILL(b->site);
938 evas_object_data_set(b->site, "__bryce", b);
939 elm_object_content_set(b->scroller, b->site);
940 e_gadget_site_owner_setup(b->site, b->anchor, _bryce_style, _bryce_context, _bryce_context_cancel);
941 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
942 {
943 elm_layout_signal_emit(b->layout, "e,state,orient,horizontal", "e");
944 elm_layout_signal_emit(b->scroller, "e,state,orient,horizontal", "e");
945 elm_scroller_policy_set(b->scroller, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
946 }
947 else
948 {
949 elm_layout_signal_emit(b->layout, "e,state,orient,vertical", "e");
950 elm_layout_signal_emit(b->scroller, "e,state,orient,vertical", "e");
951 elm_scroller_policy_set(b->scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
952 }
953 evas_object_event_callback_add(b->site, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _bryce_site_hints, b);
954 evas_object_smart_callback_add(b->site, "gadget_site_anchor", _bryce_site_anchor, b);
955 evas_object_smart_callback_add(b->site, "gadget_site_style_menu", _bryce_style_menu, b);
956 evas_object_smart_callback_add(b->site, "gadget_site_owner_menu", _bryce_owner_menu, b);
957 evas_object_smart_callback_add(b->site, "gadget_site_popup", _bryce_gadget_popup, b);
958 evas_object_smart_callback_add(b->site, "gadget_site_locked", _bryce_gadget_locked, b);
959 evas_object_smart_callback_add(b->site, "gadget_site_unlocked", _bryce_gadget_unlocked, b);
960 evas_object_smart_callback_add(b->site, "gadget_site_parent_size_request", _bryce_gadget_size_request, b);
961 }
962
963 static void
_bryce_style_apply(Bryce * b)964 _bryce_style_apply(Bryce *b)
965 {
966 char buf[1024];
967 Eina_Bool noshadow;
968
969 snprintf(buf, sizeof(buf), "e/bryce/%s/base", b->style ?: "default");
970 e_theme_edje_object_set(b->layout, NULL, buf);
971 noshadow = b->noshadow;
972 b->noshadow = !!elm_layout_data_get(b->layout, "noshadow");
973 if (b->bryce && (noshadow != b->noshadow))
974 e_comp_object_util_type_set(b->bryce, _bryce_shadow_type(b));
975 }
976
977 static void
_bryce_create(Bryce * b,Evas_Object * parent)978 _bryce_create(Bryce *b, Evas_Object *parent)
979 {
980 Evas_Object *ly, *bryce, *scr;
981
982 b->e_obj_inherit = E_OBJECT_ALLOC(E_Object, E_BRYCE_TYPE, _bryce_object_free);
983 b->events = evas_object_rectangle_add(e_comp->evas);
984 evas_object_repeat_events_set(b->events, EINA_TRUE);
985 evas_object_color_set(b->events, 0, 0, 0, 0);
986 evas_object_name_set(b->events, "b->events");
987 evas_object_show(b->events);
988 e_object_data_set(b->e_obj_inherit, b);
989 b->layout = ly = elm_layout_add(parent);
990 _bryce_style_apply(b);
991
992 b->scroller = scr = elm_scroller_add(ly);
993 elm_scroller_bounce_set(scr, 0, 0);
994 elm_object_style_set(scr, "bryce");
995 _bryce_orient(b);
996 elm_object_part_content_set(ly, "e.swallow.content", scr);
997 evas_object_show(ly);
998 b->bryce = bryce = e_comp_object_util_add(ly, _bryce_shadow_type(b));
999 // evas_object_repeat_events_set(evas_object_smart_parent_get(ly), 1);
1000 evas_object_smart_member_add(b->events, bryce);
1001 evas_object_raise(b->events);
1002 evas_object_data_set(bryce, "comp_skip", (void*)1);
1003 evas_object_layer_set(bryce, b->layer);
1004 evas_object_lower(bryce);
1005
1006 b->parent = parent;
1007 {
1008 const char *str;
1009
1010 str = elm_layout_data_get(ly, "hidden_state_size");
1011 if (str && str[0])
1012 b->autohide_size = strtol(str, NULL, 10);
1013 }
1014 evas_object_data_set(bryce, "__bryce", b);
1015 evas_object_event_callback_add(bryce, EVAS_CALLBACK_DEL, _bryce_del, b);
1016 evas_object_event_callback_add(bryce, EVAS_CALLBACK_RESTACK, _bryce_restack, b);
1017 evas_object_event_callback_add(bryce, EVAS_CALLBACK_MOVE, _bryce_moveresize, b);
1018 evas_object_event_callback_add(bryce, EVAS_CALLBACK_RESIZE, _bryce_moveresize, b);
1019 evas_object_event_callback_add(b->events, EVAS_CALLBACK_MOUSE_WHEEL, _bryce_mouse_wheel, b);
1020
1021 _bryce_zone_setup(b);
1022 _bryce_autohide_setup(b);
1023 _bryce_autosize(b);
1024 }
1025
1026 static Eina_Bool
_bryce_act_resize(E_Object * obj,const char * params,E_Binding_Event_Wheel * ev)1027 _bryce_act_resize(E_Object *obj, const char *params, E_Binding_Event_Wheel *ev)
1028 {
1029 Bryce *b;
1030 int size, step = 4;
1031 char buf[64];
1032
1033 if (obj->type != E_BRYCE_TYPE) return EINA_FALSE;
1034 if (params && params[0])
1035 {
1036 step = strtol(params, NULL, 10);
1037 step = MAX(step, 4);
1038 }
1039 b = e_object_data_get(obj);
1040 size = b->size;
1041 if (ev->z < 0)//up
1042 b->size += step;
1043 else
1044 b->size -= step;
1045 b->size = E_CLAMP(b->size, 20, 256);
1046 if (dblequal(e_scale, 1.0))
1047 snprintf(buf, sizeof(buf), "%dpx", b->size);
1048 else
1049 snprintf(buf, sizeof(buf), "%dpx (%ldpx scaled)", b->size, lround(b->size * e_scale));
1050 elm_object_part_text_set(b->layout, "e.text", buf);
1051 elm_object_signal_emit(b->layout, "e,action,resize", "e");
1052 e_config_save_queue();
1053 if (size == b->size) return EINA_TRUE;
1054 b->size_changed = 1;
1055 if (!b->calc_job)
1056 b->calc_job = ecore_job_add((Ecore_Cb)_bryce_autosize, b);
1057 return EINA_TRUE;
1058 }
1059
1060 static void
_bryce_menu(Bryce * b,Evas_Object * g)1061 _bryce_menu(Bryce *b, Evas_Object *g)
1062 {
1063 E_Menu *m;
1064 int x = 0, y = 0, w = 1, h = 1;
1065
1066 m = e_menu_new();
1067 e_menu_hold_mode_set(m, EINA_FALSE);
1068 _bryce_menu_populate(b, m, g);
1069 if (g)
1070 evas_object_geometry_get(g, &x, &y, &w, &h);
1071 else
1072 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1073 e_menu_activate_mouse(m, e_zone_current_get(), x, y, w, h,
1074 E_MENU_POP_DIRECTION_AUTO, b->last_timestamp);
1075 _bryce_popup(b, m->comp_object);
1076 }
1077
1078 static Eina_Bool
_bryce_zone_useful_geometry_changed(void * d EINA_UNUSED,int t EINA_UNUSED,E_Event_Zone_Move_Resize * ev)1079 _bryce_zone_useful_geometry_changed(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Zone_Move_Resize *ev)
1080 {
1081 Eina_List *l;
1082 Bryce *b;
1083
1084 EINA_LIST_FOREACH(bryces->bryces, l, b)
1085 {
1086 if (b->bryce && (b->zone == ev->zone->num) &&
1087 (b->orient == E_GADGET_SITE_ORIENT_VERTICAL))
1088 _bryce_autosize(b);
1089 }
1090 return ECORE_CALLBACK_RENEW;
1091 }
1092
1093 static void
_bryce_comp_resize(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1094 _bryce_comp_resize(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1095 {
1096 Eina_List *l;
1097 Bryce *b;
1098
1099 EINA_LIST_FOREACH(bryces->bryces, l, b)
1100 {
1101 if (e_comp_zone_number_get(b->zone))
1102 {
1103 if (b->bryce) continue;
1104 _bryce_create(b, e_comp->elm);
1105 evas_object_show(b->bryce);
1106 }
1107 }
1108 }
1109
1110 E_API Evas_Object *
e_bryce_add(Evas_Object * parent,const char * name,E_Gadget_Site_Orient orient,E_Gadget_Site_Anchor an)1111 e_bryce_add(Evas_Object *parent, const char *name, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an)
1112 {
1113 Bryce *b;
1114 const char *z;
1115
1116 b = E_NEW(Bryce, 1);
1117 b->size = 48;
1118 b->name = eina_stringshare_add(name);
1119 z = strrchr(name, '_');
1120 b->zone = strtoul(z + 1, NULL, 10);
1121 b->anchor = an;
1122 b->orient = orient;
1123 b->layer = DEFAULT_LAYER;
1124 b->version = bryce_version;
1125 _bryce_create(b, parent);
1126 bryces->bryces = eina_list_append(bryces->bryces, b);
1127 e_config_save_queue();
1128 return b->bryce;
1129 }
1130
1131 E_API void
e_bryce_orient(Evas_Object * bryce,E_Gadget_Site_Orient orient,E_Gadget_Site_Anchor an)1132 e_bryce_orient(Evas_Object *bryce, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an)
1133 {
1134 const char *loc = NULL, *loc2 = NULL;
1135 char buf[1024], buf2[1024];
1136
1137 BRYCE_GET(bryce);
1138 if ((b->orient == orient) && (b->anchor == an)) return;
1139 if (an & E_GADGET_SITE_ANCHOR_TOP)
1140 loc = "top";
1141 else if (an & E_GADGET_SITE_ANCHOR_BOTTOM)
1142 loc = "bottom";
1143 else if (an & E_GADGET_SITE_ANCHOR_LEFT)
1144 loc = "left";
1145 else if (an & E_GADGET_SITE_ANCHOR_RIGHT)
1146 loc = "right";
1147 if (an & E_GADGET_SITE_ANCHOR_RIGHT)
1148 loc2 = "right";
1149 else if (an & E_GADGET_SITE_ANCHOR_LEFT)
1150 loc2 = "left";
1151 else if (an & E_GADGET_SITE_ANCHOR_TOP)
1152 loc2 = "top";
1153 else if (an & E_GADGET_SITE_ANCHOR_BOTTOM)
1154 loc2 = "bottom";
1155
1156 snprintf(buf, sizeof(buf), "__bryce%s", b->name);
1157 snprintf(buf2, sizeof(buf2), "__brycebryce_%s_%s_%d", loc, loc2, b->zone);
1158 e_gadget_site_rename(buf, buf2);
1159 b->orient = orient;
1160 b->anchor = an;
1161 snprintf(buf2, sizeof(buf2), "bryce_%s_%s_%d", loc, loc2, b->zone);
1162 eina_stringshare_replace(&b->name, buf2);
1163 _bryce_orient(b);
1164 _bryce_autosize(b);
1165 }
1166
1167 E_API Evas_Object *
e_bryce_site_get(Evas_Object * bryce)1168 e_bryce_site_get(Evas_Object *bryce)
1169 {
1170 BRYCE_GET(bryce);
1171
1172 return b->site;
1173 }
1174
1175 E_API Eina_Bool
e_bryce_autosize_get(Evas_Object * bryce)1176 e_bryce_autosize_get(Evas_Object *bryce)
1177 {
1178 BRYCE_GET(bryce);
1179 return b->autosize;
1180 }
1181
1182 E_API void
e_bryce_autosize_set(Evas_Object * bryce,Eina_Bool set)1183 e_bryce_autosize_set(Evas_Object *bryce, Eina_Bool set)
1184 {
1185 BRYCE_GET(bryce);
1186 set = !!set;
1187
1188 if (b->autosize == set) return;
1189 b->autosize = set;
1190 if (set)
1191 {
1192 while (b->spacers)
1193 e_gadget_del(eina_list_data_get(b->spacers));
1194 }
1195 e_config_save_queue();
1196 _bryce_autosize(b);
1197 }
1198
1199 E_API Eina_Bool
e_bryce_autohide_get(Evas_Object * bryce)1200 e_bryce_autohide_get(Evas_Object *bryce)
1201 {
1202 BRYCE_GET(bryce);
1203 return b->autohide;
1204 }
1205
1206 E_API void
e_bryce_autohide_set(Evas_Object * bryce,Eina_Bool set)1207 e_bryce_autohide_set(Evas_Object *bryce, Eina_Bool set)
1208 {
1209 BRYCE_GET(bryce);
1210 set = !!set;
1211
1212 if (b->autohide == set) return;
1213 b->autohide = set;
1214
1215 if (set)
1216 _bryce_autohide_setup(b);
1217 else
1218 {
1219 E_FREE_FUNC(b->autohide_event, evas_object_del);
1220 evas_object_event_callback_del_full(bryce, EVAS_CALLBACK_MOVE, _bryce_autohide_moveresize, b);
1221 evas_object_event_callback_del_full(bryce, EVAS_CALLBACK_RESIZE, _bryce_autohide_moveresize, b);
1222 if (!b->hidden) return;
1223 e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(b->x, b->y), 0.5, _bryce_autohide_end, b);
1224 b->animating = 1;
1225 b->hidden = 0;
1226 }
1227 e_config_save_queue();
1228 }
1229
1230 E_API Eina_List *
e_bryce_list(Evas_Object * parent)1231 e_bryce_list(Evas_Object *parent)
1232 {
1233 Eina_List *l, *ret = NULL;
1234 Bryce *b;
1235
1236 if (!parent) parent = e_comp->elm;
1237 EINA_LIST_FOREACH(bryces->bryces, l, b)
1238 {
1239 if (!b->bryce) continue;
1240 if (parent == b->parent)
1241 ret = eina_list_append(ret, b->bryce);
1242 }
1243 return ret;
1244 }
1245
1246 E_API Eina_Bool
e_bryce_exists(Evas_Object * parent,Evas_Object * bryce,E_Gadget_Site_Orient orient,E_Gadget_Site_Anchor an)1247 e_bryce_exists(Evas_Object *parent, Evas_Object *bryce, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an)
1248 {
1249 Eina_List *l;
1250 Bryce *b;
1251 int zone = -1;
1252
1253 if (!parent) parent = e_comp->elm;
1254 if (parent == e_comp->elm)
1255 {
1256 E_Shelf *es;
1257 E_Zone *z;
1258
1259 z = e_zone_current_get();
1260 zone = z->num;
1261 /* FIXME: remove shelf block once shelves are dead */
1262 l = e_shelf_list_all();
1263 EINA_LIST_FREE(l, es)
1264 {
1265 if (es->zone != z) continue;
1266 switch (es->cfg->orient)
1267 {
1268 #define ORIENT_CHECK(ORIENT, ANCHOR1, ANCHOR2) \
1269 if ((orient == E_GADGET_SITE_ORIENT_##ORIENT) && \
1270 ((an == (E_GADGET_SITE_ANCHOR_##ANCHOR1)) || \
1271 ((an & E_GADGET_SITE_ANCHOR_##ANCHOR2) && (!es->cfg->fit_along)))) \
1272 return EINA_TRUE; \
1273 break
1274 default: break;
1275 case E_GADCON_ORIENT_LEFT:
1276 ORIENT_CHECK(VERTICAL, LEFT, LEFT);
1277 case E_GADCON_ORIENT_RIGHT:
1278 ORIENT_CHECK(VERTICAL, RIGHT, RIGHT);
1279 case E_GADCON_ORIENT_TOP:
1280 ORIENT_CHECK(HORIZONTAL, TOP, TOP);
1281 case E_GADCON_ORIENT_BOTTOM:
1282 ORIENT_CHECK(HORIZONTAL, BOTTOM, BOTTOM);
1283 case E_GADCON_ORIENT_CORNER_TL:
1284 ORIENT_CHECK(HORIZONTAL, TOP | E_GADGET_SITE_ANCHOR_LEFT, TOP);
1285 case E_GADCON_ORIENT_CORNER_TR:
1286 ORIENT_CHECK(HORIZONTAL, TOP | E_GADGET_SITE_ANCHOR_RIGHT, TOP);
1287 case E_GADCON_ORIENT_CORNER_BL:
1288 ORIENT_CHECK(HORIZONTAL, BOTTOM | E_GADGET_SITE_ANCHOR_LEFT, BOTTOM);
1289 case E_GADCON_ORIENT_CORNER_BR:
1290 ORIENT_CHECK(HORIZONTAL, BOTTOM | E_GADGET_SITE_ANCHOR_RIGHT, BOTTOM);
1291 case E_GADCON_ORIENT_CORNER_LT:
1292 ORIENT_CHECK(VERTICAL, LEFT | E_GADGET_SITE_ANCHOR_TOP, LEFT);
1293 case E_GADCON_ORIENT_CORNER_RT:
1294 ORIENT_CHECK(VERTICAL, RIGHT | E_GADGET_SITE_ANCHOR_TOP, RIGHT);
1295 case E_GADCON_ORIENT_CORNER_LB:
1296 ORIENT_CHECK(VERTICAL, LEFT | E_GADGET_SITE_ANCHOR_BOTTOM, LEFT);
1297 case E_GADCON_ORIENT_CORNER_RB:
1298 ORIENT_CHECK(VERTICAL, RIGHT | E_GADGET_SITE_ANCHOR_BOTTOM, RIGHT);
1299 #undef ORIENT_CHECK
1300 }
1301 }
1302 /* end FIXME */
1303 }
1304 EINA_LIST_FOREACH(bryces->bryces, l, b)
1305 {
1306 if (!b->bryce) continue;
1307 if (b->bryce == bryce) return EINA_FALSE;
1308 if (parent != b->parent) continue;
1309 if (b->orient != orient) continue;
1310 if ((zone >= 0) && ((int)b->zone != zone)) continue;
1311 if ((b->anchor & an) == an) return EINA_TRUE;
1312 if (b->autosize) continue;
1313 if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL)
1314 {
1315 if ((b->anchor & E_GADGET_SITE_ANCHOR_BOTTOM) && (an & E_GADGET_SITE_ANCHOR_BOTTOM))
1316 return EINA_TRUE;
1317 if ((b->anchor & E_GADGET_SITE_ANCHOR_TOP) && (an & E_GADGET_SITE_ANCHOR_TOP))
1318 return EINA_TRUE;
1319 }
1320 else
1321 {
1322 if ((b->anchor & E_GADGET_SITE_ANCHOR_LEFT) && (an & E_GADGET_SITE_ANCHOR_LEFT))
1323 return EINA_TRUE;
1324 if ((b->anchor & E_GADGET_SITE_ANCHOR_RIGHT) && (an & E_GADGET_SITE_ANCHOR_RIGHT))
1325 return EINA_TRUE;
1326 }
1327 }
1328 return EINA_FALSE;
1329 }
1330
1331 E_API void
e_bryce_style_set(Evas_Object * bryce,const char * style)1332 e_bryce_style_set(Evas_Object *bryce, const char *style)
1333 {
1334 BRYCE_GET(bryce);
1335
1336 eina_stringshare_replace(&b->style, style);
1337 _bryce_style_apply(b);
1338 e_config_save_queue();
1339 evas_object_smart_callback_call(b->site, "gadget_site_style", NULL);
1340 }
1341
1342 /* FIXME */
1343 EINTERN void
e_bryce_save(void)1344 e_bryce_save(void)
1345 {
1346 e_config_domain_save("e_bryces", edd_bryces, bryces);
1347 }
1348
1349 static void
bryce_spacer_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1350 bryce_spacer_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1351 {
1352 Bryce *b = data;
1353
1354 b->spacers = eina_list_remove(b->spacers, obj);
1355 }
1356
1357 static Evas_Object *
bryce_spacer_create(Evas_Object * parent,int * id,E_Gadget_Site_Orient orient)1358 bryce_spacer_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient)
1359 {
1360 Bryce *b;
1361 Eina_List *l;
1362 Evas_Object *r;
1363
1364 if (!orient) return NULL;
1365
1366 /* only allow on bryces */
1367 EINA_LIST_FOREACH(bryces->bryces, l, b)
1368 {
1369 if (b->editing || (parent == b->site)) break;
1370 }
1371 if (!b) return NULL;
1372 if (b->autosize) return NULL;
1373 r = evas_object_rectangle_add(e_comp->evas);
1374 evas_object_event_callback_add(r, EVAS_CALLBACK_DEL, bryce_spacer_del, b);
1375 b->spacers = eina_list_append(b->spacers, r);
1376 E_EXPAND(r);
1377 E_FILL(r);
1378 /* FIXME: this should be better for demo gadgets... */
1379 if (*id < 0)
1380 {
1381 evas_object_size_hint_aspect_set(r, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
1382 evas_object_color_set(r, 255, 0, 0, 255);
1383 }
1384 else
1385 evas_object_color_set(r, 0, 0, 0, 0);
1386 return r;
1387 }
1388
1389 EINTERN void
e_bryce_init(void)1390 e_bryce_init(void)
1391 {
1392 resize_act = e_action_add("bryce_resize");
1393 e_action_predef_name_set(_("Bryces"), _("Resize Gadget Bar"), "bryce_resize", NULL, "syntax: step, example: 4", 1);
1394 resize_act->func.go_wheel = _bryce_act_resize;
1395
1396 edd_bryce = E_CONFIG_DD_NEW("Bryce", Bryce);
1397 E_CONFIG_VAL(edd_bryce, Bryce, name, STR);
1398 E_CONFIG_VAL(edd_bryce, Bryce, style, STR);
1399 E_CONFIG_VAL(edd_bryce, Bryce, zone, UINT);
1400 E_CONFIG_VAL(edd_bryce, Bryce, size, INT);
1401 E_CONFIG_VAL(edd_bryce, Bryce, layer, UINT);
1402 E_CONFIG_VAL(edd_bryce, Bryce, autosize, UCHAR);
1403 E_CONFIG_VAL(edd_bryce, Bryce, autohide, UCHAR);
1404 E_CONFIG_VAL(edd_bryce, Bryce, orient, UINT);
1405 E_CONFIG_VAL(edd_bryce, Bryce, anchor, UINT);
1406 E_CONFIG_VAL(edd_bryce, Bryce, version, UINT);
1407
1408 edd_bryces = E_CONFIG_DD_NEW("Bryces", Bryces);
1409 E_CONFIG_LIST(edd_bryces, Bryces, bryces, edd_bryce);
1410 bryces = e_config_domain_load("e_bryces", edd_bryces);
1411
1412 if (bryces)
1413 {
1414 Eina_List *l;
1415 Bryce *b;
1416
1417 EINA_LIST_FOREACH(bryces->bryces, l, b)
1418 {
1419 if (b->version < 2)
1420 {
1421 /* I broke this the first time by forgetting the __bryce prefix :(
1422 */
1423 _bryce_rename(b, b->zone);
1424 if (b->version < 1)
1425 {
1426 char buf[1024];
1427
1428 snprintf(buf, sizeof(buf), "%s_%u", b->name, b->zone);
1429 eina_stringshare_replace(&b->name, buf);
1430 }
1431 }
1432 b->version = bryce_version;
1433 if (!e_comp_zone_number_get(b->zone)) continue;
1434 b->layer = E_CLAMP(b->layer, E_LAYER_DESKTOP_TOP, E_LAYER_CLIENT_ABOVE);
1435 _bryce_create(b, e_comp->elm);
1436 evas_object_show(b->bryce);
1437 }
1438 }
1439 else
1440 bryces = E_NEW(Bryces, 1);
1441
1442 evas_object_event_callback_add(e_comp->canvas->resize_object, EVAS_CALLBACK_RESIZE, _bryce_comp_resize, NULL);
1443 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGED, _bryce_zone_useful_geometry_changed, NULL);
1444 e_gadget_type_add("Spacer Bar", bryce_spacer_create, NULL);
1445 }
1446
1447 EINTERN void
e_bryce_shutdown(void)1448 e_bryce_shutdown(void)
1449 {
1450 Bryce *b;
1451
1452 E_CONFIG_DD_FREE(edd_bryce);
1453 E_CONFIG_DD_FREE(edd_bryces);
1454 EINA_LIST_FREE(bryces->bryces, b)
1455 {
1456 E_Zone *zone;
1457 void *obs;
1458
1459 EINA_LIST_FREE(b->zone_obstacles, obs)
1460 {
1461 E_OBJECT_DEL_SET(obs, NULL);
1462 e_object_del(obs);
1463 }
1464 evas_object_event_callback_del(b->bryce, EVAS_CALLBACK_DEL, _bryce_del);
1465 EINA_LIST_FREE(b->popups, obs)
1466 evas_object_event_callback_del(obs, EVAS_CALLBACK_HIDE, _bryce_popup_hide);
1467 evas_object_hide(b->bryce);
1468 evas_object_del(b->bryce);
1469 evas_object_del(b->autohide_event);
1470 eina_stringshare_del(b->name);
1471 eina_stringshare_del(b->style);
1472 ecore_job_del(b->calc_job);
1473 ecore_timer_del(b->save_timer);
1474 ecore_timer_del(b->autohide_timer);
1475 zone = e_comp_zone_number_get(b->zone);
1476 if (zone)
1477 {
1478 evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_DEL, _bryce_zone_del);
1479 evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_MOVE, _bryce_zone_moveresize);
1480 evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_RESIZE, _bryce_zone_moveresize);
1481 }
1482 free(b->e_obj_inherit);
1483 free(b);
1484 }
1485 E_FREE_LIST(handlers, ecore_event_handler_del);
1486 E_FREE(bryces);
1487 e_gadget_type_del("Spacer Bar");
1488 }
1489