UI Update

This commit is contained in:
Josef 2025-06-19 19:22:25 +02:00
parent 31f5077b72
commit dab72b46d9
169 changed files with 8755 additions and 418 deletions

158
Icons/PostProcess.svg Normal file
View File

@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16"
viewBox="0 0 16 16"
width="16"
version="1.1"
id="svg4"
sodipodi:docname="PostProcess.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs8"><linearGradient
inkscape:collect="never"
id="linearGradient13704"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop13700" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop13702" /></linearGradient><linearGradient
inkscape:collect="never"
id="linearGradient10604"><stop
style="stop-color:#18e9e8;stop-opacity:1;"
offset="0"
id="stop10600" /><stop
style="stop-color:#18e9e8;stop-opacity:0;"
offset="1"
id="stop10602" /></linearGradient><linearGradient
inkscape:collect="never"
id="linearGradient1024"><stop
style="stop-color:#f70000;stop-opacity:1;"
offset="0"
id="stop1020" /><stop
style="stop-color:#fa7207;stop-opacity:1;"
offset="0.15848443"
id="stop1149" /><stop
style="stop-color:#ffce12;stop-opacity:1;"
offset="0.30084926"
id="stop1096" /><stop
style="stop-color:#a1e00a;stop-opacity:1;"
offset="0.37199998"
id="stop1153" /><stop
style="stop-color:#24f800;stop-opacity:1;"
offset="0.44346777"
id="stop1092" /><stop
style="stop-color:#1beda1;stop-opacity:1;"
offset="0.51599997"
id="stop1151" /><stop
style="stop-color:#18e9e9;stop-opacity:1;"
offset="0.56800002"
id="stop1098" /><stop
style="stop-color:#1e97ff;stop-opacity:1;"
offset="0.64159107"
id="stop1155" /><stop
style="stop-color:#272eff;stop-opacity:1;"
offset="0.73000002"
id="stop1094" /><stop
style="stop-color:#f604ff;stop-opacity:1;"
offset="0.86199999"
id="stop1100" /><stop
style="stop-color:#ff0202;stop-opacity:1;"
offset="1"
id="stop1022" /></linearGradient><linearGradient
inkscape:collect="never"
id="linearGradient3074"><stop
style="stop-color:#e26708;stop-opacity:1;"
offset="0"
id="stop3070" /><stop
style="stop-color:#bb3c00;stop-opacity:1;"
offset="1"
id="stop3072" /></linearGradient><radialGradient
xlink:href="#linearGradient45008"
id="radialGradient3076"
cx="30.688875"
cy="30.069115"
fx="30.688875"
fy="30.069115"
r="14.05412"
gradientUnits="userSpaceOnUse" /><linearGradient
xlink:href="#linearGradient45008"
id="linearGradient45010"
x1="-31.87768"
y1="22.065159"
x2="-31.87768"
y2="48.78738"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(101.16951,-6.5921995)" /><linearGradient
id="linearGradient45008"><stop
style="stop-color:#e14500;stop-opacity:1;"
offset="0"
id="stop45004" /><stop
style="stop-color:#e17900;stop-opacity:1;"
offset="0.59811592"
id="stop45012" /><stop
style="stop-color:#e19c00;stop-opacity:1;"
offset="1"
id="stop45006" /></linearGradient><linearGradient
xlink:href="#linearGradient45008"
id="linearGradient46715"
x1="31.917692"
y1="47.524929"
x2="31.917692"
y2="22.632998"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1.7923447e-6)" /><linearGradient
inkscape:collect="never"
xlink:href="#linearGradient1024"
id="linearGradient1026"
x1="20.242241"
y1="33.851089"
x2="37.684772"
y2="46.330421"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0816006,0,0,1.0816006,-2.5901136,-2.8438444)" /><linearGradient
xlink:href="#linearGradient1024"
id="linearGradient10606"
x1="13.452065"
y1="32.650345"
x2="48.054203"
y2="44.499554"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="never"
xlink:href="#linearGradient13704"
id="linearGradient13706"
x1="18.869927"
y1="34.850642"
x2="44.631165"
y2="34.850642"
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
id="namedview6"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
showgrid="false"
inkscape:zoom="22.627418"
inkscape:cx="3.9995725"
inkscape:cy="13.72229"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g2210"
showguides="false" /><g
id="g2210"
transform="matrix(0.54328517,0,0,0.54328517,-9.4489315,-11.300948)"><path
fill="#fc7f7f"
id="path66330"
style="fill:url(#linearGradient1026);fill-opacity:1;stroke:#000000;stroke-width:3.9817;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
d="m 34.4587,25.032669 a 5.3547445,5.3547445 0 0 0 -5.355897,4.95546 5.3547445,5.3547445 0 1 0 -5.356838,9.007222 l -9.03e-4,3.883973 a 1.784915,1.784915 0 0 0 1.784502,1.785329 l 10.709489,0.0023 a 1.784915,1.784915 0 0 0 1.785331,-1.7845 l 4.15e-4,-1.784915 5.353916,3.571076 0.0023,-10.709489 -5.355576,3.568584 7.33e-4,-3.159303 a 5.3547445,5.3547445 0 0 0 -3.567585,-9.335851 z" /></g></svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dfoere3ebvqcd"
path="res://.godot/imported/PostProcess.svg-9bd595bde45601bf2c44bb02a5f521fa.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rokojori_action_library/Icons/PostProcess.svg"
dest_files=["res://.godot/imported/PostProcess.svg-9bd595bde45601bf2c44bb02a5f521fa.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -2,6 +2,9 @@
using Godot;
using Rokojori;
using System.Collections.Generic;
using System.Globalization;
using System;
using System.Data;
namespace Rokojori
{
@ -11,6 +14,7 @@ namespace Rokojori
GizmoDrawerPlugin gizmoDrawerPlugin = new GizmoDrawerPlugin();
public static readonly string path = "res://addons/rokojori_action_library";
public static string Path( string path )
{
return RokojoriPlugin.path + "/" + path;
@ -18,25 +22,208 @@ namespace Rokojori
static readonly string RokojoriRootAutoLoad = "RokojoriRootAutoLoad";
static readonly string RokojoriRootAutoLoadPath = Path( "Runtime/Godot/Root.cs" );
static readonly string RokojoriProjectInternalPath = "res://.rokojori";
static readonly string RokojoriSettingsPath = "res://.rokojori/settings";
static readonly string RokojoriCachePath = "res://.rokojori/cache";
public override void _EnablePlugin()
{
this.LogInfo();
AddAutoloadSingleton( RokojoriRootAutoLoad, RokojoriRootAutoLoadPath );
EnsureHiddenProjectPath( RokojoriProjectInternalPath );
EnsureHiddenProjectPath( RokojoriSettingsPath );
EnsureHiddenProjectPath( RokojoriCachePath );
}
void EnsureHiddenProjectPath( string resPath )
{
var gdIgnorePath = resPath + "/.gdignore" ;
FilesSync.EnsureDirectoryExists( ProjectSettings.GlobalizePath( resPath ) );
if ( ! FilesSync.FileExists( ProjectSettings.GlobalizePath( gdIgnorePath ) ) )
{
FilesSync.SaveUTF8( ProjectSettings.GlobalizePath( gdIgnorePath ), "" );
}
}
public override void _DisablePlugin()
{
this.LogInfo();
RemoveAutoloadSingleton( RokojoriRootAutoLoad );
}
static readonly string ProblemsExplorerPath = "res://addons/rokojori_action_library/Tools/Messages/Messages.tscn";
static Control messages;
public override void _EnterTree()
{
EnsureHiddenProjectPath( RokojoriProjectInternalPath );
EnsureHiddenProjectPath( RokojoriSettingsPath );
EnsureHiddenProjectPath( RokojoriCachePath );
this.LogInfo();
AddNode3DGizmoPlugin( gizmoDrawerPlugin );
var pePackedScene = GD.Load<PackedScene>( ProblemsExplorerPath );
if ( pePackedScene != null )
{
// this.LogInfo( "Problems Explorer found: ", pePackedScene );
messages = ((PackedScene)pePackedScene).Instantiate<Control>();
var ui = messages.Get<UI>();
ui.BindOwnChildren();
var shortCut = new Shortcut();
shortCut.Events = [ new InputEventKey{ CtrlPressed = true, Keycode = Key.U } ];
AddControlToDock( DockSlot.RightBr, messages, shortCut );
}
else
{
this.LogInfo( "Problems Explorer not found: ", ProblemsExplorerPath );
}
}
public override void _ExitTree()
{
this.LogInfo();
if ( messages != null )
{
RemoveControlFromDocks( messages );
}
RemoveNode3DGizmoPlugin( gizmoDrawerPlugin );
}
bool wasDisposed = true;
public RokojoriPlugin()
{
wasDisposed = true;
}
public class MarkerData
{
public DateTime time;
}
static readonly string markerPath = "reload-marker.json";
protected override void Dispose( bool disposing )
{
var markerData = new MarkerData();
markerData.time = DateTime.Now;
SaveCache( markerPath, markerData );
}
float reloadDuration = 2;
DateTime lastUpdateTime = DateTime.Now;
DateTime lastDisposalTime = DateTime.Now;
public void SaveCache( string relativeCachePath, object data )
{
var path = RokojoriCachePath + "/" + relativeCachePath;
FilesSync.SaveJSON( ProjectSettings.GlobalizePath( path ), data );
}
public T LoadCache<T>( string relativeCachePath ) where T:new()
{
var path = RokojoriCachePath + "/" + relativeCachePath;
return FilesSync.LoadJSON<T>( ProjectSettings.GlobalizePath( path ));
}
public T LoadSettings<T>( string relativeSettingsPath ) where T:new()
{
var path = RokojoriSettingsPath + "/" + relativeSettingsPath;
return FilesSync.LoadJSON<T>( ProjectSettings.GlobalizePath( path ));
}
UI editingSceneUI = null;
UIRegion editingSceneRegion = null;
public override void _Process( double delta )
{
var editingScene = EditorInterface.Singleton.GetEditedSceneRoot();
if ( lastUpdateTime.HasExpired( reloadDuration ) )
{
lastUpdateTime = DateTime.Now;
var markerData = LoadCache<MarkerData>( markerPath );
if ( markerData != null && markerData.time != lastDisposalTime )
{
lastDisposalTime = markerData.time;
editingScene.ForEach<IAssemblyReload>( ar => ar.OnAssemblyReloaded() );
if ( messages != null )
{
messages.ForEach<IAssemblyReload>( ar => ar.OnAssemblyReloaded() );
}
}
}
if ( editingScene is UIRegion region && ! ( editingScene is UI ) )
{
if ( editingSceneRegion != region )
{
if ( editingSceneUI != null )
{
editingSceneUI.RemoveSelf();
editingSceneUI = null;
}
editingSceneRegion = region;
editingSceneUI = this.CreateChild<UI>();
editingSceneUI.settings = region.uiSettings;
editingSceneUI.BindChildrenOf( region );
}
editingSceneUI.updateMode = UI.UpdateMode.Only_Manual_Updates;
if ( region.reassignUI )
{
editingSceneUI.settings = region.uiSettings;
region.SetUI( editingSceneUI );
editingSceneUI.BindChildrenOf( region );
region.reassignUI = false;
}
if ( region.updateInEditor )
{
region.SetUI( editingSceneUI );
editingSceneUI.BindChildrenOf( region );
editingSceneUI.fontZoom = region.fontZoom;
editingSceneUI.UpdateExternal( (float)delta );
region.Layout();
region.computedFontSize = editingSceneUI.X_computedFontSizePixels;
}
}
}
}
}

View File

@ -9,6 +9,9 @@ namespace Rokojori
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
public partial class Action : NetworkNode
{
[ExportToolButton( "Trigger Action in Editor")]
public Callable TriggerActionButton => Callable.From( ()=> Trigger() );
NetworkNodeSlot _seedSlot = new NetworkNodeSlot();
NetworkNodeSlot _dataSlot = new NetworkNodeSlot();
NetworkNodeSlot _seedAndDataSlot = new NetworkNodeSlot();

View File

@ -23,7 +23,7 @@ namespace Rokojori
public bool changePlayState = true;
[Export]
public float changingPlayStateTresholdDB = -40f;
public float changingPlayStateTresholdDB = -80f;
[Export]
public TweenType tweenType = new TweenTimeCurve();

View File

@ -14,6 +14,8 @@ namespace Rokojori
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/SequenceAction.svg")]
public partial class SequenceAction : Action
{
int _dispatchCounter = 0;
public int GetLastSequenceActionID()

View File

@ -24,6 +24,11 @@ namespace Rokojori
protected override void _OnTrigger()
{
if ( Engine.IsEditorHint() )
{
return;
}
if ( light3D == null || tweenLightData == null )
{
return;

View File

@ -24,6 +24,11 @@ namespace Rokojori
protected override void _OnTrigger()
{
if ( Engine.IsEditorHint() )
{
return;
}
if ( particles3D == null )
{
return;

View File

@ -12,16 +12,29 @@ namespace Rokojori
[Export]
public Node3D target;
[Export]
public Mode positionSpace = Mode.Global;
[Export]
public Node3D endPosition;
public enum Mode
{
Global,
Local
}
[Export]
public Vector3 endOffset;
[Export]
public TweenType tweenType = new TweenTimeCurve();
[Export]
public bool cacheEndPositionOnStart = true;
@ -29,6 +42,32 @@ namespace Rokojori
public TimeLine timeLine;
Vector3 GetToPosition()
{
var toPosition = endOffset;
if ( Mode.Global == positionSpace )
{
if ( endPosition != null )
{
toPosition += endPosition.GlobalPosition;
}
}
else
{
if ( endPosition != null )
{
toPosition += endPosition.Position;
}
}
return toPosition;
}
protected override void _OnTrigger()
{
if ( target == null )
@ -40,13 +79,8 @@ namespace Rokojori
var start = tl.position;
var fromPosition = target.GlobalPosition;
var toPosition = endOffset;
if ( endPosition != null )
{
toPosition += endPosition.GlobalPosition;
}
var fromPosition = target.GetPosition( Mode.Global == positionSpace );
var toPosition = GetToPosition();
var sequenceID = DispatchStart();
@ -67,17 +101,19 @@ namespace Rokojori
if ( ! cacheEndPositionOnStart )
{
toPosition = endOffset;
if ( endPosition != null )
{
toPosition += endPosition.GlobalPosition;
}
toPosition = GetToPosition();
}
var lerpedPosition = fromPosition.Lerp( toPosition, state );
target.GlobalPosition = lerpedPosition;
if ( Mode.Global == positionSpace )
{
target.GlobalPosition = lerpedPosition;
}
else if ( Mode.Local == positionSpace )
{
target.Position = lerpedPosition;
}
if ( type == TimeLineSpanUpdateType.End )
{

View File

@ -64,6 +64,27 @@ namespace Rokojori
OmniLight3D light = null;
public override string[] _GetConfigurationWarnings()
{
var warnigns = new List<string>();
if ( flashEffect == null )
{
warnigns.Add( HierarchyName.Of( this ) + ":" + "No flash effect assigned");
}
for ( int i = 0; i < targets.Length; i++ )
{
if ( targets[ i ] == null )
{
warnigns.Add( HierarchyName.Of( this ) + ":" +"A null target is assigned in the targets array at index " + i );
}
}
return warnigns.ToArray();
}
Color ComputeLightColor( Color color, float phase )
{
if ( phase < 5/100f )

View File

@ -41,7 +41,7 @@ timeline = ExtResource("3_pgufg")
smooth = true
smoothingStrength = 0.477
positionShake = Vector3(0.075, 0, 0.075)
globalPosition = true
globalPosition = false
repeatAndFlipFirstPosition = true
rotationShake = Vector3(0.5, 0.5, 10)
globalRotation = false

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using Godot;
using System.Linq;
namespace Rokojori
{
@ -25,6 +26,27 @@ namespace Rokojori
public void OnAnimatorEnd(){}
public void OnAnimatorCancel(){}
public override string[] _GetConfigurationWarnings()
{
var warnigns = new List<string>();
if ( shakeEffect == null )
{
warnigns.Add( HierarchyName.Of( this ) + ":" + "No shake effect assigned");
}
for ( int i = 0; i < targets.Length; i++ )
{
if ( targets[ i ] == null )
{
warnigns.Add( HierarchyName.Of( this ) + ":" +"A null target is assigned in the targets array at index " + i );
}
}
return warnigns.ToArray();
}
protected override void _OnTrigger()
{
if ( _actionID != -1 )

View File

@ -22,12 +22,18 @@ namespace Rokojori
public void AddAction( Action<T> action )
{
if ( _actions.IndexOf( action ) != - 1 || _additions.IndexOf( action ) != -1 )
{
return;
}
if ( _canModify )
{
_actions.Add( action );
}
else
{
_additions.Add( action );
}
}

View File

@ -119,6 +119,17 @@ namespace Rokojori
return null;
}
public static T LoadJSON<T>( string path ) where T:new()
{
if ( ! FilesSync.FileExists( path ) )
{
return default(T);
}
var jsonString = LoadUTF8( path );
return JSON.ParseObject<T>( jsonString );
}
public static bool SaveBytes( string fileName, byte[] byteArray )
{
try

View File

@ -0,0 +1,15 @@
using Godot;
using System.Text;
using System.Collections.Generic;
namespace Rokojori
{
public interface ICustomDisposer
{
public void Dispose();
public string GetUID();
public string GetInfo();
}
}

View File

@ -0,0 +1 @@
uid://bgyrh3cmiuric

View File

@ -0,0 +1,12 @@
using Godot;
using System.Text;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
public interface IAssemblyReload
{
public void OnAssemblyReloaded();
}
}

View File

@ -0,0 +1 @@
uid://culnn75r8fbu4

View File

@ -183,7 +183,7 @@ namespace Rokojori
return list;
}
public static void ForEach<T>( Node root, Action<T> callback ) where T:class
public static void ForEach<T>( this Node root, Action<T> callback ) where T:class
{
var walker = nodesWalker;
@ -421,6 +421,18 @@ namespace Rokojori
nodes.ForEach( n => RemoveAndDelete( n ) );
}
public static void RemoveSelf( this Node node )
{
var parent = node.GetParent();
if ( parent != null )
{
parent.RemoveChild( node );
}
node.QueueFree();
}
public static void RemoveAndDeleteChildrenOfType<T>( Node parent, bool includeInternal = false ) where T:Node
{
if ( parent == null )
@ -470,6 +482,8 @@ namespace Rokojori
}
public static T GetDirectChild<T>( Node parent ) where T:Node
{
if ( parent == null )

View File

@ -1,3 +1,4 @@
using System;
using Godot;
@ -41,5 +42,55 @@ namespace Rokojori
return _singleton;
}
#if TOOLS
public override void _Process( double delta )
{
if ( ! Engine.IsEditorHint() )
{
return;
}
CheckWarnings();
}
int step = 0;
void CheckWarnings()
{
var walker = NodesWalker.Get();
for ( int i = 0; i < numNodeTests; i++ )
{
if ( _iterationNode == null || ! IsInstanceValid( _iterationNode ) )
{
_iterationNode = EditorInterface.Singleton.GetEditedSceneRoot();
}
else
{
_iterationNode = walker.NextNode( _iterationNode );
}
UpdateWarning( _iterationNode );
}
}
Node _iterationNode = null;
int numNodeTests = 100;
void UpdateWarning( Node n )
{
if ( n == null )
{
return;
}
n.UpdateConfigurationWarnings();
}
#endif
}
}

View File

@ -262,6 +262,17 @@ namespace Rokojori
return null;
}
public N NextAfterChildren( N node )
{
var lastGrandChild = LastGrandChild( node );
if ( lastGrandChild != null )
{
return NextNode( lastGrandChild );
}
return NextNode( node );
}
public bool IsChildOf( N child, N parent )
{
@ -490,6 +501,25 @@ namespace Rokojori
}
public void PruneChildTraversal( N root, Func<N,bool> callback )
{
var it = NextNode( root );
while ( it != null && IsChildOf( it, root ) )
{
var continueWithChildren = callback( it );
if ( continueWithChildren )
{
it = NextNode( it );
}
else
{
it = NextAfterChildren( it );
}
}
}
}
}

View File

@ -29,10 +29,24 @@ namespace Rokojori
[Export]
public RigidBody3D rigidBody3D;
[Export] Pointable pointable;
[Export]
public bool disablePointableDuringGrab = true;
public Pointable pointable;
bool _disablePointableDuringGrab;
[Export]
public bool disablePointableDuringGrab
{
get => _disablePointableDuringGrab;
set
{
_disablePointableDuringGrab = value;
#if TOOLS
UpdateConfigurationWarnings();
#endif
}
}
[ExportGroup("Read Only")]
[Export]
@ -40,6 +54,28 @@ namespace Rokojori
protected bool enablePointableOnRelease = false;
public override string[] _GetConfigurationWarnings()
{
var warnigns = new List<string>();
if ( grabTarget == null )
{
warnigns.Add( HierarchyName.Of( this ) + ":" + "No grabTarget assigned.");
}
if ( rigidBody3D == null )
{
warnigns.Add( HierarchyName.Of( this ) + ":" + "No rigidBody3D assigned.");
}
if ( pointable == null && _disablePointableDuringGrab )
{
warnigns.Add( HierarchyName.Of( this ) + ":" + "No pointable assigned, although 'disablePointableDuringGrab' is active.");
}
return warnigns.ToArray();
}
public void SetGrabber( Grabber grabber )
{
this.grabber = grabber;

View File

@ -50,7 +50,7 @@ namespace Rokojori
lc = lm.languageLocale;
}
RJLog.Log( "currentLanguage", lc );
// RJLog.Log( "currentLanguage", lc );
return lc;
}

View File

@ -709,6 +709,11 @@ namespace Rokojori
return q.X == 0 && q.Y == 0 && q.Z == 0 && q.W == 0;
}
public static bool IsZero( this Vector3 v )
{
return v.X == 0 && v.Y == 0 && v.Z == 0;
}
public static bool IsValid( this Quaternion q )
{
return ! ( q.IsFinite() || q.IsZero() );
@ -776,6 +781,11 @@ namespace Rokojori
return node.GlobalTransform.Basis.Scale;
}
public static Vector3 GetPosition( this Node3D node, bool global = false )
{
return global ? node.GlobalPosition : node.Position;
}
public static float GetGlobalUniScale( Node3D node )
{
var scale3 = GetGlobalScale( node );

View File

@ -72,7 +72,7 @@ namespace Rokojori
public override void _Process( double delta )
{
if ( ! IsInSession )
if ( sessionManager == null || ! sessionManager.isInSession )
{
return;
}

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Text;
namespace Rokojori
{
public class IDGenerator
{
static readonly string DefaultID_CharacterSet =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static readonly int DefaultID_NumCharacters = 16;
protected string characterSet = IDGenerator.DefaultID_CharacterSet;
protected int numCharacters = DefaultID_NumCharacters;
public IDGenerator set( string characterSet, int numCharacters )
{
this.characterSet = characterSet;
this.numCharacters = numCharacters;
return this;
}
public static string GenerateID( RandomEngine randomEngine = null )
{
var id = "";
randomEngine = RandomEngine.CreateIfNull( randomEngine );
for ( var i = 0; i < DefaultID_NumCharacters; i++ )
{
var randomCharacter = randomEngine.From( DefaultID_CharacterSet );
id += randomCharacter;
}
return id;
}
public string generate( RandomEngine randomEngine = null )
{
var id = new StringBuilder();
randomEngine = RandomEngine.CreateIfNull( randomEngine );
for ( var i = 0; i < numCharacters; i++ )
{
var randomCharacter = randomEngine.From( characterSet );
id.Append( randomCharacter );
}
return id.ToString();
}
}
}

View File

@ -0,0 +1 @@
uid://bc5kpq03hnesn

View File

@ -12,6 +12,9 @@ namespace Rokojori
[GlobalClass]
public partial class SelectorFlag:Resource
{
public override string ToString()
{
return HierarchyName.Of( this );
}
}
}

View File

@ -20,6 +20,8 @@ namespace Rokojori
return _name as S;
}
public string propertyName => _name.propertyName;
public T Get()
{
return _name._Get<T>( _material, default( T ) );

View File

@ -21,6 +21,16 @@ namespace Rokojori
this[ key ].Add( value );
}
public void AddIfNotPresent( K key, V value )
{
if ( ContainsKey( key ) && this[ key ].Contains( value ) )
{
return;
}
Add( key, value );
}
public void Remove( K key, V value )
{
if ( ! ContainsKey( key ) )

View File

View File

@ -0,0 +1 @@
uid://be3ypxsvvjele

View File

@ -0,0 +1,81 @@
using Godot;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Reflection;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class CheckTransforms:DebugAction
{
protected new const string name = "Check Transforms";
[Export]
public Node[] roots = [];
int _numProcessed = 0;
protected override void _OnTrigger()
{
ClearMessages();
_numProcessed = 0;
var id = DispatchStart();
roots.ForEach(
( r )=>
{
Nodes.ForEach<Node3D>( r, n => CheckTransformsOf( n ) );
}
);
UpdateStatus( "Processed: " + _numProcessed );
FinishMessages();
DispatchEnd( id );
}
void CheckTransformsOf( Node3D node3D )
{
if ( ! Math3D.IsValid( node3D.GlobalPosition ) )
{
Error( node3D, "GlobalPosition not valid", node3D.GlobalPosition );
}
if ( ! Math3D.IsValid( node3D.Position ) )
{
Error( node3D, "Position not valid", node3D.Position );
}
if ( ! Math3D.IsValid( node3D.GlobalRotation ) )
{
Error( node3D, "GlobalRotation not valid", node3D.GlobalRotation );
}
if ( ! Math3D.IsValid( node3D.Rotation ) )
{
Error( node3D, "Rotation not valid", node3D.Rotation );
}
if ( ! Math3D.IsValid( node3D.Scale ) )
{
Error( node3D, "Scale not valid", node3D.Scale );
}
if ( Math3D.IsZero( node3D.Scale ) )
{
Error( node3D, "Scale is zero", node3D.Scale );
}
_numProcessed ++;
}
}
}

View File

@ -0,0 +1 @@
uid://cau3dsmyw72km

View File

@ -0,0 +1,55 @@
using Godot;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Reflection;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class CheckWarnings:DebugAction
{
protected new const string name = "Check Warnings";
[Export]
public Node[] roots = [];
int _numProcessed = 0;
protected override void _OnTrigger()
{
ClearMessages();
_numProcessed = 0;
var id = DispatchStart();
roots.ForEach(
( r )=>
{
Nodes.ForEach<Node3D>( r, n => CheckWarningsOf( n ) );
}
);
UpdateStatus( "Processed: " + _numProcessed );
FinishMessages();
DispatchEnd( id );
}
void CheckWarningsOf( Node n )
{
var warnings = n._GetConfigurationWarnings();
if ( warnings != null && warnings.Length > 0 )
{
Warning( n, "Has " + warnings.Length + " warnings");
}
_numProcessed ++;
}
}
}

View File

@ -0,0 +1 @@
uid://dfxk0nger1ug

View File

@ -0,0 +1,102 @@
using Godot;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Reflection;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class DebugAction:SequenceAction
{
protected const string name = "Run";
protected List<DebugMessage> _messages = [];
[Export]
public DebugMessage[] messages = [];
public void ClearMessages()
{
_messages.Clear();
messages = [];
}
public void FinishMessages()
{
messages = _messages.ToArray();
}
[Export(PropertyHint.MultilineText)]
public string status = "";
public virtual void UpdateStatus( string status)
{
this.status = RJLog.Stringify(
status + ( status == "" ? "" : "," ),
"Errors:",
_messages.FindAll( m => m.type == MessageType.Error ).Count + ",",
"Warnings:",
_messages.FindAll( m => m.type == MessageType.Warning ).Count
);
}
[ExportToolButton( name )]
public Callable RunButton => Callable.From(
()=>
{
Trigger( this );
}
);
void AddMessage( MessageType type, Node n, params object[] messages )
{
var msg = new DebugMessage();
msg.type = type;
msg.node = n.GetPath();
msg.content = HierarchyName.Of( n ) + ":" + RJLog.Stringify( messages );
_messages.Add( msg );
}
void AddMessage( MessageType type, params object[] messages )
{
var msg = new DebugMessage();
msg.type = type;
msg.content = RJLog.Stringify( messages );
_messages.Add( msg );
}
public void Verbose( Node n, params object[] messages )
{
AddMessage( MessageType.Verbose, n, messages );
}
public void Verbose( params object[] messages )
{
AddMessage( MessageType.Verbose, messages );
}
public void Info( Node n, params object[] messages )
{
AddMessage( MessageType.Info, n, messages );
}
public void Error( Node n, params object[] messages )
{
AddMessage( MessageType.Error, n, messages );
}
public void Warning( Node n, params object[] messages )
{
AddMessage( MessageType.Warning, n, messages );
}
}
}

View File

@ -0,0 +1 @@
uid://bpch2aat78rqo

View File

@ -0,0 +1,62 @@
using Godot;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Reflection;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class DebugMessage:Resource
{
[Export]
public MessageType type;
[Export(PropertyHint.MultilineText)]
public string content;
[ExportToolButton( "Show Node")]
public Callable ShowNodeButton => Callable.From(
( ) =>
{
if ( node == null )
{
return;
}
#if TOOLS
var root = EditorInterface.Singleton.GetEditedSceneRoot();
var resolvedNode = root.GetNode( node );
if ( resolvedNode == null )
{
this.LogError( "Couldn't resolve node", node );
return;
}
this.LogInfo( resolvedNode );
// var selection = EditorInterface.Singleton.GetSelection();
// selection.Clear();
// selection.AddNode( resolvedNode );
EditorInterface.Singleton.InspectObject( resolvedNode );
#endif
}
);
[Export]
public NodePath node;
[Export]
public Resource resource;
}
}

