summaryrefslogtreecommitdiff
path: root/src/lib/efl
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/efl
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 '')
-rw-r--r--src/lib/efl/Efl.h1
-rw-r--r--src/lib/efl/interfaces/efl_ui_format.c169
-rw-r--r--src/lib/efl/interfaces/efl_ui_format.eo42
-rw-r--r--src/lib/efl/interfaces/meson.build2
4 files changed, 0 insertions, 214 deletions
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index aa88196720..5cbd1c2f96 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -147,7 +147,6 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
147#include "interfaces/efl_ui_property_bind.eo.h" 147#include "interfaces/efl_ui_property_bind.eo.h"
148#include "interfaces/efl_ui_factory.eo.h" 148#include "interfaces/efl_ui_factory.eo.h"
149#include "interfaces/efl_ui_factory_bind.eo.h" 149#include "interfaces/efl_ui_factory_bind.eo.h"
150#include "interfaces/efl_ui_format.eo.h"
151#include "interfaces/efl_cached_item.eo.h" 150#include "interfaces/efl_cached_item.eo.h"
152 151
153/* Observable interface */ 152/* Observable interface */
diff --git a/src/lib/efl/interfaces/efl_ui_format.c b/src/lib/efl/interfaces/efl_ui_format.c
deleted file mode 100644
index f6f1b811e2..0000000000
--- a/src/lib/efl/interfaces/efl_ui_format.c
+++ /dev/null
@@ -1,169 +0,0 @@
1#include "config.h"
2#include "Efl.h"
3
4#define ERR(...) EINA_LOG_DOM_ERR(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
5#define DBG(...) EINA_LOG_DOM_DBG(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
6
7typedef enum _Format_Type
8{
9 FORMAT_TYPE_INVALID,
10 FORMAT_TYPE_DOUBLE,
11 FORMAT_TYPE_INT,
12 FORMAT_TYPE_STRING,
13 FORMAT_TYPE_STATIC
14} Format_Type;
15
16typedef struct
17{
18 const char *template;
19 Format_Type format_type;
20} Efl_Ui_Format_Data;
21
22static Eina_Bool
23_is_valid_digit(char x)
24{
25 return ((x >= '0' && x <= '9') || (x == '.')) ? EINA_TRUE : EINA_FALSE;
26}
27
28static Format_Type
29_format_string_check(const char *fmt)
30{
31 const char *itr;
32 Eina_Bool found = EINA_FALSE;
33 Format_Type ret_type = FORMAT_TYPE_STATIC;
34
35 for (itr = fmt; *itr; itr++)
36 {
37 if (itr[0] != '%') continue;
38 if (itr[1] == '%')
39 {
40 itr++;
41 if (ret_type == FORMAT_TYPE_STATIC)
42 ret_type = FORMAT_TYPE_STRING;
43 continue;
44 }
45
46 if (!found)
47 {
48 found = EINA_TRUE;
49 for (itr++; *itr; itr++)
50 {
51 // FIXME: This does not properly support int64 or unsigned.
52 if ((*itr == 'd') || (*itr == 'u') || (*itr == 'i') ||
53 (*itr == 'o') || (*itr == 'x') || (*itr == 'X'))
54 {
55 ret_type = FORMAT_TYPE_INT;
56 break;
57 }
58 else if ((*itr == 'f') || (*itr == 'F'))
59 {
60 ret_type = FORMAT_TYPE_DOUBLE;
61 break;
62 }
63 else if (*itr == 's')
64 {
65 ret_type = FORMAT_TYPE_STRING;
66 break;
67 }
68 else if (_is_valid_digit(*itr))
69 {
70 continue;
71 }
72 else
73 {
74 ERR("Format string '%s' has unknown format element '%c' in format. It must have one format element of type 's', 'f', 'F', 'd', 'u', 'i', 'o', 'x' or 'X'", fmt, *itr);
75 found = EINA_FALSE;
76 break;
77 }
78 }
79 if (!(*itr)) break;
80 }
81 else
82 {
83 ret_type = FORMAT_TYPE_INVALID;
84 break;
85 }
86 }
87
88 if (ret_type == FORMAT_TYPE_INVALID)
89 {
90 ERR("Format string '%s' is invalid. It must have one and only one format element of type 's', 'f', 'F', 'd', 'u', 'i', 'o', 'x' or 'X'", fmt);
91 }
92 return ret_type;
93}
94
95static void
96_default_format_cb(void *data, Eina_Strbuf *str, const Eina_Value value)
97{
98 Efl_Ui_Format_Data *sd = data;
99 Eina_Value copy;
100
101 if (sd->format_type == FORMAT_TYPE_DOUBLE)
102 {
103 double v = 0.0;
104 eina_value_setup(&copy, EINA_VALUE_TYPE_DOUBLE);
105 eina_value_convert(&value, &copy);
106 eina_value_get(&copy, &v);
107 eina_strbuf_append_printf(str, sd->template, v);
108 eina_value_flush(&copy);
109 }
110 else if (sd->format_type == FORMAT_TYPE_INT)
111 {
112 int v = 0;
113 eina_value_setup(&copy, EINA_VALUE_TYPE_INT);
114 eina_value_convert(&value, &copy);
115 eina_value_get(&copy, &v);
116 eina_strbuf_append_printf(str, sd->template, v);
117 eina_value_flush(&copy);
118 }
119 else if (sd->format_type == FORMAT_TYPE_STRING)
120 {
121 char *v = eina_value_to_string(&value);
122 eina_strbuf_append_printf(str, sd->template, v);
123 free(v);
124 }
125 else if (sd->format_type == FORMAT_TYPE_STATIC)
126 {
127 eina_strbuf_append(str, sd->template);
128 }
129 else
130 {
131 // Error: Discard format string and just print value.
132 DBG("Could not guess value type in format string: '%s'", sd->template);
133 char *v = eina_value_to_string(&value);
134 eina_strbuf_append(str, v);
135 free(v);
136 }
137}
138
139static void
140_default_format_free_cb(void *data)
141{
142 Efl_Ui_Format_Data *sd = data;
143
144 if (sd && sd->template)
145 {
146 eina_stringshare_del(sd->template);
147 sd->template = NULL;
148 }
149}
150
151EOLIAN static void
152_efl_ui_format_format_string_set(Eo *obj, Efl_Ui_Format_Data *sd, const char *template)
153{
154 if (!template) return;
155
156 eina_stringshare_replace(&sd->template, template);
157 sd->format_type = _format_string_check(sd->template);
158
159 efl_ui_format_cb_set(obj, sd, _default_format_cb, _default_format_free_cb);
160}
161
162EOLIAN static const char *
163_efl_ui_format_format_string_get(const Eo *obj EINA_UNUSED, Efl_Ui_Format_Data *sd)
164{
165 return sd->template;
166}
167
168#include "interfaces/efl_ui_format.eo.c"
169
diff --git a/src/lib/efl/interfaces/efl_ui_format.eo b/src/lib/efl/interfaces/efl_ui_format.eo
deleted file mode 100644
index c7b6aba841..0000000000
--- a/src/lib/efl/interfaces/efl_ui_format.eo
+++ /dev/null
@@ -1,42 +0,0 @@
1import eina_types;
2
3function @beta Efl.Ui.Format_Func_Cb {
4 [[Function pointer for format function hook]]
5 params {
6 @in str: strbuf; [[the formated string to be appended by user.]]
7 @in value: const(any_value); [[The @Eina.Value passed by $obj.]]
8 }
9};
10
11mixin @beta Efl.Ui.Format
12{
13 [[interface class for format_func]]
14 methods {
15 @property format_cb {
16 set @pure_virtual {
17 [[Set the format function pointer to format the string.
18 ]]
19 }
20 values {
21 func: Efl.Ui.Format_Func_Cb; [[The format function callback]]
22 }
23 }
24 @property format_string {
25 [[Control the format string for a given units label
26
27 If $NULL is passed to $format, it will hide $obj's units
28 area completely. If not, it'll set the <b>format
29 string</b> for the units label text. The units label is
30 provided as a floating point value, so the units text can display
31 at most one floating point value. Note that the units label is
32 optional. Use a format string such as "%1.2f meters" for example.
33
34 Note: The default format string is an integer percentage,
35 as in $"%.0f %%".
36 ]]
37 values {
38 units: string; [[The format string for $obj's units label.]]
39 }
40 }
41 }
42}
diff --git a/src/lib/efl/interfaces/meson.build b/src/lib/efl/interfaces/meson.build
index e3baa55571..d09a24c255 100644
--- a/src/lib/efl/interfaces/meson.build
+++ b/src/lib/efl/interfaces/meson.build
@@ -94,7 +94,6 @@ pub_eo_files = [
94 'efl_observer.eo', 94 'efl_observer.eo',
95 'efl_observable.eo', 95 'efl_observable.eo',
96 'efl_ui_autorepeat.eo', 96 'efl_ui_autorepeat.eo',
97 'efl_ui_format.eo',
98 'efl_gfx_color_class.eo', 97 'efl_gfx_color_class.eo',
99 'efl_gfx_text_class.eo', 98 'efl_gfx_text_class.eo',
100 'efl_gfx_size_class.eo', 99 'efl_gfx_size_class.eo',
@@ -166,7 +165,6 @@ efl_src += files([
166 'efl_io_queue.c', 165 'efl_io_queue.c',
167 'efl_observer.c', 166 'efl_observer.c',
168 'efl_file.c', 167 'efl_file.c',
169 'efl_ui_format.c',
170 'efl_ui_layout_orientable_readonly.c', 168 'efl_ui_layout_orientable_readonly.c',
171 'efl_text_markup_util.c', 169 'efl_text_markup_util.c',
172]) 170])