Updated changelog
[profile/ivi/lemolo.git] / utils / simple-popup.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include <Elementary.h>
5
6 #include "simple-popup.h"
7 #include "util.h"
8
9 typedef struct _Simple_Popup
10 {
11         Evas_Object *popup;
12         Evas_Object *box;
13         Evas_Object *message;
14         Evas_Object *entry;
15         Ecore_Timer *recalc_timer; /* HACK */
16 } Simple_Popup;
17
18 static void _popup_close(void *data, Evas_Object *bt __UNUSED__,
19                                 void *event __UNUSED__)
20 {
21         Evas_Object *popup = data;
22         evas_object_del(popup);
23 }
24
25 void simple_popup_title_set(Evas_Object *p, const char *title)
26 {
27         if (title) {
28                 elm_object_part_text_set(p, "elm.text.title", title);
29                 elm_object_signal_emit(p, "show,title", "gui");
30         } else {
31                 elm_object_part_text_set(p, "elm.text.title", "");
32                 elm_object_signal_emit(p, "hide,title", "gui");
33         }
34 }
35
36 /* HACK: force recalc from an idler to fix elm_entry problem */
37 static Eina_Bool _simple_popup_entries_reeval(void *data)
38 {
39         Simple_Popup *ctx = data;
40         if (ctx->message)
41                 elm_entry_calc_force(ctx->message);
42         if (ctx->entry)
43                 elm_entry_calc_force(ctx->entry);
44         ctx->recalc_timer = NULL;
45         return EINA_FALSE;
46 }
47
48 static void _simple_popup_timer_cancel_if_needed(Simple_Popup *ctx)
49 {
50         if (!ctx->recalc_timer)
51                 return;
52         if (ctx->message || ctx->entry)
53                 return;
54         ecore_timer_del(ctx->recalc_timer);
55         ctx->recalc_timer = NULL;
56 }
57
58 static void _simple_popup_message_del(void *data, Evas *e __UNUSED__,
59                                                 Evas_Object *en __UNUSED__,
60                                                 void *einfo __UNUSED__)
61 {
62         Simple_Popup *ctx = data;
63         ctx->message = NULL;
64         _simple_popup_timer_cancel_if_needed(ctx);
65 }
66
67 static void _simple_popup_entry_del(void *data, Evas *e __UNUSED__,
68                                         Evas_Object *en __UNUSED__,
69                                         void *einfo __UNUSED__)
70 {
71         Simple_Popup *ctx = data;
72         ctx->entry = NULL;
73         _simple_popup_timer_cancel_if_needed(ctx);
74 }
75
76 static void _simple_popup_reeval_content(Simple_Popup *ctx)
77 {
78         if ((!ctx->message) && (!ctx->entry)) {
79                 elm_object_part_content_unset(ctx->popup,
80                                                 "elm.swallow.content");
81                 elm_object_signal_emit(ctx->popup, "hide,content", "gui");
82                 evas_object_hide(ctx->box);
83                 return;
84         }
85
86         elm_box_unpack_all(ctx->box);
87         if (ctx->message) {
88                 elm_box_pack_end(ctx->box, ctx->message);
89                 evas_object_show(ctx->message);
90         }
91         if (ctx->entry) {
92                 elm_box_pack_end(ctx->box, ctx->entry);
93                 evas_object_show(ctx->entry);
94         }
95
96         elm_object_part_content_set(ctx->popup, "elm.swallow.content",
97                                         ctx->box);
98         elm_object_signal_emit(ctx->popup, "show,content", "gui");
99
100         /* HACK: elm_entry is not evaluating properly and the text is
101          * not centered as it should be. Then we must force a
102          * calculation from an timer.
103          */
104         if (ctx->recalc_timer)
105                 ecore_timer_del(ctx->recalc_timer);
106         ctx->recalc_timer = ecore_timer_add(
107                 0.02, _simple_popup_entries_reeval, ctx);
108 }
109
110 void simple_popup_message_set(Evas_Object *p, const char *msg)
111 {
112         Simple_Popup *ctx = evas_object_data_get(p, "simple_popup");
113         Evas_Object *en;
114
115         EINA_SAFETY_ON_NULL_RETURN(ctx);
116
117         if (!msg) {
118                 if (ctx->message)
119                         evas_object_del(ctx->message);
120                 _simple_popup_reeval_content(ctx);
121                 return;
122         }
123
124         if (ctx->message)
125                 en = ctx->message;
126         else {
127                 en = ctx->message = elm_entry_add(p);
128                 elm_object_style_set(en, "dialer-popup");
129                 elm_entry_editable_set(en, EINA_FALSE);
130                 elm_entry_scrollable_set(en, EINA_TRUE);
131 #ifdef HAVE_TIZEN
132                 /* old, deprecated API */
133                 elm_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF,
134                                                 ELM_SCROLLER_POLICY_AUTO);
135 #else
136                 elm_scroller_policy_set(en, ELM_SCROLLER_POLICY_OFF,
137                                         ELM_SCROLLER_POLICY_AUTO);
138 #endif
139
140                 evas_object_event_callback_add(en, EVAS_CALLBACK_DEL,
141                                         _simple_popup_message_del,
142                                         ctx);
143                 evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND,
144                                                         EVAS_HINT_EXPAND);
145                 evas_object_size_hint_align_set(en, EVAS_HINT_FILL,
146                                                 EVAS_HINT_FILL);
147         }
148
149         elm_object_text_set(en, msg);
150         _simple_popup_reeval_content(ctx);
151 }
152
153 void simple_popup_entry_enable(Evas_Object *p)
154 {
155         Simple_Popup *ctx = evas_object_data_get(p, "simple_popup");
156         Evas_Object *en;
157
158         EINA_SAFETY_ON_NULL_RETURN(ctx);
159
160         if (ctx->entry)
161                 return;
162         en = ctx->entry = elm_entry_add(p);
163         elm_object_style_set(en, "dialer-popup-editable");
164         elm_entry_editable_set(en, EINA_TRUE);
165         elm_entry_scrollable_set(en, EINA_TRUE);
166 #ifdef HAVE_TIZEN
167         /* old, deprecated API */
168         elm_entry_scrollbar_policy_set(en, ELM_SCROLLER_POLICY_OFF,
169                                         ELM_SCROLLER_POLICY_AUTO);
170 #else
171         elm_scroller_policy_set(en, ELM_SCROLLER_POLICY_OFF,
172                                 ELM_SCROLLER_POLICY_AUTO);
173 #endif
174
175         evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND,
176                                                 EVAS_HINT_EXPAND);
177         evas_object_size_hint_align_set(en, EVAS_HINT_FILL,
178                                         EVAS_HINT_FILL);
179
180         evas_object_event_callback_add(en, EVAS_CALLBACK_DEL,
181                                         _simple_popup_entry_del,
182                                         ctx);
183         _simple_popup_reeval_content(ctx);
184 }
185
186 void simple_popup_entry_disable(Evas_Object *p)
187 {
188         Simple_Popup *ctx = evas_object_data_get(p, "simple_popup");
189         EINA_SAFETY_ON_NULL_RETURN(ctx);
190         if (!ctx->entry)
191                 return;
192         evas_object_del(ctx->entry);
193         _simple_popup_reeval_content(ctx);
194 }
195
196 const char *simple_popup_entry_get(const Evas_Object *p)
197 {
198         Simple_Popup *ctx = evas_object_data_get(p, "simple_popup");
199         EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
200         EINA_SAFETY_ON_NULL_RETURN_VAL(ctx->entry, NULL);
201         return elm_object_text_get(ctx->entry);
202 }
203
204 void simple_popup_button_dismiss_set(Evas_Object *p)
205 {
206         simple_popup_buttons_set(p,
207                                         "Dismiss",
208                                         "dialer",
209                                         _popup_close,
210                                         NULL, NULL, NULL,
211                                         p);
212 }
213
214 void simple_popup_buttons_set(Evas_Object *p,
215                                         const char *b1_label,
216                                         const char *b1_class,
217                                         Evas_Smart_Cb b1_cb,
218                                         const char *b2_label,
219                                         const char *b2_class,
220                                         Evas_Smart_Cb b2_cb,
221                                         const void *data)
222 {
223         Evas_Object *bt;
224         unsigned int count = 0;
225
226         if (b1_label) {
227                 bt = elm_button_add(p);
228                 elm_object_style_set(bt, b1_class ? b1_class : "dialer");
229                 elm_object_text_set(bt, b1_label);
230                 elm_object_part_content_set(p, "elm.swallow.button1", bt);
231                 evas_object_smart_callback_add(bt, "clicked", b1_cb, data);
232                 count++;
233         }
234
235         if (b2_label) {
236                 const char *part;
237                 bt = elm_button_add(p);
238                 elm_object_style_set(bt, b2_class ? b2_class : "dialer");
239                 elm_object_text_set(bt, b2_label);
240
241                 if (count == 1)
242                         part = "elm.swallow.button2";
243                 else
244                         part = "elm.swallow.button1";
245
246                 elm_object_part_content_set(p, part, bt);
247                 evas_object_smart_callback_add(bt, "clicked", b2_cb, data);
248                 count++;
249         }
250
251         if (count == 2)
252                 elm_object_signal_emit(p, "buttons,2", "gui");
253         else if (count == 1) {
254                 elm_object_signal_emit(p, "buttons,1", "gui");
255                 elm_object_part_content_set(p, "elm.swallow.button2", NULL);
256         } else {
257                 elm_object_signal_emit(p, "buttons,0", "gui");
258                 elm_object_part_content_set(p, "elm.swallow.button1", NULL);
259                 elm_object_part_content_set(p, "elm.swallow.button2", NULL);
260         }
261 }
262
263 static void _simple_popup_del(void *data, Evas *e __UNUSED__,
264                                         Evas_Object *o __UNUSED__,
265                                         void *event_info __UNUSED__)
266 {
267         Simple_Popup *ctx = data;
268         free(ctx);
269 }
270
271 Evas_Object *simple_popup_add(Evas_Object *win,
272                                 const char *title, const char *message)
273 {
274         Evas_Object *p = layout_add(win, "popup");
275         Simple_Popup *ctx;
276
277         EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
278
279         ctx = calloc(1, sizeof(Simple_Popup));
280         EINA_SAFETY_ON_NULL_GOTO(ctx, failed_calloc);
281
282         evas_object_data_set(p, "simple_popup", ctx);
283         ctx->popup = p;
284         evas_object_event_callback_add(p, EVAS_CALLBACK_DEL,
285                                         _simple_popup_del, ctx);
286
287         evas_object_size_hint_weight_set(p, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
288         elm_win_resize_object_add(win, p);
289
290         ctx->box = elm_box_add(p);
291
292         simple_popup_title_set(p, title);
293         simple_popup_message_set(p, message);
294         simple_popup_button_dismiss_set(p);
295
296         evas_object_show(p);
297
298         return p;
299
300 failed_calloc:
301         evas_object_del(p);
302         return NULL;
303 }