1#include <gtk/gtk.h>
2
3#ifdef SMALL
4#define AVERAGE 15
5#define VARIANCE 10
6#else
7#define AVERAGE 300
8#define VARIANCE 200
9#endif
10
11static void
12setup_list_item (GtkSignalListItemFactory *factory,
13 GtkListItem *list_item)
14{
15 GtkWidget *label = gtk_label_new (str: "");
16
17 gtk_list_item_set_child (self: list_item, child: label);
18}
19
20static void
21bind_list_item (GtkSignalListItemFactory *factory,
22 GtkListItem *list_item)
23{
24 GtkWidget *label;
25 gpointer item;
26 char *s;
27
28 item = gtk_list_item_get_item (self: list_item);
29
30 if (item)
31 s = g_strdup_printf (format: "%u: %s",
32 gtk_list_item_get_position (self: list_item),
33 (const char *) g_object_get_data (object: item, key: "message"));
34 else
35 s = NULL;
36
37 label = gtk_list_item_get_child (self: list_item);
38 gtk_label_set_text (GTK_LABEL (label), str: s);
39
40 g_free (mem: s);
41}
42
43static GtkWidget *
44create_widget_for_listbox (gpointer item,
45 gpointer unused)
46{
47 const char *message = g_object_get_data (object: item, key: "message");
48 GtkWidget *widget;
49
50 widget = gtk_label_new (str: message);
51
52 return widget;
53}
54
55static guint
56get_number (GObject *item)
57{
58 return GPOINTER_TO_UINT (g_object_get_data (item, "counter")) % 1000;
59}
60
61static void
62add (GListStore *store)
63{
64 static guint counter;
65 GObject *o;
66 char *message;
67 guint pos;
68
69 counter++;
70 o = g_object_new (G_TYPE_OBJECT, NULL);
71 g_object_set_data (object: o, key: "counter", GUINT_TO_POINTER (counter));
72 message = g_strdup_printf (format: "Item %u", counter);
73 g_object_set_data_full (object: o, key: "message", data: message, destroy: g_free);
74
75 pos = g_random_int_range (begin: 0, end: g_list_model_get_n_items (list: G_LIST_MODEL (ptr: store)) + 1);
76 g_list_store_insert (store, position: pos, item: o);
77 g_object_unref (object: o);
78}
79
80static void
81delete (GListStore *store)
82{
83 guint pos;
84
85 pos = g_random_int_range (begin: 0, end: g_list_model_get_n_items (list: G_LIST_MODEL (ptr: store)));
86 g_list_store_remove (store, position: pos);
87}
88
89static gboolean
90do_stuff (gpointer store)
91{
92 if (g_random_int_range (AVERAGE - VARIANCE, AVERAGE + VARIANCE) < g_list_model_get_n_items (list: store))
93 delete (store);
94 else
95 add (store);
96
97 return G_SOURCE_CONTINUE;
98}
99
100static gboolean
101revert_sort (gpointer sorter)
102{
103 if (gtk_numeric_sorter_get_sort_order (self: sorter) == GTK_SORT_ASCENDING)
104 gtk_numeric_sorter_set_sort_order (self: sorter, sort_order: GTK_SORT_DESCENDING);
105 else
106 gtk_numeric_sorter_set_sort_order (self: sorter, sort_order: GTK_SORT_ASCENDING);
107
108 return G_SOURCE_CONTINUE;
109}
110
111int
112main (int argc,
113 char *argv[])
114{
115 GtkWidget *win, *hbox, *vbox, *sw, *listview, *listbox, *label;
116 GListStore *store;
117 GListModel *toplevels;
118 GtkSortListModel *sort;
119 GtkSorter *sorter;
120 guint i;
121 GtkListItemFactory *factory;
122 GtkSelectionModel *selection;
123
124 gtk_init ();
125
126 store = g_list_store_new (G_TYPE_OBJECT);
127 for (i = 0; i < AVERAGE; i++)
128 add (store);
129 sorter = GTK_SORTER (ptr: gtk_numeric_sorter_new (expression: gtk_cclosure_expression_new (G_TYPE_UINT, NULL, n_params: 0, NULL, callback_func: (GCallback)get_number, NULL, NULL)));
130 sort = gtk_sort_list_model_new (model: G_LIST_MODEL (ptr: store), sorter);
131
132 win = gtk_window_new ();
133 gtk_window_set_default_size (GTK_WINDOW (win), width: 400, height: 600);
134
135 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 4);
136 gtk_window_set_child (GTK_WINDOW (win), child: hbox);
137
138 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 4);
139 gtk_box_append (GTK_BOX (hbox), child: vbox);
140
141 label = gtk_label_new (str: "GtkListView");
142 gtk_box_append (GTK_BOX (vbox), child: label);
143
144 sw = gtk_scrolled_window_new ();
145 gtk_widget_set_hexpand (widget: sw, TRUE);
146 gtk_widget_set_vexpand (widget: sw, TRUE);
147 gtk_box_append (GTK_BOX (vbox), child: sw);
148
149 factory = gtk_signal_list_item_factory_new ();
150 g_signal_connect (factory, "setup", G_CALLBACK (setup_list_item), NULL);
151 g_signal_connect (factory, "bind", G_CALLBACK (bind_list_item), NULL);
152 listview = gtk_list_view_new (NULL, factory);
153
154 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child: listview);
155
156 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 4);
157 gtk_box_append (GTK_BOX (hbox), child: vbox);
158
159 label = gtk_label_new (str: "GtkListBox");
160 gtk_box_append (GTK_BOX (vbox), child: label);
161
162 sw = gtk_scrolled_window_new ();
163 gtk_widget_set_hexpand (widget: sw, TRUE);
164 gtk_widget_set_vexpand (widget: sw, TRUE);
165 gtk_box_append (GTK_BOX (vbox), child: sw);
166
167 listbox = gtk_list_box_new ();
168 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child: listbox);
169
170 selection = GTK_SELECTION_MODEL (ptr: gtk_single_selection_new (model: G_LIST_MODEL (ptr: sort)));
171 gtk_list_view_set_model (GTK_LIST_VIEW (listview), model: selection);
172 g_object_unref (object: selection);
173 gtk_list_box_bind_model (GTK_LIST_BOX (listbox),
174 model: G_LIST_MODEL (ptr: sort),
175 create_widget_func: create_widget_for_listbox,
176 NULL, NULL);
177
178 g_timeout_add (interval: 100, function: do_stuff, data: store);
179 g_timeout_add_seconds (interval: 3, function: revert_sort, data: sorter);
180
181 gtk_widget_show (widget: win);
182
183 toplevels = gtk_window_get_toplevels ();
184 while (g_list_model_get_n_items (list: toplevels))
185 g_main_context_iteration (NULL, TRUE);
186
187 return 0;
188}
189

source code of gtk/tests/testlistview-animating.c