|
@@ -1,21 +1,20 @@
|
|
|
-using ChangeableDocument;
|
|
|
-using ChangeableDocument.Actions.Document;
|
|
|
-using ChangeableDocument.Actions.Drawing;
|
|
|
-using ChangeableDocument.Actions.Drawing.Rectangle;
|
|
|
-using ChangeableDocument.Actions.Drawing.Selection;
|
|
|
-using ChangeableDocument.Actions.Properties;
|
|
|
-using ChangeableDocument.Actions.Structure;
|
|
|
-using ChangeableDocument.Actions.Undo;
|
|
|
-using ChunkyImageLib.DataHolders;
|
|
|
+using ChunkyImageLib.DataHolders;
|
|
|
+using PixiEditor.ChangeableDocument;
|
|
|
+using PixiEditor.ChangeableDocument.Actions.Document;
|
|
|
+using PixiEditor.ChangeableDocument.Actions.Drawing;
|
|
|
+using PixiEditor.ChangeableDocument.Actions.Drawing.Rectangle;
|
|
|
+using PixiEditor.ChangeableDocument.Actions.Drawing.Selection;
|
|
|
+using PixiEditor.ChangeableDocument.Actions.Properties;
|
|
|
+using PixiEditor.ChangeableDocument.Actions.Structure;
|
|
|
+using PixiEditor.ChangeableDocument.Actions.Undo;
|
|
|
+using PixiEditor.Zoombox;
|
|
|
using PixiEditorPrototype.Models;
|
|
|
-using PixiEditorPrototype.Views;
|
|
|
using SkiaSharp;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.ComponentModel;
|
|
|
using System.Linq;
|
|
|
using System.Windows;
|
|
|
-using System.Windows.Input;
|
|
|
using System.Windows.Media;
|
|
|
using System.Windows.Media.Imaging;
|
|
|
|
|
@@ -34,8 +33,6 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private Tool activeTool = Tool.Rectangle;
|
|
|
-
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
|
|
|
|
public void RaisePropertyChanged(string name)
|
|
@@ -43,12 +40,6 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
|
|
}
|
|
|
|
|
|
- public ActionAccumulator ActionAccumulator { get; }
|
|
|
- public DocumentChangeTracker Tracker { get; }
|
|
|
- public DocumentStructureHelper StructureHelper { get; }
|
|
|
- public IDocumentView? View { get; set; }
|
|
|
- private DocumentUpdater Updater { get; }
|
|
|
-
|
|
|
public FolderViewModel StructureRoot { get; }
|
|
|
public RelayCommand? UndoCommand { get; }
|
|
|
public RelayCommand? RedoCommand { get; }
|
|
@@ -57,14 +48,10 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
public RelayCommand? CreateNewFolderCommand { get; }
|
|
|
public RelayCommand? DeleteStructureMemberCommand { get; }
|
|
|
public RelayCommand? ChangeSelectedItemCommand { get; }
|
|
|
- public RelayCommand? ChangeActiveToolCommand { get; }
|
|
|
public RelayCommand? ResizeCanvasCommand { get; }
|
|
|
public RelayCommand? CombineCommand { get; }
|
|
|
public RelayCommand? ClearHistoryCommand { get; }
|
|
|
-
|
|
|
- public RelayCommand? MouseDownCommand { get; }
|
|
|
- public RelayCommand? MouseMoveCommand { get; }
|
|
|
- public RelayCommand? MouseUpCommand { get; }
|
|
|
+ public RelayCommand? MoveViewportCommand { get; }
|
|
|
|
|
|
|
|
|
public SKSurface SurfaceFull { get; set; }
|
|
@@ -85,18 +72,24 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
- if (GetCorrespondingBitmap(ChosenResolution) is not null)
|
|
|
- return ChosenResolution;
|
|
|
+ var targetRes = GetResolutionForViewport(Helpers.State.ViewportSize, Helpers.State.ViewportRealSize);
|
|
|
+ if (GetCorrespondingBitmap(targetRes) is not null)
|
|
|
+ return targetRes;
|
|
|
return ChunkResolution.Full;
|
|
|
}
|
|
|
}
|
|
|
- public ChunkResolution ChosenResolution { get; set; }
|
|
|
- public ChunkResolution ResolutionFromView
|
|
|
+
|
|
|
+ public ChunkResolution GetResolutionForViewport(Vector2d size, Vector2d realSize)
|
|
|
{
|
|
|
- set
|
|
|
- {
|
|
|
- ActionAccumulator.AddAction(new MoveViewport_PassthroughAction(SKRect.Create(0, 0, BitmapFull.PixelWidth, BitmapFull.PixelHeight), value));
|
|
|
- }
|
|
|
+ Vector2d densityVec = size.Divide(realSize);
|
|
|
+ double density = Math.Min(densityVec.X, densityVec.Y);
|
|
|
+ if (density > 8)
|
|
|
+ return ChunkResolution.Eighth;
|
|
|
+ else if (density > 4)
|
|
|
+ return ChunkResolution.Quarter;
|
|
|
+ else if (density > 2)
|
|
|
+ return ChunkResolution.Half;
|
|
|
+ return ChunkResolution.Full;
|
|
|
}
|
|
|
|
|
|
public WriteableBitmap? GetCorrespondingBitmap(ChunkResolution resolution)
|
|
@@ -111,34 +104,33 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
};
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- public Color SelectedColor { get; set; } = Colors.Black;
|
|
|
public int ResizeWidth { get; set; }
|
|
|
public int ResizeHeight { get; set; }
|
|
|
|
|
|
- public DocumentViewModel()
|
|
|
+ private DocumentHelpers Helpers { get; }
|
|
|
+ public object MoveViewportEventArgs { get; private set; }
|
|
|
+
|
|
|
+ private ViewModelMain owner;
|
|
|
+
|
|
|
+ public DocumentViewModel(ViewModelMain owner)
|
|
|
{
|
|
|
- Tracker = new DocumentChangeTracker();
|
|
|
- Updater = new DocumentUpdater(this);
|
|
|
- StructureRoot = new FolderViewModel(this, Tracker.Document.ReadOnlyStructureRoot);
|
|
|
- ActionAccumulator = new ActionAccumulator(Tracker, Updater, this);
|
|
|
- StructureHelper = new DocumentStructureHelper(this);
|
|
|
+ this.owner = owner;
|
|
|
+
|
|
|
+ Helpers = new DocumentHelpers(this);
|
|
|
+ StructureRoot = new FolderViewModel(this, Helpers, Helpers.Tracker.Document.ReadOnlyStructureRoot);
|
|
|
+
|
|
|
|
|
|
UndoCommand = new RelayCommand(Undo);
|
|
|
RedoCommand = new RelayCommand(Redo);
|
|
|
ClearSelectionCommand = new RelayCommand(ClearSelection);
|
|
|
- CreateNewLayerCommand = new RelayCommand(_ => StructureHelper.CreateNewStructureMember(StructureMemberType.Layer));
|
|
|
- CreateNewFolderCommand = new RelayCommand(_ => StructureHelper.CreateNewStructureMember(StructureMemberType.Folder));
|
|
|
+ CreateNewLayerCommand = new RelayCommand(_ => Helpers.StructureHelper.CreateNewStructureMember(StructureMemberType.Layer));
|
|
|
+ CreateNewFolderCommand = new RelayCommand(_ => Helpers.StructureHelper.CreateNewStructureMember(StructureMemberType.Folder));
|
|
|
DeleteStructureMemberCommand = new RelayCommand(DeleteStructureMember);
|
|
|
ChangeSelectedItemCommand = new RelayCommand(ChangeSelectedItem);
|
|
|
- ChangeActiveToolCommand = new RelayCommand(ChangeActiveTool);
|
|
|
ResizeCanvasCommand = new RelayCommand(ResizeCanvas);
|
|
|
CombineCommand = new RelayCommand(Combine);
|
|
|
ClearHistoryCommand = new RelayCommand(ClearHistory);
|
|
|
-
|
|
|
- MouseDownCommand = new RelayCommand(MouseDown);
|
|
|
- MouseMoveCommand = new RelayCommand(MouseMove);
|
|
|
- MouseUpCommand = new RelayCommand(MouseUp);
|
|
|
+ MoveViewportCommand = new RelayCommand(MoveViewport);
|
|
|
|
|
|
SurfaceFull = SKSurface.Create(
|
|
|
new SKImageInfo(BitmapFull.PixelWidth, BitmapFull.PixelHeight, SKColorType.Bgra8888, SKAlphaType.Premul, SKColorSpace.CreateSrgb()),
|
|
@@ -146,112 +138,70 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
BitmapFull.BackBufferStride);
|
|
|
}
|
|
|
|
|
|
- private bool mouseIsDown = false;
|
|
|
- private int mouseDownCanvasX = 0;
|
|
|
- private int mouseDownCanvasY = 0;
|
|
|
-
|
|
|
- private bool startedDrawingRect = false;
|
|
|
- private bool startedSelectingRect = false;
|
|
|
-
|
|
|
- public void MouseDown(object? param)
|
|
|
+ bool startedRectangle = false;
|
|
|
+ public void StartUpdateRectangle(ShapeData data)
|
|
|
{
|
|
|
- mouseIsDown = true;
|
|
|
- var args = (MouseButtonEventArgs)(param!);
|
|
|
- var source = (System.Windows.Controls.Image)args.Source;
|
|
|
- var pos = args.GetPosition(source);
|
|
|
- mouseDownCanvasX = (int)(pos.X / source.Width * BitmapFull.PixelHeight);
|
|
|
- mouseDownCanvasY = (int)(pos.Y / source.Height * BitmapFull.PixelHeight);
|
|
|
+ if (SelectedStructureMember is null)
|
|
|
+ return;
|
|
|
+ startedRectangle = true;
|
|
|
+ Helpers.ActionAccumulator.AddAction(new DrawRectangle_Action(SelectedStructureMember.GuidValue, data));
|
|
|
}
|
|
|
|
|
|
- public void MouseMove(object? param)
|
|
|
+ public void EndRectangle()
|
|
|
{
|
|
|
- if (!mouseIsDown)
|
|
|
+ if (!startedRectangle)
|
|
|
return;
|
|
|
- var args = (MouseEventArgs)(param!);
|
|
|
- var source = (System.Windows.Controls.Image)args.Source;
|
|
|
- var pos = args.GetPosition(source);
|
|
|
- int curX = (int)(pos.X / source.Width * BitmapFull.PixelHeight);
|
|
|
- int curY = (int)(pos.Y / source.Height * BitmapFull.PixelHeight);
|
|
|
-
|
|
|
- ProcessToolMouseMove(curX, curY);
|
|
|
+ startedRectangle = false;
|
|
|
+ Helpers.ActionAccumulator.AddAction(new EndDrawRectangle_Action());
|
|
|
}
|
|
|
|
|
|
- private void ProcessToolMouseMove(int canvasX, int canvasY)
|
|
|
+ bool startedSelection = false;
|
|
|
+ public void StartUpdateSelection(Vector2i pos, Vector2i size)
|
|
|
{
|
|
|
- if (activeTool == Tool.Rectangle)
|
|
|
- {
|
|
|
- if (SelectedStructureMember is null)
|
|
|
- return;
|
|
|
- startedDrawingRect = true;
|
|
|
- ActionAccumulator.AddAction(new DrawRectangle_Action(
|
|
|
- SelectedStructureMember.GuidValue,
|
|
|
- new ShapeData(
|
|
|
- new(mouseDownCanvasX, mouseDownCanvasY),
|
|
|
- new(canvasX - mouseDownCanvasX, canvasY - mouseDownCanvasY),
|
|
|
- 90,
|
|
|
- new SKColor(SelectedColor.R, SelectedColor.G, SelectedColor.B, SelectedColor.A),
|
|
|
- SKColors.Transparent)
|
|
|
- ));
|
|
|
- }
|
|
|
- else if (activeTool == Tool.Select)
|
|
|
- {
|
|
|
- if (!startedSelectingRect)
|
|
|
- ActionAccumulator.AddAction(new ClearSelection_Action());
|
|
|
- startedSelectingRect = true;
|
|
|
- ActionAccumulator.AddAction(new SelectRectangle_Action(
|
|
|
- new(mouseDownCanvasX, mouseDownCanvasY),
|
|
|
- new(canvasX - mouseDownCanvasX, canvasY - mouseDownCanvasY)
|
|
|
- ));
|
|
|
- }
|
|
|
+ if (!startedSelection)
|
|
|
+ Helpers.ActionAccumulator.AddAction(new ClearSelection_Action());
|
|
|
+ startedSelection = true;
|
|
|
+ Helpers.ActionAccumulator.AddAction(new SelectRectangle_Action(pos, size));
|
|
|
}
|
|
|
|
|
|
- public void MouseUp(object? param)
|
|
|
+ public void EndSelection()
|
|
|
{
|
|
|
- if (!mouseIsDown)
|
|
|
+ if (!startedSelection)
|
|
|
return;
|
|
|
- mouseIsDown = false;
|
|
|
- ProcessToolMouseUp();
|
|
|
+ startedSelection = false;
|
|
|
+ Helpers.ActionAccumulator.AddAction(new EndSelectRectangle_Action());
|
|
|
+ Helpers.ActionAccumulator.AddAction(new MergeLatestChanges_Action(2));
|
|
|
}
|
|
|
|
|
|
- private void ProcessToolMouseUp()
|
|
|
+ public void ForceRefreshView()
|
|
|
{
|
|
|
- if (startedDrawingRect)
|
|
|
- {
|
|
|
- startedDrawingRect = false;
|
|
|
- ActionAccumulator.AddAction(new EndDrawRectangle_Action());
|
|
|
- }
|
|
|
- if (startedSelectingRect)
|
|
|
- {
|
|
|
- startedSelectingRect = false;
|
|
|
- ActionAccumulator.AddAction(new EndSelectRectangle_Action());
|
|
|
- ActionAccumulator.AddAction(new MergeLatestChanges_Action(2));
|
|
|
- }
|
|
|
+ owner.View?.ForceRefreshFinalImage();
|
|
|
}
|
|
|
|
|
|
- public void ClearSelection(object? param)
|
|
|
+ private void ClearSelection(object? param)
|
|
|
{
|
|
|
- ActionAccumulator.AddAction(new ClearSelection_Action());
|
|
|
+ Helpers.ActionAccumulator.AddAction(new ClearSelection_Action());
|
|
|
}
|
|
|
|
|
|
- public void DeleteStructureMember(object? param)
|
|
|
+ private void DeleteStructureMember(object? param)
|
|
|
{
|
|
|
if (SelectedStructureMember is not null)
|
|
|
- ActionAccumulator.AddAction(new DeleteStructureMember_Action(SelectedStructureMember.GuidValue));
|
|
|
+ Helpers.ActionAccumulator.AddAction(new DeleteStructureMember_Action(SelectedStructureMember.GuidValue));
|
|
|
}
|
|
|
|
|
|
- public void Undo(object? param)
|
|
|
+ private void Undo(object? param)
|
|
|
{
|
|
|
- ActionAccumulator.AddAction(new Undo_Action());
|
|
|
+ Helpers.ActionAccumulator.AddAction(new Undo_Action());
|
|
|
}
|
|
|
|
|
|
- public void Redo(object? param)
|
|
|
+ private void Redo(object? param)
|
|
|
{
|
|
|
- ActionAccumulator.AddAction(new Redo_Action());
|
|
|
+ Helpers.ActionAccumulator.AddAction(new Redo_Action());
|
|
|
}
|
|
|
|
|
|
- public void ResizeCanvas(object? param)
|
|
|
+ private void ResizeCanvas(object? param)
|
|
|
{
|
|
|
- ActionAccumulator.AddAction(new ResizeCanvas_Action(new(ResizeWidth, ResizeHeight)));
|
|
|
+ Helpers.ActionAccumulator.AddAction(new ResizeCanvas_Action(new(ResizeWidth, ResizeHeight)));
|
|
|
}
|
|
|
|
|
|
private void ChangeSelectedItem(object? param)
|
|
@@ -268,22 +218,30 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
if (selected.Count < 2)
|
|
|
return;
|
|
|
|
|
|
- var (child, parent) = StructureHelper.FindChildAndParentOrThrow(selected[0]);
|
|
|
+ var (child, parent) = Helpers.StructureHelper.FindChildAndParentOrThrow(selected[0]);
|
|
|
int index = parent.Children.IndexOf(child);
|
|
|
Guid newGuid = Guid.NewGuid();
|
|
|
|
|
|
//make a new layer, put combined image onto it, delete layers that were merged
|
|
|
- ActionAccumulator.AddAction(new CreateStructureMember_Action(parent.GuidValue, newGuid, index, StructureMemberType.Layer));
|
|
|
- ActionAccumulator.AddAction(new SetStructureMemberName_Action(child.Name + "-comb", newGuid));
|
|
|
- ActionAccumulator.AddAction(new CombineStructureMembersOnto_Action(newGuid, selected.ToHashSet()));
|
|
|
+ Helpers.ActionAccumulator.AddAction(new CreateStructureMember_Action(parent.GuidValue, newGuid, index, StructureMemberType.Layer));
|
|
|
+ Helpers.ActionAccumulator.AddAction(new SetStructureMemberName_Action(child.Name + "-comb", newGuid));
|
|
|
+ Helpers.ActionAccumulator.AddAction(new CombineStructureMembersOnto_Action(newGuid, selected.ToHashSet()));
|
|
|
foreach (var member in selected)
|
|
|
- ActionAccumulator.AddAction(new DeleteStructureMember_Action(member));
|
|
|
- ActionAccumulator.AddAction(new MergeLatestChanges_Action(3 + selected.Count));
|
|
|
+ Helpers.ActionAccumulator.AddAction(new DeleteStructureMember_Action(member));
|
|
|
+ Helpers.ActionAccumulator.AddAction(new MergeLatestChanges_Action(3 + selected.Count));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void MoveViewport(object? param)
|
|
|
+ {
|
|
|
+ if (param is null)
|
|
|
+ throw new ArgumentNullException(nameof(param));
|
|
|
+ var args = (ViewportRoutedEventArgs)param;
|
|
|
+ Helpers.ActionAccumulator.AddAction(new MoveViewport_PassthroughAction(args.Center, args.Size / 2, args.Angle, args.RealSize / 2));
|
|
|
}
|
|
|
|
|
|
private void ClearHistory(object? param)
|
|
|
{
|
|
|
- ActionAccumulator.AddAction(new DeleteRecordedChanges_Action());
|
|
|
+ Helpers.ActionAccumulator.AddAction(new DeleteRecordedChanges_Action());
|
|
|
}
|
|
|
|
|
|
private void AddSelectedMembers(FolderViewModel folder, List<Guid> collection)
|
|
@@ -296,12 +254,5 @@ namespace PixiEditorPrototype.ViewModels
|
|
|
AddSelectedMembers(innerFolder, collection);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private void ChangeActiveTool(object? param)
|
|
|
- {
|
|
|
- if (param is null)
|
|
|
- return;
|
|
|
- activeTool = (Tool)param;
|
|
|
- }
|
|
|
}
|
|
|
}
|