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