Merge pull request #157 from Bebo-Maker/previewer

Previewer - ViewModel for PreviewerWindow
This commit is contained in:
Marcin Ziąbek
2022-03-24 22:20:28 +01:00
committed by GitHub
5 changed files with 117 additions and 102 deletions
@@ -1,5 +1,6 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.ReactiveUI;
using QuestPDF.Infrastructure;
namespace QuestPDF.Previewer
@@ -24,7 +25,10 @@ namespace QuestPDF.Previewer
{
desktop.MainWindow = new PreviewerWindow()
{
Document = document,
DataContext = new PreviewerWindowViewModel()
{
Document = document,
}
};
desktop.MainWindow.Show();
@@ -39,6 +43,7 @@ namespace QuestPDF.Previewer
Document = document,
})
.UsePlatformDetect()
.UseReactiveUI()
.StartWithClassicDesktopLifetime(Array.Empty<string>());
}
}
+4 -1
View File
@@ -20,7 +20,10 @@ namespace QuestPDF.Previewer
{
desktop.MainWindow = new PreviewerWindow()
{
Document = Document
DataContext = new PreviewerWindowViewModel()
{
Document = Document,
}
};
}
+7 -9
View File
@@ -11,9 +11,7 @@
Background="#666"
Icon="/Images/Logo.png"
UseLayoutRounding="True"
x:Name="Window"
Title="QuestPDF Document Preview">
<Panel>
<Grid>
<Grid.RowDefinitions>
@@ -33,14 +31,14 @@
<previewer:PreviewerControl Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
HorizontalAlignment="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"
VerticalAlignment="Bottom" HorizontalAlignment="Left"
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.">
<Viewbox Width="24" Height="24">
<Canvas Width="24" Height="24">
@@ -53,9 +51,9 @@
Orientation="Vertical"
AllowAutoHide="False"
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>
</Panel>
</Window>
+2 -91
View File
@@ -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.Threading;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using ReactiveUI;
namespace QuestPDF.Previewer
{
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()
{
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)
{
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()
{
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();
}
}
}
@@ -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();
}
}
}