Skip to content

Commit

Permalink
more
Browse files Browse the repository at this point in the history
  • Loading branch information
PurelyAndy committed Jan 7, 2025
1 parent 876d117 commit e9d8626
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 17 deletions.
13 changes: 13 additions & 0 deletions .idea/.idea.Pinta/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/.idea.Pinta/.idea/indexLayout.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/.idea.Pinta/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Pinta.Core/Classes/Rectangle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public RectangleD (in PointD point, double width, double height)
/// </summary>
/// <param name="invert_if_negative">
/// Flips the start and end points if necessary to produce a rectangle with positive width and height.
/// Otherwise, a negative width or height is clamped to zero.
/// Otherwise, a negative width or height is allowed.
/// </param>
public static RectangleD FromPoints (in PointD start, in PointD end, bool invert_if_negative = true)
{
Expand All @@ -63,9 +63,9 @@ public static RectangleD FromPoints (in PointD start, in PointD end, bool invert
double x1 = Math.Min (start.X, end.X);
double x2 = Math.Max (start.X, end.X);
return new RectangleD (x1, y1, x2 - x1, y2 - y1);
} else {
return new RectangleD (start.X, start.Y, end.X - start.X, end.Y - start.Y);
}

return new RectangleD (start.X, start.Y, end.X - start.X, end.Y - start.Y);
}

public static readonly RectangleD Zero;
Expand Down
25 changes: 18 additions & 7 deletions Pinta.Tools/Handles/RectangleHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ public class RectangleHandle : IToolHandle
private readonly MoveHandle[] handles = new MoveHandle[8];
private MoveHandle? active_handle = null;
private PointD? drag_start_pos = null;
private PointD drag_offset_from_handle = PointD.Zero;
private double aspect_ratio = 1;
public Matrix Transform { get; set; } = CairoExtensions.CreateIdentityMatrix ();

public RectangleHandle ()
{
Expand Down Expand Up @@ -87,6 +89,11 @@ public RectangleD Rectangle {
}
}

/// <summary>
/// Corrects the rectangle if the point meant to be the bottom right corner is above or to the left of the point meant to be the top left corner.
/// </summary>
public void CorrectRectangle () => Rectangle = RectangleD.FromPoints (start_pt, end_pt);

/// <summary>
/// Begins a drag operation if the mouse position is on top of a handle.
/// Mouse movements are clamped to fall within the specified image size.
Expand All @@ -106,6 +113,7 @@ public bool BeginDrag (in PointD canvas_pos, in Size image_size)
return false;

drag_start_pos = view_pos;
drag_offset_from_handle = new PointD (canvas_pos.X - active_handle.CanvasPosition.X, canvas_pos.Y - active_handle.CanvasPosition.Y);
return true;
}

Expand All @@ -121,8 +129,8 @@ public RectangleI UpdateDrag (PointD canvas_pos, ConstrainType constrain = Const

// Clamp mouse position to the image size.
canvas_pos = new PointD (
Math.Round (Math.Clamp (canvas_pos.X, 0, image_size.Width)),
Math.Round (Math.Clamp (canvas_pos.Y, 0, image_size.Height)));
Math.Round (Math.Clamp (canvas_pos.X - drag_offset_from_handle.X, 0, image_size.Width)),
Math.Round (Math.Clamp (canvas_pos.Y - drag_offset_from_handle.Y, 0, image_size.Height)));

var dirty = InvalidateRect;

Expand Down Expand Up @@ -162,7 +170,6 @@ public void EndDrag ()
var rect = Rectangle;
start_pt = rect.Location ();
end_pt = rect.EndLocation ();
Console.WriteLine($"Start: {start_pt}, End: {end_pt}");
}

/// <summary>
Expand All @@ -171,7 +178,7 @@ public void EndDrag ()
public string? GetCursorAtPoint (PointD view_pos)
=> handles.FirstOrDefault (c => c.ContainsPoint (view_pos))?.CursorName;

private void UpdateHandlePositions ()
public void UpdateHandlePositions ()
{
var rect = Rectangle;
var center = rect.GetCenter ();
Expand All @@ -183,6 +190,12 @@ private void UpdateHandlePositions ()
handles[5].CanvasPosition = new PointD (center.X, rect.Top);
handles[6].CanvasPosition = new PointD (rect.Right, center.Y);
handles[7].CanvasPosition = new PointD (center.X, rect.Bottom);
foreach (var handle in handles) {
double x = handle.CanvasPosition.X;
double y = handle.CanvasPosition.Y;
Transform.TransformPoint (ref x, ref y);
handle.CanvasPosition = new PointD (x, y);
}
}

private void UpdateHandleUnderPoint (PointD view_pos)
Expand All @@ -193,13 +206,11 @@ private void UpdateHandleUnderPoint (PointD view_pos)
// at the same position so pick the bottom right corner.
var rect = Rectangle;
if (active_handle is not null && rect.Width == 0.0 && rect.Height == 0.0)
active_handle = handles[3];
active_handle = handles[(int)HandleIndex.BottomRight];
}

