summaryrefslogtreecommitdiff
path: root/src/lib/elementary/efl_ui_spin_button.c
diff options
context:
space:
mode:
authorXavi Artigas <xavierartigas@yahoo.es>2019-07-02 14:40:06 +0200
committerXavi Artigas <xavierartigas@yahoo.es>2019-07-04 19:38:20 +0200
commite776f5f0d7b6292d32c29ccb4fffe3f20063d53d (patch)
tree0191eda9933ca930e90078fc9a35762b4b71538a /src/lib/elementary/efl_ui_spin_button.c
parent87cfde51d3e143260a1b431f9c14d30536b549ce (diff)
Efl.Ui.Format revamp
This class helps widgets which contain a numerical value and must display it, like Progressbar (units label), Spin, Spin_Button, Slider (both units and popup labels, in legacy), Tags (when in shrunk mode) or Calendar (year_month label). Previously this was a mix of interface and mixin: widgets had to support setting a formatting func, and the mixin offered support for formatting strings, by setting an internal formatting func. On top of that, the spinner widget supported "special values", a list of values that should be shown as certain strings instead. This has now been simplified and unified: Widgets including this mixin can use the formatted_value_get() method which accepts an Eina_Value and returns a string. Thats's it. The mixin adds three properties to the widget (format_values, format_func and format_string) which users can use to tailor formatting. The widget does not need to know which method has been used, it just retrieves the resulting string. This removes a lot of duplicated widget code, and adds functionality which was missing before. For example, all widgets support passing a list of values now. Widgets must implement the apply_formatted_value() method so they are notified of changes in the format and they can redraw anything they need. Tests have been added to the Elementary Spec suite for all cases. Legacy widgets behavior has not been modified, although a few needed some code changes.
Diffstat (limited to 'src/lib/elementary/efl_ui_spin_button.c')
-rw-r--r--src/lib/elementary/efl_ui_spin_button.c57
1 files changed, 18 insertions, 39 deletions
diff --git a/src/lib/elementary/efl_ui_spin_button.c b/src/lib/elementary/efl_ui_spin_button.c
index 71eaec1..c356686 100644
--- a/src/lib/elementary/efl_ui_spin_button.c
+++ b/src/lib/elementary/efl_ui_spin_button.c
@@ -6,6 +6,7 @@
6#define EFL_ACCESS_VALUE_PROTECTED 6#define EFL_ACCESS_VALUE_PROTECTED
7#define EFL_ACCESS_WIDGET_ACTION_PROTECTED 7#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
8#define EFL_UI_FOCUS_COMPOSITION_PROTECTED 8#define EFL_UI_FOCUS_COMPOSITION_PROTECTED
9#define EFL_UI_FORMAT_PROTECTED
9 10
10#include <Elementary.h> 11#include <Elementary.h>
11 12
@@ -50,29 +51,20 @@ EFL_CALLBACKS_ARRAY_DEFINE(_inc_dec_button_cb,
50static void 51static void
51_entry_show(Evas_Object *obj) 52_entry_show(Evas_Object *obj)
52{ 53{
53 Efl_Ui_Spin_Special_Value *sv;
54 Eina_Array_Iterator iterator;
55 unsigned int i;
56 char buf[32], fmt[32] = "%0.f"; 54 char buf[32], fmt[32] = "%0.f";
57 55
58 Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS); 56 Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
59 Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS); 57 Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
60 58
61 EINA_ARRAY_ITER_NEXT(pd->special_values, i, sv, iterator) 59 const char *format_string;
62 { 60 efl_ui_format_string_get(obj, &format_string, NULL);
63 if (sv->value == pd->val)
64 {
65 snprintf(buf, sizeof(buf), "%s", sv->label);
66 elm_object_text_set(sd->ent, buf);
67 }
68 }
69 61
70 /* try to construct just the format from given label 62 /* try to construct just the format from given label
71 * completely ignoring pre/post words 63 * completely ignoring pre/post words
72 */ 64 */
73 if (pd->templates) 65 if (format_string)
74 { 66 {
75 const char *start = strchr(pd->templates, '%'); 67 const char *start = strchr(format_string, '%');
76 while (start) 68 while (start)
77 { 69 {
78 /* handle %% */ 70 /* handle %% */
@@ -103,10 +95,7 @@ _entry_show(Evas_Object *obj)
103 } 95 }
104 } 96 }
105 97
106 if (pd->format_type == SPIN_FORMAT_INT) 98 snprintf(buf, sizeof(buf), fmt, pd->val);
107 snprintf(buf, sizeof(buf), fmt, (int)pd->val);
108 else
109 snprintf(buf, sizeof(buf), fmt, pd->val);
110 99
111 elm_object_text_set(sd->ent, buf); 100 elm_object_text_set(sd->ent, buf);
112} 101}
@@ -115,20 +104,16 @@ static void
115_label_write(Evas_Object *obj) 104_label_write(Evas_Object *obj)
116{ 105{
117 Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS); 106 Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
118
119 Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS); 107 Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
120 108
121 if (pd->templates) 109 Eina_Strbuf *strbuf = eina_strbuf_new();
122 { 110 Eina_Value val = eina_value_double_init(pd->val);
123 efl_text_set(sd->text_button, pd->templates); 111 efl_ui_format_formatted_value_get(obj, strbuf, val);
124 }
125 else
126 {
127 char buf[1024];
128 112
129 snprintf(buf, sizeof(buf), "%.0f", pd->val); 113 efl_text_set(sd->text_button, eina_strbuf_string_get(strbuf));
130 efl_text_set(sd->text_button, buf); 114
131 } 115 eina_value_flush(&val);
116 eina_strbuf_free(strbuf);
132} 117}
133 118
134static Eina_Bool 119static Eina_Bool
@@ -182,9 +167,6 @@ _entry_hide(Evas_Object *obj)
182static void 167static void
183_entry_value_apply(Evas_Object *obj) 168_entry_value_apply(Evas_Object *obj)
184{ 169{
185 Efl_Ui_Spin_Special_Value *sv;
186 Eina_Array_Iterator iterator;
187 unsigned int i;
188 const char *str; 170 const char *str;
189 double val; 171 double val;
190 char *end; 172 char *end;
@@ -200,10 +182,6 @@ _entry_value_apply(Evas_Object *obj)
200 str = elm_object_text_get(sd->ent); 182 str = elm_object_text_get(sd->ent);
201 if (!str) return; 183 if (!str) return;
202 184
203 EINA_ARRAY_ITER_NEXT(pd->special_values, i, sv, iterator)
204 if (sv->value == pd->val)
205 if (!strcmp(sv->label, str)) return;
206
207 val = strtod(str, &end); 185 val = strtod(str, &end);
208 if (((*end != '\0') && (!isspace(*end))) || (fabs(val - pd->val) < DBL_EPSILON)) return; 186 if (((*end != '\0') && (!isspace(*end))) || (fabs(val - pd->val) < DBL_EPSILON)) return;
209 efl_ui_range_value_set(obj, val); 187 efl_ui_range_value_set(obj, val);
@@ -267,14 +245,14 @@ static void
267_entry_accept_filter_add(Evas_Object *obj) 245_entry_accept_filter_add(Evas_Object *obj)
268{ 246{
269 Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS); 247 Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
270 Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
271 static Elm_Entry_Filter_Accept_Set digits_filter_data; 248 static Elm_Entry_Filter_Accept_Set digits_filter_data;
249 int decimal_places = efl_ui_format_decimal_places_get(obj);
272 250
273 if (!sd->ent) return; 251 if (!sd->ent) return;
274 252
275 elm_entry_markup_filter_remove(sd->ent, elm_entry_filter_accept_set, &digits_filter_data); 253 elm_entry_markup_filter_remove(sd->ent, elm_entry_filter_accept_set, &digits_filter_data);
276 254
277 if (pd->decimal_points > 0) 255 if (decimal_places > 0)
278 digits_filter_data.accepted = "-.0123456789"; 256 digits_filter_data.accepted = "-.0123456789";
279 else 257 else
280 digits_filter_data.accepted = "-0123456789"; 258 digits_filter_data.accepted = "-0123456789";
@@ -307,6 +285,7 @@ _min_max_validity_filter(void *data, Evas_Object *obj, char **text)
307 char *insert, *new_str = NULL; 285 char *insert, *new_str = NULL;
308 double val; 286 double val;
309 int max_len = 0, len; 287 int max_len = 0, len;
288 int decimal_places = efl_ui_format_decimal_places_get(data);
310 289
311 EINA_SAFETY_ON_NULL_RETURN(data); 290 EINA_SAFETY_ON_NULL_RETURN(data);
312 EINA_SAFETY_ON_NULL_RETURN(obj); 291 EINA_SAFETY_ON_NULL_RETURN(obj);
@@ -322,12 +301,12 @@ _min_max_validity_filter(void *data, Evas_Object *obj, char **text)
322 if (!new_str) return; 301 if (!new_str) return;
323 if (strchr(new_str, '-')) max_len++; 302 if (strchr(new_str, '-')) max_len++;
324 303
325 if (pd->format_type == SPIN_FORMAT_FLOAT) 304 if (decimal_places > 0)
326 { 305 {
327 point = strchr(new_str, '.'); 306 point = strchr(new_str, '.');
328 if (point) 307 if (point)
329 { 308 {
330 if ((int) strlen(point + 1) > pd->decimal_points) 309 if ((int) strlen(point + 1) > decimal_places)
331 { 310 {
332 *insert = 0; 311 *insert = 0;
333 goto end; 312 goto end;