View File

@ -0,0 +1 @@
uid://b2pay1d2traba

View File

@ -0,0 +1,26 @@
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
namespace Rokojori
{
public static class DateMath
{
public static float GetDifference( this DateTime a, DateTime b )
{
return (float) ( ( a - b ).TotalSeconds );
}
public static bool HasExpired( this DateTime oldTime, float duration )
{
var difference = GetDifference( DateTime.Now, oldTime );
return difference >= duration;
}
}
}

View File

@ -0,0 +1 @@
uid://ua87gtx3gt06

View File

@ -73,6 +73,11 @@ namespace Rokojori
timeline = TimeLineManager.Ensure( timeline );
var runner = timeline.runner;
if ( runner == null )
{
return null;
}
var start = timeline.position + delay;
var end = start + duration;

View File

@ -79,7 +79,7 @@ namespace Rokojori
public int GetTimeLineIndex( TimeLine timeLine )
{
return Arrays.IndexOf( timeLines, timeLine );
return timeLines == null ? -1 : Arrays.IndexOf( timeLines, timeLine );
}
public void Modulate( TimeLine timeline, AnimationCurve c, Action<bool> onReady )

View File

@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="TimeLine" load_steps=2 format=3 uid="uid://b4iykcwesp1y6"]
[ext_resource type="Script" uid="uid://fqm54rn8fnnl" path="res://addons/rokojori_action_library/Runtime/Time/TimeLine.cs" id="1_xynux"]
[resource]
script = ExtResource("1_xynux")
isLooping = false
loopStart = 0.0
loopEnd = 100000.0
startSpeed = 1.0
autoStart = true

