|
@@ -5,87 +5,169 @@ using System.Windows.Input;
|
|
|
|
|
|
namespace PixiEditor.Views.UserControls
|
|
|
{
|
|
|
- /// <summary>
|
|
|
- /// Interaction logic for ZoomBox.xaml
|
|
|
- /// </summary>
|
|
|
public partial class ZoomBox : ContentControl
|
|
|
{
|
|
|
- private bool captured = false;
|
|
|
- private Point prevMousePos;
|
|
|
+ public enum Mode
|
|
|
+ {
|
|
|
+ Normal, Move, Zoom
|
|
|
+ }
|
|
|
+
|
|
|
+ private interface IDragOperation
|
|
|
+ {
|
|
|
+ void Start(MouseButtonEventArgs e);
|
|
|
+
|
|
|
+ void Update(MouseEventArgs e);
|
|
|
+
|
|
|
+ void Terminate();
|
|
|
+ }
|
|
|
+
|
|
|
+ private class MoveDragOperation : IDragOperation
|
|
|
+ {
|
|
|
+ private ZoomBox parent;
|
|
|
+ private Point prevMousePos;
|
|
|
+
|
|
|
+ public MoveDragOperation(ZoomBox zoomBox)
|
|
|
+ {
|
|
|
+ parent = zoomBox;
|
|
|
+ }
|
|
|
+ public void Start(MouseButtonEventArgs e)
|
|
|
+ {
|
|
|
+ prevMousePos = e.GetPosition(parent.mainCanvas);
|
|
|
+ parent.mainCanvas.CaptureMouse();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Update(MouseEventArgs e)
|
|
|
+ {
|
|
|
+ var curMousePos = e.GetPosition(parent.mainCanvas);
|
|
|
+ parent.SpaceOriginPos += curMousePos - prevMousePos;
|
|
|
+ prevMousePos = e.GetPosition(parent.mainCanvas);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Terminate()
|
|
|
+ {
|
|
|
+ parent.mainCanvas.ReleaseMouseCapture();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private class ZoomDragOperation : IDragOperation
|
|
|
+ {
|
|
|
+ private ZoomBox parent;
|
|
|
+
|
|
|
+ private int initZoomPower;
|
|
|
+ private Point initSpaceOriginPos;
|
|
|
+
|
|
|
+ private Point zoomOrigin;
|
|
|
+ private Point screenZoomOrigin;
|
|
|
+
|
|
|
+ public ZoomDragOperation(ZoomBox zoomBox)
|
|
|
+ {
|
|
|
+ parent = zoomBox;
|
|
|
+ }
|
|
|
+ public void Start(MouseButtonEventArgs e)
|
|
|
+ {
|
|
|
+ screenZoomOrigin = e.GetPosition(parent.mainCanvas);
|
|
|
+ zoomOrigin = parent.ToZoomboxSpace(screenZoomOrigin);
|
|
|
+ initZoomPower = parent.ZoomPower;
|
|
|
+ initSpaceOriginPos = parent.SpaceOriginPos;
|
|
|
+ parent.mainCanvas.CaptureMouse();
|
|
|
+ }
|
|
|
|
|
|
- private Point backingSpaceOriginPos;
|
|
|
+ public void Update(MouseEventArgs e)
|
|
|
+ {
|
|
|
+ var curScreenPos = e.GetPosition(parent.mainCanvas);
|
|
|
+ double deltaX = screenZoomOrigin.X - curScreenPos.X;
|
|
|
+ int deltaPower = (int)(deltaX / 10.0);
|
|
|
+ parent.ZoomPower = initZoomPower - deltaPower;
|
|
|
+
|
|
|
+ parent.SpaceOriginPos = initSpaceOriginPos;
|
|
|
+ var shiftedOriginPos = parent.ToScreenSpace(zoomOrigin);
|
|
|
+ var deltaOriginPos = shiftedOriginPos - screenZoomOrigin;
|
|
|
+ parent.SpaceOriginPos = initSpaceOriginPos - deltaOriginPos;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Terminate()
|
|
|
+ {
|
|
|
+ parent.mainCanvas.ReleaseMouseCapture();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Point spaceOriginPos;
|
|
|
private Point SpaceOriginPos
|
|
|
{
|
|
|
- get => backingSpaceOriginPos;
|
|
|
+ get => spaceOriginPos;
|
|
|
set
|
|
|
{
|
|
|
- backingSpaceOriginPos = value;
|
|
|
- Canvas.SetLeft(mainGrid, backingSpaceOriginPos.X);
|
|
|
- Canvas.SetTop(mainGrid, backingSpaceOriginPos.Y);
|
|
|
+ spaceOriginPos = value;
|
|
|
+ Canvas.SetLeft(mainGrid, spaceOriginPos.X);
|
|
|
+ Canvas.SetTop(mainGrid, spaceOriginPos.Y);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private int backingZoomPower;
|
|
|
+ private int zoomPower;
|
|
|
private int ZoomPower
|
|
|
{
|
|
|
- get => backingZoomPower;
|
|
|
+ get => zoomPower;
|
|
|
set
|
|
|
{
|
|
|
- backingZoomPower = value;
|
|
|
+ zoomPower = value;
|
|
|
var mult = Zoom;
|
|
|
scaleTransform.ScaleX = mult;
|
|
|
scaleTransform.ScaleY = mult;
|
|
|
}
|
|
|
}
|
|
|
- private double Zoom => Math.Pow(1.1, backingZoomPower);
|
|
|
+ private double Zoom => Math.Pow(1.1, zoomPower);
|
|
|
+ private Mode mode;
|
|
|
+
|
|
|
+ private IDragOperation activeDragOperation = null;
|
|
|
|
|
|
public ZoomBox()
|
|
|
{
|
|
|
InitializeComponent();
|
|
|
+ mode = Mode.Zoom;
|
|
|
}
|
|
|
|
|
|
- private void OnMouseDown(object sender, MouseButtonEventArgs e)
|
|
|
+ private Point ToScreenSpace(Point p)
|
|
|
{
|
|
|
- mainCanvas.CaptureMouse();
|
|
|
- captured = true;
|
|
|
- prevMousePos = e.GetPosition(mainCanvas);
|
|
|
+ double zoom = Zoom;
|
|
|
+ p.X *= zoom;
|
|
|
+ p.Y *= zoom;
|
|
|
+ p += (Vector)SpaceOriginPos;
|
|
|
+ return p;
|
|
|
}
|
|
|
|
|
|
- private void OnMouseUp(object sender, MouseButtonEventArgs e)
|
|
|
+ private Point ToZoomboxSpace(Point mousePos)
|
|
|
{
|
|
|
- mainCanvas.ReleaseMouseCapture();
|
|
|
- captured = false;
|
|
|
- prevMousePos = e.GetPosition(mainCanvas);
|
|
|
+ double zoom = Zoom;
|
|
|
+ mousePos -= (Vector)SpaceOriginPos;
|
|
|
+ mousePos.X /= zoom;
|
|
|
+ mousePos.Y /= zoom;
|
|
|
+ return mousePos;
|
|
|
}
|
|
|
|
|
|
- private void OnMouseMove(object sender, MouseEventArgs e)
|
|
|
+ private void OnMouseDown(object sender, MouseButtonEventArgs e)
|
|
|
{
|
|
|
- if (!captured)
|
|
|
+ if (mode == Mode.Normal)
|
|
|
return;
|
|
|
- var curMousePos = e.GetPosition(mainCanvas);
|
|
|
- SpaceOriginPos += curMousePos - prevMousePos;
|
|
|
|
|
|
- prevMousePos = e.GetPosition(mainCanvas);
|
|
|
+ activeDragOperation?.Terminate();
|
|
|
+
|
|
|
+ if (mode == Mode.Move)
|
|
|
+ activeDragOperation = new MoveDragOperation(this);
|
|
|
+ else if (mode == Mode.Zoom)
|
|
|
+ activeDragOperation = new ZoomDragOperation(this);
|
|
|
+
|
|
|
+ activeDragOperation.Start(e);
|
|
|
}
|
|
|
|
|
|
- private Point ToScreenSpace(Point p)
|
|
|
+ private void OnMouseUp(object sender, MouseButtonEventArgs e)
|
|
|
{
|
|
|
- double zoom = Zoom;
|
|
|
- p.X /= zoom;
|
|
|
- p.Y /= zoom;
|
|
|
- p.X += SpaceOriginPos.X;
|
|
|
- p.Y += SpaceOriginPos.Y;
|
|
|
- return p;
|
|
|
+ activeDragOperation?.Terminate();
|
|
|
+ activeDragOperation = null;
|
|
|
}
|
|
|
|
|
|
- private Point ToZoomboxSpace(Point mousePos)
|
|
|
+ private void OnMouseMove(object sender, MouseEventArgs e)
|
|
|
{
|
|
|
- double zoom = Zoom;
|
|
|
- mousePos.X -= SpaceOriginPos.X;
|
|
|
- mousePos.Y -= SpaceOriginPos.Y;
|
|
|
- mousePos.X *= zoom;
|
|
|
- mousePos.Y *= zoom;
|
|
|
- return mousePos;
|
|
|
+ activeDragOperation?.Update(e);
|
|
|
}
|
|
|
|
|
|
private void OnScroll(object sender, MouseWheelEventArgs e)
|
|
@@ -97,7 +179,7 @@ namespace PixiEditor.Views.UserControls
|
|
|
|
|
|
var shiftedMousePos = ToScreenSpace(oldZoomboxMousePos);
|
|
|
var deltaMousePos = oldMousePos - shiftedMousePos;
|
|
|
- SpaceOriginPos = SpaceOriginPos - deltaMousePos;
|
|
|
+ SpaceOriginPos = SpaceOriginPos + deltaMousePos;
|
|
|
}
|
|
|
}
|
|
|
}
|