Add a test for g_list_box_bind_model
This commit is contained in:
		| @ -167,6 +167,7 @@ noinst_PROGRAMS =  $(TEST_PROGS)	\ | |||||||
| 	testwindowsize			\ | 	testwindowsize			\ | ||||||
| 	testpopover			\ | 	testpopover			\ | ||||||
| 	gdkgears			\ | 	gdkgears			\ | ||||||
|  | 	listmodel			\ | ||||||
| 	$(NULL) | 	$(NULL) | ||||||
|  |  | ||||||
| if USE_X11 | if USE_X11 | ||||||
| @ -306,6 +307,7 @@ teststack_DEPENDENCIES = $(TEST_DEPS) | |||||||
| testrevealer_DEPENDENCIES = $(TEST_DEPS) | testrevealer_DEPENDENCIES = $(TEST_DEPS) | ||||||
| testtitlebar_DEPENDENCIES = $(TEST_DEPS) | testtitlebar_DEPENDENCIES = $(TEST_DEPS) | ||||||
| testwindowsize_DEPENDENCIES = $(TEST_DEPS) | testwindowsize_DEPENDENCIES = $(TEST_DEPS) | ||||||
|  | listmodel_DEPENDENCIES = $(TEST_DEPS) | ||||||
|  |  | ||||||
| animated_resizing_SOURCES = 	\ | animated_resizing_SOURCES = 	\ | ||||||
| 	animated-resizing.c	\ | 	animated-resizing.c	\ | ||||||
| @ -538,6 +540,8 @@ testglblending_SOURCES =	\ | |||||||
| 	gtkgears.c	\ | 	gtkgears.c	\ | ||||||
| 	gtkgears.h | 	gtkgears.h | ||||||
|  |  | ||||||
|  | listmodel_SOURCES = listmodel.c | ||||||
|  |  | ||||||
| EXTRA_DIST += 			\ | EXTRA_DIST += 			\ | ||||||
| 	gradient1.png		\ | 	gradient1.png		\ | ||||||
| 	testgtk.1 		\ | 	testgtk.1 		\ | ||||||
|  | |||||||
							
								
								
									
										220
									
								
								tests/listmodel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								tests/listmodel.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,220 @@ | |||||||
