Files
RobustToolbox/Robust.Client/UserInterface/DevWindow/DevWindowTabUI.xaml.cs
Letter N 7a8abb3db7 debug ui ui update (#4782)
* UI Debugger: Make it look better

* cleanup

- Use GetOrNew()
- Use typeof(Control)
- Don't check string prefixes
2023-12-31 06:24:06 +11:00

234 lines
6.7 KiB
C#

using System;
using System.Collections.Generic;
using Robust.Client.AutoGenerated;
using Robust.Client.Console.Commands;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Input;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
namespace Robust.Client.UserInterface;
[GenerateTypedNameReferences]
public sealed partial class DevWindowTabUI : Control
{
[Dependency] private readonly IClydeInternal _clyde = default!;
[Dependency] private readonly IInputManager _input = default!;
public Control? SelectedControl { get; private set; }
private Dictionary<Control, DevWindowUITreeEntry> ControlMap { get; } = new();
private Control? LastHoveredControl { get; set; }
public event Action? SelectedControlChanged;
public DevWindowTabUI()
{
InitializeComponent();
TopbarButtons.PanelOverride = new StyleBoxFlat
{
BorderThickness = new Thickness(0, 0, 0, 1),
BorderColor = Color.Gray,
ContentMarginLeftOverride = 3,
ContentMarginRightOverride = 3,
ContentMarginBottomOverride = 1,
ContentMarginTopOverride = 3,
};
TreeRootBG.PanelOverride = new StyleBoxFlat
{
BorderThickness = new Thickness(0, 0, 1, 0),
BorderColor = Color.Gray,
ContentMarginLeftOverride = 3,
ContentMarginBottomOverride = 3,
};
}
private void InitializeComponent()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
ControlTreeRoot.OnKeyBindDown += ControlTreeRootOnKeyBindDown;
RefreshPropertiesButton.OnPressed += _ => Refresh();
}
private Control? GetControlUnderMouse()
{
return UserInterfaceManager.MouseGetControl(_input.MouseScreenPosition);
}
private void OnMouseMove(MouseMoveEventArgs obj)
{
if (!ControlPicker.Pressed)
return;
var controlUnderMouse = GetControlUnderMouse();
if (LastHoveredControl == controlUnderMouse)
return;
LastHoveredControl = controlUnderMouse;
Stack<Control> entryStack = new();
DevWindowUITreeEntry? entry = null;
var control = controlUnderMouse;
while (control != null)
{
if (ControlMap.TryGetValue(control, out entry))
break;
entryStack.Push(control);
control = control.Parent;
}
if (entry == null)
return;
if (entryStack.Count > 0)
entry.Open();
foreach (var subEntry in entryStack)
{
ControlMap[subEntry].Open();
}
SelectControl(controlUnderMouse);
}
private bool OnUIKeyBindStateChanged(BoundKeyEventArgs arg)
{
if (arg.Function != EngineKeyFunctions.UIClick)
return false;
if (!ControlPicker.Pressed)
return false;
var control = GetControlUnderMouse();
if (control == ControlPicker)
return false;
ControlPicker.Pressed = false;
return true;
}
private void ControlTreeRootOnKeyBindDown(GUIBoundKeyEventArgs obj)
{
if (obj.Function != EngineKeyFunctions.UIClick)
return;
obj.Handle();
SelectControl(null);
}
protected override void EnteredTree()
{
base.EnteredTree();
// Load tree roots.
foreach (var root in UserInterfaceManager.AllRoots)
{
var entry = new DevWindowUITreeEntry(this, root);
ControlTreeRoot.AddChild(entry);
}
UserInterfaceManager.OnPostDrawUIRoot += OnPostDrawUIRoot;
_clyde.MouseMove += OnMouseMove;
_input.UIKeyBindStateChanged += OnUIKeyBindStateChanged;
}
protected override void ExitedTree()
{
base.ExitedTree();
// Clear tree children.
ControlTreeRoot.RemoveAllChildren();
UserInterfaceManager.OnPostDrawUIRoot -= OnPostDrawUIRoot;
_clyde.MouseMove -= OnMouseMove;
_input.UIKeyBindStateChanged -= OnUIKeyBindStateChanged;
}
private void OnPostDrawUIRoot(PostDrawUIRootEventArgs eventArgs)
{
if (SelectedControl == null || eventArgs.Root != SelectedControl.Root)
return;
var rect = UIBox2i.FromDimensions(SelectedControl.GlobalPixelPosition, SelectedControl.PixelSize);
eventArgs.DrawingHandle.DrawRect(rect, Color.Cyan.WithAlpha(0.35f));
}
internal void EntryAdded(DevWindowUITreeEntry entry)
{
ControlMap[entry.VisControl] = entry;
}
public void EntryRemoved(DevWindowUITreeEntry entry)
{
if (SelectedControl == entry.VisControl)
SelectControl(null);
ControlMap.Remove(entry.VisControl);
}
public void SelectControl(Control? control)
{
SelectedControl = control;
SelectedControlChanged?.Invoke();
Refresh();
}
private void Refresh()
{
ControlProperties.RemoveAllChildren();
if (SelectedControl == null)
return;
var props = GuiDumpCommand.PropertyValuesForInheritance(SelectedControl);
foreach (var (classname, values) in props)
{
ControlProperties.AddChild(new PanelContainer
{
Children = { new Label
{
Text = classname,
Margin = new Thickness(3, 2)
}},
PanelOverride = new StyleBoxFlat
{
BorderThickness = new Thickness(0, 1),
BorderColor = Color.Gray,
BackgroundColor = Color.FromHex("#555555"),
}
});
foreach (var (prop, value) in values)
{
ControlProperties.AddChild(new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
SeparationOverride = 3,
Margin = new Thickness(3, 1),
Children =
{
new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
Children =
{
new Label { Text = $"{prop}", FontColorOverride = Color.GreenYellow },
new Label { Text = ":" }, // this is for the non colored ":", intentional
}
},
new Label { Text = $"{value}" },
}
});
}
}
}
}