mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-02-05 04:01:14 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
398 lines
15 KiB
C#
398 lines
15 KiB
C#
using System.Runtime.InteropServices;
|
|
|
|
namespace Editor;
|
|
|
|
public static partial class Theme
|
|
{
|
|
public static Color32[] QtColors = new Color32[(int)QPalette.ColorRole.NumColorRoles];
|
|
|
|
internal static void CollectQtColors()
|
|
{
|
|
QtColors[(int)QPalette.ColorRole.WindowText] = Text;
|
|
QtColors[(int)QPalette.ColorRole.Mid] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.Text] = Text;
|
|
QtColors[(int)QPalette.ColorRole.BrightText] = TextLight;
|
|
QtColors[(int)QPalette.ColorRole.ButtonText] = TextButton;
|
|
QtColors[(int)QPalette.ColorRole.Base] = Base;
|
|
QtColors[(int)QPalette.ColorRole.AlternateBase] = BaseAlt;
|
|
QtColors[(int)QPalette.ColorRole.Window] = WindowBackground;
|
|
QtColors[(int)QPalette.ColorRole.Shadow] = Shadow;
|
|
QtColors[(int)QPalette.ColorRole.Highlight] = Highlight;
|
|
QtColors[(int)QPalette.ColorRole.HighlightedText] = TextHighlight;
|
|
QtColors[(int)QPalette.ColorRole.Link] = TextLink;
|
|
QtColors[(int)QPalette.ColorRole.LinkVisited] = TextLink;
|
|
QtColors[(int)QPalette.ColorRole.NoRole] = SurfaceBackground;
|
|
QtColors[(int)QPalette.ColorRole.ToolTipBase] = SurfaceBackground;
|
|
QtColors[(int)QPalette.ColorRole.ToolTipText] = Text;
|
|
QtColors[(int)QPalette.ColorRole.PlaceholderText] = TextLight;
|
|
QtColors[(int)QPalette.ColorRole.Grid] = Base;
|
|
QtColors[(int)QPalette.ColorRole.DarkSplitterHandle] = Border;
|
|
QtColors[(int)QPalette.ColorRole.HeaderSectionBackground] = WindowBackground;
|
|
QtColors[(int)QPalette.ColorRole.Black] = Color.Black;
|
|
QtColors[(int)QPalette.ColorRole.Red] = Color.Red;
|
|
QtColors[(int)QPalette.ColorRole.Green] = Color.Green;
|
|
QtColors[(int)QPalette.ColorRole.Blue] = Color.Blue;
|
|
QtColors[(int)QPalette.ColorRole.CheckmarkPossible] = Primary;
|
|
QtColors[(int)QPalette.ColorRole.FlatSelection] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.DarkSplitter] = SurfaceBackground;
|
|
QtColors[(int)QPalette.ColorRole.MenuBackground] = WindowBackground;
|
|
QtColors[(int)QPalette.ColorRole.MenuBarBackground] = WindowBackground;
|
|
QtColors[(int)QPalette.ColorRole.ToolBarBackground] = WindowBackground;
|
|
QtColors[(int)QPalette.ColorRole.ViewportBackground] = WindowBackground;
|
|
QtColors[(int)QPalette.ColorRole.ViewportText] = TextLight;
|
|
QtColors[(int)QPalette.ColorRole.DockWidgetTitleBackground] = SurfaceBackground;
|
|
QtColors[(int)QPalette.ColorRole.TabBarBackgroundNotSelected] = SurfaceBackground;
|
|
QtColors[(int)QPalette.ColorRole.TabTextInactive] = TextLight;
|
|
QtColors[(int)QPalette.ColorRole.TabBarBackground] = TabBarBackground;
|
|
QtColors[(int)QPalette.ColorRole.Button] = ButtonBackground;
|
|
QtColors[(int)QPalette.ColorRole.DefaultButtonBackground] = SurfaceBackground;
|
|
QtColors[(int)QPalette.ColorRole.ButtonBackground] = ButtonBackground;
|
|
QtColors[(int)QPalette.ColorRole.ButtonHighlight] = ButtonBackground;
|
|
QtColors[(int)QPalette.ColorRole.ButtonPressed] = ButtonBackground;
|
|
QtColors[(int)QPalette.ColorRole.DefaultButtonOuterBorder] = Border;
|
|
QtColors[(int)QPalette.ColorRole.DefaultButtonInnerBorder] = Border;
|
|
QtColors[(int)QPalette.ColorRole.ToolButtonBackground] = ButtonBackground;
|
|
QtColors[(int)QPalette.ColorRole.ToolButtonActiveBackground] = ButtonBackground;
|
|
QtColors[(int)QPalette.ColorRole.LightSplitterHandle] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.ScrollbarBackground] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.HeaderSectionLine] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.InnerHighlight] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.LighterLine] = BorderLight;
|
|
QtColors[(int)QPalette.ColorRole.UpperLine] = BorderLight;
|
|
QtColors[(int)QPalette.ColorRole.LowerLine] = BorderLight;
|
|
QtColors[(int)QPalette.ColorRole.ToolButtonBorder] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.ToolBarBorderLight] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.ToolBarBorderDark] = Color.Transparent;
|
|
QtColors[(int)QPalette.ColorRole.ButtonBorder] = BorderButton;
|
|
QtColors[(int)QPalette.ColorRole.ToolButtonActiveBorder] = Border;
|
|
QtColors[(int)QPalette.ColorRole.ViewportToolBarBorderLight] = BorderLight;
|
|
QtColors[(int)QPalette.ColorRole.ViewportToolBarBorderDark] = SurfaceBackground;
|
|
QtColors[(int)QPalette.ColorRole.Light] = BorderLight;
|
|
QtColors[(int)QPalette.ColorRole.Midlight] = BorderLight;
|
|
QtColors[(int)QPalette.ColorRole.Dark] = BorderLight;
|
|
}
|
|
|
|
private static GCHandle PaletteHandle;
|
|
private static unsafe Color32* PalettePtr;
|
|
|
|
internal static unsafe Color32* GetPaletteColors()
|
|
{
|
|
return PalettePtr;
|
|
}
|
|
|
|
internal static string GetDefaultFont()
|
|
{
|
|
return DefaultFont;
|
|
}
|
|
|
|
public static Color Blue;
|
|
public static Color Green;
|
|
public static Color Red;
|
|
public static Color Yellow;
|
|
public static Color Pink;
|
|
|
|
public static Color Prefab;
|
|
public static Color Folder;
|
|
|
|
public static Color TabBackground;
|
|
public static Color TabBarBackground;
|
|
public static Color TabInactiveBackground;
|
|
public static Color SurfaceBackground;
|
|
public static Color SurfaceLightBackground;
|
|
public static Color SidebarBackground;
|
|
public static Color WindowBackground;
|
|
public static Color WidgetBackground;
|
|
public static Color ControlBackground;
|
|
public static Color ButtonBackground;
|
|
public static Color SelectedBackground;
|
|
public static Color StatusBarBackground;
|
|
public static Color Text;
|
|
public static Color TextControl;
|
|
public static Color TextLight;
|
|
public static Color TextWidget;
|
|
public static Color TextButton;
|
|
public static Color TextSelected;
|
|
public static Color TextLink;
|
|
public static Color TextHighlight;
|
|
public static Color TextDisabled;
|
|
public static Color Border;
|
|
public static Color BorderLight;
|
|
public static Color BorderButton;
|
|
public static Color Shadow;
|
|
public static Color Primary;
|
|
public static Color Overlay;
|
|
public static Color MultipleValues;
|
|
public static Color Highlight;
|
|
public static Color TextDark;
|
|
public static Color Base;
|
|
public static Color BaseAlt;
|
|
|
|
public static Color ToggleEnabled;
|
|
public static Color ToggleDisabled;
|
|
|
|
public static float ControlRadius;
|
|
public static float ControlHeight;
|
|
public static float RowHeight;
|
|
|
|
public static string HeadingFont;
|
|
public static string DefaultFont;
|
|
public static string MonospaceFont;
|
|
|
|
static unsafe Theme()
|
|
{
|
|
LoadFromFile();
|
|
|
|
CollectQtColors();
|
|
|
|
PaletteHandle = GCHandle.Alloc( QtColors, GCHandleType.Pinned );
|
|
PalettePtr = (Color32*)PaletteHandle.AddrOfPinnedObject();
|
|
}
|
|
|
|
private static void LoadFromFile()
|
|
{
|
|
var themeJson = FileSystem.Root.ReadAllText( "/addons/tools/assets/styles/theme.json" );
|
|
var theme = Json.Deserialize<Dictionary<string, string>>( themeJson );
|
|
|
|
TabBackground = Color.Parse( theme["TabBackground"] ) ?? Color.Parse( "#3b3b3b" ).Value;
|
|
TabBarBackground = Color.Parse( theme["TabBarBackground"] ) ?? Color.Parse( "#242424" ).Value;
|
|
TabInactiveBackground = Color.Parse( theme["TabInactiveBackground"] ) ?? Color.Parse( "#242424" ).Value;
|
|
SurfaceBackground = Color.Parse( theme["SurfaceBackground"] ) ?? Color.Parse( "#3b3b3b" ).Value;
|
|
SurfaceLightBackground = Color.Parse( theme["SurfaceLightBackground"] ) ?? Color.Parse( "#696969" ).Value;
|
|
SidebarBackground = Color.Parse( theme["SidebarBackground"] ) ?? Color.Parse( "#242424" ).Value;
|
|
WindowBackground = Color.Parse( theme["WindowBackground"] ) ?? Color.Parse( "#181818" ).Value;
|
|
WidgetBackground = Color.Parse( theme["WidgetBackground"] ) ?? Color.Parse( "#242424" ).Value;
|
|
ControlBackground = Color.Parse( theme["ControlBackground"] ) ?? Color.Parse( "#181818" ).Value;
|
|
ButtonBackground = Color.Parse( theme["ButtonBackground"] ) ?? Color.Parse( "#181818" ).Value;
|
|
SelectedBackground = Color.Parse( theme["SelectedBackground"] ) ?? Color.Parse( "#808080" ).Value;
|
|
StatusBarBackground = Color.Parse( theme["StatusBarBackground"] ) ?? Color.Parse( "#242424" ).Value;
|
|
Text = Color.Parse( theme["Text"] ) ?? Color.Parse( "#FFFFFF" ).Value;
|
|
TextControl = Color.Parse( theme["TextControl"] ) ?? Color.Parse( "#FFFFFF" ).Value;
|
|
TextLight = Color.Parse( theme["TextLight"] ) ?? Color.Parse( "#9E9E9E" ).Value;
|
|
TextWidget = Color.Parse( theme["TextWidget"] ) ?? Color.Parse( "#FFFFFF" ).Value;
|
|
TextButton = Color.Parse( theme["TextButton"] ) ?? Color.Parse( "#FFFFFF" ).Value;
|
|
TextSelected = Color.Parse( theme["TextSelected"] ) ?? Color.Parse( "#66a3ff" ).Value;
|
|
TextLink = Color.Parse( theme["TextLink"] ) ?? Color.Parse( "#FFFFFF" ).Value;
|
|
TextHighlight = Color.Parse( theme["TextHighlight"] ) ?? Color.Parse( "#66a3ff" ).Value;
|
|
TextDisabled = Color.Parse( theme["TextDisabled"] ) ?? Color.Parse( "#FFFFFF55" ).Value;
|
|
Border = Color.Parse( theme["Border"] ) ?? Color.Parse( "#525252" ).Value;
|
|
BorderLight = Color.Parse( theme["BorderLight"] ) ?? Color.Parse( "#696969" ).Value;
|
|
BorderButton = Color.Parse( theme["BorderButton"] ) ?? Color.Parse( "#696969" ).Value;
|
|
Shadow = Color.Parse( theme["Shadow"] ) ?? Color.Parse( "#242424" ).Value;
|
|
Primary = Color.Parse( theme["Primary"] ) ?? Color.Parse( "#5a8deb" ).Value;
|
|
Overlay = Color.Parse( theme["Overlay"] ) ?? Color.Parse( "#242424" ).Value;
|
|
MultipleValues = Color.Parse( theme["MultipleValues"] ) ?? Color.Parse( "#808080" ).Value;
|
|
Highlight = Color.Parse( theme["Highlight"] ) ?? Color.Parse( "#9E9E9E" ).Value;
|
|
TextDark = Color.Parse( theme["TextDark"] ) ?? Color.Parse( "#000000" ).Value;
|
|
Base = Color.Parse( theme["Base"] ) ?? Color.Parse( "#202020" ).Value;
|
|
BaseAlt = Color.Parse( theme["BaseAlt"] ) ?? Color.Parse( "#242424" ).Value;
|
|
|
|
ToggleEnabled = Color.Parse( theme["ToggleEnabled"] ) ?? Color.Parse( "#5aeb5c" ).Value;
|
|
ToggleDisabled = Color.Parse( theme["ToggleDisabled"] ) ?? Color.Parse( "#566e56" ).Value;
|
|
|
|
Blue = Color.Parse( theme["Blue"] ) ?? Color.Parse( "#3273EB" ).Value;
|
|
Green = Color.Parse( theme["Green"] ) ?? Color.Parse( "#B0E24D" ).Value;
|
|
Red = Color.Parse( theme["Red"] ) ?? Color.Parse( "#FB5A5A" ).Value;
|
|
Yellow = Color.Parse( theme["Yellow"] ) ?? Color.Parse( "#E6DB74" ).Value;
|
|
Pink = Color.Parse( theme["Pink"] ) ?? Color.Parse( "#DF9194" ).Value;
|
|
|
|
Prefab = Color.Parse( theme["Prefab"] ) ?? Color.Parse( "#3273EB" ).Value;
|
|
Folder = Color.Parse( theme["Folder"] ) ?? Color.Parse( "#E6DB74" ).Value;
|
|
|
|
if ( !float.TryParse( theme["ControlRadius"], out ControlRadius ) )
|
|
ControlRadius = 3.0f;
|
|
|
|
if ( !float.TryParse( theme["ControlHeight"], out ControlHeight ) )
|
|
ControlHeight = 18.0f;
|
|
|
|
if ( !float.TryParse( theme["RowHeight"], out RowHeight ) )
|
|
RowHeight = 16.0f;
|
|
|
|
HeadingFont = theme["HeadingFont"];
|
|
DefaultFont = theme["DefaultFont"];
|
|
MonospaceFont = theme["MonospaceFont"];
|
|
}
|
|
|
|
public static Color GetTint( EditorTint tint )
|
|
{
|
|
return tint switch
|
|
{
|
|
EditorTint.Blue => Blue,
|
|
EditorTint.Green => Green,
|
|
EditorTint.Red => Red,
|
|
EditorTint.Yellow => Yellow,
|
|
EditorTint.Pink => Pink,
|
|
_ => Color.White
|
|
};
|
|
}
|
|
|
|
public static void DrawFilename( Rect rect, string filename, TextFlag flags, Color color )
|
|
{
|
|
var dir = System.IO.Path.GetDirectoryName( filename ) + "/";
|
|
var file = System.IO.Path.GetFileNameWithoutExtension( filename );
|
|
var extension = System.IO.Path.GetExtension( filename );
|
|
|
|
// if we really cared we could do this better
|
|
var size = Paint.MeasureText( rect, filename, flags );
|
|
var overshoot = (size.Width - rect.Width) + 5;
|
|
if ( overshoot > 0 )
|
|
{
|
|
overshoot += 10;
|
|
var startIndex = (overshoot / 4).CeilToInt();
|
|
|
|
if ( startIndex < dir.Length )
|
|
dir = ".." + dir.Substring( startIndex );
|
|
else
|
|
dir = "";
|
|
}
|
|
|
|
dir = dir.Replace( '\\', '/' );
|
|
|
|
Paint.SetPen( color.Darken( 0.3f ) );
|
|
var r = Paint.DrawText( rect, dir, flags );
|
|
rect.Left += r.Width;
|
|
Paint.SetPen( color );
|
|
r = Paint.DrawText( rect, file, flags );
|
|
rect.Left += r.Width;
|
|
Paint.SetPen( color.Darken( 0.1f ) );
|
|
r = Paint.DrawText( rect, extension, flags );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draw a button with a background color, text, and an optional icon. We'll use Paint.HasPressed and Paint.HasMouseOver to determine the button's state.
|
|
/// </summary>
|
|
public static void DrawButton( Rect LocalRect, string text = null, string Icon = null, bool Enabled = true, Color? Tint = null )
|
|
{
|
|
var c = Tint?.ToHsv() ?? Color.Parse( "#48494c" )?.ToHsv() ?? default;
|
|
var bg = c;
|
|
|
|
if ( Enabled )
|
|
{
|
|
if ( Paint.HasPressed )
|
|
{
|
|
bg = c with { Value = (c.Value + 0.1f) };
|
|
}
|
|
else if ( Paint.HasMouseOver )
|
|
{
|
|
bg = c with { Value = (c.Value + 0.2f) };
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bg = c = Theme.SurfaceLightBackground;
|
|
}
|
|
|
|
if ( !Enabled )
|
|
{
|
|
c = c.WithSaturation( 0.1f ).WithAlpha( 0.5f );
|
|
bg = c.WithAlpha( 0.2f );
|
|
}
|
|
|
|
if ( bg.Alpha > 0 )
|
|
{
|
|
float radius = 3;
|
|
Paint.Antialiasing = true;
|
|
|
|
Paint.ClearPen();
|
|
Paint.SetBrush( bg with { Value = (bg.Value + 0.04f), Saturation = (c.Saturation * 0.8f) } );
|
|
Paint.DrawRect( LocalRect, radius );
|
|
|
|
Paint.SetBrushLinear( LocalRect.TopLeft, LocalRect.BottomRight, bg, bg with { Value = (bg.Value - 0.03f) } );
|
|
Paint.DrawRect( LocalRect.Shrink( 1, 1, 1, 1 ), radius );
|
|
}
|
|
else
|
|
{
|
|
c = Color.White.WithAlpha( 0.5f );
|
|
}
|
|
|
|
Paint.SetDefaultFont();
|
|
|
|
if ( !string.IsNullOrWhiteSpace( text ) )
|
|
{
|
|
var textSize = Paint.MeasureText( text );
|
|
float iconSize = 16;
|
|
float spacing = 4;
|
|
|
|
float startX = 8;
|
|
float centerY = LocalRect.Center.y;
|
|
|
|
Paint.SetPen( c with { Value = 0.99f, Saturation = c.Saturation * 0.20f } );
|
|
|
|
if ( !string.IsNullOrWhiteSpace( Icon ) )
|
|
{
|
|
var iconRect = new Rect( startX, centerY - iconSize / 2, iconSize, iconSize );
|
|
Paint.DrawIcon( iconRect, Icon, iconSize );
|
|
startX += iconSize + spacing;
|
|
}
|
|
|
|
Paint.SetPen( c with { Value = 0.99f, Saturation = c.Saturation * 0.20f, Alpha = 0.75f } );
|
|
|
|
var textRect = new Rect( startX, LocalRect.Top, textSize.x, LocalRect.Height );
|
|
Paint.DrawText( textRect, text, TextFlag.Center );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draw a dropdown control with a text label and an icon. Has a up/down chevron icon to indicate the dropdown state.
|
|
/// </summary>
|
|
public static void DrawDropdown( Rect rect, string text, string icon, bool open, bool disabled = false )
|
|
{
|
|
Paint.ClearPen();
|
|
|
|
if ( open ) Paint.SetBrush( Theme.ControlBackground.LerpTo( Theme.Green, 0.05f ) );
|
|
else Paint.SetBrush( Theme.ControlBackground );
|
|
|
|
Paint.DrawRect( rect, Theme.ControlRadius );
|
|
|
|
// cap off the bottom
|
|
if ( open )
|
|
{
|
|
Paint.DrawRect( rect.Shrink( 0, 4, 0, 0 ) );
|
|
}
|
|
|
|
if ( disabled ) Paint.SetPen( Theme.Text.WithAlpha( 0.2f ) );
|
|
else if ( open ) Paint.SetPen( Theme.Green );
|
|
else if ( Paint.HasMouseOver ) Paint.SetPen( Theme.TextButton.WithAlpha( 0.7f ) );
|
|
else Paint.SetPen( Theme.TextButton.WithAlpha( 0.5f ) );
|
|
|
|
Paint.DrawIcon( rect.Shrink( 0, 0, 4, 0 ), open ? "expand_less" : "expand_more", rect.Height - 3, TextFlag.RightCenter );
|
|
Paint.DrawIcon( rect.Shrink( 4, 0, 0, 0 ), icon, 16, TextFlag.LeftCenter );
|
|
|
|
Paint.SetDefaultFont();
|
|
Paint.DrawText( rect.Shrink( 30, 0, 26, 0 ), text, TextFlag.LeftCenter );
|
|
}
|
|
|
|
internal static string ParseVariables( string input )
|
|
{
|
|
var values = new Dictionary<string, string>();
|
|
var fields = typeof( Theme ).GetFields();
|
|
|
|
foreach ( var field in fields )
|
|
{
|
|
var value = field.GetValue( null );
|
|
|
|
if ( value is Color color )
|
|
{
|
|
values.Add( $"${field.Name}", color.Hex );
|
|
}
|
|
else if ( value is float f )
|
|
{
|
|
values.Add( $"${field.Name}", $"{f}px" );
|
|
}
|
|
else if ( value is string s )
|
|
{
|
|
values.Add( $"${field.Name}", s );
|
|
}
|
|
}
|
|
|
|
// Sort by length so we don't stomp stuff, e.g. $Surface and $SurfaceSubtle
|
|
values = values.OrderByDescending( x => x.Key.Length ).ToDictionary();
|
|
|
|
foreach ( var color in values )
|
|
{
|
|
input = input.Replace( color.Key, color.Value );
|
|
}
|
|
|
|
return input;
|
|
}
|
|
}
|