Improve documentation for Evas, Ecore, Edje and Elementary.
[platform/upstream/elementary.git] / src / lib / elm_button.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Button Button
6  *
7  * This is a push-button. Press it and run some function. It can contain
8  * a simple label and icon object.
9  */
10
11 typedef struct _Widget_Data Widget_Data;
12
13 struct _Widget_Data
14 {
15    Evas_Object *btn;
16    Evas_Object *icon;
17    const char *label;
18 };
19
20 static void _del_hook(Evas_Object *obj);
21 static void _theme_hook(Evas_Object *obj);
22 static void _disable_hook(Evas_Object *obj);
23 static void _sizing_eval(Evas_Object *obj);
24 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
25 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
26 static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
27
28 static void
29 _del_hook(Evas_Object *obj)
30 {
31    Widget_Data *wd = elm_widget_data_get(obj);
32    if (!wd) return;
33    if (wd->label) eina_stringshare_del(wd->label);
34    free(wd);
35 }
36
37 static void
38 _theme_hook(Evas_Object *obj)
39 {
40    Widget_Data *wd = elm_widget_data_get(obj);
41    if (!wd) return;
42    _elm_theme_set(wd->btn, "button", "base", elm_widget_style_get(obj));
43    if (wd->icon)
44      edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
45    if (wd->label)
46      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
47    else
48      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
49    if (wd->icon)
50      edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
51    else
52      edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
53    edje_object_part_text_set(wd->btn, "elm.text", wd->label);
54    edje_object_message_signal_process(wd->btn);
55    edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) * _elm_config->scale);
56    _sizing_eval(obj);
57 }
58
59 static void
60 _disable_hook(Evas_Object *obj)
61 {
62    Widget_Data *wd = elm_widget_data_get(obj);
63    if (elm_widget_disabled_get(obj))
64      edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
65    else
66      edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
67 }
68
69 static void
70 _sizing_eval(Evas_Object *obj)
71 {
72    Widget_Data *wd = elm_widget_data_get(obj);
73    if (!wd) return;
74    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
75
76    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
77    edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
78    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
79    evas_object_size_hint_min_set(obj, minw, minh);
80    evas_object_size_hint_max_set(obj, maxw, maxh);
81 }
82
83 static void
84 _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
85 {
86    Widget_Data *wd = elm_widget_data_get(data);
87    if (!wd) return;
88    if (obj != wd->icon) return;
89    edje_object_part_swallow(wd->btn, "elm.swallow.content", obj);
90    _sizing_eval(data);
91 }
92
93 static void
94 _sub_del(void *data, Evas_Object *obj, void *event_info)
95 {
96    Widget_Data *wd = elm_widget_data_get(obj);
97    if (!wd) return;
98    Evas_Object *sub = event_info;
99    if (sub == wd->icon)
100      {
101         edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
102         evas_object_event_callback_del
103           (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints);
104         wd->icon = NULL;
105         edje_object_message_signal_process(wd->btn);
106         _sizing_eval(obj);
107      }
108 }
109
110 static void
111 _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
112 {
113    Widget_Data *wd = elm_widget_data_get(data);
114    if (!wd) return;
115    evas_object_smart_callback_call(data, "clicked", NULL);
116 }
117
118 /**
119  * Add a new button to the parent
120  * @param parent The parent object
121  * @return The new object or NULL if it cannot be created
122  *
123  * @ingroup Button
124  */
125 EAPI Evas_Object *
126 elm_button_add(Evas_Object *parent)
127 {
128    Evas_Object *obj;
129    Evas *e;
130    Widget_Data *wd;
131
132    wd = ELM_NEW(Widget_Data);
133    e = evas_object_evas_get(parent);
134    obj = elm_widget_add(e);
135    elm_widget_type_set(obj, "button");
136    elm_widget_sub_object_add(parent, obj);
137    elm_widget_data_set(obj, wd);
138    elm_widget_del_hook_set(obj, _del_hook);
139    elm_widget_theme_hook_set(obj, _theme_hook);
140    elm_widget_disable_hook_set(obj, _disable_hook);
141
142    wd->btn = edje_object_add(e);
143    _elm_theme_set(wd->btn, "button", "base", "default");
144    edje_object_signal_callback_add(wd->btn, "elm,action,click", "", _signal_clicked, obj);
145    elm_widget_resize_object_set(obj, wd->btn);
146
147    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
148
149    _sizing_eval(obj);
150    return obj;
151 }
152
153 /**
154  * Set the label used in the button
155  *
156  * @param obj The button object
157  * @param label The text will be written on the button 
158  *
159  * @ingroup Button
160  */
161 EAPI void
162 elm_button_label_set(Evas_Object *obj, const char *label)
163 {
164    Widget_Data *wd = elm_widget_data_get(obj);
165    if (!wd) return;
166    Evas_Coord mw, mh;
167
168    if (wd->label) eina_stringshare_del(wd->label);
169    if (label)
170      {
171         wd->label = eina_stringshare_add(label);
172         edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
173         edje_object_message_signal_process(wd->btn);
174      }
175    else
176      {
177         wd->label = NULL;
178         edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
179         edje_object_message_signal_process(wd->btn);
180      }
181    edje_object_part_text_set(wd->btn, "elm.text", label);
182    _sizing_eval(obj);
183 }
184
185 EAPI const char*
186 elm_button_label_get(Evas_Object *obj)
187 {
188    Widget_Data *wd = elm_widget_data_get(obj);
189    if (!wd) return NULL;
190
191    return wd->label;
192 }
193
194 /**
195  * Set the icon used for the button
196  *
197  * @param obj The button object
198  * @param icon  The image for the button
199  *
200  * @ingroup Button
201  */
202 EAPI void
203 elm_button_icon_set(Evas_Object *obj, Evas_Object *icon)
204 {
205    Widget_Data *wd = elm_widget_data_get(obj);
206    if (!wd) return;
207    if ((wd->icon != icon) && (wd->icon))
208      elm_widget_sub_object_del(obj, wd->icon);
209    if ((icon) && (wd->icon != icon))
210      {
211         wd->icon = icon;
212         elm_widget_sub_object_add(obj, icon);
213         edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
214         edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
215         evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
216                                        _changed_size_hints, obj);
217         edje_object_message_signal_process(wd->btn);
218         _sizing_eval(obj);
219      }
220    else
221      wd->icon = icon;
222 }
223
224 EAPI Evas_Object *
225 elm_button_icon_get(Evas_Object *obj)
226 {
227    Widget_Data *wd = elm_widget_data_get(obj);
228    if (!wd) return NULL;
229    return wd->icon;
230 }
231
232 /**
233  * Set the button style
234  *
235  * @param obj The button object
236  * @param style The style for the button
237  *
238  * @ingroup Button
239  */
240 EAPI void
241 elm_button_style_set(Evas_Object *obj, const char *style)
242 {
243    elm_widget_style_set(obj, style);
244 }