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