UI - Avalonia Part 2 (#3351)
* add settings windows and children views * Expose hotkeys configuration on the UI * Remove double spacing from locale JSON * simplify button assigner * add cemuhook buttons and title to locale * move common button assigner to own class * cancel button assigner when window is closed * remove unused setting * address review. fix controller profile not loading default when switching devices * fix updater file name * Input cleanup (#37) * addressed review * add device type to controller device checks * change accessibility modifier of public classes to internal * Update Ryujinx.Ava/Ui/ViewModels/ControllerSettingsViewModel.cs Co-authored-by: gdkchan <gab.dark.100@gmail.com> * Update de_DE.json * Update de_DE.json * Update tr_TR.json Translated newly added lines * Update it_IT.json * fix rebase * update avalonia * fix wrong key used for button text * Align settings window elements * Tabs to spaces * Update brazilian portuguese translation * Minor improvement on brazilian portuguese translation * fix turkish translation * remove unused text * change view related classes to public * unsubscribe from deferred event if dialog is closed * Load the default language before loading any other when switching languages * Make controller settings more compact * increase default width of settings window, reduce profile buttons width Co-authored-by: gdk <gab.dark.100@gmail.com> Co-authored-by: MutantAura <44103205+MutantAura@users.noreply.github.com> Co-authored-by: Niwu34 <67392333+Niwu34@users.noreply.github.com> Co-authored-by: aegiff <99728970+aegiff@users.noreply.github.com> Co-authored-by: Antonio Brugnolo <36473846+AntoSkate@users.noreply.github.com>
This commit is contained in:
@@ -5,7 +5,7 @@ using System.Runtime.Versioning;
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
[SupportedOSPlatform("linux")]
|
||||
public class AvaloniaGlxContext : SPB.Platform.GLX.GLXOpenGLContext
|
||||
internal class AvaloniaGlxContext : SPB.Platform.GLX.GLXOpenGLContext
|
||||
{
|
||||
public AvaloniaGlxContext(IntPtr handle)
|
||||
: base(FramebufferFormat.Default, 0, 0, 0, false, null)
|
||||
|
@@ -5,7 +5,7 @@ using System.Runtime.Versioning;
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class AvaloniaWglContext : SPB.Platform.WGL.WGLOpenGLContext
|
||||
internal class AvaloniaWglContext : SPB.Platform.WGL.WGLOpenGLContext
|
||||
{
|
||||
public AvaloniaWglContext(IntPtr handle)
|
||||
: base(FramebufferFormat.Default, 0, 0, 0, false, null)
|
||||
|
@@ -7,7 +7,7 @@ using System.IO;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public class BitmapArrayValueConverter : IValueConverter
|
||||
internal class BitmapArrayValueConverter : IValueConverter
|
||||
{
|
||||
public static BitmapArrayValueConverter Instance = new();
|
||||
|
||||
|
118
Ryujinx.Ava/Ui/Controls/ButtonKeyAssigner.cs
Normal file
118
Ryujinx.Ava/Ui/Controls/ButtonKeyAssigner.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Threading;
|
||||
using Ryujinx.Input;
|
||||
using Ryujinx.Input.Assigner;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
internal class ButtonKeyAssigner
|
||||
{
|
||||
internal class ButtonAssignedEventArgs : EventArgs
|
||||
{
|
||||
public ToggleButton Button { get; }
|
||||
public bool IsAssigned { get; }
|
||||
|
||||
public ButtonAssignedEventArgs(ToggleButton button, bool isAssigned)
|
||||
{
|
||||
Button = button;
|
||||
IsAssigned = isAssigned;
|
||||
}
|
||||
}
|
||||
|
||||
public ToggleButton ToggledButton { get; set; }
|
||||
|
||||
private bool _isWaitingForInput;
|
||||
private bool _shouldUnbind;
|
||||
public event EventHandler<ButtonAssignedEventArgs> ButtonAssigned;
|
||||
|
||||
public ButtonKeyAssigner(ToggleButton toggleButton)
|
||||
{
|
||||
ToggledButton = toggleButton;
|
||||
}
|
||||
|
||||
public async void GetInputAndAssign(IButtonAssigner assigner, IKeyboard keyboard = null)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
ToggledButton.IsChecked = true;
|
||||
});
|
||||
|
||||
if (_isWaitingForInput)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
Cancel();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_isWaitingForInput = true;
|
||||
|
||||
assigner.Initialize();
|
||||
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (!_isWaitingForInput)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.Delay(10);
|
||||
|
||||
assigner.ReadInput();
|
||||
|
||||
if (assigner.HasAnyButtonPressed() || assigner.ShouldCancel() || (keyboard != null && keyboard.IsPressed(Key.Escape)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
string pressedButton = assigner.GetPressedButton();
|
||||
|
||||
if (_shouldUnbind)
|
||||
{
|
||||
SetButtonText(ToggledButton, "Unbound");
|
||||
}
|
||||
else if (pressedButton != "")
|
||||
{
|
||||
SetButtonText(ToggledButton, pressedButton);
|
||||
}
|
||||
|
||||
_shouldUnbind = false;
|
||||
_isWaitingForInput = false;
|
||||
|
||||
ToggledButton.IsChecked = false;
|
||||
|
||||
ButtonAssigned?.Invoke(this, new ButtonAssignedEventArgs(ToggledButton, pressedButton != null));
|
||||
|
||||
static void SetButtonText(ToggleButton button, string text)
|
||||
{
|
||||
ILogical textBlock = button.GetLogicalDescendants().First(x => x is TextBlock);
|
||||
|
||||
if (textBlock != null && textBlock is TextBlock block)
|
||||
{
|
||||
block.Text = text;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Cancel(bool shouldUnbind = false)
|
||||
{
|
||||
_isWaitingForInput = false;
|
||||
ToggledButton.IsChecked = false;
|
||||
_shouldUnbind = shouldUnbind;
|
||||
}
|
||||
}
|
||||
}
|
@@ -97,10 +97,12 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
});
|
||||
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
|
||||
{
|
||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
||||
result = UserResult.No;
|
||||
});
|
||||
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
|
||||
{
|
||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
||||
result = UserResult.Cancel;
|
||||
});
|
||||
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
|
||||
@@ -115,6 +117,8 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
return;
|
||||
}
|
||||
|
||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
||||
|
||||
startedDeferring = true;
|
||||
|
||||
var deferral = args.GetDeferral();
|
||||
|
@@ -4,7 +4,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public static class IGlContextExtension
|
||||
internal static class IGlContextExtension
|
||||
{
|
||||
public static OpenGLContextBase AsOpenGLContextBase(this IGlContext context)
|
||||
{
|
||||
|
@@ -6,7 +6,7 @@ using System.Globalization;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public class KeyValueConverter : IValueConverter
|
||||
internal class KeyValueConverter : IValueConverter
|
||||
{
|
||||
public static KeyValueConverter Instance = new();
|
||||
|
||||
|
@@ -3,7 +3,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public class OpenToolkitBindingsContext : IBindingsContext
|
||||
internal class OpenToolkitBindingsContext : IBindingsContext
|
||||
{
|
||||
private readonly Func<string, IntPtr> _getProcAddress;
|
||||
|
||||
|
@@ -18,7 +18,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public class RendererControl : Control
|
||||
internal class RendererControl : Control
|
||||
{
|
||||
private int _image;
|
||||
|
||||
|
Reference in New Issue
Block a user