[gtk/rubberband-again: 1/2] listbase: Redo rubberbanding
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/rubberband-again: 1/2] listbase: Redo rubberbanding
- Date: Fri, 5 Jun 2020 04:52:29 +0000 (UTC)
commit eeb2d2cc38b2306505e1d61340cbb716cb5c2f14
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Jun 4 22:30:47 2020 -0400
listbase: Redo rubberbanding
Make it so that the selection is only updated in the end.
gtk/gtklistbase.c | 95 ++++++++++++++++++++++++++++++-------------------------
1 file changed, 52 insertions(+), 43 deletions(-)
---
diff --git a/gtk/gtklistbase.c b/gtk/gtklistbase.c
index 7f8bf34ba5..373ba704e3 100644
--- a/gtk/gtklistbase.c
+++ b/gtk/gtklistbase.c
@@ -34,13 +34,13 @@
#include "gtksnapshot.h"
#include "gtkmultiselection.h"
#include "gtkgizmoprivate.h"
+#include "gtkset.h"
typedef struct _RubberbandData RubberbandData;
struct _RubberbandData
{
GtkWidget *widget;
- GtkSelectionModel *selection;
double x1, y1;
double x2, y2;
gboolean modify;
@@ -53,7 +53,6 @@ rubberband_data_free (gpointer data)
RubberbandData *rdata = data;
g_clear_pointer (&rdata->widget, gtk_widget_unparent);
- g_clear_object (&rdata->selection);
g_free (rdata);
}
@@ -1324,7 +1323,6 @@ gtk_list_base_start_rubberband (GtkListBase *self,
{
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
double value_x, value_y;
- GtkSelectionModel *selection;
if (priv->rubberband)
return;
@@ -1343,24 +1341,66 @@ gtk_list_base_start_rubberband (GtkListBase *self,
priv->rubberband->widget = gtk_gizmo_new ("rubberband",
NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_set_parent (priv->rubberband->widget, GTK_WIDGET (self));
+}
- selection = gtk_list_item_manager_get_model (priv->item_manager);
- if ((modify || extend) &&
- GTK_IS_MULTI_SELECTION (selection))
- priv->rubberband->selection = GTK_SELECTION_MODEL (gtk_multi_selection_copy (selection));
+static void
+range_cb (guint position,
+ guint *start,
+ guint *n_items,
+ gboolean *selected,
+ gpointer data)
+{
+ GtkSet *set = data;
- if (!modify && !extend)
- gtk_selection_model_unselect_all (selection);
+ gtk_set_find_range (set, position, gtk_set_get_max (set), start, n_items, selected);
}
static void
gtk_list_base_stop_rubberband (GtkListBase *self)
{
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
+ GtkListItemManagerItem *item;
+ GtkSelectionModel *model;
+ GtkSet *active;
if (!priv->rubberband)
return;
+ active = gtk_set_new ();
+
+ for (item = gtk_list_item_manager_get_first (priv->item_manager);
+ item != NULL;
+ item = gtk_rb_tree_node_get_next (item))
+ {
+ if (!item->widget)
+ continue;
+
+ if (gtk_widget_get_state_flags (item->widget) & GTK_STATE_FLAG_ACTIVE)
+ {
+ guint pos;
+
+ pos = gtk_list_item_manager_get_item_position (priv->item_manager, item);
+ gtk_set_add_item (active, pos);
+ gtk_widget_unset_state_flags (item->widget, GTK_STATE_FLAG_ACTIVE);
+ }
+ }
+
+ model = gtk_list_item_manager_get_model (priv->item_manager);
+
+ if (priv->rubberband->modify)
+ {
+ gtk_selection_model_unselect_callback (model, range_cb, active);
+ }
+ else
+ {
+ if (!priv->rubberband->extend)
+ gtk_selection_model_unselect_all (model);
+
+ gtk_selection_model_select_callback (model, range_cb, active);
+ }
+
+ gtk_set_free (active);
+
g_clear_pointer (&priv->rubberband, rubberband_data_free);
remove_autoscroll (self);
@@ -1423,55 +1463,24 @@ gtk_list_base_update_rubberband_selection (GtkListBase *self)
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
GdkRectangle rect;
GdkRectangle alloc;
- GtkSelectionModel *model;
GtkListItemManagerItem *item;
gtk_list_base_allocate_rubberband (self);
gtk_widget_get_allocation (priv->rubberband->widget, &rect);
- model = gtk_list_item_manager_get_model (priv->item_manager);
-
for (item = gtk_list_item_manager_get_first (priv->item_manager);
item != NULL;
item = gtk_rb_tree_node_get_next (item))
{
- guint pos;
- gboolean selected;
- gboolean was_selected;
-
if (!item->widget)
continue;
- pos = gtk_list_item_manager_get_item_position (priv->item_manager, item);
-
gtk_widget_get_allocation (item->widget, &alloc);
- if (priv->rubberband->selection)
- was_selected = gtk_selection_model_is_selected (priv->rubberband->selection, pos);
- else
- was_selected = FALSE;
-
- selected = gdk_rectangle_intersect (&rect, &alloc, &alloc);
-
- if (priv->rubberband->modify)
- {
- if (was_selected)
- {
- if (selected)
- gtk_selection_model_unselect_item (model, pos);
- else
- gtk_selection_model_select_item (model, pos, FALSE);
- }
- else
- gtk_selection_model_unselect_item (model, pos);
- }
+ if (gdk_rectangle_intersect (&rect, &alloc, &alloc))
+ gtk_widget_set_state_flags (item->widget, GTK_STATE_FLAG_ACTIVE, FALSE);
else
- {
- if (selected || was_selected)
- gtk_selection_model_select_item (model, pos, FALSE);
- else
- gtk_selection_model_unselect_item (model, pos);
- }
+ gtk_widget_unset_state_flags (item->widget, GTK_STATE_FLAG_ACTIVE);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]