diff --git a/src/bin/elementary/test_ui_spin.c b/src/bin/elementary/test_ui_spin.c index a1a27c1905..c857cd040b 100644 --- a/src/bin/elementary/test_ui_spin.c +++ b/src/bin/elementary/test_ui_spin.c @@ -65,5 +65,5 @@ test_ui_spin(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_i efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _dec_clicked, sp), efl_pack(bx, efl_added)); - efl_gfx_entity_size_set(win, EINA_SIZE2D(100, 80)); + efl_gfx_entity_size_set(win, EINA_SIZE2D(100, 120)); } diff --git a/src/bin/elementary/test_ui_spin_button.c b/src/bin/elementary/test_ui_spin_button.c index c135848007..0a91da7170 100644 --- a/src/bin/elementary/test_ui_spin_button.c +++ b/src/bin/elementary/test_ui_spin_button.c @@ -3,6 +3,8 @@ #endif #include +#define NUM_OF_VALS 12 + static void _spin_delay_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev) { @@ -13,6 +15,17 @@ void test_ui_spin_button(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Eo *win, *bx; + int i; + Eina_Array *array; + Efl_Ui_Spin_Special_Value values[12] = { + {1, "January"}, {2, "February"}, {3, "March"}, {4, "April"}, + {5, "May"}, {6, "June"}, {7, "July"}, {8, "August"}, + {9, "September"}, {10, "October"}, {11, "November"}, {12, "December"} + }; + + array = eina_array_new(sizeof(Efl_Ui_Spin_Special_Value)); + for (i = 0; i < NUM_OF_VALS; i++) + eina_array_push(array, &values[i]); win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(), efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC), @@ -39,5 +52,13 @@ test_ui_spin_button(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void * efl_ui_spin_button_editable_set(efl_added, EINA_FALSE), efl_pack(bx, efl_added)); - efl_gfx_entity_size_set(win, EINA_SIZE2D(180, 100)); + efl_add(EFL_UI_SPIN_BUTTON_CLASS, bx, + efl_ui_range_min_max_set(efl_added, 1, 12), + efl_ui_range_value_set(efl_added, 1), + efl_ui_spin_button_editable_set(efl_added, EINA_FALSE), + efl_ui_spin_special_value_set(efl_added, array), + efl_pack(bx, efl_added)); + eina_array_free(array); + + efl_gfx_entity_size_set(win, EINA_SIZE2D(180, 140)); } diff --git a/src/lib/elementary/efl_ui_spin.c b/src/lib/elementary/efl_ui_spin.c index 44b985cbd1..151fa8810e 100644 --- a/src/lib/elementary/efl_ui_spin.c +++ b/src/lib/elementary/efl_ui_spin.c @@ -73,8 +73,24 @@ _is_label_format_integer(const char *fmt) static void _label_write(Evas_Object *obj) { + Efl_Ui_Spin_Special_Value *sv; + unsigned int i; + Eina_Array_Iterator iterator; + Efl_Ui_Spin_Data *sd = efl_data_scope_get(obj, MY_CLASS); + EINA_ARRAY_ITER_NEXT(sd->special_values, i, sv, iterator) + { + if (sv->value == sd->val) + { + char buf[1024]; + snprintf(buf, sizeof(buf), "%s", sv->label); + elm_layout_text_set(obj, "elm.text", buf); + sd->templates = sv->label; + return; + } + } + if (sd->format_cb) { const char *buf; @@ -172,6 +188,48 @@ _efl_ui_spin_efl_ui_widget_widget_event(Eo *obj, Efl_Ui_Spin_Data *sd, const Efl return EINA_TRUE; } +EOLIAN static void +_efl_ui_spin_special_value_set(Eo *obj, Efl_Ui_Spin_Data *sd, const Eina_Array *values) +{ + EINA_SAFETY_ON_NULL_RETURN(values); + + unsigned int i; + Efl_Ui_Spin_Special_Value *sv; + Efl_Ui_Spin_Special_Value *temp; + Eina_Array_Iterator iterator; + + if (eina_array_count(sd->special_values)) + { + EINA_ARRAY_ITER_NEXT(sd->special_values, i, sv, iterator) + { + eina_stringshare_del(sv->label); + free(sv); + } + eina_array_clean(sd->special_values); + } + + if (eina_array_count(values)) + EINA_ARRAY_ITER_NEXT(values, i, temp, iterator) + { + sv = calloc(1, sizeof(*sv)); + if (!sv) return; + sv->value = temp->value; + sv->label = eina_stringshare_add(temp->label); + eina_array_push(sd->special_values, sv); + } + + _label_write(obj); +} + +EOLIAN static const Eina_Array* +_efl_ui_spin_special_value_get(const Eo *obj EINA_UNUSED, Efl_Ui_Spin_Data *sd) +{ + if (eina_array_count(sd->special_values)) + return sd->special_values; + else + return NULL; +} + EOLIAN static Eo * _efl_ui_spin_efl_object_constructor(Eo *obj, Efl_Ui_Spin_Data *sd) { @@ -185,6 +243,7 @@ _efl_ui_spin_efl_object_constructor(Eo *obj, Efl_Ui_Spin_Data *sd) sd->val_max = 100.0; sd->step = 1.0; + sd->special_values = eina_array_new(sizeof(Efl_Ui_Spin_Special_Value)); if (!elm_widget_theme_object_set(obj, wd->resize_obj, elm_widget_theme_klass_get(obj), @@ -203,7 +262,19 @@ _efl_ui_spin_efl_object_constructor(Eo *obj, Efl_Ui_Spin_Data *sd) EOLIAN static void _efl_ui_spin_efl_object_destructor(Eo *obj, Efl_Ui_Spin_Data *sd EINA_UNUSED) { + Efl_Ui_Spin_Special_Value *sv; + Eina_Array_Iterator iterator; + unsigned int i; + efl_ui_format_cb_set(obj, NULL, NULL, NULL); + + EINA_ARRAY_ITER_NEXT(sd->special_values, i, sv, iterator) + { + eina_stringshare_del(sv->label); + free(sv); + } + eina_array_free(sd->special_values); + efl_destructor(efl_super(obj, MY_CLASS)); } diff --git a/src/lib/elementary/efl_ui_spin.eo b/src/lib/elementary/efl_ui_spin.eo index 5ed516659d..55996b5c40 100644 --- a/src/lib/elementary/efl_ui_spin.eo +++ b/src/lib/elementary/efl_ui_spin.eo @@ -1,3 +1,10 @@ +struct Efl.Ui.Spin_Special_Value +{ + [[Special value]] + value: double; [[Target value]] + label: string; [[String to replace]] +} + class Efl.Ui.Spin (Efl.Ui.Layout.Object, Efl.Ui.Range, Efl.Ui.Format, Efl.Access.Value, Efl.Access.Widget.Action) { @@ -8,6 +15,24 @@ class Efl.Ui.Spin (Efl.Ui.Layout.Object, Efl.Ui.Range, Efl.Ui.Format, @since 1.21 ]] + methods { + @property special_value { + [[Control special string to display in the place of the numerical value. + + It's useful for cases when a user should select an item that is + better indicated by a label than a value. For example, weekdays or months. + + Note: If another label was previously set to $value, it will be replaced + by the new label.]] + set { + } + get { + } + values { + values: const(array); [[The array of special values, or NULL if none]] + } + } + } implements { Efl.Object.constructor; Efl.Object.destructor; diff --git a/src/lib/elementary/efl_ui_spin_button.c b/src/lib/elementary/efl_ui_spin_button.c index 37ef72f7d9..6b2bfbeae8 100644 --- a/src/lib/elementary/efl_ui_spin_button.c +++ b/src/lib/elementary/efl_ui_spin_button.c @@ -50,9 +50,22 @@ EFL_CALLBACKS_ARRAY_DEFINE(_inc_dec_button_cb, static void _entry_show(Evas_Object *obj) { + Efl_Ui_Spin_Special_Value *sv; + Eina_Array_Iterator iterator; + unsigned int i; + char buf[32], fmt[32] = "%0.f"; + Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS); Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS); - char buf[32], fmt[32] = "%0.f"; + + EINA_ARRAY_ITER_NEXT(pd->special_values, i, sv, iterator) + { + if (sv->value == pd->val) + { + snprintf(buf, sizeof(buf), "%s", sv->label); + elm_object_text_set(sd->ent, buf); + } + } /* try to construct just the format from given label * completely ignoring pre/post words @@ -169,6 +182,9 @@ _entry_hide(Evas_Object *obj) static void _entry_value_apply(Evas_Object *obj) { + Efl_Ui_Spin_Special_Value *sv; + Eina_Array_Iterator iterator; + unsigned int i; const char *str; double val; char *end; @@ -184,6 +200,10 @@ _entry_value_apply(Evas_Object *obj) str = elm_object_text_get(sd->ent); if (!str) return; + EINA_ARRAY_ITER_NEXT(pd->special_values, i, sv, iterator) + if (sv->value == pd->val) + if (!strcmp(sv->label, str)) return; + val = strtod(str, &end); if (((*end != '\0') && (!isspace(*end))) || (fabs(val - pd->val) < DBL_EPSILON)) return; efl_ui_range_value_set(obj, val); diff --git a/src/lib/elementary/efl_ui_spin_private.h b/src/lib/elementary/efl_ui_spin_private.h index a8065dc647..3d21e3df54 100644 --- a/src/lib/elementary/efl_ui_spin_private.h +++ b/src/lib/elementary/efl_ui_spin_private.h @@ -24,6 +24,8 @@ struct _Efl_Ui_Spin_Data Eina_Free_Cb format_free_cb; void *format_cb_data; Eina_Strbuf *format_strbuf; + + Eina_Array *special_values; }; #endif