upload codes for TIZEN 2.0
[apps/home/clock.git] / worldclock / src / worldclock_detail_view.c
1 /*
2 *
3 * Copyright 2012  Samsung Electronics Co., Ltd
4 *
5 * Licensed under the Flora License, Version 1.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *    http://www.tizenopensource.org/license
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <stdio.h>
20 #include <appcore-efl.h>
21 #include <Elementary.h>
22 #include <Ecore_X.h>
23 #include <vconf.h>
24 #include <unicode/utf8.h>
25 #include <unicode/ustring.h>
26
27 #include "worldclock.h"
28 #include "worldclock_dlog.h"
29 #include "worldclock_util.h"
30 #include "worldclock_detail_view.h"
31
32 /**********************************************************************
33 ******************define, struct ,typedef, union, enum, global val *************************************
34 ***********************************************************************/
35 typedef struct {
36         Evas_Object *eo_parent; //parent
37         Evas_Object *eo_navibar;        //navi_bar
38         Elm_Object_Item *ei_naviframe;
39         Evas_Object *eo_controlbar;     //controlbar
40         /*Evas_Object *eo_btn_lft, *eo_btn_rht; //button */
41         /*Elm_Object_Item *eci_btn_lft, *eci_btn_rht; */
42         Evas_Object *eo_btn_back;       //button back
43         Evas_Object *eo_layout; //layout
44         Evas_Object *eo_content;        //content
45         //
46         Evas_Object *eo_genlist;        //genlist
47         Evas_Object *eo_radio_grp;
48         /*int total_number;     //total number */
49         struct appdata *ad;
50         Wcl_Return_Cb return_cb;
51         Wcl_CitySet *cs;
52         Evas_Object *icon ;
53         Elm_Object_Item *egi_item[WCL_DST_TYPES_COUNT];
54 } view_data;
55
56 /**********************************************************************
57 ******************Local function declear, extern function declear*************************************
58 ***********************************************************************/
59 static void __detailview_quit_cb(void *data, Evas_Object * obj,
60                                  void *event_info);
61 static void __detailview_onoff_changed_cb(void *data, Evas_Object * obj,
62                                           void *event_info);
63 static char *__detailview_gl_label_get(void *data, Evas_Object * obj,
64                                        const char *part);
65 static Evas_Object *__detailview_gl_icon_get(void *data, Evas_Object * obj,
66                                              const char *part);
67 static Eina_Bool __detailview_gl_state_get(void *data, Evas_Object * obj,
68                                            const char *part);
69 static void __detailview_gl_del(void *data, Evas_Object * obj);
70 static void __detailview_genlist_item_sel(void *data, Evas_Object * obj,
71                                           void *event_info);
72 static void __detailview_genlist_dst_items_del();
73 static void __detailview_genlist_dst_items_add(Evas_Object * parent,
74                                                void *data);
75 static Evas_Object *__detailview_genlist_add(Evas_Object * parent, void *data);
76 static Evas_Object *__detailview_radiobox_add(Evas_Object * parent);
77
78 /**********************************************************************
79 ******************Global val , static global val*************************************
80 ***********************************************************************/
81
82 static view_data *g_view_data = NULL;
83
84 static Elm_Genlist_Item_Class g_ts = {
85         .item_style = "dialogue/1text.1icon",
86         .func.text_get = __detailview_gl_label_get,
87         .func.content_get = __detailview_gl_icon_get,
88         .func.state_get = __detailview_gl_state_get,
89         .func.del = __detailview_gl_del,
90 };
91
92 static Elm_Genlist_Item_Class g_ts2 = {
93         .item_style = "dialogue/1text.1icon.2",
94         .func.text_get = __detailview_gl_label_get,
95         .func.content_get = __detailview_gl_icon_get,
96         .func.state_get = __detailview_gl_state_get,
97         .func.del = __detailview_gl_del,
98 };
99
100 /**********************************************************************
101 ******************Local function ref*************************************
102 ***********************************************************************/
103 /**
104  * Callback function used for quit event caused by Evas_Object event
105  *
106  * @param[in]  data        data used for this function
107  * @param[in]  obj         object which caused this function
108  * @param[in]  event_info  event data
109  *
110  * @return
111  */
112 static void __detailview_quit_cb(void *data, Evas_Object * obj,
113                                  void *event_info)
114 {
115         ret_if(!g_view_data);
116         view_data *view = g_view_data;
117
118         if (view->return_cb) {
119                 view->return_cb(data, EINA_FALSE);
120                 view->return_cb = NULL;
121         }
122         EVAS_OBJECT_DELIF(view->eo_genlist);
123         EVAS_OBJECT_DELIF(view->eo_radio_grp);
124         elm_naviframe_item_pop(view->eo_navibar);
125         FREEIF(g_view_data);
126 }
127
128 static void __detailview_onoff_changed_cb(void *data, Evas_Object * obj,
129                                           void *event_info)
130 {
131         ret_if(!g_view_data);
132         view_data *view = g_view_data;
133         Wcl_CitySet *cs = view->cs;
134         ret_if(!cs);
135
136         cs->dst_enabled = !cs->dst_enabled;
137         elm_check_state_set(obj, cs->dst_enabled);
138         //  update dst disable flag
139         if (0 == cs->dst_enabled) {
140                 __detailview_genlist_dst_items_del();
141         } else {
142                 __detailview_genlist_dst_items_add(view->eo_genlist, data);
143         }
144 }
145
146 //////////////////////////// genlist related /////////////////////////////////////////////////
147 /**
148  * Callback function used for get label as member in genlist item
149  *
150  * @param[in]  data   data used for this function
151  * @param[in]  obj    object which caused this function
152  * @param[in]  part   part name of the label member in genlist item
153  * @return     pointer to content of label
154  */
155 static char *__detailview_gl_label_get(void *data, Evas_Object * obj,
156                                        const char *part)
157 {
158         int index = (int)data;
159         char buf[BUF_SIZE] = { '\0' };
160
161         if (!strcmp(part, "elm.text")) {
162                 switch (index) {
163                 case WCL_DST_AUTO:
164                         snprintf(buf, BUF_SIZE, _("Auto"));
165                         break;
166                 case WCL_DST_1_HOUR:
167                         snprintf(buf, BUF_SIZE, S_("IDS_COM_BODY_1_HOUR"));
168                         break;
169                 case WCL_DST_2_HOURS:
170                         snprintf(buf, BUF_SIZE, S_("IDS_COM_POP_PD_HOURS"),
171                                  index);
172                         break;
173                 case WCL_DST_OFF:
174                         snprintf(buf, BUF_SIZE, _("Daylight saving time"),
175                                  index);
176                         break;
177                 default:
178                         break;
179                 }
180                 CLK_FUN_DEBUG_END();
181                 return strdup(buf);
182         }
183         return NULL;
184 }
185
186 /**
187  * Get icon of given part in genlist item
188  *
189  * @param[in]  data   Data used in this function
190  * @param[in]  obj    Evas_Object who emit this event
191  * @param[in]  part   Name of the part in genlist item
192  *
193  * @return     NULL if meet error
194  *             Pointer to new icon
195  */
196 static Evas_Object *__detailview_gl_icon_get(void *data, Evas_Object * obj,
197                                              const char *part)
198 {
199         int index = (int)data;
200         //Evas_Object *icon = NULL;
201         retv_if(!g_view_data, NULL);
202         Wcl_CitySet *cs = g_view_data->cs;
203         retv_if(!cs, NULL);
204
205         if (!strcmp(part, "elm.icon")) {
206                 switch (index) {
207                 case WCL_DST_AUTO:
208                 case WCL_DST_1_HOUR:
209                 case WCL_DST_2_HOURS:
210                         g_view_data->icon = elm_radio_add(obj);
211                         elm_radio_state_value_set(g_view_data->icon, index);
212                         elm_radio_group_add(g_view_data->icon, g_view_data->eo_radio_grp);
213                         if (cs && index == cs->dst_type) {
214                                 elm_radio_value_set(g_view_data->icon, cs->dst_type);
215                         }
216                         evas_object_size_hint_weight_set(g_view_data->icon, EVAS_HINT_EXPAND,
217                                                          EVAS_HINT_EXPAND);
218                         evas_object_size_hint_align_set(g_view_data->icon, EVAS_HINT_FILL,
219                                                         EVAS_HINT_FILL);
220                         break;
221                 case WCL_DST_OFF:
222                         g_view_data->icon = elm_check_add(obj);
223                         elm_object_style_set(g_view_data->icon, "on&off");
224                         if (cs && 0 == cs->dst_enabled) {
225                                 elm_check_state_set(g_view_data->icon, EINA_FALSE);
226                         } else if (cs) {
227                                 elm_check_state_set(g_view_data->icon, EINA_TRUE);
228                         }
229                         evas_object_smart_callback_add(g_view_data->icon, "changed",
230                                                        __detailview_onoff_changed_cb,
231                                                        g_view_data);
232                         evas_object_propagate_events_set(g_view_data->icon, EINA_FALSE);
233                         break;
234                 default:
235                         break;
236                 }
237         }
238         return g_view_data->icon;
239 }
240
241 static Eina_Bool __detailview_gl_state_get(void *data, Evas_Object * obj,
242                                            const char *part)
243 {
244         return EINA_FALSE;
245 }
246
247 static void __detailview_gl_del(void *data, Evas_Object * obj)
248 {
249         return;
250 }
251
252 /**
253  * Callback function which used for genlist selection event processing
254  *
255  * @param[in]  data         data which used in this function
256  * @param[in]  obj          the object which emit the selection event
257  * @param[in]  event_info   information about selection event
258  *
259  * @return
260  */
261 static void __detailview_genlist_item_sel(void *data, Evas_Object * obj,
262                                           void *event_info)
263 {
264         ret_if(!event_info);
265         Elm_Object_Item *gli = (Elm_Object_Item *) (event_info);
266         elm_genlist_item_selected_set(gli, 0);
267         Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up *) event_info;
268         ret_if(ev && (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD));
269
270         int index = ((int)elm_object_item_data_get(gli));
271         ret_if(!g_view_data);
272         Wcl_CitySet *cs = g_view_data->cs;
273         ret_if(!cs);
274         if (WCL_DST_OFF == index) {
275         __detailview_onoff_changed_cb(g_view_data, g_view_data->icon, NULL);
276         }
277         if (cs) {
278                 cs->dst_type = index;
279                 elm_genlist_item_update(gli);
280         }
281 }
282
283 static void __detailview_genlist_dst_items_del()
284 {
285         ret_if(!g_view_data);
286         int index = 0;
287         for (index = 0; index < WCL_DST_TYPES_COUNT; index++) {
288                 // append data to genlist
289                 if (g_view_data->egi_item[index]) {
290                         elm_object_item_del(g_view_data->egi_item[index]);
291                         g_view_data->egi_item[index] = NULL;
292                 }
293         }
294 }
295
296 static void __detailview_genlist_dst_items_add(Evas_Object * parent, void *data)
297 {
298         ret_if(!parent);
299         ret_if(!g_view_data);
300
301         int index = 0;
302         for (index = 0; index < WCL_DST_TYPES_COUNT; index++) {
303                 if (g_view_data->egi_item[index]) {
304                         elm_object_item_del(g_view_data->egi_item[index]);
305                 }
306                 // append data to genlist
307                 g_view_data->egi_item[index] =
308                     elm_genlist_item_append(parent, &g_ts2, (void *)index,
309                                             NULL, ELM_GENLIST_ITEM_NONE,
310                                             __detailview_genlist_item_sel,
311                                             data);
312         }
313 }
314
315 /**
316  * Add new genlist which used for displaying all cities which could be append
317  * into worldclock.
318  *
319  * @param[in]  parent   The parent object of the new genlist object
320  * @param[in]  data     Data used in this function
321  *
322  * @return     NULL if create genlist failed.
323  *             Pointer to the new genlist object if create genlist successfully.
324  */
325 static Evas_Object *__detailview_genlist_add(Evas_Object * parent, void *data)
326 {
327         retv_if(!data, NULL);
328         Wcl_CitySet *cs = (Wcl_CitySet *) data;
329
330         Evas_Object *genlist = elm_genlist_add(parent);
331         evas_object_show(genlist);
332         // append data to genlist
333         elm_genlist_item_append(genlist, &g_ts, (void *)(WCL_DST_OFF),
334                                 NULL, ELM_GENLIST_ITEM_NONE,
335                                 __detailview_genlist_item_sel, data);
336         if (cs->dst_enabled) {
337                 __detailview_genlist_dst_items_add(genlist, data);
338         }
339         elm_object_part_content_set(parent, "elm.swallow.content", genlist);
340         return genlist;
341 }
342
343 /////////////////////////////////// genlist related finish /////////////////////////////////////////
344
345 static Evas_Object *__detailview_radiobox_add(Evas_Object * parent)
346 {
347         retv_if(!parent, NULL);
348         Evas_Object *radio_box = elm_radio_add(parent);
349         retv_if(!radio_box, NULL);
350         elm_radio_state_value_set(radio_box, 0);
351         elm_radio_value_set(radio_box, 0);
352
353         return radio_box;
354 }
355
356 /**********************************************************************
357 ******************Global function  ref*************************************
358 ***********************************************************************/
359 /**
360  * Create add view for append new city into the selection list of worldclock
361  *
362  * @param[in]  parent    Evas_Object which is the parent of add view
363  * @param[in]  data      data which used in this function
364  * @param[in]  func      Callback function which used for invoking when exit from add view
365  *
366  * @return    FAILED if create add view failed.
367  *            SUCCESS if create add view successfully.
368  */
369 int worldclock_detailview_add(Evas_Object * parent, void *data,
370                               Wcl_Return_Cb func, Wcl_CitySet * cs)
371 {
372         retv_if(!data || !cs, FAILED);
373         struct appdata *ad = (struct appdata *)data;
374         if (g_view_data) {
375                 return SUCCESS;
376         }
377         view_data *view = CALLOC(1, view_data);
378         retv_if(!view, FAILED);
379         memset(view, 0, sizeof(view_data));
380         g_view_data = view;
381
382         view->eo_parent = parent;
383         view->eo_navibar = ad->navi_bar;
384         view->ad = ad;
385         view->return_cb = func;
386         view->cs = cs;
387         ad->page = WCL_PAGE_DETAIL;
388
389         /* detail layout */
390         view->eo_layout = widget_create_layout(view->eo_parent);
391         retv_if(!view->eo_layout, FAILED);
392         /* detail radio box */
393         view->eo_radio_grp = __detailview_radiobox_add(view->eo_layout);
394         retv_if(!view->eo_radio_grp, FAILED);
395         /* detail genlist */
396         view->eo_genlist = __detailview_genlist_add(view->eo_layout, view->cs);
397         retv_if(!view->eo_genlist, FAILED);
398         // create left button
399         view->eo_btn_back =
400             widget_create_button(view->eo_layout, "naviframe/end_btn/default",
401                                  NULL, NULL, __detailview_quit_cb, view->cs);
402         // set segment control as title about layout
403         view->ei_naviframe =
404             widget_naviframe_push(view->eo_navibar, S_("IDS_COM_BODY_DETAILS"),
405                                   view->eo_btn_back, NULL, view->eo_layout,
406                                   "tabbar", NULL);
407         return SUCCESS;
408 }
409
410 /**
411  * Release all resources which used in add view when exit from add view
412  *
413  * @param[in]  data   data which used in this function
414  *
415  * @return
416  */
417 void worldclock_detailview_free(void *data)
418 {
419         ret_if(!data);
420         __detailview_quit_cb(NULL, NULL, NULL);
421 }