Sandbox updates 3 (#3589)

* Gibs copy tint
* Add ClientEditableAttribute
* Panel based ControlSheet supports ToggleGroup
* Panel based ControlSheet hides empty titles
* Fix SliderControl default step
* Fix SliderControl text box resizing
* Fix slidercontrol number entry not getting styled
* ControlSheetGroup support ShowIf
* Make wheel joint properties ClientEditable, add steps
This commit is contained in:
Garry Newman
2025-12-10 14:43:30 +00:00
committed by GitHub
parent 91f8fcf183
commit 5046b22eee
10 changed files with 220 additions and 19 deletions

View File

@@ -498,6 +498,7 @@ public class Prop : Component, Component.ExecuteInEditor, Component.IDamageable
return gibs;
var rb = Components.Get<Rigidbody>();
var mr = Components.Get<ModelRenderer>();
gibs.EnsureCapacity( breaklist.Length );
@@ -531,6 +532,7 @@ public class Prop : Component, Component.ExecuteInEditor, Component.IDamageable
c.FadeTime = breakModel.FadeTime;
c.Model = model;
c.Enabled = true;
c.Tint = mr?.Tint ?? c.Tint;
gibs.Add( c );

View File

@@ -9,7 +9,7 @@
public sealed class WheelJoint : Joint
{
/// <inheritdoc cref="Physics.WheelJoint.EnableSuspensionLimit"/>
[Property, ToggleGroup( "EnableSuspensionLimit", Label = "Suspension Limit" ), ShowIf( nameof( EnableSuspension ), true )]
[Property, ToggleGroup( "EnableSuspensionLimit", Label = "Suspension Limit" ), ShowIf( nameof( EnableSuspension ), true ), ClientEditable]
public bool EnableSuspensionLimit
{
get;
@@ -28,7 +28,7 @@ public sealed class WheelJoint : Joint
}
/// <inheritdoc cref="Physics.WheelJoint.SuspensionLimits"/>
[Property, Group( "EnableSuspensionLimit" ), Title( "Translation Limits" ), Range( -25, 25 ), ShowIf( nameof( EnableSuspension ), true )]
[Property, Group( "EnableSuspensionLimit" ), Title( "Translation Limits" ), Range( -25, 25 ), ShowIf( nameof( EnableSuspension ), true ), ClientEditable]
public Vector2 SuspensionLimits
{
get;
@@ -47,7 +47,7 @@ public sealed class WheelJoint : Joint
}
/// <inheritdoc cref="Physics.WheelJoint.EnableSpinMotor"/>
[Property, ToggleGroup( "EnableSpinMotor", Label = "Motor" )]
[Property, ToggleGroup( "EnableSpinMotor", Label = "Motor" ), ClientEditable]
public bool EnableSpinMotor
{
get;
@@ -66,7 +66,7 @@ public sealed class WheelJoint : Joint
}
/// <inheritdoc cref="Physics.WheelJoint.MaxSpinTorque"/>
[Property, Group( "EnableSpinMotor" ), Title( "Max Torque" )]
[Property, Group( "EnableSpinMotor" ), Title( "Max Torque" ), ClientEditable]
public float MaxSpinTorque
{
get;
@@ -85,7 +85,7 @@ public sealed class WheelJoint : Joint
}
/// <inheritdoc cref="Physics.WheelJoint.SpinMotorSpeed"/>
[Property, Group( "EnableSpinMotor" ), Title( "Speed" )]
[Property, Group( "EnableSpinMotor" ), Title( "Speed" ), ClientEditable]
public float SpinMotorSpeed
{
get;
@@ -104,7 +104,7 @@ public sealed class WheelJoint : Joint
}
/// <inheritdoc cref="Physics.WheelJoint.EnableSuspension"/>
[Property, ToggleGroup( "EnableSuspension", Label = "Suspension" )]
[Property, ToggleGroup( "EnableSuspension", Label = "Suspension" ), ClientEditable]
public bool EnableSuspension
{
get;
@@ -142,7 +142,7 @@ public sealed class WheelJoint : Joint
}
/// <inheritdoc cref="Physics.WheelJoint.SuspensionHertz"/>
[Property, Group( "EnableSuspension" ), Title( "Hertz" ), Range( 0, 30 )]
[Property, Group( "EnableSuspension" ), Title( "Hertz" ), Range( 0, 30 ), Step( 1 ), ClientEditable]
public float SuspensionHertz
{
get;
@@ -161,7 +161,7 @@ public sealed class WheelJoint : Joint
} = 10.0f;
/// <inheritdoc cref="Physics.WheelJoint.SuspensionDampingRatio"/>
[Property, Group( "EnableSuspension" ), Title( "Damping" ), Range( 0, 2 )]
[Property, Group( "EnableSuspension" ), Title( "Damping" ), Range( 0, 2 ), Step( 0.1f ), ClientEditable]
public float SuspensionDampingRatio
{
get;

View File

@@ -0,0 +1,10 @@
namespace Sandbox;
/// <summary>
/// Indicates that this propery can be edited by the client, in a game like Sandbox Mode. In reality
/// this is used however the game wants to implement it.
/// </summary>
[AttributeUsage( AttributeTargets.Property )]
public sealed class ClientEditableAttribute : Attribute
{
}

View File

@@ -75,9 +75,28 @@ public class ControlSheet : Panel, IControlSheet
void IControlSheet.AddGroup( IControlSheet.Group group )
{
var g = _body.AddChild<ControlSheetGroup>();
g.Header.Title = group.Name;
var title = g.Header.AddChild<Label>( "title" );
title.Text = group.Name;
//
// This is part of a toggle group - so add a checkbox to the header
//
var toggleGroup = group.Properties.FirstOrDefault( x => x.HasAttribute<ToggleGroupAttribute>() && x.Name == group.Name );
if ( toggleGroup is not null )
{
toggleGroup.TryGetAttribute<ToggleGroupAttribute>( out var toggleAttr );
if ( toggleGroup is not null )
{
group.Properties.Remove( toggleGroup );
var enabler = BaseControl.CreateFor( toggleGroup );
g.Header.Title = toggleAttr.Label ?? g.Header.Title;
g.SetToggle( toggleGroup );
g.SetVisibility( toggleGroup.GetAttributes<InspectorVisibilityAttribute>()?.ToArray() );
if ( !toggleGroup.As.Bool ) g.Closed = true;
}
}
foreach ( var prop in group.Properties )
{

View File

@@ -5,14 +5,54 @@ namespace Sandbox.UI;
/// </summary>
public class ControlSheetGroup : Panel
{
public Panel Header { get; set; }
public ControlSheetGroupHeader Header { get; set; }
public Panel ToggleContainer { get; set; }
public Panel Body { get; set; }
public bool Closed { get; internal set; }
InspectorVisibilityAttribute[] _visibility;
public ControlSheetGroup()
{
AddClass( "controlgroup" );
Header = AddChild<Panel>( "header" );
Header = AddChild<ControlSheetGroupHeader>( "header" );
Body = AddChild<Panel>( "body" );
}
/// <summary>
/// Set the control that is going to toggle this group open and closed.
/// </summary>
public void SetToggle( SerializedProperty toggleGroup )
{
Header.ToggleProperty = toggleGroup;
}
public override void Tick()
{
base.Tick();
if ( Header.ToggleProperty != null )
{
Body.SetClass( "hidden", Header.ToggleProperty.As.Bool == false );
}
if ( _visibility?.Length > 0 )
{
SetClass( "hidden", _visibility.All( x => x.TestCondition( Header.ToggleProperty?.Parent ) ) );
}
}
/// <summary>
/// Hide this group if these attributes say so.
/// </summary>
public void SetVisibility( InspectorVisibilityAttribute[] inspectorVisibilityAttributes )
{
_visibility = null;
if ( inspectorVisibilityAttributes?.Length == 0 ) return;
_visibility = inspectorVisibilityAttributes;
}
}

View File

@@ -4,6 +4,11 @@
padding: 0.5rem;
flex-direction: column;
flex-shrink: 0;
&.hidden
{
display: none;
}
}
.controlgroup > .header
@@ -20,4 +25,10 @@
flex-direction: column;
flex-shrink: 0;
gap: 2px;
padding-left: 16px;
&.hidden
{
display: none;
}
}

View File

@@ -0,0 +1,60 @@
namespace Sandbox.UI;
public class ControlSheetGroupHeader : Panel
{
public string Title
{
get;
set
{
field = value;
textLabel.Text = field;
}
}
public string Icon
{
get;
set
{
field = value;
iconLabel.Text = field;
}
}
public SerializedProperty ToggleProperty
{
get;
set
{
field = value;
SetClass( "has-toggle", field != null );
}
}
Label iconLabel;
Label textLabel;
public ControlSheetGroupHeader()
{
iconLabel = AddChild<Label>( "icon" );
textLabel = AddChild<Label>( "title" );
}
public override void Tick()
{
base.Tick();
SetClass( "checked", ToggleProperty?.As.Bool == true );
SetClass( "hidden", string.IsNullOrWhiteSpace( Title ) && ToggleProperty == null );
}
protected override void OnMouseDown( MousePanelEvent e )
{
base.OnMouseDown( e );
ToggleProperty?.As.Bool = !(ToggleProperty?.As.Bool ?? false);
}
}

View File

@@ -0,0 +1,62 @@
ControlSheetGroupHeader
{
font-size: 1.33rem;
color: red;
gap: 2px;
align-items: center;
&.hidden
{
display: none;
}
> .title
{
font-weight: 600;
}
&.has-toggle
{
cursor: pointer;
opacity: 0.8;
&:before
{
content: ' ';
width: 22px;
height: 22px;
background-color: #000a;
align-items: center;
justify-content: center;
text-align: center;
border-radius: 5px;
border: 1px solid #555;
}
&:hover
{
opacity: 1;
&:before
{
border-color: #888;
}
}
&.checked
{
> .title
{
color: white;
}
&:before
{
content: '';
font-weight: bold;
color: #08f;
border-color: #08f;
}
}
}
}

View File

@@ -59,7 +59,7 @@
/// If set to 10, value will be rounded to 10's
/// If set to 0.1, value will be rounded to 0.1's
/// </summary>
[Parameter] public float Step { get; set; } = 1.0f;
[Parameter] public float Step { get; set; } = 0.001f;
/// <summary>
/// Show the range values above the slider

View File

@@ -67,14 +67,11 @@
{
flex-shrink: 0;
flex-grow: 0;
width: 50px;
> textentry
> numberentry
{
text-align: right;
width: 100%;
border-radius: 4px;
padding: 0;
min-height: 0px;
background-color: transparent;
> .content-label
{