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_fixed: 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_image_load_orientation_set(sd->obj, EINA_TRUE);
92 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
94 evas_object_smart_member_add(sd->obj, obj);
95 if (sd->prev) evas_object_smart_member_add(sd->prev, obj);
96 evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
97 evas_object_clip_set(sd->obj, pclip);
99 sd->edje = EINA_FALSE;
103 evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
107 _els_smart_icon_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key)
111 sd = evas_object_smart_data_get(obj);
112 if (!sd) return EINA_FALSE;
113 _els_smart_icon_file_helper(obj);
115 evas_object_image_memfile_set(sd->obj, (void*)img, size, (char*)format, (char*)key);
116 sd->preloading = EINA_TRUE;
117 sd->show = EINA_TRUE;
118 evas_object_hide(sd->obj);
119 evas_object_image_preload(sd->obj, EINA_FALSE);
120 if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
122 ERR("Things are going bad for some random " FMT_SIZE_T " byte chunk of memory (%p)", size, sd->obj);
125 _smart_reconfigure(sd);
130 _els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
134 sd = evas_object_smart_data_get(obj);
135 if (!sd) return EINA_FALSE;
136 _els_smart_icon_file_helper(obj);
138 evas_object_image_file_set(sd->obj, file, key);
139 // NOTE: Do not merge upstream for sd->preloading.
140 sd->preloading = EINA_FALSE; // by default preload off by seok.j.jeong
141 sd->show = EINA_TRUE;
142 // NOTE: Do not merge upstream for sd->preloading.
144 evas_object_image_preload(sd->obj, EINA_FALSE);
145 // NOTE: Do not merge upstream for sd->preloading.
146 if (sd->preloading) // sd->preloading can be changed by above function. so add "if (sd->preloading)" as below
147 evas_object_hide(sd->obj);
148 if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
150 ERR("Things are going bad for '%s' (%p)", file, sd->obj);
153 _smart_reconfigure(sd);
158 _els_smart_icon_preload_set(Evas_Object *obj, Eina_Bool disable)
162 sd = evas_object_smart_data_get(obj);
163 if ((!sd) || sd->edje) return;
164 evas_object_image_preload(sd->obj, disable);
165 sd->preloading = !disable;
169 _els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
174 sd = evas_object_smart_data_get(obj);
175 if (!sd) return EINA_FALSE;
176 /* smart code here */
177 if (sd->prev) evas_object_del(sd->prev);
182 pclip = evas_object_clip_get(sd->obj);
183 if (sd->obj) evas_object_del(sd->obj);
184 sd->obj = edje_object_add(evas_object_evas_get(obj));
185 evas_object_smart_member_add(sd->obj, obj);
186 if (sd->show) evas_object_show(sd->obj);
187 evas_object_clip_set(sd->obj, pclip);
189 sd->edje = EINA_TRUE;
190 if (!edje_object_file_set(sd->obj, file, part))
192 _smart_reconfigure(sd);
197 _els_smart_icon_file_get(const Evas_Object *obj, const char **file, const char **key)
199 Smart_Data *sd = evas_object_smart_data_get(obj);
202 edje_object_file_get(sd->obj, file, key);
204 evas_object_image_file_get(sd->obj, file, key);
208 _els_smart_icon_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
210 Smart_Data *sd = evas_object_smart_data_get(obj);
214 evas_object_image_smooth_scale_set(sd->obj, smooth);
218 _els_smart_icon_smooth_scale_get(const Evas_Object *obj)
220 Smart_Data *sd = evas_object_smart_data_get(obj);
221 if (!sd) return EINA_FALSE;
224 return evas_object_image_smooth_scale_get(sd->obj);
228 _els_smart_icon_object_get(const Evas_Object *obj)
230 Smart_Data *sd = evas_object_smart_data_get(obj);
231 if (!sd) return NULL;
236 _els_smart_icon_size_get(const Evas_Object *obj, int *w, int *h)
243 sd = evas_object_smart_data_get(obj);
245 type = evas_object_type_get(sd->obj);
247 if (!strcmp(type, "edje"))
248 edje_object_size_min_get(sd->obj, &tw, &th);
250 evas_object_image_size_get(sd->obj, &tw, &th);
251 evas_object_geometry_get(sd->obj, NULL, NULL, &cw, &ch);
252 tw = tw > cw ? tw : cw;
253 th = th > ch ? th : ch;
254 tw = ((double)tw) * sd->scale;
255 th = ((double)th) * sd->scale;
261 _els_smart_icon_fill_inside_set(Evas_Object *obj, Eina_Bool fill_inside)
265 sd = evas_object_smart_data_get(obj);
267 if (((sd->fill_inside) && (fill_inside)) ||
268 ((!sd->fill_inside) && (!fill_inside))) return;
269 sd->fill_inside = fill_inside;
270 _smart_reconfigure(sd);
274 _els_smart_icon_fill_inside_get(const Evas_Object *obj)
276 Smart_Data *sd = evas_object_smart_data_get(obj);
277 if (!sd) return EINA_FALSE;
278 return sd->fill_inside;
282 _els_smart_icon_scale_up_set(Evas_Object *obj, Eina_Bool scale_up)
286 sd = evas_object_smart_data_get(obj);
288 if (((sd->scale_up) && (scale_up)) ||
289 ((!sd->scale_up) && (!scale_up))) return;
290 sd->scale_up = scale_up;
291 _smart_reconfigure(sd);
295 _els_smart_icon_scale_up_get(const Evas_Object *obj)
297 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
298 if (!sd) return EINA_FALSE;
303 _els_smart_icon_scale_down_set(Evas_Object *obj, Eina_Bool scale_down)
307 sd = evas_object_smart_data_get(obj);
309 if (((sd->scale_down) && (scale_down)) ||
310 ((!sd->scale_down) && (!scale_down))) return;
311 sd->scale_down = scale_down;
312 _smart_reconfigure(sd);
316 _els_smart_icon_scale_down_get(const Evas_Object *obj)
318 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
319 if (!sd) return EINA_FALSE;
324 _els_smart_icon_scale_size_set(Evas_Object *obj, int size)
328 sd = evas_object_smart_data_get(obj);
331 if (!sd->obj) return;
334 evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
338 _els_smart_icon_scale_size_get(const Evas_Object *obj)
340 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
346 _els_smart_icon_scale_set(Evas_Object *obj, double scale)
348 Smart_Data *sd = evas_object_smart_data_get(obj);
351 _smart_reconfigure(sd);
355 _els_smart_icon_scale_get(const Evas_Object *obj)
357 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
363 _els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
366 unsigned int *data, *data2 = NULL, *to, *from;
367 int x, y, w, hw, iw, ih;
369 sd = evas_object_smart_data_get(obj);
376 case ELM_IMAGE_FLIP_HORIZONTAL:
377 _els_smart_icon_flip_horizontal(sd);
379 case ELM_IMAGE_FLIP_VERTICAL:
380 _els_smart_icon_flip_vertical(sd);
382 case ELM_IMAGE_ROTATE_180_CW:
383 _els_smart_icon_rotate_180(sd);
389 evas_object_image_size_get(sd->obj, &iw, &ih);
390 /* we need separate destination memory if we want to rotate 90 or 270 degree */
391 evas_object_image_data_copy_set(sd->obj, data2);
399 evas_object_image_size_set(sd->obj, iw, ih);
400 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
404 case ELM_IMAGE_FLIP_TRANSPOSE:
408 case ELM_IMAGE_FLIP_TRANSVERSE:
413 case ELM_IMAGE_ROTATE_90_CW:
417 case ELM_IMAGE_ROTATE_90_CCW:
423 ERR("unknown orient %d", orient);
424 evas_object_image_data_set(sd->obj, data); // give it back
425 if (data2) free(data2);
429 for (x = iw; --x >= 0;)
431 for (y = ih; --y >= 0;)
440 if (data2) free(data2);
441 evas_object_image_data_set(sd->obj, data);
442 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
443 _smart_reconfigure(sd);
447 _els_smart_icon_orient_get(const Evas_Object *obj)
449 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
455 * Turns on editing through drag and drop and copy and paste.
458 _els_smart_icon_edit_set(Evas_Object *obj, Eina_Bool edit, Evas_Object *parent)
460 Smart_Data *sd = evas_object_smart_data_get(obj);
465 printf("No editing edje objects yet (ever)\n");
469 /* Unfortunately eina bool is not a bool, but a char */
470 if (edit == sd->edit) return;
475 elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE, _els_smart_icon_dropcb,
478 elm_drop_target_del(obj);
482 _els_smart_icon_edit_get(const Evas_Object *obj)
484 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
485 if (!sd) return EINA_FALSE;
490 _els_smart_icon_edje_get(Evas_Object *obj)
492 Smart_Data *sd = evas_object_smart_data_get(obj);
493 if (!sd) return NULL;
494 if (!sd->edje) return NULL;
499 _els_smart_icon_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed)
503 sd = evas_object_smart_data_get(obj);
507 if (sd->aspect_fixed == fixed) return;
508 sd->aspect_fixed = fixed;
509 _smart_reconfigure(sd);
513 _els_smart_icon_aspect_fixed_get(const Evas_Object *obj)
517 sd = evas_object_smart_data_get(obj);
518 if (!sd) return EINA_FALSE;
519 return sd->aspect_fixed;
522 /* local subsystem globals */
524 _smart_reconfigure(Smart_Data *sd)
526 Evas_Coord x, y, w, h;
529 if (!sd->obj) return;
534 type = evas_object_type_get(sd->obj);
536 if (!strcmp(type, "edje"))
540 evas_object_move(sd->obj, x, y);
541 evas_object_resize(sd->obj, w, h);
546 double alignh = 0.5, alignv = 0.5;
549 evas_object_image_size_get(sd->obj, &iw, &ih);
551 iw = ((double)iw) * sd->scale;
552 ih = ((double)ih) * sd->scale;
557 if (sd->aspect_fixed)
559 h = ((double)ih * w) / (double)iw;
565 w = ((double)iw * h) / (double)ih;
573 w = ((double)iw * h) / (double)ih;
587 parent = elm_widget_parent_widget_get(sd->obj);
589 evas_object_size_hint_align_get(parent, &alignh, &alignv);
590 if (alignh == EVAS_HINT_FILL) alignh = 0.5;
591 if (alignv == EVAS_HINT_FILL) alignv = 0.5;
592 x = sd->x + ((sd->w - w) * alignh);
593 y = sd->y + ((sd->h - h) * alignv);
594 evas_object_move(sd->obj, x, y);
595 evas_object_image_fill_set(sd->obj, 0, 0, w, h);
596 evas_object_resize(sd->obj, w, h);
603 if (_e_smart) return;
605 static const Evas_Smart_Class sc =
608 EVAS_SMART_CLASS_VERSION,
626 _e_smart = evas_smart_class_new(&sc);
631 _smart_add(Evas_Object *obj)
635 sd = calloc(1, sizeof(Smart_Data));
637 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
639 evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
644 sd->fill_inside = EINA_TRUE;
645 sd->scale_up = EINA_TRUE;
646 sd->scale_down = EINA_TRUE;
647 sd->aspect_fixed = EINA_TRUE;
650 evas_object_smart_member_add(sd->obj, obj);
651 evas_object_smart_data_set(obj, sd);
652 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
657 _smart_del(Evas_Object *obj)
661 sd = evas_object_smart_data_get(obj);
663 evas_object_del(sd->obj);
664 if (sd->prev) evas_object_del(sd->prev);
669 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
673 sd = evas_object_smart_data_get(obj);
675 if ((sd->x == x) && (sd->y == y)) return;
678 _smart_reconfigure(sd);
682 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
686 sd = evas_object_smart_data_get(obj);
688 if ((sd->w == w) && (sd->h == h)) return;
691 _smart_reconfigure(sd);
695 _smart_show(Evas_Object *obj)
699 sd = evas_object_smart_data_get(obj);
701 sd->show = EINA_TRUE;
704 evas_object_show(sd->obj);
705 if (sd->prev) evas_object_del(sd->prev);
711 _smart_hide(Evas_Object *obj)
715 sd = evas_object_smart_data_get(obj);
717 sd->show = EINA_FALSE;
718 evas_object_hide(sd->obj);
719 if (sd->prev) evas_object_del(sd->prev);
724 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
728 sd = evas_object_smart_data_get(obj);
730 evas_object_color_set(sd->obj, r, g, b, a);
731 if (sd->prev) evas_object_color_set(sd->prev, r, g, b, a);
735 _smart_clip_set(Evas_Object *obj, Evas_Object * clip)
739 sd = evas_object_smart_data_get(obj);
741 evas_object_clip_set(sd->obj, clip);
742 if (sd->prev) evas_object_clip_set(sd->prev, clip);
746 _smart_clip_unset(Evas_Object *obj)
750 sd = evas_object_smart_data_get(obj);
752 evas_object_clip_unset(sd->obj);
753 if (sd->prev) evas_object_clip_unset(sd->prev);
757 _els_smart_icon_flip_horizontal(Smart_Data *sd)
760 unsigned int *p1, *p2, tmp;
763 evas_object_image_size_get(sd->obj, &iw, &ih);
764 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
766 for (y = 0; y < ih; y++)
768 p1 = data + (y * iw);
769 p2 = data + ((y + 1) * iw) - 1;
770 for (x = 0; x < (iw >> 1); x++)
780 evas_object_image_data_set(sd->obj, data);
781 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
782 _smart_reconfigure(sd);
786 _els_smart_icon_flip_vertical(Smart_Data *sd)
789 unsigned int *p1, *p2, tmp;
792 evas_object_image_size_get(sd->obj, &iw, &ih);
793 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
795 for (y = 0; y < (ih >> 1); y++)
797 p1 = data + (y * iw);
798 p2 = data + ((ih - 1 - y) * iw);
799 for (x = 0; x < iw; x++)
809 evas_object_image_data_set(sd->obj, data);
810 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
811 _smart_reconfigure(sd);
815 _els_smart_icon_rotate_180(Smart_Data *sd)
818 unsigned int *p1, *p2, tmp;
821 evas_object_image_size_get(sd->obj, &iw, &ih);
822 data = evas_object_image_data_get(sd->obj, 1);
836 evas_object_image_data_set(sd->obj, data);
837 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
838 _smart_reconfigure(sd);
842 _els_smart_icon_dropcb(void *elmobj,Evas_Object *obj, Elm_Selection_Data *drop)
844 _els_smart_icon_file_key_set(obj, drop->data, NULL);
845 evas_object_smart_callback_call(elmobj, "drop", drop->data);
849 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/