123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- using System.Collections.Generic;
- using Avalonia.Input;
- using ChunkyImageLib.DataHolders;
- using PixiEditor.AvaloniaUI.Models.DocumentModels.UpdateableChangeExecutors;
- using PixiEditor.AvaloniaUI.Models.Handlers;
- using PixiEditor.AvaloniaUI.Models.Position;
- using PixiEditor.AvaloniaUI.Models.Tools;
- using PixiEditor.AvaloniaUI.Views.Overlays.SymmetryOverlay;
- using PixiEditor.ChangeableDocument.Enums;
- using PixiEditor.DrawingApi.Core.Numerics;
- namespace PixiEditor.AvaloniaUI.Models.DocumentModels;
- #nullable enable
- internal class ChangeExecutionController
- {
- public bool LeftMousePressed { get; private set; }
- public ShapeCorners LastTransformState { get; private set; }
- public VecI LastPixelPosition => lastPixelPos;
- public VecD LastPrecisePosition => lastPrecisePos;
- public bool IsChangeActive => currentSession is not null;
- private readonly IDocument document;
- private readonly IServiceProvider services;
- private readonly DocumentInternalParts internals;
- private VecI lastPixelPos;
- private VecD lastPrecisePos;
- private UpdateableChangeExecutor? currentSession = null;
-
- private UpdateableChangeExecutor? _queuedExecutor = null;
- public ChangeExecutionController(IDocument document, DocumentInternalParts internals, IServiceProvider services)
- {
- this.document = document;
- this.internals = internals;
- this.services = services;
- }
- public ExecutorType GetCurrentExecutorType()
- {
- if (currentSession is null)
- return ExecutorType.None;
- return currentSession.Type;
- }
- public bool TryStartExecutor<T>(bool force = false)
- where T : UpdateableChangeExecutor, new()
- {
- if (CanStartExecutor(force))
- return false;
- if (force)
- currentSession?.ForceStop();
-
- T executor = new T();
- return TryStartExecutorInternal(executor);
- }
- public bool TryStartExecutor(UpdateableChangeExecutor brandNewExecutor, bool force = false)
- {
- if (CanStartExecutor(force))
- return false;
- if (force)
- currentSession?.ForceStop();
-
- return TryStartExecutorInternal(brandNewExecutor);
- }
- private bool CanStartExecutor(bool force)
- {
- return (currentSession is not null || _queuedExecutor is not null) && !force;
- }
- private bool TryStartExecutorInternal(UpdateableChangeExecutor executor)
- {
- executor.Initialize(document, internals, services, this, EndExecutor);
- if (executor.StartMode == ExecutorStartMode.OnMouseLeftButtonDown)
- {
- _queuedExecutor = executor;
- return true;
- }
- return StartExecutor(executor);
- }
-
- private bool StartExecutor(UpdateableChangeExecutor brandNewExecutor)
- {
- if (brandNewExecutor.Start() == ExecutionState.Success)
- {
- currentSession = brandNewExecutor;
- return true;
- }
- return false;
- }
- private void EndExecutor(UpdateableChangeExecutor executor)
- {
- if (executor != currentSession)
- throw new InvalidOperationException();
- currentSession = null;
- _queuedExecutor = null;
- }
- public bool TryStopActiveExecutor()
- {
- if (currentSession is null)
- return false;
- currentSession.ForceStop();
- currentSession = null;
- return true;
- }
- public void MidChangeUndoInlet() => currentSession?.OnMidChangeUndo();
- public void MidChangeRedoInlet() => currentSession?.OnMidChangeRedo();
- public void ConvertedKeyDownInlet(Key key)
- {
- currentSession?.OnConvertedKeyDown(key);
- }
- public void ConvertedKeyUpInlet(Key key)
- {
- currentSession?.OnConvertedKeyUp(key);
- }
- public void MouseMoveInlet(VecD newCanvasPos)
- {
- //update internal state
- VecI newPixelPos = (VecI)newCanvasPos.Floor();
- bool pixelPosChanged = false;
- if (lastPixelPos != newPixelPos)
- {
- lastPixelPos = newPixelPos;
- pixelPosChanged = true;
- }
- lastPrecisePos = newCanvasPos;
- //call session events
- if (currentSession is not null)
- {
- if (pixelPosChanged)
- currentSession.OnPixelPositionChange(newPixelPos);
- currentSession.OnPrecisePositionChange(newCanvasPos);
- }
- }
- public void OpacitySliderDragStartedInlet() => currentSession?.OnOpacitySliderDragStarted();
- public void OpacitySliderDraggedInlet(float newValue)
- {
- currentSession?.OnOpacitySliderDragged(newValue);
- }
- public void OpacitySliderDragEndedInlet() => currentSession?.OnOpacitySliderDragEnded();
- public void SymmetryDragStartedInlet(SymmetryAxisDirection dir) => currentSession?.OnSymmetryDragStarted(dir);
- public void SymmetryDraggedInlet(SymmetryAxisDragInfo info)
- {
- currentSession?.OnSymmetryDragged(info);
- }
- public void SymmetryDragEndedInlet(SymmetryAxisDirection dir) => currentSession?.OnSymmetryDragEnded(dir);
- public void LeftMouseButtonDownInlet(VecD canvasPos)
- {
- //update internal state
- LeftMousePressed = true;
- if (_queuedExecutor != null && currentSession == null)
- {
- StartExecutor(_queuedExecutor);
- }
-
- //call session event
- currentSession?.OnLeftMouseButtonDown(canvasPos);
- }
- public void LeftMouseButtonUpInlet()
- {
- //update internal state
- LeftMousePressed = false;
- //call session events
- currentSession?.OnLeftMouseButtonUp();
- }
- public void TransformMovedInlet(ShapeCorners corners)
- {
- LastTransformState = corners;
- currentSession?.OnTransformMoved(corners);
- }
- public void TransformAppliedInlet() => currentSession?.OnTransformApplied();
- public void LineOverlayMovedInlet(VecD start, VecD end)
- {
- currentSession?.OnLineOverlayMoved(start, end);
- }
- public void SelectedObjectNudgedInlet(VecI distance)
- {
- currentSession?.OnSelectedObjectNudged(distance);
- }
- }
|