Utility class for dispatching UI event handlers for Goo panels. It invokes provided handlers for generic payloads, manages enter/leave state for mouse events, and optionally calls a rebuild request after a handler runs.
using System;
using Sandbox;
using Sandbox.UI;
namespace Goo.Internal;
/// <summary>Invokes a user event handler and, if it ran, requests a rebuild.
/// Centralizes the "auto-rebuild after a handler fires" rule (the GooPanel
/// AutoRebuildOnEvents contract) for every event-host panel. Generic over the
/// payload so mouse (MousePanelEvent), wheel (Vector2), and drag (DragEvent /
/// PanelEvent) handlers all route through the same path.</summary>
internal static class EventDispatch
{
public static void Fire<T>(Action<T>? handler, T e, Action? requestRebuild)
{
if (handler == null) return;
handler.Invoke(e);
requestRebuild?.Invoke();
}
public static void FireEnter(ref bool inside, Action<MousePanelEvent>? handler, MousePanelEvent e, Action? requestRebuild)
{
if (inside) return;
inside = true;
Fire(handler, e, requestRebuild);
}
public static void FireLeave(Panel self, ref bool inside, Action<MousePanelEvent>? handler, MousePanelEvent e, Action? requestRebuild)
{
if (!inside) return;
if (self.IsInside(Mouse.Position)) return;
inside = false;
Fire(handler, e, requestRebuild);
}
// Fires enter/leave on an outline-crossing transition. The caller computes nowInside against the
// drawn outline (not the rect), so this drives precise enter/leave from OnMouseMove/OnMouseOut.
public static void FireCrossing(ref bool inside, bool nowInside,
Action<MousePanelEvent>? onEnter, Action<MousePanelEvent>? onLeave,
MousePanelEvent e, Action? requestRebuild)
{
if (nowInside == inside) return;
inside = nowInside;
Fire(nowInside ? onEnter : onLeave, e, requestRebuild);
}
}