conjure-os-overlay/Views/MainOverlayWindow.xaml.cs
2025-10-10 18:26:49 -04:00

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);
}
}
}