2 #include "elementary_config.h"
5 #include <Elementary.h>
6 #include "elm_widget.h"
7 #include "elm_widget_datetime.h"
9 #define DATETIME_FIELD_COUNT 6
10 #define FIELD_FORMAT_LEN 3
11 #define DISKSELECTOR_MIN_ITEMS 4
12 #define BUFF_SIZE 1024
14 typedef struct _Ctxpopup_Module_Data Ctxpopup_Module_Data;
15 typedef struct _DiskItem_Data DiskItem_Data;
17 struct _Ctxpopup_Module_Data
19 Elm_Datetime_Module_Data mod_data;
20 Evas_Object *ctxpopup;
25 Ctxpopup_Module_Data *ctx_mod;
26 Elm_Datetime_Field_Type sel_field_type;
27 unsigned int sel_field_value;
31 _diskselector_item_free_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
37 _ctxpopup_dismissed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED )
39 Evas_Object *diskselector;
41 diskselector = elm_object_content_unset(obj);
42 if (diskselector) evas_object_del(diskselector);
46 _datetime_resize_cb(void *data, Evas *e EINA_UNUSED,Evas_Object *obj EINA_UNUSED,
47 void *event_info EINA_UNUSED)
49 Ctxpopup_Module_Data *ctx_mod;
51 ctx_mod = (Ctxpopup_Module_Data *)data;
52 if (!ctx_mod || !ctx_mod->ctxpopup) return;
54 evas_object_hide(ctx_mod->ctxpopup);
58 _datetime_move_cb(void *data, Evas *e EINA_UNUSED,Evas_Object *obj EINA_UNUSED,
59 void *event_info EINA_UNUSED)
61 Ctxpopup_Module_Data *ctx_mod;
63 ctx_mod = (Ctxpopup_Module_Data *)data;
64 if (!ctx_mod || !ctx_mod->ctxpopup) return;
66 evas_object_hide(ctx_mod->ctxpopup);
70 _field_value_set(struct tm *tim, Elm_Datetime_Field_Type field_type, int val)
72 if (field_type >= DATETIME_FIELD_COUNT - 1) return;
74 int *timearr[]= { &tim->tm_year, &tim->tm_mon, &tim->tm_mday, &tim->tm_hour, &tim->tm_min };
75 *timearr[field_type] = val;
79 _field_value_get(struct tm *tim, Elm_Datetime_Field_Type field_type)
81 if (field_type >= DATETIME_FIELD_COUNT - 1) return -1;
83 int *timearr[]= { &tim->tm_year, &tim->tm_mon, &tim->tm_mday, &tim->tm_hour, &tim->tm_min };
84 return (*timearr[field_type]);
88 _diskselector_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
90 DiskItem_Data *disk_data;
94 disk_data = (DiskItem_Data *)elm_object_item_data_get(event_info);
95 if (!disk_data || !(disk_data->ctx_mod)) return;
97 elm_datetime_value_get(disk_data->ctx_mod->mod_data.base, &curr_time);
98 fmt = disk_data->ctx_mod->mod_data.field_format_get(disk_data->ctx_mod->mod_data.base, disk_data->sel_field_type);
99 if ((disk_data->sel_field_type == ELM_DATETIME_HOUR) && ((!strncmp(fmt, "%I", FIELD_FORMAT_LEN)) ||
100 (!strncmp(fmt, "%l", FIELD_FORMAT_LEN))) && (curr_time.tm_hour >= 12))
101 disk_data->sel_field_value += 12;
102 _field_value_set(&curr_time, disk_data->sel_field_type, disk_data->sel_field_value);
103 elm_datetime_value_set(disk_data->ctx_mod->mod_data.base, &curr_time);
104 evas_object_hide(disk_data->ctx_mod->ctxpopup);
108 _ampm_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
110 Ctxpopup_Module_Data *ctx_mod;
113 ctx_mod = (Ctxpopup_Module_Data *)data;
114 if (!ctx_mod) return;
116 elm_datetime_value_get(ctx_mod->mod_data.base, &curr_time);
117 if (curr_time.tm_hour >= 12) curr_time.tm_hour -= 12;
118 else curr_time.tm_hour += 12;
119 elm_datetime_value_set(ctx_mod->mod_data.base, &curr_time);
123 _field_clicked_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
125 Ctxpopup_Module_Data *ctx_mod;
126 Evas_Object *diskselector;
127 Elm_Object_Item *item;
128 DiskItem_Data *disk_data;
129 Elm_Datetime_Field_Type field_type;
132 char buf[BUFF_SIZE], label[BUFF_SIZE];
134 int idx, min, max, val;
135 unsigned int display_item_num, text_len = 0;
136 Evas_Coord x = 0, y = 0, w = 0, h = 0, width;
138 ctx_mod = (Ctxpopup_Module_Data *)data;
139 if (!ctx_mod) return;
141 snprintf(buf, sizeof(buf), "datetime/%s", elm_object_style_get(obj));
143 if (!ctx_mod->ctxpopup)
145 ctx_mod->ctxpopup = elm_ctxpopup_add(obj);
146 elm_object_style_set(ctx_mod->ctxpopup, buf);
147 elm_ctxpopup_horizontal_set(ctx_mod->ctxpopup, EINA_TRUE);
148 evas_object_size_hint_weight_set(ctx_mod->ctxpopup, EVAS_HINT_EXPAND,
150 evas_object_size_hint_align_set(ctx_mod->ctxpopup, EVAS_HINT_FILL, 0.5);
151 evas_object_smart_callback_add(ctx_mod->ctxpopup, "dismissed",
152 _ctxpopup_dismissed_cb, ctx_mod);
155 elm_ctxpopup_hover_parent_set(ctx_mod->ctxpopup, elm_widget_top_get(obj));
157 // because of the diskselector behaviour, it is being recreated
158 diskselector = elm_diskselector_add(elm_widget_top_get(ctx_mod->mod_data.base));
159 evas_object_smart_callback_add(diskselector, "clicked", _diskselector_cb, NULL);
160 elm_object_style_set(diskselector, buf);
161 elm_object_content_set(ctx_mod->ctxpopup, diskselector);
164 localtime_r(&t, &time1);
166 field_type = (Elm_Datetime_Field_Type )evas_object_data_get(obj, "_field_type");
167 fmt = ctx_mod->mod_data.field_format_get(ctx_mod->mod_data.base, field_type);
168 elm_datetime_value_get(ctx_mod->mod_data.base, &time1);
169 val = _field_value_get(&time1, field_type);
170 ctx_mod->mod_data.field_limit_get(ctx_mod->mod_data.base, field_type, &min, &max);
172 time1.tm_mday = 1; // To avoid month wrapping, set the first day of the month to start with.
174 if ((field_type == ELM_DATETIME_HOUR) && ((!strncmp(fmt, "%I", FIELD_FORMAT_LEN)) ||
175 (!strncmp(fmt, "%l", FIELD_FORMAT_LEN))))
177 if (max >= 12) max -= 12;
178 if (val >= 12) val -= 12;
179 if (min >= 12) min -= 12;
181 for (idx = min; idx <= max; idx++)
183 _field_value_set(&time1, field_type, idx);
184 strftime(label, BUFF_SIZE, fmt, &time1);
185 if (strlen(label) > text_len) text_len = strlen(label);
188 item = elm_diskselector_item_append(diskselector, label, NULL, NULL, NULL);
189 elm_diskselector_item_selected_set(item, EINA_TRUE);
193 disk_data = (DiskItem_Data *) malloc (sizeof(DiskItem_Data));
194 if (!disk_data) return;
196 disk_data->ctx_mod = ctx_mod;
197 disk_data->sel_field_type = field_type;
198 disk_data->sel_field_value = idx;
199 item = elm_diskselector_item_append(diskselector, label, NULL, NULL, disk_data);
200 elm_object_item_del_cb_set(item, _diskselector_item_free_cb);
203 elm_diskselector_side_text_max_length_set(diskselector, text_len);
205 evas_object_geometry_get(obj, &x, &y, &w, &h);
206 evas_object_geometry_get(elm_widget_top_get(ctx_mod->mod_data.base), NULL, NULL, &width, NULL);
207 evas_object_size_hint_min_set(ctx_mod->ctxpopup, width, -1);
208 display_item_num = width / (w + elm_config_finger_size_get());
209 // always display even number of items to avoid autoselection
210 if (display_item_num % 2) display_item_num -= 1;
211 if (display_item_num < DISKSELECTOR_MIN_ITEMS)
212 display_item_num = DISKSELECTOR_MIN_ITEMS;
213 elm_diskselector_display_item_num_set(diskselector, display_item_num);
214 elm_diskselector_round_enabled_set(diskselector, EINA_TRUE);
216 elm_ctxpopup_direction_priority_set(ctx_mod->ctxpopup, ELM_CTXPOPUP_DIRECTION_DOWN,
217 ELM_CTXPOPUP_DIRECTION_UP, -1, -1);
218 evas_object_move(ctx_mod->ctxpopup, (x+w/2), (y+h));
220 // if the direction of Ctxpopup is upwards, move it to the top of datetime
221 if (elm_ctxpopup_direction_get (ctx_mod->ctxpopup) == ELM_CTXPOPUP_DIRECTION_UP)
223 elm_ctxpopup_direction_priority_set(ctx_mod->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
224 ELM_CTXPOPUP_DIRECTION_DOWN, -1, -1);
225 evas_object_move(ctx_mod->ctxpopup, (x+w/2), y);
227 evas_object_show(ctx_mod->ctxpopup);
231 _access_set(Evas_Object *obj, Elm_Datetime_Field_Type field_type)
233 const char* type = NULL;
237 case ELM_DATETIME_YEAR:
238 type = "datetime field, year";
241 case ELM_DATETIME_MONTH:
242 type = "datetime field, month";
245 case ELM_DATETIME_DATE:
246 type = "datetime field, date";
249 case ELM_DATETIME_HOUR:
250 type = "datetime field, hour";
253 case ELM_DATETIME_MINUTE:
254 type = "datetime field, minute";
257 case ELM_DATETIME_AMPM:
258 type = "datetime field, AM PM";
266 (_elm_access_info_get(obj), ELM_ACCESS_TYPE, type);
267 _elm_access_callback_set
268 (_elm_access_info_get(obj), ELM_ACCESS_STATE, NULL, NULL);
271 // module fucns for the specific module type
273 field_value_display(Elm_Datetime_Module_Data *module_data, Evas_Object *obj)
275 Ctxpopup_Module_Data *ctx_mod;
276 Elm_Datetime_Field_Type field_type;
281 ctx_mod = (Ctxpopup_Module_Data *)module_data;
282 if (!ctx_mod || !obj) return;
284 elm_datetime_value_get(ctx_mod->mod_data.base, &tim);
285 field_type = (Elm_Datetime_Field_Type )evas_object_data_get(obj, "_field_type");
286 fmt = ctx_mod->mod_data.field_format_get(ctx_mod->mod_data.base, field_type);
288 strftime(buf, sizeof(buf), fmt, &tim);
289 if ((!buf[0]) && ((!strcmp(fmt, "%p")) || (!strcmp(fmt, "%P"))))
291 // yes BUFF_SIZE is more than 2 bytes!
292 if (tim.tm_hour < 12) strcpy(buf, "AM");
293 else strcpy(buf, "PM");
295 elm_object_text_set(obj, buf);
299 field_create(Elm_Datetime_Module_Data *module_data, Elm_Datetime_Field_Type field_type)
301 Ctxpopup_Module_Data *ctx_mod;
302 Evas_Object *field_obj;
304 ctx_mod = (Ctxpopup_Module_Data *)module_data;
305 if (!ctx_mod) return NULL;
307 if (field_type == ELM_DATETIME_AMPM)
309 field_obj = elm_button_add(ctx_mod->mod_data.base);
310 evas_object_smart_callback_add(field_obj, "clicked", _ampm_clicked_cb, ctx_mod);
314 field_obj = elm_entry_add(ctx_mod->mod_data.base);
315 elm_entry_single_line_set(field_obj, EINA_TRUE);
316 elm_entry_editable_set(field_obj, EINA_FALSE);
317 elm_entry_input_panel_enabled_set(field_obj, EINA_FALSE);
318 elm_entry_context_menu_disabled_set(field_obj, EINA_TRUE);
319 evas_object_smart_callback_add(field_obj, "clicked", _field_clicked_cb, ctx_mod);
321 evas_object_data_set(field_obj, "_field_type", (void *)field_type);
324 _access_set(field_obj, field_type);
329 EAPI Elm_Datetime_Module_Data *
330 obj_hook(Evas_Object *obj)
332 Ctxpopup_Module_Data *ctx_mod;
333 ctx_mod = calloc(1, sizeof(Ctxpopup_Module_Data));
334 if (!ctx_mod) return NULL;
336 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
337 _datetime_resize_cb, ctx_mod);
338 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
339 _datetime_move_cb, ctx_mod);
341 return ((Elm_Datetime_Module_Data*)ctx_mod);
345 obj_unhook(Elm_Datetime_Module_Data *module_data)
347 Ctxpopup_Module_Data *ctx_mod;
349 ctx_mod = (Ctxpopup_Module_Data *)module_data;
350 if (!ctx_mod) return;
352 if (ctx_mod->ctxpopup)
353 evas_object_del(ctx_mod->ctxpopup);
363 obj_hide(Elm_Datetime_Module_Data *module_data)
365 Ctxpopup_Module_Data *ctx_mod;
367 ctx_mod = (Ctxpopup_Module_Data *)module_data;
368 if (!ctx_mod) return;
370 if (ctx_mod->ctxpopup)
371 evas_object_hide(ctx_mod->ctxpopup);
374 // module api funcs needed
376 elm_modapi_init(void *m EINA_UNUSED)
378 return 1; // succeed always
382 elm_modapi_shutdown(void *m EINA_UNUSED)
384 return 1; // succeed always