f397626a2f71d87d34c602eb5cc4128a56595530
[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                 elm_scroller_policy_set(en, ELM_SCROLLER_POLICY_OFF,
132                                         ELM_SCROLLER_POLICY_AUTO);
133
134                 evas_object_event_callback_add(en, EVAS_CALLBACK_DEL,
135                                         _simple_popup_message_del,
136                                         ctx);
137                 evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND,
138                                                         EVAS_HINT_EXPAND);
139                 evas_object_size_hint_align_set(en, EVAS_HINT_FILL,
140                                                 EVAS_HINT_FILL);
141         }
142
143         elm_object_text_set(en, msg);
144         _simple_popup_reeval_content(ctx);
145 }
146
147 void simple_popup_entry_enable(Evas_Object *p)
148 {
149         Simple_Popup *ctx = evas_object_data_get(p, "simple_popup");
150         Evas_Object *en;
151
152         EINA_SAFETY_ON_NULL_RETURN(ctx);
153
154         if (ctx->entry)
155                 return;
156         en = ctx->entry = elm_entry_add(p);
157         elm_object_style_set(en, "dialer-popup-editable");
158         elm_entry_editable_set(en, EINA_TRUE);
159         elm_entry_scrollable_set(en, EINA_TRUE);
160         elm_scroller_policy_set(en, ELM_SCROLLER_POLICY_OFF,
161                                 ELM_SCROLLER_POLICY_AUTO);
162
163         evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND,
164                                                 EVAS_HINT_EXPAND);
165         evas_object_size_hint_align_set(en, EVAS_HINT_FILL,
166                                         EVAS_HINT_FILL);
167
168         evas_object_event_callback_add(en, EVAS_CALLBACK_DEL,
169                                         _simple_popup_entry_del,
170                                         ctx);
171         _simple_popup_reeval_content(ctx);
172 }
173
174 void simple_popup_entry_disable(Evas_Object *p)
175 {
176         Simple_Popup *ctx = evas_object_data_get(p, "simple_popup");
177         EINA_SAFETY_ON_NULL_RETURN(ctx);
178         if (!ctx->entry)
179                 return;
180         evas_object_del(ctx->entry);
181         _simple_popup_reeval_content(ctx);
182 }
183
184 const char *simple_popup_entry_get(const Evas_Object *p)
185 {
186         Simple_Popup *ctx = evas_object_data_get(p, "simple_popup");
187         EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
188         EINA_SAFETY_ON_NULL_RETURN_VAL(ctx->entry, NULL);
189         return elm_object_text_get(ctx->entry);
190 }
191
192 void simple_popup_button_dismiss_set(Evas_Object *p)
193 {
194         simple_popup_buttons_set(p,
195                                         "Dismiss",
196                                         "dialer",
197                                         _popup_close,
198                                         NULL, NULL, NULL,
199                                         p);
200 }
201
202 void simple_popup_buttons_set(Evas_Object *p,
203                                         const char *b1_label,
204                                         const char *b1_class,
205                                         Evas_Smart_Cb b1_cb,
206                                         const char *b2_label,
207                                         const char *b2_class,
208                                         Evas_Smart_Cb b2_cb,
209                                         const void *data)
210 {
211         Evas_Object *bt;
212         unsigned int count = 0;
213
214         if (b1_label) {
215                 bt = elm_button_add(p);
216                 elm_object_style_set(bt, b1_class ? b1_class : "dialer");
217                 elm_object_text_set(bt, b1_label);
218                 elm_object_part_content_set(p, "elm.swallow.button1", bt);
219                 evas_object_smart_callback_add(bt, "clicked", b1_cb, data);
220                 count++;
221         }
222
223         if (b2_label) {
224                 const char *part;
225                 bt = elm_button_add(p);
226                 elm_object_style_set(bt, b2_class ? b2_class : "dialer");
227                 elm_object_text_set(bt, b2_label);
228
229                 if (count == 1)
230                         part = "elm.swallow.button2";
231                 else
232                         part = "elm.swallow.button1";
233
234                 elm_object_part_content_set(p, part, bt);
235                 evas_object_smart_callback_add(bt, "clicked", b2_cb, data);
236                 count++;
237         }
238
239         if (count == 2)
240                 elm_object_signal_emit(p, "buttons,2", "gui");
241         else if (count == 1) {
242                 elm_object_signal_emit(p, "buttons,1", "gui");
243                 elm_object_part_content_set(p, "elm.swallow.button2", NULL);
244         } else {
245                 elm_object_signal_emit(p, "buttons,0", "gui");
246                 elm_object_part_content_set(p, "elm.swallow.button1", NULL);
247                 elm_object_part_content_set(p, "elm.swallow.button2", NULL);
248         }
249 }
250
251 static void _simple_popup_del(void *data, Evas *e __UNUSED__,
252                                         Evas_Object *o __UNUSED__,
253                                         void *event_info __UNUSED__)
254 {
255         Simple_Popup *ctx = data;
256         free(ctx);
257 }
258
259 Evas_Object *simple_popup_add(Evas_Object *win,
260                                 const char *title, const char *message)
261 {
262         Evas_Object *p = layout_add(win, "popup");
263         Simple_Popup *ctx;
264
265         EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
266
267         ctx = calloc(1, sizeof(Simple_Popup));
268         EINA_SAFETY_ON_NULL_GOTO(ctx, failed_calloc);
269
270         evas_object_data_set(p, "simple_popup", ctx);
271         ctx->popup = p;
272         evas_object_event_callback_add(p, EVAS_CALLBACK_DEL,
273                                         _simple_popup_del, ctx);
274
275         evas_object_size_hint_weight_set(p, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
276         elm_win_resize_object_add(win, p);
277
278         ctx->box = elm_box_add(p);
279
280         simple_popup_title_set(p, title);
281         simple_popup_message_set(p, message);
282         simple_popup_button_dismiss_set(p);
283
284         evas_object_show(p);
285
286         return p;
287
288 failed_calloc:
289         evas_object_del(p);
290         return NULL;
291 }