Files
sbox-public/game/addons/tools/Code/Curves/Graphics/EditableCurve.HandlePopup.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

185 lines
3.9 KiB
C#

namespace Editor.GraphicsItems;
public partial class EditableCurve
{
/// <summary>
/// This would be a lot simpler if we just passed the handle to it, and let it fuck with it directly!!
/// </summary>
public class HandlePopup : Widget
{
Widget X;
Widget Y;
public bool AimUp;
const float ArrowHeight = 8;
Handle Handle;
float HandleTime
{
get
{
if ( !Handle.IsValid() )
return 0.0f;
var rangeX = Handle.EditableCurve.TimeRange;
return Handle.Frame.Time.Remap( 0, 1, rangeX.x, rangeX.y, false );
}
set
{
Handle?.SetValue( value, HandleValue );
}
}
float HandleValue
{
get
{
if ( !Handle.IsValid() )
return 0.0f;
var rangeY = Handle.EditableCurve.ValueRange;
return Handle.Frame.Value.Remap( 0, 1, rangeY.x, rangeY.y, false );
}
set
{
Handle?.SetValue( HandleTime, value );
}
}
public HandlePopup( Widget parent ) : base( parent )
{
Layout = Layout.Column();
var so = this.GetSerialized();
{
X = new Widget( this );
X.Layout = Layout.Row();
var control = X.Layout.Add( new FloatControlWidget( so.GetProperty( nameof( HandleTime ) ) ) );
control.Label = null;
control.Icon = "east";
control.HighlightColor = Theme.Red;
}
{
Y = new Widget( this );
Y.Layout = Layout.Row();
var control = Y.Layout.Add( new FloatControlWidget( so.GetProperty( nameof( HandleValue ) ) ) );
control.Label = null;
control.Icon = "north";
control.HighlightColor = Theme.Green;
}
Layout.Add( X );
Layout.Add( Y );
Layout.Spacing = 2;
Layout.Margin = new Sandbox.UI.Margin( 4, 4, 4, 4 + ArrowHeight );
var row = Layout.AddRow();
foreach ( var e in DisplayInfo.ForEnumValues<Curve.HandleMode>() )
{
var b = new Button( this );
b.MaximumSize = 19;
b.ToolTip = $"{e.info.Name} - {e.info.Description}";
b.Clicked = () => Handle?.SetHandleMode( e.value );
b.OnPaintOverride = () => PaintButton( b, e.value, e.info.Icon );
row.Add( b );
}
}
public void UpdateFrom( Handle handle )
{
Handle = handle;
HandleMode = Handle.Frame.Mode;
Position = Handle.ViewPosition - (Size * new Vector2( 0.5f, 1.0f )) - new Vector2( 0, 60 );
Layout.Margin = new Sandbox.UI.Margin( 4, 4, 4, 4 + 8 );
// popping off screen, be at the bottom instead
if ( Position.y < -4 )
{
Position += new Vector2( 0, 110 + Height );
Layout.Margin = new Sandbox.UI.Margin( 4, 4 + 8, 4, 4 );
}
if ( Parent.IsValid() )
{
ConstrainTo( Parent.LocalRect.Shrink( 4 ) );
}
}
protected override void DoLayout()
{
base.DoLayout();
if ( Handle.IsValid() )
UpdateFrom( Handle );
}
protected override void OnPaint()
{
base.OnPaint();
var c = Theme.WidgetBackground;
Paint.Antialiasing = true;
Paint.SetBrush( c );
Paint.ClearPen();
var r = LocalRect;
if ( Layout.Margin.Top > 4 )
{
Paint.DrawArrow( new Vector2( r.Center.x, Layout.Margin.Top ), new Vector2( r.Center.x, 0 ), Layout.Margin.Top );
r.Top += Layout.Margin.Top - 4;
}
if ( Layout.Margin.Bottom > 4 )
{
Paint.DrawArrow( new Vector2( r.Center.x, r.Bottom - Layout.Margin.Bottom ), new Vector2( r.Center.x, r.Bottom ), Layout.Margin.Bottom );
r.Bottom -= Layout.Margin.Bottom - 4;
}
Paint.DrawRect( r, 4 );
}
Curve.HandleMode _handlemode;
public Curve.HandleMode HandleMode
{
get => _handlemode;
set
{
if ( _handlemode == value ) return;
_handlemode = value;
Update();
}
}
protected bool PaintButton( Button b, Curve.HandleMode h, string icon )
{
if ( HandleMode == h )
{
Paint.Antialiasing = true;
Paint.ClearPen();
Paint.SetBrush( Theme.Blue.WithAlpha( 0.3f ) );
Paint.DrawRect( b.LocalRect, 3 );
Paint.SetPen( Theme.Blue );
Paint.DrawIcon( b.LocalRect, icon, 12 );
}
else
{
Paint.SetPen( Theme.Blue.WithAlpha( 0.5f ) );
Paint.DrawIcon( b.LocalRect, icon, 14 );
}
return true;
}
}
}