Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
<BclVersion>10.0.8</BclVersion>
<AvaloniaVersion>12.0.4</AvaloniaVersion>
<BclVersion>10.0.10</BclVersion>
<AvaloniaVersion>12.1.0</AvaloniaVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="12.0.0" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="12.0.0" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="12.1.0" />
<PackageVersion Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="$(AvaloniaVersion)" />
<PackageVersion Include="Avalonia.Fonts.Inter" Version="$(AvaloniaVersion)" />
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.1" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="$(AvaloniaVersion)" />
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" />
<PackageVersion Include="BCnEncoder.Net" Version="2.2.1" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.2" />
<PackageVersion Include="CommunityToolkit.Diagnostics" Version="8.4.2" />
<PackageVersion Include="ConsoleAppFramework" Version="5.2.4" />
<PackageVersion Include="FluentValidation" Version="12.1.1" />
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(BclVersion)" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(BclVersion)" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Threading;
using EgoEngineLibrary.Frontend.Dialogs.File;

namespace EgoEngineLibrary.Frontend.Dialogs;

/// <summary>
/// A <see cref="IDialogService"/> for Avalonia.
/// </summary>
public sealed class AvaloniaDialogService : DialogServiceBase
{
/// <summary>
/// Initializes a new instance of <see cref="AvaloniaDialogService"/>.
/// </summary>
public AvaloniaDialogService(IServiceProvider serviceProvider) : base(serviceProvider)
{
}

/// <inheritdoc />
public override async Task<bool?> ShowDialogAsync(IDialogViewModel viewModel)
{
if (!Dispatcher.UIThread.CheckAccess())
{
return await Dispatcher.UIThread.InvokeAsync(() => ShowDialogAsync(viewModel));
}

var frameworkHandled = await HandleFrameworkDialogsAsync(viewModel);
if (frameworkHandled)
{
// result unused
return false;
}

var window = CreateWindow(viewModel);
var ctx = new DialogContext(window, viewModel);
try
{
viewModel.DialogContext = ctx;
_ = await window.ShowDialog<bool>(GetOwner());
return await ctx.ResultTask;
}
finally
{
ctx.Close(false);
}
}

private static async Task<bool> HandleFrameworkDialogsAsync(IDialogViewModel viewModel)
{
Task? task = viewModel switch
{
FileOpenViewModel fileOpenViewModel => FileDialogAvalonia.FileOpen(GetOwner(), fileOpenViewModel),
FileSaveViewModel fileSaveViewModel => FileDialogAvalonia.FileSave(GetOwner(), fileSaveViewModel),
FolderOpenViewModel folderOpenViewModel => FileDialogAvalonia.FolderOpen(GetOwner(), folderOpenViewModel),
_ => null
};

if (task is null)
{
return false;
}

await task;
return true;
}

public override void Show(IDialogViewModel viewModel)
{
if (!Dispatcher.UIThread.CheckAccess())
{
Dispatcher.UIThread.Invoke(() => Show(viewModel));
return;
}

var window = CreateWindow(viewModel);
var ctx = new DialogContext(window, viewModel);
try
{
viewModel.DialogContext = ctx;
}
catch
{
ctx.Close(false);
throw;
}

window.Show(GetOwner());
}

private static Window CreateWindow(IDialogViewModel viewModel)
{
return new Window
{
Title = viewModel.Title,
CanMinimize = false,
CanResize = false,
Content = viewModel,
SizeToContent = SizeToContent.WidthAndHeight,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
}

private static Window GetOwner()
{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
return desktop.MainWindow ?? throw new InvalidOperationException("Main window is null.");
}

throw new InvalidOperationException("ApplicationLifetime not supported");
}

private class DialogContext : IDialogContext
{
private readonly TaskCompletionSource<bool> _resultTcs;
private Window? _dialogWindow;
private IDialogViewModel? _viewModel;

public Task<bool> ResultTask => _resultTcs.Task;

public DialogContext(Window dialogWindow, IDialogViewModel viewModel)
{
_resultTcs = new TaskCompletionSource<bool>();
_dialogWindow = dialogWindow;
_viewModel = viewModel;
_dialogWindow.Closed += DialogWindowOnClosed;
}

private void DialogWindowOnClosed(object? sender, EventArgs e)
{
_dialogWindow?.Closed -= DialogWindowOnClosed;
Close(false);
}

public void Close(bool result = true)
{
if (!_resultTcs.TrySetResult(result))
{
// Already closed
return;
}

_viewModel?.DialogContext = null;
_viewModel = null;

var dialogWindow = _dialogWindow;
_dialogWindow = null;
if (dialogWindow is null)
{
return;
}

dialogWindow.Closed -= DialogWindowOnClosed;
if (dialogWindow.Dispatcher.CheckAccess())
{
dialogWindow.Close();
}
else
{
dialogWindow.Dispatcher.Invoke(dialogWindow.Close);
}
}
}
}

This file was deleted.

Loading