mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-04 12:25:46 +00:00
Initial work on a setup wizard
Setup wizard abstraction & architecture from TKMM
This commit is contained in:
31
src/Ryujinx/Systems/SetupWizard/BaseSetupWizard.cs
Normal file
31
src/Ryujinx/Systems/SetupWizard/BaseSetupWizard.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Systems.SetupWizard;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Systems.SetupWizard
|
||||
{
|
||||
public abstract class BaseSetupWizard(ContentPresenter presenter)
|
||||
{
|
||||
/// <summary>
|
||||
/// Define the logic and flow of this <see cref="BaseSetupWizard"/>.
|
||||
/// </summary>
|
||||
public abstract ValueTask Start();
|
||||
|
||||
protected ValueTask<bool> FirstPage()
|
||||
{
|
||||
SetupWizardPageBuilder builder = new(presenter, isFirstPage: true);
|
||||
|
||||
return builder
|
||||
.WithTitle(LocaleKeys.SetupWizardFirstPageTitle)
|
||||
.WithContent(LocaleKeys.SetupWizardFirstPageContent)
|
||||
.WithActionContent(LocaleKeys.SetupWizardFirstPageAction)
|
||||
.Show();
|
||||
}
|
||||
|
||||
protected SetupWizardPageBuilder NextPage()
|
||||
{
|
||||
return new SetupWizardPageBuilder(presenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
src/Ryujinx/Systems/SetupWizard/README.md
Normal file
3
src/Ryujinx/Systems/SetupWizard/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Ryubing Setup Wizard
|
||||
|
||||
Directly modified from the code found [here](https://github.com/TKMM-Team/Tkmm/tree/master/src/Tkmm/Wizard).
|
||||
62
src/Ryujinx/Systems/SetupWizard/SetupWizardPage.cs
Normal file
62
src/Ryujinx/Systems/SetupWizard/SetupWizardPage.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Avalonia.Controls.Presenters;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Systems.SetupWizard;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Systems.SetupWizard
|
||||
{
|
||||
public partial class SetupWizardPage(bool isFirstPage = false) : BaseModel
|
||||
{
|
||||
protected bool? _result;
|
||||
protected readonly CancellationTokenSource _cancellationTokenSource = new();
|
||||
|
||||
public bool IsFirstPage { get; } = isFirstPage;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _title;
|
||||
|
||||
[ObservableProperty]
|
||||
private object? _content;
|
||||
|
||||
[ObservableProperty]
|
||||
private object? _helpContent;
|
||||
|
||||
[ObservableProperty]
|
||||
private object? _actionContent = LocaleManager.Instance[LocaleKeys.SetupWizardActionNext];
|
||||
|
||||
[RelayCommand]
|
||||
private void MoveBack()
|
||||
{
|
||||
_result = false;
|
||||
_cancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void MoveNext()
|
||||
{
|
||||
_result = true;
|
||||
_cancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
public async ValueTask<bool> Show(ContentPresenter presenter)
|
||||
{
|
||||
presenter.Content = new SetupWizardPageView
|
||||
{
|
||||
DataContext = this,
|
||||
};
|
||||
|
||||
try {
|
||||
await Task.Delay(-1, _cancellationTokenSource.Token);
|
||||
}
|
||||
catch (TaskCanceledException) {
|
||||
return _result ?? false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/Ryujinx/Systems/SetupWizard/SetupWizardPageBuilder.cs
Normal file
69
src/Ryujinx/Systems/SetupWizard/SetupWizardPageBuilder.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Systems.SetupWizard;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Systems.SetupWizard
|
||||
{
|
||||
public class SetupWizardPageBuilder(ContentPresenter presenter, bool isFirstPage = false)
|
||||
{
|
||||
private readonly SetupWizardPage _page = new(isFirstPage);
|
||||
|
||||
public SetupWizardPage Build()
|
||||
{
|
||||
return _page;
|
||||
}
|
||||
|
||||
public SetupWizardPageBuilder WithTitle(LocaleKeys title) => WithTitle(LocaleManager.Instance[title]);
|
||||
|
||||
public SetupWizardPageBuilder WithTitle(string title)
|
||||
{
|
||||
_page.Title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SetupWizardPageBuilder WithContent(LocaleKeys content) => WithContent(LocaleManager.Instance[content]);
|
||||
|
||||
public SetupWizardPageBuilder WithContent(object? content)
|
||||
{
|
||||
if (content is StyledElement { Parent: ContentControl parent }) {
|
||||
parent.Content = null;
|
||||
}
|
||||
|
||||
_page.Content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SetupWizardPageBuilder WithHelpContent(LocaleKeys content) => WithHelpContent(LocaleManager.Instance[content]);
|
||||
|
||||
public SetupWizardPageBuilder WithHelpContent(object? content)
|
||||
{
|
||||
_page.HelpContent = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SetupWizardPageBuilder WithContent<TControl>(object? context = null) where TControl : Control, new()
|
||||
{
|
||||
_page.Content = new TControl {
|
||||
DataContext = context
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public SetupWizardPageBuilder WithActionContent(LocaleKeys content) => WithActionContent(LocaleManager.Instance[content]);
|
||||
|
||||
public SetupWizardPageBuilder WithActionContent(object? content)
|
||||
{
|
||||
_page.ActionContent = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ValueTask<bool> Show()
|
||||
{
|
||||
return _page.Show(presenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
77
src/Ryujinx/Systems/SetupWizard/SetupWizardPageView.axaml
Normal file
77
src/Ryujinx/Systems/SetupWizard/SetupWizardPageView.axaml
Normal file
@@ -0,0 +1,77 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:fa="using:Projektanker.Icons.Avalonia"
|
||||
xmlns:wiz="using:Ryujinx.Ava.Systems.SetupWizard"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:DataType="wiz:SetupWizardPage"
|
||||
x:Class="Ryujinx.Systems.SetupWizard.SetupWizardPageView">
|
||||
<Grid RowDefinitions="*,Auto" Margin="60">
|
||||
<ScrollViewer>
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<TextBlock Grid.Row="0"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
FontFamily="{StaticResource HyliaGlyph}"
|
||||
FontSize="46"
|
||||
Text="{Binding Title}" />
|
||||
|
||||
<ContentPresenter Grid.Row="1"
|
||||
Content="{Binding}"
|
||||
IsVisible="{Binding !#InfoToggle.IsChecked}"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
Margin="0,15,0,0">
|
||||
<ContentPresenter.DataTemplates>
|
||||
<DataTemplate DataType="{x:Type wiz:SetupWizardPage}">
|
||||
<ContentControl Content="{Binding Content}" VerticalAlignment="Stretch"/>
|
||||
</DataTemplate>
|
||||
</ContentPresenter.DataTemplates>
|
||||
</ContentPresenter>
|
||||
|
||||
<Grid Grid.Row="2"
|
||||
ColumnDefinitions="Auto,*"
|
||||
IsVisible="{Binding #InfoToggle.IsChecked}">
|
||||
<StackPanel Spacing="5" VerticalAlignment="Top">
|
||||
<HyperlinkButton NavigateUri="https://discord.gg/PEuzjrFXUA" Content="Join Discord" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Content="{Binding}"
|
||||
Grid.Column="1"
|
||||
Margin="20,0,0,0"
|
||||
TextWrapping="WrapWithOverflow">
|
||||
<ContentPresenter.DataTemplates>
|
||||
<DataTemplate DataType="{x:Type wiz:SetupWizardPage}">
|
||||
<ContentControl Content="{Binding HelpContent}" />
|
||||
</DataTemplate>
|
||||
</ContentPresenter.DataTemplates>
|
||||
</ContentPresenter>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
<Grid ColumnDefinitions="Auto,Auto,*" Grid.Row="1">
|
||||
<ToggleButton Name="InfoToggle"
|
||||
Padding="6">
|
||||
<fa:Icon Value="fa-solid fa-circle-info" />
|
||||
</ToggleButton>
|
||||
|
||||
<Button IsVisible="{Binding !IsFirstPage}"
|
||||
Grid.Column="1"
|
||||
Content="{ext:Locale SetupWizardActionBack}"
|
||||
Margin="10,0,0,0"
|
||||
Command="{Binding MoveBackCommand}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Right"
|
||||
Grid.Column="2">
|
||||
<Button Content="{Binding ActionContent}"
|
||||
Command="{Binding MoveNextCommand}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
17
src/Ryujinx/Systems/SetupWizard/SetupWizardPageView.axaml.cs
Normal file
17
src/Ryujinx/Systems/SetupWizard/SetupWizardPageView.axaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Ryujinx.Ava.Systems.SetupWizard;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
|
||||
namespace Ryujinx.Systems.SetupWizard
|
||||
{
|
||||
public partial class SetupWizardPageView : RyujinxControl<SetupWizardPage>
|
||||
{
|
||||
public SetupWizardPageView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user