mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Meta - Replace WPF projects with Avalonia projects
This commit is contained in:
1 parent
fcf0376a9a
commit
d7f3ee1190
1110 files changed
+10872
-52240
No files matched your search
@@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Controls;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Shared.Services.Builders
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a builder that can be used to create Fluent UI dialogs.
|
||||
/// </summary>
|
||||
public class ContentDialogBuilder
|
||||
{
|
||||
private readonly ContentDialog _contentDialog;
|
||||
private readonly IKernel _kernel;
|
||||
private readonly Window _parent;
|
||||
private ContentDialogViewModelBase? _viewModel;
|
||||
|
||||
internal ContentDialogBuilder(IKernel kernel, Window parent)
|
||||
{
|
||||
_kernel = kernel;
|
||||
_parent = parent;
|
||||
_contentDialog = new ContentDialog
|
||||
{
|
||||
CloseButtonText = "Close"
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the title of the dialog.
|
||||
/// </summary>
|
||||
/// <param name="title">The new title.</param>
|
||||
/// <returns>The builder that can be used to further build the dialog.</returns>
|
||||
public ContentDialogBuilder WithTitle(string? title)
|
||||
{
|
||||
_contentDialog.Title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the content of the dialog.
|
||||
/// </summary>
|
||||
/// <param name="content">The new content.</param>
|
||||
/// <returns>The builder that can be used to further build the dialog.</returns>
|
||||
public ContentDialogBuilder WithContent(string? content)
|
||||
{
|
||||
_contentDialog.Content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the default button of the dialog that is pressed on enter.
|
||||
/// </summary>
|
||||
/// <param name="defaultButton">The default button.</param>
|
||||
/// <returns>The builder that can be used to further build the dialog.</returns>
|
||||
public ContentDialogBuilder WithDefaultButton(ContentDialogButton defaultButton)
|
||||
{
|
||||
_contentDialog.DefaultButton = (FluentAvalonia.UI.Controls.ContentDialogButton) defaultButton;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the primary button of the dialog.
|
||||
/// </summary>
|
||||
/// <param name="configure">An action to configure the button.</param>
|
||||
/// <returns>The builder that can be used to further build the dialog.</returns>
|
||||
public ContentDialogBuilder HavingPrimaryButton(Action<ContentDialogButtonBuilder> configure)
|
||||
{
|
||||
ContentDialogButtonBuilder builder = new();
|
||||
configure(builder);
|
||||
|
||||
_contentDialog.IsPrimaryButtonEnabled = true;
|
||||
_contentDialog.PrimaryButtonText = builder.Text;
|
||||
_contentDialog.PrimaryButtonCommand = builder.Command;
|
||||
_contentDialog.PrimaryButtonCommandParameter = builder.CommandParameter;
|
||||
|
||||
// I feel like this isn't my responsibility...
|
||||
if (builder.Command != null)
|
||||
{
|
||||
_contentDialog.IsPrimaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter);
|
||||
builder.Command.CanExecuteChanged += (_, _) => _contentDialog.IsPrimaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the secondary button of the dialog.
|
||||
/// </summary>
|
||||
/// <param name="configure">An action to configure the button.</param>
|
||||
/// <returns>The builder that can be used to further build the dialog.</returns>
|
||||
public ContentDialogBuilder HavingSecondaryButton(Action<ContentDialogButtonBuilder> configure)
|
||||
{
|
||||
ContentDialogButtonBuilder builder = new();
|
||||
configure(builder);
|
||||
|
||||
_contentDialog.IsSecondaryButtonEnabled = true;
|
||||
_contentDialog.SecondaryButtonText = builder.Text;
|
||||
_contentDialog.SecondaryButtonCommand = builder.Command;
|
||||
_contentDialog.SecondaryButtonCommandParameter = builder.CommandParameter;
|
||||
|
||||
// I feel like this isn't my responsibility...
|
||||
if (builder.Command != null)
|
||||
{
|
||||
_contentDialog.IsSecondaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter);
|
||||
builder.Command.CanExecuteChanged += (_, _) => _contentDialog.IsSecondaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the text of the close button of the dialog.
|
||||
/// </summary>
|
||||
/// <param name="text">The new text.</param>
|
||||
/// <returns>The builder that can be used to further build the dialog.</returns>
|
||||
public ContentDialogBuilder WithCloseButtonText(string? text)
|
||||
{
|
||||
_contentDialog.CloseButtonText = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the view model of the content dialog, hosting it inside the dialog.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the view model to host.</typeparam>
|
||||
/// <param name="viewModel">The resulting view model.</param>
|
||||
/// <param name="parameters">Optional parameters to pass to the constructor of the view model, case and order sensitive.</param>
|
||||
/// <returns>The builder that can be used to further build the dialog.</returns>
|
||||
public ContentDialogBuilder WithViewModel<T>(out T viewModel, params (string name, object? value)[] parameters) where T : ContentDialogViewModelBase
|
||||
{
|
||||
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast<IParameter>().ToArray();
|
||||
viewModel = _kernel.Get<T>(paramsArray);
|
||||
viewModel.ContentDialog = _contentDialog;
|
||||
_contentDialog.Content = viewModel;
|
||||
|
||||
_viewModel = viewModel;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously shows the content dialog.
|
||||
/// </summary>
|
||||
/// <returns>A task containing the result of the content dialog.</returns>
|
||||
/// <exception cref="ArtemisSharedUIException">Thrown when the parent window does not contain a panel at its root.</exception>
|
||||
public async Task<ContentDialogResult> ShowAsync()
|
||||
{
|
||||
if (_parent.Content is not Panel panel)
|
||||
throw new ArtemisSharedUIException($"The parent window {_parent.GetType().FullName} should contain a panel at its root");
|
||||
|
||||
try
|
||||
{
|
||||
panel.Children.Add(_contentDialog);
|
||||
ContentDialogResult result = await _contentDialog.ShowAsync();
|
||||
|
||||
// Take the dialog away from the VM in case it's going to try to hide it again or whatever...
|
||||
if (_viewModel != null)
|
||||
_viewModel.ContentDialog = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
panel.Children.Remove(_contentDialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a content dialog button.
|
||||
/// </summary>
|
||||
public enum ContentDialogButton
|
||||
{
|
||||
/// <summary>
|
||||
/// No button.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// The primary button.
|
||||
/// </summary>
|
||||
Primary,
|
||||
|
||||
/// <summary>
|
||||
/// The secondary button.
|
||||
/// </summary>
|
||||
Secondary,
|
||||
|
||||
/// <summary>
|
||||
/// The close button.
|
||||
/// </summary>
|
||||
Close,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a builder that can be used to create buttons inside content dialogs.
|
||||
/// </summary>
|
||||
public class ContentDialogButtonBuilder
|
||||
{
|
||||
internal ContentDialogButtonBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
internal string? Text { get; set; }
|
||||
internal ICommand? Command { get; set; }
|
||||
internal Action? Action { get; set; }
|
||||
internal object? CommandParameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Changes text message of the button.
|
||||
/// </summary>
|
||||
/// <param name="text">The new text.</param>
|
||||
/// <returns>The notification builder that can be used to further build the button.</returns>
|
||||
public ContentDialogButtonBuilder WithText(string? text)
|
||||
{
|
||||
Text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes action that is called when the button is clicked.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to call when the button is clicked.</param>
|
||||
/// <returns>The builder that can be used to further build the button.</returns>
|
||||
public ContentDialogButtonBuilder WithAction(Action action)
|
||||
{
|
||||
Action = action;
|
||||
Command = ReactiveCommand.Create(() => Action());
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes command that is called when the button is clicked.
|
||||
/// </summary>
|
||||
/// <param name="command">The command to call when the button is clicked.</param>
|
||||
/// <returns>The builder that can be used to further build the button.</returns>
|
||||
public ContentDialogButtonBuilder WithCommand(ICommand? command)
|
||||
{
|
||||
Command = command;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes parameter of the command that is called when the button is clicked.
|
||||
/// </summary>
|
||||
/// <param name="commandParameter">The parameter of the command to call when the button is clicked.</param>
|
||||
/// <returns>The builder that can be used to further build the button.</returns>
|
||||
public ContentDialogButtonBuilder WithCommandParameter(object? commandParameter)
|
||||
{
|
||||
CommandParameter = commandParameter;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user