View File

@ -53,13 +53,25 @@ namespace Rokojori
return -1;
}
public static T Find<T>( T[] values, Func<T,bool> predicate )
public static T Find<T>( this T[] values, Func<T,bool> predicate )
{
var entryIndex = FindIndex( values, predicate );
return entryIndex == -1 ? default(T) : values[ entryIndex ];
}
public static T FindNonNull<T>( this T[] values, Func<T,bool> predicate )
{
if ( values == null )
{
return default(T);
}
var entryIndex = FindIndex( values, ( v ) => v != null && predicate( v ) );
return entryIndex == -1 ? default(T) : values[ entryIndex ];
}
public static bool Contains <T>( T[] values, T other )
{
return Array.IndexOf( values, other ) != -1;

View File

@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class BoxedFloatValue:Resource
{
public virtual float GetFloatValue()
{
return 0;
}
public virtual void SetFloatValue( float value )
{
}
public override string ToString()
{
return this.GetType().Name + "( " + RegexUtility.NumberToString( GetFloatValue() ) + " )";
}
public static void Lerp( BoxedFloatValue a, BoxedFloatValue b, float amount, BoxedFloatValue output )
{
if ( a == null || b == null || output == null )
{
return;
}
output.SetFloatValue( Mathf.Lerp( a.GetFloatValue(), b.GetFloatValue(), amount ) );
}
}
}

View File

@ -0,0 +1 @@
uid://d2l63proa4fod

View File

@ -26,6 +26,19 @@ namespace Rokojori
return cv;
}
public static ColorValue Create( ColorValue value )
{
if ( value == null )
{
return null;
}
var cv = new ColorValue();
cv.value = value.value;
return cv;
}
public static ColorValue Clone( ColorValue value, bool deepClone )
{
if ( deepClone )

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class BoolFloatValue:BoxedFloatValue
{
[Export]
public bool value;
public override float GetFloatValue()
{
return value ? 1f : 9f;
}
public override void SetFloatValue( float value )
{
this.value = value > 0.5f;
}
public static BoolFloatValue Create( float value )
{
var fv = new BoolFloatValue();
fv.value = value > 0.5f;
return fv;
}
public static BoolFloatValue Create( double value )
{
return Create( (float) value );
}
public static BoolFloatValue Clone( BoolFloatValue value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value ? 1f : 0f);
}
return value;
}
public static BoolFloatValue Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new BoolFloatValue { value = floatValue.GetFloatValue() > 0.5f };
}
}
}

View File

