rj-action-library/Runtime/UI/Styling/UINumber.cs

153 lines
3.3 KiB
C#
Raw Normal View History

2024-08-09 13:52:49 +00:00
using Godot;
using Rokojori;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class UINumber : Resource
{
[Export]
public float value = 0;
[Export]
public string unit = "";
public bool IsNone => unit == "none";
public float Compute( Control control, float alternative )
{
return UINumber.Compute( control, this, alternative );
}
public static bool IsNullOrNone( UINumber number )
{
if ( number == null )
{
return true;
}
return number.IsNone;
}
2024-08-11 17:38:06 +00:00
2024-08-09 13:52:49 +00:00
public static float Compute( Control control, UINumber number, float alternative = 0, float relative = 100 )
{
if ( number == null || control == null || number.IsNone )
{
return alternative;
}
2024-08-11 17:38:06 +00:00
var width = UI.GetWindowWidth( control );
var height = UI.GetWindowHeight( control );
2024-08-09 13:52:49 +00:00
return Compute( control, number, width, height, relative );
}
static UI _ui;
static float em()
{
return _ui == null ? 12 : _ui.X_computedFontSizePixels;
}
public static float Compute( Control control, UINumber number, float width, float height, float relative )
{
if ( number == null )
{
return 0;
}
if ( _ui == null )
{
2024-08-11 17:38:06 +00:00
_ui = NodesWalker.Get().GetInParents( control, n => n is UI ) as UI;
2024-08-09 13:52:49 +00:00
}
switch ( number.unit )
{
case "em":
{
return number.value * em();
}
case "vw":
{
return number.value * width / 100f;
}
case "vh":
{
return number.value * height / 100f;
}
2024-08-11 17:38:06 +00:00
case "pw":
{
var parent = control.GetParent<Control>();
return number.value / 100f * ( parent == null ? width : parent.Size.X );
}
case "ph":
{
var parent = control.GetParent<Control>();
return number.value / 100f * ( parent == null ? height : parent.Size.Y );
}
2024-08-09 13:52:49 +00:00
case "px": case "":
{
return number.value;
}
case "%":
{
return number.value * relative / 100f;
}
}
var expression = new Expression();
var expressionText = number.unit == null ? "" : RegexUtility.Replace( number.unit, "%", " * relative " );
2024-08-11 17:38:06 +00:00
var parseResult = expression.Parse( expressionText,
new string[]
{
"em","vw", "vh", "pw", "ph", "px", "relative", "value" }
);
2024-08-09 13:52:49 +00:00
if ( Error.Ok != parseResult )
{
return 0;
}
2024-08-11 17:38:06 +00:00
var parentControl = control.GetParent<Control>();
2024-08-09 13:52:49 +00:00
var inputs = new Godot.Collections.Array();
inputs.Add( em() );
inputs.Add( width / 100f );
inputs.Add( height / 100f );
2024-08-11 17:38:06 +00:00
inputs.Add( ( parentControl == null ? width : parentControl.Size.X ) / 100f );
inputs.Add( ( parentControl == null ? height : parentControl.Size.Y ) / 100f );
2024-08-09 13:52:49 +00:00
inputs.Add( 1 );
inputs.Add( relative / 100f );
if ( number.unit.IndexOf( "value" ) == -1 )
{
inputs.Add( 0 );
return number.value * (float) expression.Execute( inputs ).AsDouble() ;
}
inputs.Add( number.value );
return (float) expression.Execute( inputs ).AsDouble() ;
}
}
}