MosswartMassacre/MosswartMassacre/Views/BaseView.cs
2025-05-29 17:58:56 +02:00

177 lines
No EOL
5.1 KiB
C#

using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using MyClasses.MetaViewWrappers;
namespace MosswartMassacre.Views
{
public class BaseView : IDisposable
{
#region Windows API for boundary checking
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public int Width { get { return Right - Left; } }
public int Height { get { return Bottom - Top; } }
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
#endregion
internal IView view;
protected PluginCore pluginCore;
public BaseView(PluginCore core)
{
pluginCore = core;
}
protected void CreateFromXMLResource(string resourcePath)
{
try
{
view = ViewSystemSelector.CreateViewResource(PluginCore.MyHost, resourcePath);
// Note: IView doesn't have VisibleChanged event, so we'll check bounds manually when needed
}
catch (Exception ex)
{
PluginCore.WriteToChat($"Error creating view from {resourcePath}: {ex.Message}");
}
}
protected void KeepWindowInBounds()
{
try
{
RECT rect = new RECT();
IntPtr gameWindowHandle = PluginCore.MyHost?.Decal?.Hwnd ?? IntPtr.Zero;
if (gameWindowHandle != IntPtr.Zero && GetWindowRect(gameWindowHandle, ref rect))
{
Point currentLocation = view.Location;
Size viewSize = view.Size;
// Check if window is outside right boundary
if (currentLocation.X + viewSize.Width > rect.Width)
{
currentLocation.X = rect.Width - viewSize.Width;
}
// Check if window is outside left boundary
else if (currentLocation.X < 0)
{
currentLocation.X = 20;
}
// Check if window is outside bottom boundary
if (currentLocation.Y + viewSize.Height > rect.Height)
{
currentLocation.Y = rect.Height - viewSize.Height;
}
// Check if window is outside top boundary
else if (currentLocation.Y < 0)
{
currentLocation.Y = 20;
}
// Only update location if it changed
if (currentLocation != view.Location)
{
view.Location = currentLocation;
}
}
}
catch
{
// Don't spam chat with boundary check errors, just log silently
}
}
protected virtual void SaveWindowPosition()
{
// Override in derived classes to save position to settings
}
protected virtual void RestoreWindowPosition()
{
// Override in derived classes to restore position from settings
}
public virtual void Initialize()
{
try
{
RestoreWindowPosition();
}
catch (Exception ex)
{
PluginCore.WriteToChat($"Error initializing view: {ex.Message}");
}
}
public virtual void Show()
{
if (view != null)
{
view.Visible = true;
}
}
public virtual void Hide()
{
if (view != null)
{
view.Visible = false;
}
}
public virtual void Toggle()
{
if (view != null)
{
view.Visible = !view.Visible;
}
}
#region IDisposable Support
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
try
{
SaveWindowPosition();
if (view != null)
{
view.Dispose();
}
view = null;
}
catch (Exception ex)
{
PluginCore.WriteToChat($"Error disposing view: {ex.Message}");
}
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
}
#endregion
}
}