@ -0,0 +1 @@
uid://y1ku3iitb6bh

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Float16Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"0,16")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Float16Value Create( float value )
{
var fv = new Float16Value();
fv.value = value;
return fv;
}
public static Float16Value Create( double value )
{
return Create( (float) value );
}
public static Float16Value Clone( Float16Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Float16Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Float16Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://b0kgrebe0q3ht

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Float256Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"0,256")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Float256Value Create( float value )
{
var fv = new Float256Value();
fv.value = value;
return fv;
}
public static Float256Value Create( double value )
{
return Create( (float) value );
}
public static Float256Value Clone( Float256Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Float256Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Float256Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://72iqkk7yl6d8

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Float2Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"0,2")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Float2Value Create( float value )
{
var fv = new Float2Value();
fv.value = value;
return fv;
}
public static Float2Value Create( double value )
{
return Create( (float) value );
}
public static Float2Value Clone( Float2Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Float2Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Float2Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://2gc332dhq6h6

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Float4Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"0,4")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Float4Value Create( float value )
{
var fv = new Float4Value();
fv.value = value;
return fv;
}
public static Float4Value Create( double value )
{
return Create( (float) value );
}
public static Float4Value Clone( Float4Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Float4Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Float4Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://bc40dwhrgpsr0

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Float8Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"0,8")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Float8Value Create( float value )
{
var fv = new Float8Value();
fv.value = value;
return fv;
}
public static Float8Value Create( double value )
{
return Create( (float) value );
}
public static Float8Value Clone( Float8Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Float8Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Float8Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://fcr85dhuuhx7

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class FloatDOFDistanceValue:BoxedFloatValue
{
[Export(PropertyHint.Range,"0.01,8192")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static FloatDOFDistanceValue Create( float value )
{
var fv = new FloatDOFDistanceValue();
fv.value = value;
return fv;
}
public static FloatDOFDistanceValue Create( double value )
{
return Create( (float) value );
}
public static FloatDOFDistanceValue Clone( FloatDOFDistanceValue value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static FloatDOFDistanceValue Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new FloatDOFDistanceValue { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://ju7lmk5w3ofw

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class FloatDOFTransitionValue:BoxedFloatValue
{
[Export(PropertyHint.Range,"-1,8192")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static FloatDOFTransitionValue Create( float value )
{
var fv = new FloatDOFTransitionValue();
fv.value = value;
return fv;
}
public static FloatDOFTransitionValue Create( double value )
{
return Create( (float) value );
}
public static FloatDOFTransitionValue Clone( FloatDOFTransitionValue value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static FloatDOFTransitionValue Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new FloatDOFTransitionValue { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://b26si6ilxpea

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Polar1024Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"-1024,1024")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Polar1024Value Create( float value )
{
var fv = new Polar1024Value();
fv.value = value;
return fv;
}
public static Polar1024Value Create( double value )
{
return Create( (float) value );
}
public static Polar1024Value Clone( Polar1024Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Polar1024Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Polar1024Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://bfa4er62bvogk

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Polar16Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"-16,16")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Polar16Value Create( float value )
{
var fv = new Polar16Value();
fv.value = value;
return fv;
}
public static Polar16Value Create( double value )
{
return Create( (float) value );
}
public static Polar16Value Clone( Polar16Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Polar16Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Polar16Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://bjjubtyf02q1v

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Polar2Value:BoxedFloatValue
{
[Export(PropertyHint.Range,"-2,2")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static Polar2Value Create( float value )
{
var fv = new Polar2Value();
fv.value = value;
return fv;
}
public static Polar2Value Create( double value )
{
return Create( (float) value );
}
public static Polar2Value Clone( Polar2Value value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static Polar2Value Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new Polar2Value { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://ddh3df5imkqkq

View File

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class PolarValue:BoxedFloatValue
{
[Export(PropertyHint.Range,"-1,1")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static PolarValue Create( float value )
{
var fv = new PolarValue();
fv.value = value;
return fv;
}
public static PolarValue Create( double value )
{
return Create( (float) value );
}
public static PolarValue Clone( PolarValue value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
public static PolarValue Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new PolarValue { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1 @@
uid://csmp7gbpbwb5w

View File

@ -8,14 +8,19 @@ namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class FloatValue:Resource
public partial class FloatValue:BoxedFloatValue
{
[Export]
public float value;
public override string ToString()
public override float GetFloatValue()
{
return "FloatValue( " + RegexUtility.NumberToString( value ) + " )";
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static FloatValue Create( float value )
@ -41,15 +46,15 @@ namespace Rokojori
return value;
}
public static void Lerp( FloatValue a, FloatValue b, float amount, FloatValue output )
public static FloatValue Create( BoxedFloatValue floatValue )
{
if ( a == null || b == null || output == null )
if ( floatValue == null )
{
return;
return null;
}
output.value = Mathf.Lerp( a.value, b.value, amount );
return new FloatValue { value = floatValue.GetFloatValue() };
}
}
}

View File

@ -0,0 +1,62 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class NormalizedValue:BoxedFloatValue
{
[Export(PropertyHint.Range,"0,1")]
public float value;
public override float GetFloatValue()
{
return value;
}
public override void SetFloatValue( float value )
{
this.value = value;
}
public static NormalizedValue Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new NormalizedValue { value = floatValue.GetFloatValue() };
}
public static NormalizedValue Create( float value )
{
var fv = new NormalizedValue();
fv.value = value;
return fv;
}
public static NormalizedValue Create( double value )
{
return Create( (float) value );
}
public static NormalizedValue Clone( NormalizedValue value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value );
}
return value;
}
}
}

View File

@ -0,0 +1 @@
uid://b0mm8ah33f6id

View File

@ -0,0 +1,66 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class PowerValue:BoxedFloatValue
{
[Export(PropertyHint.Range,"0,1")]
public float value;
[Export(PropertyHint.Range,"0.1,10")]
public float power = 1.0f;
public override float GetFloatValue()
{
return Mathf.Pow( value, power );
}
public override void SetFloatValue( float value )
{
this.value = MathX.Base( power, value );
}
public static PowerValue Create( BoxedFloatValue floatValue )
{
if ( floatValue == null )
{
return null;
}
return new PowerValue { value = floatValue.GetFloatValue() };
}
public static PowerValue Create( float value, float power = 1.0f )
{
var fv = new PowerValue();
fv.value = value;
fv.power = power;
return fv;
}
public static PowerValue Create( double value )
{
return Create( (float) value );
}
public static PowerValue Clone( PowerValue value, bool deepClone )
{
if ( deepClone )
{
return value == null ? null : Create( value.value, value.power );
}
return value;
}
}
}

View File

@ -0,0 +1 @@
uid://1a3u3dm571er

View File

@ -13,6 +13,7 @@ namespace Rokojori
int _offset;
int _length;
public ListView( List<T> list, int offset, int length )
{
_list = list;
@ -50,6 +51,24 @@ namespace Rokojori
public static class Lists
{
public static void Union<T>( this List<T> list, List<T> other )
{
var set = new HashSet<T>( list );
set.UnionWith( other );
list.Clear();
list.AddRange( [.. set ] );
}
public static void AddIfNotPresent<T>( this List<T> values, T value )
{
if ( values.Contains( value ) )
{
return;
}
values.Add( value );
}
public static bool IsOneOf<T>( T value, params T[] values )
{
for ( int i = 0; i < values.Length; i++ )
@ -660,7 +679,7 @@ namespace Rokojori
}
public static List<R> FilterType<T,R>( List<T> inputList ) where R:T
public static List<R> FilterType<T,R>( this List<T> inputList ) where R:T
{
var list = new List<R>();

View File

@ -0,0 +1,418 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Rokojori
{
public class UIDragging
{
public class UIDraggingCallbacks: ICustomDisposer
{
public UI ui;
public Control control;
public bool wasDisposed = false;
public Action<InputEvent> onMouseClick;
public Callable callable;
public Action<InputEvent> onDragging;
public Action<float> onProcess;
public Dictionary<MouseButton,EditableUIDraggingEvent> mouseEvents = new Dictionary<MouseButton, EditableUIDraggingEvent>();
public Dictionary<MouseButton,bool> mouseEventsDragging = new Dictionary<MouseButton, bool>();
public string uid = IDGenerator.GenerateID();
public string GetUID(){ return uid; }
string info = "";
public string GetInfo(){ return info;}
public void Set( Control c, Func<UIDraggingEvent,bool> callback )
{
var callbacks = this;
callbacks.control = c;
callbacks.ui = c.FindParentThatIs<UI>();
callbacks.ui.AddForDisposing( callbacks );
info = HierarchyName.Of( c );
callbacks.onProcess = (float delta )=>
{
foreach ( var m in callbacks.mouseEvents )
{
callback( callbacks.mouseEvents[ m.Key ] );
}
};
callbacks.onDragging = ( InputEvent ie ) =>
{
if ( ie is InputEventMouseButton mb && ! mb.Pressed )
{
callbacks.mouseEventsDragging[ mb.ButtonIndex ] = false;
callbacks.mouseEvents[ mb.ButtonIndex ].UpdatePosition( mb.GlobalPosition, true );
callback( callbacks.mouseEvents[ mb.ButtonIndex ] );
if ( ! callbacks.hasAnyMouseDragging )
{
callbacks.ui.onInputEvent.RemoveAction( callbacks.onDragging );
callbacks.ui.onProcess.RemoveAction( callbacks.onProcess );
callbacks.hasDraggingCallback = false;
if ( c is UIStylePropertyContainer sc )
{
sc.GetUISelectorFlags().Remove( UISelectorFlag.Dragging );
}
}
}
if ( ie is InputEventMouseMotion mo )
{
var globalPosition = mo.GlobalPosition;
foreach ( var m in callbacks.mouseEvents )
{
callbacks.mouseEvents[ m.Key ].UpdatePosition( globalPosition );
// callback( callbacks.mouseEvents[ m.Key ] );
}
}
};
callbacks.onMouseClick = ( InputEvent ie )=>
{
if ( ! ( ie is InputEventMouseButton b && b.Pressed ) )
{
return;
}
var mb = ie as InputEventMouseButton;
var button = mb.ButtonIndex;
var draggingEvent = callbacks.GetMouseEvent( button );
draggingEvent.SetStart( mb.GlobalPosition );
var result = callback( draggingEvent );
if ( ! result )
{
return;
}
if ( c is UIStylePropertyContainer sc )
{
sc.GetUISelectorFlags().AddIfNotPresent( UISelectorFlag.Dragging );
}
callbacks.mouseEventsDragging[ button ] = true;
if ( ! callbacks.hasDraggingCallback )
{
callbacks.ui.onInputEvent.AddAction( callbacks.onDragging );
callbacks.ui.onProcess.AddAction( callbacks.onProcess );
}
};
callbacks.Connect();
wasDisposed = false;
}
public void Dispose()
{
wasDisposed = true;
if ( control != null && Node.IsInstanceValid( control ) )
{
control.Disconnect( "gui_input", callable );
}
// ui = null;
// control = null;
onMouseClick = null;
onDragging = null;
onProcess = null;
mouseEvents.Clear();
mouseEventsDragging.Clear();
// mouseEvents = null;
// mouseEventsDragging = null;
}
public bool hasAnyMouseDragging
{
get
{
foreach ( var mb in mouseEventsDragging )
{
if ( mb.Value )
{
return true;
}
}
return false;
}
}
public bool hasDraggingCallback = false;
public EditableUIDraggingEvent GetMouseEvent( MouseButton mb )
{
if ( ! mouseEvents.ContainsKey( mb ) )
{
mouseEvents[ mb ] = new EditableUIDraggingEvent( mb );
}
mouseEvents[ mb ].SetUI( ui );
return mouseEvents[ mb ];
}
public void Clear()
{
control.Disconnect( "gui_input", callable );
}
public void Connect()
{
callable = Callable.From( onMouseClick );
control.Connect( "gui_input", callable );
}
}
public class UIDraggingEvent
{
public enum Phase
{
Start,
Dragging,
End
}
protected Phase _phase = Phase.Start;
public bool isStart => Phase.Start == _phase;
public bool isDragging => Phase.Dragging == _phase;
public bool isEnd => Phase.End == _phase;
protected UI _ui;
public UI ui => _ui;
protected MouseButton _mouseButton;
public MouseButton mouseButton => _mouseButton;
public bool isLeftMouseButton => MouseButton.Left == _mouseButton;
public bool isMiddleMouseButton => MouseButton.Middle == _mouseButton;
public bool isRightMouseButton => MouseButton.Right == _mouseButton;
public Vector2 customOffset;
protected int _touchID = -1;
protected Vector2 _startPosition;
protected Vector2 _position;
protected Vector2 _lastPosition;
protected Vector2 _furthestPointFromStart;
protected float _biggestDistance;
public Vector2 startPosition => _startPosition;
public Vector2 position => _position;
public Vector2 lastPosition => _lastPosition;
public Vector2 movementSinceLastFrame => _position - lastPosition;
public Vector2 distanceToStart => _position - _startPosition;
public Vector2 furthestPointToStart => _furthestPointFromStart;
public float maximumMovement => _biggestDistance;
public UIDraggingEvent( MouseButton mb )
{
_mouseButton = mb;
}
public UIDraggingEvent( int touchID )
{
this._touchID = touchID;
}
}
public class EditableUIDraggingEvent:UIDraggingEvent
{
public EditableUIDraggingEvent( MouseButton mb ):base( mb ){}
public EditableUIDraggingEvent( int touchID ):base( touchID ){}
public void SetUI( UI ui )
{
_ui = ui;
}
public void SetStart( Vector2 startPosition )
{
_startPosition = startPosition;
_position = startPosition;
_lastPosition = startPosition;
_furthestPointFromStart = Vector2.Zero;
_phase = Phase.Start;
}
public void UpdatePosition( Vector2 position, bool isEnd = false )
{
_lastPosition = _position;
_position = position;
var d = position.DistanceTo( _startPosition );
if ( d > _biggestDistance )
{
_biggestDistance = d;
_furthestPointFromStart = position;
}
_phase = isEnd ? Phase.End : Phase.Dragging;
}
}
public static UIDraggingCallbacks OnLeftMouseButton( Control c, Action<UIDraggingEvent> callback )
{
return OnOneMouseButton( c, MouseButton.Left, callback );
}
public static UIDraggingCallbacks OnMiddleMouseButton( Control c, Action<UIDraggingEvent> callback )
{
return OnOneMouseButton( c, MouseButton.Middle, callback );
}
public static UIDraggingCallbacks OnRightMouseButton( Control c, Action<UIDraggingEvent> callback )
{
return OnOneMouseButton( c, MouseButton.Right, callback );
}
public static UIDraggingCallbacks OnOneMouseButton( Control c, MouseButton mouseButton, Action<UIDraggingEvent> callback )
{
var oneButtonCallback = ( UIDraggingEvent ev ) =>
{
if ( ev.mouseButton != mouseButton )
{
return false;
}
callback( ev );
return true;
};
return OnAnyMouseButton( c, oneButtonCallback );
}
public static UIDraggingCallbacks OnAnyMouseButton( Control c, Func<UIDraggingEvent,bool> callback )
{
var callbacks = new UIDraggingCallbacks();
callbacks.Set( c, callback );
// callbacks.control = c;
// callbacks.ui = c.FindParentThatIs<UI>();
// callbacks.ui.AddForDisposing( callbacks );
// callbacks.onProcess = (float delta )=>
// {
// foreach ( var m in callbacks.mouseEvents )
// {
// callback( callbacks.mouseEvents[ m.Key ] );
// }
// };
// callbacks.onDragging = ( InputEvent ie ) =>
// {
// if ( ie is InputEventMouseButton mb && ! mb.Pressed )
// {
// callbacks.mouseEventsDragging[ mb.ButtonIndex ] = false;
// callbacks.mouseEvents[ mb.ButtonIndex ].UpdatePosition( mb.GlobalPosition, true );
// callback( callbacks.mouseEvents[ mb.ButtonIndex ] );
// if ( ! callbacks.hasAnyMouseDragging )
// {
// callbacks.ui.onInputEvent.RemoveAction( callbacks.onDragging );
// callbacks.ui.onProcess.RemoveAction( callbacks.onProcess );
// callbacks.hasDraggingCallback = false;
// }
// }
// if ( ie is InputEventMouseMotion mo )
// {
// var globalPosition = mo.GlobalPosition;
// foreach ( var m in callbacks.mouseEvents )
// {
// callbacks.mouseEvents[ m.Key ].UpdatePosition( globalPosition );
// // callback( callbacks.mouseEvents[ m.Key ] );
// }
// }
// };
// callbacks.onMouseClick = ( InputEvent ie )=>
// {
// if ( ! ( ie is InputEventMouseButton b && b.Pressed ) )
// {
// return;
// }
// var mb = ie as InputEventMouseButton;
// var button = mb.ButtonIndex;
// var draggingEvent = callbacks.GetMouseEvent( button );
// draggingEvent.SetStart( mb.GlobalPosition );
// var result = callback( draggingEvent );
// if ( ! result )
// {
// return;
// }
// callbacks.mouseEventsDragging[ button ] = true;
// if ( ! callbacks.hasDraggingCallback )
// {
// callbacks.ui.onInputEvent.AddAction( callbacks.onDragging );
// callbacks.ui.onProcess.AddAction( callbacks.onProcess );
// }
// };
// callbacks.Connect();
// c.Connect( "gui_input", Callable.From( callbacks.onMouseClick ) );
// c.GuiInput += callbacks.onMouseClick;
return callbacks;
}
}
}

View File

@ -0,0 +1 @@
uid://b7ykgc6yec5fj

View File

@ -0,0 +1,354 @@
using Godot;
using System;
using System.IO;
namespace Rokojori
{
[Tool][GlobalClass]
public partial class UISlider : Node, IAssemblyReload
{
[Export]
public Control button;
[Export]
public Control background;
[Export]
public Smoothing smoothing;
public enum Direction
{
Vertical,
Horizontal,
Both
}
[Export]
public Direction direction = Direction.Vertical;
[Export]
public Vector2 sliderValue;
[ExportGroup( "Scrolling")]
[Export]
public Control scrollTarget;
[Export]
public Control scrollContainer;
[Export]
public bool adjustButtonSizeToScrollContent;
[Export( PropertyHint.Range, "0,500, suffix:px")]
public float mouseWheelAbsoluteScroll = 10f;
[Export( PropertyHint.Range, "0,100, suffix:%")]
public float mouseWheelRelativeScroll = 10f;
Vector2 cachedMouseOffset;
Vector2 cachedButtonPosition;
public void OnAssemblyReloaded()
{
AddDraggingListener();
}
string scrollID = IDGenerator.GenerateID();
public override void _Ready()
{
// button.GuiInput += OnGUIInput;
// this.LogInfo( "S Adding new listeners" );
AddDraggingListener();
if ( scrollTarget != null && scrollContainer != null )
{
scrollContainer.Resized += SyncScroll;
scrollContainer.GuiInput += ( InputEvent ie )=>
{
if ( ie is InputEventMouseButton mb &&
( mb.ButtonIndex == MouseButton.WheelUp || mb.ButtonIndex == MouseButton.WheelDown ||
mb.ButtonIndex == MouseButton.WheelLeft || mb.ButtonIndex == MouseButton.WheelRight )
)
{
var range = GetScrollRange();
// var percentageAmount = 0.1f;
// var relativeToAbsolute = percentageAmount * range;
var absoluteAmount = mouseWheelAbsoluteScroll;
var absoluteToRelative = mouseWheelAbsoluteScroll * Vector2.One / range;
var buttonRange = absoluteToRelative * GetButtonScrollRange();
var scrollDelta = buttonRange;
// this.LogInfo( leftMouseCallback == null, leftMouseCallback?.GetUID(), leftMouseCallback?.GetInfo(), leftMouseCallback?.wasDisposed );
// scrollContainer.LogInfo( "Input", ie );
if ( mb.ButtonIndex == MouseButton.WheelUp )
{
scrollDelta.Y *= -1;
}
if ( mb.ButtonIndex == MouseButton.WheelLeft )
{
scrollDelta.X *= -1;
}
// sliderValue += scrollDelta;
// sliderValue = sliderValue.Clamp( 0, 1 );
// SyncScroll();
if ( Direction.Horizontal == direction )
{
scrollDelta.Y = 0;
}
else if ( Direction.Vertical == direction )
{
scrollDelta.X = 0;
}
nextValue = ( button.Position + scrollDelta ).Clamp( Vector2.Zero, GetButtonScrollRange() );
// this.LogInfo( scrollDelta );
var ui = this.FindParentThatIs<UI>();
ui.onProcess.AddAction( UpdatePosition );
( button as UIStylePropertyContainer ).AddUISelectorFlag( UISelectorFlag.Scrolling, scrollID );
}
};
}
if ( adjustButtonSizeToScrollContent )
{
scrollTarget.Resized += UpdateButtonSize;
scrollContainer.Resized += UpdateButtonSize;
UpdateButtonSize();
}
}
void UpdateButtonSize()
{
var value = new UINumber();
var target = button as UIStylePropertyContainer;
if ( Direction.Vertical == direction )
{
value.value = Mathf.Min( 10, background.Size.Y - Mathf.Max( 10, scrollTarget.Size.Y - scrollContainer.Size.Y ) );
target.SetUIStyleNumberProperty( UIStyleNumberProperty.Height, value );
}
if ( Direction.Horizontal == direction )
{
value.value = Mathf.Min( 10, background.Size.X - Mathf.Max( 10, scrollTarget.Size.X - scrollContainer.Size.X ) );
target.SetUIStyleNumberProperty( UIStyleNumberProperty.Width, value );
}
}
bool _dragging = false;
bool _updatingPosition = false;
UIDragging.UIDraggingCallbacks leftMouseCallback;
void AddDraggingListener()
{
leftMouseCallback = UIDragging.OnLeftMouseButton( button,
( ev )=>
{
if ( ev.isStart )
{
cachedButtonPosition = button.Position;
smoothing.SetCurrent( cachedButtonPosition );
_dragging = true;
_updatingPosition = true;
ev.ui.onProcess.AddAction( UpdatePosition );
( button as UIStylePropertyContainer ).AddUISelectorFlag( UISelectorFlag.Scrolling, scrollID );
}
else if ( ev.isEnd )
{
_dragging = false;
}
var nextPosition = cachedButtonPosition + ev.distanceToStart;
nextValue = nextPosition.Clamp( Vector2.Zero, GetButtonScrollRange() );
}
);
UIDragging.OnMiddleMouseButton( scrollContainer,
( ev )=>
{
if ( ev.isStart )
{
cachedButtonPosition = button.Position;
smoothing.SetCurrent( cachedButtonPosition );
_dragging = true;
_updatingPosition = true;
ev.ui.onProcess.AddAction( UpdatePosition );
( button as UIStylePropertyContainer ).AddUISelectorFlag( UISelectorFlag.Scrolling, scrollID );
ev.customOffset = Vector2.Zero;
}
else if ( ev.isEnd )
{
_dragging = false;
}
ev.customOffset += ev.distanceToStart * 0.1f;
var nextPosition = cachedButtonPosition + ev.customOffset;
nextValue = nextPosition.Clamp( Vector2.Zero, GetButtonScrollRange() );
ev.customOffset = nextValue - cachedButtonPosition;
}
);
}
Vector2 cachedOffset = Vector2.Zero;
void UpdatePosition( float delta )
{
var value = Smoothing.Apply( smoothing, nextValue, delta );
var uiStyleContainer = ( UIStylePropertyContainer ) button;
if ( ! _dragging && ( value - nextValue ).Length() < 1 )
{
var ui = this.FindParentThatIs<UI>();
ui.onProcess.RemoveAction( UpdatePosition );
_updatingPosition = false;
// this.LogInfo( "Removed Processing" );
value = nextValue;
uiStyleContainer.RemoveUISelectorFlag( UISelectorFlag.Scrolling, scrollID );
}
if ( Direction.Both == direction || Direction.Horizontal == direction )
{
var left = new UINumber();
left.value = value.X;
uiStyleContainer.SetUIStyleNumberProperty( UIStyleNumberProperty.Left, left );
}
if ( Direction.Both == direction || Direction.Vertical == direction )
{
var top = new UINumber();
top.value = value.Y;
uiStyleContainer.SetUIStyleNumberProperty( UIStyleNumberProperty.Top, top );
}
var range = background.Size - button.Size;
sliderValue = button.Position / range;
if ( scrollTarget != null && scrollContainer != null )
{
var scrollRange = scrollTarget.Size - scrollContainer.Size;
var scrollOffset = scrollRange * sliderValue;
if ( Direction.Both == direction || Direction.Horizontal == direction )
{
var left = new UINumber();
left.value = -scrollOffset.X;
( scrollTarget as UIStylePropertyContainer ).SetUIStyleNumberProperty( UIStyleNumberProperty.Left, left );
}
if ( Direction.Both == direction || Direction.Vertical == direction )
{
var top = new UINumber();
top.value = -scrollOffset.Y;
( scrollTarget as UIStylePropertyContainer ).SetUIStyleNumberProperty( UIStyleNumberProperty.Top, top );
}
}
}
Vector2 nextValue;
Vector2 GetButtonScrollRange()
{
return ( background.Size - button.Size ).Max( Vector2.Zero );
}
Vector2 GetScrollRange()
{
return ( scrollTarget.Size - scrollContainer.Size ).Max( Vector2.Zero );
}
void SyncScroll()
{
if ( _dragging || _updatingPosition )
{
// this.LogInfo( "SyncScroll blocked" );
return;
}
// this.LogInfo( "SyncScroll" );
var uiStyleContainer = ( UIStylePropertyContainer ) button;
var value = GetButtonScrollRange() * sliderValue;
if ( Direction.Both == direction || Direction.Horizontal == direction )
{
var left = new UINumber();
left.value = value.X;
uiStyleContainer.SetUIStyleNumberProperty( UIStyleNumberProperty.Left, left );
}
if ( Direction.Both == direction || Direction.Vertical == direction )
{
var top = new UINumber();
top.value = value.Y;
uiStyleContainer.SetUIStyleNumberProperty( UIStyleNumberProperty.Top, top );
}
if ( scrollTarget != null && scrollContainer != null )
{
var scrollRange = scrollTarget.Size - scrollContainer.Size;
var scrollOffset = scrollRange * sliderValue;
if ( Direction.Both == direction || Direction.Horizontal == direction )
{
var left = new UINumber();
left.value = -scrollOffset.X;
( scrollTarget as UIStylePropertyContainer ).SetUIStyleNumberProperty( UIStyleNumberProperty.Left, left );
}
if ( Direction.Both == direction || Direction.Vertical == direction )
{
var top = new UINumber();
top.value = -scrollOffset.Y;
( scrollTarget as UIStylePropertyContainer ).SetUIStyleNumberProperty( UIStyleNumberProperty.Top, top );
}
}
}
}
}

View File

@ -0,0 +1 @@
uid://btwjt483gljv7

View File

@ -80,12 +80,12 @@ namespace Rokojori
}
else
{
maxWidth = UINumber.Compute( region, UIStyleNumberProperty.Width );
maxWidth = UINumber.Compute( region, UIStyleNumberProperty.Width, 0 );
}
if ( ! UINumber.IsNullOrNone( UIStyle.GetUINumberProperty( region, UIStyleNumberProperty.Height ) ) )
if ( ! UINumber.IsNullOrNone( UIStyle.GetUINumberProperty( region, UIStyleNumberProperty.Height, "", region ) ) )
{
maxHeight = UINumber.Compute( region, UIStyleNumberProperty.Height );
maxHeight = UINumber.Compute( region, UIStyleNumberProperty.Height, 0 );
maxVerticalPlacementOffset = maxHeight - maxLineY;
}

View File

@ -1,4 +1,5 @@
using System.Linq;
using Godot;
using Rokojori;
@ -71,35 +72,52 @@ namespace Rokojori
if ( uiImage.Material != null )
{
var ui = Unique<UI>.Get();
var ui = uiImage.GetUI();
if ( ui == null )
{
ui = NodesWalker.Get().GetInParents( control, n => n is UI ) as UI;
}
if ( ui == null )
{
RJLog.Log( "No UI Found" );
RJLog.Log( "No UI Found", HierarchyName.Of( uiImage ) );
return;
}
if ( ui.settings == null )
{
// RJLog.Log( "No UI.settings Found" );
RJLog.Log( "No UI settings Found", HierarchyName.Of( uiImage ) );
return;
}
if ( ui.settings.sizePropertyName == null )
{
RJLog.Log( "No UI.settings.sizePropertyName Found" );
// RJLog.Log( "No UI.settings.sizePropertyName Found" );
return;
}
//RJLog.Log( "Setting Size", ui.settings.sizePropertyName.propertyName, HierarchyName.Of( uiImage ) );
ui.settings.sizePropertyName.Set( uiImage.Material, uiImage.Size );
UIShaderProperties.UpdateProperties( uiImage, uiImage.Material );
// UIShaderProperties.UpdatePropertiesInHierarchy( uiImage, uiImage.Material );
var colorProperties = uiImage.imageType != null ? uiImage.imageType.GetColorShaderProperties() : [];
var colorPropertyName = new ColorPropertyName();
foreach ( var c in colorProperties )
{
// uiImage.LogInfo( c );
var color = UIColor.Compute( control, UIStyleColorProperty.ColorShaderProperty, c, Colors.White );
colorPropertyName.propertyName = c;
colorPropertyName.Set( uiImage.Material, color );
}
var numberProperties = uiImage.imageType != null ? uiImage.imageType.GetNumberShaderProperties() : [];
var numberPropertyName = new FloatPropertyName();
foreach ( var n in numberProperties )
{
// uiImage.LogInfo( c );
var value = UINumber.Compute( control, UIStyleNumberProperty.FloatShaderProperty, n );
numberPropertyName.propertyName = n;
numberPropertyName.Set( uiImage.Material, value );
}
return;
}
@ -111,22 +129,23 @@ namespace Rokojori
var container = (UIStylePropertyContainer) control;
text.uiTextLabelSettings.FontSize =
UINumber.ComputeInt( control, UIStyleNumberProperty.FontSize, UINumber.em(), UINumber.em() / 100f );
text.uiTextLabelSettings.FontSize = Mathf.Max( 1,
UINumber.ComputeInt( control, UIStyleNumberProperty.FontSize, UINumber.em( control ), UINumber.em( control ) / 100f ) );
text.uiTextLabelSettings.FontColor =
UIColor.Compute( control, UIStyleColorProperty.FontColor, Colors.White );
UIColor.Compute( control, UIStyleColorProperty.FontColor, "", Colors.White );
text.uiTextLabelSettings.OutlineSize =
UINumber.ComputeInt( control, UIStyleNumberProperty.FontOutlineSize, 0 );
text.uiTextLabelSettings.OutlineColor =
UIColor.Compute( control, UIStyleColorProperty.FontOutlineColor, Colors.Transparent );
UIColor.Compute( control, UIStyleColorProperty.FontOutlineColor, "", Colors.Transparent );
text.uiTextLabelSettings.ShadowSize =
UINumber.ComputeInt( control, UIStyleNumberProperty.FontShadowSize, 0 );
text.uiTextLabelSettings.ShadowColor =
UIColor.Compute( control, UIStyleColorProperty.FontShadowColor, Colors.Black );
UIColor.Compute( control, UIStyleColorProperty.FontShadowColor, "", Colors.Black );
text.uiTextLabelSettings.ShadowOffset = new Vector2(
UINumber.Compute( control, UIStyleNumberProperty.FontShadowOffsetX, 0 ),
@ -138,6 +157,17 @@ namespace Rokojori
if ( text.alwaysMinimumSize )
{
if ( text.AutowrapMode == TextServer.AutowrapMode.Word )
{
text.AutowrapMode = TextServer.AutowrapMode.Off;
var minSize = text.GetMinimumSize();
text.AutowrapMode = TextServer.AutowrapMode.Word;
var w = UINumber.Compute( control, UIStyleNumberProperty.Width, minSize.X, minSize.X / 100f );
var h = UINumber.Compute( control, UIStyleNumberProperty.Height, minSize.Y, minSize.Y / 100f );
control.CustomMinimumSize = new Vector2( Mathf.Min( minSize.X, w ), 0 );
}
control.Size = control.GetMinimumSize();
}

View File

@ -0,0 +1,21 @@
using Godot;
using Rokojori;
using System.Collections.Generic;
namespace Rokojori
{
public interface UIHolderControl
{
public void SetUI( UI ui);
public UI GetUI();
}
public class UIHolder
{
public static UI GetUI( Control c )
{
return c is UIHolderControl ? ( (UIHolderControl)c ).GetUI() : c.FindParentThatIs<UI>();
}
}
}

View File

@ -0,0 +1 @@
uid://c3626fy08o6w2

View File

@ -0,0 +1,12 @@
using Godot;
using Rokojori;
using System.Collections.Generic;
namespace Rokojori
{
public interface UIHoverable
{
public void SetUnhovered();
}
}

View File

@ -0,0 +1 @@
uid://cu4uhwhrfyct2

View File

@ -2,16 +2,14 @@
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 UIImage:TextureRect, UIStylePropertyContainer
public partial class UIImage:TextureRect, UIStylePropertyContainer, UIHolderControl, IAssemblyReload
{
[Export]
public bool freezeImageType = false;
UIImageType _imageType;
[Export]
public UIImageType imageType
@ -19,11 +17,6 @@ namespace Rokojori
get => _imageType;
set
{
if ( freezeImageType )
{
return;
}
if ( _imageType != value )
{
if ( _imageType != null )
@ -38,16 +31,72 @@ namespace Rokojori
}
}
UI ui;
public void SetUI( UI ui )
{
this.ui = ui;
}
public UI GetUI()
{
var ui = this.ui != null ? this.ui : Unique<UI>.Get();
if ( ui == null )
{
ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
this.LogInfo( "No UI in parents >", ui );
return null;
}
}
return ui;
}
void UpdateImageType()
{
ResetImageType();
if ( _imageType != null )
{
this.LogInfo( "Assigning Image Type:", _imageType );
_imageType.Assign( this );
}
}
string hoverID = IDGenerator.GenerateID();
public override void _Ready()
{
MouseEntered += ()=>
{
AddUISelectorFlag( UISelectorFlag.Hover, hoverID );
};
MouseExited += ()=>
{
RemoveUISelectorFlag( UISelectorFlag.Hover, hoverID );
};
UpdateImageType();
}
public override void _EnterTree()
{
UpdateImageType();
}
public void OnAssemblyReloaded()
{
UpdateImageType();
}
void ResetImageType()
{
ExpandMode = TextureRect.ExpandModeEnum.IgnoreSize;
@ -55,6 +104,52 @@ namespace Rokojori
Material = null;
}
protected override void Dispose( bool disposing)
{
_selectorFlagReferenceCounter.Clear();
}
MapList<UISelectorFlag,string> _selectorFlagReferenceCounter = new MapList<UISelectorFlag, string>();
public void AddUISelectorFlag( UISelectorFlag flag, string reference = "" )
{
SetSelectorFlagReference( flag, reference, true );
}
public void RemoveUISelectorFlag( UISelectorFlag flag, string reference = "" )
{
SetSelectorFlagReference( flag, reference, false );
}
void SetSelectorFlagReference( UISelectorFlag flag, string reference, bool enable )
{
if ( enable )
{
_selectorFlagReferenceCounter.AddIfNotPresent( flag, reference );
}
else
{
_selectorFlagReferenceCounter.Remove( flag );
}
_selectorFlags = _selectorFlagReferenceCounter.Keys.ToList();
UISelector.UpdateParentUISelectorFlags( this );
}
List<UISelectorFlag> _selectorFlags = [];
List<UISelectorFlag> _parentSelectorFlags = [];
public List<UISelectorFlag> GetUISelectorFlags()
{
return _selectorFlags;
}
public List<UISelectorFlag> GetParentUISelectorFlags()
{
return _parentSelectorFlags;
}
public void CopyNumberShaderPropertyFrom( CustomMaterialProperty<float> name, UINumber number, TransitionSettings transition )
{
SetNumberShaderProperty( name.GetPropertyName<FloatPropertyName>(), number, transition );
@ -94,7 +189,6 @@ namespace Rokojori
}
shaderUINumber.number = number;
shaderUINumber.transitionSettings = transition;
}
public void CopyColorShaderPropertyFrom( CustomMaterialProperty<Color> name, UIColor color )
@ -118,7 +212,6 @@ namespace Rokojori
}
}
if ( color == null )
{
var index = Arrays.FindIndex( colorProperties, p => p != null && p.colorPropertyName.propertyName == name.propertyName );
@ -126,10 +219,6 @@ namespace Rokojori
return;
}
var shaderUIColor = Arrays.Find( colorProperties, p => p != null && p.colorPropertyName.propertyName == name.propertyName );
if ( shaderUIColor == null )
@ -201,19 +290,19 @@ namespace Rokojori
[ExportGroup( "Shader Properties" )]
[Export]
public ShaderUIColor[] colorProperties = new ShaderUIColor[ 0 ];
public List<ActiveStyleTransition<UIColor,ColorPropertyName>> activeShaderColorTransitions = new List<ActiveStyleTransition<UIColor,ColorPropertyName>>();
public List<ActiveStyleTransition<UIColor,ColorPropertyName>> GetActiveShaderUIColorTransitions()
{
return activeShaderColorTransitions;
}
// public List<ActiveStyleTransition<UIColor,ColorPropertyName>> activeShaderColorTransitions = new List<ActiveStyleTransition<UIColor,ColorPropertyName>>();
// public List<ActiveStyleTransition<UIColor,ColorPropertyName>> GetActiveShaderUIColorTransitions()
// {
// return activeShaderColorTransitions;
// }
[Export]
public ShaderUINumber[] numberProperties = new ShaderUINumber[ 0 ];
public List<ActiveStyleTransition<UINumber,FloatPropertyName>> activeShaderNumberTransitions = new List<ActiveStyleTransition<UINumber,FloatPropertyName>>();
public List<ActiveStyleTransition<UINumber,FloatPropertyName>> GetActiveShaderUINumberTransitions()
{
return activeShaderNumberTransitions;
}
// public List<ActiveStyleTransition<UINumber,FloatPropertyName>> activeShaderNumberTransitions = new List<ActiveStyleTransition<UINumber,FloatPropertyName>>();
// public List<ActiveStyleTransition<UINumber,FloatPropertyName>> GetActiveShaderUINumberTransitions()
// {
// return activeShaderNumberTransitions;
// }
[ExportGroup("Transitions")]
[Export]
@ -230,8 +319,8 @@ namespace Rokojori
return numberTransitions;
}
public List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>> activeNumberTransitions = new List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>>();
public List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>> GetActiveUINumberTransitions()
public List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>> activeNumberTransitions = new List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>>();
public List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>> GetActiveUINumberTransitions()
{
return activeNumberTransitions;
}
@ -243,8 +332,8 @@ namespace Rokojori
return colorTransitions;
}
public List<ActiveStyleTransition<UIColor,UIStyleColorProperty>> activeColorTransitions = new List<ActiveStyleTransition<UIColor,UIStyleColorProperty>>();
public List<ActiveStyleTransition<UIColor,UIStyleColorProperty>> GetActiveUIColorTransitions()
public List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>> activeColorTransitions = new List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>>();
public List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>> GetActiveUIColorTransitions()
{
return activeColorTransitions;
}
@ -282,8 +371,9 @@ namespace Rokojori
return numberProperties;
}
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
switch ( property )
{
case UIStyleNumberProperty.Width: return width;
@ -311,12 +401,72 @@ namespace Rokojori
case UIStyleNumberProperty.ScaleY: return scaleY;
}
if ( UIStyleNumberProperty.FloatShaderProperty == property )
{
var numberProperty = numberProperties.Find( n => n.floatPropertyName.propertyName == shaderPropertyName );
if ( numberProperty != null )
{
return numberProperty.number;
}
}
return null;
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property )
public void SetUIStyleNumberProperty( UIStyleNumberProperty property, UINumber number )
{
return null;
switch ( property )
{
case UIStyleNumberProperty.Left: { left = number; } break;
case UIStyleNumberProperty.Right: { right = number; } break;
case UIStyleNumberProperty.Top: { top = number; } break;
case UIStyleNumberProperty.Bottom: { bottom = number; } break;
case UIStyleNumberProperty.Width: { width = number; } break;
case UIStyleNumberProperty.Height: { height = number; } break;
case UIStyleNumberProperty.Margin: { margin = number; } break;
case UIStyleNumberProperty.MarginLeft: { marginLeft = number; } break;
case UIStyleNumberProperty.MarginRight: { marginRight = number; } break;
case UIStyleNumberProperty.MarginTop: { marginTop = number; } break;
case UIStyleNumberProperty.MarginBottom: { marginBottom = number; } break;
case UIStyleNumberProperty.PivotX: { pivotX = number; } break;
case UIStyleNumberProperty.PivotY: { pivotY = number; } break;
case UIStyleNumberProperty.Rotation: { rotation = number; } break;
case UIStyleNumberProperty.Scale: { scale = number; } break;
case UIStyleNumberProperty.ScaleX: { scaleX = number; } break;
case UIStyleNumberProperty.ScaleY: { scaleY = number; } break;
}
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
if ( property != UIStyleColorProperty.ColorShaderProperty )
{
return null;
}
if ( imageType != null )
{
var uiColor = imageType.GetUIStyleColorProperty( property, shaderPropertyName );
if ( uiColor != null )
{
return uiColor;
}
}
var shaderUIColor = colorProperties.Find( c => c.colorPropertyName.propertyName == shaderPropertyName );
return shaderUIColor != null ? shaderUIColor.color : null;
}
public Font GetFont()

View File

@ -11,6 +11,27 @@ namespace Rokojori
{
Dictionary<UIImage,RoundedRectangleMaterial> _materials = new Dictionary<UIImage, RoundedRectangleMaterial>();
static readonly string[] colorProperties = [
RoundedRectangleShader.fillColor.propertyName,
RoundedRectangleShader.strokeColor.propertyName
];
public override string[] GetColorShaderProperties()
{
return colorProperties;
}
static readonly string[] numberProperties = [
RoundedRectangleShader.borderRadius.propertyName,
RoundedRectangleShader.strokeSize.propertyName,
RoundedRectangleShader.offset.propertyName
];
public override string[] GetNumberShaderProperties()
{
return numberProperties;
}
UIColor _fillColor;
[Export]
public UIColor fillColor
@ -35,13 +56,13 @@ namespace Rokojori
set { _borderRadius = value; onChange.DispatchEvent( null ); }
}
TransitionSettings _borderRadiusTransition;
[Export]
public TransitionSettings borderRadiusTransition
{
get => _borderRadiusTransition;
set { _borderRadiusTransition = value; onChange.DispatchEvent( null ); }
}
// TransitionSettings _borderRadiusTransition;
// [Export]
// public TransitionSettings borderRadiusTransition
// {
// get => _borderRadiusTransition;
// set { _borderRadiusTransition = value; onChange.DispatchEvent( null ); }
// }
UINumber _strokeSize;
[Export]
@ -51,13 +72,13 @@ namespace Rokojori
set { _strokeSize = value; onChange.DispatchEvent( null ); }
}
TransitionSettings _strokeSizeTransition;
[Export]
public TransitionSettings strokeSizeTransition
{
get => _strokeSizeTransition;
set { _strokeSizeTransition = value; onChange.DispatchEvent( null ); }
}
// TransitionSettings _strokeSizeTransition;
// [Export]
// public TransitionSettings strokeSizeTransition
// {
// get => _strokeSizeTransition;
// set { _strokeSizeTransition = value; onChange.DispatchEvent( null ); }
// }
UINumber _offset;
[Export]
@ -67,18 +88,38 @@ namespace Rokojori
set { _offset = value; onChange.DispatchEvent( null ); }
}
TransitionSettings _offsetTransition;
[Export]
public TransitionSettings offsetTransition
// TransitionSettings _offsetTransition;
// [Export]
// public TransitionSettings offsetTransition
// {
// get => _offsetTransition;
// set { _offsetTransition = value; onChange.DispatchEvent( null ); }
// }
public override UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName )
{
get => _offsetTransition;
set { _offsetTransition = value; onChange.DispatchEvent( null ); }
if ( RoundedRectangleShader.fillColor.propertyName == shaderPropertyName )
{
return fillColor;
}
if ( RoundedRectangleShader.strokeColor.propertyName == shaderPropertyName )
{
return strokeColor;
}
return null;
}
protected override void _Assign( UIImage image )
{
if ( _materials.ContainsKey( image ) )
{
if ( image.Material == null )
{
image.Material = _materials[ image ];
}
return;
}
@ -101,18 +142,21 @@ namespace Rokojori
protected override void _ApplyChange( UIImage image )
{
var material = _materials[ image ];
image.CopyColorShaderPropertyFrom( material.fillColor, _fillColor );
image.CopyColorShaderPropertyFrom( material.strokeColor, _strokeColor );
// AssignColor( image, material.fillColor, _fillColor );
// // image.CopyColorShaderPropertyFrom( material.fillColor, GetUIColor( _fillColor, image, material.fillColor.propertyName ) );
// AssignColor( image, material.strokeColor, _strokeColor );
image.CopyNumberShaderPropertyFrom( material.borderRadius, _borderRadius, _borderRadiusTransition );
image.CopyNumberShaderPropertyFrom( material.strokeSize, _strokeSize, _strokeSizeTransition );
image.CopyNumberShaderPropertyFrom( material.offset, _offset, _offsetTransition );
// image.CopyNumberShaderPropertyFrom( material.borderRadius, _borderRadius, _borderRadiusTransition );
// image.CopyNumberShaderPropertyFrom( material.strokeSize, _strokeSize, _strokeSizeTransition );
// image.CopyNumberShaderPropertyFrom( material.offset, _offset, _offsetTransition );
}
}
}

View File

@ -2,6 +2,7 @@
using Godot;
using Rokojori;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
@ -12,6 +13,7 @@ namespace Rokojori
public readonly EventSlot<Null> onChange = new EventSlot<Null>();
List<UIImage> _images = new List<UIImage>();
public UIImageType()
{
onChange.AddAction( a => ApplyChanges() );
@ -35,6 +37,11 @@ namespace Rokojori
_images.ForEach( i => _ApplyChange( i ) );
}
public virtual UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName )
{
return null;
}
protected virtual void _ApplyChange( UIImage image )
{
@ -50,5 +57,40 @@ namespace Rokojori
}
public virtual string[] GetColorShaderProperties()
{
return [];
}
public virtual string[] GetNumberShaderProperties()
{
return [];
}
protected UIColor GetUIColor( UIColor member, UIImage parent, string name )
{
if ( member != null )
{
return member;
}
var style = parent.parentStyle;
if ( style == null )
{
return null;
}
var colorProperty = style.colorProperties.Find( c => c.colorPropertyName.propertyName == name );
return colorProperty == null ? null : colorProperty.color;
}
protected void AssignColor( UIImage image, CustomMaterialProperty<Color> colorProperty, UIColor memberColor )
{
image.CopyColorShaderPropertyFrom( colorProperty, GetUIColor( memberColor, image, colorProperty.propertyName ) );
}
}
}

