[gtk/wip/otte/listview: 1/38] gridview: Add factory handling



commit c9010b816c45c7699f65b8695b73ef09194ced8c
Author: Benjamin Otte <otte redhat com>
Date:   Thu Oct 10 03:38:51 2019 +0200

    gridview: Add factory handling
    
    Just copy the listview APIs.
    
    Code still doesn't do anything with it.

 gtk/gtkgridview.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 gtk/gtkgridview.h |  10 +++-
 2 files changed, 166 insertions(+), 5 deletions(-)
---
diff --git a/gtk/gtkgridview.c b/gtk/gtkgridview.c
index a39c9e1b7e..46764b89f5 100644
--- a/gtk/gtkgridview.c
+++ b/gtk/gtkgridview.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Benjamin Otte
+ * Copyright © 2019 Benjamin Otte
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,6 +23,8 @@
 
 #include "gtkadjustment.h"
 #include "gtkintl.h"
+#include "gtklistitemfactory.h"
+#include "gtklistitemmanagerprivate.h"
 #include "gtkprivate.h"
 #include "gtkscrollable.h"
 
@@ -34,23 +36,44 @@
  * @short_description: A widget for displaying lists
  * @see_also: #GListModel
  *
- * GtkGridView is a widget to present a view into a large dynamic list of items.
+ * GtkGridView is a widget to present a view into a large dynamic grid of items.
  */
 
+typedef struct _Cell Cell;
+typedef struct _CellAugment CellAugment;
+
 struct _GtkGridView
 {
   GtkWidget parent_instance;
 
   GListModel *model;
+  GtkListItemManager *item_manager;
   GtkAdjustment *adjustment[2];
   GtkScrollablePolicy scroll_policy[2];
   guint min_columns;
   guint max_columns;
 };
 
+struct _Cell
+{
+  GtkListItemManagerItem parent;
+  guint size_first_row; /* total */
+  guint size; /* total */
+  guint size_last_row; /* total */
+};
+
+struct _CellAugment
+{
+  GtkListItemManagerItemAugment parent;
+  guint size_first_row; /* total */
+  guint size; /* total */
+  guint size_last_row; /* total */
+};
+
 enum
 {
   PROP_0,
+  PROP_FACTORY,
   PROP_HADJUSTMENT,
   PROP_HSCROLL_POLICY,
   PROP_MAX_COLUMNS,
@@ -173,6 +196,8 @@ gtk_grid_view_dispose (GObject *object)
   gtk_grid_view_clear_adjustment (self, GTK_ORIENTATION_HORIZONTAL);
   gtk_grid_view_clear_adjustment (self, GTK_ORIENTATION_VERTICAL);
 
+  g_clear_object (&self->item_manager);
+
   G_OBJECT_CLASS (gtk_grid_view_parent_class)->dispose (object);
 }
 
