mirror of
https://github.com/MAKS-IT-COM/maksit-cluster-console.git
synced 2026-11-14 20:56:12 +01:00
168 lines
4.2 KiB
C#
168 lines
4.2 KiB
C#
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Threading;
|
|
using MaksIT.ClusterConsole.Shared;
|
|
using MaksIT.ClusterConsole.UI.Controls;
|
|
using MaksIT.ClusterConsole.UI.ViewModels.Shell;
|
|
|
|
|
|
namespace MaksIT.ClusterConsole.UI.Services;
|
|
|
|
internal sealed class ScreenSaverController : IDisposable {
|
|
private readonly Window _window;
|
|
private readonly MainViewModel _viewModel;
|
|
private readonly ConfigurationFileService _configuration;
|
|
private readonly BubblesScreenSaverControl _overlay;
|
|
private readonly DispatcherTimer _idleTimer;
|
|
private bool _attached;
|
|
private bool _active;
|
|
|
|
public ScreenSaverController(
|
|
Window window,
|
|
MainViewModel viewModel,
|
|
ConfigurationFileService configuration,
|
|
BubblesScreenSaverControl overlay) {
|
|
_window = window;
|
|
_viewModel = viewModel;
|
|
_configuration = configuration;
|
|
_overlay = overlay;
|
|
_idleTimer = new DispatcherTimer();
|
|
_idleTimer.Tick += (_, _) => Activate();
|
|
}
|
|
|
|
public bool IsActive => _active;
|
|
|
|
public void Attach() {
|
|
if (_attached)
|
|
return;
|
|
|
|
_attached = true;
|
|
_window.PropertyChanged += OnWindowPropertyChanged;
|
|
_window.AddHandler(InputElement.PointerMovedEvent, OnPointerActivity, RoutingStrategies.Tunnel);
|
|
_window.AddHandler(InputElement.PointerPressedEvent, OnPointerPressed, RoutingStrategies.Tunnel);
|
|
_window.AddHandler(InputElement.PointerWheelChangedEvent, OnPointerWheel, RoutingStrategies.Tunnel);
|
|
_window.AddHandler(InputElement.KeyDownEvent, OnKeyDown, RoutingStrategies.Tunnel);
|
|
_viewModel.ScreenSaverSettingsChanged += OnSettingsChanged;
|
|
SyncFromWindowState();
|
|
}
|
|
|
|
public void Dispose() {
|
|
if (!_attached)
|
|
return;
|
|
|
|
_attached = false;
|
|
_idleTimer.Stop();
|
|
_overlay.Stop();
|
|
_window.PropertyChanged -= OnWindowPropertyChanged;
|
|
_window.RemoveHandler(InputElement.PointerMovedEvent, OnPointerActivity);
|
|
_window.RemoveHandler(InputElement.PointerPressedEvent, OnPointerPressed);
|
|
_window.RemoveHandler(InputElement.PointerWheelChangedEvent, OnPointerWheel);
|
|
_window.RemoveHandler(InputElement.KeyDownEvent, OnKeyDown);
|
|
_viewModel.ScreenSaverSettingsChanged -= OnSettingsChanged;
|
|
}
|
|
|
|
public bool TryDismiss() {
|
|
if (!_active)
|
|
return false;
|
|
|
|
Dismiss();
|
|
|
|
return true;
|
|
}
|
|
|
|
private void OnSettingsChanged() =>
|
|
SyncFromWindowState();
|
|
|
|
private void OnWindowPropertyChanged(object? sender, Avalonia.AvaloniaPropertyChangedEventArgs e) {
|
|
if (e.Property == Window.WindowStateProperty)
|
|
SyncFromWindowState();
|
|
}
|
|
|
|
private void SyncFromWindowState() {
|
|
if (_window.WindowState != WindowState.FullScreen) {
|
|
StopIdle();
|
|
Dismiss();
|
|
|
|
return;
|
|
}
|
|
|
|
RestartIdleIfNeeded();
|
|
}
|
|
|
|
private void OnPointerActivity(object? sender, PointerEventArgs e) =>
|
|
HandleActivity(e);
|
|
|
|
private void OnPointerPressed(object? sender, PointerPressedEventArgs e) =>
|
|
HandleActivity(e);
|
|
|
|
private void OnPointerWheel(object? sender, PointerWheelEventArgs e) =>
|
|
HandleActivity(e);
|
|
|
|
private void HandleActivity(RoutedEventArgs e) {
|
|
if (_window.WindowState != WindowState.FullScreen)
|
|
return;
|
|
|
|
if (_active) {
|
|
Dismiss();
|
|
e.Handled = true;
|
|
|
|
return;
|
|
}
|
|
|
|
RestartIdleIfNeeded();
|
|
}
|
|
|
|
private void OnKeyDown(object? sender, KeyEventArgs e) {
|
|
if (_window.WindowState != WindowState.FullScreen)
|
|
return;
|
|
|
|
if (_active) {
|
|
Dismiss();
|
|
e.Handled = true;
|
|
|
|
return;
|
|
}
|
|
|
|
if (e.Key == Key.Escape)
|
|
return;
|
|
|
|
RestartIdleIfNeeded();
|
|
}
|
|
|
|
private void RestartIdleIfNeeded() {
|
|
_idleTimer.Stop();
|
|
|
|
var settings = _configuration.Current.ScreenSaver;
|
|
settings.Ensure();
|
|
|
|
if (!settings.Enabled || _window.WindowState != WindowState.FullScreen)
|
|
return;
|
|
|
|
_idleTimer.Interval = TimeSpan.FromMinutes(settings.IdleMinutes);
|
|
_idleTimer.Start();
|
|
}
|
|
|
|
private void StopIdle() =>
|
|
_idleTimer.Stop();
|
|
|
|
private void Activate() {
|
|
_idleTimer.Stop();
|
|
|
|
if (!_configuration.Current.ScreenSaver.Enabled || _window.WindowState != WindowState.FullScreen)
|
|
return;
|
|
|
|
_active = true;
|
|
_overlay.Start();
|
|
}
|
|
|
|
private void Dismiss() {
|
|
if (!_active && !_overlay.IsVisible)
|
|
return;
|
|
|
|
_active = false;
|
|
_overlay.Stop();
|
|
RestartIdleIfNeeded();
|
|
}
|
|
}
|