Editor/WidgetExtensions.cs
#if DEBUG
// ReSharper disable UnusedMember.Global
using System.Runtime.CompilerServices;
using Sandbox.UI;
namespace Sandbox.Reactivity.Editor;
internal static class WidgetExtensions
{
private static readonly ConditionalWeakTable<Widget, Dictionary<string, string>> AppliedProperties = [];
extension(Widget widget)
{
public string FontFamily
{
set => widget.SetStyleProperty("font-family", $"\"{value}\"");
}
public string FontSize
{
set => widget.SetStyleProperty("font-size", value);
}
public int FontWeight
{
set => widget.SetStyleProperty("font-weight", value.ToString());
}
public string FontStyle
{
set => widget.SetStyleProperty("font-style", value);
}
public Color TextColor
{
set => widget.SetStyleProperty("color", value.ToString(false, true));
}
public string TextDecoration
{
set => widget.SetStyleProperty("text-decoration", value);
}
public Color BackgroundColor
{
set => widget.SetStyleProperty("background-color", value.ToString(false, true));
}
public float BorderRadius
{
set => widget.SetStyleProperty("border-radius", $"{value}px");
}
private void SetStyleProperty(string property, string value)
{
AppliedProperties.GetOrCreateValue(widget)[property] = value;
widget.RefreshStyles();
}
private void RefreshStyles()
{
if (AppliedProperties.TryGetValue(widget, out var properties))
{
widget.SetStyles(string.Join(';', properties.Select(x => $"{x.Key}: {x.Value}")));
}
}
}
extension(Layout layout)
{
/// <summary>
/// Adds the given widgets to this layout. Does not overwrite the current child widgets.
/// </summary>
public ReadOnlySpan<Widget?> Children
{
set
{
foreach (var widget in value)
{
if (widget == null)
{
continue;
}
layout.Add(widget);
}
}
}
}
extension(InspectorHeader widget)
{
public bool AutoBuild
{
set
{
if (value)
{
widget.BuildUI();
}
}
}
}
}
internal abstract class WrappedLayout
{
protected abstract Layout Layout { get; }
public float Spacing
{
get => Layout.Spacing;
set => Layout.Spacing = value;
}
public SizeConstraint SizeConstraint
{
get => Layout.SizeConstraint;
set => Layout.SizeConstraint = value;
}
public Margin Margin
{
get => Layout.Margin;
set => Layout.Margin = value;
}
public TextFlag Alignment
{
get => Layout.Alignment;
set => Layout.Alignment = value;
}
public ReadOnlySpan<Widget?> Children
{
set
{
foreach (var widget in value)
{
if (widget == null)
{
continue;
}
Layout.Add(widget);
}
}
}
public static implicit operator Layout(WrappedLayout wrapped)
{
return wrapped.Layout;
}
}
internal sealed class Row(bool reversed = false) : WrappedLayout
{
protected override Layout Layout { get; } = Layout.Row(reversed);
}
internal sealed class Column(bool reversed = false) : WrappedLayout
{
protected override Layout Layout { get; } = Layout.Column(reversed);
}
#endif