Files
sbox-public/engine/Sandbox.Engine/Systems/UI/Panel/Panel.Template.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

117 lines
3.5 KiB
C#

namespace Sandbox.UI;
public partial class Panel
{
string previouslyLoadedTemplateStylesheet;
private void LoadStyleSheet()
{
if ( LoadStyleSheetFromAttribute() )
return;
if ( LoadStyleSheetAuto() )
return;
}
/// <summary>
/// Loads a stylesheet from one specified within a [StyleSheet] attribute.
/// </summary>
/// <returns>True if the attribute exists and we loaded from it, otherwise false</returns>
private bool LoadStyleSheetFromAttribute()
{
var type = Game.TypeLibrary?.GetType( GetType() );
var attr = type?.GetAttribute<StyleSheetAttribute>( false );
if ( attr == null )
{
if ( !string.IsNullOrWhiteSpace( previouslyLoadedTemplateStylesheet ) )
StyleSheet.Remove( previouslyLoadedTemplateStylesheet );
previouslyLoadedTemplateStylesheet = null;
return false;
}
var path = attr?.Name;
var classFileLocation = type?.GetAttributes<Internal.ClassFileLocationAttribute>()
.MinBy( x => x.Path.Length );
if ( path == null && classFileLocation == null )
{
Log.Warning( $"{this} has [StyleSheet] but ClassFileLocation wasn't generated!" );
}
var fullPath = GetFullPath( path, classFileLocation );
return LoadStyleSheetFromPath( fullPath, false );
}
/// <summary>
/// Loads a stylesheet from one based on the class name.
/// </summary>
/// <returns>True if the attribute exists and we loaded from it, otherwise false</returns>
private bool LoadStyleSheetAuto()
{
var type = Game.TypeLibrary?.GetType( GetType() );
// Get the shortest class file (incase we have MyPanel.SomeStuff.Blah)
var classFileLocation = type?.GetAttributes<Internal.ClassFileLocationAttribute>()
.MinBy( x => x.Path.Length );
if ( classFileLocation == null )
{
// Couldn't find a stylesheet w/ the class name, but this isn't an error, fail silently.
return false;
}
var fullPath = GetFullPath( null, classFileLocation );
return LoadStyleSheetFromPath( fullPath, true );
}
/// <summary>
/// Loads a stylesheet from the specified path.
/// </summary>
/// <returns>True if the stylesheet was loaded successfully, otherwise false</returns>
private bool LoadStyleSheetFromPath( string path, bool failSilently )
{
path = BaseFileSystem.NormalizeFilename( path );
// Nothing to do
if ( previouslyLoadedTemplateStylesheet == path )
return true;
// Remove old sheet
if ( !string.IsNullOrWhiteSpace( previouslyLoadedTemplateStylesheet ) )
StyleSheet.Remove( previouslyLoadedTemplateStylesheet );
// Add new one
previouslyLoadedTemplateStylesheet = path;
StyleSheet.Load( previouslyLoadedTemplateStylesheet, true, failSilently );
return true;
}
private string GetFullPath( string path, Internal.ClassFileLocationAttribute classFileLocation )
{
if ( string.IsNullOrWhiteSpace( path ) && classFileLocation != null )
{
return classFileLocation.Path + ".scss";
}
else if ( classFileLocation != null && (!path.StartsWith( '/' ) && !path.StartsWith( '\\' )) )
{
var newpath = System.IO.Path.GetDirectoryName( classFileLocation.Path );
newpath = System.IO.Path.Combine( newpath, path );
return newpath;
}
return path;
}
/// <summary>
/// TODO: Obsolete this and instead maybe we have something like [PanelSlot( "slotname" )] that
/// is applied on properties. Then when we find a slot="slotname" we chase up the heirachy and set the property.
/// </summary>
public virtual void OnTemplateSlot( Html.INode element, string slotName, Panel panel )
{
Parent?.OnTemplateSlot( element, slotName, panel );
}
}