summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2018-06-12 03:56:21 +0200
committerBenjamin Otte <otte@redhat.com>2018-09-16 18:50:17 +0200
commit573c63973abb30d99fc953037f8b303f5b4f3387 (patch)
treefc14bc2dc5c2e1172e8076a66bc49534d678c392 /tests
parentd7a5dcba0b06a51781b4c7207f47f2155646dbc0 (diff)
downloadgtk+-573c63973abb30d99fc953037f8b303f5b4f3387.tar.gz
gtk: Add GtkTreeListModel
This is a GListModel implementation with a neat API that can be used to implement trees inside GtkListBox.
Diffstat (limited to 'tests')
-rw-r--r--tests/meson.build1
-rw-r--r--tests/testtreelistmodel.c152
2 files changed, 153 insertions, 0 deletions
diff --git a/tests/meson.build b/tests/meson.build
index 16beab8d36..a6d6350662 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -112,6 +112,7 @@ gtk_tests = [
['testrevealer'],
['testrevealer2'],
['testtitlebar'],
+ ['testtreelistmodel'],
['testsplitheaders'],
['teststackedheaders'],
['testactionbar'],
diff --git a/tests/testtreelistmodel.c b/tests/testtreelistmodel.c
new file mode 100644
index 0000000000..e22b2bcec2
--- /dev/null
+++ b/tests/testtreelistmodel.c
@@ -0,0 +1,152 @@
+#include <gtk/gtk.h>
+
+static GListModel *
+create_list_model_for_directory (gpointer file,
+ gpointer unused)
+{
+ GFileEnumerator *enumerate;
+ GListStore *store;
+ GFile *child;
+ GFileInfo *info;
+
+ enumerate = g_file_enumerate_children (file,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE
+ "," G_FILE_ATTRIBUTE_STANDARD_NAME,
+ 0,
+ NULL,
+ NULL);
+ if (enumerate == NULL)
+ return NULL;
+
+ store = g_list_store_new (G_TYPE_FILE);
+
+ while (g_file_enumerator_iterate (enumerate, &info, NULL, NULL, NULL))
+ {
+ if (info == NULL)
+ break;
+
+ if (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
+ continue;
+
+ child = g_file_get_child (file, g_file_info_get_name (info));
+ g_list_store_append (store, child);
+ g_object_unref (child);
+ }
+
+ g_object_unref (enumerate);
+
+ return G_LIST_MODEL (store);
+}
+
+static GtkTreeListModel *
+get_tree_list_model (GtkWidget *row)
+{
+ return GTK_TREE_LIST_MODEL (g_object_get_data (G_OBJECT (gtk_widget_get_parent (row)), "model"));
+}
+
+static void
+expand_clicked (GtkWidget *button,
+ GtkWidget *row)
+{
+ gtk_tree_list_model_set_expanded (get_tree_list_model (row),
+ gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (row)),
+ TRUE);
+}
+
+static void
+collapse_clicked (GtkWidget *button,
+ GtkWidget *row)
+{
+ gtk_tree_list_model_set_expanded (get_tree_list_model (row),
+ gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (row)),
+ FALSE);
+}
+
+static GtkWidget *
+create_widget_for_model (gpointer file,
+ gpointer root)
+{
+ GtkWidget *row, *box, *child;
+ GFile *iter;
+ guint depth;
+
+ row = gtk_list_box_row_new ();
+
+ depth = 0;
+ for (iter = g_object_ref (g_file_get_parent (file));
+ !g_file_equal (root, iter);
+ g_set_object (&iter, g_file_get_parent (iter)))
+ {
+ g_object_unref (iter);
+ depth++;
+ }
+ g_object_unref (iter);
+ g_object_unref (iter);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_container_add (GTK_CONTAINER (row), box);
+
+ if (depth > 0)
+ {
+ child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_size_request (child, 16 * depth, 0);
+ gtk_container_add (GTK_CONTAINER (box), child);
+ }
+
+ child = gtk_button_new_from_icon_name ("list-remove-symbolic");
+ gtk_button_set_relief (GTK_BUTTON (child), GTK_RELIEF_NONE);
+ g_signal_connect (child, "clicked", G_CALLBACK (collapse_clicked), row);
+ gtk_container_add (GTK_CONTAINER (box), child);
+
+ child = gtk_button_new_from_icon_name ("list-add-symbolic");
+ gtk_button_set_relief (GTK_BUTTON (child), GTK_RELIEF_NONE);
+ g_signal_connect (child, "clicked", G_CALLBACK (expand_clicked), row);
+ gtk_container_add (GTK_CONTAINER (box), child);
+
+ child = gtk_label_new (g_file_get_basename (file));
+ gtk_container_add (GTK_CONTAINER (box), child);
+
+ return row;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *win;
+ GtkWidget *sw;
+ GtkWidget *listbox;
+ GListModel *model, *dirmodel;
+ GFile *root;
+
+ gtk_init ();
+
+ win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (win), 400, 600);
+ g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), win);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (win), sw);
+
+ listbox = gtk_list_box_new ();
+ gtk_container_add (GTK_CONTAINER (sw), listbox);
+
+ root = g_file_new_for_path (g_get_current_dir ());
+ dirmodel = create_list_model_for_directory (root, NULL);
+ model = G_LIST_MODEL (gtk_tree_list_model_new (dirmodel,
+ FALSE,
+ create_list_model_for_directory,
+ NULL, NULL));
+ g_object_unref (dirmodel);
+ gtk_list_box_bind_model (GTK_LIST_BOX (listbox),
+ model,
+ create_widget_for_model,
+ root, g_object_unref);
+ g_object_set_data (G_OBJECT (listbox), "model", model);
+ g_object_unref (model);
+
+ gtk_widget_show (win);
+
+ gtk_main ();
+
+ return 0;
+}