View File

@ -92,9 +92,17 @@ namespace Rokojori
}
UI ui;
public void SetUI( UI ui )
{
this.ui = ui;
}
InputIconsLibrary GetInputIconsLibrary()
{
var ui = Unique<UI>.Get();
var ui = this.ui != null ? this.ui : Unique<UI>.Get();
if ( ui == null )
{
@ -108,7 +116,7 @@ namespace Rokojori
}
}
var lib = ui.inputIconsLibrary;
var lib = ui.settings.inputIconsLibrary;
return lib;
}

View File

@ -1,12 +1,13 @@
using Godot;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIRegion.svg")]
public partial class UIRegion : Control, UIStylePropertyContainer
public partial class UIRegion : Control, UIStylePropertyContainer, UIHolderControl
{
[Export]
public UIStyle parentStyle;
@ -85,15 +86,15 @@ namespace Rokojori
[Export]
public UINumber shadowOffsetY;
public List<ActiveStyleTransition<UIColor,ColorPropertyName>> GetActiveShaderUIColorTransitions()
{
return null;
}
// public List<ActiveStyleTransition<UIColor,ColorPropertyName>> GetActiveShaderUIColorTransitions()
// {
// return null;
// }
public List<ActiveStyleTransition<UINumber,FloatPropertyName>> GetActiveShaderUINumberTransitions()
{
return null;
}
// public List<ActiveStyleTransition<UINumber,FloatPropertyName>> GetActiveShaderUINumberTransitions()
// {
// return null;
// }
[ExportGroup("Transitions")]
[Export]
@ -110,8 +111,8 @@ namespace Rokojori
return numberTransitions;
}
public List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>> activeNumberTransitions = new List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>>();
public List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>> GetActiveUINumberTransitions()
public List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>> activeNumberTransitions = new List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>>();
public List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>> GetActiveUINumberTransitions()
{
return activeNumberTransitions;
}
@ -123,12 +124,29 @@ namespace Rokojori
return colorTransitions;
}
public List<ActiveStyleTransition<UIColor,UIStyleColorProperty>> activeColorTransitions = new List<ActiveStyleTransition<UIColor,UIStyleColorProperty>>();
public List<ActiveStyleTransition<UIColor,UIStyleColorProperty>> GetActiveUIColorTransitions()
public List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>> activeColorTransitions = new List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>>();
public List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>> GetActiveUIColorTransitions()
{
return activeColorTransitions;
}
#if TOOLS
[ExportGroup("Editor SceneSetup")]
[Export]
public UISettings uiSettings;
[Export]
public float fontZoom = 1f;
[Export]
public bool updateInEditor;
[Export]
public bool reassignUI;
[ExportGroup("Editor SceneSetup/Read Only")]
[Export]
public float computedFontSize = 0f;
#endif
public UIStyle GetUIStyleParent()
{
return parentStyle;
@ -169,7 +187,7 @@ namespace Rokojori
return GetSize();
}
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
switch ( property )
{
@ -205,7 +223,42 @@ namespace Rokojori
return null;
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property )
public void SetUIStyleNumberProperty( UIStyleNumberProperty property, UINumber number )
{
switch ( property )
{
case UIStyleNumberProperty.Left: { left = number; } break;
case UIStyleNumberProperty.Right: { right = number; } break;
case UIStyleNumberProperty.Top: { top = number; } break;
case UIStyleNumberProperty.Bottom: { bottom = number; } break;
case UIStyleNumberProperty.HorizontalAlignment: { horizontalAlignment = number; } break;
case UIStyleNumberProperty.VerticalAlignment: { verticalAlignment = number; } break;
case UIStyleNumberProperty.VerticalPlacement: { verticalPlacement = number; } break;
case UIStyleNumberProperty.ElementSpacing: { elementSpacing = number; } break;
case UIStyleNumberProperty.LineSpacing: { lineSpacing = number; } break;
case UIStyleNumberProperty.Width: { width = number; } break;
case UIStyleNumberProperty.Height: { height = number; } break;
case UIStyleNumberProperty.Margin: { margin = number; } break;
case UIStyleNumberProperty.MarginLeft: { marginLeft = number; } break;
case UIStyleNumberProperty.MarginRight: { marginRight = number; } break;
case UIStyleNumberProperty.MarginTop: { marginTop = number; } break;
case UIStyleNumberProperty.MarginBottom: { marginBottom = number; } break;
case UIStyleNumberProperty.FontSize: { fontSize = number; } break;
case UIStyleNumberProperty.FontOutlineSize: { outlineSize = number; } break;
case UIStyleNumberProperty.FontShadowSize: { shadowSize = number; } break;
case UIStyleNumberProperty.FontShadowOffsetX: { shadowOffsetX = number; } break;
case UIStyleNumberProperty.FontShadowOffsetY: { shadowOffsetY = number; } break;
}
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
switch ( property )
{
@ -217,7 +270,69 @@ namespace Rokojori
return null;
}
public void Layout()
string hoverID = IDGenerator.GenerateID();
public override void _Ready()
{
MouseEntered += ()=>
{
AddUISelectorFlag( UISelectorFlag.Hover, hoverID );
};
MouseExited += ()=>
{
RemoveUISelectorFlag( UISelectorFlag.Hover, hoverID );
};
}
MapList<UISelectorFlag,string> _selectorFlagReferenceCounter = new MapList<UISelectorFlag, string>();
public void AddUISelectorFlag( UISelectorFlag flag, string reference = "" )
{
SetSelectorFlagReference( flag, reference, true );
}
public void RemoveUISelectorFlag( UISelectorFlag flag, string reference = "" )
{
SetSelectorFlagReference( flag, reference, false );
}
protected override void Dispose( bool disposing)
{
_selectorFlagReferenceCounter.Clear();
}
void SetSelectorFlagReference( UISelectorFlag flag, string reference, bool enable )
{
if ( enable )
{
_selectorFlagReferenceCounter.AddIfNotPresent( flag, reference );
}
else
{
_selectorFlagReferenceCounter.Remove( flag );
}
_selectorFlags = _selectorFlagReferenceCounter.Keys.ToList();
UISelector.UpdateParentUISelectorFlags( this );
}
List<UISelectorFlag> _selectorFlags = [];
List<UISelectorFlag> _parentSelectorFlags = [];
public List<UISelectorFlag> GetUISelectorFlags()
{
return _selectorFlags;
}
public List<UISelectorFlag> GetParentUISelectorFlags()
{
return _parentSelectorFlags;
}
public virtual void Layout()
{
var layout = UIStyle.Layout( this );
@ -235,6 +350,31 @@ namespace Rokojori
public Vector2 contentSize = Vector2.Zero;
public Vector2 contentOffset = Vector2.Zero;
UI ui;
public void SetUI( UI ui )
{
this.ui = ui;
}
public UI GetUI()
{
var ui = this.ui != null ? this.ui : Unique<UI>.Get();
if ( ui == null )
{
ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
this.LogInfo( "No UI in parents >", ui );
return null;
}
}
return ui;
}
}
}

