namespace Editor.NodeEditor; public class FloatEditor : ValueEditor { public string Title { get; set; } public float Value { get; set; } public float Min { get; set; } = 0; public float Max { get; set; } = 1; public float Step { get; set; } = 0f; public NodeUI Node { get; set; } private bool IsRange => Min != Max; private Vector2 _lastCursorPos; public FloatEditor( GraphicsItem parent ) : base( parent ) { HoverEvents = true; Cursor = CursorShape.Finger; } protected override void OnPaint() { if ( !Enabled ) return; Paint.Antialiasing = true; Paint.TextAntialiasing = true; var isRange = IsRange; var sliderBg = Theme.Blue.WithAlpha( 0.6f ); var bg = Theme.ControlBackground.WithAlpha( 0.4f ); var fg = Theme.TextControl; if ( !Paint.HasMouseOver ) { bg = bg.Darken( 0.2f ); fg = fg.Darken( 0.1f ); sliderBg = sliderBg.WithAlpha( 0.5f ); } var rect = LocalRect.Shrink( 1 ); Paint.ClearPen(); Paint.SetBrush( bg ); Paint.DrawRect( rect, 2 ); if ( isRange && Value >= Min ) { Paint.SetBrush( sliderBg.WithAlpha( 0.2f ) ); Paint.DrawRect( rect.Shrink( 1, 1, (Value <= Max) ? 40 : 1, 1 ), 2 ); var sliderRect = rect.Shrink( 1, 1, (Value <= Max) ? 40 : 1, 1 ); sliderRect.Right = sliderRect.Left.LerpTo( sliderRect.Right, (Value - Min) / (Max - Min) ); Paint.SetBrush( sliderBg ); Paint.DrawRect( sliderRect, 2 ); } if ( !isRange ) { Paint.SetBrush( Paint.HasPressed ? sliderBg : sliderBg.WithAlpha( 0.2f ) ); Paint.DrawRect( rect.Shrink( 1 ), 2 ); if ( Paint.HasMouseOver ) { Paint.SetPen( fg ); Paint.DrawIcon( rect.Shrink( 1 ), "navigate_before", 10, TextFlag.LeftCenter ); Paint.DrawIcon( rect.Shrink( 1 ), "navigate_next", 10, TextFlag.RightCenter ); } } Paint.SetDefaultFont(); Paint.SetPen( fg ); var shrink = isRange ? 4 : 10; if ( !string.IsNullOrWhiteSpace( Title ) ) { Paint.DrawText( rect.Shrink( shrink, 0, shrink, 0 ), Title, TextFlag.LeftCenter ); } Paint.DrawText( rect.Shrink( shrink, 0, shrink, 0 ), $"{Value:0.000}", TextFlag.RightCenter ); } protected override void OnMousePressed( GraphicsMouseEvent e ) { base.OnMousePressed( e ); if ( !Enabled ) return; if ( !e.LeftMouseButton ) return; if ( IsRange ) { UpdateValue( e.LocalPosition.x ); } else { _lastCursorPos = Application.UnscaledCursorPosition; } e.Accepted = true; } protected override void OnMouseReleased( GraphicsMouseEvent e ) { base.OnMouseReleased( e ); Cursor = IsRange ? CursorShape.Finger : CursorShape.SizeH; Update(); } protected override void OnHoverEnter( GraphicsHoverEvent e ) { base.OnHoverEnter( e ); Cursor = IsRange ? CursorShape.Finger : CursorShape.SizeH; } protected override void OnMouseMove( GraphicsMouseEvent e ) { base.OnMouseMove( e ); if ( !Enabled ) return; if ( !e.LeftMouseButton ) return; if ( IsRange ) { Cursor = CursorShape.Finger; UpdateValue( e.LocalPosition.x ); } else { Cursor = CursorShape.Blank; var cursorPos = Application.UnscaledCursorPosition; var delta = cursorPos - _lastCursorPos; Application.UnscaledCursorPosition = _lastCursorPos; Value += delta.x * 0.01f; Node.Graph.ChildValuesChanged( null ); Node.Update(); } e.Accepted = true; } private void UpdateValue( float position ) { Value = (position - 1) / (Size.x - 43); Value = Min.LerpTo( Max, Value ).Clamp( Min, Max ); if ( Step > 0 ) { Value = (float)Math.Round( Value / Step ) * Step; } Node.Graph.ChildValuesChanged( null ); Node.Update(); } }