161 lines
4.6 KiB
C#
161 lines
4.6 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Windows;
|
|
using System.Windows.Interop;
|
|
using System.Windows.Threading;
|
|
using System.Windows.Media.Imaging; // Add this for BitmapImage
|
|
|
|
namespace Conjure.Arcade.Overlay.Views
|
|
{
|
|
public partial class MainOverlayWindow : OverlayWindow
|
|
{
|
|
private readonly TickEngine _tickEngine;
|
|
private Process? _targetProcess;
|
|
private const string TARGET_PROCESS = "notepad";
|
|
private HotkeyManager? _hotkeyManager;
|
|
private bool _isPaused;
|
|
private bool _isVisible;
|
|
private readonly DispatcherTimer _timer;
|
|
private readonly string _logoPath;
|
|
|
|
public MainOverlayWindow(string logoPath)
|
|
{
|
|
InitializeComponent();
|
|
_logoPath = logoPath;
|
|
|
|
_tickEngine = new TickEngine(Update, 60);
|
|
Loaded += OnLoaded;
|
|
Closed += OnClosed;
|
|
|
|
// Start hidden
|
|
Visibility = Visibility.Hidden;
|
|
_isVisible = false;
|
|
|
|
// Setup timer for clock updates
|
|
_timer = new DispatcherTimer();
|
|
_timer.Interval = TimeSpan.FromSeconds(1);
|
|
_timer.Tick += Timer_Tick;
|
|
_timer.Start();
|
|
|
|
// Initial time update
|
|
UpdateTime();
|
|
|
|
// Load logo
|
|
LoadLogo();
|
|
}
|
|
|
|
private void LoadLogo()
|
|
{
|
|
try
|
|
{
|
|
var image = new BitmapImage(new Uri(_logoPath, UriKind.Absolute));
|
|
GameLogo.Source = image;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Failed to load game logo: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
|
{
|
|
var windowHandle = new WindowInteropHelper(this).Handle;
|
|
_hotkeyManager = new HotkeyManager(windowHandle, ToggleOverlay);
|
|
_hotkeyManager.Register();
|
|
|
|
_targetProcess = WindowUtils.FindProcess(TARGET_PROCESS);
|
|
if (_targetProcess == null)
|
|
{
|
|
MessageBox.Show($"Could not find process: {TARGET_PROCESS}");
|
|
Close();
|
|
return;
|
|
}
|
|
_tickEngine.Start();
|
|
}
|
|
|
|
private void OnClosed(object? sender, EventArgs e)
|
|
{
|
|
_hotkeyManager?.Unregister();
|
|
_tickEngine.Stop();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (_targetProcess?.HasExited ?? true)
|
|
{
|
|
Dispatcher.Invoke(Close);
|
|
return;
|
|
}
|
|
|
|
var handle = _targetProcess.MainWindowHandle;
|
|
if (WindowUtils.GetWindowBounds(handle, out var rect))
|
|
{
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
Left = rect.Left;
|
|
Top = rect.Top;
|
|
Width = rect.Right - rect.Left;
|
|
Height = rect.Bottom - rect.Top;
|
|
});
|
|
}
|
|
}
|
|
|
|
private void ToggleOverlay()
|
|
{
|
|
_isVisible = !_isVisible;
|
|
_isPaused = _isVisible;
|
|
|
|
Visibility = _isVisible ? Visibility.Visible : Visibility.Hidden;
|
|
SetClickThrough(!_isVisible); // Make window interactive when visible
|
|
|
|
if (_targetProcess != null)
|
|
{
|
|
if (_isPaused)
|
|
WindowUtils.SuspendProcess(_targetProcess);
|
|
else
|
|
WindowUtils.ResumeProcess(_targetProcess);
|
|
|
|
UpdateOverlayText();
|
|
}
|
|
}
|
|
|
|
private void UpdateOverlayText()
|
|
{
|
|
StatusText.Text = _isPaused ? "PAUSED" : "Running";
|
|
}
|
|
|
|
private void Timer_Tick(object? sender, EventArgs e)
|
|
{
|
|
UpdateTime();
|
|
}
|
|
|
|
private void UpdateTime()
|
|
{
|
|
TimeText.Text = DateTime.Now.ToString("HH:mm:ss");
|
|
}
|
|
|
|
private void OnResumeClick(object sender, RoutedEventArgs e)
|
|
{
|
|
if (_targetProcess != null && _isPaused)
|
|
{
|
|
_isPaused = false;
|
|
_isVisible = false;
|
|
WindowUtils.ResumeProcess(_targetProcess);
|
|
Visibility = Visibility.Hidden;
|
|
SetClickThrough(true);
|
|
UpdateOverlayText();
|
|
}
|
|
}
|
|
|
|
private void OnQuitClick(object sender, RoutedEventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
protected override void OnClosed(EventArgs e)
|
|
{
|
|
_timer.Stop();
|
|
base.OnClosed(e);
|
|
}
|
|
}
|
|
} |