Browse Source

Merge pull request #157 from Bebo-Maker/previewer

Previewer - ViewModel for PreviewerWindow
Marcin Ziąbek 3 years ago
parent
commit
d2601e9e5a

+ 6 - 1
QuestPDF.Previewer/DocumentPreviewerExtensions.cs

@@ -1,5 +1,6 @@
 using Avalonia;
 using Avalonia;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.ReactiveUI;
 using QuestPDF.Infrastructure;
 using QuestPDF.Infrastructure;
 
 
 namespace QuestPDF.Previewer
 namespace QuestPDF.Previewer
@@ -24,7 +25,10 @@ namespace QuestPDF.Previewer
             {
             {
                 desktop.MainWindow = new PreviewerWindow()
                 desktop.MainWindow = new PreviewerWindow()
                 {
                 {
-                    Document = document,
+                    DataContext = new PreviewerWindowViewModel()
+                    {
+                        Document = document,
+                    }
                 };
                 };
                 
                 
                 desktop.MainWindow.Show();
                 desktop.MainWindow.Show();
@@ -39,6 +43,7 @@ namespace QuestPDF.Previewer
                     Document = document,
                     Document = document,
                 })
                 })
                 .UsePlatformDetect()
                 .UsePlatformDetect()
+                .UseReactiveUI()
                 .StartWithClassicDesktopLifetime(Array.Empty<string>());
                 .StartWithClassicDesktopLifetime(Array.Empty<string>());
         }
         }
     }
     }

+ 4 - 1
QuestPDF.Previewer/PreviewerApp.axaml.cs

@@ -20,7 +20,10 @@ namespace QuestPDF.Previewer
             {
             {
                 desktop.MainWindow = new PreviewerWindow()
                 desktop.MainWindow = new PreviewerWindow()
                 {
                 {
-                    Document = Document
+                    DataContext = new PreviewerWindowViewModel()
+                    {
+                        Document = Document,
+                    }
                 };
                 };
             }
             }
             
             

+ 7 - 9
QuestPDF.Previewer/PreviewerWindow.axaml

@@ -11,9 +11,7 @@
 							Background="#666"
 							Background="#666"
 							Icon="/Images/Logo.png"
 							Icon="/Images/Logo.png"
 							UseLayoutRounding="True"
 							UseLayoutRounding="True"
-							x:Name="Window"
 							Title="QuestPDF Document Preview">
 							Title="QuestPDF Document Preview">
-	
 	<Panel>
 	<Panel>
 		<Grid>
 		<Grid>
 			<Grid.RowDefinitions>
 			<Grid.RowDefinitions>
@@ -33,14 +31,14 @@
 			<previewer:PreviewerControl Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
 			<previewer:PreviewerControl Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
 			                            HorizontalAlignment="Stretch" 
 			                            HorizontalAlignment="Stretch" 
 			                            VerticalAlignment="Stretch"
 			                            VerticalAlignment="Stretch"
-			                            CurrentScroll="{Binding #Window.CurrentScroll, Mode=TwoWay}"
-			                            ScrollViewportSize="{Binding #Window.ScrollViewportSize, Mode=OneWayToSource}"
-			                            Pages="{Binding #Window.DocumentRenderer.Pages, Mode=OneWay}" />
+			                            CurrentScroll="{Binding CurrentScroll, Mode=TwoWay}"
+			                            ScrollViewportSize="{Binding ScrollViewportSize, Mode=OneWayToSource}"
+			                            Pages="{Binding DocumentRenderer.Pages, Mode=OneWay}" />
 			
 			
 			<Button Grid.Row="1" Grid.Column="0" 
 			<Button Grid.Row="1" Grid.Column="0" 
 			        VerticalAlignment="Bottom" HorizontalAlignment="Left" 
 			        VerticalAlignment="Bottom" HorizontalAlignment="Left" 
 			        Margin="32" Padding="10" CornerRadius="100" 
 			        Margin="32" Padding="10" CornerRadius="100" 
