1 #include <Elementary.h>
6 # define FMT_SIZE_T "%Iu"
8 # define FMT_SIZE_T "%zu"
11 typedef struct _Smart_Data Smart_Data;
15 Evas_Coord x, y, w, h;
20 Eina_Bool fill_inside : 1;
21 Eina_Bool scale_up : 1;
22 Eina_Bool scale_down : 1;
23 Eina_Bool preloading : 1;
27 Eina_Bool aspect_ratio_retained: 1;
28 Elm_Image_Orient orient;
31 /* local subsystem functions */
32 static void _smart_reconfigure(Smart_Data *sd);
33 static void _smart_init(void);
34 static void _smart_add(Evas_Object *obj);
35 static void _smart_del(Evas_Object *obj);
36 static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
37 static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
38 static void _smart_show(Evas_Object *obj);
39 static void _smart_hide(Evas_Object *obj);
40 static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
41 static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
42 static void _smart_clip_unset(Evas_Object *obj);
44 static void _els_smart_icon_flip_horizontal(Smart_Data *sd);
45 static void _els_smart_icon_flip_vertical(Smart_Data *sd);
46 static void _els_smart_icon_rotate_180(Smart_Data *sd);
47 static Eina_Bool _els_smart_icon_dropcb(void *,Evas_Object *, Elm_Selection_Data *);
49 /* local subsystem globals */
50 static Evas_Smart *_e_smart = NULL;
52 /* externally accessible functions */
54 _els_smart_icon_add(Evas *evas)
57 return evas_object_smart_add(evas, _e_smart);
61 _preloaded(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event __UNUSED__)
63 Smart_Data *sd = data;
65 sd->preloading = EINA_FALSE;
69 evas_object_show(sd->obj);
71 if (sd->prev) evas_object_del(sd->prev);
76 _els_smart_icon_file_helper(Evas_Object *obj)
81 sd = evas_object_smart_data_get(obj);
83 /* NOTE: Do not merge upstream for the if (sd->edje) { } statements
84 But wonder whether the edje resource icons have no problem. */
85 if (!sd->edje) goto out;
87 if (sd->prev) evas_object_del(sd->prev);
88 pclip = evas_object_clip_get(sd->obj);
89 if (sd->obj) sd->prev = sd->obj;
90 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
91 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
93 evas_object_smart_member_add(sd->obj, obj);
94 if (sd->prev) evas_object_smart_member_add(sd->prev, obj);
95 evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
96 evas_object_clip_set(sd->obj, pclip);
98 sd->edje = EINA_FALSE;
102 evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
106 _els_smart_icon_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key)
110 sd = evas_object_smart_data_get(obj);
111 if (!sd) return EINA_FALSE;
112 _els_smart_icon_file_helper(obj);
114 evas_object_image_memfile_set(sd->obj, (void*)img, size, (char*)format, (char*)key);
115 sd->preloading = EINA_TRUE;
116 sd->show = EINA_TRUE;
117 evas_object_hide(sd->obj);
118 evas_object_image_preload(sd->obj, EINA_FALSE);
119 if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
121 ERR("Things are going bad for some random " FMT_SIZE_T " byte chunk of memory (%p)", size, sd->obj);
124 _smart_reconfigure(sd);
129 _els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
133 sd = evas_object_smart_data_get(obj);
134 if (!sd) return EINA_FALSE;
135 _els_smart_icon_file_helper(obj);
137 evas_object_image_file_set(sd->obj, file, key);
138 // NOTE: Do not merge upstream for sd->preloading.
139 sd->preloading = EINA_FALSE; // by default preload off by seok.j.jeong
140 sd->show = EINA_TRUE;
141 // NOTE: Do not merge upstream for sd->preloading.
143 evas_object_image_preload(sd->obj, EINA_FALSE);
144 // NOTE: Do not merge upstream for sd->preloading.
145 if (sd->preloading) // sd->preloading can be changed by above function. so add "if (sd->preloading)" as below
146 evas_object_hide(sd->obj);
147 if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
149 ERR("Things are going bad for '%s' (%p)", file, sd->obj);
152 _smart_reconfigure(sd);
157 _els_smart_icon_preload_set(Evas_Object *obj, Eina_Bool disable)
161 sd = evas_object_smart_data_get(obj);
162 if ((!sd) || sd->edje) return;
163 evas_object_image_preload(sd->obj, disable);
164 sd->preloading = !disable;
168 _els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
173 sd = evas_object_smart_data_get(obj);
174 if (!sd) return EINA_FALSE;
175 /* smart code here */
176 if (sd->prev) evas_object_del(sd->prev);
181 pclip = evas_object_clip_get(sd->obj);
182 if (sd->obj) evas_object_del(sd->obj);
183 sd->obj = edje_object_add(evas_object_evas_get(obj));
184 evas_object_smart_member_add(sd->obj, obj);
185 if (sd->show) evas_object_show(sd->obj);
186 evas_object_clip_set(sd->obj, pclip);
188 sd->edje = EINA_TRUE;
189 if (!edje_object_file_set(sd->obj, file, part))
191 _smart_reconfigure(sd);
196 _els_smart_icon_file_get(const Evas_Object *obj, const char **file, const char **key)
198 Smart_Data *sd = evas_object_smart_data_get(obj);
201 edje_object_file_get(sd->obj, file, key);
203 evas_object_image_file_get(sd->obj, file, key);
207 _els_smart_icon_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
209 Smart_Data *sd = evas_object_smart_data_get(obj);
213 evas_object_image_smooth_scale_set(sd->obj, smooth);
217 _els_smart_icon_smooth_scale_get(const Evas_Object *obj)
219 Smart_Data *sd = evas_object_smart_data_get(obj);
220 if (!sd) return EINA_FALSE;
223 return evas_object_image_smooth_scale_get(sd->obj);
227 _els_smart_icon_object_get(const Evas_Object *obj)
229 Smart_Data *sd = evas_object_smart_data_get(obj);
230 if (!sd) return NULL;
235 _els_smart_icon_size_get(const Evas_Object *obj, int *w, int *h)
242 sd = evas_object_smart_data_get(obj);
244 type = evas_object_type_get(sd->obj);
246 if (!strcmp(type, "edje"))
247 edje_object_size_min_get(sd->obj, &tw, &th);
249 evas_object_image_size_get(sd->obj, &tw, &th);
250 evas_object_geometry_get(sd->obj, NULL, NULL, &cw, &ch);
251 tw = tw > cw ? tw : cw;
252 th = th > ch ? th : ch;
253 tw = ((double)tw) * sd->scale;
254 th = ((double)th) * sd->scale;
260 _els_smart_icon_fill_inside_set(Evas_Object *obj, Eina_Bool fill_inside)
264 sd = evas_object_smart_data_get(obj);
266 if (((sd->fill_inside) && (fill_inside)) ||
267 ((!sd->fill_inside) && (!fill_inside))) return;
268 sd->fill_inside = fill_inside;
269 _smart_reconfigure(sd);
273 _els_smart_icon_fill_inside_get(const Evas_Object *obj)
275 Smart_Data *sd = evas_object_smart_data_get(obj);
276 if (!sd) return EINA_FALSE;
277 return sd->fill_inside;
281 _els_smart_icon_scale_up_set(Evas_Object *obj, Eina_Bool scale_up)
285 sd = evas_object_smart_data_get(obj);
287 if (((sd->scale_up) && (scale_up)) ||
288 ((!sd->scale_up) && (!scale_up))) return;
289 sd->scale_up = scale_up;
290 _smart_reconfigure(sd);
294 _els_smart_icon_scale_up_get(const Evas_Object *obj)
296 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
297 if (!sd) return EINA_FALSE;
302 _els_smart_icon_scale_down_set(Evas_Object *obj, Eina_Bool scale_down)
306 sd = evas_object_smart_data_get(obj);
308 if (((sd->scale_down) && (scale_down)) ||
309 ((!sd->scale_down) && (!scale_down))) return;
310 sd->scale_down = scale_down;
311 _smart_reconfigure(sd);
315 _els_smart_icon_scale_down_get(const Evas_Object *obj)
317 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
318 if (!sd) return EINA_FALSE;
323 _els_smart_icon_scale_size_set(Evas_Object *obj, int size)
327 sd = evas_object_smart_data_get(obj);
330 if (!sd->obj) return;
333 evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
337 _els_smart_icon_scale_size_get(const Evas_Object *obj)
339 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
345 _els_smart_icon_scale_set(Evas_Object *obj, double scale)
347 Smart_Data *sd = evas_object_smart_data_get(obj);
350 _smart_reconfigure(sd);
354 _els_smart_icon_scale_get(const Evas_Object *obj)
356 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
362 _els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
366 unsigned int *data, *data2, *to, *from;
367 int x, y, w, hw, iw, ih;
368 const char *file, *key;
370 sd = evas_object_smart_data_get(obj);
377 case ELM_IMAGE_FLIP_HORIZONTAL:
378 _els_smart_icon_flip_horizontal(sd);
380 case ELM_IMAGE_FLIP_VERTICAL:
381 _els_smart_icon_flip_vertical(sd);
383 case ELM_IMAGE_ROTATE_180_CW:
384 _els_smart_icon_rotate_180(sd);
390 evas_object_image_size_get(sd->obj, &iw, &ih);
391 evas_object_image_file_get(sd->obj, &file, &key);
392 tmp = evas_object_image_add(evas_object_evas_get(sd->obj));
393 evas_object_image_file_set(tmp, file, key);
394 data2 = evas_object_image_data_get(tmp, EINA_FALSE);
401 evas_object_image_size_set(sd->obj, iw, ih);
402 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
405 case ELM_IMAGE_FLIP_TRANSPOSE:
409 case ELM_IMAGE_FLIP_TRANSVERSE:
414 case ELM_IMAGE_ROTATE_90_CW:
418 case ELM_IMAGE_ROTATE_90_CCW:
424 ERR("unknown orient %d", orient);
425 evas_object_del(tmp);
426 evas_object_image_data_set(sd->obj, data); // give it back
430 for (x = iw; --x >= 0;)
432 for (y = ih; --y >= 0;)
441 evas_object_del(tmp);
442 evas_object_image_data_set(sd->obj, data);
443 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
444 _smart_reconfigure(sd);
448 _els_smart_icon_orient_get(const Evas_Object *obj)
450 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
456 * Turns on editing through drag and drop and copy and paste.
459 _els_smart_icon_edit_set(Evas_Object *obj, Eina_Bool edit, Evas_Object *parent)
461 Smart_Data *sd = evas_object_smart_data_get(obj);
466 printf("No editing edje objects yet (ever)\n");
470 /* Unfortunately eina bool is not a bool, but a char */
471 if (edit == sd->edit) return;
476 elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE, _els_smart_icon_dropcb,
479 elm_drop_target_del(obj);
483 _els_smart_icon_edit_get(const Evas_Object *obj)
485 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
486 if (!sd) return EINA_FALSE;
491 _els_smart_icon_edje_get(Evas_Object *obj)
493 Smart_Data *sd = evas_object_smart_data_get(obj);
494 if (!sd) return NULL;
495 if (!sd->edje) return NULL;
500 _els_smart_icon_aspect_ratio_retained_set(Evas_Object *obj, Eina_Bool retained)
504 sd = evas_object_smart_data_get(obj);
507 retained = !!retained;
508 if (sd->aspect_ratio_retained == retained) return;
509 sd->aspect_ratio_retained = retained;
510 _smart_reconfigure(sd);
514 _els_smart_icon_aspect_ratio_retained_get(const Evas_Object *obj)
518 sd = evas_object_smart_data_get(obj);
519 if (!sd) return EINA_FALSE;
520 return sd->aspect_ratio_retained;
523 /* local subsystem globals */
525 _smart_reconfigure(Smart_Data *sd)
527 Evas_Coord x, y, w, h;
530 if (!sd->obj) return;
535 type = evas_object_type_get(sd->obj);
537 if (!strcmp(type, "edje"))
541 evas_object_move(sd->obj, x, y);
542 evas_object_resize(sd->obj, w, h);
548 evas_object_image_size_get(sd->obj, &iw, &ih);
550 iw = ((double)iw) * sd->scale;
551 ih = ((double)ih) * sd->scale;
556 if (sd->aspect_ratio_retained)
558 h = ((double)ih * w) / (double)iw;
564 w = ((double)iw * h) / (double)ih;
572 w = ((double)iw * h) / (double)ih;
586 x = sd->x + ((sd->w - w) / 2);
587 y = sd->y + ((sd->h - h) / 2);
588 evas_object_move(sd->obj, x, y);
589 evas_object_image_fill_set(sd->obj, 0, 0, w, h);
590 evas_object_resize(sd->obj, w, h);
597 if (_e_smart) return;
599 static const Evas_Smart_Class sc =
602 EVAS_SMART_CLASS_VERSION,
620 _e_smart = evas_smart_class_new(&sc);
625 _smart_add(Evas_Object *obj)
629 sd = calloc(1, sizeof(Smart_Data));
631 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
633 evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
638 sd->fill_inside = EINA_TRUE;
639 sd->scale_up = EINA_TRUE;
640 sd->scale_down = EINA_TRUE;
641 sd->aspect_ratio_retained = EINA_TRUE;
644 evas_object_smart_member_add(sd->obj, obj);
645 evas_object_smart_data_set(obj, sd);
646 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
651 _smart_del(Evas_Object *obj)
655 sd = evas_object_smart_data_get(obj);
657 evas_object_del(sd->obj);
658 if (sd->prev) evas_object_del(sd->prev);
663 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
667 sd = evas_object_smart_data_get(obj);
669 if ((sd->x == x) && (sd->y == y)) return;
672 _smart_reconfigure(sd);
676 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
680 sd = evas_object_smart_data_get(obj);
682 if ((sd->w == w) && (sd->h == h)) return;
685 _smart_reconfigure(sd);
689 _smart_show(Evas_Object *obj)
693 sd = evas_object_smart_data_get(obj);
695 sd->show = EINA_TRUE;
698 evas_object_show(sd->obj);
699 if (sd->prev) evas_object_del(sd->prev);
705 _smart_hide(Evas_Object *obj)
709 sd = evas_object_smart_data_get(obj);
711 sd->show = EINA_FALSE;
712 evas_object_hide(sd->obj);
713 if (sd->prev) evas_object_del(sd->prev);
718 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
722 sd = evas_object_smart_data_get(obj);
724 evas_object_color_set(sd->obj, r, g, b, a);
725 if (sd->prev) evas_object_color_set(sd->prev, r, g, b, a);
729 _smart_clip_set(Evas_Object *obj, Evas_Object * clip)
733 sd = evas_object_smart_data_get(obj);
735 evas_object_clip_set(sd->obj, clip);
736 if (sd->prev) evas_object_clip_set(sd->prev, clip);
740 _smart_clip_unset(Evas_Object *obj)
744 sd = evas_object_smart_data_get(obj);
746 evas_object_clip_unset(sd->obj);
747 if (sd->prev) evas_object_clip_unset(sd->prev);
751 _els_smart_icon_flip_horizontal(Smart_Data *sd)
754 unsigned int *p1, *p2, tmp;
757 evas_object_image_size_get(sd->obj, &iw, &ih);
758 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
760 for (y = 0; y < ih; y++)
762 p1 = data + (y * iw);
763 p2 = data + ((y + 1) * iw) - 1;
764 for (x = 0; x < (iw >> 1); x++)
774 evas_object_image_data_set(sd->obj, data);
775 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
776 _smart_reconfigure(sd);
780 _els_smart_icon_flip_vertical(Smart_Data *sd)
783 unsigned int *p1, *p2, tmp;
786 evas_object_image_size_get(sd->obj, &iw, &ih);
787 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
789 for (y = 0; y < (ih >> 1); y++)
791 p1 = data + (y * iw);
792 p2 = data + ((ih - 1 - y) * iw);
793 for (x = 0; x < iw; x++)
803 evas_object_image_data_set(sd->obj, data);
804 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
805 _smart_reconfigure(sd);
809 _els_smart_icon_rotate_180(Smart_Data *sd)
812 unsigned int *p1, *p2, tmp;
815 evas_object_image_size_get(sd->obj, &iw, &ih);
816 data = evas_object_image_data_get(sd->obj, 1);
830 evas_object_image_data_set(sd->obj, data);
831 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
832 _smart_reconfigure(sd);
836 _els_smart_icon_dropcb(void *elmobj,Evas_Object *obj, Elm_Selection_Data *drop)
838 _els_smart_icon_file_key_set(obj, drop->data, NULL);
839 evas_object_smart_callback_call(elmobj, "drop", drop->data);
843 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/