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 if (sd->prev) evas_object_del(sd->prev);
84 pclip = evas_object_clip_get(sd->obj);
85 if (sd->obj) sd->prev = sd->obj;
86 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
87 evas_object_image_load_orientation_set(sd->obj, EINA_TRUE);
88 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
90 evas_object_smart_member_add(sd->obj, obj);
91 if (sd->prev) evas_object_smart_member_add(sd->prev, obj);
92 evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
93 evas_object_clip_set(sd->obj, pclip);
95 sd->edje = EINA_FALSE;
98 evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
102 _els_smart_icon_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key)
106 sd = evas_object_smart_data_get(obj);
107 if (!sd) return EINA_FALSE;
108 _els_smart_icon_file_helper(obj);
110 evas_object_image_memfile_set(sd->obj, (void*)img, size, (char*)format, (char*)key);
111 sd->preloading = EINA_TRUE;
112 sd->show = EINA_TRUE;
113 evas_object_hide(sd->obj);
114 evas_object_image_preload(sd->obj, EINA_FALSE);
115 if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
117 ERR("Things are going bad for some random " FMT_SIZE_T " byte chunk of memory (%p)", size, sd->obj);
120 _smart_reconfigure(sd);
125 _els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
130 sd = evas_object_smart_data_get(obj);
131 if (!sd) return EINA_FALSE;
132 _els_smart_icon_file_helper(obj);
134 evas_object_image_file_set(sd->obj, file, key);
135 sd->preloading = EINA_TRUE;
136 sd->show = EINA_TRUE;
137 evas_object_hide(sd->obj);
138 _els_smart_icon_size_get(obj, &w, &h);
139 evas_object_image_load_size_set(sd->obj, w, h);
140 evas_object_image_preload(sd->obj, EINA_FALSE);
141 if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
143 ERR("Things are going bad for '%s' (%p)", file, sd->obj);
146 _smart_reconfigure(sd);
151 _els_smart_icon_preload_set(Evas_Object *obj, Eina_Bool disable)
155 sd = evas_object_smart_data_get(obj);
156 if ((!sd) || sd->edje) return;
157 evas_object_image_preload(sd->obj, disable);
158 sd->preloading = !disable;
162 _els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
167 sd = evas_object_smart_data_get(obj);
168 if (!sd) return EINA_FALSE;
169 /* smart code here */
170 if (sd->prev) evas_object_del(sd->prev);
175 pclip = evas_object_clip_get(sd->obj);
176 if (sd->obj) evas_object_del(sd->obj);
177 sd->obj = edje_object_add(evas_object_evas_get(obj));
178 evas_object_smart_member_add(sd->obj, obj);
179 if (sd->show) evas_object_show(sd->obj);
180 evas_object_clip_set(sd->obj, pclip);
182 sd->edje = EINA_TRUE;
183 if (!edje_object_file_set(sd->obj, file, part))
185 _smart_reconfigure(sd);
190 _els_smart_icon_file_get(const Evas_Object *obj, const char **file, const char **key)
192 Smart_Data *sd = evas_object_smart_data_get(obj);
195 edje_object_file_get(sd->obj, file, key);
197 evas_object_image_file_get(sd->obj, file, key);
201 _els_smart_icon_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
203 Smart_Data *sd = evas_object_smart_data_get(obj);
207 evas_object_image_smooth_scale_set(sd->obj, smooth);
211 _els_smart_icon_smooth_scale_get(const Evas_Object *obj)
213 Smart_Data *sd = evas_object_smart_data_get(obj);
214 if (!sd) return EINA_FALSE;
217 return evas_object_image_smooth_scale_get(sd->obj);
221 _els_smart_icon_object_get(const Evas_Object *obj)
223 Smart_Data *sd = evas_object_smart_data_get(obj);
224 if (!sd) return NULL;
229 _els_smart_icon_size_get(const Evas_Object *obj, int *w, int *h)
236 sd = evas_object_smart_data_get(obj);
238 type = evas_object_type_get(sd->obj);
240 if (!strcmp(type, "edje"))
241 edje_object_size_min_get(sd->obj, &tw, &th);
243 evas_object_image_size_get(sd->obj, &tw, &th);
244 evas_object_geometry_get(sd->obj, NULL, NULL, &cw, &ch);
245 tw = tw > cw ? tw : cw;
246 th = th > ch ? th : ch;
247 tw = ((double)tw) * sd->scale;
248 th = ((double)th) * sd->scale;
254 _els_smart_icon_fill_inside_set(Evas_Object *obj, Eina_Bool fill_inside)
258 sd = evas_object_smart_data_get(obj);
260 if (((sd->fill_inside) && (fill_inside)) ||
261 ((!sd->fill_inside) && (!fill_inside))) return;
262 sd->fill_inside = fill_inside;
263 _smart_reconfigure(sd);
267 _els_smart_icon_fill_inside_get(const Evas_Object *obj)
269 Smart_Data *sd = evas_object_smart_data_get(obj);
270 if (!sd) return EINA_FALSE;
271 return sd->fill_inside;
275 _els_smart_icon_scale_up_set(Evas_Object *obj, Eina_Bool scale_up)
279 sd = evas_object_smart_data_get(obj);
281 if (((sd->scale_up) && (scale_up)) ||
282 ((!sd->scale_up) && (!scale_up))) return;
283 sd->scale_up = scale_up;
284 _smart_reconfigure(sd);
288 _els_smart_icon_scale_up_get(const Evas_Object *obj)
290 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
291 if (!sd) return EINA_FALSE;
296 _els_smart_icon_scale_down_set(Evas_Object *obj, Eina_Bool scale_down)
300 sd = evas_object_smart_data_get(obj);
302 if (((sd->scale_down) && (scale_down)) ||
303 ((!sd->scale_down) && (!scale_down))) return;
304 sd->scale_down = scale_down;
305 _smart_reconfigure(sd);
309 _els_smart_icon_scale_down_get(const Evas_Object *obj)
311 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
312 if (!sd) return EINA_FALSE;
317 _els_smart_icon_scale_size_set(Evas_Object *obj, int size)
321 sd = evas_object_smart_data_get(obj);
324 if (!sd->obj) return;
327 evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
331 _els_smart_icon_scale_size_get(const Evas_Object *obj)
333 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
339 _els_smart_icon_scale_set(Evas_Object *obj, double scale)
341 Smart_Data *sd = evas_object_smart_data_get(obj);
344 _smart_reconfigure(sd);
348 _els_smart_icon_scale_get(const Evas_Object *obj)
350 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
356 _els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
359 unsigned int *data, *data2 = NULL, *to, *from;
360 int x, y, w, hw, iw, ih;
362 sd = evas_object_smart_data_get(obj);
369 case ELM_IMAGE_FLIP_HORIZONTAL:
370 _els_smart_icon_flip_horizontal(sd);
372 case ELM_IMAGE_FLIP_VERTICAL:
373 _els_smart_icon_flip_vertical(sd);
375 case ELM_IMAGE_ROTATE_180:
376 _els_smart_icon_rotate_180(sd);
382 evas_object_image_size_get(sd->obj, &iw, &ih);
383 /* we need separate destination memory if we want to rotate 90 or 270 degree */
384 evas_object_image_data_copy_set(sd->obj, data2);
392 evas_object_image_size_set(sd->obj, iw, ih);
393 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
397 case ELM_IMAGE_FLIP_TRANSPOSE:
401 case ELM_IMAGE_FLIP_TRANSVERSE:
406 case ELM_IMAGE_ROTATE_90:
410 case ELM_IMAGE_ROTATE_270:
416 ERR("unknown orient %d", orient);
417 evas_object_image_data_set(sd->obj, data); // give it back
418 if (data2) free(data2);
422 for (x = iw; --x >= 0;)
424 for (y = ih; --y >= 0;)
433 if (data2) free(data2);
434 evas_object_image_data_set(sd->obj, data);
435 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
436 _smart_reconfigure(sd);
440 _els_smart_icon_orient_get(const Evas_Object *obj)
442 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
448 * Turns on editing through drag and drop and copy and paste.
451 _els_smart_icon_edit_set(Evas_Object *obj, Eina_Bool edit, Evas_Object *parent)
453 Smart_Data *sd = evas_object_smart_data_get(obj);
458 printf("No editing edje objects yet (ever)\n");
462 /* Unfortunately eina bool is not a bool, but a char */
463 if (edit == sd->edit) return;
468 elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE, _els_smart_icon_dropcb,
471 elm_drop_target_del(obj);
475 _els_smart_icon_edit_get(const Evas_Object *obj)
477 Smart_Data *sd; sd = evas_object_smart_data_get(obj);
478 if (!sd) return EINA_FALSE;
483 _els_smart_icon_edje_get(Evas_Object *obj)
485 Smart_Data *sd = evas_object_smart_data_get(obj);
486 if (!sd) return NULL;
487 if (!sd->edje) return NULL;
492 _els_smart_icon_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed)
496 sd = evas_object_smart_data_get(obj);
500 if (sd->aspect_fixed == fixed) return;
501 sd->aspect_fixed = fixed;
502 _smart_reconfigure(sd);
506 _els_smart_icon_aspect_fixed_get(const Evas_Object *obj)
510 sd = evas_object_smart_data_get(obj);
511 if (!sd) return EINA_FALSE;
512 return sd->aspect_fixed;
515 /* local subsystem globals */
517 _smart_reconfigure(Smart_Data *sd)
519 Evas_Coord x, y, w, h;
522 if (!sd->obj) return;
527 type = evas_object_type_get(sd->obj);
529 if (!strcmp(type, "edje"))
533 evas_object_move(sd->obj, x, y);
534 evas_object_resize(sd->obj, w, h);
539 double alignh = 0.5, alignv = 0.5;
542 evas_object_image_size_get(sd->obj, &iw, &ih);
544 iw = ((double)iw) * sd->scale;
545 ih = ((double)ih) * sd->scale;
550 if (sd->aspect_fixed)
552 h = ((double)ih * w) / (double)iw;
558 w = ((double)iw * h) / (double)ih;
566 w = ((double)iw * h) / (double)ih;
580 parent = elm_widget_parent_widget_get(sd->obj);
582 evas_object_size_hint_align_get(parent, &alignh, &alignv);
583 x = sd->x + ((sd->w - w) * alignh);
584 y = sd->y + ((sd->h - h) * alignv);
585 evas_object_move(sd->obj, x, y);
586 evas_object_image_fill_set(sd->obj, 0, 0, w, h);
587 evas_object_resize(sd->obj, w, h);
594 if (_e_smart) return;
596 static const Evas_Smart_Class sc =
599 EVAS_SMART_CLASS_VERSION,
617 _e_smart = evas_smart_class_new(&sc);
622 _smart_add(Evas_Object *obj)
626 sd = calloc(1, sizeof(Smart_Data));
628 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
630 evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
635 sd->fill_inside = EINA_TRUE;
636 sd->scale_up = EINA_TRUE;
637 sd->scale_down = EINA_TRUE;
638 sd->aspect_fixed = EINA_TRUE;
641 evas_object_smart_member_add(sd->obj, obj);
642 evas_object_smart_data_set(obj, sd);
643 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
648 _smart_del(Evas_Object *obj)
652 sd = evas_object_smart_data_get(obj);
654 evas_object_del(sd->obj);
655 if (sd->prev) evas_object_del(sd->prev);
660 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
664 sd = evas_object_smart_data_get(obj);
666 if ((sd->x == x) && (sd->y == y)) return;
669 _smart_reconfigure(sd);
673 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
677 sd = evas_object_smart_data_get(obj);
679 if ((sd->w == w) && (sd->h == h)) return;
682 _smart_reconfigure(sd);
686 _smart_show(Evas_Object *obj)
690 sd = evas_object_smart_data_get(obj);
692 sd->show = EINA_TRUE;
695 evas_object_show(sd->obj);
696 if (sd->prev) evas_object_del(sd->prev);
702 _smart_hide(Evas_Object *obj)
706 sd = evas_object_smart_data_get(obj);
708 sd->show = EINA_FALSE;
709 evas_object_hide(sd->obj);
710 if (sd->prev) evas_object_del(sd->prev);
715 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
719 sd = evas_object_smart_data_get(obj);
721 evas_object_color_set(sd->obj, r, g, b, a);
722 if (sd->prev) evas_object_color_set(sd->prev, r, g, b, a);
726 _smart_clip_set(Evas_Object *obj, Evas_Object * clip)
730 sd = evas_object_smart_data_get(obj);
732 evas_object_clip_set(sd->obj, clip);
733 if (sd->prev) evas_object_clip_set(sd->prev, clip);
737 _smart_clip_unset(Evas_Object *obj)
741 sd = evas_object_smart_data_get(obj);
743 evas_object_clip_unset(sd->obj);
744 if (sd->prev) evas_object_clip_unset(sd->prev);
748 _els_smart_icon_flip_horizontal(Smart_Data *sd)
751 unsigned int *p1, *p2, tmp;
754 evas_object_image_size_get(sd->obj, &iw, &ih);
755 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
757 for (y = 0; y < ih; y++)
759 p1 = data + (y * iw);
760 p2 = data + ((y + 1) * iw) - 1;
761 for (x = 0; x < (iw >> 1); x++)
771 evas_object_image_data_set(sd->obj, data);
772 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
773 _smart_reconfigure(sd);
777 _els_smart_icon_flip_vertical(Smart_Data *sd)
780 unsigned int *p1, *p2, tmp;
783 evas_object_image_size_get(sd->obj, &iw, &ih);
784 data = evas_object_image_data_get(sd->obj, EINA_TRUE);
786 for (y = 0; y < (ih >> 1); y++)
788 p1 = data + (y * iw);
789 p2 = data + ((ih - 1 - y) * iw);
790 for (x = 0; x < iw; x++)
800 evas_object_image_data_set(sd->obj, data);
801 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
802 _smart_reconfigure(sd);
806 _els_smart_icon_rotate_180(Smart_Data *sd)
809 unsigned int *p1, *p2, tmp;
812 evas_object_image_size_get(sd->obj, &iw, &ih);
813 data = evas_object_image_data_get(sd->obj, 1);
827 evas_object_image_data_set(sd->obj, data);
828 evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
829 _smart_reconfigure(sd);
833 _els_smart_icon_dropcb(void *elmobj,Evas_Object *obj, Elm_Selection_Data *drop)
835 _els_smart_icon_file_key_set(obj, drop->data, NULL);
836 evas_object_smart_callback_call(elmobj, "drop", drop->data);
840 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/