@@ -186,6 +211,10 @@ gtk_grid_view_get_property (GObject    *object,
 
   switch (property_id)
     {
+    case PROP_FACTORY:
+      g_value_set_object (value, gtk_list_item_manager_get_factory (self->item_manager));
+      break;
+
     case PROP_HADJUSTMENT:
       g_value_set_object (value, self->adjustment[GTK_ORIENTATION_HORIZONTAL]);
       break;
@@ -271,6 +300,10 @@ gtk_grid_view_set_property (GObject      *object,
 
   switch (property_id)
     {
+    case PROP_FACTORY:
+      gtk_grid_view_set_factory (self, g_value_get_object (value));
+      break;
+
     case PROP_HADJUSTMENT:
       gtk_grid_view_set_adjustment (self, GTK_ORIENTATION_HORIZONTAL, g_value_get_object (value));
       break;
@@ -334,6 +367,19 @@ gtk_grid_view_class_init (GtkGridViewClass *klass)
       g_param_spec_override ("vscroll-policy",
                              g_object_interface_find_property (iface, "vscroll-policy"));
 
+  /**
+   * GtkGridView:factory:
+   *
+   * Factory for populating list items
+   */
+  properties[PROP_FACTORY] =
+    g_param_spec_object ("factory",
+                         P_("Factory"),
+                         P_("Factory for populating list items"),
+                         GTK_TYPE_LIST_ITEM_FACTORY,
+                         G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+
   /**
    * GtkGridView:max-columns:
    *
@@ -378,9 +424,42 @@ gtk_grid_view_class_init (GtkGridViewClass *klass)
   gtk_widget_class_set_css_name (widget_class, I_("grid"));
 }
 
+static void
+cell_augment (GtkRbTree *tree,
+              gpointer   node_augment,
+              gpointer   node,
+              gpointer   left,
+              gpointer   right)
+{
+#if 0
+  Cell *cell = node;
+  CellAugment *aug = node_augment;
+
+  gtk_list_item_manager_augment_node (tree, node_augment, node, left, right);
+
+  aug->height = row->height * row->parent.n_items;
+
+  if (left)
+    {
+      ListRowAugment *left_aug = gtk_rb_tree_get_augment (tree, left);
+
+      aug->height += left_aug->height;
+    }
+
+  if (right)
+    {
+      ListRowAugment *right_aug = gtk_rb_tree_get_augment (tree, right);
+
+      aug->height += right_aug->height;
+    }
+#endif
+}
+
 static void
 gtk_grid_view_init (GtkGridView *self)
 {
+  self->item_manager = gtk_list_item_manager_new (GTK_WIDGET (self), Cell, CellAugment, cell_augment);
+
   self->min_columns = 1;
   self->max_columns = DEFAULT_MAX_COLUMNS;
 
@@ -395,8 +474,9 @@ gtk_grid_view_init (GtkGridView *self)
  *
  * Creates a new empty #GtkGridView.
  *
- * You most likely want to call gtk_grid_view_set_model() to set
- * a model and then set up a way to map its items to widgets next.
+ * You most likely want to call gtk_grid_view_set_factory() to
+ * set up a way to map its items to widgets and gtk_grid_view_set_model()
+ * to set a model to provide items next.
  *
  * Returns: a new #GtkGridView
  **/
@@ -406,6 +486,41 @@ gtk_grid_view_new (void)
   return g_object_new (GTK_TYPE_GRID_VIEW, NULL);
 }
 
+/**
+ * gtk_grid_view_new_with_factory:
+ * @factory: (transfer full): The factory to populate items with
+ *
+ * Creates a new #GtkGridView that uses the given @factory for
+ * mapping items to widgets.
+ *
+ * You most likely want to call gtk_grid_view_set_model() to set
+ * a model next.
+ *
+ * The function takes ownership of the
+ * argument, so you can write code like
+ * ```
+ *   grid_view = gtk_grid_view_new_with_factory (
+ *     gtk_builder_list_item_factory_new_from_resource ("/resource.ui"));
+ * ```
+ *
+ * Returns: a new #GtkGridView using the given @factory
+ **/
+GtkWidget *
+gtk_grid_view_new_with_factory (GtkListItemFactory *factory)
+{
+  GtkWidget *result;
+
+  g_return_val_if_fail (GTK_IS_LIST_ITEM_FACTORY (factory), NULL);
+
+  result = g_object_new (GTK_TYPE_GRID_VIEW,
+                         "factory", factory,
+                         NULL);
+
+  g_object_unref (factory);
+
+  return result;
+}
+
 /**
  * gtk_grid_view_get_model:
  * @self: a #GtkGridView
@@ -454,6 +569,44 @@ gtk_grid_view_set_model (GtkGridView *self,
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
 }
 
+/**
+ * gtk_grid_view_get_factory:
+ * @self: a #GtkGridView
+ *
+ * Gets the factory that's currently used to populate list items.
+ *
+ * Returns: (nullable) (transfer none): The factory in use
+ **/
+GtkListItemFactory *
+gtk_grid_view_get_factory (GtkGridView *self)
+{
+  g_return_val_if_fail (GTK_IS_GRID_VIEW (self), NULL);
+
+  return gtk_list_item_manager_get_factory (self->item_manager);
+}
+
+/**
+ * gtk_grid_view_set_factory:
+ * @self: a #GtkGridView
+ * @factory: (allow-none) (transfer none): the factory to use or %NULL for none
+ *
+ * Sets the #GtkListItemFactory to use for populating list items.
+ **/
+void
+gtk_grid_view_set_factory (GtkGridView        *self,
+                           GtkListItemFactory *factory)
+{
+  g_return_if_fail (GTK_IS_GRID_VIEW (self));
+  g_return_if_fail (factory == NULL || GTK_LIST_ITEM_FACTORY (factory));
+
+  if (factory == gtk_list_item_manager_get_factory (self->item_manager))
+    return;
+
+  gtk_list_item_manager_set_factory (self->item_manager, factory);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
+}
+
 /**
  * gtk_grid_view_get_max_columns:
  * @self: a #GtkGridView
diff --git a/gtk/gtkgridview.h b/gtk/gtkgridview.h
index 3bdd6505ba..5c42776dbe 100644
--- a/gtk/gtkgridview.h
+++ b/gtk/gtkgridview.h
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Benjamin Otte
+ * Copyright © 2019 Benjamin Otte
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -35,6 +35,8 @@ G_DECLARE_FINAL_TYPE (GtkGridView, gtk_grid_view, GTK, GRID_VIEW, GtkWidget)
 
 GDK_AVAILABLE_IN_ALL
 GtkWidget *     gtk_grid_view_new                               (void);
+GDK_AVAILABLE_IN_ALL
+GtkWidget *     gtk_grid_view_new_with_factory                  (GtkListItemFactory     *factory);
 
 GDK_AVAILABLE_IN_ALL
 GListModel *    gtk_grid_view_get_model                         (GtkGridView            *self);
@@ -42,6 +44,12 @@ GDK_AVAILABLE_IN_ALL
 void            gtk_grid_view_set_model                         (GtkGridView            *self,
                                                                  GListModel             *model);
 GDK_AVAILABLE_IN_ALL
+void            gtk_grid_view_set_factory                       (GtkGridView            *self,
+                                                                 GtkListItemFactory     *factory);
+GDK_AVAILABLE_IN_ALL
+GtkListItemFactory *
+                gtk_grid_view_get_factory                       (GtkGridView            *self);
+GDK_AVAILABLE_IN_ALL
 guint           gtk_grid_view_get_min_columns                   (GtkGridView            *self);
 GDK_AVAILABLE_IN_ALL
 void            gtk_grid_view_set_min_columns                   (GtkGridView            *self,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]