浏览代码

Made proper steam overlay

Krzysztof Krysiński 2 年之前
父节点
当前提交
acc74eeb94

+ 5 - 1
src/PixiEditor.Platform.Steam/OverlayHandler.cs

@@ -7,6 +7,8 @@ public class SteamOverlayHandler
     public event Action<bool> ActivateRefreshingElement;
     protected Callback<GameOverlayActivated_t> overlayActivated;
 
+    private bool _isOverlayActive;
+
     public SteamOverlayHandler()
     {
         overlayActivated = Callback<GameOverlayActivated_t>.Create(OnOverlayActivated);
@@ -18,15 +20,17 @@ public class SteamOverlayHandler
         System.Timers.Timer timer = new(10000);
         timer.Elapsed += (sender, args) =>
         {
-            if (SteamUtils.IsOverlayEnabled()) return;
+            if (_isOverlayActive) return;
 
             ActivateRefreshingElement?.Invoke(false);
+            timer.Stop();
         };
         timer.Start();
     }
 
     private void OnOverlayActivated(GameOverlayActivated_t param)
     {
+        _isOverlayActive = param.m_bActive == 1;
         ActivateRefreshingElement?.Invoke(param.m_bActive == 1);
     }
 }

+ 5 - 0
src/PixiEditor.Platform.Steam/SteamPlatform.cs

@@ -20,5 +20,10 @@ public class SteamPlatform : IPlatform
         }
     }
 
+    public void Update()
+    {
+        SteamAPI.RunCallbacks();
+    }
+
     public IAdditionalContentProvider? AdditionalContentProvider { get; } = new SteamAdditionalContentProvider();
 }

+ 1 - 0
src/PixiEditor.Platform/IPlatform.cs

@@ -6,6 +6,7 @@ public interface IPlatform
     public abstract string Id { get; }
     public abstract string Name { get; }
     public bool PerformHandshake();
+    public void Update();
     public IAdditionalContentProvider? AdditionalContentProvider { get; }
 
     public static void RegisterPlatform(IPlatform platform)

+ 18 - 0
src/PixiEditor/ViewModels/ViewModelMain.cs

@@ -1,4 +1,5 @@
 using System.ComponentModel;
+using System.Timers;
 using System.Windows;
 using Microsoft.Extensions.DependencyInjection;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
@@ -14,9 +15,11 @@ using PixiEditor.Models.Dialogs;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Events;
 using PixiEditor.Models.Localization;
+using PixiEditor.Platform;
 using PixiEditor.ViewModels.SubViewModels.AdditionalContent;
 using PixiEditor.ViewModels.SubViewModels.Document;
 using PixiEditor.ViewModels.SubViewModels.Tools;
+using Timer = System.Timers.Timer;
 
 namespace PixiEditor.ViewModels;
 
@@ -81,6 +84,8 @@ internal class ViewModelMain : ViewModelBase
     public IPreferences Preferences { get; set; }
     public ILocalizationProvider LocalizationProvider { get; set; }
 
+    private Timer _updateTimer;
+
     public LocalizedString ActiveActionDisplay
     {
         get
@@ -161,6 +166,19 @@ internal class ViewModelMain : ViewModelBase
         ExtensionsSubViewModel = services.GetService<ExtensionsViewModel>(); // Must be last
 
         DocumentManagerSubViewModel.ActiveDocumentChanged += OnActiveDocumentChanged;
+        InitUpdateTimer();
+    }
+
+    private void InitUpdateTimer()
+    {
+        _updateTimer = new Timer(50);
+        _updateTimer.Elapsed += UpdateTimerOnElapsed;
+        _updateTimer.Start();
+    }
+
+    private void UpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
+    {
+        IPlatform.Current?.Update();
     }
 
     public bool DocumentIsNotNull(object property)

+ 2 - 17
src/PixiEditor/Views/MainWindow.xaml

@@ -101,23 +101,8 @@
         </b:EventTrigger>
     </b:Interaction.Triggers>
     <Grid>
-        <Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Name="steamRefresher"
-                Visibility="Collapsed"
-                Background="Transparent"
-                BorderThickness="0"
-                Focusable="False"
-                Width="{Binding ElementName=mainWindow, Path=Width}"
-                Height="{Binding ElementName=mainWindow, Path=Height}" Panel.ZIndex="-1000">
-            <Border.Triggers>
-                <EventTrigger RoutedEvent="Loaded">
-                    <BeginStoryboard>
-                        <Storyboard>
-                            <DoubleAnimation Storyboard.TargetProperty="Opacity" RepeatBehavior="Forever" From="0" To="1" Duration="0:0:10"/>
-                        </Storyboard>
-                    </BeginStoryboard>
-                </EventTrigger>
-            </Border.Triggers>
-        </Border>
+        <usercontrols:SteamOverlay x:Name="steamRefresher" Width="{Binding ElementName=mainWindow, Path=Width}"
+                                   Height="{Binding ElementName=mainWindow, Path=Height}"/>
         <Grid
             Name="mainGrid"
             Margin="5"

