288 lines
5.7 KiB
C#
288 lines
5.7 KiB
C#
|
|
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
|
|
[Tool]
|
|
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UI.svg")]
|
|
public partial class UI : Control, IDisposable
|
|
{
|
|
|
|
[Export]
|
|
public UISettings settings;
|
|
|
|
[Export]
|
|
public float fontZoom = 1;
|
|
|
|
public enum UpdateMode
|
|
{
|
|
Always,
|
|
Only_Manual_Updates
|
|
}
|
|
[Export]
|
|
public UpdateMode updateMode = UpdateMode.Always;
|
|
|
|
[Export]
|
|
public bool useParentSize = false;
|
|
|
|
[ExportGroup("Functions")]
|
|
[ExportToolButton( "Mouse:Stop => Pass")]
|
|
public Callable StopToPassButton => Callable.From( ()=>{ MakeStopToPass(); } );
|
|
|
|
[Export]
|
|
public Node[] stopToPassRoots = [];
|
|
|
|
[ExportGroup("Read Only")]
|
|
|
|
[Export]
|
|
public float X_computedFontSizePixels = 1;
|
|
|
|
|
|
|
|
List<ICustomDisposer> _customDisposers = [];
|
|
|
|
public void AddForDisposing( ICustomDisposer customDisposer )
|
|
{
|
|
_customDisposers.Add( customDisposer );
|
|
}
|
|
|
|
protected override void Dispose( bool disposing )
|
|
{
|
|
_customDisposers.ForEach( cd => cd.Dispose() );
|
|
_customDisposers = [];
|
|
}
|
|
|
|
[Export]
|
|
public string[] customDisposerIDs = [];
|
|
|
|
public void MakeStopToPass()
|
|
{
|
|
var roots = stopToPassRoots;
|
|
|
|
if ( roots == null || roots.Length == 0 )
|
|
{
|
|
roots = [ this ];
|
|
}
|
|
|
|
foreach ( var n in roots )
|
|
{
|
|
if ( n is Control c )
|
|
{
|
|
if ( c.MouseFilter == MouseFilterEnum.Stop )
|
|
{
|
|
c.MouseFilter = MouseFilterEnum.Pass;
|
|
}
|
|
}
|
|
|
|
n.ForEach<Control>(
|
|
( c )=>
|
|
{
|
|
if ( c.MouseFilter == MouseFilterEnum.Stop )
|
|
{
|
|
c.MouseFilter = MouseFilterEnum.Pass;
|
|
}
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
Vector2 cachedSize;
|
|
|
|
public static UI Get( Control c )
|
|
{
|
|
return UIHolder.GetUI( c );
|
|
}
|
|
|
|
public static UIStylePropertyContainer GetStylePropertyContainerParent( Control c )
|
|
{
|
|
var it = c as Node;
|
|
var walker = NodesWalker.Get();
|
|
|
|
it = walker.Parent( it );
|
|
|
|
if ( it is UI )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
while ( it != null )
|
|
{
|
|
if ( it is UIStylePropertyContainer )
|
|
{
|
|
return it as UIStylePropertyContainer;
|
|
}
|
|
|
|
it = walker.Parent( it );
|
|
|
|
if ( it is UI )
|
|
{
|
|
it = null;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
public static TimeLine GetTimeLine( Control c, TimeLine timeLine )
|
|
{
|
|
if ( timeLine != null )
|
|
{
|
|
return timeLine;
|
|
}
|
|
|
|
var ui = Get( c );
|
|
|
|
if ( ui == null || ui.settings == null )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return ui.settings.defaultTimeline;
|
|
}
|
|
|
|
public override void _Process( double delta )
|
|
{
|
|
if ( settings == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( useParentSize )
|
|
{
|
|
var parentSize = GetParent<Control>().Size;
|
|
|
|
if ( parentSize != cachedSize )
|
|
{
|
|
Size = parentSize;
|
|
|
|
cachedSize = parentSize;
|
|
|
|
// this.LogInfo( "Size Changed" );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
onProcess.DispatchEvent( (float)delta );
|
|
UpdateFontSize();
|
|
UpdateUIElements();
|
|
|
|
// customDisposerIDs = _customDisposers.Map( c => c.GetUID() + ":" + c.GetInfo() ).ToArray();
|
|
|
|
}
|
|
|
|
public void UpdateExternal( float delta)
|
|
{
|
|
onProcess.DispatchEvent( delta );
|
|
UpdateFontSize();
|
|
}
|
|
|
|
public readonly EventSlot<InputEvent> onInputEvent = new EventSlot<InputEvent>();
|
|
public readonly EventSlot<float> onProcess = new EventSlot<float>();
|
|
|
|
public override void _Input( InputEvent ie )
|
|
{
|
|
onInputEvent.DispatchEvent( ie );
|
|
}
|
|
|
|
List<UIHoverable> hoveredControls = new List<UIHoverable>();
|
|
|
|
public void SetHovered( UIHoverable control )
|
|
{
|
|
hoveredControls.Add( control );
|
|
}
|
|
|
|
public void BindOwnChildren()
|
|
{
|
|
BindChildrenOf( this );
|
|
}
|
|
|
|
public void BindChildrenOf( Node node )
|
|
{
|
|
node.ForEach<UIImage>( img => img.SetUI( this ) );
|
|
node.ForEach<UIInputInfo>( info => info.SetUI( this ) );
|
|
node.ForEach<UIText>( text => text.SetUI( this ) );
|
|
node.ForEach<UIRegion>( region => region.SetUI( this ) );
|
|
}
|
|
|
|
public override void _Ready()
|
|
{
|
|
var sm = Unique<SensorManager>.Get();
|
|
|
|
if ( sm != null )
|
|
{
|
|
sm._onActiveDeviceChange.AddAction( a => UpdateUIInputs() );
|
|
}
|
|
|
|
UpdateUIInputs();
|
|
}
|
|
|
|
void UpdateUIInputs()
|
|
{
|
|
Nodes.ForEach<UIInputInfo>( this, uii => uii.updateInfo = true );
|
|
}
|
|
|
|
|
|
|
|
void UpdateFontSize()
|
|
{
|
|
if ( settings == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
X_computedFontSizePixels = UINumber.Compute( this, settings.fontSize ) * fontZoom;
|
|
|
|
|
|
if ( Theme != null )
|
|
{
|
|
Theme.DefaultFontSize = Mathf.RoundToInt( X_computedFontSizePixels );
|
|
}
|
|
}
|
|
|
|
void UpdateUIElements()
|
|
{
|
|
if ( UpdateMode.Always != updateMode )
|
|
{
|
|
return;
|
|
}
|
|
|
|
UpdateAllUIRegions();
|
|
}
|
|
|
|
public void UpdateAllUIRegions()
|
|
{
|
|
Nodes.ForEachDirectChild<UIRegion>( this, r => r.Layout() );
|
|
}
|
|
|
|
public static float GetWindowWidth( Control control )
|
|
{
|
|
if ( Engine.IsEditorHint() )
|
|
{
|
|
return ProjectSettings.GetSetting( "display/window/size/viewport_width" ).AsInt32();
|
|
}
|
|
else
|
|
{
|
|
return control.GetWindow().Size.X;
|
|
}
|
|
}
|
|
|
|
public static float GetWindowHeight( Control control )
|
|
{
|
|
if ( Engine.IsEditorHint() )
|
|
{
|
|
return ProjectSettings.GetSetting( "display/window/size/viewport_height" ).AsInt32();
|
|
}
|
|
else
|
|
{
|
|
return control.GetWindow().Size.Y;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
} |