-			        Click="ShowPDF" 
+			        Command="{Binding ShowPdfCommand, Mode=OneTime}"
 			        ToolTip.Tip="Generates PDF file and shows it in the default browser. Useful for testing compatibility and interactive links.">
 			        ToolTip.Tip="Generates PDF file and shows it in the default browser. Useful for testing compatibility and interactive links.">
 				<Viewbox Width="24" Height="24">
 				<Viewbox Width="24" Height="24">
 					<Canvas Width="24" Height="24">
 					<Canvas Width="24" Height="24">
@@ -53,9 +51,9 @@
 			           Orientation="Vertical" 
 			           Orientation="Vertical" 
 			           AllowAutoHide="False" 
 			           AllowAutoHide="False" 
 			           Minimum="0" Maximum="1" 
 			           Minimum="0" Maximum="1" 
-			           IsVisible="{Binding #Window.VerticalScrollbarVisible, Mode=OneWay}"
-			           Value="{Binding #Window.CurrentScroll, Mode=TwoWay}" 
-			           ViewportSize="{Binding #Window.ScrollViewportSize, Mode=OneWay}"></ScrollBar>
+			           IsVisible="{Binding VerticalScrollbarVisible, Mode=OneWay}"
+			           Value="{Binding CurrentScroll, Mode=TwoWay}" 
+			           ViewportSize="{Binding ScrollViewportSize, Mode=OneWay}"></ScrollBar>
 		</Grid>
 		</Grid>
 	</Panel>
 	</Panel>
 </Window>
 </Window>

+ 2 - 91
QuestPDF.Previewer/PreviewerWindow.axaml.cs

@@ -1,112 +1,23 @@
-using System.Diagnostics;
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.Interactivity;
+using Avalonia.Controls;
 using Avalonia.Markup.Xaml;
 using Avalonia.Markup.Xaml;
-using Avalonia.Threading;
-using QuestPDF.Fluent;
-using QuestPDF.Helpers;
-using QuestPDF.Infrastructure;
-using ReactiveUI;
 
 
 namespace QuestPDF.Previewer
 namespace QuestPDF.Previewer
 {
 {
     class PreviewerWindow : Window
     class PreviewerWindow : Window
     {
     {
-        public DocumentRenderer DocumentRenderer { get; } = new();
-
-        public static readonly StyledProperty<IDocument?> DocumentProperty =
-            AvaloniaProperty.Register<PreviewerWindow, IDocument?>(nameof(Document));
-
-        public IDocument? Document
-        {
-            get => GetValue(DocumentProperty);
-            set => SetValue(DocumentProperty, value);
-        }
-
-        public static readonly StyledProperty<float> CurrentScrollProperty = AvaloniaProperty.Register<PreviewerWindow, float>(nameof(CurrentScroll));
-
-        public float CurrentScroll
-        {
-            get => GetValue(CurrentScrollProperty);
-            set => SetValue(CurrentScrollProperty, value);
-        }
-
-        public static readonly StyledProperty<float> ScrollViewportSizeProperty = AvaloniaProperty.Register<PreviewerWindow, float>(nameof(ScrollViewportSize));
-
-        public float ScrollViewportSize
-        {
-            get => GetValue(ScrollViewportSizeProperty);
-            set => SetValue(ScrollViewportSizeProperty, value);
-        }
-
-        public static readonly StyledProperty<bool> VerticalScrollbarVisibleProperty = AvaloniaProperty.Register<PreviewerWindow, bool>(nameof(VerticalScrollbarVisible));
-
-        public bool VerticalScrollbarVisible
-        {
-            get => GetValue(VerticalScrollbarVisibleProperty);
-            set => SetValue(VerticalScrollbarVisibleProperty, value);
-        }
-
         public PreviewerWindow()
         public PreviewerWindow()
         {
         {
             InitializeComponent();
             InitializeComponent();
-
-            ScrollViewportSizeProperty.Changed
-                .Subscribe(e => Dispatcher.UIThread.Post(() =>
-                {
-                    VerticalScrollbarVisible = e.NewValue.Value < 1;
-                }));
-  
-            DocumentProperty.Changed.Subscribe(v => Task.Run(() => DocumentRenderer.UpdateDocument(v.NewValue.Value)));
-            HotReloadManager.UpdateApplicationRequested += InvalidatePreview;
         }
         }
 
 
         protected override void OnClosed(EventArgs e)
         protected override void OnClosed(EventArgs e)
         {
         {
-            HotReloadManager.UpdateApplicationRequested -= InvalidatePreview;
-            base.OnClosed(e);
-        }
-
-        private void InvalidatePreview(object? sender, EventArgs e) => InvalidatePreview();
-        private void InvalidatePreview()
-        {
-            Dispatcher.UIThread.Post(() =>
-            {
-                var document = Document;
-                _ = Task.Run(() => DocumentRenderer.UpdateDocument(document));
-            });
+            (DataContext as PreviewerWindowViewModel)?.UnregisterHotReloadHandler();
         }
         }
 
 
         private void InitializeComponent()
         private void InitializeComponent()
         {
         {
             AvaloniaXamlLoader.Load(this);
             AvaloniaXamlLoader.Load(this);
         }
         }
-
-        private void ShowPDF(object? sender, RoutedEventArgs e)
-        {
-            var path = Path.GetTempPath() + ".pdf";
-            
-            try
-            {
-                DocumentRenderer.Document?.GeneratePdf(path);
-            }
-            catch (Exception exception)
-            {
-                new ExceptionDocument(exception).GeneratePdf(path);
-            }
-            
-            var openBrowserProcess = new Process
-            {
-                StartInfo = new()
-                {
-                    UseShellExecute = true,
-                    FileName = path
-                }
-            };
-
-            openBrowserProcess.Start();
-        }
     }
     }
 }
 }