+ 14 - 5
src/PixiEditor/Views/MainWindow.xaml.cs

@@ -4,6 +4,7 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Input;
 using System.Windows.Interop;
+using System.Windows.Media.Animation;
 using System.Windows.Media.Imaging;
 using AvalonDock.Layout;
 using Microsoft.Extensions.DependencyInjection;
@@ -62,8 +63,6 @@ internal partial class MainWindow : Window
 
         InitializeComponent();
 
-        StartSteamRefresher();
-
         OnDataContextInitialized?.Invoke();
         pixiEditorLogo = BitmapFactory.FromResource(@"/Images/PixiEditorLogo.png");
 
@@ -87,12 +86,22 @@ internal partial class MainWindow : Window
     private void StartSteamRefresher()
     {
 #if STEAM
-        steamRefresher.Visibility = Visibility.Visible;
+        steamRefresher.Activate();
 
-        PixiEditor.Platform.Steam.SteamOverlayHandler handler = new PixiEditor.Platform.Steam.SteamOverlayHandler();
+        var handler = new PixiEditor.Platform.Steam.SteamOverlayHandler();
         handler.ActivateRefreshingElement += (bool activate) =>
         {
-            steamRefresher.Visibility = activate ? Visibility.Visible : Visibility.Collapsed;
+            Application.Current.Dispatcher.Invoke(() =>
+            {
+                if (activate)
+                {
+                    steamRefresher.Activate();
+                }
+                else
+                {
+                    steamRefresher.Deactivate();
+                }
+            });
         };
 #endif
     }

+ 18 - 0
src/PixiEditor/Views/UserControls/SteamOverlay.xaml

@@ -0,0 +1,18 @@
+<UserControl x:Class="PixiEditor.Views.UserControls.SteamOverlay"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:local="clr-namespace:PixiEditor.Views.UserControls"
+             Name="uc"
+             mc:Ignorable="d">
+    <Border HorizontalAlignment="Right" VerticalAlignment="Bottom"
+            Background="Transparent"
+            BorderThickness="0"
+            Width="{Binding Width, ElementName=uc}"
+            Height="{Binding Height, ElementName=uc}"
+            Focusable="False"
+            Panel.ZIndex="-1000"
+            Name="refresher">
+    </Border>
+</UserControl>

+ 77 - 0
src/PixiEditor/Views/UserControls/SteamOverlay.xaml.cs

@@ -0,0 +1,77 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Threading;
+
+namespace PixiEditor.Views.UserControls;
+
+public partial class SteamOverlay : UserControl
+{
+    private DispatcherTimer _timer;
+    private DispatcherTimer _fadeTimer;
+    public SteamOverlay()
+    {
+        InitializeComponent();
+        CreateRefreshTimer();
+    }
+
+    private void CreateFadeTimer()
+    {
+        StopFadeTimer();
+        _fadeTimer = new DispatcherTimer(DispatcherPriority.Render) { Interval = TimeSpan.FromSeconds(1f) };
+        _fadeTimer.Tick += FadeOut;
+    }
+
+    private void FadeOut(object sender, EventArgs eventArgs)
+    {
+        RemoveTimer();
+        Visibility = Visibility.Collapsed;
+        StopFadeTimer();
+    }
+
+    private void CreateRefreshTimer()
+    {
+        RemoveTimer();
+        _timer = new DispatcherTimer(DispatcherPriority.Render) { Interval = TimeSpan.FromMilliseconds(16.6f) };
+        _timer.Tick += Refresh;
+    }
+
+    private void RemoveTimer()
+    {
+        if (_timer != null)
+        {
+            _timer.Stop();
+            _timer.Tick -= Refresh;
+            _timer = null;
+        }
+    }
+
+    public void Activate()
+    {
+        StopFadeTimer();
+        CreateRefreshTimer();
+        Visibility = Visibility.Visible;
+        _timer.Start();
+    }
+
+    public void Deactivate()
+    {
+        CreateFadeTimer();
+        _fadeTimer.Start();
+    }
+
+    private void StopFadeTimer()
+    {
+        if (_fadeTimer != null)
+        {
+            _fadeTimer.Stop();
+            _fadeTimer.Tick -= FadeOut;
+            _fadeTimer = null;
+        }
+    }
+
+    private void Refresh(object sender, EventArgs e)
+    {
+        refresher.InvalidateVisual();
+    }
+}
+