[f-spot: 39/41] Selecing a zone, moving a selection works
- From: Stephane Delcroix <sdelcroix src gnome org>
- To: svn-commits-list gnome org
- Subject: [f-spot: 39/41] Selecing a zone, moving a selection works
- Date: Mon, 15 Jun 2009 08:43:08 -0400 (EDT)
commit 81ec5d59ea88bebc4ca6ef69eefa350053d98b52
Author: Stephane Delcroix <stephane delcroix org>
Date: Mon Jun 15 13:30:02 2009 +0200
Selecing a zone, moving a selection works
src/Makefile.am | 1 +
src/Widgets/ImageView.cs | 318 ++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 291 insertions(+), 28 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index cb92663..14bb4d9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -331,6 +331,7 @@ WIDGETS_ASSEMBLIES = \
-pkg:gtk-sharp-2.0 \
-pkg:gnome-sharp-2.0 \
$(LINK_GTKSHARPBEANS) \
+ -r:Mono.Cairo \
-r:Cms.dll \
-r:Mono.Posix \
-r:FSpot.Core.dll \
diff --git a/src/Widgets/ImageView.cs b/src/Widgets/ImageView.cs
index a3f4893..6c7fe0a 100644
--- a/src/Widgets/ImageView.cs
+++ b/src/Widgets/ImageView.cs
@@ -20,16 +20,22 @@ namespace FSpot.Widgets
{
#region public API
- public ImageView (Adjustment hadjustment, Adjustment vadjustment) : base ()
+ public ImageView (Adjustment hadjustment, Adjustment vadjustment, bool can_select) : base ()
{
OnSetScrollAdjustments (hadjustment, vadjustment);
children = new List<LayoutChild> ();
AdjustmentsChanged += ScrollToAdjustments;
WidgetFlags &= ~WidgetFlags.NoWindow;
SetFlag (WidgetFlags.CanFocus);
+
+ this.can_select = can_select;
+ }
+
+ public ImageView (bool can_select) : this (null, null, can_select)
+ {
}
- public ImageView () : this (null, null)
+ public ImageView () : this (true)
{
}
@@ -66,9 +72,13 @@ namespace FSpot.Widgets
}
}
+ PointerMode pointer_mode = PointerMode.Select;
public PointerMode PointerMode {
- get { throw new NotImplementedException ();}
- set { throw new NotImplementedException ();}
+ get { return pointer_mode; }
+ set {
+ pointer_mode = value;
+ Console.WriteLine ("FIXME: Set the Pointer mode");
+ }
}
Adjustment hadjustment;
@@ -81,10 +91,37 @@ namespace FSpot.Widgets
get { return vadjustment; }
}
+ bool can_select = false;
+ public bool CanSelect {
+ get { return can_select; }
+ set {
+ if (can_select == value)
+ return;
+ can_select = value;
+ if (!can_select)
+ selection = Rectangle.Zero;
+
+ if (!IsRealized)
+ return;
+
+ if (can_select)
+ OnSelectionRealized ();
+ else
+ OnSelectionUnrealized ();
+ }
+ }
+
Gdk.Rectangle selection = Rectangle.Zero;
public Gdk.Rectangle Selection {
- get { return selection; }
+ get {
+ if (!can_select)
+ return Rectangle.Zero;
+ return selection;
+ }
set {
+ if (!can_select)
+ return;
+
if (value == selection)
return;
@@ -93,6 +130,7 @@ namespace FSpot.Widgets
EventHandler eh = SelectionChanged;
if (eh != null)
eh (this, EventArgs.Empty);
+ QueueDraw ();
}
}
@@ -129,12 +167,53 @@ namespace FSpot.Widgets
DoZoom (zoom * zoom_increment, true, x, y);
}
- public Gdk.Point WindowCoordsToImage (Point win)
+ public Point WindowCoordsToImage (Point win)
+ {
+ if (Pixbuf == null)
+ return Point.Zero;
+
+ int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
+ int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;
+
+ win.X = Clamp (win.X, x_offset, x_offset + (int)scaled_width - 1);
+ win.Y = Clamp (win.Y, y_offset, y_offset + (int)scaled_height - 1);
+
+ return new Point ((int) Math.Floor ((win.X - x_offset) * (double)(Pixbuf.Width - 1) / (double)(scaled_width - 1) + .5),
+ (int) Math.Floor ((win.Y - y_offset) * (double)(Pixbuf.Height - 1) / (double)(scaled_height - 1) + .5));
+ }
+
+ public Rectangle WindowCoordsToImage (Rectangle win)
+ {
+ if (Pixbuf == null)
+ return Rectangle.Zero;
+
+ int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
+ int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;
+
+ win.Intersect (new Rectangle (x_offset, y_offset, (int)scaled_width - 1, (int)scaled_height - 1));
+
+ Rectangle img = Rectangle.Zero;
+ img.X = (int) Math.Floor ((win.X - x_offset) * (double)(Pixbuf.Width - 1) / (double)(scaled_width - 1) + .5);
+ img.Y = (int) Math.Floor ((win.Y - y_offset) * (double)(Pixbuf.Height - 1) / (double)(scaled_height - 1) + .5);
+ img.Width = (int) Math.Floor ((win.X + win.Width - x_offset) * (double)(Pixbuf.Width - 1) / (double)(scaled_width - 1) + .5) - win.X;
+ img.Height = (int) Math.Floor ((win.Y + win.Height - y_offset) * (double)(Pixbuf.Height - 1) / (double)(scaled_height - 1) + .5) - win.Y;
+
+ return img;
+ }
+
+ public Point ImageCoordsToWindow (Point image)
{
- throw new NotImplementedException ();
+ if (this.Pixbuf == null)
+ return Point.Zero;
+
+ int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
+ int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;
+
+ return new Point ((int) Math.Floor (image.X * (double) (scaled_width - 1) / (this.Pixbuf.Width - 1) + 0.5) + x_offset,
+ (int) Math.Floor (image.Y * (double) (scaled_height - 1) / (this.Pixbuf.Height - 1) + 0.5) + y_offset);
}
- public Gdk.Rectangle ImageCoordsToWindow (Gdk.Rectangle image)
+ public Rectangle ImageCoordsToWindow (Rectangle image)
{
if (this.Pixbuf == null)
return Gdk.Rectangle.Zero;
@@ -172,7 +251,6 @@ namespace FSpot.Widgets
QueueResize ();
}
-
public event EventHandler ZoomChanged;
public event EventHandler SelectionChanged;
#endregion
@@ -221,9 +299,9 @@ namespace FSpot.Widgets
#endregion
#region GtkWidgetry
+ Gdk.GC selection_gc;
protected override void OnRealized ()
{
-Console.WriteLine ("IsNoWindow: " + IsNoWindow);
SetFlag (Gtk.WidgetFlags.Realized);
GdkWindow = new Gdk.Window (ParentWindow,
new Gdk.WindowAttr { WindowType = Gdk.WindowType.Child,
@@ -254,7 +332,14 @@ Console.WriteLine ("IsNoWindow: " + IsNoWindow);
foreach (var child in children)
child.Widget.ParentWindow = GdkWindow;
-Console.WriteLine ("IsNoWindow: " + IsNoWindow);
+ if (can_select)
+ OnSelectionRealized ();
+ }
+
+ protected override void OnUnrealized ()
+ {
+ if (can_select)
+ OnSelectionUnrealized ();
}
protected override void OnMapped ()
@@ -343,6 +428,9 @@ Console.WriteLine ("IsNoWindow: " + IsNoWindow);
PaintRectangle (p_area, InterpType.Nearest);
}
+
+ if (can_select)
+ OnSelectionExposeEvent (evnt);
return true;
}
@@ -371,30 +459,60 @@ Console.WriteLine ("IsNoWindow: " + IsNoWindow);
HandleAdjustmentsValueChanged (this, EventArgs.Empty);
}
- bool dragging = false;
- int draganchor_x = 0;
- int draganchor_y = 0;
+// bool dragging = false;
+// int draganchor_x = 0;
+// int draganchor_y = 0;
protected override bool OnButtonPressEvent (EventButton evnt)
{
- Console.WriteLine ("OnButtonPressEvent {0}", evnt.Button);
+ bool handled = false;
if (!HasFocus)
GrabFocus ();
- if (dragging)
- return base.OnButtonPressEvent (evnt);
+ if (can_select)
+ handled |= OnSelectionButtonPressEvent (evnt);
- switch (evnt.Button) {
- case 1:
- dragging = true;
- draganchor_x = (int)evnt.X;
- draganchor_y = (int)evnt.Y;
+ if (handled)
+ return handled;
- return true;
- default:
- break;
- }
+ // if (dragging)
+ // return base.OnButtonPressEvent (evnt);
+
+ // switch (evnt.Button) {
+ // case 1:
+ // dragging = true;
+ // draganchor_x = (int)evnt.X;
+ // draganchor_y = (int)evnt.Y;
+
+ // handled = true;
+ // default:
+ // break;
+ // }
+
+ return handled || base.OnButtonPressEvent (evnt);
+ }
+
+ protected override bool OnButtonReleaseEvent (EventButton evnt)
+ {
+ bool handled = false;
+
+ if (can_select)
+ handled |= OnSelectionButtonReleaseEvent (evnt);
+
+ if (handled)
+ return handled;
+
+ return handled |= base.OnButtonReleaseEvent (evnt);
+ }
+
+ protected override bool OnMotionNotifyEvent (EventMotion evnt)
+ {
+ bool handled = false;
+
+ if (can_select)
+ handled |= OnSelectionMotionNotifyEvent (evnt);
+
+ return handled || base.OnMotionNotifyEvent (evnt);
- return base.OnButtonPressEvent (evnt);
}
protected override bool OnScrollEvent (EventScroll evnt)
@@ -516,7 +634,6 @@ Console.WriteLine ("IsNoWindow: " + IsNoWindow);
void PaintRectangle (Rectangle area, InterpType interpolation)
{
-Console.WriteLine ("PaintRectangle {0}", area);
int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;
//Draw background
@@ -668,5 +785,150 @@ Console.WriteLine ("PaintRectangle {0}", area);
return null;
}
#endregion
+
+#region selection
+ void OnSelectionRealized ()
+ {
+ //FIXME SetCUrsor
+
+ selection_gc = new Gdk.GC (GdkWindow);
+ selection_gc.Copy (Style.ForegroundGCs [(int)StateType.Normal]);
+ selection_gc.Function = Gdk.Function.Invert;
+ selection_gc.SetLineAttributes (1, LineStyle.Solid, CapStyle.NotLast, JoinStyle.Miter);
+ }
+
+ void OnSelectionUnrealized ()
+ {
+ selection_gc.Unref ();
+ selection_gc = null;
+ }
+
+ bool OnSelectionExposeEvent (EventExpose evnt)
+ {
+ if (selection == Rectangle.Zero)
+ return false;
+
+ Rectangle win_selection = ImageCoordsToWindow (selection);
+ Region r = new Region ();
+ r.UnionWithRect (win_selection);
+ evnt.Region.Subtract (r);
+ r.Destroy ();
+
+ using (Cairo.Context ctx = CairoHelper.Create (GdkWindow)) {
+ ctx.SetSourceRGBA (.5, .5, .5, .7);
+ CairoHelper.Region (ctx, evnt.Region);
+ ctx.Fill ();
+ }
+
+ return true;
+ }
+
+ enum DragMode {
+ None,
+ Move,
+ Extend,
+ }
+
+ const int SELECTION_SNAP_DISTANCE = 8;
+ DragMode GetDragMode (int x, int y)
+ {
+ Rectangle win_selection = ImageCoordsToWindow (selection);
+ if (Rectangle.Inflate (win_selection, -SELECTION_SNAP_DISTANCE, -SELECTION_SNAP_DISTANCE).Contains (x, y))
+ return DragMode.Move;
+ if (Rectangle.Inflate (win_selection, SELECTION_SNAP_DISTANCE, SELECTION_SNAP_DISTANCE).Contains (x, y))
+ return DragMode.Extend;
+ return DragMode.None;
+ }
+
+ bool is_dragging_selection = false;
+ bool is_moving_selection = false;
+ Point selection_anchor = Point.Zero;
+ bool OnSelectionButtonPressEvent (EventButton evnt)
+ {
+ if (evnt.Button != 1)
+ return false;
+
+ if (PointerMode == PointerMode.None)
+ return false;
+
+ if (evnt.Type == EventType.TwoButtonPress) {
+ return false;
+ }
+
+ bool is_new_selection;
+ switch (GetDragMode ((int)evnt.X, (int)evnt.Y)) {
+ case DragMode.None:
+ is_dragging_selection = true;
+ PointerMode = PointerMode.Select;
+ Selection = Rectangle.Zero;
+ selection_anchor = WindowCoordsToImage (new Point ((int)evnt.X, (int)evnt.Y));
+ break;
+ case DragMode.Extend:
+ //is_dragging_selection = true;
+ //SetPointer
+ break;
+ case DragMode.Move:
+ Console.WriteLine ("DragMode: Move");
+ is_moving_selection = true;
+ selection_anchor = WindowCoordsToImage (new Point ((int)evnt.X, (int)evnt.Y));
+ //SetPointer
+ break;
+ }
+
+ return true;
+ }
+
+ bool OnSelectionButtonReleaseEvent (EventButton evnt)
+ {
+ if (evnt.Button != 1)
+ return false;
+
+ is_dragging_selection = false;
+ is_moving_selection = false;
+ //SetCursor
+ return true;
+ }
+
+ const int SELECTION_THRESHOLD = 5;
+ bool OnSelectionMotionNotifyEvent (EventMotion evnt)
+ {
+ int x, y;
+ ModifierType mod;
+
+ if (evnt.IsHint)
+ GdkWindow.GetPointer (out x, out y, out mod);
+ else {
+ x = (int)evnt.X;
+ y = (int)evnt.Y;
+ }
+
+
+ Point img = WindowCoordsToImage (new Point (x, y));
+ if (is_dragging_selection) {
+ Point win_anchor = ImageCoordsToWindow (selection_anchor);
+ if (Selection == Rectangle.Zero &&
+ Math.Abs (evnt.X - win_anchor.X) < SELECTION_THRESHOLD &&
+ Math.Abs (evnt.Y - win_anchor.Y) < SELECTION_THRESHOLD)
+ return true;
+
+ Selection = new Rectangle (Math.Min (selection_anchor.X, img.X),
+ Math.Min (selection_anchor.Y, img.Y),
+ Math.Abs (selection_anchor.X - img.X),
+ Math.Abs (selection_anchor.Y - img.Y));
+ return true;
+ }
+
+ if (is_moving_selection) {
+ Selection = new Rectangle (Selection.X + img.X - selection_anchor.X,
+ Selection.Y + img.Y - selection_anchor.Y,
+ Selection.Width, Selection.Height);
+ selection_anchor = img;
+ return true;
+ }
+
+ //set the pointer according to DragMode
+ return true;
+ }
+#endregion
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]