Files
sbox-public/engine/Sandbox.Engine/Systems/UI/Styles/BaseStyles.cs
Alex Guthrie 8421496ed2 Menu: New games dashboard (#4468)
* Common components

* Replace PackageCard with GameCard in content blocks, wrapped grid layout

* Move GameCard to New/ folder, use ThumbWide for all sizes

* Add `overflow: clip` and `overflow: clip-whole` modes

* New game hub layout, hero

* Layout + hero tweaks

* Hero tweaks

* Clean up content blocks, make it so that game cards don't clip on hover

* Dynamic mask

* Don't bother building CL for panels outside scroll view (400% perf benefit in main game hub)

* Disable 3D bg when not visible (50% performance benefit)

* Cards take their sizes from the image within them

* Stash tweaks before big refactor

* Initial hero carousel

* Better carousel transitions

* Try and reduce allocs inside CL combos

* `background-playback-state` CSS property (`paused` or `running`, applies to video `background-image`)

* Make out-of-focus carousel elements more obvious (no playing video, darkened)

* New branding

* Tweak navbar

* Carousel shows full thumb if not visible, helps with visual noise

* Accurate vote percentage 🙈

* Fix some carousel jankiness

* Navbar feels less disjointed

* Rebake menu lighting & envmaps

* Finalize

https://files.facepunch.com/alexguthrie/1b0311b1/bZKOQIQD0o.jpg

* Trim down visual noise

https://files.facepunch.com/alexguthrie/1b0311b1/oJh4qqaPsC.jpg

* Gradient

https://files.facepunch.com/alexguthrie/1b0511b1/uCyZyolkXE.jpg

* Format

* .heading labels use heading vars

* Carousel slower time between auto switch

* No play button on GameCard

* Content blocks full width

* Adjust GameCard sizes

* Content block header padding

* Add MenuHelpers.PlayGame, GameModal uses it, make hero "Play Now" button use it

---------

Co-authored-by: Matt Stevens <matt@mattstevens.co.uk>
2026-04-08 17:00:02 +00:00

135 lines
3.2 KiB
C#

namespace Sandbox.UI;
public abstract partial class BaseStyles : ICloneable
{
/// <summary>
/// Called when any CSS properties are changed.
/// </summary>
public abstract void Dirty();
/// <summary>
/// Represents the <c>overflow</c> CSS property.
/// </summary>
public OverflowMode? Overflow
{
get
{
if ( _overflowx.HasValue && _overflowx.Value == OverflowMode.Scroll ) return OverflowMode.Scroll;
if ( _overflowy.HasValue && _overflowy.Value == OverflowMode.Scroll ) return OverflowMode.Scroll;
return _overflowx ?? _overflowy;
}
set
{
if ( _overflowx == value && _overflowy == value ) return;
_overflowx = value;
_overflowy = value;
Dirty();
}
}
/// <summary>
/// Copy over only the styles that are set.
/// </summary>
public virtual void Add( BaseStyles bs )
{
AddGenerated( bs );
if ( bs._backgroundImage != null ) _backgroundImage = bs._backgroundImage;
if ( bs._maskImage != null ) _maskImage = bs._maskImage;
if ( bs._borderImageSource != null ) _borderImageSource = bs._borderImageSource;
if ( bs._backgroundPlaybackPaused.HasValue ) _backgroundPlaybackPaused = bs._backgroundPlaybackPaused;
}
/// <summary>
/// Copy all styles from given style set.
/// </summary>
public virtual void From( BaseStyles bs )
{
FromGenerated( bs );
_backgroundImage = bs._backgroundImage;
_maskImage = bs._maskImage;
_borderImageSource = bs._borderImageSource;
_backgroundPlaybackPaused = bs._backgroundPlaybackPaused;
}
/// <summary>
/// Copy all styles from given style set.
/// </summary>
public virtual bool Set( string property, string value )
{
if ( SetGenerated( property, value ) )
return true;
switch ( property )
{
case "overflow":
return SetOverflow( value, x => Overflow = x );
case "overflow-x":
return SetOverflow( value, x => OverflowX = x );
case "overflow-y":
return SetOverflow( value, x => OverflowY = x );
}
return false;
}
public void FillDefaults()
{
_overflowx ??= Overflow ?? OverflowMode.Visible;
_overflowy ??= Overflow ?? OverflowMode.Visible;
FillDefaultsGenerated();
}
bool SetOverflow( string value, Action<OverflowMode> set )
{
switch ( value )
{
case "hidden":
set( OverflowMode.Hidden );
return true;
case "scroll":
set( OverflowMode.Scroll );
return true;
case "clip":
set( OverflowMode.Clip );
return true;
case "clip-whole":
set( OverflowMode.ClipWhole );
return true;
case "visible":
set( OverflowMode.Visible );
return true;
default:
Log.Warning( $"Unhandled overflow property: {value}" );
return false;
}
}
/// <summary>
/// Set Left, Right, Width and Height based on this rect. Scale can be used to scale the rect (maybe you want to use Panel.ScaleFromScreen etc)
/// </summary>
public void SetRect( in Rect r, float scale = 1.0f )
{
Top = Length.Pixels( r.Top * scale );
Left = Length.Pixels( r.Left * scale );
Width = Length.Pixels( r.Width * scale );
Height = Length.Pixels( r.Height * scale );
}
public override int GetHashCode()
{
var generated_hash = GetHashCodeGenerated();
generated_hash = HashCode.Combine( generated_hash, _backgroundImage, _borderImageSource, _maskImage, _backgroundPlaybackPaused );
return generated_hash;
}
}