1#include <gtk/gtk.h>
2
3static int
4sort_list (GtkListBoxRow *row1,
5 GtkListBoxRow *row2,
6 gpointer data)
7{
8 GtkWidget *label1, *label2;
9 int n1, n2;
10 int *count = data;
11
12 (*count)++;
13
14 label1 = gtk_list_box_row_get_child (row: row1);
15 n1 = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label1), "data"));
16
17 label2 = gtk_list_box_row_get_child (row: row2);
18 n2 = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label2), "data"));
19
20 return (n1 - n2);
21}
22
23static void
24check_sorted (GtkListBox *list)
25{
26 GtkWidget *row, *label;
27 int res[100];
28 int index, value;
29 int n_rows = 0;
30 int i;
31
32 for (row = gtk_widget_get_first_child (GTK_WIDGET (list));
33 row != NULL;
34 row = gtk_widget_get_next_sibling (widget: row))
35 {
36 if (!GTK_IS_LIST_BOX_ROW (row))
37 continue;
38
39 index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (row));
40 label = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row));
41 value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label), "data"));
42 res[index] = value;
43 n_rows++;
44 }
45
46 for (i = 1; i < n_rows; i++)
47 g_assert_cmpint (res[i - 1], <=, res[i]);
48}
49
50static void
51test_sort (void)
52{
53 GtkListBox *list;
54 GtkListBoxRow *row;
55 GtkWidget *label;
56 int i, r;
57 char *s;
58 int count;
59
60 list = GTK_LIST_BOX (gtk_list_box_new ());
61 g_object_ref_sink (list);
62 gtk_widget_show (GTK_WIDGET (list));
63
64 for (i = 0; i < 100; i++)
65 {
66 r = g_random_int_range (begin: 0, end: 1000);
67 s = g_strdup_printf (format: "%d: %d", i, r);
68 label = gtk_label_new (str: s);
69 g_object_set_data (G_OBJECT (label), key: "data", GINT_TO_POINTER (r));
70 g_free (mem: s);
71 gtk_list_box_insert (GTK_LIST_BOX (list), child: label, position: -1);
72 }
73
74 count = 0;
75 gtk_list_box_set_sort_func (box: list, sort_func: sort_list, user_data: &count, NULL);
76 g_assert_cmpint (count, >, 0);
77
78 check_sorted (list);
79
80 count = 0;
81 gtk_list_box_invalidate_sort (box: list);
82 g_assert_cmpint (count, >, 0);
83
84 count = 0;
85 row = gtk_list_box_get_row_at_index (box: list, index_: 0);
86 gtk_list_box_row_changed (row);
87 g_assert_cmpint (count, >, 0);
88
89 g_object_unref (object: list);
90}
91
92static GtkListBoxRow *callback_row;
93
94static void
95on_row_selected (GtkListBox *list_box,
96 GtkListBoxRow *row,
97 gpointer data)
98{
99 int *i = data;
100
101 (*i)++;
102
103 callback_row = row;
104}
105
106static void
107test_selection (void)
108{
109 GtkListBox *list;
110 GtkListBoxRow *row, *row2;
111 GtkWidget *label;
112 int i;
113 char *s;
114 int count;
115 int index;
116
117 list = GTK_LIST_BOX (gtk_list_box_new ());
118 g_object_ref_sink (list);
119 gtk_widget_show (GTK_WIDGET (list));
120
121 g_assert_cmpint (gtk_list_box_get_selection_mode (list), ==, GTK_SELECTION_SINGLE);
122 g_assert_null (gtk_list_box_get_selected_row (list));
123
124 for (i = 0; i < 100; i++)
125 {
126 s = g_strdup_printf (format: "%d", i);
127 label = gtk_label_new (str: s);
128 g_object_set_data (G_OBJECT (label), key: "data", GINT_TO_POINTER (i));
129 g_free (mem: s);
130 gtk_list_box_insert (GTK_LIST_BOX (list), child: label, position: -1);
131 }
132
133 count = 0;
134 g_signal_connect (list, "row-selected",
135 G_CALLBACK (on_row_selected),
136 &count);
137
138 row = gtk_list_box_get_row_at_index (box: list, index_: 20);
139 g_assert_false (gtk_list_box_row_is_selected (row));
140 gtk_list_box_select_row (box: list, row);
141 g_assert_true (gtk_list_box_row_is_selected (row));
142 g_assert_true (callback_row == row);
143 g_assert_cmpint (count, ==, 1);
144 row2 = gtk_list_box_get_selected_row (box: list);
145 g_assert_true (row2 == row);
146 gtk_list_box_unselect_all (box: list);
147 row2 = gtk_list_box_get_selected_row (box: list);
148 g_assert_null (row2);
149 gtk_list_box_select_row (box: list, row);
150 row2 = gtk_list_box_get_selected_row (box: list);
151 g_assert_true (row2 == row);
152
153 gtk_list_box_set_selection_mode (box: list, mode: GTK_SELECTION_BROWSE);
154 gtk_list_box_remove (GTK_LIST_BOX (list), GTK_WIDGET (row));
155 g_assert_null (callback_row);
156 g_assert_cmpint (count, ==, 4);
157 row2 = gtk_list_box_get_selected_row (box: list);
158 g_assert_null (row2);
159
160 row = gtk_list_box_get_row_at_index (box: list, index_: 20);
161 gtk_list_box_select_row (box: list, row);
162 g_assert_true (gtk_list_box_row_is_selected (row));
163 g_assert_true (callback_row == row);
164 g_assert_cmpint (count, ==, 5);
165
166 gtk_list_box_set_selection_mode (box: list, mode: GTK_SELECTION_NONE);
167 g_assert_false (gtk_list_box_row_is_selected (row));
168 g_assert_null (callback_row);
169 g_assert_cmpint (count, ==, 6);
170 row2 = gtk_list_box_get_selected_row (box: list);
171 g_assert_null (row2);
172
173 row = gtk_list_box_get_row_at_index (box: list, index_: 20);
174 index = gtk_list_box_row_get_index (row);
175 g_assert_cmpint (index, ==, 20);
176
177 row = GTK_LIST_BOX_ROW (gtk_list_box_row_new ());
178 g_object_ref_sink (row);
179 index = gtk_list_box_row_get_index (row);
180 g_assert_cmpint (index, ==, -1);
181 g_object_unref (object: row);
182
183 g_object_unref (object: list);
184}
185
186static void
187on_selected_rows_changed (GtkListBox *box, gpointer data)
188{
189 int *i = data;
190
191 (*i)++;
192}
193
194static void
195test_multi_selection (void)
196{
197 GtkListBox *list;
198 GList *l;
199 GtkListBoxRow *row, *row2;
200 GtkWidget *label;
201 int i;
202 char *s;
203 int count;
204
205 list = GTK_LIST_BOX (gtk_list_box_new ());
206 g_object_ref_sink (list);
207 gtk_widget_show (GTK_WIDGET (list));
208
209 g_assert_cmpint (gtk_list_box_get_selection_mode (list), ==, GTK_SELECTION_SINGLE);
210 g_assert_null (gtk_list_box_get_selected_rows (list));
211
212 gtk_list_box_set_selection_mode (box: list, mode: GTK_SELECTION_MULTIPLE);
213
214 for (i = 0; i < 100; i++)
215 {
216 s = g_strdup_printf (format: "%d", i);
217 label = gtk_label_new (str: s);
218 g_object_set_data (G_OBJECT (label), key: "data", GINT_TO_POINTER (i));
219 g_free (mem: s);
220 gtk_list_box_insert (GTK_LIST_BOX (list), child: label, position: -1);
221 }
222
223 count = 0;
224 g_signal_connect (list, "selected-rows-changed",
225 G_CALLBACK (on_selected_rows_changed),
226 &count);
227
228 row = gtk_list_box_get_row_at_index (box: list, index_: 20);
229
230 gtk_list_box_select_all (box: list);
231 g_assert_cmpint (count, ==, 1);
232 l = gtk_list_box_get_selected_rows (box: list);
233 g_assert_cmpint (g_list_length (l), ==, 100);
234 g_list_free (list: l);
235 g_assert_true (gtk_list_box_row_is_selected (row));
236
237 gtk_list_box_unselect_all (box: list);
238 g_assert_cmpint (count, ==, 2);
239 l = gtk_list_box_get_selected_rows (box: list);
240 g_assert_null (l);
241 g_assert_false (gtk_list_box_row_is_selected (row));
242
243 gtk_list_box_select_row (box: list, row);
244 g_assert_true (gtk_list_box_row_is_selected (row));
245 g_assert_cmpint (count, ==, 3);
246 l = gtk_list_box_get_selected_rows (box: list);
247 g_assert_cmpint (g_list_length (l), ==, 1);
248 g_assert_true (l->data == row);
249 g_list_free (list: l);
250
251 row2 = gtk_list_box_get_row_at_index (box: list, index_: 40);
252 g_assert_false (gtk_list_box_row_is_selected (row2));
253 gtk_list_box_select_row (box: list, row: row2);
254 g_assert_true (gtk_list_box_row_is_selected (row2));
255 g_assert_cmpint (count, ==, 4);
256 l = gtk_list_box_get_selected_rows (box: list);
257 g_assert_cmpint (g_list_length (l), ==, 2);
258 g_assert_true (l->data == row);
259 g_assert_true (l->next->data == row2);
260 g_list_free (list: l);
261
262 gtk_list_box_unselect_row (box: list, row);
263 g_assert_false (gtk_list_box_row_is_selected (row));
264 g_assert_cmpint (count, ==, 5);
265 l = gtk_list_box_get_selected_rows (box: list);
266 g_assert_cmpint (g_list_length (l), ==, 1);
267 g_assert_true (l->data == row2);
268 g_list_free (list: l);
269
270 g_object_unref (object: list);
271}
272
273static gboolean
274filter_func (GtkListBoxRow *row,
275 gpointer data)
276{
277 int *count = data;
278 GtkWidget *child;
279 int i;
280
281 (*count)++;
282
283 child = gtk_list_box_row_get_child (row);
284 i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "data"));
285
286 return (i % 2) == 0;
287}
288
289static void
290check_filtered (GtkListBox *list)
291{
292 int count;
293 GtkWidget *row;
294
295 count = 0;
296 for (row = gtk_widget_get_first_child (GTK_WIDGET (list));
297 row != NULL;
298 row = gtk_widget_get_next_sibling (widget: row))
299 {
300 if (!GTK_IS_LIST_BOX_ROW (row))
301 continue;
302
303 if (gtk_widget_get_child_visible (widget: row))
304 count++;
305 }
306 g_assert_cmpint (count, ==, 50);
307}
308
309static void
310test_filter (void)
311{
312 GtkListBox *list;
313 GtkListBoxRow *row;
314 int i;
315 char *s;
316 GtkWidget *label;
317 int count;
318
319 list = GTK_LIST_BOX (gtk_list_box_new ());
320 g_object_ref_sink (list);
321 gtk_widget_show (GTK_WIDGET (list));
322
323 g_assert_cmpint (gtk_list_box_get_selection_mode (list), ==, GTK_SELECTION_SINGLE);
324 g_assert_null (gtk_list_box_get_selected_row (list));
325
326 for (i = 0; i < 100; i++)
327 {
328 s = g_strdup_printf (format: "%d", i);
329 label = gtk_label_new (str: s);
330 g_object_set_data (G_OBJECT (label), key: "data", GINT_TO_POINTER (i));
331 g_free (mem: s);
332 gtk_list_box_insert (GTK_LIST_BOX (list), child: label, position: -1);
333 }
334
335 count = 0;
336 gtk_list_box_set_filter_func (box: list, filter_func, user_data: &count, NULL);
337 g_assert_cmpint (count, >, 0);
338
339 check_filtered (list);
340
341 count = 0;
342 gtk_list_box_invalidate_filter (box: list);
343 g_assert_cmpint (count, >, 0);
344
345 count = 0;
346 row = gtk_list_box_get_row_at_index (box: list, index_: 0);
347 gtk_list_box_row_changed (row);
348 g_assert_cmpint (count, >, 0);
349
350 g_object_unref (object: list);
351}
352
353static void
354header_func (GtkListBoxRow *row,
355 GtkListBoxRow *before,
356 gpointer data)
357{
358 GtkWidget *child;
359 int i;
360 int *count = data;
361 GtkWidget *header;
362 char *s;
363
364 (*count)++;
365
366 child = gtk_list_box_row_get_child (row);
367 i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "data"));
368
369 if (i % 2 == 0)
370 {
371 s = g_strdup_printf (format: "Header %d", i);
372 header = gtk_label_new (str: s);
373 g_free (mem: s);
374 }
375 else
376 header = NULL;
377
378 gtk_list_box_row_set_header (row, header);
379}
380
381static void
382check_headers (GtkListBox *list)
383{
384 int count;
385 GtkWidget *row;
386
387 count = 0;
388 for (row = gtk_widget_get_first_child (GTK_WIDGET (list));
389 row != NULL;
390 row = gtk_widget_get_next_sibling (widget: row))
391 {
392 if (!GTK_IS_LIST_BOX_ROW (row))
393 continue;
394
395 if (gtk_list_box_row_get_header (GTK_LIST_BOX_ROW (row)) != NULL)
396 count++;
397 }
398 g_assert_cmpint (count, ==, 50);
399}
400
401static void
402test_header (void)
403{
404 GtkListBox *list;
405 GtkListBoxRow *row;
406 int i;
407 char *s;
408 GtkWidget *label;
409 int count;
410
411 list = GTK_LIST_BOX (gtk_list_box_new ());
412 g_object_ref_sink (list);
413 gtk_widget_show (GTK_WIDGET (list));
414
415 g_assert_cmpint (gtk_list_box_get_selection_mode (list), ==, GTK_SELECTION_SINGLE);
416 g_assert_null (gtk_list_box_get_selected_row (list));
417
418 for (i = 0; i < 100; i++)
419 {
420 s = g_strdup_printf (format: "%d", i);
421 label = gtk_label_new (str: s);
422 g_object_set_data (G_OBJECT (label), key: "data", GINT_TO_POINTER (i));
423 g_free (mem: s);
424 gtk_list_box_insert (GTK_LIST_BOX (list), child: label, position: -1);
425 }
426
427 count = 0;
428 gtk_list_box_set_header_func (box: list, update_header: header_func, user_data: &count, NULL);
429 g_assert_cmpint (count, >, 0);
430
431 check_headers (list);
432
433 count = 0;
434 gtk_list_box_invalidate_headers (box: list);
435 g_assert_cmpint (count, >, 0);
436
437 count = 0;
438 row = gtk_list_box_get_row_at_index (box: list, index_: 0);
439 gtk_list_box_row_changed (row);
440 g_assert_cmpint (count, >, 0);
441
442 g_object_unref (object: list);
443}
444
445int
446main (int argc, char *argv[])
447{
448 gtk_test_init (argcp: &argc, argvp: &argv);
449
450 g_test_add_func (testpath: "/listbox/sort", test_func: test_sort);
451 g_test_add_func (testpath: "/listbox/selection", test_func: test_selection);
452 g_test_add_func (testpath: "/listbox/multi-selection", test_func: test_multi_selection);
453 g_test_add_func (testpath: "/listbox/filter", test_func: test_filter);
454 g_test_add_func (testpath: "/listbox/header", test_func: test_header);
455
456 return g_test_run ();
457}
458

source code of gtk/testsuite/gtk/listbox.c