[gtk/rubberband-again: 2/3] Add gtk_selection_model_[un]select_callback



commit 20611cf68c6a95765bd0c1a87f8e66423ee56f9f
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Jun 4 21:33:44 2020 -0400

    Add gtk_selection_model_[un]select_callback
    
    Add a methods to add or remove a whole set
    (specified via a query-range style callback).

 gtk/gtkmultiselection.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkselectionmodel.c | 54 +++++++++++++++++++++++++++++++++++++++-------
 gtk/gtkselectionmodel.h | 23 +++++++++++++++++++-
 3 files changed, 125 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkmultiselection.c b/gtk/gtkmultiselection.c
index f8ed44c2d4..a0ffb92fee 100644
--- a/gtk/gtkmultiselection.c
+++ b/gtk/gtkmultiselection.c
@@ -167,6 +167,61 @@ gtk_multi_selection_unselect_all (GtkSelectionModel *model)
   return gtk_multi_selection_unselect_range (model, 0, g_list_model_get_n_items (G_LIST_MODEL (model)));
 }
 
+static gboolean
+gtk_multi_selection_add_or_remove (GtkSelectionModel    *model,
+                                   gboolean              add,
+                                   GtkSelectionCallback  callback,
+                                   gpointer              data)
+{
+  GtkMultiSelection *self = GTK_MULTI_SELECTION (model);
+  guint pos, start, n;
+  gboolean in;
+  guint min, max;
+
+  min = G_MAXUINT;
+  max = 0;
+
+  pos = 0;
+  do
+    {
+      callback (pos, &start, &n, &in, data);
+      if (in)
+        {
+          if (start < min)
+            min = start;
+          if (start + n - 1 > max)
+            max = start + n - 1;
+
+          if (add)
+            gtk_set_add_range (self->selected, start, n);
+          else
+            gtk_set_remove_range (self->selected, start, n);
+        }
+      pos = start + n;
+    }
+  while (n > 0);
+
+  gtk_selection_model_selection_changed (model, min, max - min + 1);
+
+  return TRUE;
+}
+
+static gboolean
+gtk_multi_selection_select_callback (GtkSelectionModel    *model,
+                                     GtkSelectionCallback  callback,
+                                     gpointer              data)
+{
+  return gtk_multi_selection_add_or_remove (model, TRUE, callback, data);
+}
+
+static gboolean
+gtk_multi_selection_unselect_callback (GtkSelectionModel    *model,
+                                       GtkSelectionCallback  callback,
+                                       gpointer              data)
+{
+  return gtk_multi_selection_add_or_remove (model, FALSE, callback, data);
+}
+
 static void
 gtk_multi_selection_query_range (GtkSelectionModel *model,
                                  guint              position,
@@ -190,6 +245,8 @@ gtk_multi_selection_selection_model_init (GtkSelectionModelInterface *iface)
   iface->unselect_range = gtk_multi_selection_unselect_range;
   iface->select_all = gtk_multi_selection_select_all;
   iface->unselect_all = gtk_multi_selection_unselect_all;
+  iface->select_callback = gtk_multi_selection_select_callback;
+  iface->unselect_callback = gtk_multi_selection_unselect_callback;
   iface->query_range = gtk_multi_selection_query_range;
 }
 
diff --git a/gtk/gtkselectionmodel.c b/gtk/gtkselectionmodel.c
index 8053368c6b..dfbf167f9a 100644
--- a/gtk/gtkselectionmodel.c
+++ b/gtk/gtkselectionmodel.c
@@ -113,6 +113,22 @@ gtk_selection_model_default_unselect_range (GtkSelectionModel *model,
   return FALSE;
 }
 
