Files
sbox-public/engine/Sandbox.Engine/Systems/UI/Panel/Panel.Style.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

99 lines
3.0 KiB
C#

namespace Sandbox.UI;
public partial class Panel
{
/// <summary>
/// This is the style that we computed last. If you're looking to see which
/// styles are set on this panel then this is what you're looking for.
/// </summary>
[Hide]
public Styles ComputedStyle { get; internal set; }
/// <summary>
/// A importance sorted list of style blocks that are active on this panel
/// </summary>
[Hide]
public IEnumerable<IStyleBlock> ActiveStyleBlocks => Style?.LastActiveRules?.Select( x => x.Block ) ?? Enumerable.Empty<IStyleBlock>();
/// <summary>
/// Allows you to set styles specifically on this panel. Setting the style will
/// only affect this panel and no others and will override any other styles.
/// </summary>
[Hide]
public PanelStyle Style { get; private set; }
/// <summary>
/// Try to find <c>@keyframes</c> CSS rule with given name in <see cref="AllStyleSheets"/>.
/// </summary>
/// <param name="name">The name to search for.</param>
/// <param name="keyframes">The keyframes, if any are found, or <see langword="null"/>.</param>
/// <returns><see langword="true"/> if <c>@keyframes</c> with given name were found.</returns>
public bool TryFindKeyframe( string name, out KeyFrames keyframes )
{
// TODO: optimization - cache found keyframes? Clear on load?
keyframes = null;
foreach ( var sheet in AllStyleSheets )
{
if ( sheet.KeyFrames.TryGetValue( name, out var keyframe ) )
{
keyframes = keyframe;
return true;
}
}
return false;
}
internal void MarkStylesRebuilt()
{
inRebuildStyleRulesList = false;
inRebuildStyleRulesList_Ancestors = false;
inRebuildStyleRulesList_Children = false;
}
bool inRebuildStyleRulesList;
bool inRebuildStyleRulesList_Ancestors;
bool inRebuildStyleRulesList_Children;
/// <summary>
/// Should be called when something happens that means that this panel's stylesheets need to be
/// re-evaluated. Like becoming hovered or classes changed. You don't call this when changing styles
/// directly on the panel, just on anything that will change which stylesheets should get selected.
/// </summary>
/// <param name="ancestors">Also re-evaluate all ancestor panels. (for <c>:has()</c>)</param>
/// <param name="descendants">Also re-evaluate all child panels. (for parent selectors)</param>
/// <param name="root">Root panel cache so we don't need to keep looking it up.</param>
protected void StyleSelectorsChanged( bool ancestors, bool descendants, RootPanel root = null )
{
root ??= FindRootPanel();
if ( root == null )
return;
if ( ancestors && !inRebuildStyleRulesList_Ancestors )
{
inRebuildStyleRulesList_Ancestors = true;
Parent?.StyleSelectorsChanged( true, false, root );
}
if ( descendants && !inRebuildStyleRulesList_Children && HasChildren )
{
inRebuildStyleRulesList_Children = true;
foreach ( var child in Children )
{
child.StyleSelectorsChanged( false, true, root );
}
}
if ( !inRebuildStyleRulesList )
{
inRebuildStyleRulesList = true;
root.AddToBuildStyleRulesList( this );
}
}
}