mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-12-12 07:36:59 +00:00
Overhaul setup wizard help pages
the context can now override a virtual method named `CreateHelpContent` which the setup wizard system will automatically try to use when you use the generic overload taking a generic context type. If the return is null, it skips setting entirely (the default impl is null) additionally made the discord join link a button with code copied from the about window, and made it centered at the bottom.
This commit is contained in:
parent
1c6652bae1
commit
09d8b4880b
10 changed files with 229 additions and 40 deletions
|
|
@ -13,6 +13,12 @@ namespace Ryujinx.Common
|
||||||
public const string SetupGuideWikiUrl =
|
public const string SetupGuideWikiUrl =
|
||||||
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Setup-&-Configuration-Guide";
|
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Setup-&-Configuration-Guide";
|
||||||
|
|
||||||
|
public const string DumpKeysWikiUrl =
|
||||||
|
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Dumping/Keys";
|
||||||
|
|
||||||
|
public const string DumpFirmwareWikiUrl =
|
||||||
|
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Dumping/Firmware";
|
||||||
|
|
||||||
public const string MultiplayerWikiUrl =
|
public const string MultiplayerWikiUrl =
|
||||||
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Multiplayer-(LDN-Local-Wireless)-Guide";
|
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Multiplayer-(LDN-Local-Wireless)-Guide";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Layout;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -68,6 +71,32 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Control CreateHelpContent()
|
||||||
|
{
|
||||||
|
Grid grid = new()
|
||||||
|
{
|
||||||
|
RowDefinitions = [new(GridLength.Auto), new(GridLength.Auto)],
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center
|
||||||
|
};
|
||||||
|
|
||||||
|
grid.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = "Not sure how to get your firmware off of your Switch?",
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
GridRow = 0
|
||||||
|
});
|
||||||
|
|
||||||
|
grid.Children.Add(new HyperlinkButton
|
||||||
|
{
|
||||||
|
Content = "Click here to view a guide.",
|
||||||
|
NavigateUri = new Uri(SharedConstants.DumpFirmwareWikiUrl),
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
GridRow = 1
|
||||||
|
});
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
public override Result CompleteStep()
|
public override Result CompleteStep()
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(FirmwareSourcePath))
|
if (!Directory.Exists(FirmwareSourcePath))
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Layout;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.Exceptions;
|
using Ryujinx.HLE.Exceptions;
|
||||||
|
|
@ -23,16 +26,43 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages
|
||||||
? Result.Fail
|
? Result.Fail
|
||||||
: InstallKeys(KeysFolderPath);
|
: InstallKeys(KeysFolderPath);
|
||||||
|
|
||||||
[ObservableProperty]
|
public override Control CreateHelpContent()
|
||||||
public partial string KeysFolderPath { get; set; }
|
{
|
||||||
|
Grid grid = new()
|
||||||
|
{
|
||||||
|
RowDefinitions = [new(GridLength.Auto), new(GridLength.Auto)],
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center
|
||||||
|
};
|
||||||
|
|
||||||
|
grid.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = "Not sure how to get your keys?",
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
GridRow = 0
|
||||||
|
});
|
||||||
|
|
||||||
|
grid.Children.Add(new HyperlinkButton
|
||||||
|
{
|
||||||
|
Content = "Click here to view a guide.",
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
NavigateUri = new Uri(SharedConstants.DumpKeysWikiUrl),
|
||||||
|
GridRow = 1
|
||||||
|
});
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ObservableProperty] public partial string KeysFolderPath { get; set; }
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private static async Task Browse(TextBox tb)
|
private static async Task Browse(TextBox tb)
|
||||||
{
|
{
|
||||||
Optional<IStorageFolder> result = await RyujinxApp.MainWindow.ViewModel.StorageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
Optional<IStorageFolder> result =
|
||||||
{
|
await RyujinxApp.MainWindow.ViewModel.StorageProvider.OpenSingleFolderPickerAsync(
|
||||||
Title = LocaleManager.Instance[LocaleKeys.SetupWizardKeysPageFolderPopupTitle]
|
new FolderPickerOpenOptions
|
||||||
});
|
{
|
||||||
|
Title = LocaleManager.Instance[LocaleKeys.SetupWizardKeysPageFolderPopupTitle]
|
||||||
|
});
|
||||||
|
|
||||||
if (result.TryGet(out IStorageFolder keyFolder))
|
if (result.TryGet(out IStorageFolder keyFolder))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.Notifications;
|
using Avalonia.Controls.Notifications;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
|
using Avalonia.Styling;
|
||||||
|
using Avalonia.Threading;
|
||||||
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Systems.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.SetupWizard.Pages;
|
using Ryujinx.Ava.UI.SetupWizard.Pages;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.SetupWizard
|
namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
{
|
{
|
||||||
public class RyujinxSetupWizard(RyujinxSetupWizardWindow wizardWindow, bool overwriteMode)
|
public class RyujinxSetupWizard : IDisposable, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private bool _configWasModified;
|
private bool _configWasModified;
|
||||||
|
|
||||||
|
|
@ -18,12 +26,12 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
|
|
||||||
public async Task Start()
|
public async Task Start()
|
||||||
{
|
{
|
||||||
NotificationManager = wizardWindow.CreateNotificationManager(
|
NotificationManager = _window.CreateNotificationManager(
|
||||||
// I wanted to do bottom center but that...literally just shows top center? Okay.
|
// I wanted to do bottom center but that...literally just shows top center? Okay.
|
||||||
// Fuck it, weird window height hack to do it instead.
|
// Fuck it, weird window height hack to do it instead.
|
||||||
// 120 is not exact, just a random number. Looks fine though.
|
// 120 is not exact, just a random number. Looks fine though.
|
||||||
NotificationPosition.TopCenter,
|
NotificationPosition.TopCenter,
|
||||||
margin: new Thickness(0, wizardWindow.Height - 120, 0, 0)
|
margin: new Thickness(0, _window.Height - 120, 0, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
RyujinxSetupWizardWindow.IsOpen = true;
|
RyujinxSetupWizardWindow.IsOpen = true;
|
||||||
|
|
@ -49,13 +57,38 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.GlobalConfigurationPath);
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.GlobalConfigurationPath);
|
||||||
|
|
||||||
NotificationManager = null;
|
NotificationManager = null;
|
||||||
wizardWindow.Close();
|
_window.Close();
|
||||||
RyujinxSetupWizardWindow.IsOpen = false;
|
RyujinxSetupWizardWindow.IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitmap DiscordLogo
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set => SetField(ref field, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Ryujinx_ThemeChanged()
|
||||||
|
{
|
||||||
|
Dispatcher.UIThread.Post(() => UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string LogoPathFormat = "resm:Ryujinx.Assets.UIImages.Logo_{0}_{1}.png?assembly=Ryujinx";
|
||||||
|
|
||||||
|
private void UpdateLogoTheme(string theme)
|
||||||
|
{
|
||||||
|
bool isDarkTheme = theme == "Dark" ||
|
||||||
|
(theme == "Auto" && RyujinxApp.DetectSystemTheme() == ThemeVariant.Dark);
|
||||||
|
|
||||||
|
string themeName = isDarkTheme ? "Dark" : "Light";
|
||||||
|
|
||||||
|
DiscordLogo = LoadBitmap(LogoPathFormat.Format("Discord", themeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Bitmap LoadBitmap(string uri) => new(Avalonia.Platform.AssetLoader.Open(new Uri(uri)));
|
||||||
|
|
||||||
private async ValueTask<bool> SetupKeys()
|
private async ValueTask<bool> SetupKeys()
|
||||||
{
|
{
|
||||||
if (overwriteMode || !RyujinxApp.MainWindow.VirtualFileSystem.HasKeySet)
|
if (_overwrite || !RyujinxApp.MainWindow.VirtualFileSystem.HasKeySet)
|
||||||
{
|
{
|
||||||
Retry:
|
Retry:
|
||||||
bool result = await NextPage()
|
bool result = await NextPage()
|
||||||
|
|
@ -75,7 +108,7 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
|
|
||||||
private async ValueTask<bool> SetupFirmware()
|
private async ValueTask<bool> SetupFirmware()
|
||||||
{
|
{
|
||||||
if (overwriteMode || !HasFirmware)
|
if (_overwrite || !HasFirmware)
|
||||||
{
|
{
|
||||||
if (!RyujinxApp.MainWindow.VirtualFileSystem.HasKeySet)
|
if (!RyujinxApp.MainWindow.VirtualFileSystem.HasKeySet)
|
||||||
{
|
{
|
||||||
|
|
@ -99,13 +132,54 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SetupWizardPage FirstPage() => new(wizardWindow.WizardPresenter, this, isFirstPage: true);
|
private SetupWizardPage FirstPage() => new(_window.WizardPresenter, this, isFirstPage: true);
|
||||||
|
|
||||||
private SetupWizardPage NextPage() => new(wizardWindow.WizardPresenter, this);
|
private SetupWizardPage NextPage() => new(_window.WizardPresenter, this);
|
||||||
|
|
||||||
public void SignalConfigModified()
|
public void SignalConfigModified()
|
||||||
{
|
{
|
||||||
_configWasModified = true;
|
_configWasModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly RyujinxSetupWizardWindow _window;
|
||||||
|
private readonly bool _overwrite;
|
||||||
|
|
||||||
|
public RyujinxSetupWizard(RyujinxSetupWizardWindow wizardWindow, bool overwriteMode)
|
||||||
|
{
|
||||||
|
_window = wizardWindow;
|
||||||
|
_overwrite = overwriteMode;
|
||||||
|
|
||||||
|
if (Program.PreviewerDetached)
|
||||||
|
{
|
||||||
|
UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle);
|
||||||
|
RyujinxApp.ThemeChanged += Ryujinx_ThemeChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
RyujinxApp.ThemeChanged -= Ryujinx_ThemeChanged;
|
||||||
|
|
||||||
|
DiscordLogo.Dispose();
|
||||||
|
|
||||||
|
Console.WriteLine("disposed");
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
|
||||||
|
field = value;
|
||||||
|
OnPropertyChanged(propertyName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Gommon;
|
||||||
using Ryujinx.Ava.Systems.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
|
@ -33,7 +34,7 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
owner
|
owner
|
||||||
);
|
);
|
||||||
_ = wiz.Start();
|
_ = wiz.Start();
|
||||||
return windowTask;
|
return windowTask.ContinueWith(_ => wiz.Dispose());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RyujinxSetupWizardWindow CreateWindow(out RyujinxSetupWizard setupWizard, bool overwriteMode = false)
|
public static RyujinxSetupWizardWindow CreateWindow(out RyujinxSetupWizard setupWizard, bool overwriteMode = false)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.SetupWizard
|
namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
{
|
{
|
||||||
|
|
@ -34,6 +36,7 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
public SetupWizardPage WithHelpContent(object? content)
|
public SetupWizardPage WithHelpContent(object? content)
|
||||||
{
|
{
|
||||||
HelpContent = content;
|
HelpContent = content;
|
||||||
|
HasHelpContent = content != null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,12 +47,17 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SetupWizardPage WithContent<TControl, TViewModel>(out TViewModel boundViewModel)
|
public SetupWizardPage WithContent<TControl, TContext>(out TContext boundContext)
|
||||||
where TControl : RyujinxControl<TViewModel>, new()
|
where TControl : RyujinxControl<TContext>, new()
|
||||||
where TViewModel : SetupWizardPageContext, new()
|
where TContext : SetupWizardPageContext, new()
|
||||||
=> WithContent<TControl>(
|
{
|
||||||
boundViewModel = new() { NotificationManager = ownerWizard.NotificationManager }
|
boundContext = new() { NotificationManager = ownerWizard.NotificationManager };
|
||||||
);
|
|
||||||
|
if (boundContext.CreateHelpContent() is { } content)
|
||||||
|
WithHelpContent(content);
|
||||||
|
|
||||||
|
return WithContent<TControl>(boundContext);
|
||||||
|
}
|
||||||
|
|
||||||
public SetupWizardPage WithActionContent(LocaleKeys content) =>
|
public SetupWizardPage WithActionContent(LocaleKeys content) =>
|
||||||
WithActionContent(LocaleManager.Instance[content]);
|
WithActionContent(LocaleManager.Instance[content]);
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,16 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
|
|
||||||
public bool IsFirstPage => isFirstPage;
|
public bool IsFirstPage => isFirstPage;
|
||||||
|
|
||||||
|
public RyujinxSetupWizard Parent => ownerWizard;
|
||||||
|
|
||||||
[ObservableProperty] public partial string? Title { get; set; }
|
[ObservableProperty] public partial string? Title { get; set; }
|
||||||
|
|
||||||
[ObservableProperty] public partial object? Content { get; set; }
|
[ObservableProperty] public partial object? Content { get; set; }
|
||||||
|
|
||||||
[ObservableProperty] public partial object? HelpContent { get; set; }
|
[ObservableProperty] public partial object? HelpContent { get; set; }
|
||||||
|
|
||||||
|
[ObservableProperty] public partial bool HasHelpContent { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public partial object? ActionContent { get; set; } = LocaleManager.Instance[LocaleKeys.SetupWizardActionNext];
|
public partial object? ActionContent { get; set; } = LocaleManager.Instance[LocaleKeys.SetupWizardActionNext];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Avalonia.Controls;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
|
@ -9,5 +10,10 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
public RyujinxNotificationManager NotificationManager { get; init; }
|
public RyujinxNotificationManager NotificationManager { get; init; }
|
||||||
|
|
||||||
public abstract Result CompleteStep();
|
public abstract Result CompleteStep();
|
||||||
|
|
||||||
|
public virtual Control CreateHelpContent()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,11 @@
|
||||||
x:Class="Ryujinx.Ava.UI.SetupWizard.SetupWizardPageView">
|
x:Class="Ryujinx.Ava.UI.SetupWizard.SetupWizardPageView">
|
||||||
<Grid RowDefinitions="*,Auto" Margin="60">
|
<Grid RowDefinitions="*,Auto" Margin="60">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<Grid RowDefinitions="Auto,*,Auto">
|
<Grid RowDefinitions="Auto,*">
|
||||||
<TextBlock Grid.Row="0"
|
<TextBlock Grid.Row="0"
|
||||||
TextWrapping="WrapWithOverflow"
|
TextWrapping="WrapWithOverflow"
|
||||||
FontSize="46"
|
FontSize="46"
|
||||||
Text="{Binding Title}" />
|
Text="{Binding Title}" />
|
||||||
|
|
||||||
<ContentPresenter Grid.Row="1"
|
<ContentPresenter Grid.Row="1"
|
||||||
Content="{Binding}"
|
Content="{Binding}"
|
||||||
IsVisible="{Binding !#InfoToggle.IsChecked}"
|
IsVisible="{Binding !#InfoToggle.IsChecked}"
|
||||||
|
|
@ -28,22 +27,44 @@
|
||||||
</ContentPresenter.DataTemplates>
|
</ContentPresenter.DataTemplates>
|
||||||
</ContentPresenter>
|
</ContentPresenter>
|
||||||
|
|
||||||
<Grid Grid.Row="2"
|
<Grid Grid.Row="1"
|
||||||
ColumnDefinitions="Auto,*"
|
ColumnDefinitions="*" RowDefinitions="*,Auto"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
IsVisible="{Binding #InfoToggle.IsChecked}">
|
IsVisible="{Binding #InfoToggle.IsChecked}">
|
||||||
<StackPanel Spacing="5" VerticalAlignment="Top">
|
<Border
|
||||||
<HyperlinkButton NavigateUri="https://discord.gg/PEuzjrFXUA" Content="Join Discord" />
|
Margin="15"
|
||||||
</StackPanel>
|
IsVisible="{Binding HasHelpContent}"
|
||||||
<ContentPresenter Content="{Binding}"
|
HorizontalAlignment="Stretch"
|
||||||
Grid.Column="1"
|
VerticalAlignment="Stretch"
|
||||||
Margin="20,0,0,0"
|
ClipToBounds="True"
|
||||||
TextWrapping="WrapWithOverflow">
|
CornerRadius="5"
|
||||||
<ContentPresenter.DataTemplates>
|
Background="{DynamicResource AppListBackgroundColor}">
|
||||||
<DataTemplate DataType="{x:Type wiz:SetupWizardPage}">
|
<ContentPresenter Content="{Binding}"
|
||||||
<ContentControl Content="{Binding HelpContent}" />
|
Margin="5"
|
||||||
</DataTemplate>
|
TextWrapping="WrapWithOverflow" VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||||
</ContentPresenter.DataTemplates>
|
<ContentPresenter.DataTemplates>
|
||||||
</ContentPresenter>
|
<DataTemplate DataType="{x:Type wiz:SetupWizardPage}">
|
||||||
|
<ContentControl Content="{Binding HelpContent}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ContentPresenter.DataTemplates>
|
||||||
|
</ContentPresenter>
|
||||||
|
</Border>
|
||||||
|
<Button Grid.Row="1"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
MinWidth="45"
|
||||||
|
MinHeight="32"
|
||||||
|
MaxWidth="45"
|
||||||
|
MaxHeight="32"
|
||||||
|
Padding="8"
|
||||||
|
Background="Transparent"
|
||||||
|
Click="Button_OnClick"
|
||||||
|
CornerRadius="5"
|
||||||
|
Tag="https://discord.gg/PEuzjrFXUA"
|
||||||
|
ToolTip.Tip="{ext:Locale AboutDiscordUrlTooltipMessage}">
|
||||||
|
<Image Source="{Binding Parent.DiscordLogo}" />
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
|
|
||||||
|
using Ryujinx.Common.Helper;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.SetupWizard
|
namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
{
|
{
|
||||||
public partial class SetupWizardPageView : RyujinxControl<SetupWizardPage>
|
public partial class SetupWizardPageView : RyujinxControl<SetupWizardPage>
|
||||||
|
|
@ -8,6 +12,12 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Button_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Button { Tag: string url })
|
||||||
|
OpenHelper.OpenUrl(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue