UI/WebLinkLabel.cs
using Sandbox.UI;
namespace BlockParty;
/// <summary>
/// Rich-text label whose anchor opens in the user's web browser. The engine only opens web pages
/// from a rich label's http/https anchor (Label.OnClick) — game code has no browser-open API — so
/// the whole chip is one big anchor glyph. Fixes up the two engine behaviours that don't fit this
/// game: anchor hover stamps Style.Cursor = "pointer" (the real OS hand — everything here uses the
/// blanked cursor names so the software cursor draws instead), and clicks are silent.
/// </summary>
public sealed class WebLinkLabel : Label
{
// Whether the anchor glyph itself is under the cursor — i.e. whether a click here will actually
// navigate. A rich label only hit-tests the TEXT, so the ring of label around the glyph is dead
// space, and the chip this lives in is deliberately bigger than its icon; blipping there promised
// a navigation that never came.
private bool _overAnchor;
protected override void OnMouseMove( MousePanelEvent e )
{
// The engine resolves which rich-text span is under the cursor inside its OnMouseMove and
// publishes that resolution ONLY as Style.Cursor ("pointer" over an <a>, else null), and only
// on the frames where the hovered span CHANGES. Our own "blank-hand" write below therefore
// doubles as the sentinel: if it survived the call, the span is the same as last move and the
// latch still holds. Should the engine ever stop stamping the cursor, this fails QUIET (no
// blip) rather than wrong (blip with no navigation).
base.OnMouseMove( e );
if ( Style.Cursor == "pointer" ) _overAnchor = true;
else if ( Style.Cursor is null ) _overAnchor = false;
Style.Cursor = "blank-hand";
}
protected override void OnClick( MousePanelEvent e )
{
if ( _overAnchor )
Audio.PlaySfx( SfxType.MenuBlip, 0.7f );
base.OnClick( e );
}
}