+ 98 - 0
QuestPDF.Previewer/PreviewerWindowViewModel.cs

@@ -0,0 +1,98 @@
+using QuestPDF.Fluent;
+using System.Diagnostics;
+using ReactiveUI;
+using QuestPDF.Infrastructure;
+using Unit = System.Reactive.Unit;
+using Avalonia.Threading;
+
+namespace QuestPDF.Previewer
+{
+    internal class PreviewerWindowViewModel : ReactiveObject
+    {
+        public DocumentRenderer DocumentRenderer { get; } = new();
+
+        private IDocument? _document;
+        public IDocument? Document
+        {
+            get => _document;
+            set
+            {
+                this.RaiseAndSetIfChanged(ref _document, value);
+                UpdateDocument(value);
+            }
+        }
+
+        private float _currentScroll;
+        public float CurrentScroll
+        {
+            get => _currentScroll;
+            set => this.RaiseAndSetIfChanged(ref _currentScroll, value);
+        }
+
+        private float _scrollViewportSize;
+        public float ScrollViewportSize
+        {
+            get => _scrollViewportSize;
+            set
+            {
+                this.RaiseAndSetIfChanged(ref _scrollViewportSize, value);
+                VerticalScrollbarVisible = value < 1;
+            }
+        }
+
+        private bool _verticalScrollbarVisible;
+        public bool VerticalScrollbarVisible
+        {
+            get => _verticalScrollbarVisible;
+            private set => Dispatcher.UIThread.Post(() => this.RaiseAndSetIfChanged(ref _verticalScrollbarVisible, value));
+        }
+
+        public ReactiveCommand<Unit, Unit> ShowPdfCommand { get; }
+
+        public PreviewerWindowViewModel()
+        {
+            HotReloadManager.UpdateApplicationRequested += InvalidateDocument;
+            ShowPdfCommand = ReactiveCommand.Create(ShowPdf);
+        }
+
+        public void UnregisterHotReloadHandler()
+        {
+            HotReloadManager.UpdateApplicationRequested -= InvalidateDocument;
+        }
+
+        private void InvalidateDocument(object? sender, EventArgs e)
+        {
+            UpdateDocument(Document);
+        }
+
+        private Task UpdateDocument(IDocument? document)
+        {
+            return Task.Run(() => DocumentRenderer.UpdateDocument(document));
+        }
+
+        private void ShowPdf()
+        {
+            var path = Path.Combine(Path.GetTempPath(), ".pdf");
+
+            try
+            {
+                Document?.GeneratePdf(path);
+            }
+            catch (Exception exception)
+            {
+                new ExceptionDocument(exception).GeneratePdf(path);
+            }
+
+            var openBrowserProcess = new Process
+            {
+                StartInfo = new()
+                {
+                    UseShellExecute = true,
+                    FileName = path
+                }
+            };
+
+            openBrowserProcess.Start();
+        }
+    }
+}