mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-20 04:10:00 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
297 lines
7.4 KiB
C#
297 lines
7.4 KiB
C#
using Sandbox.Engine;
|
|
|
|
namespace Sandbox.UI;
|
|
|
|
/// <summary>
|
|
/// Represents all supported CSS properties and their currently assigned values.
|
|
/// </summary>
|
|
[SkipHotload]
|
|
public partial class Styles : BaseStyles
|
|
{
|
|
internal Dictionary<string, IStyleBlock.StyleProperty> RawValues = new Dictionary<string, IStyleBlock.StyleProperty>( StringComparer.OrdinalIgnoreCase );
|
|
internal GradientInfo TextGradient;
|
|
|
|
/// <summary>
|
|
/// Whether this style sheet has any transitions that would need to be run.
|
|
/// </summary>
|
|
public bool HasTransitions => Transitions != null && Transitions.List.Count > 0;
|
|
|
|
/// <summary>
|
|
/// List of transitions this style sheet has.
|
|
/// </summary>
|
|
public TransitionList Transitions;
|
|
|
|
//
|
|
// Shadows
|
|
//
|
|
public ShadowList BoxShadow = new ShadowList();
|
|
public ShadowList TextShadow = new ShadowList();
|
|
public ShadowList FilterDropShadow = new ShadowList();
|
|
|
|
public Styles()
|
|
{
|
|
|
|
}
|
|
|
|
public override void Dirty()
|
|
{
|
|
// Nothing
|
|
}
|
|
|
|
public Length? Padding
|
|
{
|
|
set
|
|
{
|
|
PaddingLeft = value;
|
|
PaddingTop = value;
|
|
PaddingRight = value;
|
|
PaddingBottom = value;
|
|
}
|
|
}
|
|
|
|
public Length? Margin
|
|
{
|
|
set
|
|
{
|
|
MarginLeft = value;
|
|
MarginTop = value;
|
|
MarginRight = value;
|
|
MarginBottom = value;
|
|
}
|
|
}
|
|
|
|
public Length? BorderWidth
|
|
{
|
|
set
|
|
{
|
|
BorderLeftWidth = value;
|
|
BorderRightWidth = value;
|
|
BorderTopWidth = value;
|
|
BorderBottomWidth = value;
|
|
}
|
|
}
|
|
|
|
public Color? BorderColor
|
|
{
|
|
set
|
|
{
|
|
BorderLeftColor = value;
|
|
BorderRightColor = value;
|
|
BorderTopColor = value;
|
|
BorderBottomColor = value;
|
|
}
|
|
}
|
|
|
|
public bool HasBorder
|
|
{
|
|
get
|
|
{
|
|
if ( BorderTopWidth.HasValue && BorderTopWidth.Value.Value > 0 ) return true;
|
|
if ( BorderRightWidth.HasValue && BorderRightWidth.Value.Value > 0 ) return true;
|
|
if ( BorderBottomWidth.HasValue && BorderBottomWidth.Value.Value > 0 ) return true;
|
|
if ( BorderLeftWidth.HasValue && BorderLeftWidth.Value.Value > 0 ) return true;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public Margin GetInset( Vector2 size )
|
|
{
|
|
var border = Sandbox.UI.Margin.GetEdges( size, BorderLeftWidth, BorderTopWidth, BorderRightWidth, BorderBottomWidth );
|
|
var padding = Sandbox.UI.Margin.GetEdges( size, PaddingLeft, PaddingTop, PaddingRight, PaddingBottom );
|
|
|
|
return border + padding;
|
|
}
|
|
|
|
public Margin GetOutset( Vector2 size ) => Sandbox.UI.Margin.GetEdges( size, MarginLeft, MarginTop, MarginRight, MarginBottom );
|
|
|
|
public readonly static Styles Default = new Styles
|
|
{
|
|
Padding = 0
|
|
};
|
|
|
|
internal bool SetInternal( string styles, string filename, int lineoffset )
|
|
{
|
|
bool success = false;
|
|
|
|
Parse p = new( styles, filename, lineoffset );
|
|
|
|
while ( !p.IsEnd )
|
|
{
|
|
p = p.SkipWhitespaceAndNewlines();
|
|
var property = p.ReadUntilOrEnd( " :;" );
|
|
|
|
p = p.SkipWhitespaceAndNewlines();
|
|
|
|
if ( p.IsEnd )
|
|
break;
|
|
|
|
if ( p.Current != ':' )
|
|
throw new System.Exception( $"Error parsing style: {styles}" );
|
|
|
|
p.Pointer++;
|
|
|
|
p = p.SkipWhitespaceAndNewlines();
|
|
if ( p.IsEnd )
|
|
throw new System.Exception( $"Error parsing style: {styles}" );
|
|
|
|
var line = p.CurrentLine;
|
|
var value = p.ReadUntilOrEnd( ";" );
|
|
p.Pointer++;
|
|
|
|
bool wasSuccessful = Set( property, value );
|
|
if ( !wasSuccessful )
|
|
{
|
|
Log.Error( $"{value} is not valid with {property} {p.FileAndLine}" );
|
|
}
|
|
|
|
var prop = new IStyleBlock.StyleProperty
|
|
{
|
|
Name = property,
|
|
Value = value,
|
|
OriginalValue = value,
|
|
Line = line,
|
|
IsValid = wasSuccessful
|
|
};
|
|
|
|
RawValues[property] = prop;
|
|
success = wasSuccessful || success;
|
|
|
|
p = p.SkipWhitespaceAndNewlines();
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
public bool Set( string styles )
|
|
{
|
|
return SetInternal( styles, null, 0 );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a matrix based on this style's "transform" and other related properties
|
|
/// </summary>
|
|
public Matrix BuildTransformMatrix( Vector2 size )
|
|
{
|
|
if ( Transform?.IsEmpty() ?? true )
|
|
return Matrix.Identity;
|
|
|
|
var t = Transform.Value;
|
|
|
|
Vector2 perspectiveCenter = new Vector2( size.x * 0.5f, size.y * 0.5f );
|
|
Vector2 perspectiveOrigin = perspectiveCenter;
|
|
|
|
if ( PerspectiveOriginX.HasValue )
|
|
{
|
|
perspectiveOrigin.x = PerspectiveOriginX.Value.GetPixels( size.x );
|
|
}
|
|
|
|
if ( PerspectiveOriginY.HasValue )
|
|
{
|
|
perspectiveOrigin.y = PerspectiveOriginY.Value.GetPixels( size.y );
|
|
}
|
|
|
|
return t.BuildTransform( size.x, size.y, perspectiveOrigin - perspectiveCenter );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Try to find all panels using this style and mark them dirty so they'll
|
|
/// redraw with the style. This should be called when the style is changed. Which
|
|
/// is only technically when done via the editor.
|
|
/// </summary>
|
|
internal void MarkPanelsDirty()
|
|
{
|
|
foreach ( var panel in GlobalContext.Current.UISystem.RootPanels )
|
|
{
|
|
// Dirty all panels that contain this style
|
|
panel.DirtyStylesWithStyle( this, true );
|
|
}
|
|
}
|
|
|
|
public override void LerpProperty( string name, BaseStyles from, BaseStyles to, float delta )
|
|
{
|
|
base.LerpProperty( name, from, to, delta );
|
|
|
|
//
|
|
// Properties that aren't auto-generated (i.e. ones not defined in BaseStyles, but are defined in this class)
|
|
//
|
|
if ( from is Styles a && to is Styles b )
|
|
{
|
|
switch ( name )
|
|
{
|
|
case "box-shadow":
|
|
if ( a.BoxShadow != b.BoxShadow )
|
|
BoxShadow.SetFromLerp( a.BoxShadow, b.BoxShadow, delta );
|
|
break;
|
|
|
|
case "text-shadow":
|
|
if ( a.TextShadow != b.TextShadow )
|
|
TextShadow.SetFromLerp( a.TextShadow, b.TextShadow, delta );
|
|
break;
|
|
|
|
case "filter-drop-shadow":
|
|
if ( a.FilterDropShadow != b.FilterDropShadow )
|
|
FilterDropShadow.SetFromLerp( a.FilterDropShadow, b.FilterDropShadow, delta );
|
|
break;
|
|
|
|
case "padding":
|
|
LerpProperty( "padding-left", from, to, delta );
|
|
LerpProperty( "padding-right", from, to, delta );
|
|
LerpProperty( "padding-bottom", from, to, delta );
|
|
LerpProperty( "padding-top", from, to, delta );
|
|
break;
|
|
|
|
case "margin":
|
|
LerpProperty( "margin-left", from, to, delta );
|
|
LerpProperty( "margin-right", from, to, delta );
|
|
LerpProperty( "margin-bottom", from, to, delta );
|
|
LerpProperty( "margin-top", from, to, delta );
|
|
break;
|
|
|
|
case "border-color":
|
|
LerpProperty( "border-color-left", from, to, delta );
|
|
LerpProperty( "border-color-right", from, to, delta );
|
|
LerpProperty( "border-color-bottom", from, to, delta );
|
|
LerpProperty( "border-color-top", from, to, delta );
|
|
break;
|
|
|
|
case "border-width":
|
|
LerpProperty( "border-width-left", from, to, delta );
|
|
LerpProperty( "border-width-right", from, to, delta );
|
|
LerpProperty( "border-width-bottom", from, to, delta );
|
|
LerpProperty( "border-width-top", from, to, delta );
|
|
break;
|
|
|
|
case "border-radius":
|
|
LerpProperty( "border-top-left-radius", from, to, delta );
|
|
LerpProperty( "border-top-right-radius", from, to, delta );
|
|
LerpProperty( "border-bottom-right-radius", from, to, delta );
|
|
LerpProperty( "border-bottom-left-radius", from, to, delta );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void FromLerp( BaseStyles from, BaseStyles to, float delta )
|
|
{
|
|
base.FromLerp( from, to, delta );
|
|
|
|
//
|
|
// Shadows
|
|
//
|
|
if ( from is Styles a && to is Styles b )
|
|
{
|
|
if ( a.BoxShadow != b.BoxShadow )
|
|
BoxShadow.SetFromLerp( a.BoxShadow, b.BoxShadow, delta );
|
|
|
|
if ( a.TextShadow != b.TextShadow )
|
|
TextShadow.SetFromLerp( a.TextShadow, b.TextShadow, delta );
|
|
|
|
if ( a.FilterDropShadow != b.FilterDropShadow )
|
|
FilterDropShadow.SetFromLerp( a.FilterDropShadow, b.FilterDropShadow, delta );
|
|
}
|
|
}
|
|
}
|
|
|