|
@@ -1,5 +1,6 @@
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
+using Avalonia.Input;
|
|
|
using ChunkyImageLib.DataHolders;
|
|
|
using PixiEditor.ChangeableDocument.Actions.Generated;
|
|
|
using Drawie.Backend.Core.Numerics;
|
|
@@ -10,6 +11,7 @@ using PixiEditor.Models.Handlers;
|
|
|
using PixiEditor.Models.Handlers.Tools;
|
|
|
using PixiEditor.Models.Tools;
|
|
|
using Drawie.Numerics;
|
|
|
+using PixiEditor.Models.Controllers.InputDevice;
|
|
|
using PixiEditor.ViewModels.Document.Nodes;
|
|
|
|
|
|
namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
|
|
@@ -21,10 +23,12 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
private bool isInProgress;
|
|
|
public override ExecutorType Type { get; }
|
|
|
|
|
|
- public override bool BlocksOtherActions => false;
|
|
|
-
|
|
|
+ public override bool BlocksOtherActions => false;
|
|
|
+
|
|
|
private List<Guid> selectedMembers = new();
|
|
|
|
|
|
+ private ShapeCorners lastCorners = new();
|
|
|
+
|
|
|
public TransformSelectedExecutor(bool toolLinked)
|
|
|
{
|
|
|
Type = toolLinked ? ExecutorType.ToolLinked : ExecutorType.Regular;
|
|
@@ -46,6 +50,7 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
if (!members.Any())
|
|
|
return ExecutionState.Error;
|
|
|
|
|
|
+ document.TransformHandler.PassthroughPointerPressed += OnLeftMouseButtonDown;
|
|
|
return SelectMembers(members);
|
|
|
}
|
|
|
|
|
@@ -81,15 +86,18 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
DocumentTransformMode mode = allRaster
|
|
|
? DocumentTransformMode.Scale_Rotate_Shear_Perspective
|
|
|
: DocumentTransformMode.Scale_Rotate_Shear_NoPerspective;
|
|
|
-
|
|
|
+
|
|
|
foreach (var structureMemberHandler in members)
|
|
|
{
|
|
|
document.SnappingHandler.Remove(structureMemberHandler.Id.ToString());
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
selectedMembers = members.Select(m => m.Id).ToList();
|
|
|
-
|
|
|
- document.TransformHandler.ShowTransform(mode, true, masterCorners, Type == ExecutorType.Regular);
|
|
|
+
|
|
|
+ lastCorners = masterCorners;
|
|
|
+ document.TransformHandler.ShowTransform(mode, true, masterCorners,
|
|
|
+ Type == ExecutorType.Regular || tool.KeepOriginalImage);
|
|
|
+
|
|
|
internals!.ActionAccumulator.AddActions(
|
|
|
new TransformSelected_Action(masterCorners, tool.KeepOriginalImage, memberCorners, false,
|
|
|
document.AnimationHandler.ActiveFrameBindable));
|
|
@@ -98,6 +106,87 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
return ExecutionState.Success;
|
|
|
}
|
|
|
|
|
|
+ public override void OnLeftMouseButtonDown(MouseOnCanvasEventArgs args)
|
|
|
+ {
|
|
|
+ var allLayers = document.StructureHelper.GetAllLayers();
|
|
|
+ var topMostWithinClick = allLayers.Where(x =>
|
|
|
+ x is { IsVisibleBindable: true, TightBounds: not null } &&
|
|
|
+ x.TightBounds.Value.ContainsInclusive(args.PositionOnCanvas))
|
|
|
+ .OrderByDescending(x => allLayers.IndexOf(x));
|
|
|
+
|
|
|
+ var nonSelected = topMostWithinClick.Where(x => x != document.SelectedStructureMember
|
|
|
+ && !document.SoftSelectedStructureMembers.Contains(x))
|
|
|
+ .ToArray();
|
|
|
+
|
|
|
+ bool isHoldingShift = args.KeyModifiers.HasFlag(KeyModifiers.Shift);
|
|
|
+
|
|
|
+ if (nonSelected.Any())
|
|
|
+ {
|
|
|
+ var topMost = nonSelected.First();
|
|
|
+
|
|
|
+ if (!isHoldingShift)
|
|
|
+ {
|
|
|
+ document.Operations.ClearSoftSelectedMembers();
|
|
|
+ document.Operations.SetSelectedMember(topMost.Id);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ document.Operations.AddSoftSelectedMember(topMost.Id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (isHoldingShift)
|
|
|
+ {
|
|
|
+ var topMostList = topMostWithinClick.ToList();
|
|
|
+ if (document.SoftSelectedStructureMembers.Count > 0)
|
|
|
+ {
|
|
|
+ Deselect(topMostList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Deselect(List<ILayerHandler> topMostWithinClick)
|
|
|
+ {
|
|
|
+ var topMost = topMostWithinClick.FirstOrDefault();
|
|
|
+ if (topMost is not null)
|
|
|
+ {
|
|
|
+ bool deselectingWasMain = document.SelectedStructureMember.Id == topMost.Id;
|
|
|
+ if (deselectingWasMain)
|
|
|
+ {
|
|
|
+ Guid? nextMain = document.SoftSelectedStructureMembers.FirstOrDefault().Id;
|
|
|
+ List<Guid> softSelected = document.SoftSelectedStructureMembers
|
|
|
+ .Select(x => x.Id).Where(x => x != nextMain.Value).ToList();
|
|
|
+
|
|
|
+ document.Operations.ClearSoftSelectedMembers();
|
|
|
+ document.Operations.SetSelectedMember(nextMain.Value);
|
|
|
+
|
|
|
+ foreach (var guid in softSelected)
|
|
|
+ {
|
|
|
+ document.Operations.AddSoftSelectedMember(guid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ List<Guid> softSelected = document.SoftSelectedStructureMembers
|
|
|
+ .Select(x => x.Id).Where(x => x != topMost.Id).ToList();
|
|
|
+
|
|
|
+ document.Operations.ClearSoftSelectedMembers();
|
|
|
+
|
|
|
+ foreach (var guid in softSelected)
|
|
|
+ {
|
|
|
+ document.Operations.AddSoftSelectedMember(guid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void OnSettingsChanged(string name, object value)
|
|
|
+ {
|
|
|
+ if (name == nameof(IMoveToolHandler.KeepOriginalImage))
|
|
|
+ {
|
|
|
+ DoTransform(lastCorners);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public override void OnMembersSelected(List<Guid> memberGuids)
|
|
|
{
|
|
|
if (isInProgress)
|
|
@@ -105,7 +194,7 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
internals.ActionAccumulator.AddActions(new EndTransformSelected_Action());
|
|
|
document!.TransformHandler.HideTransform();
|
|
|
AddSnappingForMembers(selectedMembers);
|
|
|
-
|
|
|
+
|
|
|
selectedMembers.Clear();
|
|
|
memberCorners.Clear();
|
|
|
isInProgress = false;
|
|
@@ -122,6 +211,12 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
public bool IsTransforming => isInProgress;
|
|
|
|
|
|
public void OnTransformMoved(ShapeCorners corners)
|
|
|
+ {
|
|
|
+ DoTransform(corners);
|
|
|
+ lastCorners = corners;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void DoTransform(ShapeCorners corners)
|
|
|
{
|
|
|
if (!isInProgress)
|
|
|
return;
|
|
@@ -138,7 +233,7 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
public void OnMidChangeUndo() => document!.TransformHandler.Undo();
|
|
|
|
|
|
public void OnMidChangeRedo() => document!.TransformHandler.Redo();
|
|
|
- public bool CanUndo => document!.TransformHandler.HasUndo;
|
|
|
+ public bool CanUndo => document!.TransformHandler.HasUndo;
|
|
|
public bool CanRedo => document!.TransformHandler.HasRedo;
|
|
|
|
|
|
public void OnTransformApplied()
|
|
@@ -160,6 +255,7 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
}
|
|
|
|
|
|
isInProgress = false;
|
|
|
+ document.TransformHandler.PassthroughPointerPressed -= OnLeftMouseButtonDown;
|
|
|
}
|
|
|
|
|
|
public override void ForceStop()
|
|
@@ -175,8 +271,9 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
|
|
|
AddSnappingForMembers(memberCorners.Keys.ToList());
|
|
|
|
|
|
isInProgress = false;
|
|
|
+ document.TransformHandler.PassthroughPointerPressed -= OnLeftMouseButtonDown;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private void AddSnappingForMembers(List<Guid> memberGuids)
|
|
|
{
|
|
|
foreach (Guid memberGuid in memberGuids)
|