diff options
| author | Mary Guillemard <mary@mary.zone> | 2024-03-02 12:51:05 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-02 12:51:05 +0100 |
| commit | ec6cb0abb4b7669895b6e96fd7581c93b5abd691 (patch) | |
| tree | 128c862ff5faea0b219467656d4023bee7faefb5 /src/Ryujinx.Ava/UI/Applet | |
| parent | 53b5985da6b9d7b281d9fc25b93bfd1d1918a107 (diff) | |
infra: Make Avalonia the default UI (#6375)
* misc: Move Ryujinx project to Ryujinx.Gtk3
This breaks release CI for now but that's fine.
Signed-off-by: Mary Guillemard <mary@mary.zone>
* misc: Move Ryujinx.Ava project to Ryujinx
This breaks CI for now, but it's fine.
Signed-off-by: Mary Guillemard <mary@mary.zone>
* infra: Make Avalonia the default UI
Should fix CI after the previous changes.
GTK3 isn't build by the release job anymore, only by PR CI.
This also ensure that the test-ava update package is still generated to
allow update from the old testing channel.
Signed-off-by: Mary Guillemard <mary@mary.zone>
* Fix missing copy in create_app_bundle.sh
Signed-off-by: Mary Guillemard <mary@mary.zone>
* Fix syntax error
Signed-off-by: Mary Guillemard <mary@mary.zone>
---------
Signed-off-by: Mary Guillemard <mary@mary.zone>
Diffstat (limited to 'src/Ryujinx.Ava/UI/Applet')
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs | 204 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs | 162 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs | 41 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml | 145 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs | 140 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml | 54 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs | 74 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml | 67 | ||||
| -rw-r--r-- | src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs | 183 |
9 files changed, 0 insertions, 1070 deletions
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs deleted file mode 100644 index 4bcc35a7..00000000 --- a/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs +++ /dev/null @@ -1,204 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Threading; -using FluentAvalonia.UI.Controls; -using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Controls; -using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.Windows; -using Ryujinx.HLE; -using Ryujinx.HLE.HOS.Applets; -using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types; -using Ryujinx.HLE.UI; -using System; -using System.Threading; - -namespace Ryujinx.Ava.UI.Applet -{ - internal class AvaHostUIHandler : IHostUIHandler - { - private readonly MainWindow _parent; - - public IHostUITheme HostUITheme { get; } - - public AvaHostUIHandler(MainWindow parent) - { - _parent = parent; - - HostUITheme = new AvaloniaHostUITheme(parent); - } - - public bool DisplayMessageDialog(ControllerAppletUIArgs args) - { - ManualResetEvent dialogCloseEvent = new(false); - - bool okPressed = false; - - Dispatcher.UIThread.InvokeAsync(async () => - { - var response = await ControllerAppletDialog.ShowControllerAppletDialog(_parent, args); - if (response == UserResult.Ok) - { - okPressed = true; - } - - dialogCloseEvent.Set(); - }); - - dialogCloseEvent.WaitOne(); - - return okPressed; - } - - public bool DisplayMessageDialog(string title, string message) - { - ManualResetEvent dialogCloseEvent = new(false); - - bool okPressed = false; - - Dispatcher.UIThread.InvokeAsync(async () => - { - try - { - ManualResetEvent deferEvent = new(false); - - bool opened = false; - - UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent, - title, - message, - "", - LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel], - "", - LocaleManager.Instance[LocaleKeys.SettingsButtonClose], - (int)Symbol.Important, - deferEvent, - async window => - { - if (opened) - { - return; - } - - opened = true; - - _parent.SettingsWindow = new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager); - - await _parent.SettingsWindow.ShowDialog(window); - - _parent.SettingsWindow = null; - - opened = false; - }); - - if (response == UserResult.Ok) - { - okPressed = true; - } - - dialogCloseEvent.Set(); - } - catch (Exception ex) - { - await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex)); - - dialogCloseEvent.Set(); - } - }); - - dialogCloseEvent.WaitOne(); - - return okPressed; - } - - public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText) - { - ManualResetEvent dialogCloseEvent = new(false); - - bool okPressed = false; - bool error = false; - string inputText = args.InitialText ?? ""; - - Dispatcher.UIThread.InvokeAsync(async () => - { - try - { - var response = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args); - - if (response.Result == UserResult.Ok) - { - inputText = response.Input; - okPressed = true; - } - } - catch (Exception ex) - { - error = true; - - await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex)); - } - finally - { - dialogCloseEvent.Set(); - } - }); - - dialogCloseEvent.WaitOne(); - - userText = error ? null : inputText; - - return error || okPressed; - } - - public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value) - { - device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value); - _parent.ViewModel.AppHost?.Stop(); - } - - public bool DisplayErrorAppletDialog(string title, string message, string[] buttons) - { - ManualResetEvent dialogCloseEvent = new(false); - - bool showDetails = false; - - Dispatcher.UIThread.InvokeAsync(async () => - { - try - { - ErrorAppletWindow msgDialog = new(_parent, buttons, message) - { - Title = title, - WindowStartupLocation = WindowStartupLocation.CenterScreen, - Width = 400, - }; - - object response = await msgDialog.Run(); - - if (response != null && buttons != null && buttons.Length > 1 && (int)response != buttons.Length - 1) - { - showDetails = true; - } - - dialogCloseEvent.Set(); - - msgDialog.Close(); - } - catch (Exception ex) - { - dialogCloseEvent.Set(); - - await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex)); - } - }); - - dialogCloseEvent.WaitOne(); - - return showDetails; - } - - public IDynamicTextInputHandler CreateDynamicTextInputHandler() - { - return new AvaloniaDynamicTextInputHandler(_parent); - } - } -} diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs deleted file mode 100644 index 531d0061..00000000 --- a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs +++ /dev/null @@ -1,162 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Input; -using Avalonia.Threading; -using Ryujinx.Ava.Input; -using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.Windows; -using Ryujinx.HLE.UI; -using System; -using System.Threading; -using HidKey = Ryujinx.Common.Configuration.Hid.Key; - -namespace Ryujinx.Ava.UI.Applet -{ - class AvaloniaDynamicTextInputHandler : IDynamicTextInputHandler - { - private MainWindow _parent; - private readonly OffscreenTextBox _hiddenTextBox; - private bool _canProcessInput; - private IDisposable _textChangedSubscription; - private IDisposable _selectionStartChangedSubscription; - private IDisposable _selectionEndtextChangedSubscription; - - public AvaloniaDynamicTextInputHandler(MainWindow parent) - { - _parent = parent; - - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput += AvaloniaDynamicTextInputHandler_TextInput; - - _hiddenTextBox = _parent.HiddenTextBox; - - Dispatcher.UIThread.Post(() => - { - _textChangedSubscription = _hiddenTextBox.GetObservable(TextBox.TextProperty).Subscribe(TextChanged); - _selectionStartChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionStartProperty).Subscribe(SelectionChanged); - _selectionEndtextChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionEndProperty).Subscribe(SelectionChanged); - }); - } - - private void TextChanged(string text) - { - TextChangedEvent?.Invoke(text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, true); - } - - private void SelectionChanged(int selection) - { - if (_hiddenTextBox.SelectionEnd < _hiddenTextBox.SelectionStart) - { - _hiddenTextBox.SelectionStart = _hiddenTextBox.SelectionEnd; - } - - TextChangedEvent?.Invoke(_hiddenTextBox.Text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, true); - } - - private void AvaloniaDynamicTextInputHandler_TextInput(object sender, string text) - { - Dispatcher.UIThread.InvokeAsync(() => - { - if (_canProcessInput) - { - _hiddenTextBox.SendText(text); - } - }); - } - - private void AvaloniaDynamicTextInputHandler_KeyRelease(object sender, KeyEventArgs e) - { - var key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key); - - if (!(KeyReleasedEvent?.Invoke(key)).GetValueOrDefault(true)) - { - return; - } - - e.RoutedEvent = OffscreenTextBox.GetKeyUpRoutedEvent(); - - Dispatcher.UIThread.InvokeAsync(() => - { - if (_canProcessInput) - { - _hiddenTextBox.SendKeyUpEvent(e); - } - }); - } - - private void AvaloniaDynamicTextInputHandler_KeyPressed(object sender, KeyEventArgs e) - { - var key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key); - - if (!(KeyPressedEvent?.Invoke(key)).GetValueOrDefault(true)) - { - return; - } - - e.RoutedEvent = OffscreenTextBox.GetKeyUpRoutedEvent(); - - Dispatcher.UIThread.InvokeAsync(() => - { - if (_canProcessInput) - { - _hiddenTextBox.SendKeyDownEvent(e); - } - }); - } - - public bool TextProcessingEnabled - { - get - { - return Volatile.Read(ref _canProcessInput); - } - set - { - Volatile.Write(ref _canProcessInput, value); - } - } - - public event DynamicTextChangedHandler TextChangedEvent; - public event KeyPressedHandler KeyPressedEvent; - public event KeyReleasedHandler KeyReleasedEvent; - - public void Dispose() - { - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease; - (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput -= AvaloniaDynamicTextInputHandler_TextInput; - - _textChangedSubscription?.Dispose(); - _selectionStartChangedSubscription?.Dispose(); - _selectionEndtextChangedSubscription?.Dispose(); - - Dispatcher.UIThread.Post(() => - { - _hiddenTextBox.Clear(); - _parent.ViewModel.RendererHostControl.Focus(); - - _parent = null; - }); - } - - public void SetText(string text, int cursorBegin) - { - Dispatcher.UIThread.Post(() => - { - _hiddenTextBox.Text = text; - _hiddenTextBox.CaretIndex = cursorBegin; - }); - } - - public void SetText(string text, int cursorBegin, int cursorEnd) - { - Dispatcher.UIThread.Post(() => - { - _hiddenTextBox.Text = text; - _hiddenTextBox.SelectionStart = cursorBegin; - _hiddenTextBox.SelectionEnd = cursorEnd; - }); - } - } -} diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs deleted file mode 100644 index 016fb484..00000000 --- a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Avalonia.Media; -using Ryujinx.Ava.UI.Windows; -using Ryujinx.HLE.UI; -using System; - -namespace Ryujinx.Ava.UI.Applet -{ - class AvaloniaHostUITheme : IHostUITheme - { - public AvaloniaHostUITheme(MainWindow parent) - { - FontFamily = OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000) ? "Segoe UI Variable" : parent.FontFamily.Name; - DefaultBackgroundColor = BrushToThemeColor(parent.Background); - DefaultForegroundColor = BrushToThemeColor(parent.Foreground); - DefaultBorderColor = BrushToThemeColor(parent.BorderBrush); - SelectionBackgroundColor = BrushToThemeColor(parent.ViewControls.SearchBox.SelectionBrush); - SelectionForegroundColor = BrushToThemeColor(parent.ViewControls.SearchBox.SelectionForegroundBrush); - } - - public string FontFamily { get; } - - public ThemeColor DefaultBackgroundColor { get; } - public ThemeColor DefaultForegroundColor { get; } - public ThemeColor DefaultBorderColor { get; } - public ThemeColor SelectionBackgroundColor { get; } - public ThemeColor SelectionForegroundColor { get; } - - private static ThemeColor BrushToThemeColor(IBrush brush) - { - if (brush is SolidColorBrush solidColor) - { - return new ThemeColor((float)solidColor.Color.A / 255, - (float)solidColor.Color.R / 255, - (float)solidColor.Color.G / 255, - (float)solidColor.Color.B / 255); - } - - return new ThemeColor(); - } - } -} diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml deleted file mode 100644 index b2c22f6b..00000000 --- a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml +++ /dev/null @@ -1,145 +0,0 @@ -<UserControl - x:Class="Ryujinx.Ava.UI.Applet.ControllerAppletDialog" - 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:locale="clr-namespace:Ryujinx.Ava.Common.Locale" - xmlns:applet="using:Ryujinx.Ava.UI.Applet" - mc:Ignorable="d" - Width="400" - Focusable="True" - x:DataType="applet:ControllerAppletDialog"> - <Grid - HorizontalAlignment="Stretch" - VerticalAlignment="Stretch"> - <Grid.RowDefinitions> - <RowDefinition Height="Auto" /> - <RowDefinition Height="*" /> - <RowDefinition Height="Auto" /> - </Grid.RowDefinitions> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="*" /> - <ColumnDefinition Width="Auto" /> - </Grid.ColumnDefinitions> - <Border - Grid.Column="0" - Grid.Row="0" - Grid.ColumnSpan="2" - Margin="0 0 0 10" - BorderBrush="{DynamicResource ThemeControlBorderColor}" - BorderThickness="1" - CornerRadius="5"> - <StackPanel - Spacing="10" - Margin="10"> - <TextBlock - Text="{locale:Locale ControllerAppletDescription}" /> - <TextBlock - IsVisible="{Binding IsDocked}" - FontWeight="Bold" - Text="{locale:Locale ControllerAppletDocked}" /> - </StackPanel> - </Border> - <Border - Grid.Column="0" - Grid.Row="1" - BorderBrush="{DynamicResource ThemeControlBorderColor}" - BorderThickness="1" - CornerRadius="5" - Margin="0 0 10 0"> - <StackPanel - Margin="10" - Spacing="10" - Orientation="Vertical"> - <TextBlock - HorizontalAlignment="Center" - VerticalAlignment="Center" - TextAlignment="Center" - FontWeight="Bold" - Text="{locale:Locale ControllerAppletControllers}" /> - <StackPanel - Spacing="10" - HorizontalAlignment="Center" - VerticalAlignment="Center" - Orientation="Horizontal"> - <Image - Height="50" - Width="50" - Stretch="Uniform" - Source="{Binding ProControllerImage}" - IsVisible="{Binding SupportsProController}" /> - <Image - Height="50" - Width="50" - Stretch="Uniform" - Source="{Binding JoyconPairImage}" - IsVisible="{Binding SupportsJoyconPair}" /> - <Image - Height="50" - Width="50" - Stretch="Uniform" - Source="{Binding JoyconLeftImage}" - IsVisible="{Binding SupportsLeftJoycon}" /> - <Image - Height="50" - Width="50" - Stretch="Uniform" - Source="{Binding JoyconRightImage}" - IsVisible="{Binding SupportsRightJoycon}" /> - </StackPanel> - </StackPanel> - </Border> - <Border - Grid.Column="1" - Grid.Row="1" - BorderBrush="{DynamicResource ThemeControlBorderColor}" - BorderThickness="1" - CornerRadius="5"> - <StackPanel - Margin="10" - Spacing="10" - Orientation="Vertical"> - <TextBlock - HorizontalAlignment="Center" - VerticalAlignment="Center" - TextAlignment="Center" - FontWeight="Bold" - Text="{locale:Locale ControllerAppletPlayers}" /> - <Border Height="50"> - <TextBlock - HorizontalAlignment="Center" - VerticalAlignment="Center" - TextAlignment="Center" - FontSize="40" - FontWeight="Thin" - Text="{Binding PlayerCount}" /> - </Border> - </StackPanel> - </Border> - <Panel - Margin="0 24 0 0" - Grid.Column="0" - Grid.Row="2" - Grid.ColumnSpan="2"> - <StackPanel - Orientation="Horizontal" - Spacing="10" - HorizontalAlignment="Right"> - <Button - Name="SaveButton" - MinWidth="90" - Command="{Binding OpenSettingsWindow}"> - <TextBlock Text="{locale:Locale DialogOpenSettingsWindowLabel}" /> - </Button> - <Button - Name="CancelButton" - MinWidth="90" - Command="{Binding Close}"> - <TextBlock Text="{locale:Locale SettingsButtonClose}" /> - </Button> - </StackPanel> - </Panel> - </Grid> -</UserControl> - diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs deleted file mode 100644 index 279af07c..00000000 --- a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs +++ /dev/null @@ -1,140 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Styling; -using Avalonia.Svg.Skia; -using Avalonia.Threading; -using FluentAvalonia.UI.Controls; -using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.Windows; -using Ryujinx.Common; -using Ryujinx.HLE.HOS.Applets; -using Ryujinx.HLE.HOS.Services.Hid; -using System; -using System.Linq; -using System.Threading.Tasks; - -namespace Ryujinx.Ava.UI.Applet -{ - internal partial class ControllerAppletDialog : UserControl - { - private const string ProControllerResource = "Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg"; - private const string JoyConPairResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg"; - private const string JoyConLeftResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg"; - private const string JoyConRightResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg"; - - public static SvgImage ProControllerImage => GetResource(ProControllerResource); - public static SvgImage JoyconPairImage => GetResource(JoyConPairResource); - public static SvgImage JoyconLeftImage => GetResource(JoyConLeftResource); - public static SvgImage JoyconRightImage => GetResource(JoyConRightResource); - - public string PlayerCount { get; set; } = ""; - public bool SupportsProController { get; set; } - public bool SupportsLeftJoycon { get; set; } - public bool SupportsRightJoycon { get; set; } - public bool SupportsJoyconPair { get; set; } - public bool IsDocked { get; set; } - - private readonly MainWindow _mainWindow; - - public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUIArgs args) - { - if (args.PlayerCountMin == args.PlayerCountMax) - { - PlayerCount = args.PlayerCountMin.ToString(); - } - else - { - PlayerCount = $"{args.PlayerCountMin} - {args.PlayerCountMax}"; - } - - SupportsProController = (args.SupportedStyles & ControllerType.ProController) != 0; - SupportsLeftJoycon = (args.SupportedStyles & ControllerType.JoyconLeft) != 0; - SupportsRightJoycon = (args.SupportedStyles & ControllerType.JoyconRight) != 0; - SupportsJoyconPair = (args.SupportedStyles & ControllerType.JoyconPair) != 0; - - IsDocked = args.IsDocked; - - _mainWindow = mainWindow; - - DataContext = this; - - InitializeComponent(); - } - - public ControllerAppletDialog(MainWindow mainWindow) - { - _mainWindow = mainWindow; - DataContext = this; - - InitializeComponent(); - } - - public static async Task<UserResult> ShowControllerAppletDialog(MainWindow window, ControllerAppletUIArgs args) - { - ContentDialog contentDialog = new(); - UserResult result = UserResult.Cancel; - ControllerAppletDialog content = new(window, args); - - contentDialog.Title = LocaleManager.Instance[LocaleKeys.DialogControllerAppletTitle]; - contentDialog.Content = content; - - void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs) - { - if (eventArgs.Result == ContentDialogResult.Primary) - { - result = UserResult.Ok; - } - } - - contentDialog.Closed += Handler; - - Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>()); - bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false)); - - contentDialog.Styles.Add(bottomBorder); - - await ContentDialogHelper.ShowAsync(contentDialog); - - return result; - } - - private static SvgImage GetResource(string path) - { - SvgImage image = new(); - - if (!string.IsNullOrWhiteSpace(path)) - { - SvgSource source = new(default(Uri)); - - source.Load(EmbeddedResources.GetStream(path)); - - image.Source = source; - } - - return image; - } - - public void OpenSettingsWindow() - { - if (_mainWindow.SettingsWindow == null) - { - Dispatcher.UIThread.InvokeAsync(async () => - { - _mainWindow.SettingsWindow = new SettingsWindow(_mainWindow.VirtualFileSystem, _mainWindow.ContentManager); - _mainWindow.SettingsWindow.NavPanel.Content = _mainWindow.SettingsWindow.InputPage; - _mainWindow.SettingsWindow.NavPanel.SelectedItem = _mainWindow.SettingsWindow.NavPanel.MenuItems.ElementAt(1); - - await ContentDialogHelper.ShowWindowAsync(_mainWindow.SettingsWindow, _mainWindow); - _mainWindow.SettingsWindow = null; - this.Close(); - }); - } - } - - public void Close() - { - ((ContentDialog)Parent)?.Hide(); - } - } -} - diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml deleted file mode 100644 index 51f37051..00000000 --- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml +++ /dev/null @@ -1,54 +0,0 @@ -<Window - x:Class="Ryujinx.Ava.UI.Applet.ErrorAppletWindow" - xmlns="https://github.com/avaloniaui" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - Title="{locale:Locale ErrorWindowTitle}" - xmlns:views="using:Ryujinx.Ava.UI.Applet" - Width="450" - Height="340" - CanResize="False" - x:DataType="views:ErrorAppletWindow" - SizeToContent="Height" - mc:Ignorable="d" - Focusable="True"> - <Grid - Margin="20" - HorizontalAlignment="Stretch" - VerticalAlignment="Stretch"> - <Grid.RowDefinitions> - <RowDefinition Height="Auto" /> - <RowDefinition Height="*" /> - <RowDefinition Height="Auto" /> - </Grid.RowDefinitions> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="Auto" /> - <ColumnDefinition /> - </Grid.ColumnDefinitions> - <Image - Grid.Row="1" - Grid.RowSpan="2" - Grid.Column="0" - Height="80" - MinWidth="50" - Margin="5,10,20,10" - Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" /> - <TextBlock - Grid.Row="1" - Grid.Column="1" - Margin="10" - VerticalAlignment="Stretch" - Text="{Binding Message}" - TextWrapping="Wrap" /> - <StackPanel - Name="ButtonStack" - Grid.Row="2" - Grid.Column="1" - Margin="10" - HorizontalAlignment="Right" - Orientation="Horizontal" - Spacing="10" /> - </Grid> -</Window> diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs deleted file mode 100644 index ec6f7682..00000000 --- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Threading; -using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Windows; -using System.Threading.Tasks; - -namespace Ryujinx.Ava.UI.Applet -{ - internal partial class ErrorAppletWindow : StyleableWindow - { - private readonly Window _owner; - private object _buttonResponse; - - public ErrorAppletWindow(Window owner, string[] buttons, string message) - { - _owner = owner; - Message = message; - DataContext = this; - InitializeComponent(); - - int responseId = 0; - - if (buttons != null) - { - foreach (string buttonText in buttons) - { - AddButton(buttonText, responseId); - responseId++; - } - } - else - { - AddButton(LocaleManager.Instance[LocaleKeys.InputDialogOk], 0); - } - } - - public ErrorAppletWindow() - { - DataContext = this; - InitializeComponent(); - } - - public string Message { get; set; } - - private void AddButton(string label, object tag) - { - Dispatcher.UIThread.InvokeAsync(() => - { - Button button = new() { Content = label, Tag = tag }; - - button.Click += Button_Click; - ButtonStack.Children.Add(button); - }); - } - - private void Button_Click(object sender, RoutedEventArgs e) - { - if (sender is Button button) - { - _buttonResponse = button.Tag; - } - - Close(); - } - - public async Task<object> Run() - { - await ShowDialog(_owner); - - return _buttonResponse; - } - } -} diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml deleted file mode 100644 index b1c84734..00000000 --- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml +++ /dev/null @@ -1,67 +0,0 @@ -<UserControl - x:Class="Ryujinx.Ava.UI.Controls.SwkbdAppletDialog" - 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:views="using:Ryujinx.Ava.UI.Controls" - Width="400" - x:DataType="views:SwkbdAppletDialog" - mc:Ignorable="d" - Focusable="True"> - <Grid - Margin="20" - HorizontalAlignment="Stretch" - VerticalAlignment="Stretch"> - <Grid.RowDefinitions> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - </Grid.RowDefinitions> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="Auto" /> - <ColumnDefinition /> - </Grid.ColumnDefinitions> - <Image - Grid.Row="1" - Grid.RowSpan="5" - Height="80" - MinWidth="50" - Margin="5,10,20,10" - VerticalAlignment="Center" - Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" /> - <TextBlock - Grid.Row="1" - Grid.Column="1" - Margin="5" - Text="{Binding MainText}" - TextWrapping="Wrap" /> - <TextBlock - Grid.Row="2" - Grid.Column="1" - Margin="5" - Text="{Binding SecondaryText}" - TextWrapping="Wrap" /> - <TextBox - Name="Input" - Grid.Row="3" - Grid.Column="1" - HorizontalAlignment="Stretch" - VerticalAlignment="Center" - Focusable="True" - KeyUp="Message_KeyUp" - Text="{Binding Message}" - TextInput="Message_TextInput" - TextWrapping="Wrap" - UseFloatingWatermark="True" /> - <TextBlock - Name="Error" - Grid.Row="4" - Grid.Column="1" - Margin="5" - HorizontalAlignment="Stretch" - TextWrapping="Wrap" /> - </Grid> -</UserControl> diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs deleted file mode 100644 index af3837e4..00000000 --- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs +++ /dev/null @@ -1,183 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Input; -using Avalonia.Interactivity; -using Avalonia.Media; -using FluentAvalonia.UI.Controls; -using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Helpers; -using Ryujinx.HLE.HOS.Applets; -using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard; -using System; -using System.Linq; -using System.Threading.Tasks; - -namespace Ryujinx.Ava.UI.Controls -{ - internal partial class SwkbdAppletDialog : UserControl - { - private Predicate<int> _checkLength = _ => true; - private Predicate<string> _checkInput = _ => true; - private int _inputMax; - private int _inputMin; - private readonly string _placeholder; - - private ContentDialog _host; - - public SwkbdAppletDialog(string mainText, string secondaryText, string placeholder, string message) - { - MainText = mainText; - SecondaryText = secondaryText; - Message = message ?? ""; - DataContext = this; - _placeholder = placeholder; - InitializeComponent(); - - Input.Watermark = _placeholder; - - Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true); - } - - public SwkbdAppletDialog() - { - DataContext = this; - InitializeComponent(); - } - - protected override void OnGotFocus(GotFocusEventArgs e) - { - // FIXME: This does not work. Might be a bug in Avalonia with DialogHost - // Currently focus will be redirected to the overlay window instead. - Input.Focus(); - } - - public string Message { get; set; } = ""; - public string MainText { get; set; } = ""; - public string SecondaryText { get; set; } = ""; - - public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, SoftwareKeyboardUIArgs args) - { - ContentDialog contentDialog = new(); - - UserResult result = UserResult.Cancel; - - SwkbdAppletDialog content = new(args.HeaderText, args.SubtitleText, args.GuideText, args.InitialText); - - string input = string.Empty; - - content.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax); - content.SetInputValidation(args.KeyboardMode); - - content._host = contentDialog; - contentDialog.Title = title; - contentDialog.PrimaryButtonText = args.SubmitText; - contentDialog.IsPrimaryButtonEnabled = content._checkLength(content.Message.Length); - contentDialog.SecondaryButtonText = ""; - contentDialog.CloseButtonText = LocaleManager.Instance[LocaleKeys.InputDialogCancel]; - contentDialog.Content = content; - - void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs) - { - if (eventArgs.Result == ContentDialogResult.Primary) - { - result = UserResult.Ok; - input = content.Input.Text; - } - } - - contentDialog.Closed += Handler; - - await ContentDialogHelper.ShowAsync(contentDialog); - - return (result, input); - } - - private void ApplyValidationInfo(string text) - { - Error.IsVisible = !string.IsNullOrEmpty(text); - Error.Text = text; - } - - public void SetInputLengthValidation(int min, int max) - { - _inputMin = Math.Min(min, max); - _inputMax = Math.Max(min, max); - - Error.IsVisible = false; - Error.FontStyle = FontStyle.Italic; - - string validationInfoText = ""; - - if (_inputMin <= 0 && _inputMax == int.MaxValue) // Disable. - { - Error.IsVisible = false; - - _checkLength = length => true; - } - else if (_inputMin > 0 && _inputMax == int.MaxValue) - { - validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinCharacters, _inputMin); - - _checkLength = length => _inputMin <= length; - } - else - { - validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinRangeCharacters, _inputMin, _inputMax); - - _checkLength = length => _inputMin <= length && length <= _inputMax; - } - - ApplyValidationInfo(validationInfoText); - Message_TextInput(this, new TextInputEventArgs()); - } - - private void SetInputValidation(KeyboardMode mode) - { - string validationInfoText = Error.Text; - string localeText; - switch (mode) - { - case KeyboardMode.Numeric: - localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeNumeric); - validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText); - _checkInput = text => text.All(NumericCharacterValidation.IsNumeric); - break; - case KeyboardMode.Alphabet: - localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet); - validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText); - _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value)); - break; - case KeyboardMode.ASCII: - localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII); - validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText); - _checkInput = text => text.All(char.IsAscii); - break; - default: - _checkInput = _ => true; - break; - } - - ApplyValidationInfo(validationInfoText); - Message_TextInput(this, new TextInputEventArgs()); - } - - private void Message_TextInput(object sender, TextInputEventArgs e) - { - if (_host != null) - { - _host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message); - } - } - - private void Message_KeyUp(object sender, KeyEventArgs e) - { - if (e.Key == Key.Enter && _host.IsPrimaryButtonEnabled) - { - _host.Hide(ContentDialogResult.Primary); - } - else - { - _host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message); - } - } - } -} |
