diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/elementary/src/lib/elm_icon.c | 1006 |
1 files changed, 1006 insertions, 0 deletions
diff --git a/libraries/elementary/src/lib/elm_icon.c b/libraries/elementary/src/lib/elm_icon.c new file mode 100644 index 0000000..187df0e --- /dev/null +++ b/libraries/elementary/src/lib/elm_icon.c | |||
@@ -0,0 +1,1006 @@ | |||
1 | #include <Elementary.h> | ||
2 | #include "elm_priv.h" | ||
3 | #include "els_icon.h" | ||
4 | #include <assert.h> | ||
5 | |||
6 | #ifdef ELM_EFREET | ||
7 | #define NON_EXISTING (void *)-1 | ||
8 | static const char *icon_theme = NULL; | ||
9 | #endif | ||
10 | |||
11 | typedef struct _Widget_Data Widget_Data; | ||
12 | |||
13 | struct _Widget_Data | ||
14 | { | ||
15 | Evas_Object *img; | ||
16 | const char *stdicon; | ||
17 | Elm_Icon_Lookup_Order lookup_order; | ||
18 | |||
19 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
20 | struct | ||
21 | { | ||
22 | struct | ||
23 | { | ||
24 | const char *path; | ||
25 | const char *key; | ||
26 | } file, thumb; | ||
27 | |||
28 | Ecore_Event_Handler *eeh; | ||
29 | |||
30 | Ethumb_Thumb_Format format; | ||
31 | |||
32 | Ethumb_Client_Async *request; | ||
33 | |||
34 | Eina_Bool retry : 1; | ||
35 | } thumb; | ||
36 | #endif | ||
37 | |||
38 | #ifdef ELM_EFREET | ||
39 | struct | ||
40 | { | ||
41 | int requested_size; | ||
42 | Eina_Bool use : 1; | ||
43 | } freedesktop; | ||
44 | #endif | ||
45 | int in_eval; | ||
46 | Eina_Bool scale_up : 1; | ||
47 | Eina_Bool scale_down : 1; | ||
48 | Eina_Bool smooth : 1; | ||
49 | Eina_Bool fill_outside : 1; | ||
50 | Eina_Bool no_scale : 1; | ||
51 | |||
52 | /* for animation feature */ | ||
53 | Ecore_Timer *timer; | ||
54 | int frame_count; | ||
55 | int cur_frame; | ||
56 | double duration; | ||
57 | Eina_Bool anim : 1; | ||
58 | Eina_Bool play : 1; | ||
59 | }; | ||
60 | |||
61 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
62 | static Eina_List *_elm_icon_retry = NULL; | ||
63 | static int _icon_pending_request = 0; | ||
64 | #endif | ||
65 | |||
66 | static const char *widtype = NULL; | ||
67 | static void _del_hook(Evas_Object *obj); | ||
68 | static void _theme_hook(Evas_Object *obj); | ||
69 | static void _sizing_eval(Evas_Object *obj); | ||
70 | static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
71 | |||
72 | static Eina_Bool _icon_standard_set(Widget_Data *wd, Evas_Object *obj, const char *name); | ||
73 | static Eina_Bool _icon_freedesktop_set(Widget_Data *wd, Evas_Object *obj, const char *name, int size); | ||
74 | |||
75 | static const char SIG_CLICKED[] = "clicked"; | ||
76 | |||
77 | static const Evas_Smart_Cb_Description _signals[] = { | ||
78 | {SIG_CLICKED, ""}, | ||
79 | {NULL, NULL} | ||
80 | }; | ||
81 | |||
82 | |||
83 | //FIXME: move this code to ecore | ||
84 | #ifdef _WIN32 | ||
85 | static Eina_Bool | ||
86 | _path_is_absolute(const char *path) | ||
87 | { | ||
88 | //TODO: Check if this works with all absolute paths in windows | ||
89 | return ((isalpha (*path)) && (*(path + 1) == ':') && ((*(path + 2) == '\\') || (*(path + 2) == '/'))); | ||
90 | } | ||
91 | #else | ||
92 | static Eina_Bool | ||
93 | _path_is_absolute(const char *path) | ||
94 | { | ||
95 | return (*path == '/'); | ||
96 | } | ||
97 | #endif | ||
98 | |||
99 | static inline int | ||
100 | _icon_size_min_get(Evas_Object *icon) | ||
101 | { | ||
102 | int size; | ||
103 | _els_smart_icon_size_get(icon, &size, NULL); | ||
104 | return (size < 16) ? 16 : size; | ||
105 | } | ||
106 | |||
107 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
108 | static void | ||
109 | _icon_thumb_stop(Widget_Data *wd, void *ethumbd) | ||
110 | { | ||
111 | if (wd->thumb.request) | ||
112 | { | ||
113 | ethumb_client_thumb_async_cancel(ethumbd, wd->thumb.request); | ||
114 | wd->thumb.request = NULL; | ||
115 | _icon_pending_request--; | ||
116 | } | ||
117 | |||
118 | if (wd->thumb.retry) | ||
119 | { | ||
120 | _elm_icon_retry = eina_list_remove(_elm_icon_retry, wd); | ||
121 | wd->thumb.retry = EINA_FALSE; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static Eina_Bool | ||
126 | _icon_thumb_display(Widget_Data *wd) | ||
127 | { | ||
128 | Eina_Bool ret = EINA_FALSE; | ||
129 | |||
130 | if (wd->thumb.format == ETHUMB_THUMB_EET) | ||
131 | { | ||
132 | static const char *extensions[] = { | ||
133 | ".avi", ".mp4", ".ogv", ".mov", ".mpg", ".wmv", NULL | ||
134 | }; | ||
135 | const char **ext, *ptr; | ||
136 | int prefix_size; | ||
137 | Eina_Bool video = EINA_FALSE; | ||
138 | |||
139 | prefix_size = eina_stringshare_strlen(wd->thumb.file.path) - 4; | ||
140 | if (prefix_size >= 0) | ||
141 | { | ||
142 | ptr = wd->thumb.file.path + prefix_size; | ||
143 | for (ext = extensions; *ext; ++ext) | ||
144 | if (!strcasecmp(ptr, *ext)) | ||
145 | { | ||
146 | video = EINA_TRUE; | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | if (video) | ||
152 | ret = _els_smart_icon_file_edje_set(wd->img, wd->thumb.thumb.path, wd->thumb.thumb.key); | ||
153 | } | ||
154 | |||
155 | if (!ret) | ||
156 | ret = _els_smart_icon_file_key_set(wd->img, wd->thumb.thumb.path, wd->thumb.thumb.key); | ||
157 | |||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | static Eina_Bool | ||
162 | _icon_thumb_retry(Widget_Data *wd) | ||
163 | { | ||
164 | return _icon_thumb_display(wd); | ||
165 | } | ||
166 | |||
167 | static void | ||
168 | _icon_thumb_cleanup(Ethumb_Client *ethumbd) | ||
169 | { | ||
170 | Eina_List *l, *ll; | ||
171 | Widget_Data *wd; | ||
172 | |||
173 | EINA_LIST_FOREACH_SAFE(_elm_icon_retry, l, ll, wd) | ||
174 | if (_icon_thumb_retry(wd)) | ||
175 | { | ||
176 | _elm_icon_retry = eina_list_remove_list(_elm_icon_retry, l); | ||
177 | wd->thumb.retry = EINA_FALSE; | ||
178 | } | ||
179 | |||
180 | if (_icon_pending_request == 0) | ||
181 | EINA_LIST_FREE(_elm_icon_retry, wd) | ||
182 | _icon_thumb_stop(wd, ethumbd); | ||
183 | } | ||
184 | |||
185 | static void | ||
186 | _icon_thumb_finish(Widget_Data *wd, Ethumb_Client *ethumbd) | ||
187 | { | ||
188 | const char *file = NULL, *group = NULL; | ||
189 | Eina_Bool ret; | ||
190 | |||
191 | _els_smart_icon_file_get(wd->img, &file, &group); | ||
192 | file = eina_stringshare_ref(file); | ||
193 | group = eina_stringshare_ref(group); | ||
194 | |||
195 | ret = _icon_thumb_display(wd); | ||
196 | |||
197 | if (!ret && file) | ||
198 | { | ||
199 | const char *p; | ||
200 | |||
201 | if (!wd->thumb.retry) | ||
202 | { | ||
203 | _elm_icon_retry = eina_list_append(_elm_icon_retry, wd); | ||
204 | wd->thumb.retry = EINA_TRUE; | ||
205 | } | ||
206 | |||
207 | /* Back to previous image */ | ||
208 | if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj"))) | ||
209 | _els_smart_icon_file_edje_set(wd->img, file, group); | ||
210 | else | ||
211 | _els_smart_icon_file_key_set(wd->img, file, group); | ||
212 | } | ||
213 | |||
214 | _icon_thumb_cleanup(ethumbd); | ||
215 | |||
216 | eina_stringshare_del(file); | ||
217 | eina_stringshare_del(group); | ||
218 | } | ||
219 | |||
220 | static void | ||
221 | _icon_thumb_done(Ethumb_Client *client, const char *thumb_path, const char *thumb_key, void *data) | ||
222 | { | ||
223 | Widget_Data *wd = data; | ||
224 | |||
225 | assert(wd->thumb.request); | ||
226 | |||
227 | _icon_pending_request--; | ||
228 | wd->thumb.request = NULL; | ||
229 | |||
230 | eina_stringshare_replace(&wd->thumb.thumb.path, thumb_path); | ||
231 | eina_stringshare_replace(&wd->thumb.thumb.key, thumb_key); | ||
232 | wd->thumb.format = ethumb_client_format_get(client); | ||
233 | |||
234 | _icon_thumb_finish(wd, client); | ||
235 | } | ||
236 | |||
237 | static void | ||
238 | _icon_thumb_error(Ethumb_Client *client, void *data) | ||
239 | { | ||
240 | Widget_Data *wd = data; | ||
241 | |||
242 | assert(wd->thumb.request); | ||
243 | |||
244 | _icon_pending_request--; | ||
245 | wd->thumb.request = NULL; | ||
246 | |||
247 | ERR("could not generate thumbnail for %s (key: %s)", wd->thumb.file.path, wd->thumb.file.key); | ||
248 | _icon_thumb_cleanup(client); | ||
249 | } | ||
250 | |||
251 | static void | ||
252 | _icon_thumb_apply(Widget_Data *wd) | ||
253 | { | ||
254 | Ethumb_Client *ethumbd; | ||
255 | |||
256 | ethumbd = elm_thumb_ethumb_client_get(); | ||
257 | |||
258 | _icon_thumb_stop(wd, ethumbd); | ||
259 | |||
260 | if (!wd->thumb.file.path) return ; | ||
261 | |||
262 | _icon_pending_request++; | ||
263 | if (!ethumb_client_file_set(ethumbd, wd->thumb.file.path, wd->thumb.file.key)) return ; | ||
264 | ethumb_client_size_set(ethumbd, _icon_size_min_get(wd->img), _icon_size_min_get(wd->img)); | ||
265 | wd->thumb.request = ethumb_client_thumb_async_get(ethumbd, _icon_thumb_done, _icon_thumb_error, wd); | ||
266 | } | ||
267 | |||
268 | static Eina_Bool | ||
269 | _icon_thumb_apply_cb(void *data, int type __UNUSED__, void *ev __UNUSED__) | ||
270 | { | ||
271 | Widget_Data *wd = data; | ||
272 | |||
273 | _icon_thumb_apply(wd); | ||
274 | return ECORE_CALLBACK_RENEW; | ||
275 | } | ||
276 | #endif | ||
277 | |||
278 | static void | ||
279 | _del_hook(Evas_Object *obj) | ||
280 | { | ||
281 | Widget_Data *wd = elm_widget_data_get(obj); | ||
282 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
283 | Ethumb_Client *ethumbd; | ||
284 | #endif | ||
285 | |||
286 | if (!wd) return; | ||
287 | if (wd->stdicon) eina_stringshare_del(wd->stdicon); | ||
288 | |||
289 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
290 | ethumbd = elm_thumb_ethumb_client_get(); | ||
291 | _icon_thumb_stop(wd, ethumbd); | ||
292 | |||
293 | eina_stringshare_del(wd->thumb.file.path); | ||
294 | eina_stringshare_del(wd->thumb.file.key); | ||
295 | eina_stringshare_del(wd->thumb.thumb.path); | ||
296 | eina_stringshare_del(wd->thumb.thumb.key); | ||
297 | |||
298 | if (wd->thumb.eeh) | ||
299 | ecore_event_handler_del(wd->thumb.eeh); | ||
300 | #endif | ||
301 | |||
302 | if (wd->timer) | ||
303 | ecore_timer_del(wd->timer); | ||
304 | free(wd); | ||
305 | } | ||
306 | |||
307 | static void | ||
308 | _theme_hook(Evas_Object *obj) | ||
309 | { | ||
310 | Widget_Data *wd = elm_widget_data_get(obj); | ||
311 | if (!wd) return; | ||
312 | if (wd->stdicon) | ||
313 | _elm_theme_object_icon_set(obj, wd->img, wd->stdicon, elm_widget_style_get(obj)); | ||
314 | _sizing_eval(obj); | ||
315 | } | ||
316 | |||
317 | static void | ||
318 | _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) | ||
319 | { | ||
320 | Widget_Data *wd = elm_widget_data_get(obj); | ||
321 | if (!wd) return; | ||
322 | Evas_Object *icon_edje; | ||
323 | icon_edje = _els_smart_icon_edje_get(wd->img); | ||
324 | if (!icon_edje) return; | ||
325 | edje_object_signal_emit(icon_edje, emission, source); | ||
326 | } | ||
327 | |||
328 | static void | ||
329 | _signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) | ||
330 | { | ||
331 | Widget_Data *wd = elm_widget_data_get(obj); | ||
332 | if (!wd) return; | ||
333 | Evas_Object *icon_edje; | ||
334 | icon_edje = _els_smart_icon_edje_get(wd->img); | ||
335 | if (!icon_edje) return; | ||
336 | edje_object_signal_callback_add(icon_edje, emission, source, func_cb, data); | ||
337 | } | ||
338 | |||
339 | static void | ||
340 | _signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) | ||
341 | { | ||
342 | Widget_Data *wd = elm_widget_data_get(obj); | ||
343 | if (!wd) return; | ||
344 | Evas_Object *icon_edje; | ||
345 | icon_edje = _els_smart_icon_edje_get(wd->img); | ||
346 | if (!icon_edje) return; | ||
347 | edje_object_signal_callback_del_full(icon_edje, emission, source, func_cb, | ||
348 | data); | ||
349 | } | ||
350 | |||
351 | static void | ||
352 | _sizing_eval(Evas_Object *obj) | ||
353 | { | ||
354 | Widget_Data *wd = elm_widget_data_get(obj); | ||
355 | if (!wd) return; | ||
356 | Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; | ||
357 | int w, h; | ||
358 | |||
359 | wd->in_eval++; | ||
360 | _els_smart_icon_size_get(wd->img, &w, &h); | ||
361 | #ifdef ELM_EFREET | ||
362 | if (wd->freedesktop.use && wd->stdicon) | ||
363 | { | ||
364 | int size; | ||
365 | /* This icon has been set to a freedesktop icon, and the requested | ||
366 | appears to have a different size than the requested size, so try to | ||
367 | request another, higher resolution, icon. | ||
368 | FIXME: Find a better heuristic to determine if there should be | ||
369 | an icon with a different resolution. */ | ||
370 | size = ((w / 16) + 1) * 16; | ||
371 | _icon_freedesktop_set(wd, obj, wd->stdicon, size); | ||
372 | } | ||
373 | #endif | ||
374 | _els_smart_icon_scale_up_set(wd->img, wd->scale_up); | ||
375 | _els_smart_icon_scale_down_set(wd->img, wd->scale_down); | ||
376 | _els_smart_icon_smooth_scale_set(wd->img, wd->smooth); | ||
377 | _els_smart_icon_fill_inside_set(wd->img, !(wd->fill_outside)); | ||
378 | if (wd->no_scale) _els_smart_icon_scale_set(wd->img, 1.0); | ||
379 | else | ||
380 | { | ||
381 | _els_smart_icon_scale_set(wd->img, elm_widget_scale_get(obj) * | ||
382 | _elm_config->scale); | ||
383 | _els_smart_icon_size_get(wd->img, &w, &h); | ||
384 | } | ||
385 | if (!wd->scale_down) | ||
386 | { | ||
387 | minw = w; | ||
388 | minh = h; | ||
389 | } | ||
390 | if (!wd->scale_up) | ||
391 | { | ||
392 | maxw = w; | ||
393 | maxh = h; | ||
394 | } | ||
395 | evas_object_size_hint_min_set(obj, minw, minh); | ||
396 | evas_object_size_hint_max_set(obj, maxw, maxh); | ||
397 | wd->in_eval--; | ||
398 | } | ||
399 | |||
400 | static void | ||
401 | _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) | ||
402 | { | ||
403 | Evas_Event_Mouse_Up *ev = event_info; | ||
404 | if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; | ||
405 | evas_object_smart_callback_call(data, SIG_CLICKED, event_info); | ||
406 | } | ||
407 | |||
408 | static Eina_Bool | ||
409 | _elm_icon_animate_cb(void *data) | ||
410 | { | ||
411 | Widget_Data *wd = data; | ||
412 | Evas_Object *img_obj; | ||
413 | |||
414 | if (!wd) return ECORE_CALLBACK_CANCEL; | ||
415 | if (!wd->anim) return ECORE_CALLBACK_CANCEL; | ||
416 | |||
417 | img_obj = _els_smart_icon_object_get(wd->img); | ||
418 | wd->cur_frame++; | ||
419 | if (wd->cur_frame > wd->frame_count) | ||
420 | wd->cur_frame = wd->cur_frame % wd->frame_count; | ||
421 | evas_object_image_animated_frame_set(img_obj, wd->cur_frame); | ||
422 | |||
423 | wd->duration = evas_object_image_animated_frame_duration_get(img_obj, wd->cur_frame, 0); | ||
424 | |||
425 | if (wd->duration > 0) | ||
426 | ecore_timer_interval_set(wd->timer, wd->duration); | ||
427 | return ECORE_CALLBACK_RENEW; | ||
428 | } | ||
429 | |||
430 | static Eina_Bool | ||
431 | _icon_standard_set(Widget_Data *wd, Evas_Object *obj, const char *name) | ||
432 | { | ||
433 | if (_elm_theme_object_icon_set(obj, wd->img, name, "default")) | ||
434 | { | ||
435 | #ifdef ELM_EFREET | ||
436 | /* TODO: elm_unneed_efreet() */ | ||
437 | wd->freedesktop.use = EINA_FALSE; | ||
438 | #endif | ||
439 | return EINA_TRUE; | ||
440 | } | ||
441 | return EINA_FALSE; | ||
442 | } | ||
443 | |||
444 | static Eina_Bool | ||
445 | #ifdef ELM_EFREET | ||
446 | _icon_file_set(Widget_Data *wd, Evas_Object *obj, const char *path) | ||
447 | #else | ||
448 | _icon_file_set(Widget_Data *wd __UNUSED__, Evas_Object *obj, const char *path) | ||
449 | #endif | ||
450 | { | ||
451 | if (elm_icon_file_set(obj, path, NULL)) | ||
452 | { | ||
453 | #ifdef ELM_EFREET | ||
454 | /* TODO: elm_unneed_efreet() */ | ||
455 | wd->freedesktop.use = EINA_FALSE; | ||
456 | #endif | ||
457 | return EINA_TRUE; | ||
458 | } | ||
459 | return EINA_FALSE; | ||
460 | } | ||
461 | |||
462 | static Eina_Bool | ||
463 | #ifdef ELM_EFREET | ||
464 | _icon_freedesktop_set(Widget_Data *wd, Evas_Object *obj, const char *name, int size) | ||
465 | #else | ||
466 | _icon_freedesktop_set(Widget_Data *wd __UNUSED__, Evas_Object *obj __UNUSED__, const char *name __UNUSED__, int size __UNUSED__) | ||
467 | #endif | ||
468 | { | ||
469 | #ifdef ELM_EFREET | ||
470 | const char *path; | ||
471 | |||
472 | elm_need_efreet(); | ||
473 | if (icon_theme == NON_EXISTING) return EINA_FALSE; | ||
474 | if (!icon_theme) | ||
475 | { | ||
476 | Efreet_Icon_Theme *theme; | ||
477 | /* TODO: Listen for EFREET_EVENT_ICON_CACHE_UPDATE */ | ||
478 | theme = efreet_icon_theme_find(getenv("E_ICON_THEME")); | ||
479 | if (!theme) | ||
480 | { | ||
481 | const char **itr; | ||
482 | static const char *themes[] = { | ||
483 | "gnome", "Human", "oxygen", "hicolor", NULL | ||
484 | }; | ||
485 | for (itr = themes; *itr; itr++) | ||
486 | { | ||
487 | theme = efreet_icon_theme_find(*itr); | ||
488 | if (theme) break; | ||
489 | } | ||
490 | } | ||
491 | |||
492 | if (!theme) | ||
493 | { | ||
494 | icon_theme = NON_EXISTING; | ||
495 | return EINA_FALSE; | ||
496 | } | ||
497 | else | ||
498 | icon_theme = eina_stringshare_add(theme->name.internal); | ||
499 | } | ||
500 | path = efreet_icon_path_find(icon_theme, name, size); | ||
501 | wd->freedesktop.use = !!path; | ||
502 | if (wd->freedesktop.use) | ||
503 | { | ||
504 | wd->freedesktop.requested_size = size; | ||
505 | elm_icon_file_set(obj, path, NULL); | ||
506 | return EINA_TRUE; | ||
507 | } | ||
508 | #endif | ||
509 | return EINA_FALSE; | ||
510 | } | ||
511 | |||
512 | static Eina_Bool | ||
513 | _elm_icon_standard_set(Widget_Data *wd, Evas_Object *obj, const char *name, Eina_Bool *fdo) | ||
514 | { | ||
515 | char *tmp; | ||
516 | Eina_Bool ret; | ||
517 | |||
518 | /* try locating the icon using the specified lookup order */ | ||
519 | switch (wd->lookup_order) | ||
520 | { | ||
521 | case ELM_ICON_LOOKUP_FDO: | ||
522 | ret = _icon_freedesktop_set(wd, obj, name, _icon_size_min_get(wd->img)); | ||
523 | if (ret && fdo) *fdo = EINA_TRUE; | ||
524 | break; | ||
525 | case ELM_ICON_LOOKUP_THEME: | ||
526 | ret = _icon_standard_set(wd, obj, name); | ||
527 | break; | ||
528 | case ELM_ICON_LOOKUP_THEME_FDO: | ||
529 | ret = _icon_standard_set(wd, obj, name); | ||
530 | if (!ret) | ||
531 | { | ||
532 | ret = _icon_freedesktop_set(wd, obj, name, _icon_size_min_get(wd->img)); | ||
533 | if (ret && fdo) *fdo = EINA_TRUE; | ||
534 | } | ||
535 | break; | ||
536 | case ELM_ICON_LOOKUP_FDO_THEME: | ||
537 | default: | ||
538 | ret = _icon_freedesktop_set(wd, obj, name, _icon_size_min_get(wd->img)); | ||
539 | if (!ret) | ||
540 | ret = _icon_standard_set(wd, obj, name); | ||
541 | else if (fdo) | ||
542 | *fdo = EINA_TRUE; | ||
543 | break; | ||
544 | } | ||
545 | |||
546 | if (ret) | ||
547 | { | ||
548 | eina_stringshare_replace(&wd->stdicon, name); | ||
549 | if (!wd->in_eval) _sizing_eval(obj); | ||
550 | return EINA_TRUE; | ||
551 | } | ||
552 | |||
553 | if (_path_is_absolute(name)) | ||
554 | return _icon_file_set(wd, obj, name); | ||
555 | |||
556 | /* if that fails, see if icon name is in the format size/name. if so, | ||
557 | try locating a fallback without the size specification */ | ||
558 | if (!(tmp = strchr(name, '/'))) return EINA_FALSE; | ||
559 | ++tmp; | ||
560 | if (*tmp) return elm_icon_standard_set(obj, tmp); | ||
561 | /* give up */ | ||
562 | return EINA_FALSE; | ||
563 | } | ||
564 | |||
565 | static void | ||
566 | _elm_icon_standard_resize(void *data, | ||
567 | Evas *e __UNUSED__, | ||
568 | Evas_Object *obj, | ||
569 | void *event_info __UNUSED__) | ||
570 | { | ||
571 | Widget_Data *wd = data; | ||
572 | const char *refup = eina_stringshare_ref(wd->stdicon); | ||
573 | Eina_Bool fdo = EINA_FALSE; | ||
574 | |||
575 | if (!_elm_icon_standard_set(wd, obj, wd->stdicon, &fdo) || (!fdo)) | ||
576 | evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, | ||
577 | _elm_icon_standard_resize, wd); | ||
578 | eina_stringshare_del(refup); | ||
579 | } | ||
580 | |||
581 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
582 | static void | ||
583 | _elm_icon_thumb_resize(void *data, | ||
584 | Evas *e __UNUSED__, | ||
585 | Evas_Object *obj, | ||
586 | void *event_info __UNUSED__) | ||
587 | { | ||
588 | Widget_Data *wd = data; | ||
589 | |||
590 | if (wd->thumb.file.path) | ||
591 | elm_icon_thumb_set(obj, wd->thumb.file.path, wd->thumb.file.key); | ||
592 | } | ||
593 | #endif | ||
594 | |||
595 | EAPI Evas_Object * | ||
596 | elm_icon_add(Evas_Object *parent) | ||
597 | { | ||
598 | Evas_Object *obj; | ||
599 | Evas *e; | ||
600 | Widget_Data *wd; | ||
601 | |||
602 | ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); | ||
603 | |||
604 | ELM_SET_WIDTYPE(widtype, "icon"); | ||
605 | elm_widget_type_set(obj, "icon"); | ||
606 | elm_widget_can_focus_set(obj, EINA_FALSE); | ||
607 | elm_widget_sub_object_add(parent, obj); | ||
608 | elm_widget_data_set(obj, wd); | ||
609 | elm_widget_del_hook_set(obj, _del_hook); | ||
610 | elm_widget_theme_hook_set(obj, _theme_hook); | ||
611 | elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); | ||
612 | elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); | ||
613 | elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); | ||
614 | |||
615 | wd->lookup_order = ELM_ICON_LOOKUP_THEME_FDO; | ||
616 | wd->img = _els_smart_icon_add(e); | ||
617 | evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP, | ||
618 | _mouse_up, obj); | ||
619 | evas_object_repeat_events_set(wd->img, EINA_TRUE); | ||
620 | elm_widget_resize_object_set(obj, wd->img); | ||
621 | |||
622 | evas_object_smart_callbacks_descriptions_set(obj, _signals); | ||
623 | |||
624 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
625 | wd->thumb.request = NULL; | ||
626 | #endif | ||
627 | |||
628 | wd->smooth = EINA_TRUE; | ||
629 | wd->scale_up = EINA_TRUE; | ||
630 | wd->scale_down = EINA_TRUE; | ||
631 | |||
632 | _sizing_eval(obj); | ||
633 | return obj; | ||
634 | } | ||
635 | |||
636 | EAPI Eina_Bool | ||
637 | elm_icon_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key) | ||
638 | { | ||
639 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
640 | Widget_Data *wd = elm_widget_data_get(obj); | ||
641 | Eina_Bool ret; | ||
642 | |||
643 | if (!wd) return EINA_FALSE; | ||
644 | EINA_SAFETY_ON_NULL_RETURN_VAL(img, EINA_FALSE); | ||
645 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, EINA_FALSE); | ||
646 | eina_stringshare_del(wd->stdicon); | ||
647 | wd->stdicon = NULL; | ||
648 | ret = _els_smart_icon_memfile_set(wd->img, img, size, format, key); | ||
649 | if (!wd->in_eval) _sizing_eval(obj); | ||
650 | return ret; | ||
651 | } | ||
652 | |||
653 | EAPI Eina_Bool | ||
654 | elm_icon_file_set(Evas_Object *obj, const char *file, const char *group) | ||
655 | { | ||
656 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
657 | Widget_Data *wd = elm_widget_data_get(obj); | ||
658 | Eina_Bool ret; | ||
659 | |||
660 | if (!wd) return EINA_FALSE; | ||
661 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); | ||
662 | |||
663 | #ifdef ELM_EFREET | ||
664 | if (!wd->freedesktop.use) | ||
665 | { | ||
666 | if (wd->stdicon) eina_stringshare_del(wd->stdicon); | ||
667 | wd->stdicon = NULL; | ||
668 | } | ||
669 | #endif | ||
670 | if (eina_str_has_extension(file, ".edj")) | ||
671 | ret = _els_smart_icon_file_edje_set(wd->img, file, group); | ||
672 | else | ||
673 | ret = _els_smart_icon_file_key_set(wd->img, file, group); | ||
674 | if (!wd->in_eval) _sizing_eval(obj); | ||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | EAPI void | ||
679 | elm_icon_file_get(const Evas_Object *obj, const char **file, const char **group) | ||
680 | { | ||
681 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
682 | Widget_Data *wd = elm_widget_data_get(obj); | ||
683 | if (!wd) return; | ||
684 | _els_smart_icon_file_get(wd->img, file, group); | ||
685 | } | ||
686 | |||
687 | EAPI void | ||
688 | elm_icon_thumb_set(Evas_Object *obj, const char *file, const char *group) | ||
689 | { | ||
690 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
691 | Widget_Data *wd = elm_widget_data_get(obj); | ||
692 | if (!wd) return; | ||
693 | |||
694 | #ifdef HAVE_ELEMENTARY_ETHUMB | ||
695 | evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, | ||
696 | _elm_icon_standard_resize, wd); | ||
697 | evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, | ||
698 | _elm_icon_thumb_resize, wd); | ||
699 | |||
700 | evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, | ||
701 | _elm_icon_thumb_resize, wd); | ||
702 | |||
703 | eina_stringshare_replace(&wd->thumb.file.path, file); | ||
704 | eina_stringshare_replace(&wd->thumb.file.key, group); | ||
705 | |||
706 | if (elm_thumb_ethumb_client_connected_get()) | ||
707 | { | ||
708 | _icon_thumb_apply(wd); | ||
709 | return ; | ||
710 | } | ||
711 | |||
712 | if (!wd->thumb.eeh) | ||
713 | { | ||
714 | wd->thumb.eeh = ecore_event_handler_add(ELM_ECORE_EVENT_ETHUMB_CONNECT, _icon_thumb_apply_cb, wd); | ||
715 | } | ||
716 | #else | ||
717 | (void) obj; | ||
718 | (void) file; | ||
719 | (void) group; | ||
720 | #endif | ||
721 | } | ||
722 | |||
723 | |||
724 | EAPI Eina_Bool | ||
725 | elm_icon_animated_available_get(const Evas_Object *obj) | ||
726 | { | ||
727 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
728 | Evas_Object *img_obj ; | ||
729 | Widget_Data *wd = elm_widget_data_get(obj); | ||
730 | if (!wd) return EINA_FALSE; | ||
731 | |||
732 | img_obj = _els_smart_icon_object_get(wd->img); | ||
733 | |||
734 | return evas_object_image_animated_get(img_obj); | ||
735 | } | ||
736 | |||
737 | EAPI void | ||
738 | elm_icon_animated_set(Evas_Object *obj, Eina_Bool anim) | ||
739 | { | ||
740 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
741 | Evas_Object *img_obj ; | ||
742 | Widget_Data *wd = elm_widget_data_get(obj); | ||
743 | if (!wd) return; | ||
744 | if (wd->anim == anim) return; | ||
745 | |||
746 | img_obj = _els_smart_icon_object_get(wd->img); | ||
747 | if (!evas_object_image_animated_get(img_obj)) return; | ||
748 | if (anim) | ||
749 | { | ||
750 | wd->frame_count = evas_object_image_animated_frame_count_get(img_obj); | ||
751 | wd->cur_frame = 1; | ||
752 | wd->duration = evas_object_image_animated_frame_duration_get(img_obj, wd->cur_frame, 0); | ||
753 | evas_object_image_animated_frame_set(img_obj, wd->cur_frame); | ||
754 | } | ||
755 | else | ||
756 | { | ||
757 | wd->frame_count = -1; | ||
758 | wd->cur_frame = -1; | ||
759 | wd->duration = -1; | ||
760 | } | ||
761 | wd->anim = anim; | ||
762 | return; | ||
763 | } | ||
764 | |||
765 | EAPI Eina_Bool | ||
766 | elm_icon_animated_get(const Evas_Object *obj) | ||
767 | { | ||
768 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
769 | Widget_Data *wd = elm_widget_data_get(obj); | ||
770 | if (!wd) return EINA_FALSE; | ||
771 | return wd->anim; | ||
772 | } | ||
773 | |||
774 | EAPI void | ||
775 | elm_icon_animated_play_set(Evas_Object *obj, Eina_Bool play) | ||
776 | { | ||
777 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
778 | Widget_Data *wd = elm_widget_data_get(obj); | ||
779 | if (!wd) return; | ||
780 | if (!wd->anim) return; | ||
781 | if (wd->play == play) return; | ||
782 | |||
783 | if (play) | ||
784 | { | ||
785 | wd->timer = ecore_timer_add(wd->duration, _elm_icon_animate_cb, wd); | ||
786 | } | ||
787 | else | ||
788 | { | ||
789 | if (wd->timer) | ||
790 | { | ||
791 | ecore_timer_del(wd->timer); | ||
792 | wd->timer = NULL; | ||
793 | } | ||
794 | } | ||
795 | wd->play = play; | ||
796 | |||
797 | } | ||
798 | |||
799 | EAPI Eina_Bool | ||
800 | elm_icon_animated_play_get(const Evas_Object *obj) | ||
801 | { | ||
802 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
803 | Widget_Data *wd = elm_widget_data_get(obj); | ||
804 | if (!wd) return EINA_FALSE; | ||
805 | return wd->play; | ||
806 | } | ||
807 | |||
808 | EAPI Eina_Bool | ||
809 | elm_icon_standard_set(Evas_Object *obj, const char *name) | ||
810 | { | ||
811 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
812 | Widget_Data *wd = elm_widget_data_get(obj); | ||
813 | Eina_Bool fdo = EINA_FALSE; | ||
814 | Eina_Bool ret; | ||
815 | |||
816 | if ((!wd) || (!name)) return EINA_FALSE; | ||
817 | |||
818 | evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, | ||
819 | _elm_icon_standard_resize, wd); | ||
820 | |||
821 | ret = _elm_icon_standard_set(wd, obj, name, &fdo); | ||
822 | |||
823 | if (fdo) | ||
824 | evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, | ||
825 | _elm_icon_standard_resize, wd); | ||
826 | |||
827 | return ret; | ||
828 | } | ||
829 | |||
830 | EAPI const char * | ||
831 | elm_icon_standard_get(const Evas_Object *obj) | ||
832 | { | ||
833 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
834 | Widget_Data *wd = elm_widget_data_get(obj); | ||
835 | if (!wd) return NULL; | ||
836 | return wd->stdicon; | ||
837 | } | ||
838 | |||
839 | EAPI void | ||
840 | elm_icon_order_lookup_set(Evas_Object *obj, Elm_Icon_Lookup_Order order) | ||
841 | { | ||
842 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
843 | Widget_Data *wd = elm_widget_data_get(obj); | ||
844 | if (wd) wd->lookup_order = order; | ||
845 | } | ||
846 | |||
847 | EAPI Elm_Icon_Lookup_Order | ||
848 | elm_icon_order_lookup_get(const Evas_Object *obj) | ||
849 | { | ||
850 | ELM_CHECK_WIDTYPE(obj, widtype) ELM_ICON_LOOKUP_THEME_FDO; | ||
851 | Widget_Data *wd = elm_widget_data_get(obj); | ||
852 | if (!wd) return ELM_ICON_LOOKUP_THEME_FDO; | ||
853 | return wd->lookup_order; | ||
854 | } | ||
855 | |||
856 | EAPI void | ||
857 | elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth) | ||
858 | { | ||
859 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
860 | Widget_Data *wd = elm_widget_data_get(obj); | ||
861 | |||
862 | if (!wd) return; | ||
863 | wd->smooth = smooth; | ||
864 | if (!wd->in_eval) _sizing_eval(obj); | ||
865 | } | ||
866 | |||
867 | EAPI Eina_Bool | ||
868 | elm_icon_smooth_get(const Evas_Object *obj) | ||
869 | { | ||
870 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
871 | Widget_Data *wd = elm_widget_data_get(obj); | ||
872 | |||
873 | if (!wd) return EINA_FALSE; | ||
874 | return wd->smooth; | ||
875 | } | ||
876 | |||
877 | EAPI void | ||
878 | elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale) | ||
879 | { | ||
880 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
881 | Widget_Data *wd = elm_widget_data_get(obj); | ||
882 | |||
883 | if (!wd) return; | ||
884 | wd->no_scale = no_scale; | ||
885 | if (!wd->in_eval) _sizing_eval(obj); | ||
886 | } | ||
887 | |||
888 | EAPI Eina_Bool | ||
889 | elm_icon_no_scale_get(const Evas_Object *obj) | ||
890 | { | ||
891 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
892 | Widget_Data *wd = elm_widget_data_get(obj); | ||
893 | if (!wd) return EINA_FALSE; | ||
894 | return wd->no_scale; | ||
895 | } | ||
896 | |||
897 | EAPI void | ||
898 | elm_icon_resizable_set(Evas_Object *obj, Eina_Bool size_up, Eina_Bool size_down) | ||
899 | { | ||
900 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
901 | Widget_Data *wd = elm_widget_data_get(obj); | ||
902 | |||
903 | if (!wd) return; | ||
904 | wd->scale_up = size_up; | ||
905 | wd->scale_down = size_down; | ||
906 | if (!wd->in_eval) _sizing_eval(obj); | ||
907 | } | ||
908 | |||
909 | EAPI void | ||
910 | elm_icon_resizable_get(const Evas_Object *obj, Eina_Bool *size_up, Eina_Bool *size_down) | ||
911 | { | ||
912 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
913 | Widget_Data *wd = elm_widget_data_get(obj); | ||
914 | if (!wd) return; | ||
915 | if (size_up) *size_up = wd->scale_up; | ||
916 | if (size_down) *size_down = wd->scale_down; | ||
917 | } | ||
918 | |||
919 | EAPI void | ||
920 | elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside) | ||
921 | { | ||
922 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
923 | Widget_Data *wd = elm_widget_data_get(obj); | ||
924 | |||
925 | if (!wd) return; | ||
926 | wd->fill_outside = fill_outside; | ||
927 | if (!wd->in_eval) _sizing_eval(obj); | ||
928 | } | ||
929 | |||
930 | EAPI void | ||
931 | elm_icon_size_get(const Evas_Object *obj, int *w, int *h) | ||
932 | { | ||
933 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
934 | Widget_Data *wd = elm_widget_data_get(obj); | ||
935 | |||
936 | if (!wd) return; | ||
937 | _els_smart_icon_size_get(wd->img, w, h); | ||
938 | } | ||
939 | |||
940 | EAPI Eina_Bool | ||
941 | elm_icon_fill_outside_get(const Evas_Object *obj) | ||
942 | { | ||
943 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
944 | Widget_Data *wd = elm_widget_data_get(obj); | ||
945 | |||
946 | if (!wd) return EINA_FALSE; | ||
947 | return wd->fill_outside; | ||
948 | } | ||
949 | |||
950 | EAPI void | ||
951 | elm_icon_prescale_set(Evas_Object *obj, int size) | ||
952 | { | ||
953 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
954 | Widget_Data *wd = elm_widget_data_get(obj); | ||
955 | |||
956 | if (!wd) return; | ||
957 | _els_smart_icon_scale_size_set(wd->img, size); | ||
958 | } | ||
959 | |||
960 | EAPI int | ||
961 | elm_icon_prescale_get(const Evas_Object *obj) | ||
962 | { | ||
963 | ELM_CHECK_WIDTYPE(obj, widtype) 0; | ||
964 | Widget_Data *wd = elm_widget_data_get(obj); | ||
965 | |||
966 | if (!wd) return 0; | ||
967 | return _els_smart_icon_scale_size_get(wd->img); | ||
968 | } | ||
969 | |||
970 | EAPI Evas_Object * | ||
971 | elm_icon_object_get(Evas_Object *obj) | ||
972 | { | ||
973 | ELM_CHECK_WIDTYPE(obj, widtype) 0; | ||
974 | Widget_Data *wd = elm_widget_data_get(obj); | ||
975 | |||
976 | if (!wd) return NULL; | ||
977 | return _els_smart_icon_object_get(wd->img); | ||
978 | } | ||
979 | |||
980 | EAPI void | ||
981 | elm_icon_preload_disabled_set(Evas_Object *obj, Eina_Bool disabled) | ||
982 | { | ||
983 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
984 | Widget_Data *wd = elm_widget_data_get(obj); | ||
985 | |||
986 | if (!wd) return; | ||
987 | _els_smart_icon_preload_set(wd->img, !!disabled); | ||
988 | } | ||
989 | |||
990 | EAPI void | ||
991 | elm_icon_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed) | ||
992 | { | ||
993 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
994 | Widget_Data *wd = elm_widget_data_get(obj); | ||
995 | if (!wd) return; | ||
996 | _els_smart_icon_aspect_fixed_set(wd->img, fixed); | ||
997 | } | ||
998 | |||
999 | EAPI Eina_Bool | ||
1000 | elm_icon_aspect_fixed_get(const Evas_Object *obj) | ||
1001 | { | ||
1002 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
1003 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1004 | if (!wd) return EINA_FALSE; | ||
1005 | return _els_smart_icon_aspect_fixed_get(wd->img); | ||
1006 | } | ||