private void MoveActiveHandle (double x, double y, ConstrainType constrain = ConstrainType.None)
{
// Update the rectangle's size depending on which handle was dragged.
Console.WriteLine((HandleIndex)Array.IndexOf (handles, active_handle));
switch ((HandleIndex)Array.IndexOf (handles, active_handle)) {
case HandleIndex.TopLeft:
start_pt = new (x, y);
Expand Down
18 changes: 15 additions & 3 deletions Pinta.Tools/Tools/BaseTransformTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public abstract class BaseTransformTool : BaseTool
{
private readonly int rotate_steps = 32;
private readonly Matrix transform = CairoExtensions.CreateIdentityMatrix ();
private Matrix stored_handle_transform = CairoExtensions.CreateIdentityMatrix ();
private RectangleD source_rect;
private PointD original_point;
private PointD rect_original_point;
Expand Down Expand Up @@ -106,6 +107,7 @@ protected override void OnMouseMove (Document document, ToolMouseEventArgs e)
var constrain = e.IsShiftPressed;

transform.InitIdentity ();
rect_handle.Transform.InitMatrix (stored_handle_transform);

if (is_scaling) {
rect_handle.UpdateDrag (e.PointDouble, constrain ? ConstrainType.AspectRatio : ConstrainType.None);
Expand All @@ -115,6 +117,7 @@ protected override void OnMouseMove (Document document, ToolMouseEventArgs e)
var sx = (source_rect.Width > 0) ? (target_rect.Width / source_rect.Width) : 0.0;
var sy = (source_rect.Height > 0) ? (target_rect.Height / source_rect.Height) : 0.0;

//transform.Multiply (rect_handle.Transform);
transform.Translate (target_rect.Left, target_rect.Top);
transform.Scale (sx, sy);
transform.Translate (-source_rect.Left, -source_rect.Top);
Expand All @@ -136,16 +139,20 @@ protected override void OnMouseMove (Document document, ToolMouseEventArgs e)
transform.Translate (center.X, center.Y);
transform.Rotate (-angle);
transform.Translate (-center.X, -center.Y);
//TODO: the handle should rotate with the selection rather than just resizing to fit the new bounds
rect_handle.Rectangle = document.Selection.SelectionPath.GetBounds ().ToDouble ();

rect_handle.Transform.Translate (center.X, center.Y);
rect_handle.Transform.Rotate (-angle);
rect_handle.Transform.Translate (-center.X, -center.Y);
rect_handle.UpdateHandlePositions ();
} else {
// The cursor position can be a subpixel value. Round to an integer
// so that we only translate by entire pixels.
// (Otherwise, blurring / anti-aliasing may be introduced)
var dx = Math.Floor (e.PointDouble.X - original_point.X);
var dy = Math.Floor (e.PointDouble.Y - original_point.Y);
transform.Translate (dx, dy);
rect_handle.Rectangle = new RectangleD(rect_original_point.X + dx, rect_original_point.Y + dy, rect_handle.Rectangle.Width, rect_handle.Rectangle.Height);
rect_handle.Transform.Translate (dx, dy);
rect_handle.UpdateHandlePositions ();
}

OnUpdateTransform (document, transform);
Expand Down Expand Up @@ -215,6 +222,7 @@ protected virtual void OnStartTransform (Document document)
{
source_rect = GetSourceRectangle (document);
transform.InitIdentity ();
stored_handle_transform.InitMatrix (rect_handle.Transform);
}

protected virtual void OnUpdateTransform (Document document, Matrix transform)
Expand All @@ -227,6 +235,8 @@ protected virtual void OnFinishTransform (Document document, Matrix transform)
is_rotating = false;
is_scaling = false;
using_mouse = false;

stored_handle_transform.Multiply (rect_handle.Transform);
}

protected override void OnAfterUndo (Document document)
Expand Down Expand Up @@ -256,6 +266,8 @@ private void HandleSourceRectangleChanged (Document document)
{
var dirty = rect_handle.InvalidateRect;
rect_handle.Rectangle = GetSourceRectangle (document);
rect_handle.Transform.InitIdentity ();
rect_handle.UpdateHandlePositions ();
dirty = dirty.Union (rect_handle.InvalidateRect);
PintaCore.Workspace.InvalidateWindowRect (dirty);
}
Expand Down
2 changes: 1 addition & 1 deletion Pinta.Tools/Tools/MoveSelectedTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ protected override void OnFinishTransform (Document document, Matrix transform)
if (hist != null)
document.History.PushNewItem (hist);

rect_handle.Rectangle = RectangleD.FromPoints (rect_handle.Rectangle.Location (), rect_handle.Rectangle.EndLocation ());
rect_handle.CorrectRectangle();

hist = null;
original_selection = null;
Expand Down
1 change: 0 additions & 1 deletion Pinta.Tools/Tools/MoveSelectionTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public sealed class MoveSelectionTool : BaseTransformTool

public MoveSelectionTool (IServiceManager service) : base (service)
{
rect_handle.InvertIfNegative = true;
}

public override string Name => Translations.GetString ("Move Selection");
Expand Down
3 changes: 1 addition & 2 deletions Pinta.Tools/Tools/SelectTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ private void AfterSelectionChange (object? sender, EventArgs event_args)
/// </summary>
private void LoadFromDocument (Document document)
{
var selection = document.Selection;
handle.Rectangle = RectangleD.FromPoints (selection.Origin, selection.End);
handle.Rectangle = document.Selection.SelectionPath.GetBounds ().ToDouble ();
ShowHandles (document.Selection.Visible && tools.CurrentTool == this);
}
}

0 comments on commit e9d8626

Please sign in to comment.