123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- using PixiEditor.Helpers;
- using PixiEditor.Models.Enums;
- using PixiEditor.Models.Tools;
- using System;
- using System.Collections.Generic;
- using System.Windows;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using PixiTools = PixiEditor.Models.Tools.Tools;
- using PixiEditor.Models.Controllers;
- using PixiEditor.Models.Dialogs;
- using PixiEditor.Models.IO;
- using PixiEditor.Models.Position;
- using PixiEditor.Models.DataHolders;
- using System.Linq;
- using System.Collections.ObjectModel;
- namespace PixiEditor.ViewModels
- {
- class ViewModelMain : ViewModelBase
- {
- public RelayCommand SelectToolCommand { get; set; } //Command that handles tool switching
- public RelayCommand GenerateDrawAreaCommand { get; set; } //Command that generates draw area
- public RelayCommand MouseMoveCommand { get; set; } //Command that is used to draw
- public RelayCommand MouseDownCommand { get; set; }
- public RelayCommand KeyDownCommand { get; set; }
- public RelayCommand SaveFileCommand { get; set; } //Command that is used to save file
- public RelayCommand UndoCommand { get; set; }
- public RelayCommand RedoCommand { get; set; }
- public RelayCommand MouseUpCommand { get; set; }
- public RelayCommand RecenterZoomboxCommand { get; set; }
- public RelayCommand OpenFileCommand { get; set; }
- public RelayCommand SetActiveLayerCommand { get; set; }
- public RelayCommand NewLayerCommand { get; set; }
- public RelayCommand ReloadImageCommand { get; set; }
- public RelayCommand DeleteLayerCommand { get; set; }
- public RelayCommand RenameLayerCommand { get; set; }
- public RelayCommand MoveToBackCommand { get; set; }
- public RelayCommand MoveToFrontCommand { get; set; }
- public RelayCommand SwapColorsCommand { get; set; }
- private double _mouseXonCanvas;
- public double MouseXOnCanvas //Mouse X coordinate relative to canvas
- {
- get => _mouseXonCanvas;
- set { _mouseXonCanvas = value; RaisePropertyChanged("MouseXonCanvas"); }
- }
- private double _mouseYonCanvas;
- public double MouseYOnCanvas //Mouse Y coordinate relative to canvas
- {
- get => _mouseYonCanvas;
- set { _mouseYonCanvas = value; RaisePropertyChanged("MouseYonCanvas"); }
- }
- private Color _primaryColor = Colors.White;
- public Color PrimaryColor //Primary color, hooked with left mouse button
- {
- get => _primaryColor;
- set
- {
- if (_primaryColor != value)
- {
- _primaryColor = value;
- BitmapUtility.PrimaryColor = value;
- RaisePropertyChanged("PrimaryColor");
- }
- }
- }
- private Color _secondaryColor = Colors.Black;
- public Color SecondaryColor //Secondary color, hooked with right mouse button
- {
- get => _secondaryColor;
- set { if (_secondaryColor != value) { _secondaryColor = value; RaisePropertyChanged("SecondaryColor"); } }
- }
- private ToolType _selectedTool;
- public ToolType SelectedTool
- {
- get { return _selectedTool; }
- set
- {
- if (_selectedTool != value)
- {
- _selectedTool = value;
- SetActiveTool(value);
- RaisePropertyChanged("SelectedTool"); } }
- }
- public ObservableCollection<Tool> ToolSet { get; set; }
- private LayerChanges _undoChanges;
- public LayerChanges UndoChanges
- {
- get { return _undoChanges; }
- set
- {
- _undoChanges = value;
- BitmapUtility.Layers[value.LayerIndex].ApplyPixels(value.PixelChanges);
- }
- }
- private Cursor _toolCursor;
- public Cursor ToolCursor
- {
- get { return _toolCursor; }
- set {
- _toolCursor = value;
- RaisePropertyChanged("ToolCursor");
- }
- }
- public BitmapOperationsUtility BitmapUtility { get; set; }
- public PixelChangesController ChangesController { get; set; }
- public ShortcutController ShortcutController { get; set; }
- public ViewModelMain()
- {
- PixiFilesManager.InitializeTempDirectories();
- BitmapUtility = new BitmapOperationsUtility();
- BitmapUtility.BitmapChanged += BitmapUtility_BitmapChanged;
- BitmapUtility.MouseController.StoppedRecordingChanges += MouseController_StoppedRecordingChanges;
- ChangesController = new PixelChangesController();
- SelectToolCommand = new RelayCommand(SetTool);
- GenerateDrawAreaCommand = new RelayCommand(GenerateDrawArea);
- MouseMoveCommand = new RelayCommand(MouseMove);
- MouseDownCommand = new RelayCommand(MouseDown);
- SaveFileCommand = new RelayCommand(SaveFile, CanSave);
- UndoCommand = new RelayCommand(Undo, CanUndo);
- RedoCommand = new RelayCommand(Redo, CanRedo);
- MouseUpCommand = new RelayCommand(MouseUp);
- RecenterZoomboxCommand = new RelayCommand(RecenterZoombox);
- OpenFileCommand = new RelayCommand(OpenFile);
- SetActiveLayerCommand = new RelayCommand(SetActiveLayer);
- NewLayerCommand = new RelayCommand(NewLayer, CanCreateNewLayer);
- DeleteLayerCommand = new RelayCommand(DeleteLayer, CanDeleteLayer);
- MoveToBackCommand = new RelayCommand(MoveLayerToBack, CanMoveToBack);
- MoveToFrontCommand = new RelayCommand(MoveLayerToFront, CanMoveToFront);
- SwapColorsCommand = new RelayCommand(SwapColors);
- KeyDownCommand = new RelayCommand(KeyDown);
- RenameLayerCommand = new RelayCommand(RenameLayer);
- ToolSet = new ObservableCollection<Tool> { new PixiTools.PenTool(), new PixiTools.FloodFill(), new PixiTools.LineTool(),
- new PixiTools.CircleTool(), new PixiTools.RectangleTool(), new PixiTools.EarserTool(), new PixiTools.ColorPickerTool(), new PixiTools.BrightnessTool() };
- ShortcutController = new ShortcutController
- {
- Shortcuts = new List<Shortcut> {
- new Shortcut(Key.B, SelectToolCommand, ToolType.Pen),
- new Shortcut(Key.X, SwapColorsCommand),
- new Shortcut(Key.O, OpenFileCommand, null, ModifierKeys.Control),
- new Shortcut(Key.E, SelectToolCommand, ToolType.Earser),
- new Shortcut(Key.O, SelectToolCommand, ToolType.ColorPicker),
- new Shortcut(Key.R, SelectToolCommand, ToolType.Rectangle),
- new Shortcut(Key.C, SelectToolCommand, ToolType.Circle),
- new Shortcut(Key.L, SelectToolCommand, ToolType.Line),
- new Shortcut(Key.G, SelectToolCommand, ToolType.Bucket),
- new Shortcut(Key.U, SelectToolCommand, ToolType.Brightness),
- new Shortcut(Key.Y, RedoCommand, null, ModifierKeys.Control),
- new Shortcut(Key.Z, UndoCommand),
- new Shortcut(Key.S, SaveFileCommand, null, ModifierKeys.Control),
- new Shortcut(Key.N, GenerateDrawAreaCommand, null, ModifierKeys.Control),
- }
- };
- UndoManager.SetMainRoot(this);
- SetActiveTool(ToolType.Pen);
- BitmapUtility.PrimaryColor = PrimaryColor;
- }
- public void SetTool(object parameter)
- {
- SetActiveTool((ToolType)parameter);
- }
- public void RenameLayer(object parameter)
- {
- BitmapUtility.Layers[(int)parameter].IsRenaming = true;
- }
- public void KeyDown(object parameter)
- {
- ShortcutController.KeyPressed(((KeyEventArgs)parameter).Key);
- }
- private void MouseController_StoppedRecordingChanges(object sender, EventArgs e)
- {
- if (BitmapUtility.SelectedTool.PerformsOperationOnBitmap)
- {
- Tuple<LayerChanges, LayerChanges> changes = ChangesController.PopChanges();
- if (changes.Item1.PixelChanges.ChangedPixels.Count > 0)
- UndoManager.AddUndoChange(new Change("UndoChanges", changes.Item2, changes.Item1)); //Item2 is old value
- }
- }
- private void BitmapUtility_BitmapChanged(object sender, BitmapChangedEventArgs e)
- {
- ChangesController.AddChanges(new LayerChanges(e.PixelsChanged, e.ChangedLayerIndex),
- new LayerChanges(e.OldPixelsValues, e.ChangedLayerIndex));
- }
- public void SwapColors(object parameter)
- {
- var tmp = PrimaryColor;
- PrimaryColor = SecondaryColor;
- SecondaryColor = tmp;
- }
- public void MoveLayerToFront(object parameter)
- {
- int oldIndex = (int)parameter;
- BitmapUtility.Layers.Move(oldIndex, oldIndex + 1);
- if(BitmapUtility.ActiveLayerIndex == oldIndex)
- {
- BitmapUtility.SetActiveLayer(oldIndex + 1);
- }
- }
- public void MoveLayerToBack(object parameter)
- {
- int oldIndex = (int)parameter;
- BitmapUtility.Layers.Move(oldIndex, oldIndex - 1);
- if (BitmapUtility.ActiveLayerIndex == oldIndex)
- {
- BitmapUtility.SetActiveLayer(oldIndex - 1);
- }
- }
- public bool CanMoveToFront(object property)
- {
- return BitmapUtility.Layers.Count - 1 > (int)property;
- }
- public bool CanMoveToBack(object property)
- {
- return (int)property > 0;
- }
- public void SetActiveLayer(object parameter)
- {
- BitmapUtility.SetActiveLayer((int)parameter);
- }
- public void DeleteLayer(object parameter)
- {
- BitmapUtility.RemoveLayer((int)parameter);
- }
- public bool CanDeleteLayer(object property)
- {
- return BitmapUtility.Layers.Count > 1;
- }
- #region Undo/Redo
- /// <summary>
- /// Undo last action
- /// </summary>
- /// <param name="parameter"></param>
- public void Undo(object parameter)
- {
- UndoManager.Undo();
- }
- /// <summary>
- /// Returns true if undo can be done.
- /// </summary>
- /// <param name="property"></param>
- /// <returns></returns>
- private bool CanUndo(object property)
- {
- return UndoManager.CanUndo;
- }
- /// <summary>
- /// Redo last action
- /// </summary>
- /// <param name="parameter"></param>
- public void Redo(object parameter)
- {
- UndoManager.Redo();
- }
- /// <summary>
- /// Returns true if redo can be done.
- /// </summary>
- /// <param name="property"></param>
- /// <returns></returns>
- private bool CanRedo(object property)
- {
- return UndoManager.CanRedo;
- }
- #endregion
- private void SetActiveTool(ToolType tool)
- {
- BitmapUtility.SetActiveTool(ToolSet.First(x=> x.ToolType == tool));
- Tool activeTool = ToolSet.FirstOrDefault(x => x.IsActive);
- if(activeTool != null)
- {
- activeTool.IsActive = false;
- }
- BitmapUtility.SelectedTool.IsActive = true;
- SetToolCursor(tool);
- }
- private void SetToolCursor(ToolType tool)
- {
- if (tool != ToolType.None && tool != ToolType.ColorPicker)
- {
- ToolCursor = BitmapUtility.SelectedTool.Cursor;
- }
- else
- {
- ToolCursor = Cursors.Arrow;
- }
- }
- /// <summary>
- /// When mouse is up stops recording changes.
- /// </summary>
- /// <param name="parameter"></param>
- private void MouseUp(object parameter)
- {
- BitmapUtility.MouseController.StopRecordingMouseMovementChanges();
- }
- private void MouseDown(object parameter)
- {
- if (BitmapUtility.Layers.Count == 0) return;
- if(BitmapUtility.SelectedTool.ToolType == ToolType.ColorPicker)
- {
- ExecuteColorPicker();
- }
- else if(Mouse.LeftButton == MouseButtonState.Pressed && BitmapUtility.SelectedTool.PerformsOperationOnBitmap)
- {
- if (!BitmapUtility.MouseController.IsRecordingChanges)
- {
- BitmapUtility.MouseController.StartRecordingMouseMovementChanges();
- BitmapUtility.MouseController.RecordMouseMovementChange(MousePositionConverter.CurrentCoordinates);
- }
- }
- }
- /// <summary>
- /// Method connected with command, it executes tool "activity"
- /// </summary>
- /// <param name="parameter"></param>
- private void MouseMove(object parameter)
- {
- Coordinates cords = new Coordinates((int)MouseXOnCanvas, (int)MouseYOnCanvas);
- MousePositionConverter.CurrentCoordinates = cords;
- if (BitmapUtility.MouseController.IsRecordingChanges && Mouse.LeftButton == MouseButtonState.Pressed)
- {
- BitmapUtility.MouseController.RecordMouseMovementChange(cords);
- }
- else
- {
- BitmapUtility.MouseController.MouseMoved(cords);
- }
- }
- private void ExecuteColorPicker()
- {
- if (Mouse.LeftButton == MouseButtonState.Pressed)
- {
- using (var bitmap = new System.Drawing.Bitmap(1, 1))
- {
- using (var graphics = System.Drawing.Graphics.FromImage(bitmap))
- {
- graphics.CopyFromScreen(MousePositionConverter.GetCursorPosition(), new System.Drawing.Point(0, 0), new System.Drawing.Size(1, 1));
- }
- var color = bitmap.GetPixel(0, 0);
- PrimaryColor = Color.FromArgb(color.A, color.R, color.G, color.B);
- }
- }
- }
- /// <summary>
- /// Generates new Layer and sets it as active one
- /// </summary>
- /// <param name="parameter"></param>
- public void GenerateDrawArea(object parameter)
- {
- NewFileDialog newFile = new NewFileDialog();
- if (newFile.ShowDialog())
- {
- NewDocument(newFile.Width, newFile.Height);
- }
- }
- #region SaveFile
- /// <summary>
- /// Generates export dialog or saves directly if save data is known.
- /// </summary>
- /// <param name="parameter"></param>
- private void SaveFile(object parameter)
- {
- WriteableBitmap bitmap = BitmapUtility.GetCombinedLayersBitmap();
- if (Exporter.SavePath == null || (string)parameter == "AsNew")
- {
- Exporter.Export(FileType.PNG, bitmap, new Size(bitmap.PixelWidth, bitmap.PixelHeight));
- }
- else
- {
- Exporter.ExportWithoutDialog(FileType.PNG, bitmap);
- }
- }
- /// <summary>
- /// Returns true if file save is possible.
- /// </summary>
- /// <param name="property"></param>
- /// <returns></returns>
- private bool CanSave(object property)
- {
- return BitmapUtility.ActiveLayer != null;
- }
- #endregion
- /// <summary>
- /// Opens file from path.
- /// </summary>
- /// <param name="parameter"></param>
- public void OpenFile(object parameter)
- {
- ImportFileDialog dialog = new ImportFileDialog();
- if (dialog.ShowDialog())
- {
- NewDocument(dialog.FileWidth, dialog.FileHeight);
- BitmapUtility.ActiveLayer.LayerBitmap = Importer.ImportImage(dialog.FilePath, dialog.FileWidth, dialog.FileHeight);
- }
- }
- private void NewDocument(int width, int height)
- {
- BitmapUtility.Layers.Clear();
- BitmapUtility.AddNewLayer("Base Layer", width, height, true);
- BitmapUtility.PreviewLayer = null;
- }
- /// <summary>
- /// For now, shows not implemented info, lol.
- /// </summary>
- /// <param name="parameter"></param>
- public void RecenterZoombox(object parameter)
- {
- MessageBox.Show("This feature is not implemented yet.", "Feature not implemented", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- public void NewLayer(object parameter)
- {
- BitmapUtility.AddNewLayer($"New Layer {BitmapUtility.Layers.Count}", BitmapUtility.Layers[0].Width, BitmapUtility.Layers[0].Height);
- }
- public bool CanCreateNewLayer(object parameter)
- {
- return BitmapUtility.Layers.Count > 0;
- }
- }
- }
|