Adding support for nightmode theme change
[profile/ivi/lemolo.git] / dialer / gui.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include <Elementary.h>
5
6 #include "log.h"
7 #include "gui.h"
8 #include "keypad.h"
9 #include "history.h"
10 #include "callscreen.h"
11 #include "ussd.h"
12 #include "util.h"
13 #include "simple-popup.h"
14
15 #ifdef HAVE_TIZEN
16 #include <appcore-efl.h>
17 #ifdef HAVE_UI_GADGET
18 #include <ui-gadget.h>
19 #endif
20 #include <Ecore_X.h>
21 #endif
22
23 static Evas_Object *win = NULL;
24 static Evas_Object *main_layout = NULL;
25 static Evas_Object *keypad = NULL;
26 static Evas_Object *contacts = NULL;
27 static Evas_Object *history = NULL;
28 static Evas_Object *cs = NULL;
29 static Evas_Object *flip = NULL;
30 static Evas_Object *current_view = NULL;
31
32 static OFono_Callback_List_Modem_Node *callback_node_modem_changed = NULL;
33 static OFono_Callback_List_USSD_Notify_Node *callback_node_ussd_notify = NULL;
34 static AMB_Callback_List_Node *callback_node_night_mode_changed = NULL;
35
36 /* XXX elm_flip should just do the right thing, but it does not */
37 static Eina_Bool in_call = EINA_FALSE;
38 static Eina_Bool in_flip_anim = EINA_FALSE;
39
40 static Eina_Bool night_mode = EINA_FALSE;
41
42 Contact_Info *gui_contact_search(const char *number, const char **type)
43 {
44         return contact_search(contacts, number, type);
45 }
46
47 static void _dial_reply(void *data, OFono_Error err,
48                         OFono_Call *call __UNUSED__)
49 {
50         char *number = data;
51
52         if (err != OFONO_ERROR_NONE) {
53                 char buf[1024];
54                 const char *msg = ofono_error_message_get(err);
55                 snprintf(buf, sizeof(buf), "Could not call %s: %s",
56                                 number, msg);
57                 gui_simple_popup("Error", buf);
58         }
59
60         free(number);
61 }
62
63 OFono_Pending *gui_dial(const char *number)
64 {
65         char *copy = strdup(number);
66         return ofono_dial(copy, NULL, _dial_reply, copy);
67 }
68
69 static void _gui_show(Evas_Object *o)
70 {
71         if (o == keypad)
72                 elm_object_signal_emit(main_layout, "show,keypad", "gui");
73         else if (o == contacts)
74                 elm_object_signal_emit(main_layout, "show,contacts", "gui");
75         else if (o == history)
76                 elm_object_signal_emit(main_layout, "show,history", "gui");
77         elm_object_focus_set(o, EINA_TRUE);
78         current_view = o;
79 }
80
81 Evas_Object *gui_simple_popup(const char *title, const char *message)
82 {
83         return simple_popup_add(win, title, message);
84 }
85
86 void gui_activate(void)
87 {
88         elm_win_raise(win);
89         elm_win_activate(win);
90         evas_object_show(win);
91
92         /* Automatically enable hfp modem if app is in the foreground */
93         if (!ofono_voice_is_online()) {
94                 ofono_powered_set(EINA_TRUE, NULL, NULL);
95         }
96 }
97
98 void gui_number_set(const char *number, Eina_Bool auto_dial)
99 {
100         _gui_show(keypad);
101         keypad_number_set(keypad, number, auto_dial);
102 }
103
104 void gui_activecall_set(Evas_Object *o)
105 {
106         if (o) {
107                 elm_object_part_content_set(main_layout,
108                                                 "elm.swallow.activecall", o);
109                 elm_object_signal_emit(main_layout, "show,activecall", "gui");
110         } else {
111                 o = elm_object_part_content_unset(
112                         main_layout, "elm.swallow.activecall");
113                 elm_object_signal_emit(main_layout, "hide,activecall", "gui");
114                 evas_object_hide(o);
115         }
116 }
117
118 void gui_contacts_show(void)
119 {
120         _gui_show(contacts);
121         gui_call_exit();
122 }
123
124 void gui_call_enter(void)
125 {
126         gui_activate();
127         if (in_call)
128                 return;
129         in_call = EINA_TRUE;
130         if (in_flip_anim)
131                 return;
132         in_flip_anim = EINA_TRUE;
133         elm_flip_go(flip, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
134         elm_object_focus_set(cs, EINA_TRUE);
135 }
136
137 void gui_call_exit(void)
138 {
139         if (!in_call)
140                 return;
141         in_call = EINA_FALSE;
142         if (in_flip_anim)
143                 return;
144         in_flip_anim = EINA_TRUE;
145         elm_flip_go(flip, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
146         elm_object_focus_set(cs, EINA_FALSE);
147 }
148
149 static void _gui_call_sync(void *data __UNUSED__, Evas_Object *o __UNUSED__,
150                                 void *event_info __UNUSED__)
151 {
152         Eina_Bool showing_call = !elm_flip_front_visible_get(flip);
153
154         if (showing_call ^ in_call) {
155                 DBG("Flip back to sync");
156                 elm_flip_go(flip, ELM_FLIP_ROTATE_Y_CENTER_AXIS);
157                 elm_object_focus_set(cs, in_call);
158         }
159         in_flip_anim = EINA_FALSE;
160 }
161
162 static void _gui_voicemail(void)
163 {
164         const char *number = ofono_voicemail_number_get();
165         EINA_SAFETY_ON_NULL_RETURN(number);
166         EINA_SAFETY_ON_FALSE_RETURN(*number != '\0');
167
168         gui_dial(number);
169 }
170
171 static void _gui_quit(void)
172 {
173         elm_exit();
174 }
175
176 static void _on_clicked(void *data __UNUSED__, Evas_Object *o __UNUSED__,
177                         const char *emission, const char *source __UNUSED__)
178 {
179         DBG("signal: %s", emission);
180
181         EINA_SAFETY_ON_FALSE_RETURN(eina_str_has_prefix(emission, "clicked,"));
182         emission += strlen("clicked,");
183
184         if (strcmp(emission, "keypad") == 0)
185                 _gui_show(keypad);
186         else if (strcmp(emission, "contacts") == 0)
187                 _gui_show(contacts);
188         else if (strcmp(emission, "history") == 0)
189                 _gui_show(history);
190         else if (strcmp(emission, "voicemail") == 0)
191                 _gui_voicemail();
192         else if (strcmp(emission, "quit") == 0)
193                 _gui_quit();
194 }
195
196 static void _ofono_changed(void *data __UNUSED__)
197 {
198         const char *number;
199         Eina_Bool waiting;
200         unsigned char count;
201         char buf[32];
202
203         if ((ofono_modem_api_get() & OFONO_API_MSG_WAITING) == 0) {
204                 elm_object_signal_emit(main_layout, "disable,voicemail", "gui");
205                 elm_object_signal_emit(main_layout,
206                                         "toggle,off,voicemail", "gui");
207                 elm_object_part_text_set(main_layout, "elm.text.voicemail", "");
208                 return;
209         }
210
211         number = ofono_voicemail_number_get();
212         waiting = ofono_voicemail_waiting_get();
213         count = ofono_voicemail_count_get();
214
215         if (number)
216                 elm_object_signal_emit(main_layout, "enable,voicemail", "gui");
217         else
218                 elm_object_signal_emit(main_layout, "disable,voicemail", "gui");
219
220         if (waiting) {
221                 if (count == 0)
222                         snprintf(buf, sizeof(buf), "*");
223                 else if (count < 255)
224                         snprintf(buf, sizeof(buf), "%d", count);
225                 else
226                         snprintf(buf, sizeof(buf), "255+");
227
228                 elm_object_signal_emit(main_layout,
229                                         "toggle,on,voicemail", "gui");
230         } else {
231                 buf[0] = '\0';
232                 elm_object_signal_emit(main_layout,
233                                         "toggle,off,voicemail", "gui");
234         }
235
236         elm_object_part_text_set(main_layout, "elm.text.voicemail", buf);
237 }
238
239 static void _night_mode_changed(void *data __UNUSED__)
240 {
241         DBG("Night mode changed");
242         Eina_Bool changed = amb_night_mode_get();
243         if (night_mode != changed)
244         {
245                 DBG("Nightmode changed to %d", changed);
246                 night_mode = changed;
247                 util_set_night_mode(night_mode);
248
249                 if (current_view)
250                         _gui_show(current_view);
251         }
252 }
253
254 static void _ofono_ussd_notify(void *data __UNUSED__, Eina_Bool needs_reply,
255                                 const char *message)
256 {
257         DBG("needs_reply=%d, message=%s", needs_reply, message);
258         ussd_start(message);
259 }
260
261 static void _on_contacts_selected(void *data __UNUSED__,
262                                         Evas_Object *obj __UNUSED__,
263                                         void *event_info)
264 {
265         const char *number = event_info;
266         DBG("Contact selected: %s", number);
267         gui_dial(number);
268 }
269
270 Eina_Bool gui_init(void)
271 {
272         Evas_Object *lay, *obj;
273         Evas_Coord w, h;
274
275         /* dialer should never, ever quit */
276         elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_NONE);
277
278         win = elm_win_util_standard_add("ofono-dialer", "oFono Dialer");
279         EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
280         elm_win_autodel_set(win, EINA_FALSE);
281
282 #ifdef HAVE_TIZEN
283         appcore_set_i18n("ofono-efl", "en-US");
284 #ifdef HAVE_UI_GADGET
285         UG_INIT_EFL(win, UG_OPT_INDICATOR_PORTRAIT_ONLY);
286 #endif
287 #endif
288
289         flip = elm_flip_add(win);
290         evas_object_size_hint_weight_set(flip,
291                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
292         evas_object_size_hint_align_set(flip, EVAS_HINT_FILL, EVAS_HINT_FILL);
293         elm_win_resize_object_add(win, flip);
294         evas_object_smart_callback_add(flip, "animate,done",
295                                         _gui_call_sync, NULL);
296         evas_object_show(flip);
297
298         main_layout = lay = layout_add(win, "dialer");
299         EINA_SAFETY_ON_NULL_RETURN_VAL(lay, EINA_FALSE);
300         evas_object_size_hint_weight_set(lay,
301                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
302         evas_object_size_hint_align_set(lay, EVAS_HINT_FILL, EVAS_HINT_FILL);
303         elm_object_part_content_set(flip, "front", lay);
304         evas_object_show(lay);
305
306         elm_object_signal_callback_add(lay, "clicked,*", "gui",
307                                         _on_clicked, NULL);
308
309         keypad = obj = keypad_add(win);
310         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
311         elm_object_part_content_set(lay, "elm.swallow.keypad", obj);
312
313         contacts = obj = contacts_add(win);
314         evas_object_smart_callback_add(contacts, "selected",
315                                         _on_contacts_selected, NULL);
316         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
317         elm_object_part_content_set(lay, "elm.swallow.contacts", obj);
318
319         history = obj = history_add(win);
320         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
321         elm_object_part_content_set(lay, "elm.swallow.history", obj);
322
323         _gui_show(keypad);
324
325         cs = obj = callscreen_add(win);
326         EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
327         evas_object_size_hint_weight_set(obj,
328                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
329         evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
330         elm_object_part_content_set(flip, "back", obj);
331         evas_object_show(obj);
332
333         callback_node_modem_changed =
334                 ofono_modem_changed_cb_add(_ofono_changed, NULL);
335         callback_node_ussd_notify =
336                 ofono_ussd_notify_cb_add(_ofono_ussd_notify, NULL);
337         callback_node_night_mode_changed =
338                 amb_properties_changed_cb_add(_night_mode_changed, NULL);
339
340         /* TODO: make it match better with Tizen: icon and other properties */
341         obj = elm_layout_edje_get(lay);
342         edje_object_size_min_get(obj, &w, &h);
343         if ((w == 0) || (h == 0))
344                 edje_object_size_min_restricted_calc(obj, &w, &h, w, h);
345         if ((w == 0) || (h == 0))
346                 edje_object_parts_extends_calc(obj, NULL, NULL, &w, &h);
347         evas_object_resize(win, w, h);
348
349         /* do not show it yet, RC will check if it should be visible or not */
350         return EINA_TRUE;
351 }
352
353 void gui_shutdown(void)
354 {
355 }