7ec0a29c4c6b6812d17f712b256a2b5519993a4f
[platform/upstream/atk.git] / tests / testvalue.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  * Copyright 2014 Igalia S.L.
4  *
5  * Author: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 #include <atk/atk.h>
23
24 /**
25  * SECTION:testvalue
26  * @Short_description: this example serves as a unit test for AtkValue
27  *  and also as an example of how to implement #AtkValue on a given
28  *  GObject.
29  *
30  *  This test will represent a volume slider, smart enough to have
31  *  classify the values on the global range [0,1] with the
32  *  descriptions "low", "medium", "high" and "very high".  As the
33  *  clasification is fixed, it also expose all the four possible
34  *  subranges. To fill the description name it will use some of the
35  *  already defined #AtkValueType.
36  *
37  *  This will implement all the methods of #AtkValue, but note that
38  *  this is not mandatory on all the cases. In several cases it is not
39  *  needed to implement the subranges methods. See #AtkValue
40  *  documentation for further information.
41  *
42  */
43
44 #define EXPECTED_NUMBER 7
45
46 #define LOWER_LIMIT 0
47 #define LOW_THRESHOLD 0.2
48 #define NORMAL_THRESHOLD 0.4
49 #define HIGH_THRESHOLD 0.8
50 #define RISKY_THRESHOLD 1.0
51 #define UPPER_LIMIT 1.0
52 #define INCREMENT 0.15
53
54 GMainLoop *global_loop = NULL;
55 gint global_number_emissions = 0;
56 gboolean test_success = TRUE;
57 GObject *my_value;
58
59 #define TEST_TYPE_VALUE                         (test_value_get_type ())
60 #define TEST_VALUE(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_VALUE, TestValue))
61 #define TEST_VALUE_CLASS(klass)                 (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_VALUE, TestValueClass))
62 #define TEST_IS_VALUE(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_VALUE))
63 #define TEST_IS_VALUE_CLASS(klass)              (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_VALUE))
64 #define TEST_VALUE_GET_CLASS(obj)               (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_VALUE, TestValueClass))
65
66 typedef struct _TestValue        TestValue;
67 typedef struct _TestValueClass   TestValueClass;
68
69 struct _TestValue
70 {
71   AtkObject parent;
72
73   gdouble value;
74 };
75
76 struct _TestValueClass
77 {
78   AtkObjectClass parent_class;
79 };
80
81 GType       test_value_get_type (void) G_GNUC_CONST;
82 static void test_value_interface_init (AtkValueIface *iface);
83
84 G_DEFINE_TYPE_WITH_CODE (TestValue,
85                          test_value,
86                          ATK_TYPE_OBJECT,
87                          G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE,
88                                                 test_value_interface_init));
89
90 static void
91 test_value_class_init (TestValueClass *klass)
92 {
93 }
94
95 static void
96 test_value_init (TestValue *value)
97 {
98 }
99
100
101 static const gchar*
102 get_description (gdouble value)
103 {
104   const gchar *description = NULL;
105
106   if (value < LOW_THRESHOLD)
107     description = atk_value_type_get_localized_name (ATK_VALUE_LOW);
108   else if (value < NORMAL_THRESHOLD)
109     description = atk_value_type_get_localized_name (ATK_VALUE_MEDIUM);
110   else if (value < HIGH_THRESHOLD)
111     description = atk_value_type_get_localized_name (ATK_VALUE_HIGH);
112   else description = atk_value_type_get_localized_name (ATK_VALUE_VERY_HIGH);
113
114   return description;
115 }
116
117 static void
118 test_value_get_value_and_text (AtkValue *value,
119                                gdouble *current_value,
120                                gchar **description)
121 {
122   g_return_if_fail (TEST_IS_VALUE (value));
123
124   TestValue *self = TEST_VALUE (value);
125
126   if (current_value != NULL)
127     *current_value = self->value;
128
129   if (description != NULL)
130     *description = g_strdup (get_description (self->value));
131 }
132
133 AtkRange*
134 test_value_get_range (AtkValue *value)
135 {
136   g_return_val_if_fail (TEST_IS_VALUE (value), NULL);
137
138   AtkRange *result = atk_range_new (LOWER_LIMIT,
139                                     UPPER_LIMIT,
140                                     NULL);
141
142   return result;
143 }
144
145 gdouble
146 test_value_get_increment (AtkValue *value)
147 {
148   g_return_val_if_fail (TEST_IS_VALUE (value), 0.0);
149
150   return INCREMENT;
151 }
152
153 GSList*
154 test_value_get_sub_ranges (AtkValue *value)
155 {
156   g_return_val_if_fail (TEST_IS_VALUE (value), NULL);
157
158   GSList *result = NULL;
159   AtkRange *range = NULL;
160
161   /* low */
162   range = atk_range_new (LOWER_LIMIT, LOW_THRESHOLD,
163                          get_description (LOWER_LIMIT));
164
165   result = g_slist_append (result, range);
166
167   /* normal */
168   range = atk_range_new (LOW_THRESHOLD, NORMAL_THRESHOLD,
169                          get_description (LOW_THRESHOLD));
170   result = g_slist_append (result, range);
171
172   /* high */
173   range = atk_range_new (NORMAL_THRESHOLD, HIGH_THRESHOLD,
174                          get_description (NORMAL_THRESHOLD));
175   result = g_slist_append (result, range);
176
177   /* very high */
178   range = atk_range_new (HIGH_THRESHOLD, UPPER_LIMIT,
179                          get_description (HIGH_THRESHOLD));
180   result = g_slist_append (result, range);
181
182   return result;
183 }
184
185 void
186 test_value_set_value (AtkValue *value,
187                       double new_value)
188 {
189   g_return_if_fail (TEST_IS_VALUE (value));
190
191   TestValue *self = TEST_VALUE (value);
192
193   if (new_value < LOWER_LIMIT)
194     new_value = LOWER_LIMIT;
195
196   if (new_value > UPPER_LIMIT)
197     new_value = UPPER_LIMIT;
198
199   if (new_value != self->value) {
200     gchar *description = g_strdup (get_description (new_value));
201     self->value = new_value;
202     g_signal_emit_by_name (value, "value-changed", new_value, description, NULL);
203     g_free (description);
204   }
205 }
206
207 static void
208 test_value_interface_init (AtkValueIface *iface)
209 {
210   iface->get_value_and_text = test_value_get_value_and_text;
211   iface->get_range = test_value_get_range;
212   iface->get_increment = test_value_get_increment;
213   iface->get_sub_ranges = test_value_get_sub_ranges;
214   iface->set_value = test_value_set_value;
215 }
216
217 static void
218 value_page_changed_cb (AtkValue *value,
219                        gdouble new_value,
220                        gchar *new_description,
221                        gpointer data)
222 {
223   g_print ("value-changed callback=(%f,%s)\n", new_value, new_description);
224   global_number_emissions++;
225 }
226
227 /**
228  * This call simulates a user interacting with the slider.
229  *
230  */
231 static gboolean
232 do_value_changed (gpointer data)
233 {
234   TestValue* test_value = TEST_VALUE (data);
235
236   atk_value_set_value (ATK_VALUE (test_value),
237                        test_value->value + INCREMENT);
238
239   if (global_number_emissions == EXPECTED_NUMBER) {
240     g_main_loop_quit (global_loop);
241     return G_SOURCE_REMOVE;
242   } else
243     return G_SOURCE_CONTINUE;
244 }
245
246 /**
247  * Prints all the info from an AtkValue
248  */
249 static void
250 print_info (AtkValue *atk_value)
251 {
252   double value;
253   gchar *description;
254   AtkRange *range;
255   GSList *sub_ranges;
256   GSList *iter;
257   gdouble increment;
258   gint i = 0;
259
260   atk_value_get_value_and_text (atk_value, &value, &description);
261   range = atk_value_get_range (atk_value);
262   increment = atk_value_get_increment (atk_value);
263   atk_value_set_value (atk_value, 0);
264
265   g_print ("Current AtkValue data:\n");
266   g_print ("\t (value,description)=(%f,%s) \n", value, description);
267   if (range != NULL)
268     g_print ("\t (min,max,description)=(%f, %f, %s)\n",
269              atk_range_get_lower_limit (range), atk_range_get_upper_limit (range), atk_range_get_description (range));
270   else
271     test_success = FALSE; /* Any AtkValue implementation should provide a range */
272   g_print ("\t minimum increment=%f\n", increment);
273
274   if (range)
275     atk_range_free (range);
276
277   sub_ranges = atk_value_get_sub_ranges (atk_value);
278   for (iter = sub_ranges; iter != NULL; iter = g_slist_next (iter),i++) {
279     range = iter->data;
280     g_print ("\t\t sub_range%i = (%f, %f, %s)\n", i,
281              atk_range_get_lower_limit (range), atk_range_get_upper_limit (range), atk_range_get_description (range));
282   }
283
284   g_slist_free_full (sub_ranges, (GDestroyNotify) atk_range_free);
285 }
286
287
288 static gboolean
289 init_test_value (void)
290 {
291   my_value = g_object_new (TEST_TYPE_VALUE, NULL);
292
293   g_signal_connect (my_value, "value-changed",
294                     G_CALLBACK (value_page_changed_cb),
295                     NULL);
296
297   print_info (ATK_VALUE (my_value));
298
299   g_idle_add (do_value_changed, my_value);
300
301   return TRUE;
302 }
303
304
305 int
306 main (gint  argc,
307       char* argv[])
308 {
309   global_loop = g_main_loop_new (NULL, FALSE);
310
311   g_print("Starting Value test suite\n\n\n");
312
313   init_test_value ();
314   g_main_loop_run (global_loop);
315
316   if (global_number_emissions == EXPECTED_NUMBER && test_success)
317     g_print ("\n\nValue tests succeeded\n\n\n");
318   else
319     g_print ("\n\nValue tests failed\n\n\n");
320
321   print_info (ATK_VALUE (my_value));
322
323   return 0;
324 }