[f-spot/icon-view-cleanup: 23/24] cleanup the rectangular selection a bit
- From: Mike Gemünde <mgemuende src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/icon-view-cleanup: 23/24] cleanup the rectangular selection a bit
- Date: Tue, 17 Aug 2010 19:21:59 +0000 (UTC)
commit c8c9c76cd3715575ba30a7af0b75118d78bc95d9
Author: Mike Gemünde <mike gemuende de>
Date: Mon Aug 16 21:54:33 2010 +0200
cleanup the rectangular selection a bit
src/Clients/MainApp/FSpot.Widgets/CellGridView.cs | 5 +
.../FSpot.Widgets/CollectionCellGridView.cs | 246 ++++++++++----------
.../MainApp/FSpot.Widgets/SelectionCollection.cs | 4 +-
3 files changed, 129 insertions(+), 126 deletions(-)
---
diff --git a/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs b/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
index 8ed2cd8..2fb47f9 100644
--- a/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/CellGridView.cs
@@ -161,6 +161,11 @@ namespace FSpot.Widgets
#region Public Methods
+ public int CellAtPosition (Point p)
+ {
+ return CellAtPosition (p.X, p.Y);
+ }
+
public int CellAtPosition (int x, int y)
{
return CellAtPosition (x, y, true, false);
diff --git a/src/Clients/MainApp/FSpot.Widgets/CollectionCellGridView.cs b/src/Clients/MainApp/FSpot.Widgets/CollectionCellGridView.cs
index abbc5ff..0f5f365 100644
--- a/src/Clients/MainApp/FSpot.Widgets/CollectionCellGridView.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/CollectionCellGridView.cs
@@ -11,6 +11,7 @@
*/
using System;
+using System.Collections.Generic;
using Gtk;
using Gdk;
@@ -81,7 +82,6 @@ namespace FSpot.Widgets
Selection = new SelectionCollection (Collection);
Collection.Changed += delegate (IBrowsableCollection sender) {
- //suppress_scroll = true;
QueueResize ();
};
@@ -210,8 +210,10 @@ namespace FSpot.Widgets
args.RetVal = true;
start_select_event = args.Event;
- start_press_x = (int) args.Event.X;
- start_press_y = (int) args.Event.Y;
+
+ selection_start = new Point ((int) args.Event.X, (int) args.Event.Y);
+ selection_modifier = args.Event.State;
+
isRectSelection = false;
isDragDrop = false;
@@ -249,7 +251,6 @@ namespace FSpot.Widgets
GLib.Source.Remove (scroll_timeout);
scroll_timeout = 0;
}
- SelectMotion ();
isRectSelection = false;
if (BinWindow != null) {
@@ -276,55 +277,59 @@ namespace FSpot.Widgets
// rectangle of dragging selection
private Rectangle rect_select;
+ private Point selection_start;
+ private Point selection_end;
+ private ModifierType selection_modifier;
private bool isRectSelection = false;
private bool isDragDrop = false;
- // initial click and scroll value
- private int start_select_x, start_select_y, start_select_vadj, start_select_hadj;
// initial selection
private int[] start_select_selection;
// initial event used to detect drag&drop
private EventButton start_select_event;
// timer using when scrolling selection
private uint scroll_timeout = 0;
- // initial click
- private int start_press_x, start_press_y;
+
+ private Rectangle BoundedRectangle (Point p1, Point p2)
+ {
+ return new Rectangle (Math.Min (p1.X, p2.X),
+ Math.Min (p1.Y, p2.Y),
+ Math.Abs (p1.X - p2.X) + 1,
+ Math.Abs (p1.Y- p2.Y) + 1);
+ }
+
+ protected Point GetPointer ()
+ {
+ int x, y;
+ GetPointer (out x, out y);
+
+ return new Point (x + (int) Hadjustment.Value, y + (int) Vadjustment.Value);
+ }
// during pointer motion, select/toggle pictures between initial x/y (param)
// and current x/y (get pointer)
- private void SelectMotion ()
+ private void UpdateRubberband ()
{
- int x2, y2;
- Gdk.ModifierType mod;
- Display.GetPointer (out x2, out y2, out mod);
- GetPointer (out x2, out y2);
-
- // check new coord
- int x1 = start_select_x;
- if (x1 < 0)
- x1 = 0;
- int y1 = start_select_y;
- if (y1 < 0)
- y1 = 0;
- if (y1 > Allocation.Height)
- y1 = (int) Allocation.Height;
- x1 += start_select_hadj;
- y1 += start_select_vadj;
-
- if (x2 < 0)
- x2 = 0;
- if (y2 < 0)
- y2 = 0;
- if (y2 > Allocation.Height)
- y2 = (int) Allocation.Height;
- x2 += (int) Hadjustment.Value;
- y2 += (int) Vadjustment.Value;
-
- int start_x = x1 < x2 ? x1 : x2;
- int end_x = x1 > x2 ? x1 : x2;
- int start_y = y1 < y2 ? y1 : y2;
- int end_y = y1 > y2 ? y1 : y2;
+ // determine old and new selection
+ var old_selection = rect_select;
+ selection_end = GetPointer ();
+ var new_selection = BoundedRectangle (selection_start, selection_end);
+
+ // determine region to invalidate
+ var region = Region.Rectangle (old_selection);
+ region.Xor (Region.Rectangle (new_selection));
+ region.Shrink (-1, -1);
+
+ BinWindow.InvalidateRegion (region, true);
+
+ rect_select = new_selection;
+ UpdateRubberbandSelection ();
+ }
+
+ private void UpdateRubberbandSelection ()
+ {
+ var selected_area = BoundedRectangle (selection_start, selection_end);
// Restore initial selection
var initial_selection = Selection.ToBitArray();
@@ -332,59 +337,48 @@ namespace FSpot.Widgets
foreach (int i in start_select_selection)
Selection.Add (i, false);
- // Select or toggle according to modifiers
- int start_row = (start_x - BorderSize) / cell_width;
- int start_line = (start_y - BorderSize) / cell_height;
- int end_row = (end_x - BorderSize + cell_width - 1) / cell_width;
- int end_line = (end_y - BorderSize + cell_height - 1) / cell_height;
- if (start_row > cells_per_row)
- start_row = cells_per_row;
- if (end_row > cells_per_row)
- end_row = cells_per_row;
-
+ // Set selection
+ int first = -1;
+ foreach (var cell_num in CellsInRect (selected_area)) {
+ if (first == -1)
+ first = cell_num;
- FocusCell = start_line * cells_per_row + start_row;
-
- if ((mod & ModifierType.ControlMask) == 0)
- Selection.SelectRect (start_row, end_row, start_line, end_line, cells_per_row);
- else
- Selection.ToggleRect (start_row, end_row, start_line, end_line, cells_per_row);
+ if ((selection_modifier & ModifierType.ControlMask) == 0)
+ Selection.Add (cell_num, false);
+ else
+ Selection.ToggleCell (cell_num, false);
+ }
+ if (first != -1)
+ FocusCell = first;
// fire events for cells which have changed selection flag
var new_selection = Selection.ToBitArray();
var selection_changed = initial_selection.Xor (new_selection);
- System.Collections.Generic.List<int> changed = new System.Collections.Generic.List<int>();
+ var changed = new List<int>();
for (int i = 0; i < selection_changed.Length; i++)
if (selection_changed.Get(i))
changed.Add (i);
- if (selection_changed.Length != 0)
+ if (changed.Count != 0)
Selection.SignalChange (changed.ToArray());
-
- // redraw selection box
- if (BinWindow != null) {
- BinWindow.InvalidateRect (rect_select, true); // old selection
- rect_select = new Rectangle (start_x, start_y, end_x - start_x, end_y - start_y);
- BinWindow.InvalidateRect (rect_select, true); // new selection
- BinWindow.ProcessUpdates (true);
- }
}
// if scroll is required, a timeout is fired
// until the button is release or the pointer is
// in window again
private int deltaVscroll;
- private bool HandleMotionTimeout()
+ private bool HandleMotionTimeout ()
{
int new_x, new_y;
- ModifierType new_mod;
- Display.GetPointer (out new_x, out new_y, out new_mod);
- GetPointer (out new_x, out new_y);
- // do scroll
+ // do scroll
double newVadj = Vadjustment.Value;
if (deltaVscroll < 130)
deltaVscroll += 15;
+ Gdk.ModifierType new_mod;
+ Display.GetPointer (out new_x, out new_y, out new_mod);
+ GetPointer (out new_x, out new_y);
+
if (new_y <= 0) {
newVadj -= deltaVscroll;
if (newVadj < 0)
@@ -393,10 +387,10 @@ namespace FSpot.Widgets
(newVadj < Vadjustment.Upper - Allocation.Height - deltaVscroll))
newVadj += deltaVscroll;
Vadjustment.Value = newVadj;
- Vadjustment.ChangeValue();
- // do again selection after scroll
- SelectMotion ();
+ UpdateRubberband ();// (new Point (new_x + (int) Hadjustment.Value, new_y + (int) Vadjustment.Value));
+
+ Vadjustment.ChangeValue ();
// stop firing timeout when no button pressed
return (new_mod & (ModifierType.Button1Mask | ModifierType.Button3Mask)) != 0;
@@ -404,58 +398,62 @@ namespace FSpot.Widgets
private void HandleSelectMotionNotify (object sender, MotionNotifyEventArgs args)
{
- if ((args.Event.State & (ModifierType.Button1Mask | ModifierType.Button3Mask)) != 0 ) {
- if (Gtk.Drag.CheckThreshold (this, start_press_x, start_press_y,
- (int) args.Event.X, (int) args.Event.Y))
- if (isRectSelection) {
- // scroll if out of window
- double d_x, d_y;
- deltaVscroll = 30;
- if (EventHelper.GetCoords (args.Event, out d_x, out d_y)) {
- int new_y = (int) d_y;
- if ((new_y <= 0) || (new_y >= Allocation.Height)) {
- if (scroll_timeout == 0)
- scroll_timeout = GLib.Timeout.Add (100, new GLib.TimeoutHandler (HandleMotionTimeout));
- }
- } else if (scroll_timeout != 0) {
- GLib.Source.Remove (scroll_timeout);
- scroll_timeout = 0;
- }
-
- // handle selection
- SelectMotion ();
- } else {
- int cell_num = CellAtPosition (start_press_x, start_press_y, false, false);
- if (Selection.Contains (cell_num)) {
- // on a selected cell : do drag&drop
- isDragDrop = true;
- if (StartDrag != null) {
- uint but;
- if ((args.Event.State & ModifierType.Button1Mask) != 0)
- but = 1;
- else
- but = 3;
- StartDrag (this, new StartDragArgs(but, start_select_event));
- }
- } else {
- // not on a selected cell : do rectangular select
- isRectSelection = true;
- start_select_hadj = (int) Hadjustment.Value;
- start_select_vadj = (int) Vadjustment.Value;
- start_select_x = start_press_x - start_select_hadj;
- start_select_y = start_press_y - start_select_vadj;
-
- // ctrl : toggle selected, shift : keep selected
- if ((args.Event.State & (ModifierType.ShiftMask | ModifierType.ControlMask)) == 0)
- Selection.Clear ();
-
- start_select_selection = Selection.Ids; // keep initial selection
- // no rect draw at beginning
- rect_select = new Rectangle ();
-
- args.RetVal = false;
- }
+ if ((args.Event.State & (ModifierType.Button1Mask | ModifierType.Button3Mask)) == 0)
+ return;
+
+ if (! Gtk.Drag.CheckThreshold (this, selection_start.X, selection_start.Y,
+ (int) args.Event.X, (int) args.Event.Y))
+ return;
+
+ if (isRectSelection) {
+ // scroll if out of window
+ double d_x, d_y;
+ deltaVscroll = 30;
+ if (EventHelper.GetCoords (args.Event, out d_x, out d_y)) {
+ int new_y = (int) d_y;
+ if ((new_y <= 0) || (new_y >= Allocation.Height)) {
+ if (scroll_timeout == 0)
+ scroll_timeout = GLib.Timeout.Add (100, new GLib.TimeoutHandler (HandleMotionTimeout));
+ } else if (scroll_timeout != 0) {
+ GLib.Source.Remove (scroll_timeout);
+ scroll_timeout = 0;
}
+ } else if (scroll_timeout != 0) {
+ GLib.Source.Remove (scroll_timeout);
+ scroll_timeout = 0;
+ }
+
+ // handle selection
+ UpdateRubberband ();
+ //SelectMotion (new Point ((int) args.Event.X, (int) args.Event.Y));
+ } else {
+ int cell_num = CellAtPosition (selection_start);
+
+ if (Selection.Contains (cell_num)) {
+ // on a selected cell : do drag&drop
+ isDragDrop = true;
+ if (StartDrag != null) {
+ uint but;
+ if ((args.Event.State & ModifierType.Button1Mask) != 0)
+ but = 1;
+ else
+ but = 3;
+ StartDrag (this, new StartDragArgs(but, start_select_event));
+ }
+ } else {
+ // not on a selected cell : do rectangular select
+ isRectSelection = true;
+
+ // ctrl : toggle selected, shift : keep selected
+ if ((args.Event.State & (ModifierType.ShiftMask | ModifierType.ControlMask)) == 0)
+ Selection.Clear ();
+
+ start_select_selection = Selection.Ids; // keep initial selection
+ // no rect draw at beginning
+ rect_select = Rectangle.Zero;
+
+ args.RetVal = false;
+ }
}
}
diff --git a/src/Clients/MainApp/FSpot.Widgets/SelectionCollection.cs b/src/Clients/MainApp/FSpot.Widgets/SelectionCollection.cs
index 5c0451d..e65e45e 100644
--- a/src/Clients/MainApp/FSpot.Widgets/SelectionCollection.cs
+++ b/src/Clients/MainApp/FSpot.Widgets/SelectionCollection.cs
@@ -81,7 +81,7 @@ namespace FSpot.Widgets
}
public BitArray ToBitArray () {
- return bit_array;
+ return new BitArray (bit_array);
}
public int [] Ids {
@@ -267,7 +267,7 @@ namespace FSpot.Widgets
return System.Array.IndexOf (Ids, parent_index);
}
- private void ToggleCell (int cell_num, bool notify)
+ public void ToggleCell (int cell_num, bool notify)
{
if (Contains (cell_num))
Remove (cell_num, notify);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]