mirror of
https://github.com/Facepunch/sbox-public.git
synced 2025-12-23 22:48:07 -05:00
192 lines
4.6 KiB
Plaintext
192 lines
4.6 KiB
Plaintext
@using System
|
|
@namespace Sandbox.UI
|
|
@inherits BaseControl
|
|
@attribute [CustomEditor( typeof(float), WithAllAttributes = [ typeof(RangeAttribute) ] )]
|
|
|
|
<root class="slidercontrol">
|
|
@if ( ShowTextEntry )
|
|
{
|
|
<div class="entry">
|
|
<NumberEntry @ref="TextEntryPanel" Value:bind="@Value" Numeric="@true" NumberFormat="@NumberFormat"></NumberEntry>
|
|
</div>
|
|
}
|
|
|
|
<div class="inner">
|
|
|
|
@if (ShowRange)
|
|
{
|
|
<div class="values">
|
|
<div class="left">@Min.ToString( NumberFormat )</div>
|
|
<div class="right">@Max.ToString( NumberFormat )</div>
|
|
</div>
|
|
}
|
|
|
|
<div @ref="TrackPanel" class="track">
|
|
<div class="track-active" style="width: @(SliderPosition)%;"></div>
|
|
<div @ref="ThumbPanel" style="left: @(SliderPosition)%;" class="thumb">
|
|
|
|
@if (this.HasActive)
|
|
{
|
|
<div class="value-tooltip">
|
|
<label>@Value.ToString( NumberFormat )</label>
|
|
<div class="tail"></div>
|
|
</div>
|
|
}
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</root>
|
|
|
|
@code
|
|
{
|
|
public override bool SupportsMultiEdit => true;
|
|
|
|
[Parameter] public Action<float> OnValueChanged { get; set; }
|
|
|
|
/// <summary>
|
|
/// The right side of the slider.
|
|
/// </summary>
|
|
[Parameter] public float Max { get; set; } = 100;
|
|
|
|
|
|
/// <summary>
|
|
/// The left side of the slider.
|
|
/// </summary>
|
|
[Parameter] public float Min { get; set; } = 0;
|
|
|
|
/// <summary>
|
|
/// If set to 1, value will be rounded to 1's
|
|
/// 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; } = 0.001f;
|
|
|
|
/// <summary>
|
|
/// Show the range values above the slider
|
|
/// </summary>
|
|
[Parameter] public bool ShowRange { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// When changing the value show the tooltip
|
|
/// </summary>
|
|
[Parameter] public bool ShowValueTooltip { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// When changing the value show the tooltip
|
|
/// </summary>
|
|
[Parameter] public bool ShowTextEntry { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// How to display numbers in this control
|
|
/// </summary>
|
|
[Parameter] public string NumberFormat { get; set; } = "0.###";
|
|
|
|
float _value;
|
|
|
|
[Parameter]
|
|
public float Value
|
|
{
|
|
get => Property?.As.Float ?? _value;
|
|
|
|
set
|
|
{
|
|
if (Property is not null)
|
|
{
|
|
Property.As.Float = value;
|
|
StateHasChanged();
|
|
return;
|
|
}
|
|
|
|
if (_value == value)
|
|
return;
|
|
|
|
_value = MathX.Clamp( _value, Min, Max );
|
|
|
|
_value = value;
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
Panel TrackPanel { get; set; }
|
|
Panel ThumbPanel { get; set; }
|
|
TextEntry TextEntryPanel { get; set; }
|
|
|
|
public SliderControl()
|
|
{
|
|
|
|
}
|
|
|
|
public SliderControl(float min, float max, float step = 1.0f)
|
|
{
|
|
Min = min;
|
|
Max = max;
|
|
Step = step;
|
|
}
|
|
|
|
public override void Rebuild()
|
|
{
|
|
if (Property is null) return;
|
|
|
|
ShowTextEntry = true;
|
|
|
|
if (Property.TryGetAttribute<RangeAttribute>(out var rangeAttribute))
|
|
{
|
|
Min = rangeAttribute.Min;
|
|
Max = rangeAttribute.Max;
|
|
}
|
|
|
|
if ( Property.TryGetAttribute<StepAttribute>( out var stepAttribute ) )
|
|
{
|
|
Step = stepAttribute.Step;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a screen position to a value. The value is clamped, but not snapped.
|
|
/// </summary>
|
|
public virtual float ScreenPosToValue( Vector2 pos )
|
|
{
|
|
var normalized = MathX.LerpInverse(pos.x, TrackPanel.Box.Left, TrackPanel.Box.Right, true);
|
|
var scaled = MathX.LerpTo( Min, Max, normalized, true );
|
|
return Step > 0 ? scaled.SnapToGrid( Step ) : scaled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// If we move the mouse while we're being pressed then set the value
|
|
/// </summary>
|
|
protected override void OnMouseMove( MousePanelEvent e )
|
|
{
|
|
base.OnMouseMove( e );
|
|
|
|
if ( !HasActive || e.MouseButton == MouseButtons.Middle ) return;
|
|
|
|
Value = ScreenPosToValue( Mouse.Position );
|
|
OnValueChanged?.Invoke( Value );
|
|
e.StopPropagation();
|
|
}
|
|
|
|
/// <summary>
|
|
/// On mouse press jump to that position
|
|
/// </summary>
|
|
protected override void OnMouseDown( MousePanelEvent e )
|
|
{
|
|
base.OnMouseDown( e );
|
|
|
|
Value = ScreenPosToValue( Mouse.Position );
|
|
OnValueChanged?.Invoke( Value );
|
|
e.StopPropagation();
|
|
|
|
TextEntryPanel?.Blur();
|
|
}
|
|
|
|
protected override void OnMiddleClick( MousePanelEvent e )
|
|
{
|
|
base.OnMiddleClick( e );
|
|
e.StopPropagation();
|
|
}
|
|
|
|
float SliderPosition => MathX.LerpInverse(Value, Min, Max, true) * 100.0f;
|
|
}
|