namespace Sandbox.UI; public partial class Panel { string previouslyLoadedTemplateStylesheet; private void LoadStyleSheet() { if ( LoadStyleSheetFromAttribute() ) return; if ( LoadStyleSheetAuto() ) return; } /// /// Loads a stylesheet from one specified within a [StyleSheet] attribute. /// /// True if the attribute exists and we loaded from it, otherwise false private bool LoadStyleSheetFromAttribute() { var type = Game.TypeLibrary?.GetType( GetType() ); var attr = type?.GetAttribute( false ); if ( attr == null ) { if ( !string.IsNullOrWhiteSpace( previouslyLoadedTemplateStylesheet ) ) StyleSheet.Remove( previouslyLoadedTemplateStylesheet ); previouslyLoadedTemplateStylesheet = null; return false; } var path = attr?.Name; var classFileLocation = type?.GetAttributes() .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 ); } /// /// Loads a stylesheet from one based on the class name. /// /// True if the attribute exists and we loaded from it, otherwise false private bool LoadStyleSheetAuto() { var type = Game.TypeLibrary?.GetType( GetType() ); // Get the shortest class file (incase we have MyPanel.SomeStuff.Blah) var classFileLocation = type?.GetAttributes() .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 ); } /// /// Loads a stylesheet from the specified path. /// /// True if the stylesheet was loaded successfully, otherwise false 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; } /// /// 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. /// public virtual void OnTemplateSlot( Html.INode element, string slotName, Panel panel ) { Parent?.OnTemplateSlot( element, slotName, panel ); } }