================================================================
[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    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
119
120    wd = ELM_NEW(Widget_Data);
121    e = evas_object_evas_get(parent);
122    if (!e) return NULL;
123    obj = elm_widget_add(e);
124    ELM_SET_WIDTYPE(widtype, "image");
125    elm_widget_type_set(obj, "image");
126    elm_widget_sub_object_add(parent, obj);
127    elm_widget_data_set(obj, wd);
128    elm_widget_del_hook_set(obj, _del_hook);
129    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
130    elm_widget_theme_hook_set(obj, _theme_hook);
131    elm_widget_can_focus_set(obj, EINA_FALSE);
132
133    wd->img = _els_smart_icon_add(e);
134    evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
135                                   _mouse_up, obj);
136    evas_object_repeat_events_set(wd->img, EINA_TRUE);
137    elm_widget_resize_object_set(obj, wd->img);
138
139    wd->smooth = EINA_TRUE;
140    wd->scale_up = EINA_TRUE;
141    wd->scale_down = EINA_TRUE;
142
143    _els_smart_icon_scale_size_set(wd->img, 0);
144
145    _sizing_eval(obj);
146    return obj;
147 }
148
149 /**
150  * Set the file that will be used as image
151  *
152  * @param obj The image object
153  * @param file The path to file that will be used as image
154  * @param group The group that the image belongs in edje file
155  *
156  * @return (1 = success, 0 = error)
157  *
158  * @ingroup Image
159  */
160 EAPI Eina_Bool
161 elm_image_file_set(Evas_Object *obj, const char *file, const char *group)
162 {
163    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
164    Widget_Data *wd = elm_widget_data_get(obj);
165    Eina_Bool ret;
166    const char *p;
167
168    if (!wd) return EINA_FALSE;
169    EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
170    if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
171      ret = _els_smart_icon_file_edje_set(wd->img, file, group);
172    else
173      ret = _els_smart_icon_file_key_set(wd->img, file, group);
174    _sizing_eval(obj);
175    return ret;
176 }
177
178 /**
179  * Get the file that will be used as image
180  *
181  * @param obj The image object
182  * @param file The path to file
183  * @param group The group that the image belongs in edje file
184  *
185  * @ingroup Image
186  */
187 EAPI void
188 elm_image_file_get(const Evas_Object *obj, const char **file, const char **group)
189 {
190    ELM_CHECK_WIDTYPE(obj, widtype);
191    Widget_Data *wd = elm_widget_data_get(obj);
192    if (!wd) return;
193    _els_smart_icon_file_get(wd->img, file, group);
194 }
195
196 /**
197  * Set the smooth effect for a image
198  *
199  * @param obj The image object
200  * @param smooth A bool to set (or no) smooth effect
201  * (1 = smooth, 0 = not smooth)
202  *
203  * @ingroup Image
204  */
205 EAPI void
206 elm_image_smooth_set(Evas_Object *obj, Eina_Bool smooth)
207 {
208    ELM_CHECK_WIDTYPE(obj, widtype);
209    Widget_Data *wd = elm_widget_data_get(obj);
210
211    if (!wd) return;
212    wd->smooth = smooth;
213    _sizing_eval(obj);
214 }
215
216 /**
217  * Get the smooth effect for a image
218  *
219  * @param obj The image object
220  * @return If setted smooth effect
221  *
222  * @ingroup Image
223  */
224 EAPI Eina_Bool
225 elm_image_smooth_get(const Evas_Object *obj)
226 {
227    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
228    Widget_Data *wd = elm_widget_data_get(obj);
229
230    if (!wd) return EINA_FALSE;
231    return wd->smooth;
232 }
233
234 /**
235  * Gets the current size of the image.
236  *
237  * Either width or height (or both) may be NULL.
238  *
239  * On error, neither w or h will be written too.
240  *
241  * @param obj The image object.
242  * @param w Pointer to store width, or NULL.
243  * @param h Pointer to store height, or NULL.
244  */
245 EAPI void
246 elm_image_object_size_get(const Evas_Object *obj, int *w, int *h)
247 {
248    ELM_CHECK_WIDTYPE(obj, widtype);
249    Widget_Data *wd = elm_widget_data_get(obj);
250
251    if (!wd) return;
252    _els_smart_icon_size_get(wd->img, w, h);
253 }
254
255 /**
256  * Set if the object are scalable
257  *
258  * @param obj The image object.
259  * @param no_scale A bool to set scale (or no).
260  * (1 = no_scale, 0 = scale)
261  *
262  * @ingroup Image
263  */
264 EAPI void
265 elm_image_no_scale_set(Evas_Object *obj, Eina_Bool no_scale)
266 {
267    ELM_CHECK_WIDTYPE(obj, widtype);
268    Widget_Data *wd = elm_widget_data_get(obj);
269
270    if (!wd) return;
271    wd->no_scale = no_scale;
272    _sizing_eval(obj);
273
274 }
275
276 /**
277  * Get if the object isn't scalable
278  *
279  * @param obj The image object
280  * @return If isn't scalable
281  *
282  * @ingroup Image
283  */
284 EAPI Eina_Bool
285 elm_image_no_scale_get(const Evas_Object *obj)
286 {
287    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
288    Widget_Data *wd = elm_widget_data_get(obj);
289    if (!wd) return EINA_FALSE;
290    return wd->no_scale;
291 }
292
293 /**
294  * Set if the object is (up/down) scalable
295  *
296  * @param obj The image object
297  * @param scale_up A bool to set if the object is scalable up
298  * @param scale_down A bool to set if the object is scalable down
299  *
300  * @ingroup Image
301  */
302 EAPI void
303 elm_image_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down)
304 {
305    ELM_CHECK_WIDTYPE(obj, widtype);
306    Widget_Data *wd = elm_widget_data_get(obj);
307
308    if (!wd) return;
309    wd->scale_up = scale_up;
310    wd->scale_down = scale_down;
311    _sizing_eval(obj);
312 }
313
314 /**
315  * Get if the object is (up/down) scalable
316  *
317  * @param obj The image object
318  * @param scale_up A bool to set if the object is scalable up
319  * @param scale_down A bool to set if the object is scalable down
320  *
321  * @ingroup Image
322  */
323 EAPI void
324 elm_image_scale_get(const Evas_Object *obj, Eina_Bool *scale_up, Eina_Bool *scale_down)
325 {
326    ELM_CHECK_WIDTYPE(obj, widtype);
327    Widget_Data *wd = elm_widget_data_get(obj);
328    if (!wd) return;
329    if (scale_up) *scale_up = wd->scale_up;
330    if (scale_down) *scale_down = wd->scale_down;
331 }
332
333 /**
334  * Set if the object is filled outside
335  *
336  * @param obj The image object
337  * @param fill_outside A bool to set if the object is filled outside
338  * (1 = filled, 0 = no filled)
339  *
340  * @ingroup Image
341  */
342 EAPI void
343 elm_image_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside)
344 {
345    ELM_CHECK_WIDTYPE(obj, widtype);
346    Widget_Data *wd = elm_widget_data_get(obj);
347
348    if (!wd) return;
349    wd->fill_outside = fill_outside;
350    _sizing_eval(obj);
351 }
352
353 /**
354  * Get if the object is filled outside
355  *
356  * @param obj The image object
357  * @return If the object is filled outside
358  *
359  * @ingroup Image
360  */
361 EAPI Eina_Bool
362 elm_image_fill_outside_get(const Evas_Object *obj)
363 {
364    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
365    Widget_Data *wd = elm_widget_data_get(obj);
366
367    if (!wd) return EINA_FALSE;
368    return wd->fill_outside;
369 }
370
371 /**
372  * Set the prescale size for the image
373  *
374  * @param obj The image object
375  * @param size The prescale size
376  *
377  * @ingroup Image
378  */
379 EAPI void
380 elm_image_prescale_set(Evas_Object *obj, int size)
381 {
382    ELM_CHECK_WIDTYPE(obj, widtype);
383    Widget_Data *wd = elm_widget_data_get(obj);
384
385    if (!wd) return;
386    _els_smart_icon_scale_size_set(wd->img, size);
387 }
388
389 /**
390  * Get the prescale size for the image
391  *
392  * @param obj The image object
393  * @return The prescale size
394  *
395  * @ingroup Image
396  */
397 EAPI int
398 elm_image_prescale_get(const Evas_Object *obj)
399 {
400    ELM_CHECK_WIDTYPE(obj, widtype) 0;
401    Widget_Data *wd = elm_widget_data_get(obj);
402
403    if (!wd) return 0;
404    return _els_smart_icon_scale_size_get(wd->img);
405 }
406
407 /**
408  * Set the image orient
409  *
410  * @param obj The image object
411  * @param orient The image orient
412  * (ELM_IMAGE_ORIENT_NONE, ELM_IMAGE_ROTATE_90_CW,
413  *  ELM_IMAGE_ROTATE_180_CW, ELM_IMAGE_ROTATE_90_CCW,
414  *  ELM_IMAGE_FLIP_HORIZONTAL,ELM_IMAGE_FLIP_VERTICAL,
415  *  ELM_IMAGE_FLIP_TRANSPOSE, ELM_IMAGE_FLIP_TRANSVERSE)
416  *
417  * @ingroup Image
418  */
419 EAPI void
420 elm_image_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
421 {
422    ELM_CHECK_WIDTYPE(obj, widtype);
423    Widget_Data *wd = elm_widget_data_get(obj);
424
425    if (!wd) return;
426    _els_smart_icon_orient_set(wd->img, orient);
427 }
428
429 /**
430  * Get the image orient
431  *
432  * @param obj The image object
433  * @return The image orient
434  * (ELM_IMAGE_ORIENT_NONE, ELM_IMAGE_ROTATE_90_CW,
435  *  ELM_IMAGE_ROTATE_180_CW, ELM_IMAGE_ROTATE_90_CCW,
436  *  ELM_IMAGE_FLIP_HORIZONTAL,ELM_IMAGE_FLIP_VERTICAL,
437  *  ELM_IMAGE_FLIP_TRANSPOSE, ELM_IMAGE_FLIP_TRANSVERSE)
438  *
439  * @ingroup Image
440  */
441 EAPI Elm_Image_Orient
442 elm_image_orient_get(const Evas_Object *obj)
443 {
444    ELM_CHECK_WIDTYPE(obj, widtype) ELM_IMAGE_ORIENT_NONE;
445    Widget_Data *wd = elm_widget_data_get(obj);
446    if (!wd) return ELM_IMAGE_ORIENT_NONE;
447    return _els_smart_icon_orient_get(wd->img);
448 }
449
450 /**
451  * Make the image 'editable'.
452  *
453  * This means the image is a valid drag target for drag and drop, and can be
454  * cut or pasted too.
455  *
456  * @param obj Image object.
457  * @param set Turn on or off editability.
458  */
459 EAPI void
460 elm_image_editable_set(Evas_Object *obj, Eina_Bool set)
461 {
462    ELM_CHECK_WIDTYPE(obj, widtype);
463    Widget_Data *wd = elm_widget_data_get(obj);
464
465    if (!wd) return;
466    _els_smart_icon_edit_set(wd->img, set, obj);
467 }
468
469 /**
470  * Make the image 'editable'.
471  *
472  * This means the image is a valid drag target for drag and drop, and can be
473  * cut or pasted too.
474  *
475  * @param obj Image object.
476  * @return Editability.
477  */
478 EAPI Eina_Bool
479 elm_image_editable_get(const Evas_Object *obj)
480 {
481    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
482    Widget_Data *wd = elm_widget_data_get(obj);
483    if (!wd) return EINA_FALSE;
484    return _els_smart_icon_edit_get(wd->img);
485 }
486
487
488 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/