Controller overlay changed from Window to UserControl

This commit is contained in:
Barış Hamil 2025-06-20 18:32:17 +03:00 committed by GreemDev
parent 1e86aa9764
commit d7929a7f0e
5 changed files with 45 additions and 58 deletions

View file

@ -1484,9 +1484,12 @@ namespace Ryujinx.Ava.Systems
{ {
try try
{ {
var overlayWindow = new UI.Windows.ControllerOverlayWindow(_topLevel as Avalonia.Controls.Window); // Access the overlay through the MainWindow via the ViewModel
overlayWindow.ShowControllerBindings(inputConfigs); if (_viewModel?.Window?.ControllerOverlay != null)
overlayWindow.Show(); {
int duration = ConfigurationState.Instance.ControllerOverlayInputCycleDuration.Value;
_viewModel.Window.ControllerOverlay.ShowControllerBindings(inputConfigs, duration);
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View file

@ -1,20 +1,15 @@
<window:StyleableAppWindow <UserControl
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignWidth="400" d:DesignWidth="400"
d:DesignHeight="300" d:DesignHeight="300"
x:Class="Ryujinx.Ava.UI.Windows.ControllerOverlayWindow" x:Class="Ryujinx.Ava.UI.Controls.ControllerOverlay"
Title="Controller Overlay"
Focusable="False" Focusable="False"
Topmost="True" IsVisible="False"
WindowStartupLocation="CenterScreen" Name="ControllerOverlayControl">
Width="400"
Height="250"
SizeToContent="Height">
<Border Background="#E0000000" <Border Background="#E0000000"
CornerRadius="12" CornerRadius="12"
@ -39,12 +34,13 @@
<!-- Player bindings will be added programmatically --> <!-- Player bindings will be added programmatically -->
</StackPanel> </StackPanel>
<TextBlock Text="This overlay will disappear in a few seconds" <TextBlock Name="DurationText"
FontSize="11" Text="This overlay will disappear in a few seconds"
Foreground="#AAAAAA" FontSize="11"
HorizontalAlignment="Center" Foreground="#AAAAAA"
Margin="0,8,0,0" HorizontalAlignment="Center"
FontStyle="Italic"/> Margin="0,8,0,0"
</StackPanel> FontStyle="Italic"/>
</Border> </StackPanel>
</window:StyleableAppWindow> </Border>
</UserControl>

View file

@ -7,46 +7,21 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Controls
{ {
public partial class ControllerOverlayWindow : StyleableWindow public partial class ControllerOverlay : UserControl
{ {
private const int AutoHideDelayMs = 4000; // 4 seconds
public ControllerOverlayWindow() public ControllerOverlay()
{ {
InitializeComponent(); InitializeComponent();
TransparencyLevelHint = [WindowTransparencyLevel.Transparent];
SystemDecorations = SystemDecorations.None;
ExtendClientAreaTitleBarHeightHint = 0;
Background = Brushes.Transparent; Background = Brushes.Transparent;
CanResize = false; HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right;
ShowInTaskbar = false; VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top;
Margin = new Avalonia.Thickness(0, 50, 20, 0);
} }
public ControllerOverlayWindow(Window owner) : this() public void ShowControllerBindings(List<InputConfig> inputConfigs, int durationSeconds = 3)
{
if (owner != null)
{
// Position the overlay in the top-right corner of the owner window
WindowStartupLocation = WindowStartupLocation.Manual;
// Set position after the window is loaded
Loaded += (s, e) =>
{
if (owner.WindowState != WindowState.Minimized)
{
Position = new Avalonia.PixelPoint(
(int)(owner.Position.X + owner.Width - Width - 20),
(int)(owner.Position.Y + 50)
);
}
};
}
}
public void ShowControllerBindings(List<InputConfig> inputConfigs)
{ {
// Clear existing bindings // Clear existing bindings
PlayerBindings.Children.Clear(); PlayerBindings.Children.Clear();
@ -118,13 +93,21 @@ namespace Ryujinx.Ava.UI.Windows
PlayerBindings.Children.Add(playerPanel); PlayerBindings.Children.Add(playerPanel);
} }
// Update duration text
DurationText.Text = durationSeconds == 1
? "This overlay will disappear in 1 second"
: $"This overlay will disappear in {durationSeconds} seconds";
// Show the overlay
IsVisible = true;
// Auto-hide after delay // Auto-hide after delay
_ = Task.Run(async () => _ = Task.Run(async () =>
{ {
await Task.Delay(AutoHideDelayMs); await Task.Delay(durationSeconds * 1000);
await Dispatcher.UIThread.InvokeAsync(() => await Dispatcher.UIThread.InvokeAsync(() =>
{ {
Close(); IsVisible = false;
}); });
}); });
} }

View file

@ -1710,9 +1710,8 @@ namespace Ryujinx.Ava.UI.ViewModels
// Only show overlay if there are actual controller configurations for players 1-4 // Only show overlay if there are actual controller configurations for players 1-4
if (inputConfigs?.Any(c => c.PlayerIndex <= PlayerIndex.Player4) == true) if (inputConfigs?.Any(c => c.PlayerIndex <= PlayerIndex.Player4) == true)
{ {
var overlay = new Windows.ControllerOverlayWindow(Window); int duration = ConfigurationState.Instance.ControllerOverlayGameStartDuration.Value;
overlay.ShowControllerBindings(inputConfigs); Window.ControllerOverlay.ShowControllerBindings(inputConfigs, duration);
overlay.Show();
} }
} }
catch (Exception ex) catch (Exception ex)

View file

@ -10,6 +10,7 @@
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls" xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
xmlns:main="clr-namespace:Ryujinx.Ava.UI.Views.Main" xmlns:main="clr-namespace:Ryujinx.Ava.UI.Views.Main"
xmlns:viewsMisc="clr-namespace:Ryujinx.Ava.UI.Views.Misc" xmlns:viewsMisc="clr-namespace:Ryujinx.Ava.UI.Views.Misc"
xmlns:overlayControls="clr-namespace:Ryujinx.Ava.UI.Controls"
Cursor="{Binding Cursor}" Cursor="{Binding Cursor}"
Title="{Binding Title}" Title="{Binding Title}"
WindowState="{Binding WindowState}" WindowState="{Binding WindowState}"
@ -178,5 +179,10 @@
Name="StatusBarView" Name="StatusBarView"
Grid.Row="2" /> Grid.Row="2" />
</Grid> </Grid>
<!-- Controller Overlay -->
<overlayControls:ControllerOverlay
Name="ControllerOverlay"
ZIndex="2000" />
</Grid> </Grid>
</window:StyleableAppWindow> </window:StyleableAppWindow>