A UI panel that captures mouse input over a strategy-view field. Handles left click press/drag/release as normalized panel coordinates, right or middle drag for camera panning, and mouse wheel for zoom, forwarding all of it to MatchController and FootballWorldPanel.
using Sandbox;
using Sandbox.UI;
using Socer;
using System;
public sealed class StrategyFieldInput : Panel
{
public MatchController Game {get;set;}
public FootballWorldPanel World {get;set;}
public Action<Vector2> Press {get;set;}
public Action<Vector2> Drag {get;set;}
public Action<Vector2> Release {get;set;}
bool leftHeld,cameraHeld;
Vector2 panLast;
Vector2 Position()=>new(MousePosition.x/Math.Max(1,Box.Rect.Width),MousePosition.y/Math.Max(1,Box.Rect.Height));
protected override void OnMouseDown(MousePanelEvent e)
{
base.OnMouseDown(e);
if(HasMouseCapture)SetMouseCapture(false);
if(e.MouseButton==MouseButtons.Right || e.MouseButton==MouseButtons.Middle){cameraHeld=true;panLast=MousePosition;return;}
if(e.MouseButton==MouseButtons.Left){leftHeld=true;Press?.Invoke(Position());}
}
protected override void OnMouseUp(MousePanelEvent e)
{
base.OnMouseUp(e);
if(e.MouseButton==MouseButtons.Left){if(leftHeld)Release?.Invoke(Position());leftHeld=false;}
if(e.MouseButton==MouseButtons.Right || e.MouseButton==MouseButtons.Middle){MovePan();cameraHeld=false;}
if(!leftHeld && !cameraHeld)SetMouseCapture(false);
}
public override void OnMouseWheel(Vector2 value){Game?.ZoomStrategyCamera(-value.y);}
public override void Tick()
{
base.Tick();
if(Game?.StrategyLabOpen!=true){leftHeld=false;cameraHeld=false;if(HasMouseCapture)SetMouseCapture(false);return;}
if(World==null)return;
if(cameraHeld)MovePan();
else if(leftHeld)Drag?.Invoke(Position());
}
void MovePan(){if(!cameraHeld)return;var pixel=MousePosition;PanPixels(pixel-panLast);panLast=pixel;}
public void PanPixels(Vector2 delta)
{
if(Game==null || World==null)return;
if(delta.Length<.01f)return;
// Invert the actual broadcast projection, preserving its current angle.
var center=World.Project(Game.Broadcast.Center);
var moved=center+new Vector2(delta.x/Math.Max(1,Box.Rect.Width),delta.y/Math.Max(1,Box.Rect.Height));
Game.PanStrategyCamera(World.CameraPanDelta(center,moved));
}
}