View File

@ -2,12 +2,13 @@
using Godot;
using Rokojori;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIText.svg")]
public partial class UIText:Label,UIStylePropertyContainer, iLocalizable
public partial class UIText:Label,UIStylePropertyContainer, iLocalizable, UIHolderControl, IAssemblyReload
{
LocalizedString _locale;
@ -41,6 +42,12 @@ namespace Rokojori
}
public void OnAssemblyReloaded()
{
UpdateLocalization();
UpdateFont();
}
[Export]
public bool alwaysMinimumSize = true;
@ -152,16 +159,111 @@ namespace Rokojori
}
public List<ActiveStyleTransition<UIColor,ColorPropertyName>> GetActiveShaderUIColorTransitions()
string hoverID = IDGenerator.GenerateID();
public override void _Ready()
{
return null;
MouseEntered += ()=>
{
AddUISelectorFlag( UISelectorFlag.Hover, hoverID );
};
MouseExited += ()=>
{
RemoveUISelectorFlag( UISelectorFlag.Hover, hoverID );
};
}
public List<ActiveStyleTransition<UINumber,FloatPropertyName>> GetActiveShaderUINumberTransitions()
protected override void Dispose( bool disposing)
{
return null;
_selectorFlagReferenceCounter.Clear();
}
MapList<UISelectorFlag,string> _selectorFlagReferenceCounter = new MapList<UISelectorFlag, string>();
public void AddUISelectorFlag( UISelectorFlag flag, string reference = "" )
{
SetSelectorFlagReference( flag, reference, true );
}
public void RemoveUISelectorFlag( UISelectorFlag flag, string reference = "" )
{
SetSelectorFlagReference( flag, reference, false );
}
void SetSelectorFlagReference( UISelectorFlag flag, string reference, bool enable )
{
if ( enable )
{
_selectorFlagReferenceCounter.AddIfNotPresent( flag, reference );
}
else
{
_selectorFlagReferenceCounter.Remove( flag );
}
_selectorFlags = _selectorFlagReferenceCounter.Keys.ToList();
UISelector.UpdateParentUISelectorFlags( this );
}
List<UISelectorFlag> _selectorFlags = [];
List<UISelectorFlag> _parentSelectorFlags = [];
public List<UISelectorFlag> GetUISelectorFlags()
{
return _selectorFlags;
}
public List<UISelectorFlag> GetParentUISelectorFlags()
{
return _parentSelectorFlags;
}
public override void _GuiInput( InputEvent inputEvent )
{
if ( ! handleMouseEvents )
{
return;
}
if ( inputEvent is InputEventMouseButton mb )
{
if ( mb.Pressed )
{
if ( mb.ButtonIndex == MouseButton.Left )
{
Action.Trigger( onLeftClick );
}
if ( mb.ButtonIndex == MouseButton.Middle )
{
Action.Trigger( onMiddleClick );
}
if ( mb.ButtonIndex == MouseButton.Right )
{
Action.Trigger( onRightClick );
}
}
}
}
// public List<ActiveStyleTransition<UIColor,ColorPropertyName>> GetActiveShaderUIColorTransitions()
// {
// return null;
// }
// public List<ActiveStyleTransition<UINumber,FloatPropertyName>> GetActiveShaderUINumberTransitions()
// {
// return null;
// }
[ExportGroup("Transitions")]
[Export]
public TransitionSettingsAll transitionSettings;
@ -177,8 +279,8 @@ namespace Rokojori
return numberTransitions;
}
public List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>> activeNumberTransitions = new List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>>();
public List<ActiveStyleTransition<UINumber,UIStyleNumberProperty>> GetActiveUINumberTransitions()
public List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>> activeNumberTransitions = new List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>>();
public List<ActiveStyleTransition<UINumber,UIStyleNumberPropertyAndName>> GetActiveUINumberTransitions()
{
return activeNumberTransitions;
}
@ -190,8 +292,8 @@ namespace Rokojori
return colorTransitions;
}
public List<ActiveStyleTransition<UIColor,UIStyleColorProperty>> activeColorTransitions = new List<ActiveStyleTransition<UIColor,UIStyleColorProperty>>();
public List<ActiveStyleTransition<UIColor,UIStyleColorProperty>> GetActiveUIColorTransitions()
public List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>> activeColorTransitions = new List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>>();
public List<ActiveStyleTransition<UIColor,UIStyleColorPropertyAndName>> GetActiveUIColorTransitions()
{
return activeColorTransitions;
}
@ -220,6 +322,19 @@ namespace Rokojori
}
}
[ExportGroup("Events")]
[Export]
public bool handleMouseEvents = false;
[Export]
public Action onLeftClick;
[Export]
public Action onMiddleClick;
[Export]
public Action onRightClick;
public UIStyle GetUIStyleParent()
{
return parentStyle;
@ -252,7 +367,7 @@ namespace Rokojori
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
switch ( property )
{
@ -287,15 +402,53 @@ namespace Rokojori
case UIStyleNumberProperty.FontShadowOffsetY: return shadowOffsetY;
}
return null;
}
public void SetUIStyleNumberProperty( UIStyleNumberProperty property, UINumber number )
{
switch ( property )
{
case UIStyleNumberProperty.Left: { left = number; } break;
case UIStyleNumberProperty.Right: { right = number; } break;
case UIStyleNumberProperty.Top: { top = number; } break;
case UIStyleNumberProperty.Bottom: { bottom = number; } break;
case UIStyleNumberProperty.Width: { width = number; } break;
case UIStyleNumberProperty.Height: { height = number; } break;
case UIStyleNumberProperty.Margin: { margin = number; } break;
case UIStyleNumberProperty.MarginLeft: { marginLeft = number; } break;
case UIStyleNumberProperty.MarginRight: { marginRight = number; } break;
case UIStyleNumberProperty.MarginTop: { marginTop = number; } break;
case UIStyleNumberProperty.MarginBottom: { marginBottom = number; } break;
case UIStyleNumberProperty.FontSize: { fontSize = number; } break;
case UIStyleNumberProperty.FontOutlineSize: { outlineSize = number; } break;
case UIStyleNumberProperty.FontShadowSize: { shadowSize = number; } break;
case UIStyleNumberProperty.FontShadowOffsetX: { shadowOffsetX = number; } break;
case UIStyleNumberProperty.FontShadowOffsetY: { shadowOffsetY = number; } break;
case UIStyleNumberProperty.PivotX: { pivotX = number; } break;
case UIStyleNumberProperty.PivotY: { pivotY = number; } break;
case UIStyleNumberProperty.Rotation: { rotation = number; } break;
case UIStyleNumberProperty.Scale: { scale = number; } break;
case UIStyleNumberProperty.ScaleX: { scaleX = number; } break;
case UIStyleNumberProperty.ScaleY: { scaleY = number; } break;
}
}
public Vector2 GetUISize()
{
return GetSize();
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property )
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
switch ( property )
{
@ -306,5 +459,31 @@ namespace Rokojori
return null;
}
UI ui;
public void SetUI( UI ui )
{
this.ui = ui;
}
public UI GetUI()
{
var ui = this.ui != null ? this.ui : Unique<UI>.Get();
if ( ui == null )
{
ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
// this.LogInfo( "No UI in parents >", HierarchyName.Of( this ) );
return null;
}
}
return ui;
}
}
}

View File

@ -0,0 +1,26 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIRegion.svg")]
public partial class UIWrapper : UIRegion
{
[Export]
public Control wrappedControl;
public override void Layout()
{
base.Layout();
if ( wrappedControl != null )
{
wrappedControl.Size = Size;
wrappedControl.Position = Vector2.Zero;
}
}
}
}

View File

@ -0,0 +1 @@
uid://bq65b10laqpg8

View File

@ -0,0 +1,15 @@
using Godot;
using System;
namespace Rokojori
{
public class RedrawCue
{
public enum CueType
{
Self,
Layout
}
}
}

View File

@ -0,0 +1 @@
uid://dslml1gawhij5

View File

@ -17,6 +17,11 @@ namespace Rokojori
public void UpdateMaterial( UIStylePropertyContainer container, Material material )
{
if ( colorPropertyName == null || color == null )
{
return;
}
var colorValue = UIColor.Compute( container as Control, color, Colors.White );
colorPropertyName.Set( material, colorValue );
}

Some files were not shown because too many files have changed in this diff Show More