302 lines
6.8 KiB
C#
302 lines
6.8 KiB
C#
![]() |
|
||
|
|
||
|
|
||
|
|
||
|
using Godot;
|
||
|
using Rokojori;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
|
||
|
namespace Rokojori
|
||
|
{
|
||
|
[Tool]
|
||
|
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIImage.svg")]
|
||
|
public partial class UISlider:UIImage
|
||
|
{
|
||
|
public enum Direction
|
||
|
{
|
||
|
Vertical,
|
||
|
Horizontal,
|
||
|
Both
|
||
|
}
|
||
|
|
||
|
[Export]
|
||
|
public Direction direction = Direction.Vertical;
|
||
|
|
||
|
[Export]
|
||
|
public Smoothing smoothing;
|
||
|
|
||
|
Vector2 _sliderValue;
|
||
|
|
||
|
[Export]
|
||
|
public Vector2 sliderValue
|
||
|
{
|
||
|
get { return _sliderValue; }
|
||
|
set
|
||
|
{
|
||
|
_sliderValue = value;
|
||
|
SyncSliderValue();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SyncSliderValue()
|
||
|
{
|
||
|
SliderShader.sliderValue.Set( Material, sliderValue );
|
||
|
}
|
||
|
|
||
|
public override void _Ready()
|
||
|
{
|
||
|
base._Ready();
|
||
|
|
||
|
if ( imageType == null )
|
||
|
{
|
||
|
imageType = new SliderUIImageType();
|
||
|
}
|
||
|
|
||
|
if ( Texture == null )
|
||
|
{
|
||
|
Texture = UI.whiteTexture.Get();
|
||
|
}
|
||
|
|
||
|
var uiSliderImageType = _imageType as SliderUIImageType;
|
||
|
|
||
|
if ( uiSliderImageType != null )
|
||
|
{
|
||
|
uiSliderImageType.Clear( this );
|
||
|
uiSliderImageType.Assign( this );
|
||
|
|
||
|
}
|
||
|
|
||
|
ComputeUIAncestorDepth();
|
||
|
|
||
|
SyncSliderValue();
|
||
|
|
||
|
|
||
|
AssignListener();
|
||
|
}
|
||
|
|
||
|
[Export]
|
||
|
public bool debugInfo = false;
|
||
|
|
||
|
[Export]
|
||
|
public string[] propertyInfos = [];
|
||
|
|
||
|
public override void _Process( double delta )
|
||
|
{
|
||
|
if ( ! debugInfo )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var it = imageType as SliderUIImageType;
|
||
|
|
||
|
if ( it == null )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var propNames = it.GetNumberShaderProperties();
|
||
|
|
||
|
var tw = Texture.GetWidth();
|
||
|
var th = Texture.GetHeight();
|
||
|
|
||
|
var w = UINumber.Compute( this, UIStyleNumberProperty.Width, tw, tw / 100f );
|
||
|
var h = UINumber.Compute( this, UIStyleNumberProperty.Height, th, th / 100f );
|
||
|
|
||
|
var infos = new List<string>();
|
||
|
for ( int i = 0; i < propNames.Length; i++ )
|
||
|
{
|
||
|
var n = propNames[ i ];
|
||
|
var p = it.GetUIStyleNumberProperty( UIStyleNumberProperty.FloatShaderProperty, n );
|
||
|
|
||
|
if ( p == null )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var relative = 100f;
|
||
|
|
||
|
if ( n.EndsWith( ".x" ) )
|
||
|
{
|
||
|
relative = w;
|
||
|
}
|
||
|
else if ( n.EndsWith( ".y" ) )
|
||
|
{
|
||
|
relative = h;
|
||
|
}
|
||
|
|
||
|
|
||
|
var value = UINumber.Compute( this, UIStyleNumberProperty.FloatShaderProperty, n, 0, relative );
|
||
|
infos.Add( "[" + n + "] (" + p.value._FFF() + " * " + p.unit +") :" + value._FFF() );
|
||
|
}
|
||
|
|
||
|
propertyInfos = infos.ToArray();
|
||
|
|
||
|
this.LogInfo( propertyInfos );
|
||
|
|
||
|
|
||
|
debugInfo = false;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
UIDragging.UIDraggingCallbacks leftMouseCallbacks;
|
||
|
Vector2 cachedMouseOffset;
|
||
|
Vector2 cachedButtonPosition;
|
||
|
|
||
|
bool _dragging = false;
|
||
|
bool _updatingPosition = false;
|
||
|
|
||
|
string scrollID = IDGenerator.GenerateID();
|
||
|
|
||
|
float ComputeShaderProperty( string n, float relative = 100 )
|
||
|
{
|
||
|
return UINumber.Compute( this, UIStyleNumberProperty.FloatShaderProperty, n, 0, relative );
|
||
|
}
|
||
|
|
||
|
Vector2 sliderSize
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
var tw = Texture.GetWidth();
|
||
|
var th = Texture.GetHeight();
|
||
|
|
||
|
var w = UINumber.Compute( this, UIStyleNumberProperty.Width, tw, tw / 100f );
|
||
|
var h = UINumber.Compute( this, UIStyleNumberProperty.Height, th, th / 100f );
|
||
|
|
||
|
var valueX = ComputeShaderProperty( SliderShader.sliderSize.propertyNameX, w );
|
||
|
var valueY = ComputeShaderProperty( SliderShader.sliderSize.propertyNameY, h );
|
||
|
|
||
|
return new Vector2( valueX, valueY );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Vector2 sliderSizeMargins
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
var tw = Texture.GetWidth();
|
||
|
var th = Texture.GetHeight();
|
||
|
|
||
|
var w = UINumber.Compute( this, UIStyleNumberProperty.Width, tw, tw / 100f );
|
||
|
var h = UINumber.Compute( this, UIStyleNumberProperty.Height, th, th / 100f );
|
||
|
|
||
|
var valueX = ComputeShaderProperty( SliderShader.sliderSizeMargins.propertyNameX, w );
|
||
|
var valueY = ComputeShaderProperty( SliderShader.sliderSizeMargins.propertyNameY, h );
|
||
|
|
||
|
return new Vector2( valueX, valueY );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Vector2 sliderRange => Size - ( sliderSize + sliderSizeMargins );
|
||
|
Vector2 sliderOffset => sliderSize;
|
||
|
|
||
|
Vector2 buttonPositionMin
|
||
|
{
|
||
|
get { return NormalizedToButtonPosition( Vector2.Zero ); }
|
||
|
}
|
||
|
|
||
|
Vector2 buttonPositionMax
|
||
|
{
|
||
|
get { return NormalizedToButtonPosition( Vector2.One ); }
|
||
|
}
|
||
|
|
||
|
|
||
|
Vector2 NormalizedToButtonPosition( Vector2 normalized )
|
||
|
{
|
||
|
return normalized * sliderRange + sliderOffset;
|
||
|
}
|
||
|
|
||
|
Vector2 ButtonPositionToNormalized( Vector2 buttonPosition )
|
||
|
{
|
||
|
return ( buttonPosition - sliderOffset ) / sliderRange;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool _listenerAssigned = false;
|
||
|
|
||
|
void AssignListener()
|
||
|
{
|
||
|
if ( _listenerAssigned )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
leftMouseCallbacks = UIDragging.OnLeftMouseButton( this,
|
||
|
( ev )=>
|
||
|
{
|
||
|
if ( ev.isStart )
|
||
|
{
|
||
|
cachedButtonPosition = NormalizedToButtonPosition( sliderValue );
|
||
|
smoothing.SetCurrent( cachedButtonPosition );
|
||
|
|
||
|
_dragging = true;
|
||
|
_updatingPosition = true;
|
||
|
|
||
|
ev.ui.onProcess.AddAction( UpdatePosition );
|
||
|
}
|
||
|
else if ( ev.isEnd )
|
||
|
{
|
||
|
_dragging = false;
|
||
|
}
|
||
|
|
||
|
var nextPosition = cachedButtonPosition + ev.distanceToStart;
|
||
|
nextValue = nextPosition.Clamp( buttonPositionMin, buttonPositionMax );
|
||
|
|
||
|
}
|
||
|
);
|
||
|
|
||
|
_listenerAssigned = true;
|
||
|
}
|
||
|
|
||
|
Vector2 nextValue;
|
||
|
|
||
|
Vector2 GetButtonScrollRange()
|
||
|
{
|
||
|
return Vector2.Zero;
|
||
|
// return ( Size - button.Size ).Max( Vector2.Zero );
|
||
|
}
|
||
|
|
||
|
Vector2 cachedOffset = Vector2.Zero;
|
||
|
|
||
|
void UpdatePosition( float delta )
|
||
|
{
|
||
|
// this.LogInfo( "UpdatePosition" );
|
||
|
var value = Smoothing.Apply( smoothing, nextValue, delta );
|
||
|
|
||
|
var uiStyleContainer = ( UIStylePropertyContainerNode ) this;
|
||
|
|
||
|
uiStyleContainer.SetLayoutDirtyFlag();
|
||
|
|
||
|
if ( ! _dragging && ( value - nextValue ).Length() < 1 )
|
||
|
{
|
||
|
var ui = UIHolder.GetUI( this );
|
||
|
ui.onProcess.RemoveAction( UpdatePosition );
|
||
|
_updatingPosition = false;
|
||
|
// this.LogInfo( "Removed Processing" );
|
||
|
|
||
|
value = nextValue;
|
||
|
|
||
|
uiStyleContainer.RemoveUISelectorFlag( UISelectorFlag.Scrolling, scrollID );
|
||
|
|
||
|
}
|
||
|
|
||
|
var currentSliderValue = ButtonPositionToNormalized( value );
|
||
|
|
||
|
if ( Direction.Vertical == direction )
|
||
|
{
|
||
|
currentSliderValue.X = 0.5f;
|
||
|
}
|
||
|
else if ( Direction.Vertical == direction )
|
||
|
{
|
||
|
currentSliderValue.Y = 0.5f;
|
||
|
}
|
||
|
|
||
|
_sliderValue = currentSliderValue;
|
||
|
SyncSliderValue();
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|