diff --git a/ViewModels/MainWindowViewModel.cs b/ViewModels/MainWindowViewModel.cs index 768299f..c48b609 100644 --- a/ViewModels/MainWindowViewModel.cs +++ b/ViewModels/MainWindowViewModel.cs @@ -75,6 +75,7 @@ public class MainWindowViewModel : ViewModelBase private void ChangeSelectedColor(SolidColorBrush color) { Brush = color; + SelectedColor = color.Color.ToString(); } private void OnCanvasPointerPressed(PointerPressedEventArgs? e) diff --git a/ViewModels/ViewModelBase.cs b/ViewModels/ViewModelBase.cs index ba4d0e7..4d8a28a 100644 --- a/ViewModels/ViewModelBase.cs +++ b/ViewModels/ViewModelBase.cs @@ -1,11 +1,19 @@ using System; using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Threading.Tasks; +using Avalonia; +using Avalonia.Controls; using Avalonia.Input; using Avalonia.Media; +using Avalonia.Media.Imaging; +using Avalonia.Platform; +using Avalonia.Platform.Storage; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using SimpleDraw.Models; +using SimpleDraw.Views; namespace SimpleDraw.ViewModels; @@ -13,8 +21,7 @@ public class ViewModelBase : ObservableObject { public int WindowWidth { get; set; } = 1200; public int WindowHeight { get; set; } = 800; - - public ObservableCollection? ColorPalette { get; set; } + public ObservableCollection? ColorPalette { get; set; } public IRelayCommand? CanvasPointerPressedCommand { get; set; } public IRelayCommand? CanvasPointerMovedCommand { get; set; } public IRelayCommand? CanvasPointerReleasedCommand { get; set; } @@ -22,7 +29,15 @@ public class ViewModelBase : ObservableObject public DrawingPoints? DrawingPoint { get; set; } protected bool IsDrawing { get; set; } - + + private string _selectedColor = "Black"; + + public string SelectedColor + { + get => _selectedColor; + set => SetProperty(ref _selectedColor, value); + } + private Brush _brush = new SolidColorBrush(new Color(a: 255, r: 0, g: 0, b: 0)); private double _brushThickness = 2.0; @@ -31,7 +46,7 @@ public class ViewModelBase : ObservableObject get => _brush; set => SetProperty(ref _brush, value); } - + public double BrushThickness { get => _brushThickness; diff --git a/Views/MainWindow.axaml b/Views/MainWindow.axaml index 38f02db..e8bc4e3 100644 --- a/Views/MainWindow.axaml +++ b/Views/MainWindow.axaml @@ -33,9 +33,9 @@ - + - + @@ -56,6 +56,7 @@ + @@ -91,7 +92,7 @@ - + - + diff --git a/Views/MainWindow.axaml.cs b/Views/MainWindow.axaml.cs index 507503d..9e2d7b0 100644 --- a/Views/MainWindow.axaml.cs +++ b/Views/MainWindow.axaml.cs @@ -1,5 +1,12 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Avalonia; using Avalonia.Controls; using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Media.Imaging; +using Avalonia.Platform.Storage; using SimpleDraw.ViewModels; namespace SimpleDraw.Views; @@ -13,4 +20,39 @@ public partial class MainWindow : Window Topmost = true; Topmost = false; } + + private async void SaveFileButton_Clicked(object sender, RoutedEventArgs args) + { + TopLevel? topLevel = TopLevel.GetTopLevel(this); + if(topLevel == null) return; + + var file = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions + { + Title = "Save Drawing", + DefaultExtension = ".png", + SuggestedFileName = "unnamed", + SuggestedStartLocation = await topLevel.StorageProvider.TryGetFolderFromPathAsync(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)), + }); + + if (file is not null) + { + SaveCanvasAsPngAsync(Canvas, file.Path.AbsolutePath); + } + } + + public async Task SaveCanvasAsPngAsync(Canvas canvas, string filePath) + { + Rect bounds = canvas.Bounds; + PixelSize pixelSize = new PixelSize((int)bounds.Width, (int)bounds.Height); + Vector dpi = new Vector(96, 96); + + RenderTargetBitmap renderBitmap = new RenderTargetBitmap(pixelSize, dpi); + + renderBitmap.Render(canvas); + + await using (FileStream stream = File.OpenWrite(filePath)) + { + renderBitmap.Save(stream); + } + } } \ No newline at end of file