Formatting.
[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, *icon;
16    const char *label;
17 };
18
19 static void _del_hook(Evas_Object *obj);
20 static void _theme_hook(Evas_Object *obj);
21 static void _disable_hook(Evas_Object *obj);
22 static void _sizing_eval(Evas_Object *obj);
23 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
24 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
25 static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
26
27 static void
28 _del_hook(Evas_Object *obj)
29 {
30    Widget_Data *wd = elm_widget_data_get(obj);
31    if (!wd) return;
32    if (wd->label) eina_stringshare_del(wd->label);
33    free(wd);
34 }
35
36 static void
37 _theme_hook(Evas_Object *obj)
38 {
39    Widget_Data *wd = elm_widget_data_get(obj);
40    if (!wd) return;
41    _elm_theme_set(wd->btn, "button", "base", elm_widget_style_get(obj));
42    if (wd->icon)
43      edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
44    if (wd->label)
45      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
46    else
47      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
48    if (wd->icon)
49      edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
50    else
51      edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
52    edje_object_part_text_set(wd->btn, "elm.text", wd->label);
53    edje_object_message_signal_process(wd->btn);
54    edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) * _elm_config->scale);
55    _sizing_eval(obj);
56 }
57
58 static void
59 _disable_hook(Evas_Object *obj)
60 {
61    Widget_Data *wd = elm_widget_data_get(obj);
62    if (elm_widget_disabled_get(obj))
63      edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
64    else
65      edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
66 }
67
68 static void
69 _sizing_eval(Evas_Object *obj)
70 {
71    Widget_Data *wd = elm_widget_data_get(obj);
72    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
73
74    if (!wd) return;
75    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
76    edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
77    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
78    evas_object_size_hint_min_set(obj, minw, minh);
79    evas_object_size_hint_max_set(obj, maxw, maxh);
80 }
81
82 static void
83 _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
84 {
85    Widget_Data *wd = elm_widget_data_get(data);
86    if (!wd) return;
87    if (obj != wd->icon) return;
88    edje_object_part_swallow(wd->btn, "elm.swallow.content", obj);
89    _sizing_eval(data);
90 }
91
92 static void
93 _sub_del(void *data, Evas_Object *obj, void *event_info)
94 {
95    Widget_Data *wd = elm_widget_data_get(obj);
96    Evas_Object *sub = event_info;
97    if (!wd) return;
98    if (sub == wd->icon)
99      {
100         edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
101         evas_object_event_callback_del(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, 
102                                        _changed_size_hints);
103         wd->icon = NULL;
104         edje_object_message_signal_process(wd->btn);
105         _sizing_eval(obj);
106      }
107 }
108
109 static void
110 _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
111 {
112    Widget_Data *wd = elm_widget_data_get(data);
113    if (!wd) return;
114    evas_object_smart_callback_call(data, "clicked", NULL);
115 }
116
117 /**
118  * Add a new button to the parent
119  * @param parent The parent object
120  * @return The new object or NULL if it cannot be created
121  *
122  * @ingroup Button
123  */
124 EAPI Evas_Object *
125 elm_button_add(Evas_Object *parent)
126 {
127    Evas_Object *obj;
128    Evas *e;
129    Widget_Data *wd;
130
131    wd = ELM_NEW(Widget_Data);
132    e = evas_object_evas_get(parent);
133    obj = elm_widget_add(e);
134    elm_widget_type_set(obj, "button");
135    elm_widget_sub_object_add(parent, obj);
136    elm_widget_data_set(obj, wd);
137    elm_widget_del_hook_set(obj, _del_hook);
138    elm_widget_theme_hook_set(obj, _theme_hook);
139    elm_widget_disable_hook_set(obj, _disable_hook);
140
141    wd->btn = edje_object_add(e);
142    _elm_theme_set(wd->btn, "button", "base", "default");
143    edje_object_signal_callback_add(wd->btn, "elm,action,click", "", 
144                                    _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    Evas_Coord mw, mh;
166
167    if (!wd) return;
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      }
174    else
175      {
176         wd->label = NULL;
177         edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
178      }
179    edje_object_message_signal_process(wd->btn);
180    edje_object_part_text_set(wd->btn, "elm.text", label);
181    _sizing_eval(obj);
182 }
183
184 EAPI const char*
185 elm_button_label_get(Evas_Object *obj)
186 {
187    Widget_Data *wd = elm_widget_data_get(obj);
188    if (!wd) return NULL;
189    return wd->label;
190 }
191
192 /**
193  * Set the icon used for the button
194  *
195  * @param obj The button object
196  * @param icon  The image for the button
197  *
198  * @ingroup Button
199  */
200 EAPI void
201 elm_button_icon_set(Evas_Object *obj, Evas_Object *icon)
202 {
203    Widget_Data *wd = elm_widget_data_get(obj);
204    if (!wd) return;
205    if ((wd->icon != icon) && (wd->icon))
206      elm_widget_sub_object_del(obj, wd->icon);
207    if ((icon) && (wd->icon != icon))
208      {
209         wd->icon = icon;
210         elm_widget_sub_object_add(obj, icon);
211         edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
212         edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
213         evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
214                                        _changed_size_hints, obj);
215         edje_object_message_signal_process(wd->btn);
216         _sizing_eval(obj);
217      }
218    else
219      wd->icon = icon;
220 }
221
222 EAPI Evas_Object *
223 elm_button_icon_get(Evas_Object *obj)
224 {
225    Widget_Data *wd = elm_widget_data_get(obj);
226    if (!wd) return NULL;
227    return wd->icon;
228 }
229
230 /**
231  * Set the button style
232  *
233  * @param obj The button object
234  * @param style The style for the button
235  *
236  * @ingroup Button
237  */
238 EAPI void
239 elm_button_style_set(Evas_Object *obj, const char *style)
240 {
241    elm_widget_style_set(obj, style);
242 }