elementary: Improve include file modularity
[framework/uifw/elementary.git] / src / lib / elm_image.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "els_icon.h"
4
5 /**
6  * @defgroup Image Image
7  * @ingroup Elementary
8  *
9  * A standard image that may be provided by the theme (delete, edit,
10  * arrows etc.) or a custom file (PNG, JPG, EDJE etc.) used for an
11  * icon. The Icon may scale or not and of course... support alpha
12  * channels.
13  *
14  * Signals that you can add callbacks for are:
15  *
16  * "clicked" - This is called when a user has clicked the image
17  */
18
19 typedef struct _Widget_Data Widget_Data;
20
21 struct _Widget_Data
22 {
23    Evas_Object *img;
24    Eina_Bool scale_up : 1;
25    Eina_Bool scale_down : 1;
26    Eina_Bool smooth : 1;
27    Eina_Bool fill_outside : 1;
28    Eina_Bool no_scale : 1;
29 };
30
31 static const char *widtype = NULL;
32 static void _del_hook(Evas_Object *obj);
33 static void _theme_hook(Evas_Object *obj);
34 static void _sizing_eval(Evas_Object *obj);
35 static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
36
37 static const char SIG_CLICKED[] = "clicked";
38
39 static const Evas_Smart_Cb_Description _signals[] = {
40    {SIG_CLICKED, ""},
41    {NULL, NULL}
42 };
43
44
45 static void
46 _del_hook(Evas_Object *obj)
47 {
48    Widget_Data *wd = elm_widget_data_get(obj);
49
50    if (!wd) return;
51    free(wd);
52 }
53
54 static void
55 _del_pre_hook(Evas_Object *obj)
56 {
57    Widget_Data *wd = elm_widget_data_get(obj);
58
59    if (!wd) return;
60    evas_object_del(wd->img);
61 }
62
63 static void
64 _theme_hook(Evas_Object *obj)
65 {
66    Widget_Data *wd = elm_widget_data_get(obj);
67
68    if (!wd) return;
69    _sizing_eval(obj);
70 }
71
72 static void
73 _sizing_eval(Evas_Object *obj)
74 {
75    Widget_Data *wd = elm_widget_data_get(obj);
76    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
77    int w, h;
78
79    if (!wd) return;
80    _els_smart_icon_size_get(wd->img, &w, &h);
81    _els_smart_icon_scale_up_set(wd->img, wd->scale_up);
82    _els_smart_icon_scale_down_set(wd->img, wd->scale_down);
83    _els_smart_icon_smooth_scale_set(wd->img, wd->smooth);
84    _els_smart_icon_fill_inside_set(wd->img, !(wd->fill_outside));
85    if (wd->no_scale) _els_smart_icon_scale_set(wd->img, 1.0);
86    else
87      {
88         _els_smart_icon_scale_set(wd->img, elm_widget_scale_get(obj) * _elm_config->scale);
89         _els_smart_icon_size_get(wd->img, &w, &h);
90      }
91    if (!wd->scale_down)
92      {
93         minw = w;
94         minh = h;
95      }
96    if (!wd->scale_up)
97      {
98         maxw = w;
99         maxh = h;
100      }
101    evas_object_size_hint_min_set(obj, minw, minh);
102    evas_object_size_hint_max_set(obj, maxw, maxh);
103 }
104
105 static void
106 _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
107 {
108    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
109 }
110
111 /**
112  * Add a new image to the parent
113  *
114  * @param parent The parent object
115  * @return The new object or NULL if it cannot be created
116  *
117  * @ingroup Image
118  */
119 EAPI Evas_Object *
120 elm_image_add(Evas_Object *parent)
121 {
122    Evas_Object *obj;
123    Evas *e;
124    Widget_Data *wd;
125
126    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
127
128    ELM_SET_WIDTYPE(widtype, "image");
129    elm_widget_type_set(obj, "image");
130    elm_widget_sub_object_add(parent, obj);
131    elm_widget_data_set(obj, wd);
132    elm_widget_del_hook_set(obj, _del_hook);
133    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
134    elm_widget_theme_hook_set(obj, _theme_hook);
135    elm_widget_can_focus_set(obj, EINA_FALSE);
136
137    wd->img = _els_smart_icon_add(e);
138    evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
139                                   _mouse_up, obj);
140    evas_object_repeat_events_set(wd->img, EINA_TRUE);
141    elm_widget_resize_object_set(obj, wd->img);
142
143    evas_object_smart_callbacks_descriptions_set(obj, _signals);
144
145    wd->smooth = EINA_TRUE;
146    wd->scale_up = EINA_TRUE;
147    wd->scale_down = EINA_TRUE;
148
149    _els_smart_icon_scale_size_set(wd->img, 0);
150
151    _sizing_eval(obj);
152    return obj;
153 }
154
155 /**
156  * Set the file that will be used as image
157  *
158  * @param obj The image object
159  * @param file The path to file that will be used as image
160  * @param group The group that the image belongs in edje file
161  *
162  * @return (1 = success, 0 = error)
163  *
164  * @ingroup Image
165  */
166 EAPI Eina_Bool
167 elm_image_file_set(Evas_Object *obj, const char *file, const char *group)
168 {
169    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
170    Widget_Data *wd = elm_widget_data_get(obj);
171    Eina_Bool ret;
172    const char *p;
173
174    if (!wd) return EINA_FALSE;
175    EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
176    if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
177      ret = _els_smart_icon_file_edje_set(wd->img, file, group);
178    else
179      ret = _els_smart_icon_file_key_set(wd->img, file, group);
180    _sizing_eval(obj);
181    return ret;
182 }
183
184 /**
185  * Get the file that will be used as image
186  *
187  * @param obj The image object
188  * @param file The path to file
189  * @param group The group that the image belongs in edje file
190  *
191  * @ingroup Image
192  */
193 EAPI void
194 elm_image_file_get(const Evas_Object *obj, const char **file, const char **group)
195 {
196    ELM_CHECK_WIDTYPE(obj, widtype);
197    Widget_Data *wd = elm_widget_data_get(obj);
198    if (!wd) return;
199    _els_smart_icon_file_get(wd->img, file, group);
200 }
201
202 /**
203  * Set the smooth effect for a image
204  *
205  * @param obj The image object
206  * @param smooth A bool to set (or no) smooth effect
207  * (1 = smooth, 0 = not smooth)
208  *
209  * @ingroup Image
210  */
211 EAPI void
212 elm_image_smooth_set(Evas_Object *obj, Eina_Bool smooth)
213 {
214    ELM_CHECK_WIDTYPE(obj, widtype);
215    Widget_Data *wd = elm_widget_data_get(obj);
216
217    if (!wd) return;
218    wd->smooth = smooth;
219    _sizing_eval(obj);
220 }
221
222 /**
223  * Get the smooth effect for a image
224  *
225  * @param obj The image object
226  * @return If setted smooth effect
227  *
228  * @ingroup Image
229  */
230 EAPI Eina_Bool
231 elm_image_smooth_get(const Evas_Object *obj)
232 {
233    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
234    Widget_Data *wd = elm_widget_data_get(obj);
235
236    if (!wd) return EINA_FALSE;
237    return wd->smooth;
238 }
239
240 /**
241  * Gets the current size of the image.
242  *
243  * Either width or height (or both) may be NULL.
244  *
245  * On error, neither w or h will be written too.
246  *
247  * @param obj The image object.
248  * @param w Pointer to store width, or NULL.
249  * @param h Pointer to store height, or NULL.
250  *
251  * @ingroup Image
252  */
253 EAPI void
254 elm_image_object_size_get(const Evas_Object *obj, int *w, int *h)
255 {
256    ELM_CHECK_WIDTYPE(obj, widtype);
257    Widget_Data *wd = elm_widget_data_get(obj);
258
259    if (!wd) return;
260    _els_smart_icon_size_get(wd->img, w, h);
261 }
262
263 /**
264  * Set if the object are scalable
265  *
266  * @param obj The image object.
267  * @param no_scale A bool to set scale (or no).
268  * (1 = no_scale, 0 = scale)
269  *
270  * @ingroup Image
271  */
272 EAPI void
273 elm_image_no_scale_set(Evas_Object *obj, Eina_Bool no_scale)
274 {
275    ELM_CHECK_WIDTYPE(obj, widtype);
276    Widget_Data *wd = elm_widget_data_get(obj);
277
278    if (!wd) return;
279    wd->no_scale = no_scale;
280    _sizing_eval(obj);
281
282 }
283
284 /**
285  * Get if the object isn't scalable
286  *
287  * @param obj The image object
288  * @return If isn't scalable
289  *
290  * @ingroup Image
291  */
292 EAPI Eina_Bool
293 elm_image_no_scale_get(const Evas_Object *obj)
294 {
295    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
296    Widget_Data *wd = elm_widget_data_get(obj);
297    if (!wd) return EINA_FALSE;
298    return wd->no_scale;
299 }
300
301 /**
302  * Set if the object is (up/down) scalable
303  *
304  * @param obj The image object
305  * @param scale_up A bool to set if the object is scalable up
306  * @param scale_down A bool to set if the object is scalable down
307  *
308  * @ingroup Image
309  */
310 EAPI void
311 elm_image_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down)
312 {
313    ELM_CHECK_WIDTYPE(obj, widtype);
314    Widget_Data *wd = elm_widget_data_get(obj);
315
316    if (!wd) return;
317    wd->scale_up = scale_up;
318    wd->scale_down = scale_down;
319    _sizing_eval(obj);
320 }
321
322 /**
323  * Get if the object is (up/down) scalable
324  *
325  * @param obj The image object
326  * @param scale_up A bool to set if the object is scalable up
327  * @param scale_down A bool to set if the object is scalable down
328  *
329  * @ingroup Image
330  */
331 EAPI void
332 elm_image_scale_get(const Evas_Object *obj, Eina_Bool *scale_up, Eina_Bool *scale_down)
333 {
334    ELM_CHECK_WIDTYPE(obj, widtype);
335    Widget_Data *wd = elm_widget_data_get(obj);
336    if (!wd) return;
337    if (scale_up) *scale_up = wd->scale_up;
338    if (scale_down) *scale_down = wd->scale_down;
339 }
340
341 /**
342  * Set if the object is filled outside
343  *
344  * @param obj The image object
345  * @param fill_outside A bool to set if the object is filled outside
346  * (1 = filled, 0 = no filled)
347  *
348  * @ingroup Image
349  */
350 EAPI void
351 elm_image_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside)
352 {
353    ELM_CHECK_WIDTYPE(obj, widtype);
354    Widget_Data *wd = elm_widget_data_get(obj);
355
356    if (!wd) return;
357    wd->fill_outside = fill_outside;
358    _sizing_eval(obj);
359 }
360
361 /**
362  * Get if the object is filled outside
363  *
364  * @param obj The image object
365  * @return If the object is filled outside
366  *
367  * @ingroup Image
368  */
369 EAPI Eina_Bool
370 elm_image_fill_outside_get(const Evas_Object *obj)
371 {
372    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
373    Widget_Data *wd = elm_widget_data_get(obj);
374
375    if (!wd) return EINA_FALSE;
376    return wd->fill_outside;
377 }
378
379 /**
380  * Set the prescale size for the image
381  *
382  * @param obj The image object
383  * @param size The prescale size
384  *
385  * @ingroup Image
386  */
387 EAPI void
388 elm_image_prescale_set(Evas_Object *obj, int size)
389 {
390    ELM_CHECK_WIDTYPE(obj, widtype);
391    Widget_Data *wd = elm_widget_data_get(obj);
392
393    if (!wd) return;
394    _els_smart_icon_scale_size_set(wd->img, size);
395 }
396
397 /**
398  * Get the prescale size for the image
399  *
400  * @param obj The image object
401  * @return The prescale size
402  *
403  * @ingroup Image
404  */
405 EAPI int
406 elm_image_prescale_get(const Evas_Object *obj)
407 {
408    ELM_CHECK_WIDTYPE(obj, widtype) 0;
409    Widget_Data *wd = elm_widget_data_get(obj);
410
411    if (!wd) return 0;
412    return _els_smart_icon_scale_size_get(wd->img);
413 }
414
415 /**
416  * Set the image orient
417  *
418  * @param obj The image object
419  * @param orient The image orient
420  * (ELM_IMAGE_ORIENT_NONE, ELM_IMAGE_ROTATE_90_CW,
421  *  ELM_IMAGE_ROTATE_180_CW, ELM_IMAGE_ROTATE_90_CCW,
422  *  ELM_IMAGE_FLIP_HORIZONTAL,ELM_IMAGE_FLIP_VERTICAL,
423  *  ELM_IMAGE_FLIP_TRANSPOSE, ELM_IMAGE_FLIP_TRANSVERSE)
424  *
425  * @ingroup Image
426  */
427 EAPI void
428 elm_image_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
429 {
430    ELM_CHECK_WIDTYPE(obj, widtype);
431    Widget_Data *wd = elm_widget_data_get(obj);
432
433    if (!wd) return;
434    _els_smart_icon_orient_set(wd->img, orient);
435 }
436
437 /**
438  * Get the image orient
439  *
440  * @param obj The image object
441  * @return The image orient
442  * (ELM_IMAGE_ORIENT_NONE, ELM_IMAGE_ROTATE_90_CW,
443  *  ELM_IMAGE_ROTATE_180_CW, ELM_IMAGE_ROTATE_90_CCW,
444  *  ELM_IMAGE_FLIP_HORIZONTAL,ELM_IMAGE_FLIP_VERTICAL,
445  *  ELM_IMAGE_FLIP_TRANSPOSE, ELM_IMAGE_FLIP_TRANSVERSE)
446  *
447  * @ingroup Image
448  */
449 EAPI Elm_Image_Orient
450 elm_image_orient_get(const Evas_Object *obj)
451 {
452    ELM_CHECK_WIDTYPE(obj, widtype) ELM_IMAGE_ORIENT_NONE;
453    Widget_Data *wd = elm_widget_data_get(obj);
454    if (!wd) return ELM_IMAGE_ORIENT_NONE;
455    return _els_smart_icon_orient_get(wd->img);
456 }
457
458 /**
459  * Make the image 'editable'.
460  *
461  * This means the image is a valid drag target for drag and drop, and can be
462  * cut or pasted too.
463  *
464  * @param obj Image object.
465  * @param set Turn on or off editability.
466  *
467  * @ingroup Image
468  */
469 EAPI void
470 elm_image_editable_set(Evas_Object *obj, Eina_Bool set)
471 {
472    ELM_CHECK_WIDTYPE(obj, widtype);
473    Widget_Data *wd = elm_widget_data_get(obj);
474
475    if (!wd) return;
476    _els_smart_icon_edit_set(wd->img, set, obj);
477 }
478
479 /**
480  * Make the image 'editable'.
481  *
482  * This means the image is a valid drag target for drag and drop, and can be
483  * cut or pasted too.
484  *
485  * @param obj Image object.
486  * @return Editability.
487  */
488 EAPI Eina_Bool
489 elm_image_editable_get(const Evas_Object *obj)
490 {
491    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
492    Widget_Data *wd = elm_widget_data_get(obj);
493    if (!wd) return EINA_FALSE;
494    return _els_smart_icon_edit_get(wd->img);
495 }
496
497 /**
498  * Get the image object
499  *
500  * When you create a image with elm_image_add(). You can get this object (be
501  * careful to not manipulate it as it is under control of elementary), and use
502  * it to do things like get pixel data, save the image to a file, etc.
503  *
504  * @param obj The image object to get the inlined image from
505  * @return The inlined image object, or NULL if none exists
506  *
507  * @ingroup Image
508  */
509 EAPI Evas_Object *
510 elm_image_object_get(const Evas_Object *obj)
511 {
512    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
513    Widget_Data *wd = elm_widget_data_get(obj);
514    if (!wd) return NULL;
515    return _els_smart_icon_object_get(wd->img);
516 }
517
518 /**
519  * Enable/disable retaining up the aspect ratio of the image.
520  *
521  * @param obj The image object.
522  * @param retained Retaining or Non retaining.
523  *
524  * @ingroup Image
525  */
526 EAPI void
527 elm_image_aspect_ratio_retained_set(Evas_Object *obj, Eina_Bool retained)
528 {
529    ELM_CHECK_WIDTYPE(obj, widtype);
530    Widget_Data *wd = elm_widget_data_get(obj);
531    if (!wd) return;
532    return _els_smart_icon_aspect_ratio_retained_set(wd->img, retained);
533 }
534
535 /**
536  * Get if the object retains the aspect ratio.
537  *
538  * @param obj The image object.
539  * @return If the object retains the aspect ratio.
540  *
541  * @ingroup Image
542  */
543 EAPI Eina_Bool
544 elm_image_aspect_ratio_retained_get(const Evas_Object *obj)
545 {
546    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
547    Widget_Data *wd = elm_widget_data_get(obj);
548    if (!wd) return EINA_FALSE;
549    return _els_smart_icon_aspect_ratio_retained_get(wd->img);
550 }
551
552 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/