d88b30abe2ff45ccc7cb77ae74969edd2c74f6f0
[framework/uifw/elementary.git] / src / lib / elm_icon.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Icon Icon
6  * @ingroup Elementary
7  *
8  * A standard icon 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 icon
16  */
17
18 typedef struct _Widget_Data Widget_Data;
19
20 struct _Widget_Data
21 {
22    Evas_Object *img;
23    const char *stdicon;
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    if (wd->stdicon) eina_stringshare_del(wd->stdicon);
44    free(wd);
45 }
46
47 static void
48 _theme_hook(Evas_Object *obj)
49 {
50    Widget_Data *wd = elm_widget_data_get(obj);
51    if (!wd) return;
52    if (wd->stdicon)
53      _elm_theme_object_icon_set(obj, wd->img, wd->stdicon, elm_widget_style_get(obj));
54    _sizing_eval(obj);
55 }
56
57 static void
58 _sizing_eval(Evas_Object *obj)
59 {
60    Widget_Data *wd = elm_widget_data_get(obj);
61    if (!wd) return;
62    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
63    int w, h;
64
65    _els_smart_icon_size_get(wd->img, &w, &h);
66    _els_smart_icon_scale_up_set(wd->img, wd->scale_up);
67    _els_smart_icon_scale_down_set(wd->img, wd->scale_down);
68    _els_smart_icon_smooth_scale_set(wd->img, wd->smooth);
69    _els_smart_icon_fill_inside_set(wd->img, !(wd->fill_outside));
70    if (wd->no_scale) _els_smart_icon_scale_set(wd->img, 1.0);
71    else
72      {
73         _els_smart_icon_scale_set(wd->img, elm_widget_scale_get(obj) *
74                                   _elm_config->scale);
75         _els_smart_icon_size_get(wd->img, &w, &h);
76      }
77    if (!wd->scale_down)
78      {
79         minw = w;
80         minh = h;
81      }
82    if (!wd->scale_up)
83      {
84         maxw = w;
85         maxh = h;
86      }
87    evas_object_size_hint_min_set(obj, minw, minh);
88    evas_object_size_hint_max_set(obj, maxw, maxh);
89 }
90
91 static void
92 _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
93 {
94    Evas_Event_Mouse_Up *ev = event_info;
95    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
96    evas_object_smart_callback_call(data, "clicked", event_info);
97 }
98
99 /**
100  * Add a new icon to the parent
101  *
102  * @param parent The parent object
103  * @return The new object or NULL if it cannot be created
104  *
105  * @ingroup Icon
106  */
107 EAPI Evas_Object *
108 elm_icon_add(Evas_Object *parent)
109 {
110    Evas_Object *obj;
111    Evas *e;
112    Widget_Data *wd;
113
114    wd = ELM_NEW(Widget_Data);
115    e = evas_object_evas_get(parent);
116    obj = elm_widget_add(e);
117    ELM_SET_WIDTYPE(widtype, "icon");
118    elm_widget_type_set(obj, "icon");
119    elm_widget_can_focus_set(obj, EINA_FALSE);
120    elm_widget_sub_object_add(parent, obj);
121    elm_widget_data_set(obj, wd);
122    elm_widget_del_hook_set(obj, _del_hook);
123    elm_widget_theme_hook_set(obj, _theme_hook);
124
125    wd->img = _els_smart_icon_add(e);
126    evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
127                                   _mouse_up, obj);
128    evas_object_repeat_events_set(wd->img, 1);
129    elm_widget_resize_object_set(obj, wd->img);
130
131    wd->smooth = EINA_TRUE;
132    wd->scale_up = EINA_TRUE;
133    wd->scale_down = EINA_TRUE;
134
135    _sizing_eval(obj);
136    return obj;
137 }
138
139 /**
140  * Set the file that will be used as icon
141  *
142  * @param obj The icon object
143  * @param file The path to file that will be used as icon
144  * @param group The group that the icon belongs in edje file
145  *
146  * @return (1 = sucess, 0 = error)
147  *
148  * @ingroup Icon
149  */
150 EAPI Eina_Bool
151 elm_icon_file_set(Evas_Object *obj, const char *file, const char *group)
152 {
153    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
154    Widget_Data *wd = elm_widget_data_get(obj);
155    Eina_Bool ret;
156    const char *p;
157
158    if ((!wd) || (!file)) return EINA_FALSE;
159    if (wd->stdicon) eina_stringshare_del(wd->stdicon);
160    wd->stdicon = NULL;
161    if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
162      ret = _els_smart_icon_file_edje_set(wd->img, file, group);
163    else
164      ret = _els_smart_icon_file_key_set(wd->img, file, group);
165    _sizing_eval(obj);
166    return ret;
167 }
168
169 /**
170  * Set the theme, as standard, for a icon
171  *
172  * @param obj The icon object
173  * @param name The theme name
174  *
175  * @return (1 = sucess, 0 = error)
176  *
177  * @ingroup Icon
178  */
179 EAPI Eina_Bool
180 elm_icon_standard_set(Evas_Object *obj, const char *name)
181 {
182    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
183    Widget_Data *wd = elm_widget_data_get(obj);
184    Eina_Bool ret;
185
186    if ((!wd) || (!name)) return EINA_FALSE;
187    eina_stringshare_replace(&wd->stdicon, name);
188    ret = _elm_theme_object_icon_set(obj, wd->img, name, "default");
189    _sizing_eval(obj);
190    return ret;
191 }
192
193 /**
194  * Set the smooth effect for a icon
195  *
196  * @param obj The icon object
197  * @param smooth A bool to set (or no) smooth effect
198  * (1 = smooth, 0 = not smooth)
199  *
200  * @ingroup Icon
201  */
202 EAPI void
203 elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth)
204 {
205    ELM_CHECK_WIDTYPE(obj, widtype);
206    Widget_Data *wd = elm_widget_data_get(obj);
207
208    if (!wd) return;
209    wd->smooth = smooth;
210    _sizing_eval(obj);
211 }
212
213 /**
214  * Set if the object are scalable
215  *
216  * @param obj The icon object
217  * @param no_scale A bool to set scale (or no)
218  * (1 = no_scale, 0 = scale)
219  *
220  * @ingroup Icon
221  */
222 EAPI void
223 elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale)
224 {
225    ELM_CHECK_WIDTYPE(obj, widtype);
226    Widget_Data *wd = elm_widget_data_get(obj);
227
228    if (!wd) return;
229    wd->no_scale = no_scale;
230    _sizing_eval(obj);
231 }
232
233 /**
234  * Set if the object is (up/down) scalable
235  *
236  * @param obj The icon object
237  * @param scale_up A bool to set if the object is scalable up
238  * @param scale_down A bool to set if the object is scalable down
239  *
240  * @ingroup Icon
241  */
242 EAPI void
243 elm_icon_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down)
244 {
245    ELM_CHECK_WIDTYPE(obj, widtype);
246    Widget_Data *wd = elm_widget_data_get(obj);
247
248    if (!wd) return;
249    wd->scale_up = scale_up;
250    wd->scale_down = scale_down;
251    _sizing_eval(obj);
252 }
253
254 /**
255  * Set if the object is filled outside
256  *
257  * @param obj The icon object
258  * @param fill_outside A bool to set if the object is filled outside
259  * (1 = filled, 0 = no filled)
260  *
261  * @ingroup Icon
262  */
263 EAPI void
264 elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside)
265 {
266    ELM_CHECK_WIDTYPE(obj, widtype);
267    Widget_Data *wd = elm_widget_data_get(obj);
268
269    if (!wd) return;
270    wd->fill_outside = fill_outside;
271    _sizing_eval(obj);
272 }
273
274
275 /**
276  * Set the prescale size for the icon
277  *
278  * @param obj The icon object
279  * @param size The prescale size
280  *
281  * @ingroup Icon
282  */
283 EAPI void
284 elm_icon_prescale_set(Evas_Object *obj, int size)
285 {
286    ELM_CHECK_WIDTYPE(obj, widtype);
287    Widget_Data *wd = elm_widget_data_get(obj);
288
289    if (!wd) return;
290    _els_smart_icon_scale_size_set(wd->img, size);
291 }
292
293