142 lines
2.9 KiB
C#
142 lines
2.9 KiB
C#
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
public static float Compute( Control control, UINumber number, float alternative = 0, float relative = 100 )
|
||
|
{
|
||
|
if ( number == null || control == null || number.IsNone )
|
||
|
{
|
||
|
return alternative;
|
||
|
}
|
||
|
|
||
|
var width = 0;
|
||
|
var height = 0;
|
||
|
|
||
|
if ( Engine.IsEditorHint() )
|
||
|
{
|
||
|
width = ProjectSettings.GetSetting( "display/window/size/viewport_width" ).AsInt32();
|
||
|
height = ProjectSettings.GetSetting( "display/window/size/viewport_height" ).AsInt32();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
width = control.GetWindow().Size.X;
|
||
|
height = control.GetWindow().Size.Y;
|
||
|
}
|
||
|
|
||
|
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 )
|
||
|
{
|
||
|
// _ui = NodesWalker.Get().GetParent( control, n => n is UI ) as UI;
|
||
|
}
|
||
|
|
||
|
switch ( number.unit )
|
||
|
{
|
||
|
case "em":
|
||
|
{
|
||
|
return number.value * em();
|
||
|
}
|
||
|
|
||
|
case "vw":
|
||
|
{
|
||
|
return number.value * width / 100f;
|
||
|
}
|
||
|
|
||
|
case "vh":
|
||
|
{
|
||
|
return number.value * height / 100f;
|
||
|
}
|
||
|
|
||
|
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 " );
|
||
|
var parseResult = expression.Parse( expressionText, new string[]{ "em","vw", "vh", "px", "relative", "value" } );
|
||
|
|
||
|
if ( Error.Ok != parseResult )
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
var inputs = new Godot.Collections.Array();
|
||
|
inputs.Add( em() );
|
||
|
inputs.Add( width / 100f );
|
||
|
inputs.Add( height / 100f );
|
||
|
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() ;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|