Files
ss14-wega/Content.Client/_Wega/GPS/UI/GpsWindow.xaml.cs
T
Zekins3366 864ab2ea6b pew
2026-06-02 01:41:45 +03:00

439 lines
13 KiB
C#

using System.Numerics;
using Content.Client.Stylesheets;
using Content.Shared.GPS;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Utility;
namespace Content.Client._Wega.GPS.UI;
[GenerateTypedNameReferences]
public sealed partial class GpsWindow : BaseWindow
{
private Dictionary<NetEntity, GpsDeviceControl> _deviceControls = new();
private Dictionary<string, NavBeaconControl> _beaconControls = new();
public Action<string>? OnUpdateGpsName;
public Action<string>? OnUpdateGpsDescription;
public Action<bool>? OnToggleBroadcast;
private List<GpsDeviceInfo> _lastGpsDevices = new();
private List<NavBeaconInfo> _lastNavBeacons = new();
private List<LavaTileInfo> _lastLavaTiles = new();
private string? _lastName = null;
private string? _lastDesc = null;
private GpsNavMapControl? _navMapControl;
private EntityUid? _currentMapUid;
private Vector2 _currentWorldPosition;
public GpsWindow()
{
RobustXamlLoader.Load(this);
CloseButton.OnPressed += _ => Close();
SaveNameButton.OnPressed += _ =>
{
if (!string.IsNullOrWhiteSpace(GpsNameEdit.Text))
{
var cleanName = FormattedMessage.RemoveMarkupOrThrow(GpsNameEdit.Text);
OnUpdateGpsName?.Invoke(cleanName);
}
};
SaveDescButton.OnPressed += _ =>
{
if (!string.IsNullOrWhiteSpace(GpsDescEdit.Text))
{
var cleanDesc = FormattedMessage.RemoveMarkupOrThrow(GpsDescEdit.Text);
OnUpdateGpsDescription?.Invoke(cleanDesc);
}
};
SetupTabs();
SetupMapControls();
}
protected override DragMode GetDragModeFor(Vector2 relativeMousePos) => DragMode.Move;
private void SetupTabs()
{
Tabs.SetTabTitle(0, Loc.GetString("gps-tab-devices"));
Tabs.SetTabTitle(1, Loc.GetString("gps-tab-beacons"));
Tabs.SetTabTitle(2, Loc.GetString("gps-tab-map"));
Tabs.OnTabChanged += OnTabChanged;
}
private void SetupMapControls()
{
_navMapControl = new GpsNavMapControl();
NavMapContainer.AddChild(_navMapControl);
ZoomInButton.OnPressed += _ =>
{
if (_navMapControl != null)
{
_navMapControl.Zoom += 0.2f;
UpdateMapZoomLabel();
}
};
ZoomOutButton.OnPressed += _ =>
{
if (_navMapControl != null)
{
_navMapControl.Zoom -= 0.2f;
UpdateMapZoomLabel();
}
};
CenterMapButton.OnPressed += _ =>
{
if (_navMapControl != null)
{
_navMapControl.CenterOnPosition(_currentWorldPosition);
}
};
ToggleBeaconsButton.OnPressed += _ =>
{
if (_navMapControl != null)
{
_navMapControl.ShowBeaconLabels = !_navMapControl.ShowBeaconLabels;
ToggleBeaconsButton.Text = _navMapControl.ShowBeaconLabels
? Loc.GetString("gps-ui-hide-beacons")
: Loc.GetString("gps-ui-show-beacons");
}
};
if (_navMapControl != null)
{
_navMapControl.OnZoomChanged += _ => UpdateMapZoomLabel();
}
UpdateMapZoomLabel();
}
public void UpdateState(GpsUpdateState state, IEntityManager entMan)
{
if (_lastName == null) _lastName = state.CurrentGpsName;
if (_lastDesc == null) _lastDesc = state.CurrentGpsDesc;
if (_lastName != state.CurrentGpsName)
{
GpsNameEdit.Text = state.CurrentGpsName;
_lastName = state.CurrentGpsName;
}
if (_lastDesc != state.CurrentGpsDesc)
{
GpsDescEdit.Text = state.CurrentGpsDesc;
_lastDesc = state.CurrentGpsDesc;
}
CoordinatesLabel.Text = $"({state.CurrentCoordinates.X}, {state.CurrentCoordinates.Y})";
_currentMapUid = entMan.GetEntity(state.MapUid);
_currentWorldPosition = new Vector2(state.CurrentCoordinates.X, state.CurrentCoordinates.Y);
_lastGpsDevices = state.OtherGpsDevices;
_lastNavBeacons = state.NavBeacons;
_lastLavaTiles = state.LavaTiles;
UpdateBroadcastStatus(state.BroadcastStatus);
UpdateDevicesList(state.OtherGpsDevices);
UpdateBeaconsList(state.NavBeacons);
if (Tabs.CurrentTab == 2)
UpdateNavMapData();
}
public void UpdateBroadcastStatus(bool enabled)
{
BroadcastStatusLabel.Text = enabled
? Loc.GetString("gps-ui-broadcast-on")
: Loc.GetString("gps-ui-broadcast-off");
ToggleBroadcastButton.Text = enabled
? Loc.GetString("gps-ui-broadcast-turn-off")
: Loc.GetString("gps-ui-broadcast-turn-on");
ToggleBroadcastButton.OnPressed += _ =>
{
OnToggleBroadcast?.Invoke(!enabled);
};
}
private void UpdateMapZoomLabel()
{
if (_navMapControl != null)
{
MapZoomLabel.Text = Loc.GetString("gps-ui-zoom-level", ("zoom", _navMapControl.Zoom.ToString("F1")));
}
}
private void OnTabChanged(int tabIndex)
{
if (tabIndex == 2 && _navMapControl != null)
UpdateNavMapData();
}
private void UpdateNavMapData()
{
if (_navMapControl != null && _currentMapUid.HasValue)
{
_navMapControl.UpdateData(
_currentMapUid,
_currentWorldPosition,
_lastGpsDevices,
_lastNavBeacons,
_lastLavaTiles
);
}
}
private void UpdateDevicesList(List<GpsDeviceInfo> devices)
{
DevicesCountLabel.Text = $"{devices.Count}";
DevicesContainer.Children.Clear();
_deviceControls.Clear();
if (devices.Count == 0)
{
var emptyLabel = new Label
{
Text = Loc.GetString("gps-ui-no-other-devices"),
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center,
FontColorOverride = Color.FromHex("#8ecae6"),
Margin = new Thickness(0, 20)
};
DevicesContainer.AddChild(emptyLabel);
return;
}
foreach (var device in devices)
{
var control = new GpsDeviceControl(device);
DevicesContainer.AddChild(control);
_deviceControls[device.EntityUid] = control;
}
}
private void UpdateBeaconsList(List<NavBeaconInfo> beacons)
{
BeaconsCountLabel.Text = $"{beacons.Count}";
BeaconsContainer.Children.Clear();
_beaconControls.Clear();
if (beacons.Count == 0)
{
var emptyLabel = new Label
{
Text = Loc.GetString("gps-ui-no-beacons"),
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center,
FontColorOverride = Color.FromHex("#c77dff"),
Margin = new Thickness(0, 20)
};
BeaconsContainer.AddChild(emptyLabel);
return;
}
foreach (var beacon in beacons)
{
var control = new NavBeaconControl(beacon);
BeaconsContainer.AddChild(control);
_beaconControls[beacon.Name] = control;
}
}
}
public sealed partial class GpsDeviceControl : PanelContainer
{
public GpsDeviceControl(GpsDeviceInfo device)
{
HorizontalExpand = true;
PanelOverride = new StyleBoxFlat
{
BackgroundColor = Color.FromHex("#3d235e"),
BorderColor = Color.FromHex("#9d4edd"),
BorderThickness = new Thickness(1),
ContentMarginBottomOverride = 6,
ContentMarginLeftOverride = 8,
ContentMarginRightOverride = 8,
ContentMarginTopOverride = 6
};
var container = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
HorizontalExpand = true,
SeparationOverride = 4
};
var header = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
HorizontalExpand = true
};
var nameLabel = new Label
{
Text = string.IsNullOrEmpty(device.Name) ? Loc.GetString("gps-ui-unnamed") : device.Name,
FontColorOverride = Color.FromHex("#ffffff"),
HorizontalExpand = true
};
header.AddChild(nameLabel);
if (!string.IsNullOrEmpty(device.Description))
{
var descLabel = new Label
{
Text = device.Description,
FontColorOverride = Color.FromHex("#c77dff"),
HorizontalExpand = true
};
descLabel.AddStyleClass(StyleClass.LabelSubText);
descLabel.AddStyleClass(StyleClass.Italic);
header.AddChild(descLabel);
}
var infoBox = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
HorizontalExpand = true
};
var coordsLabel = new Label
{
Text = $"({device.Coordinates.X}, {device.Coordinates.Y})",
FontColorOverride = Color.FromHex("#ffd166"),
Margin = new Thickness(0, 0, 10, 0)
};
var distanceLabel = new Label
{
Text = Loc.GetString("gps-ui-distance", ("distance", device.Distance.ToString("F1"))),
FontColorOverride = Color.FromHex("#c77dff"),
HorizontalAlignment = HAlignment.Right,
HorizontalExpand = true
};
infoBox.AddChild(coordsLabel);
infoBox.AddChild(distanceLabel);
container.AddChild(header);
container.AddChild(infoBox);
AddChild(container);
}
}
public sealed partial class NavBeaconControl : PanelContainer
{
public NavBeaconControl(NavBeaconInfo beacon)
{
HorizontalExpand = true;
var borderColor = beacon.Enabled ? beacon.Color : Color.FromHex("#666666");
PanelOverride = new StyleBoxFlat
{
BackgroundColor = Color.FromHex("#3d235e").WithAlpha(0.8f),
BorderColor = borderColor,
BorderThickness = new Thickness(1),
ContentMarginBottomOverride = 6,
ContentMarginLeftOverride = 8,
ContentMarginRightOverride = 8,
ContentMarginTopOverride = 6
};
var container = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
HorizontalExpand = true,
VerticalAlignment = VAlignment.Center
};
var colorBox = new PanelContainer
{
PanelOverride = new StyleBoxFlat
{
BackgroundColor = beacon.Color,
ContentMarginBottomOverride = 2,
ContentMarginLeftOverride = 2,
ContentMarginRightOverride = 2,
ContentMarginTopOverride = 2
},
MinSize = new Vector2(12, 12),
Margin = new Thickness(0, 0, 8, 0)
};
var infoContainer = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
HorizontalExpand = true,
SeparationOverride = 2
};
var nameLabel = new Label
{
Text = beacon.Name,
FontColorOverride = beacon.Enabled ? Color.FromHex("#ffffff") : Color.FromHex("#a8a8a8"),
HorizontalExpand = true
};
infoContainer.AddChild(nameLabel);
if (!string.IsNullOrEmpty(beacon.Desc))
{
var descLabel = new Label
{
Text = beacon.Desc,
FontColorOverride = Color.FromHex("#c77dff"),
HorizontalExpand = true
};
descLabel.AddStyleClass(StyleClass.LabelSubText);
descLabel.AddStyleClass(StyleClass.Italic);
infoContainer.AddChild(descLabel);
}
var detailsBox = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
HorizontalExpand = true
};
var coordsLabel = new Label
{
Text = $"({beacon.Coordinates.X}, {beacon.Coordinates.Y})",
FontColorOverride = Color.FromHex("#ffd166"),
Margin = new Thickness(0, 0, 10, 0)
};
var distanceLabel = new Label
{
Text = Loc.GetString("gps-ui-distance", ("distance", beacon.Distance.ToString("F1"))),
FontColorOverride = Color.FromHex("#c77dff"),
HorizontalAlignment = HAlignment.Right,
HorizontalExpand = true
};
detailsBox.AddChild(coordsLabel);
detailsBox.AddChild(distanceLabel);
infoContainer.AddChild(detailsBox);
container.AddChild(colorBox);
container.AddChild(infoContainer);
AddChild(container);
}
}