+static gboolean
+gtk_selection_model_default_select_callback (GtkSelectionModel    *model,
+                                             GtkSelectionCallback  callback,
+                                             gpointer              data)
+{
+  return FALSE;
+}
+
+static gboolean
+gtk_selection_model_default_unselect_callback (GtkSelectionModel    *model,
+                                               GtkSelectionCallback  callback,
+                                               gpointer              data)
+{
+  return FALSE;
+}
+
 static gboolean
 gtk_selection_model_default_select_all (GtkSelectionModel *model)
 {
@@ -142,20 +158,22 @@ gtk_selection_model_default_query_range (GtkSelectionModel *model,
   else
     {
       *n_items = 1;
-      *selected = gtk_selection_model_is_selected (model, position);  
+      *selected = gtk_selection_model_is_selected (model, position);
     }
 }
 
 static void
 gtk_selection_model_default_init (GtkSelectionModelInterface *iface)
 {
-  iface->is_selected = gtk_selection_model_default_is_selected; 
-  iface->select_item = gtk_selection_model_default_select_item; 
-  iface->unselect_item = gtk_selection_model_default_unselect_item; 
-  iface->select_range = gtk_selection_model_default_select_range; 
-  iface->unselect_range = gtk_selection_model_default_unselect_range; 
-  iface->select_all = gtk_selection_model_default_select_all; 
-  iface->unselect_all = gtk_selection_model_default_unselect_all; 
+  iface->is_selected = gtk_selection_model_default_is_selected;
+  iface->select_item = gtk_selection_model_default_select_item;
+  iface->unselect_item = gtk_selection_model_default_unselect_item;
+  iface->select_range = gtk_selection_model_default_select_range;
+  iface->unselect_range = gtk_selection_model_default_unselect_range;
+  iface->select_all = gtk_selection_model_default_select_all;
+  iface->unselect_all = gtk_selection_model_default_unselect_all;
+  iface->select_callback = gtk_selection_model_default_select_callback;
+  iface->unselect_callback = gtk_selection_model_default_unselect_callback;
   iface->query_range = gtk_selection_model_default_query_range;
 
   /**
@@ -324,6 +342,26 @@ gtk_selection_model_unselect_all (GtkSelectionModel *model)
   return iface->unselect_all (model);
 }
 
+gboolean
+gtk_selection_model_select_callback (GtkSelectionModel    *model,
+                                     GtkSelectionCallback  callback,
+                                     gpointer              data)
+{
+  g_return_val_if_fail (GTK_IS_SELECTION_MODEL (model), FALSE);
+
+  return GTK_SELECTION_MODEL_GET_IFACE (model)->select_callback (model, callback, data);
+}
+
+gboolean
+gtk_selection_model_unselect_callback (GtkSelectionModel    *model,
+                                       GtkSelectionCallback  callback,
+                                       gpointer              data)
+{
+  g_return_val_if_fail (GTK_IS_SELECTION_MODEL (model), FALSE);
+
+  return GTK_SELECTION_MODEL_GET_IFACE (model)->unselect_callback (model, callback, data);
+}
+
 /**
  * gtk_selection_model_query_range:
  * @model: a #GtkSelectionModel
diff --git a/gtk/gtkselectionmodel.h b/gtk/gtkselectionmodel.h
index 9e8de6a66b..3a73572ac2 100644
--- a/gtk/gtkselectionmodel.h
+++ b/gtk/gtkselectionmodel.h
@@ -29,10 +29,17 @@
 G_BEGIN_DECLS
 
 #define GTK_TYPE_SELECTION_MODEL       (gtk_selection_model_get_type ())
-                                                      
+
 GDK_AVAILABLE_IN_ALL
 G_DECLARE_INTERFACE (GtkSelectionModel, gtk_selection_model, GTK, SELECTION_MODEL, GListModel)
 
+typedef void     (* GtkSelectionCallback) (guint     position,
+                                           guint    *start_range,
+                                           guint    *n_items,
+                                           gboolean *selected,
+                                           gpointer  data);
+
+
 /**
  * GtkSelectionModelInterface:
  * @is_selected: Return if the item at the given position is selected.
@@ -79,6 +86,12 @@ struct _GtkSelectionModelInterface
                                                                  guint                   n_items);
   gboolean              (* select_all)                          (GtkSelectionModel      *model);
   gboolean              (* unselect_all)                        (GtkSelectionModel      *model);
+  gboolean              (* select_callback)                     (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
+  gboolean              (* unselect_callback)                   (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
   void                  (* query_range)                         (GtkSelectionModel      *model,
                                                                  guint                   position,
                                                                  guint                  *start_range,
@@ -111,6 +124,14 @@ gboolean                gtk_selection_model_select_all          (GtkSelectionMod
 GDK_AVAILABLE_IN_ALL
 gboolean                gtk_selection_model_unselect_all        (GtkSelectionModel      *model);
 
+GDK_AVAILABLE_IN_ALL
+gboolean                gtk_selection_model_select_callback     (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
+gboolean                gtk_selection_model_unselect_callback   (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
+
 GDK_AVAILABLE_IN_ALL
 void                    gtk_selection_model_query_range         (GtkSelectionModel      *model,
                                                                  guint                   position,


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