|  | #include <gtk/gtk.h> | ||||||
|  |  | ||||||
|  | enum | ||||||
|  | { | ||||||
|  |   PROP_LABEL = 1, | ||||||
|  |   PROP_ID, | ||||||
|  |   LAST_PROPERTY | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static GParamSpec *properties[LAST_PROPERTY] = { NULL, }; | ||||||
|  |  | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   GObject parent; | ||||||
|  |  | ||||||
|  |   gchar *label; | ||||||
|  |   gint id; | ||||||
|  | } MyObject; | ||||||
|  |  | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   GObjectClass parent_class; | ||||||
|  | } MyObjectClass; | ||||||
|  |  | ||||||
|  | G_DEFINE_TYPE (MyObject, my_object, G_TYPE_OBJECT) | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | my_object_init (MyObject *obj) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | my_object_get_property (GObject    *object, | ||||||
|  |                         guint       property_id, | ||||||
|  |                         GValue     *value, | ||||||
|  |                         GParamSpec *pspec) | ||||||
|  | { | ||||||
|  |   MyObject *obj = (MyObject *)object; | ||||||
|  |  | ||||||
|  |   switch (property_id) | ||||||
|  |     { | ||||||
|  |     case PROP_LABEL: | ||||||
|  |       g_value_set_string (value, obj->label); | ||||||
|  |       break; | ||||||
|  |     case PROP_ID: | ||||||
|  |       g_value_set_int (value, obj->id); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | my_object_set_property (GObject      *object, | ||||||
|  |                         guint         property_id, | ||||||
|  |                         const GValue *value, | ||||||
|  |                         GParamSpec   *pspec) | ||||||
|  | { | ||||||
|  |   MyObject *obj = (MyObject *)object; | ||||||
|  |  | ||||||
|  |   switch (property_id) | ||||||
|  |     { | ||||||
|  |     case PROP_LABEL: | ||||||
|  |       g_free (obj->label); | ||||||
|  |       obj->label = g_value_dup_string (value); | ||||||
|  |       break; | ||||||
|  |     case PROP_ID: | ||||||
|  |       obj->id = g_value_get_int (value); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | my_object_finalize (GObject *obj) | ||||||
|  | { | ||||||
|  |   MyObject *object = (MyObject *)obj; | ||||||
|  |  | ||||||
|  |   g_free (object->label); | ||||||
|  |  | ||||||
|  |   G_OBJECT_CLASS (my_object_parent_class)->finalize (obj); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | my_object_class_init (MyObjectClass *class) | ||||||
|  | { | ||||||
|  |   GObjectClass *object_class = G_OBJECT_CLASS (class); | ||||||
|  |  | ||||||
|  |   object_class->get_property = my_object_get_property; | ||||||
|  |   object_class->set_property = my_object_set_property; | ||||||
|  |   object_class->finalize = my_object_finalize; | ||||||
|  |  | ||||||
|  |   properties[PROP_LABEL] = g_param_spec_string ("label", "label", "label", | ||||||
|  |                                                 NULL, G_PARAM_READWRITE); | ||||||
|  |   properties[PROP_ID] = g_param_spec_int ("id", "id", "id", | ||||||
|  |                                           0, G_MAXINT, 0, G_PARAM_READWRITE); | ||||||
|  |  | ||||||
|  |   g_object_class_install_properties (object_class, LAST_PROPERTY, properties); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static GtkWidget * | ||||||
|  | create_widget (gpointer item, | ||||||
|  |                gpointer user_data) | ||||||
|  | { | ||||||
|  |   MyObject *obj = (MyObject *)item; | ||||||
|  |   GtkWidget *label; | ||||||
|  |  | ||||||
|  |   label = gtk_label_new (""); | ||||||
|  |   g_object_bind_property (obj, "label", label, "label", G_BINDING_SYNC_CREATE); | ||||||
|  |  | ||||||
|  |   return label; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static gint | ||||||
|  | compare_items (gconstpointer a, gconstpointer b, gpointer data) | ||||||
|  | { | ||||||
|  |   gint id_a, id_b; | ||||||
|  |  | ||||||
|  |   g_object_get ((gpointer)a, "id", &id_a, NULL); | ||||||
|  |   g_object_get ((gpointer)b, "id", &id_b, NULL); | ||||||
|  |  | ||||||
|  |   return id_a - id_b; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | add_some (GtkButton *button, GListStore *store) | ||||||
|  | { | ||||||
|  |   gint n, i; | ||||||
|  |   guint n_items; | ||||||
|  |   GObject *obj; | ||||||
|  |   gchar *label; | ||||||
|  |  | ||||||
|  |   for (n = 0; n < 50; n++) | ||||||
|  |     { | ||||||
|  |       n_items = g_list_model_get_n_items (G_LIST_MODEL (store)); | ||||||
|  |       i = g_random_int_range (0, MAX (2 * n_items, 1)); | ||||||
|  |       label = g_strdup_printf ("Added %d", i); | ||||||
|  |       obj = g_object_new (my_object_get_type (), | ||||||
|  |                           "id", i, | ||||||
|  |                           "label", label, | ||||||
|  |                           NULL); | ||||||
|  |       g_list_store_insert_sorted (store, obj, compare_items, NULL); | ||||||
|  |       g_object_unref (obj); | ||||||
|  |       g_free (label); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | remove_some (GtkButton *button, GListStore *store) | ||||||
|  | { | ||||||
|  |   gint n, i; | ||||||
|  |   guint n_items; | ||||||
|  |  | ||||||
|  |   for (n = 0; n < 50; n++) | ||||||
|  |     { | ||||||
|  |       n_items = g_list_model_get_n_items (G_LIST_MODEL (store)); | ||||||
|  |       if (n_items == 0) | ||||||
|  |         return; | ||||||
|  |       i = g_random_int_range (0, n_items); | ||||||
|  |       g_list_store_remove (store, i); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main (int argc, char *argv[]) | ||||||
|  | { | ||||||
|  |   GtkWidget *window, *grid, *sw, *list, *button; | ||||||
|  |   GListStore *store; | ||||||
|  |   gint i; | ||||||
|  |  | ||||||
|  |   gtk_init (NULL, NULL); | ||||||
|  |  | ||||||
|  |   window = gtk_window_new (GTK_WINDOW_TOPLEVEL); | ||||||
|  |   grid = gtk_grid_new (); | ||||||
|  |   gtk_container_add (GTK_CONTAINER (window), grid); | ||||||
|  |   sw = gtk_scrolled_window_new (NULL, NULL); | ||||||
|  |   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), | ||||||
|  |                                   GTK_POLICY_AUTOMATIC, | ||||||
|  |                                   GTK_POLICY_AUTOMATIC); | ||||||
|  |   gtk_widget_set_hexpand (sw, TRUE); | ||||||
|  |   gtk_widget_set_vexpand (sw, TRUE); | ||||||
|  |   gtk_grid_attach (GTK_GRID (grid), sw, 0, 0, 1, 1); | ||||||
|  |  | ||||||
|  |   store = g_list_store_new (my_object_get_type ()); | ||||||
|  |   for (i = 0; i < 100; i++) | ||||||
|  |     { | ||||||
|  |       MyObject *obj; | ||||||
|  |       gchar *label; | ||||||
|  |  | ||||||
|  |       label = g_strdup_printf ("item %d", i); | ||||||
|  |       obj = g_object_new (my_object_get_type (), | ||||||
|  |                           "id", i, | ||||||
|  |                           "label", label, | ||||||
|  |                           NULL); | ||||||
|  |       g_list_store_append (store, obj); | ||||||
|  |       g_free (label); | ||||||
|  |       g_object_unref (obj); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   list = gtk_list_box_new (); | ||||||
|  |   gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (store), create_widget, NULL, NULL); | ||||||
|  |   gtk_container_add (GTK_CONTAINER (sw), list); | ||||||
|  |  | ||||||
|  |   button = gtk_button_new_with_label ("Add some"); | ||||||
|  |   g_signal_connect (button, "clicked", G_CALLBACK (add_some), store); | ||||||
|  |   gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1); | ||||||
|  |  | ||||||
|  |   button = gtk_button_new_with_label ("Remove some"); | ||||||
|  |   g_signal_connect (button, "clicked", G_CALLBACK (remove_some), store); | ||||||
|  |   gtk_grid_attach (GTK_GRID (grid), button, 0, 2, 1, 1); | ||||||
|  |  | ||||||
|  |   gtk_widget_show_all (window); | ||||||
|  |  | ||||||
|  |   gtk_main (); | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Matthias Clasen
					Matthias Clasen