aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Ava/UI/Views
diff options
context:
space:
mode:
authorIsaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>2023-05-22 00:16:20 +0100
committerGitHub <noreply@github.com>2023-05-22 01:16:20 +0200
commitb53e7ffd46b5c4ac5c4ac3dcc24385b2c9dc4fa4 (patch)
treee2579164c7c81ab47413d30663224fbbd75e024b /src/Ryujinx.Ava/UI/Views
parentac66643346df76561ff85be741e2998290d43646 (diff)
Ava UI: Input Menu Redesign (#4990)
* Cleanup * Remove redundant locales * Start SVG Fixes… Better +/- buttons Fix the grips Bumpers Better directional pad More SVG stuff Grip adjustments Final stuff * Make image bigger * Border radius * More cleanup * Restructure * Restructure Rumble View * Use compiled bindings where possible * Round those pesky corners * Ack Suggestions * More suggestions * Update src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> --------- Co-authored-by: Ac_K <Acoustik666@gmail.com>
Diffstat (limited to 'src/Ryujinx.Ava/UI/Views')
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml1124
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs180
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml169
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs68
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml60
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs58
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml70
7 files changed, 1705 insertions, 24 deletions
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
new file mode 100644
index 00000000..2395b353
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
@@ -0,0 +1,1124 @@
+<UserControl
+ xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
+ xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
+ xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
+ xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ d:DesignHeight="800"
+ d:DesignWidth="800"
+ x:Class="Ryujinx.Ava.UI.Views.Input.ControllerInputView"
+ x:DataType="viewModels:ControllerInputViewModel"
+ x:CompileBindings="True"
+ mc:Ignorable="d"
+ Focusable="True">
+ <Design.DataContext>
+ <viewModels:ControllerInputViewModel />
+ </Design.DataContext>
+ <UserControl.Resources>
+ <helpers:KeyValueConverter x:Key="Key" />
+ </UserControl.Resources>
+ <UserControl.Styles>
+ <Style Selector="ToggleButton">
+ <Setter Property="Width" Value="90" />
+ <Setter Property="Height" Value="27" />
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
+ </Style>
+ </UserControl.Styles>
+ <StackPanel
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ Orientation="Vertical">
+ <StackPanel
+ Margin="0 0 0 5"
+ Orientation="Vertical"
+ Spacing="5">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="10" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <!-- Player Selection -->
+ <Grid
+ Grid.Column="0"
+ Margin="2"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <TextBlock
+ Margin="5,0,10,0"
+ Width="90"
+ HorizontalAlignment="Left"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsPlayer}" />
+ <ComboBox
+ Grid.Column="1"
+ Name="PlayerIndexBox"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center"
+ SelectionChanged="PlayerIndexBox_OnSelectionChanged"
+ Items="{Binding PlayerIndexes}"
+ SelectedIndex="{Binding PlayerId}">
+ <ComboBox.ItemTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Name}" />
+ </DataTemplate>
+ </ComboBox.ItemTemplate>
+ </ComboBox>
+ </Grid>
+ <!-- Profile Selection -->
+ <Grid
+ Grid.Column="2"
+ Margin="2"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <TextBlock
+ Margin="5,0,10,0"
+ Width="90"
+ HorizontalAlignment="Left"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsProfile}" />
+ <ui:ComboBox
+ Grid.Column="1"
+ IsEditable="True"
+ Name="ProfileBox"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center"
+ SelectedIndex="0"
+ Items="{Binding ProfilesList}"
+ Text="{Binding ProfileName}" />
+ <Button
+ Grid.Column="2"
+ MinWidth="0"
+ Margin="5,0,0,0"
+ VerticalAlignment="Center"
+ ToolTip.Tip="{locale:Locale ControllerSettingsLoadProfileToolTip}"
+ Command="{ReflectionBinding LoadProfile}">
+ <ui:SymbolIcon
+ Symbol="Upload"
+ FontSize="15"
+ Height="20" />
+ </Button>
+ <Button
+ Grid.Column="3"
+ MinWidth="0"
+ Margin="5,0,0,0"
+ VerticalAlignment="Center"
+ ToolTip.Tip="{locale:Locale ControllerSettingsSaveProfileToolTip}"
+ Command="{ReflectionBinding SaveProfile}">
+ <ui:SymbolIcon
+ Symbol="Save"
+ FontSize="15"
+ Height="20" />
+ </Button>
+ <Button
+ Grid.Column="4"
+ MinWidth="0"
+ Margin="5,0,0,0"
+ VerticalAlignment="Center"
+ ToolTip.Tip="{locale:Locale ControllerSettingsRemoveProfileToolTip}"
+ Command="{ReflectionBinding RemoveProfile}">
+ <ui:SymbolIcon
+ Symbol="Delete"
+ FontSize="15"
+ Height="20" />
+ </Button>
+ </Grid>
+ </Grid>
+ <Separator />
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="10" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <!-- Input Device -->
+ <Grid
+ Grid.Column="0"
+ Margin="2"
+ HorizontalAlignment="Stretch">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*"/>
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <TextBlock
+ Grid.Column="0"
+ Margin="5,0,10,0"
+ Width="90"
+ HorizontalAlignment="Left"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsInputDevice}" />
+ <ComboBox
+ Grid.Column="1"
+ Name="DeviceBox"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center"
+ Items="{Binding DeviceList}"
+ SelectedIndex="{Binding Device}" />
+ <Button
+ Grid.Column="2"
+ MinWidth="0"
+ Margin="5,0,0,0"
+ VerticalAlignment="Center"
+ Command="{ReflectionBinding LoadDevices}">
+ <ui:SymbolIcon
+ Symbol="Refresh"
+ FontSize="15"
+ Height="20"/>
+ </Button>
+ </Grid>
+ <!-- Controller Type -->
+ <Grid
+ Grid.Column="2"
+ Margin="2"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <TextBlock
+ Margin="5,0,10,0"
+ Width="90"
+ HorizontalAlignment="Left"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsControllerType}" />
+ <ComboBox
+ Grid.Column="1"
+ HorizontalAlignment="Stretch"
+ Items="{ReflectionBinding Controllers}"
+ SelectedIndex="{ReflectionBinding Controller}">
+ <ComboBox.ItemTemplate>
+ <DataTemplate DataType="models:ControllerModel">
+ <TextBlock Text="{Binding Name}" />
+ </DataTemplate>
+ </ComboBox.ItemTemplate>
+ </ComboBox>
+ </Grid>
+ </Grid>
+ </StackPanel>
+ <!-- Button / JoyStick Settings -->
+ <Grid
+ Name="SettingButtons"
+ MinHeight="450"
+ IsVisible="{Binding ShowSettings}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <!-- Left Controls -->
+ <StackPanel
+ Orientation="Vertical"
+ Margin="0,0,5,0"
+ Grid.Column="0">
+ <!-- Left Triggers -->
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ IsVisible="{Binding IsLeft}"
+ MinHeight="90"
+ CornerRadius="5">
+ <Grid
+ Margin="10"
+ HorizontalAlignment="Stretch">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition />
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <StackPanel
+ Grid.Column="0"
+ Grid.Row="0"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsTriggerZL}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonZl, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <StackPanel
+ Grid.Column="0"
+ Grid.Row="1"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsTriggerL}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonL, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <StackPanel
+ Grid.Column="1"
+ Grid.Row="1"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsButtonMinus}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonMinus, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ </Grid>
+ </Border>
+ <!-- Left Joystick -->
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ IsVisible="{Binding IsLeft}"
+ Margin="0,5,0,0"
+ CornerRadius="5">
+ <StackPanel
+ Margin="10"
+ Orientation="Vertical">
+ <TextBlock
+ Margin="0,0,0,10"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsLStick}" />
+ <!-- Left Joystick Keyboard -->
+ <StackPanel
+ IsVisible="{Binding !IsController}"
+ Orientation="Vertical">
+ <!-- Left Joystick Button -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickButton}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftKeyboardStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left Joystick Up -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickUp}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftStickUp, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left Joystick Down -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickDown}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftStickDown, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left Joystick Left -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickLeft}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftStickLeft, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left Joystick Right -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickRight}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftStickRight, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ </StackPanel>
+ <!-- Left Joystick Controller -->
+ <StackPanel
+ IsVisible="{Binding IsController}"
+ Orientation="Vertical">
+ <!-- Left Joystick Button -->
+ <StackPanel
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickButton}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftControllerStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left Joystick Stick -->
+ <StackPanel
+ Margin="0,4,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickStick}"
+ TextAlignment="Center" />
+ <ToggleButton Tag="stick">
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftJoystick, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <Separator
+ Margin="0,8,0,8"
+ Height="1" />
+ <CheckBox IsChecked="{ReflectionBinding Configuration.LeftInvertStickX}">
+ <TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
+ </CheckBox>
+ <CheckBox IsChecked="{ReflectionBinding Configuration.LeftInvertStickY}">
+ <TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
+ </CheckBox>
+ <CheckBox IsChecked="{ReflectionBinding Configuration.LeftRotate90}">
+ <TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
+ </CheckBox>
+ <Separator
+ Margin="0,8,0,8"
+ Height="1" />
+ <StackPanel Orientation="Vertical">
+ <TextBlock
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickDeadzone}" />
+ <StackPanel
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Horizontal">
+ <Slider
+ Width="130"
+ Maximum="1"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Minimum="0"
+ Value="{ReflectionBinding Configuration.DeadzoneLeft, Mode=TwoWay}" />
+ <TextBlock
+ VerticalAlignment="Center"
+ Width="25"
+ Text="{ReflectionBinding Configuration.DeadzoneLeft, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ <TextBlock
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickRange}" />
+ <StackPanel
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Horizontal">
+ <Slider
+ Width="130"
+ Maximum="2"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Minimum="0"
+ Value="{ReflectionBinding Configuration.RangeLeft, Mode=TwoWay}" />
+ <TextBlock
+ VerticalAlignment="Center"
+ Width="25"
+ Text="{ReflectionBinding Configuration.RangeLeft, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ </StackPanel>
+ </StackPanel>
+ </StackPanel>
+ </Border>
+ <!-- Left DPad -->
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ VerticalAlignment="Top"
+ IsVisible="{Binding IsLeft}"
+ Margin="0,5,0,0"
+ CornerRadius="5">
+ <StackPanel
+ Margin="10"
+ Orientation="Vertical">
+ <TextBlock
+ Margin="0,0,0,10"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsDPad}" />
+ <StackPanel Orientation="Vertical">
+ <!-- Left DPad Up -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsDPadUp}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.DpadUp, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left DPad Down -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsDPadDown}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.DpadDown, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left DPad Left -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsDPadLeft}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.DpadLeft, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Left DPad Right -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsDPadRight}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.DpadRight, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ </StackPanel>
+ </StackPanel>
+ </Border>
+ </StackPanel>
+ <!-- Triggers & Side Buttons -->
+ <StackPanel
+ Grid.Column="1"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch">
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ CornerRadius="5"
+ MinHeight="90">
+ <StackPanel
+ Margin="8"
+ Orientation="Vertical">
+ <TextBlock
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsTriggerThreshold}" />
+ <StackPanel
+ HorizontalAlignment="Center"
+ Orientation="Horizontal">
+ <Slider
+ Width="130"
+ Maximum="1"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Minimum="0"
+ Value="{ReflectionBinding Configuration.TriggerThreshold, Mode=TwoWay}" />
+ <TextBlock
+ Width="25"
+ Text="{ReflectionBinding Configuration.TriggerThreshold, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ <StackPanel
+ Margin="0,4,0,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ IsVisible="{Binding !IsRight}"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsLeftSR}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftButtonSr, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <StackPanel
+ Margin="0,4,0,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ IsVisible="{Binding !IsRight}"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsLeftSL}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.LeftButtonSl, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <StackPanel
+ Margin="0,4,0,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ IsVisible="{Binding !IsLeft}"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsRightSR}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightButtonSr, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <StackPanel
+ Margin="0,4,0,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ IsVisible="{Binding !IsLeft}"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsRightSL}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightButtonSl, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ </StackPanel>
+ </Border>
+ <!-- Controller Picture -->
+ <Image
+ Margin="0,10,0,0"
+ MaxHeight="300"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ Source="{Binding Image}" />
+ <!-- Motion + Rumble -->
+ <StackPanel
+ Margin="0,10,0,0"
+ Spacing="5"
+ Orientation="Vertical"
+ VerticalAlignment="Bottom">
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ CornerRadius="5"
+ VerticalAlignment="Bottom"
+ HorizontalAlignment="Stretch"
+ IsVisible="{Binding IsController}">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <CheckBox
+ Margin="10"
+ MinWidth="0"
+ Grid.Column="0"
+ IsChecked="{ReflectionBinding Configuration.EnableMotion, Mode=TwoWay}">
+ <TextBlock Text="{locale:Locale ControllerSettingsMotion}" />
+ </CheckBox>
+ <Button
+ Margin="10"
+ Grid.Column="1"
+ Command="{ReflectionBinding ShowMotionConfig}">
+ <TextBlock Text="{locale:Locale ControllerSettingsConfigureGeneral}" />
+ </Button>
+ </Grid>
+ </Border>
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ CornerRadius="5"
+ HorizontalAlignment="Stretch"
+ IsVisible="{Binding IsController}"
+ Margin="0,-1,0,0">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <CheckBox
+ Margin="10"
+ MinWidth="0"
+ Grid.Column="0"
+ IsChecked="{ReflectionBinding Configuration.EnableRumble, Mode=TwoWay}">
+ <TextBlock Text="{locale:Locale ControllerSettingsRumble}" />
+ </CheckBox>
+ <Button
+ Margin="10"
+ Grid.Column="1"
+ Command="{ReflectionBinding ShowRumbleConfig}">
+ <TextBlock Text="{locale:Locale ControllerSettingsConfigureGeneral}" />
+ </Button>
+ </Grid>
+ </Border>
+ </StackPanel>
+ </StackPanel>
+ <!-- Right Controls -->
+ <StackPanel
+ Orientation="Vertical"
+ Margin="5,0,0,0"
+ Grid.Column="2">
+ <!-- Right Triggers -->
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ IsVisible="{Binding IsRight}"
+ MinHeight="90"
+ CornerRadius="5">
+ <Grid
+ Margin="10"
+ HorizontalAlignment="Stretch">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition />
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <StackPanel
+ Grid.Column="1"
+ Grid.Row="0"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsTriggerZR}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonZr, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <StackPanel
+ Grid.Column="1"
+ Grid.Row="1"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsTriggerR}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonR, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <StackPanel
+ Grid.Column="0"
+ Grid.Row="1"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="20"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsButtonPlus}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonPlus, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ </Grid>
+ </Border>
+ <!-- Right Joystick -->
+ <Border
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ IsVisible="{Binding IsRight}"
+ Margin="0,5,0,0"
+ CornerRadius="5">
+ <StackPanel
+ Margin="10"
+ Orientation="Vertical">
+ <TextBlock
+ Margin="0,0,0,10"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsButtons}" />
+ <StackPanel
+ Orientation="Vertical">
+ <!-- Right Buttons A -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="120"
+ Margin="0,0,10,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsButtonA}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonA, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Buttons B -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="120"
+ Margin="0,0,10,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsButtonB}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonB, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Buttons X -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="120"
+ Margin="0,0,10,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsButtonX}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonX, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Buttons Y -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Width="120"
+ Margin="0,0,10,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsButtonY}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.ButtonY, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ </StackPanel>
+ </StackPanel>
+ </Border>
+ <!-- Right DPad -->
+ <Border
+ Padding="10"
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ CornerRadius="5"
+ IsVisible="{Binding IsRight}"
+ Margin="0,5,0,0">
+ <StackPanel Orientation="Vertical">
+ <TextBlock
+ Margin="0,0,0,10"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsRStick}" />
+ <!-- Right Joystick Keyboard -->
+ <StackPanel
+ IsVisible="{Binding !IsController}"
+ Orientation="Vertical">
+ <!-- Right Joystick Button -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickButton}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightKeyboardStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Joystick Up -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickUp}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightStickUp, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Joystick Down -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickDown}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightStickDown, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Joystick Left -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickLeft}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightStickLeft, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Joystick Right -->
+ <StackPanel
+ Margin="0,0,0,4"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickRight}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightStickRight, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ </StackPanel>
+ <!-- Right Joystick Controller -->
+ <StackPanel
+ IsVisible="{Binding IsController}"
+ Orientation="Vertical">
+ <!-- Right Joystick Button -->
+ <StackPanel
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickButton}"
+ TextAlignment="Center" />
+ <ToggleButton>
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightControllerStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <!-- Right Joystick Stick -->
+ <StackPanel
+ Margin="0,4,0,4"
+ Background="{DynamicResource ThemeDarkColor}"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="0,0,10,0"
+ Width="120"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickStick}"
+ TextAlignment="Center" />
+ <ToggleButton Tag="stick">
+ <TextBlock
+ Text="{ReflectionBinding Configuration.RightJoystick, Mode=TwoWay, Converter={StaticResource Key}}"
+ TextAlignment="Center" />
+ </ToggleButton>
+ </StackPanel>
+ <Separator Margin="0,8,0,8" Height="1" />
+ <CheckBox IsChecked="{ReflectionBinding Configuration.RightInvertStickX}">
+ <TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
+ </CheckBox>
+ <CheckBox IsChecked="{ReflectionBinding Configuration.RightInvertStickY}">
+ <TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
+ </CheckBox>
+ <CheckBox IsChecked="{ReflectionBinding Configuration.RightRotate90}">
+ <TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
+ </CheckBox>
+ <Separator Margin="0,8,0,8" Height="1" />
+ <StackPanel Orientation="Vertical">
+ <TextBlock
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickDeadzone}" />
+ <StackPanel
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Horizontal">
+ <Slider
+ Width="130"
+ Maximum="1"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Padding="0"
+ VerticalAlignment="Center"
+ Minimum="0"
+ Value="{ReflectionBinding Configuration.DeadzoneRight, Mode=TwoWay}" />
+ <TextBlock
+ VerticalAlignment="Center"
+ Width="25"
+ Text="{ReflectionBinding Configuration.DeadzoneRight, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ <TextBlock
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsStickRange}" />
+ <StackPanel
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Horizontal">
+ <Slider
+ Width="130"
+ Maximum="2"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Minimum="0"
+ Value="{ReflectionBinding Configuration.RangeRight, Mode=TwoWay}" />
+ <TextBlock
+ VerticalAlignment="Center"
+ Width="25"
+ Text="{ReflectionBinding Configuration.RangeRight, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ </StackPanel>
+ </StackPanel>
+ </StackPanel>
+ </Border>
+ </StackPanel>
+ </Grid>
+ </StackPanel>
+</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
new file mode 100644
index 00000000..8fe7b941
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
@@ -0,0 +1,180 @@
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Avalonia.LogicalTree;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Helpers;
+using Ryujinx.Ava.UI.Models;
+using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Common.Configuration.Hid.Controller;
+using Ryujinx.Input;
+using Ryujinx.Input.Assigner;
+using System;
+
+namespace Ryujinx.Ava.UI.Views.Input
+{
+ public partial class ControllerInputView : UserControl
+ {
+ private bool _dialogOpen;
+
+ private ButtonKeyAssigner _currentAssigner;
+ internal ControllerInputViewModel ViewModel { get; set; }
+
+ public ControllerInputView()
+ {
+ DataContext = ViewModel = new ControllerInputViewModel(this);
+
+ InitializeComponent();
+
+ foreach (ILogical visual in SettingButtons.GetLogicalDescendants())
+ {
+ if (visual is ToggleButton button && !(visual is CheckBox))
+ {
+ button.Checked += Button_Checked;
+ button.Unchecked += Button_Unchecked;
+ }
+ }
+ }
+
+ protected override void OnPointerReleased(PointerReleasedEventArgs e)
+ {
+ base.OnPointerReleased(e);
+
+ if (_currentAssigner != null && _currentAssigner.ToggledButton != null && !_currentAssigner.ToggledButton.IsPointerOver)
+ {
+ _currentAssigner.Cancel();
+ }
+ }
+
+ private void Button_Checked(object sender, RoutedEventArgs e)
+ {
+ if (sender is ToggleButton button)
+ {
+ if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
+ {
+ return;
+ }
+
+ bool isStick = button.Tag != null && button.Tag.ToString() == "stick";
+
+ if (_currentAssigner == null && (bool)button.IsChecked)
+ {
+ _currentAssigner = new ButtonKeyAssigner(button);
+
+ FocusManager.Instance.Focus(this, NavigationMethod.Pointer);
+
+ PointerPressed += MouseClick;
+
+ IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
+ IButtonAssigner assigner = CreateButtonAssigner(isStick);
+
+ _currentAssigner.ButtonAssigned += (sender, e) =>
+ {
+ if (e.IsAssigned)
+ {
+ ViewModel.IsModified = true;
+ }
+ };
+
+ _currentAssigner.GetInputAndAssign(assigner, keyboard);
+ }
+ else
+ {
+ if (_currentAssigner != null)
+ {
+ ToggleButton oldButton = _currentAssigner.ToggledButton;
+
+ _currentAssigner.Cancel();
+ _currentAssigner = null;
+ button.IsChecked = false;
+ }
+ }
+ }
+ }
+
+ public void SaveCurrentProfile()
+ {
+ ViewModel.Save();
+ }
+
+ private IButtonAssigner CreateButtonAssigner(bool forStick)
+ {
+ IButtonAssigner assigner;
+
+ var device = ViewModel.Devices[ViewModel.Device];
+
+ if (device.Type == DeviceType.Keyboard)
+ {
+ assigner = new KeyboardKeyAssigner((IKeyboard)ViewModel.SelectedGamepad);
+ }
+ else if (device.Type == DeviceType.Controller)
+ {
+ assigner = new GamepadButtonAssigner(ViewModel.SelectedGamepad, (ViewModel.Config as StandardControllerInputConfig).TriggerThreshold, forStick);
+ }
+ else
+ {
+ throw new Exception("Controller not supported");
+ }
+
+ return assigner;
+ }
+
+ private void Button_Unchecked(object sender, RoutedEventArgs e)
+ {
+ _currentAssigner?.Cancel();
+ _currentAssigner = null;
+ }
+
+ private void MouseClick(object sender, PointerPressedEventArgs e)
+ {
+ bool shouldUnbind = false;
+
+ if (e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed)
+ {
+ shouldUnbind = true;
+ }
+
+ _currentAssigner?.Cancel(shouldUnbind);
+
+ PointerPressed -= MouseClick;
+ }
+
+ private async void PlayerIndexBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (ViewModel.IsModified && !_dialogOpen)
+ {
+ _dialogOpen = true;
+
+ var result = await ContentDialogHelper.CreateConfirmationDialog(
+ LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmMessage],
+ LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmSubMessage],
+ LocaleManager.Instance[LocaleKeys.InputDialogYes],
+ LocaleManager.Instance[LocaleKeys.InputDialogNo],
+ LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
+
+ if (result == UserResult.Yes)
+ {
+ ViewModel.Save();
+ }
+
+ _dialogOpen = false;
+
+ ViewModel.IsModified = false;
+
+ if (e.AddedItems.Count > 0)
+ {
+ var player = (PlayerModel)e.AddedItems[0];
+ ViewModel.PlayerId = player.Id;
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ _currentAssigner?.Cancel();
+ _currentAssigner = null;
+ ViewModel.Dispose();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
new file mode 100644
index 00000000..b1832437
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
@@ -0,0 +1,169 @@
+<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:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
+ xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
+ xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
+ mc:Ignorable="d"
+ x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
+ x:CompileBindings="True"
+ x:DataType="viewModels:MotionInputViewModel"
+ Focusable="True">
+ <Grid Margin="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <StackPanel Orientation="Vertical">
+ <StackPanel
+ Orientation="Horizontal"
+ HorizontalAlignment="Center">
+ <TextBlock
+ Margin="0"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsMotionGyroSensitivity}" />
+ <Slider
+ Margin="0,-5,0,-5"
+ Width="150"
+ MaxWidth="150"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Maximum="100"
+ Minimum="0"
+ Value="{Binding Sensitivity, Mode=TwoWay}" />
+ <TextBlock
+ HorizontalAlignment="Center"
+ Margin="5, 0"
+ Text="{Binding Sensitivity, StringFormat=\{0:0\}%}" />
+ </StackPanel>
+ <StackPanel
+ Orientation="Horizontal"
+ HorizontalAlignment="Center">
+ <TextBlock
+ Margin="0"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsMotionGyroDeadzone}" />
+ <Slider
+ Margin="0,-5,0,-5"
+ Width="150"
+ MaxWidth="150"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Maximum="100"
+ Minimum="0"
+ Value="{Binding GyroDeadzone, Mode=TwoWay}" />
+ <TextBlock
+ VerticalAlignment="Center"
+ Margin="5, 0"
+ Text="{Binding GyroDeadzone, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ <Separator
+ Height="1"
+ Margin="0,5" />
+ <CheckBox
+ Margin="5"
+ IsChecked="{Binding EnableCemuHookMotion}">
+ <TextBlock
+ Margin="0,3,0,0"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsMotionUseCemuhookCompatibleMotion}" />
+ </CheckBox>
+ </StackPanel>
+ <Border
+ Grid.Row="1"
+ Padding="20,5"
+ BorderBrush="{DynamicResource ThemeControlBorderColor}"
+ BorderThickness="1"
+ CornerRadius="5"
+ HorizontalAlignment="Stretch">
+ <Grid VerticalAlignment="Top">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <StackPanel
+ Grid.Row="1"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Vertical">
+ <StackPanel
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Horizontal">
+ <TextBlock
+ Margin="5"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsMotionServerHost}" />
+ <TextBox
+ Height="30"
+ MinWidth="100"
+ MaxWidth="100"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{Binding DsuServerHost, Mode=TwoWay}" />
+ <TextBlock
+ Margin="5"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text=":" />
+ <TextBox
+ Height="30"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Text="{Binding DsuServerPort, Mode=TwoWay}" />
+ </StackPanel>
+ <StackPanel Orientation="Vertical">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition />
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <TextBlock
+ Margin="0,10,0,0"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsMotionControllerSlot}" />
+ <ui:NumberBox
+ Grid.Row="0"
+ Grid.Column="1"
+ Name="CemuHookSlotUpDown"
+ SmallChange="1"
+ LargeChange="1"
+ Maximum="4"
+ Minimum="0"
+ Value="{Binding Slot}" />
+ <TextBlock
+ Margin="0,10,0,0"
+ Grid.Row="1"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsMotionRightJoyConSlot}" />
+ <ui:NumberBox
+ Grid.Row="1"
+ Grid.Column="1"
+ Name="CemuHookRightJoyConSlotUpDown"
+ SmallChange="1"
+ LargeChange="1"
+ Maximum="4"
+ Minimum="0"
+ Value="{Binding AltSlot}" />
+ </Grid>
+ </StackPanel>
+ <CheckBox
+ HorizontalAlignment="Center"
+ IsChecked="{Binding MirrorInput, Mode=TwoWay}">
+ <TextBlock
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsMotionMirrorInput}" />
+ </CheckBox>
+ </StackPanel>
+ </Grid>
+ </Border>
+ </Grid>
+</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
new file mode 100644
index 00000000..88bbcd93
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
@@ -0,0 +1,68 @@
+using Avalonia.Controls;
+using FluentAvalonia.UI.Controls;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Models;
+using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Common.Configuration.Hid.Controller;
+using System.Threading.Tasks;
+
+namespace Ryujinx.Ava.UI.Views.Input
+{
+ public partial class MotionInputView : UserControl
+ {
+ private MotionInputViewModel _viewModel;
+
+ public MotionInputView()
+ {
+ InitializeComponent();
+ }
+
+ public MotionInputView(ControllerInputViewModel viewModel)
+ {
+ var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
+
+ _viewModel = new MotionInputViewModel
+ {
+ Slot = config.Slot,
+ AltSlot = config.AltSlot,
+ DsuServerHost = config.DsuServerHost,
+ DsuServerPort = config.DsuServerPort,
+ MirrorInput = config.MirrorInput,
+ Sensitivity = config.Sensitivity,
+ GyroDeadzone = config.GyroDeadzone,
+ EnableCemuHookMotion = config.EnableCemuHookMotion
+ };
+
+ InitializeComponent();
+ DataContext = _viewModel;
+ }
+
+ public static async Task Show(ControllerInputViewModel viewModel)
+ {
+ MotionInputView content = new(viewModel);
+
+ ContentDialog contentDialog = new()
+ {
+ Title = LocaleManager.Instance[LocaleKeys.ControllerMotionTitle],
+ PrimaryButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsSave],
+ SecondaryButtonText = "",
+ CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
+ Content = content
+ };
+ contentDialog.PrimaryButtonClick += (sender, args) =>
+ {
+ var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
+ config.Slot = content._viewModel.Slot;
+ config.Sensitivity = content._viewModel.Sensitivity;
+ config.GyroDeadzone = content._viewModel.GyroDeadzone;
+ config.AltSlot = content._viewModel.AltSlot;
+ config.DsuServerHost = content._viewModel.DsuServerHost;
+ config.DsuServerPort = content._viewModel.DsuServerPort;
+ config.EnableCemuHookMotion = content._viewModel.EnableCemuHookMotion;
+ config.MirrorInput = content._viewModel.MirrorInput;
+ };
+
+ await contentDialog.ShowAsync();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
new file mode 100644
index 00000000..3882ebe2
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
@@ -0,0 +1,60 @@
+<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:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
+ xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
+ mc:Ignorable="d"
+ x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
+ x:DataType="viewModels:RumbleInputViewModel"
+ x:CompileBindings="True"
+ Focusable="True">
+ <Grid Margin="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <StackPanel Orientation="Vertical">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock
+ Width="100"
+ TextWrapping="WrapWithOverflow"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsRumbleStrongMultiplier}" />
+ <Slider
+ Margin="0,-5,0,-5"
+ Width="200"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Maximum="10"
+ Minimum="0"
+ Value="{Binding StrongRumble, Mode=TwoWay}" />
+ <TextBlock
+ VerticalAlignment="Center"
+ Margin="5,0"
+ Text="{Binding StrongRumble, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ <StackPanel Orientation="Horizontal">
+ <TextBlock
+ Width="100"
+ TextWrapping="WrapWithOverflow"
+ HorizontalAlignment="Center"
+ Text="{locale:Locale ControllerSettingsRumbleWeakMultiplier}" />
+ <Slider
+ Margin="0,-5,0,-5"
+ Width="200"
+ MaxWidth="200"
+ Maximum="10"
+ TickFrequency="0.01"
+ IsSnapToTickEnabled="True"
+ Minimum="0"
+ Value="{Binding WeakRumble, Mode=TwoWay}" />
+ <TextBlock
+ VerticalAlignment="Center"
+ Margin="5,0"
+ Text="{Binding WeakRumble, StringFormat=\{0:0.00\}}" />
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
new file mode 100644
index 00000000..dfe05b08
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
@@ -0,0 +1,58 @@
+using Avalonia.Controls;
+using FluentAvalonia.UI.Controls;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Models;
+using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Common.Configuration.Hid.Controller;
+using System.Threading.Tasks;
+
+namespace Ryujinx.Ava.UI.Views.Input
+{
+ public partial class RumbleInputView : UserControl
+ {
+ private RumbleInputViewModel _viewModel;
+
+ public RumbleInputView()
+ {
+ InitializeComponent();
+ }
+
+ public RumbleInputView(ControllerInputViewModel viewModel)
+ {
+ var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
+
+ _viewModel = new RumbleInputViewModel
+ {
+ StrongRumble = config.StrongRumble,
+ WeakRumble = config.WeakRumble
+ };
+
+ InitializeComponent();
+
+ DataContext = _viewModel;
+ }
+
+ public static async Task Show(ControllerInputViewModel viewModel)
+ {
+ RumbleInputView content = new(viewModel);
+
+ ContentDialog contentDialog = new()
+ {
+ Title = LocaleManager.Instance[LocaleKeys.ControllerRumbleTitle],
+ PrimaryButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsSave],
+ SecondaryButtonText = "",
+ CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
+ Content = content,
+ };
+
+ contentDialog.PrimaryButtonClick += (sender, args) =>
+ {
+ var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
+ config.StrongRumble = content._viewModel.StrongRumble;
+ config.WeakRumble = content._viewModel.WeakRumble;
+ };
+
+ await contentDialog.ShowAsync();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
index 1c774bda..22ff38f5 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
@@ -1,11 +1,11 @@
-<UserControl
+<UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsInputView"
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:window="clr-namespace:Ryujinx.Ava.UI.Windows"
+ xmlns:views="clr-namespace:Ryujinx.Ava.UI.Views.Input"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
x:CompileBindings="True"
@@ -13,34 +13,56 @@
<Design.DataContext>
<viewModels:SettingsViewModel />
</Design.DataContext>
- <ScrollViewer
+ <ScrollViewer
Name="InputPage"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<Border Classes="settings">
- <StackPanel Margin="4" Orientation="Vertical">
- <StackPanel Orientation="Horizontal">
- <CheckBox Margin="5,0"
- ToolTip.Tip="{locale:Locale DockModeToggleTooltip}"
- IsChecked="{Binding EnableDockedMode}">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabInputEnableDockedMode}" />
- </CheckBox>
- <CheckBox Margin="5,0"
- ToolTip.Tip="{locale:Locale DirectKeyboardTooltip}"
- IsChecked="{Binding EnableKeyboard}">
- <TextBlock Text="{locale:Locale SettingsTabInputDirectKeyboardAccess}" />
- </CheckBox>
- <CheckBox Margin="5,0"
- ToolTip.Tip="{locale:Locale DirectMouseTooltip}"
- IsChecked="{Binding EnableMouse}">
- <TextBlock Text="{locale:Locale SettingsTabInputDirectMouseAccess}" />
- </CheckBox>
- </StackPanel>
- <window:ControllerSettingsWindow Name="ControllerSettings" Margin="0" MinHeight="600" />
- </StackPanel>
+ <Panel
+ Margin="10">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <views:ControllerInputView
+ Grid.Row="0"
+ Name="ControllerSettings" />
+ <StackPanel
+ Orientation="Vertical"
+ Grid.Row="2">
+ <Separator
+ Margin="0 10"
+ Height="1" />
+ <StackPanel
+ Orientation="Horizontal"
+ Spacing="10">
+ <CheckBox
+ ToolTip.Tip="{locale:Locale DockModeToggleTooltip}"
+ MinWidth="0"
+ IsChecked="{Binding EnableDockedMode}">
+ <TextBlock
+ Text="{locale:Locale SettingsTabInputEnableDockedMode}" />
+ </CheckBox>
+ <CheckBox
+ ToolTip.Tip="{locale:Locale DirectKeyboardTooltip}"
+ IsChecked="{Binding EnableKeyboard}">
+ <TextBlock
+ Text="{locale:Locale SettingsTabInputDirectKeyboardAccess}" />
+ </CheckBox>
+ <CheckBox
+ ToolTip.Tip="{locale:Locale DirectMouseTooltip}"
+ IsChecked="{Binding EnableMouse}">
+ <TextBlock
+ Text="{locale:Locale SettingsTabInputDirectMouseAccess}" />
+ </CheckBox>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+ </Panel>
</Border>
</ScrollViewer>
</UserControl> \ No newline at end of file