|
@@ -18,20 +18,16 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
{
|
|
|
public class MoveTool : BitmapOperationTool
|
|
|
{
|
|
|
- public bool MoveAll { get; set; } = false;
|
|
|
-
|
|
|
- public override ToolType ToolType => ToolType.Move;
|
|
|
-
|
|
|
private Layer[] affectedLayers;
|
|
|
- private Dictionary<Layer, bool> _clearedPixels = new Dictionary<Layer, bool>();
|
|
|
- private Coordinates[] _currentSelection;
|
|
|
- private Coordinates _lastMouseMove;
|
|
|
- private Coordinates _lastStartMousePos;
|
|
|
- private Dictionary<Layer, Color[]> _startPixelColors;
|
|
|
- private Dictionary<Layer, Thickness> _startingOffsets;
|
|
|
- private Coordinates[] _startSelection;
|
|
|
- private bool _updateViewModelSelection = true;
|
|
|
-
|
|
|
+ private Dictionary<Layer, bool> clearedPixels = new Dictionary<Layer, bool>();
|
|
|
+ private Coordinates[] currentSelection;
|
|
|
+ private Coordinates lastMouseMove;
|
|
|
+ private Coordinates lastStartMousePos;
|
|
|
+ private Dictionary<Layer, Color[]> startPixelColors;
|
|
|
+ private Dictionary<Layer, Thickness> startingOffsets;
|
|
|
+ private Coordinates[] startSelection;
|
|
|
+ private bool updateViewModelSelection = true;
|
|
|
+
|
|
|
public MoveTool()
|
|
|
{
|
|
|
Tooltip = "Moves selected pixels (V). Hold Ctrl to move all layers";
|
|
@@ -39,16 +35,20 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
HideHighlight = true;
|
|
|
RequiresPreviewLayer = true;
|
|
|
UseDefaultUndoMethod = true;
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool MoveAll { get; set; } = false;
|
|
|
+
|
|
|
+ public override ToolType ToolType => ToolType.Move;
|
|
|
|
|
|
public override void AfterAddedUndo()
|
|
|
{
|
|
|
- if (_currentSelection != null && _currentSelection.Length != 0)
|
|
|
+ if (currentSelection != null && currentSelection.Length != 0)
|
|
|
{
|
|
|
- //Inject to default undo system change custom changes made by this tool
|
|
|
- foreach (var item in _startPixelColors)
|
|
|
+ // Inject to default undo system change custom changes made by this tool
|
|
|
+ foreach (var item in startPixelColors)
|
|
|
{
|
|
|
- BitmapPixelChanges beforeMovePixels = BitmapPixelChanges.FromArrays(_startSelection, item.Value);
|
|
|
+ BitmapPixelChanges beforeMovePixels = BitmapPixelChanges.FromArrays(startSelection, item.Value);
|
|
|
Change changes = UndoManager.UndoStack.Peek();
|
|
|
int layerIndex = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.IndexOf(item.Key);
|
|
|
|
|
@@ -57,63 +57,66 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
|
|
|
((LayerChange[])changes.NewValue).First(x => x.LayerIndex == layerIndex).PixelChanges.ChangedPixels
|
|
|
.AddRangeNewOnly(BitmapPixelChanges
|
|
|
- .FromSingleColoredArray(_startSelection, System.Windows.Media.Colors.Transparent)
|
|
|
+ .FromSingleColoredArray(startSelection, System.Windows.Media.Colors.Transparent)
|
|
|
.ChangedPixels);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public override void OnStoppedRecordingMouseUp(MouseEventArgs e) //This adds undo if there is no selection, reason why this isn't in AfterUndoAdded,
|
|
|
- { //is because it doesn't fire if no pixel changes were made.
|
|
|
- if (_currentSelection != null && _currentSelection.Length == 0)
|
|
|
- {
|
|
|
- UndoManager.AddUndoChange(new Change(ApplyOffsets, new object[] { _startingOffsets },
|
|
|
- ApplyOffsets, new object[] { GetOffsets(affectedLayers) }, "Move layers"));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void ApplyOffsets(object[] parameters)
|
|
|
+ // This adds undo if there is no selection, reason why this isn't in AfterUndoAdded,
|
|
|
+ // is because it doesn't fire if no pixel changes were made.
|
|
|
+ public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
|
|
|
{
|
|
|
- Dictionary<Layer, Thickness> offsets = (Dictionary<Layer, Thickness>)parameters[0];
|
|
|
- foreach (var offset in offsets)
|
|
|
+ if (currentSelection != null && currentSelection.Length == 0)
|
|
|
{
|
|
|
- offset.Key.Offset = offset.Value;
|
|
|
+ UndoManager.AddUndoChange(new Change(
|
|
|
+ ApplyOffsets,
|
|
|
+ new object[] { startingOffsets },
|
|
|
+ ApplyOffsets,
|
|
|
+ new object[] { GetOffsets(affectedLayers) },
|
|
|
+ "Move layers"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public override LayerChange[] Use(Layer layer, Coordinates[] mouseMove, Color color)
|
|
|
{
|
|
|
Coordinates start = mouseMove[^1];
|
|
|
- if (_lastStartMousePos != start) //I am aware that this could be moved to OnMouseDown, but it is executed before Use, so I didn't want to complicate for now
|
|
|
+
|
|
|
+ // I am aware that this could be moved to OnMouseDown, but it is executed before Use, so I didn't want to complicate for now
|
|
|
+ if (lastStartMousePos != start)
|
|
|
{
|
|
|
ResetSelectionValues(start);
|
|
|
- if (ViewModelMain.Current.ActiveSelection != null && ViewModelMain.Current.ActiveSelection.SelectedPoints.Count > 0) //Move offset if no selection
|
|
|
+
|
|
|
+ // Move offset if no selection
|
|
|
+ if (ViewModelMain.Current.ActiveSelection != null && ViewModelMain.Current.ActiveSelection.SelectedPoints.Count > 0)
|
|
|
{
|
|
|
- _currentSelection = ViewModelMain.Current.ActiveSelection.SelectedPoints.ToArray();
|
|
|
+ currentSelection = ViewModelMain.Current.ActiveSelection.SelectedPoints.ToArray();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- _currentSelection = Array.Empty<Coordinates>();
|
|
|
+ currentSelection = Array.Empty<Coordinates>();
|
|
|
}
|
|
|
|
|
|
- if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
|
|
|
+ if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
|
|
|
+ {
|
|
|
affectedLayers = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.Where(x => x.IsVisible)
|
|
|
- .ToArray();
|
|
|
+ .ToArray();
|
|
|
+ }
|
|
|
else
|
|
|
{
|
|
|
affectedLayers = new[] { layer };
|
|
|
}
|
|
|
|
|
|
- _startSelection = _currentSelection;
|
|
|
- _startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, _startSelection);
|
|
|
- _startingOffsets = GetOffsets(affectedLayers);
|
|
|
+ startSelection = currentSelection;
|
|
|
+ startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, startSelection);
|
|
|
+ startingOffsets = GetOffsets(affectedLayers);
|
|
|
}
|
|
|
|
|
|
LayerChange[] result = new LayerChange[affectedLayers.Length];
|
|
|
var end = mouseMove[0];
|
|
|
for (int i = 0; i < affectedLayers.Length; i++)
|
|
|
{
|
|
|
- if (_currentSelection.Length > 0)
|
|
|
+ if (currentSelection.Length > 0)
|
|
|
{
|
|
|
var changes = MoveSelection(affectedLayers[i], mouseMove);
|
|
|
changes = RemoveTransparentPixels(changes);
|
|
@@ -122,15 +125,40 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- var vector = Transform.GetTranslation(_lastMouseMove, end);
|
|
|
+ var vector = Transform.GetTranslation(lastMouseMove, end);
|
|
|
affectedLayers[i].Offset = new Thickness(affectedLayers[i].OffsetX + vector.X, affectedLayers[i].OffsetY + vector.Y, 0, 0);
|
|
|
result[i] = new LayerChange(BitmapPixelChanges.Empty, affectedLayers[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- _lastMouseMove = end;
|
|
|
+ lastMouseMove = end;
|
|
|
|
|
|
return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public BitmapPixelChanges MoveSelection(Layer layer, Coordinates[] mouseMove)
|
|
|
+ {
|
|
|
+ Coordinates end = mouseMove[0];
|
|
|
+
|
|
|
+ currentSelection = TranslateSelection(end, out Coordinates[] previousSelection);
|
|
|
+ if (updateViewModelSelection)
|
|
|
+ {
|
|
|
+ ViewModelMain.Current.ActiveSelection.SetSelection(currentSelection, SelectionType.New);
|
|
|
+ }
|
|
|
+
|
|
|
+ ClearSelectedPixels(layer, previousSelection);
|
|
|
+
|
|
|
+ lastMouseMove = end;
|
|
|
+ return BitmapPixelChanges.FromArrays(currentSelection, startPixelColors[layer]);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ApplyOffsets(object[] parameters)
|
|
|
+ {
|
|
|
+ Dictionary<Layer, Thickness> offsets = (Dictionary<Layer, Thickness>)parameters[0];
|
|
|
+ foreach (var offset in offsets)
|
|
|
+ {
|
|
|
+ offset.Key.Offset = offset.Value;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private Dictionary<Layer, Thickness> GetOffsets(Layer[] layers)
|
|
@@ -154,47 +182,31 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
return pixels;
|
|
|
}
|
|
|
|
|
|
- public BitmapPixelChanges MoveSelection(Layer layer, Coordinates[] mouseMove)
|
|
|
- {
|
|
|
- Coordinates end = mouseMove[0];
|
|
|
-
|
|
|
- _currentSelection = TranslateSelection(end, out Coordinates[] previousSelection);
|
|
|
- if (_updateViewModelSelection)
|
|
|
- {
|
|
|
- ViewModelMain.Current.ActiveSelection.SetSelection(_currentSelection, SelectionType.New);
|
|
|
- }
|
|
|
-
|
|
|
- ClearSelectedPixels(layer, previousSelection);
|
|
|
-
|
|
|
- _lastMouseMove = end;
|
|
|
- return BitmapPixelChanges.FromArrays(_currentSelection, _startPixelColors[layer]);
|
|
|
- }
|
|
|
-
|
|
|
private void ResetSelectionValues(Coordinates start)
|
|
|
{
|
|
|
- _lastStartMousePos = start;
|
|
|
- _lastMouseMove = start;
|
|
|
- _clearedPixels = new Dictionary<Layer, bool>();
|
|
|
- _updateViewModelSelection = true;
|
|
|
- _startPixelColors = null;
|
|
|
- _startSelection = null;
|
|
|
+ lastStartMousePos = start;
|
|
|
+ lastMouseMove = start;
|
|
|
+ clearedPixels = new Dictionary<Layer, bool>();
|
|
|
+ updateViewModelSelection = true;
|
|
|
+ startPixelColors = null;
|
|
|
+ startSelection = null;
|
|
|
}
|
|
|
|
|
|
private Coordinates[] TranslateSelection(Coordinates end, out Coordinates[] previousSelection)
|
|
|
{
|
|
|
- Coordinates translation = Transform.GetTranslation(_lastMouseMove, end);
|
|
|
- previousSelection = _currentSelection.ToArray();
|
|
|
+ Coordinates translation = Transform.GetTranslation(lastMouseMove, end);
|
|
|
+ previousSelection = currentSelection.ToArray();
|
|
|
return Transform.Translate(previousSelection, translation);
|
|
|
}
|
|
|
|
|
|
private void ClearSelectedPixels(Layer layer, Coordinates[] selection)
|
|
|
{
|
|
|
- if (!_clearedPixels.ContainsKey(layer) || _clearedPixels[layer] == false)
|
|
|
+ if (!clearedPixels.ContainsKey(layer) || clearedPixels[layer] == false)
|
|
|
{
|
|
|
ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.First(x => x == layer)
|
|
|
.SetPixels(BitmapPixelChanges.FromSingleColoredArray(selection, System.Windows.Media.Colors.Transparent));
|
|
|
|
|
|
- _clearedPixels[layer] = true;
|
|
|
+ clearedPixels[layer] = true;
|
|
|
}
|
|
|
}
|
|
|
}
|