mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-01 00:11:29 +00:00
listbase: Split off rubberband data
This commit is contained in:
parent
14d11ebcab
commit
a9273e1c73
@ -35,6 +35,28 @@
|
|||||||
#include "gtkmultiselection.h"
|
#include "gtkmultiselection.h"
|
||||||
#include "gtkgizmoprivate.h"
|
#include "gtkgizmoprivate.h"
|
||||||
|
|
||||||
|
typedef struct _RubberbandData RubberbandData;
|
||||||
|
|
||||||
|
struct _RubberbandData
|
||||||
|
{
|
||||||
|
GtkWidget *widget;
|
||||||
|
double x1, y1;
|
||||||
|
double x2, y2;
|
||||||
|
GtkSelectionModel *selection;
|
||||||
|
gboolean modify;
|
||||||
|
gboolean extend;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
rubberband_data_free (gpointer data)
|
||||||
|
{
|
||||||
|
RubberbandData *rdata = data;
|
||||||
|
|
||||||
|
g_clear_pointer (&rdata->widget, gtk_widget_unparent);
|
||||||
|
g_clear_object (&rdata->selection);
|
||||||
|
g_free (rdata);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct _GtkListBasePrivate GtkListBasePrivate;
|
typedef struct _GtkListBasePrivate GtkListBasePrivate;
|
||||||
|
|
||||||
struct _GtkListBasePrivate
|
struct _GtkListBasePrivate
|
||||||
@ -58,15 +80,8 @@ struct _GtkListBasePrivate
|
|||||||
GtkListItemTracker *focus;
|
GtkListItemTracker *focus;
|
||||||
|
|
||||||
gboolean enable_rubberband;
|
gboolean enable_rubberband;
|
||||||
double rb_x1;
|
|
||||||
double rb_y1;
|
|
||||||
double rb_x2;
|
|
||||||
double rb_y2;
|
|
||||||
GtkGesture *drag_gesture;
|
GtkGesture *drag_gesture;
|
||||||
GtkWidget *rubberband;
|
RubberbandData *rubberband;
|
||||||
GtkSelectionModel *old_selection;
|
|
||||||
gboolean modify;
|
|
||||||
gboolean extend;
|
|
||||||
|
|
||||||
guint autoscroll_id;
|
guint autoscroll_id;
|
||||||
double autoscroll_delta_x;
|
double autoscroll_delta_x;
|
||||||
@ -1220,13 +1235,14 @@ autoscroll_cb (GtkWidget *widget,
|
|||||||
|
|
||||||
value = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
value = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
||||||
gtk_adjustment_set_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL], value + priv->autoscroll_delta_x);
|
gtk_adjustment_set_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL], value + priv->autoscroll_delta_x);
|
||||||
|
|
||||||
value = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
value = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
||||||
gtk_adjustment_set_value (priv->adjustment[GTK_ORIENTATION_VERTICAL], value + priv->autoscroll_delta_y);
|
gtk_adjustment_set_value (priv->adjustment[GTK_ORIENTATION_VERTICAL], value + priv->autoscroll_delta_y);
|
||||||
|
|
||||||
if (priv->rubberband)
|
if (priv->rubberband)
|
||||||
{
|
{
|
||||||
priv->rb_x2 += priv->autoscroll_delta_x;
|
priv->rubberband->x2 += priv->autoscroll_delta_x;
|
||||||
priv->rb_y2 += priv->autoscroll_delta_y;
|
priv->rubberband->y2 += priv->autoscroll_delta_y;
|
||||||
gtk_list_base_update_rubberband_selection (self);
|
gtk_list_base_update_rubberband_selection (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1272,19 +1288,19 @@ gtk_list_base_allocate_rubberband (GtkListBase *self)
|
|||||||
if (!priv->rubberband)
|
if (!priv->rubberband)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gtk_widget_measure (priv->rubberband,
|
gtk_widget_measure (priv->rubberband->widget,
|
||||||
GTK_ORIENTATION_HORIZONTAL, -1,
|
GTK_ORIENTATION_HORIZONTAL, -1,
|
||||||
&min, &nat, NULL, NULL);
|
&min, &nat, NULL, NULL);
|
||||||
|
|
||||||
x = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
x = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
||||||
y = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
y = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
||||||
|
|
||||||
rect.x = MIN (priv->rb_x1, priv->rb_x2) - x;
|
rect.x = MIN (priv->rubberband->x1, priv->rubberband->x2) - x;
|
||||||
rect.y = MIN (priv->rb_y1, priv->rb_y2) - y;
|
rect.y = MIN (priv->rubberband->y1, priv->rubberband->y2) - y;
|
||||||
rect.width = ABS (priv->rb_x1 - priv->rb_x2) + 1;
|
rect.width = ABS (priv->rubberband->x1 - priv->rubberband->x2) + 1;
|
||||||
rect.height = ABS (priv->rb_y1 - priv->rb_y2) + 1;
|
rect.height = ABS (priv->rubberband->y1 - priv->rubberband->y2) + 1;
|
||||||
|
|
||||||
gtk_widget_size_allocate (priv->rubberband, &rect, -1);
|
gtk_widget_size_allocate (priv->rubberband->widget, &rect, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1296,7 +1312,6 @@ gtk_list_base_start_rubberband (GtkListBase *self,
|
|||||||
{
|
{
|
||||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||||
double value_x, value_y;
|
double value_x, value_y;
|
||||||
GtkSelectionModel *selection;
|
|
||||||
|
|
||||||
if (priv->rubberband)
|
if (priv->rubberband)
|
||||||
return;
|
return;
|
||||||
@ -1304,20 +1319,25 @@ gtk_list_base_start_rubberband (GtkListBase *self,
|
|||||||
value_x = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
value_x = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
||||||
value_y = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
value_y = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
||||||
|
|
||||||
priv->rb_x1 = priv->rb_x2 = x + value_x;
|
priv->rubberband = g_new0 (RubberbandData, 1);
|
||||||
priv->rb_y1 = priv->rb_y2 = y + value_y;
|
|
||||||
|
|
||||||
priv->modify = modify;
|
priv->rubberband->x1 = priv->rubberband->x2 = x + value_x;
|
||||||
priv->extend = extend;
|
priv->rubberband->y1 = priv->rubberband->y2 = y + value_y;
|
||||||
|
|
||||||
priv->rubberband = gtk_gizmo_new ("rubberband",
|
priv->rubberband->modify = modify;
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
priv->rubberband->extend = extend;
|
||||||
gtk_widget_set_parent (priv->rubberband, GTK_WIDGET (self));
|
|
||||||
|
|
||||||
selection = gtk_list_item_manager_get_model (priv->item_manager);
|
priv->rubberband->widget = gtk_gizmo_new ("rubberband",
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
gtk_widget_set_parent (priv->rubberband->widget, GTK_WIDGET (self));
|
||||||
|
|
||||||
if (modify)
|
if (modify)
|
||||||
priv->old_selection = GTK_SELECTION_MODEL (gtk_multi_selection_copy (selection));
|
{
|
||||||
|
GtkSelectionModel *selection;
|
||||||
|
|
||||||
|
selection = gtk_list_item_manager_get_model (priv->item_manager);
|
||||||
|
priv->rubberband->selection = GTK_SELECTION_MODEL (gtk_multi_selection_copy (selection));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1328,9 +1348,7 @@ gtk_list_base_stop_rubberband (GtkListBase *self)
|
|||||||
if (!priv->rubberband)
|
if (!priv->rubberband)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_clear_pointer (&priv->rubberband, gtk_widget_unparent);
|
g_clear_pointer (&priv->rubberband, rubberband_data_free);
|
||||||
g_clear_object (&priv->old_selection);
|
|
||||||
|
|
||||||
remove_autoscroll (self);
|
remove_autoscroll (self);
|
||||||
|
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||||
@ -1353,8 +1371,8 @@ gtk_list_base_update_rubberband (GtkListBase *self,
|
|||||||
value_x = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
value_x = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_HORIZONTAL]);
|
||||||
value_y = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
value_y = gtk_adjustment_get_value (priv->adjustment[GTK_ORIENTATION_VERTICAL]);
|
||||||
|
|
||||||
priv->rb_x2 = x + value_x;
|
priv->rubberband->x2 = x + value_x;
|
||||||
priv->rb_y2 = y + value_y;
|
priv->rubberband->y2 = y + value_y;
|
||||||
|
|
||||||
gtk_list_base_update_rubberband_selection (self);
|
gtk_list_base_update_rubberband_selection (self);
|
||||||
|
|
||||||
@ -1396,7 +1414,7 @@ gtk_list_base_update_rubberband_selection (GtkListBase *self)
|
|||||||
GtkListItemManagerItem *item;
|
GtkListItemManagerItem *item;
|
||||||
|
|
||||||
gtk_list_base_allocate_rubberband (self);
|
gtk_list_base_allocate_rubberband (self);
|
||||||
gtk_widget_get_allocation (priv->rubberband, &rect);
|
gtk_widget_get_allocation (priv->rubberband->widget, &rect);
|
||||||
|
|
||||||
model = gtk_list_item_manager_get_model (priv->item_manager);
|
model = gtk_list_item_manager_get_model (priv->item_manager);
|
||||||
|
|
||||||
@ -1416,15 +1434,15 @@ gtk_list_base_update_rubberband_selection (GtkListBase *self)
|
|||||||
|
|
||||||
selected = gdk_rectangle_intersect (&rect, &alloc, &alloc);
|
selected = gdk_rectangle_intersect (&rect, &alloc, &alloc);
|
||||||
|
|
||||||
if (priv->modify)
|
if (priv->rubberband->modify)
|
||||||
{
|
{
|
||||||
was_selected = gtk_selection_model_is_selected (priv->old_selection, pos);
|
was_selected = gtk_selection_model_is_selected (priv->rubberband->selection, pos);
|
||||||
selected = selected ^ was_selected;
|
selected = selected ^ was_selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected)
|
if (selected)
|
||||||
gtk_selection_model_select_item (model, pos, FALSE);
|
gtk_selection_model_select_item (model, pos, FALSE);
|
||||||
else if (!priv->extend)
|
else if (!priv->rubberband->extend)
|
||||||
gtk_selection_model_unselect_item (model, pos);
|
gtk_selection_model_unselect_item (model, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user