summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorSumanth Krishna Mannam <sumanth.m@samsung.com>2012-03-05 11:07:05 +0000
committerCarsten Haitzler <raster@rasterman.com>2012-03-05 11:07:05 +0000
commit3448bf2eb2d24b2e3177fe3d05ec24e17d4ddb18 (patch)
tree305da2c06586814ce88120f054946b67cfd879a6 /src/modules
parente6eb4e1008e29da7843aff641b38f59c37080cab (diff)
From: Sumanth Krishna Mannam <sumanth.m@samsung.com>
Subject: [E-devel] [Patch] Elementary : New widget Elm_datetime patch Attached to the mail is the patch for new elementary widget elm_datetime. Refer to the below EFL post history for more details. The datetime widget provides an option to display Date & time based on current locale format and the user can edit them through dynamic Modules. Dynamic modules can be based on 1. Content Popup/diskselector based list 2. Elm_entry with ISE based input 3. Elm_Spinner based etc. Refer to the Screenshots: <1.ctxpopup_diskselector_UI> <2.entry_ise_UI> <3.spinner_selection_UI> Can someone review and push this patch to EFL repository? Change description: New widget Elm_datetime is added. Datetime widget displays the Date &Time fields and provides a customizable way to edit them. The widget is implemented in a modular fashion for date/time field inputs. Ctxpopup based input is proposed as the default selection module. Localization support based on Libc is also supported. Sign-Off By: Sumanth M.V.K <sumanth.m@samsug.com> SVN revision: 68696
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/Makefile.am3
-rw-r--r--src/modules/datetime_input_ctxpopup/Makefile.am33
-rw-r--r--src/modules/datetime_input_ctxpopup/datetime_input_ctxpopup.c325
3 files changed, 360 insertions, 1 deletions
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
index 9354af629..e435e37ff 100644
--- a/src/modules/Makefile.am
+++ b/src/modules/Makefile.am
@@ -4,4 +4,5 @@ MAINTAINERCLEANFILES = Makefile.in
4SUBDIRS = \ 4SUBDIRS = \
5test_entry \ 5test_entry \
6test_map \ 6test_map \
7access_output 7access_output \
8datetime_input_ctxpopup
diff --git a/src/modules/datetime_input_ctxpopup/Makefile.am b/src/modules/datetime_input_ctxpopup/Makefile.am
new file mode 100644
index 000000000..73be6a774
--- /dev/null
+++ b/src/modules/datetime_input_ctxpopup/Makefile.am
@@ -0,0 +1,33 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4AM_CPPFLAGS = \
5-DELM_INTERNAL_API_ARGESFSDFEFC=1 \
6-I. \
7-I$(top_builddir) \
8-I$(top_srcdir) \
9-I$(top_srcdir)/src/lib \
10-I$(top_builddir)/src/lib \
11-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
12-DPACKAGE_LIB_DIR=\"$(libdir)\" \
13@ELEMENTARY_CFLAGS@ \
14@ELEMENTARY_X_CFLAGS@ \
15@ELEMENTARY_FB_CFLAGS@ \
16@ELEMENTARY_WIN32_CFLAGS@ \
17@ELEMENTARY_WINCE_CFLAGS@ \
18@ELEMENTARY_EDBUS_CFLAGS@ \
19@ELEMENTARY_EFREET_CFLAGS@ \
20@ELEMENTARY_ETHUMB_CFLAGS@
21
22if ELEMENTARY_WINDOWS_BUILD
23AM_CPPFLAGS += -DELEMENTARY_BUILD
24endif
25
26pkgdir = $(libdir)/elementary/modules/datetime_input_ctxpopup/$(MODULE_ARCH)
27pkg_LTLIBRARIES = module.la
28
29module_la_SOURCES = datetime_input_ctxpopup.c
30
31module_la_LIBADD = @ELEMENTARY_LIBS@ $(top_builddir)/src/lib/libelementary.la
32module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
33module_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/src/modules/datetime_input_ctxpopup/datetime_input_ctxpopup.c b/src/modules/datetime_input_ctxpopup/datetime_input_ctxpopup.c
new file mode 100644
index 000000000..485d0f563
--- /dev/null
+++ b/src/modules/datetime_input_ctxpopup/datetime_input_ctxpopup.c
@@ -0,0 +1,325 @@
1#include <Elementary.h>
2#include "elm_priv.h"
3#ifdef HAVE_CONFIG_H
4#include "elementary_config.h"
5#endif
6
7#define DATETIME_FIELD_COUNT 6
8#define FIELD_FORMAT_LEN 3
9#define DISKSELECTOR_MIN_ITEMS 4
10#define BUFF_SIZE 1024
11
12typedef struct _Ctxpopup_Module_Data Ctxpopup_Module_Data;
13typedef struct _DiskItem_Data DiskItem_Data;
14
15struct _Ctxpopup_Module_Data
16{
17 Elm_Datetime_Module_Data mod_data;
18 Evas_Object *ctxpopup;
19};
20
21struct _DiskItem_Data
22{
23 Ctxpopup_Module_Data *ctx_mod;
24 Elm_Datetime_Field_Type sel_field_type;
25 unsigned int sel_field_value;
26};
27
28static void
29_diskselector_item_free_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
30{
31 if (data) free(data);
32}
33
34static void
35_ctxpopup_dismissed_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__ )
36{
37 Evas_Object *diskselector;
38
39 diskselector = elm_object_content_unset(obj);
40 if (diskselector) evas_object_del(diskselector);
41}
42
43static void
44_datetime_resize_cb(void *data, Evas *e __UNUSED__,Evas_Object *obj __UNUSED__,
45 void *event_info __UNUSED__)
46{
47 Ctxpopup_Module_Data *ctx_mod;
48
49 ctx_mod = (Ctxpopup_Module_Data *)data;
50 if (!ctx_mod) return;
51
52 evas_object_hide(ctx_mod->ctxpopup);
53}
54
55static void
56_ctxpopup_parent_resize_cb(void *data, Evas *e __UNUSED__,Evas_Object *obj __UNUSED__,
57 void *event_info __UNUSED__)
58{
59 Ctxpopup_Module_Data *ctx_mod;
60
61 ctx_mod = (Ctxpopup_Module_Data *)data;
62 if (!ctx_mod) return;
63 elm_ctxpopup_hover_parent_set(ctx_mod->ctxpopup, elm_widget_top_get(ctx_mod->mod_data.base));
64}
65
66static void
67_datetime_move_cb(void *data, Evas *e __UNUSED__,Evas_Object *obj __UNUSED__,
68 void *event_info __UNUSED__)
69{
70 Ctxpopup_Module_Data *ctx_mod;
71
72 ctx_mod = (Ctxpopup_Module_Data *)data;
73 if (!ctx_mod) return;
74
75 evas_object_hide(ctx_mod->ctxpopup);
76}
77
78static void
79_field_value_set(struct tm *time, Elm_Datetime_Field_Type field_type, int val)
80{
81 if (field_type >= DATETIME_FIELD_COUNT - 1) return;
82
83 int *timearr[]= { &time->tm_year, &time->tm_mon, &time->tm_mday, &time->tm_hour, &time->tm_min };
84 *timearr[field_type] = val;
85}
86
87static int
88_field_value_get(struct tm *time, Elm_Datetime_Field_Type field_type)
89{
90 if (field_type >= DATETIME_FIELD_COUNT - 1) return -1;
91
92 int *timearr[]= { &time->tm_year, &time->tm_mon, &time->tm_mday, &time->tm_hour, &time->tm_min };
93 return (*timearr[field_type]);
94}
95
96static void
97_diskselector_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
98{
99 DiskItem_Data *disk_data;
100 struct tm curr_time;
101 const char *fmt;
102
103 disk_data = (DiskItem_Data *)data;
104 if (!disk_data || !(disk_data->ctx_mod)) return;
105
106 elm_datetime_value_get(disk_data->ctx_mod->mod_data.base, &curr_time);
107 fmt = disk_data->ctx_mod->mod_data.field_format_get(disk_data->ctx_mod->mod_data.base, disk_data->sel_field_type);
108 if ((disk_data->sel_field_type == ELM_DATETIME_HOUR) && ((!strncmp(fmt, "%I", FIELD_FORMAT_LEN)) ||
109 (!strncmp(fmt, "%l", FIELD_FORMAT_LEN))) && (curr_time.tm_hour >= 12))
110 disk_data->sel_field_value += 12;
111 _field_value_set(&curr_time, disk_data->sel_field_type, disk_data->sel_field_value);
112 elm_datetime_value_set(disk_data->ctx_mod->mod_data.base, &curr_time);
113 evas_object_hide(disk_data->ctx_mod->ctxpopup);
114}
115
116static void
117_ampm_clicked_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
118{
119 Ctxpopup_Module_Data *ctx_mod;
120 struct tm curr_time;
121
122 ctx_mod = (Ctxpopup_Module_Data *)data;
123 if (!ctx_mod) return;
124
125 elm_datetime_value_get(ctx_mod->mod_data.base, &curr_time);
126 if (curr_time.tm_hour >= 12) curr_time.tm_hour -= 12;
127 else curr_time.tm_hour += 12;
128 elm_datetime_value_set(ctx_mod->mod_data.base, &curr_time);
129}
130
131static void
132_field_clicked_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
133{
134 Ctxpopup_Module_Data *ctx_mod;
135 Evas_Object *diskselector;
136 Elm_Object_Item *item;
137 DiskItem_Data *disk_data;
138 Elm_Datetime_Field_Type field_type;
139 time_t t;
140 struct tm time1;
141 char buf[BUFF_SIZE], label[BUFF_SIZE];
142 const char *fmt;
143 int idx, min, max, val;
144 unsigned int display_item_num, text_len = 0;
145 Evas_Coord x = 0, y = 0, w = 0, h = 0, width;
146
147 ctx_mod = (Ctxpopup_Module_Data *)data;
148 if (!ctx_mod || !ctx_mod->ctxpopup) return;
149
150 // because of the diskselector behaviour, it is being recreated
151 diskselector = elm_diskselector_add(elm_widget_top_get(ctx_mod->mod_data.base));
152 snprintf(buf, sizeof(buf), "datetime/%s", elm_object_style_get(obj));
153 elm_object_style_set(diskselector, buf);
154 elm_object_content_set(ctx_mod->ctxpopup, diskselector);
155
156 t = time(NULL);
157 localtime_r(&t, &time1);
158
159 field_type = (Elm_Datetime_Field_Type )evas_object_data_get(obj, "_field_type");
160 fmt = ctx_mod->mod_data.field_format_get(ctx_mod->mod_data.base, field_type);
161 elm_datetime_value_get(ctx_mod->mod_data.base, &time1);
162 val = _field_value_get(&time1, field_type);
163 ctx_mod->mod_data.field_limit_get(ctx_mod->mod_data.base, field_type, &min, &max);
164
165 time1.tm_mday = 1; // To avoid month wrapping, set the first day of the month to start with.
166
167 if ((field_type == ELM_DATETIME_HOUR) && ((!strncmp(fmt, "%I", FIELD_FORMAT_LEN)) ||
168 (!strncmp(fmt, "%l", FIELD_FORMAT_LEN))))
169 {
170 if (max >= 12) max -= 12;
171 if (val >= 12) val -= 12;
172 if (min >= 12) min -= 12;
173 }
174 for (idx = min; idx <= max; idx++)
175 {
176 _field_value_set(&time1, field_type, idx);
177 strftime(label, BUFF_SIZE, fmt, &time1);
178 if (strlen(label) > text_len) text_len = strlen(label);
179 if (idx == val)
180 {
181 item = elm_diskselector_item_append(diskselector, label, NULL, NULL, NULL);
182 elm_diskselector_item_selected_set(item, EINA_TRUE);
183 }
184 else
185 {
186 disk_data = (DiskItem_Data *) malloc (sizeof(DiskItem_Data));
187 disk_data->ctx_mod = ctx_mod;
188 disk_data->sel_field_type = field_type;
189 disk_data->sel_field_value = idx;
190 item = elm_diskselector_item_append(diskselector, label, NULL, _diskselector_cb, disk_data);
191 elm_object_item_del_cb_set(item, _diskselector_item_free_cb);
192 }
193 }
194 elm_diskselector_side_label_length_set(diskselector, text_len);
195
196 evas_object_geometry_get(obj, &x, &y, &w, &h);
197 evas_object_geometry_get(elm_widget_top_get(ctx_mod->mod_data.base), NULL, NULL, &width, NULL);
198 evas_object_size_hint_min_set(ctx_mod->ctxpopup, width, -1);
199 display_item_num = width / (w + elm_finger_size_get());
200 // always display even number of items to avoid autoselection
201 if (display_item_num % 2) display_item_num -= 1;
202 if (display_item_num < DISKSELECTOR_MIN_ITEMS)
203 display_item_num = DISKSELECTOR_MIN_ITEMS;
204 elm_diskselector_display_item_num_set(diskselector, display_item_num);
205 elm_diskselector_round_set(diskselector, EINA_TRUE);
206
207 elm_ctxpopup_direction_priority_set(ctx_mod->ctxpopup, ELM_CTXPOPUP_DIRECTION_DOWN,
208 ELM_CTXPOPUP_DIRECTION_UP, -1, -1);
209 evas_object_move(ctx_mod->ctxpopup, (x+w/2), (y+h));
210
211 // if the direction of Ctxpopup is upwards, move it to the top of datetime
212 if (elm_ctxpopup_direction_get (ctx_mod->ctxpopup) == ELM_CTXPOPUP_DIRECTION_UP)
213 {
214 elm_ctxpopup_direction_priority_set(ctx_mod->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
215 ELM_CTXPOPUP_DIRECTION_DOWN, -1, -1);
216 evas_object_move(ctx_mod->ctxpopup, (x+w/2), y);
217 }
218 evas_object_show(ctx_mod->ctxpopup);
219}
220
221// module fucns for the specific module type
222EAPI void
223field_value_display(Elm_Datetime_Module_Data *module_data, Evas_Object *obj)
224{
225 Ctxpopup_Module_Data *ctx_mod;
226 Elm_Datetime_Field_Type field_type;
227 struct tm time;
228 char buf[BUFF_SIZE];
229 const char *fmt;
230
231 ctx_mod = (Ctxpopup_Module_Data *)module_data;
232 if (!ctx_mod || !obj) return;
233
234 elm_datetime_value_get(ctx_mod->mod_data.base, &time);
235 field_type = (Elm_Datetime_Field_Type )evas_object_data_get(obj, "_field_type");
236 fmt = ctx_mod->mod_data.field_format_get(ctx_mod->mod_data.base, field_type);
237 strftime(buf, sizeof(buf), fmt, &time);
238 elm_object_text_set(obj, buf);
239}
240
241EAPI Evas_Object *
242field_create(Elm_Datetime_Module_Data *module_data, Elm_Datetime_Field_Type field_type)
243{
244 Ctxpopup_Module_Data *ctx_mod;
245 Evas_Object *field_obj;
246
247 ctx_mod = (Ctxpopup_Module_Data *)module_data;
248 if (!ctx_mod) return NULL;
249
250 if (field_type == ELM_DATETIME_AMPM)
251 {
252 field_obj = elm_button_add(ctx_mod->mod_data.base);
253 evas_object_smart_callback_add(field_obj, "clicked", _ampm_clicked_cb, ctx_mod);
254 }
255 else
256 {
257 field_obj = elm_entry_add(ctx_mod->mod_data.base);
258 elm_entry_single_line_set(field_obj, EINA_TRUE);
259 elm_entry_editable_set(field_obj, EINA_FALSE);
260 elm_entry_input_panel_enabled_set(field_obj, EINA_FALSE);
261 elm_entry_context_menu_disabled_set(field_obj, EINA_TRUE);
262 evas_object_smart_callback_add(field_obj, "clicked", _field_clicked_cb, ctx_mod);
263 }
264 evas_object_data_set(field_obj, "_field_type", (void *)field_type);
265 return field_obj;
266}
267
268EAPI Elm_Datetime_Module_Data *
269obj_hook(Evas_Object *obj)
270{
271 Ctxpopup_Module_Data *ctx_mod;
272 char buf[BUFF_SIZE];
273
274 ctx_mod = ELM_NEW(Ctxpopup_Module_Data);
275 if (!ctx_mod) return NULL;
276
277 ctx_mod->ctxpopup = elm_ctxpopup_add(elm_widget_top_get(obj));
278 snprintf(buf, sizeof(buf), "datetime/%s", elm_object_style_get(obj));
279 elm_object_style_set(ctx_mod->ctxpopup, buf);
280 elm_ctxpopup_horizontal_set(ctx_mod->ctxpopup, EINA_TRUE);
281 evas_object_size_hint_weight_set(ctx_mod->ctxpopup, EVAS_HINT_EXPAND,
282 EVAS_HINT_EXPAND);
283 evas_object_size_hint_align_set(ctx_mod->ctxpopup, EVAS_HINT_FILL, 0.5);
284 evas_object_smart_callback_add(ctx_mod->ctxpopup, "dismissed",
285 _ctxpopup_dismissed_cb, ctx_mod);
286 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
287 _datetime_resize_cb, ctx_mod);
288 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
289 _datetime_move_cb, ctx_mod);
290 evas_object_event_callback_add(elm_widget_top_get(obj), EVAS_CALLBACK_RESIZE,
291 _ctxpopup_parent_resize_cb, ctx_mod);
292
293 return ((Elm_Datetime_Module_Data*)ctx_mod);
294}
295
296EAPI void
297obj_unhook(Elm_Datetime_Module_Data *module_data)
298{
299 Ctxpopup_Module_Data *ctx_mod;
300
301 ctx_mod = (Ctxpopup_Module_Data *)module_data;
302 if (!ctx_mod) return;
303
304 if (ctx_mod->ctxpopup)
305 evas_object_del(ctx_mod->ctxpopup);
306
307 if (ctx_mod)
308 {
309 free(ctx_mod);
310 ctx_mod = NULL;
311 }
312}
313
314// module api funcs needed
315EAPI int
316elm_modapi_init(void *m __UNUSED__)
317{
318 return 1; // succeed always
319}
320
321EAPI int
322elm_modapi_shutdown(void *m __UNUSED__)
323{
324 return 1; // succeed always
325}