UI Sync/Procedural

This commit is contained in:
Josef 2025-06-23 13:16:01 +02:00
parent dab72b46d9
commit 8c8b50b6da
45 changed files with 1705 additions and 405 deletions

View File

@ -13,11 +13,13 @@ namespace Rokojori
[Export]
public Node3D target;
[Export]
public bool global = true;
public override void _Process( double delta )
{
_OnTrigger();
}
// public override void _Process( double delta )
// {
// _OnTrigger();
// }
protected override void _OnTrigger()
@ -27,8 +29,17 @@ namespace Rokojori
return;
}
if ( global )
{
target.GlobalPosition = source.GlobalPosition;
target.GlobalRotation = source.GlobalRotation;
}
else
{
target.Position = source.Position;
target.Rotation = source.Rotation;
}
}
}
}

View File

@ -13,11 +13,14 @@ namespace Rokojori
[Export]
public Node3D target;
[Export]
public bool global = true;
public override void _Process( double delta )
{
_OnTrigger();
}
// public override void _Process( double delta )
// {
// _OnTrigger();
// }
protected override void _OnTrigger()
{
@ -26,7 +29,14 @@ namespace Rokojori
return;
}
if ( global )
{
target.GlobalPosition = source.GlobalPosition;
}
else
{
target.Position = source.Position;
}
}
}
}

View File

@ -0,0 +1,39 @@
using Godot;
namespace Rokojori
{
[GlobalClass, Tool ]
public partial class CopyRotation : Action
{
[Export]
public Node3D source;
[Export]
public Node3D target;
[Export]
public bool global = true;
protected override void _OnTrigger()
{
if ( source == null || target == null )
{
return;
}
if ( global )
{
target.GlobalRotation = source.GlobalRotation;
}
else
{
target.Rotation = source.Rotation;
}
}
}
}

View File

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

View File

@ -354,6 +354,35 @@ namespace Rokojori
return null;
}
public int GetAncestorDistance( N child, N ancestor )
{
if ( ancestor == null )
{
return -1;
}
if ( child == ancestor )
{
return 0;
}
var p = Parent( child );
var distance = 1;
while ( p != null )
{
if ( p == ancestor )
{
return distance;
}
p = Parent( p );
distance ++;
}
return -1;
}
public int GetDepth( N node, Dictionary<N, int> depthMap = null )
{

View File

@ -39,7 +39,7 @@ namespace Rokojori
public override void _Process( double delta )
{
if ( graphics == null || body == null )
if ( Engine.IsEditorHint() || graphics == null || body == null )
{
return;
}

View File

@ -9,6 +9,12 @@ namespace Rokojori
[GlobalClass]
public partial class MultiRayCaster:Caster
{
public enum UpdateMode
{
Process,
Physics_Process
}
[Export]
public float rayLength = 10;
@ -27,6 +33,9 @@ namespace Rokojori
[Export]
public Node collider;
[Export]
public UpdateMode updateMode = UpdateMode.Physics_Process;
public override int NumColliders()
{
return numCollisions;
@ -55,8 +64,35 @@ namespace Rokojori
PhysicsRayQueryParameters3D rayParameters = new PhysicsRayQueryParameters3D();
public override void _PhysicsProcess (double delta )
{
if ( UpdateMode.Physics_Process != updateMode )
{
return;
}
Update( delta );
}
public override void _Process( double delta )
{
if ( UpdateMode.Process != updateMode )
{
return;
}
Update( delta );
}
void Update( double delta )
{
if ( Engine.IsEditorHint() )
{
return;
}
Action.Trigger( beforeProcess );
ResolveCollisions();
@ -72,7 +108,6 @@ namespace Rokojori
}
Action.Trigger( afterProcess );
}
ValueSorter<CollisionData> singleSorter;

View File

@ -29,6 +29,9 @@ namespace Rokojori
[Export]
public Mesh mesh;
[Export]
public GeometryInstance3D.ShadowCastingSetting castShadows = GeometryInstance3D.ShadowCastingSetting.On;
[Export]
public Material materialOveride;
@ -50,10 +53,16 @@ namespace Rokojori
public float multiMeshSplitSize = 25;
[Export]
public Vector3 multiMeshSplitScatterRelative = new Vector3( 2, 0, 2 );
public float cullDistance = 100;
[Export]
public Vector3 multiMeshSplitScatterScale = new Vector3( 10, 10, 10 );
public float cullRange = 50;
[Export]
public Vector3 multiMeshSplitNoiseAmount = new Vector3( 2, 0, 2 );
[Export]
public Vector3 multiMeshSplitNoiseFrequency = new Vector3( 10, 10, 10 );
Dictionary<Vector3I,LODMultiMeshInstance3D> multiMeshMapping = new Dictionary<Vector3I, LODMultiMeshInstance3D>();
@ -160,10 +169,12 @@ namespace Rokojori
var instancesSorted = new MapList<Vector3I,int>();
for ( int i = 0; i < positions.Length; i++ )
{
var floatIndex = ( positions[ i ] / multiMeshSplitSize );
floatIndex += Noise.Perlin3( positions[ i ] * multiMeshSplitScatterScale ) * multiMeshSplitScatterRelative;
floatIndex += Noise.Perlin3( positions[ i ] * multiMeshSplitNoiseFrequency ) * multiMeshSplitNoiseAmount;
var index = floatIndex.RoundToInt();
instancesSorted.Add( index, i );
@ -177,6 +188,10 @@ namespace Rokojori
for ( int i = 0; i < numMultiMeshes; i++ )
{
var multiMeshNode = this.CreateChild<LODMultiMeshInstance3D>();
var center = new Vector3( keys[ i ].X, keys[ i ].Y, keys[ i ].Z ) * multiMeshSplitSize;
multiMeshNode.GlobalPosition = center;
multiMeshNode.cullDistance = cullDistance;
multiMeshNode.cullRange = cullRange;
multiMeshNode.Multimesh = new MultiMesh();
multiMeshNode.Multimesh.TransformFormat = MultiMesh.TransformFormatEnum.Transform3D;
@ -186,6 +201,7 @@ namespace Rokojori
var meshIndices = instancesSorted[ keys[ i ] ];
mm.Mesh = mesh;
multiMeshNode.CastShadow = castShadows;
mm.InstanceCount = meshIndices.Count;
if ( materialOveride != null )
@ -193,12 +209,12 @@ namespace Rokojori
multiMeshNode.MaterialOverride = materialOveride;
}
this.LogInfo( i, ">>", keys[ i ], ">>", meshIndices.Count );
// this.LogInfo( i, ">>", keys[ i ], ">>", meshIndices.Count );
for ( int j = 0; j < meshIndices.Count; j++ )
{
var index = meshIndices[ j ];
var trsf = Math3D.TRS( positions[ index ], rotations[ index ], scales[ index ] );
var trsf = Math3D.TRS( positions[ index ] - center, rotations[ index ], scales[ index ] );
mm.SetInstanceTransform( j, trsf );
}

View File

@ -10,6 +10,7 @@ namespace Rokojori
public class MaterialType
{
public Trillean isStandard = Trillean.Any;
public Shader shader = null;
public BaseMaterial3D.TransparencyEnum transparency;
public BaseMaterial3D.BlendModeEnum blendMode;
public BaseMaterial3D.CullModeEnum cullMode;
@ -25,11 +26,17 @@ namespace Rokojori
public bool Equals( MaterialType materialType )
{
if ( isStandard != materialType.isStandard )
{
return false;
}
if ( Trillean.False == isStandard )
{
return shader == materialType.shader;
}
if ( transparency != materialType.transparency )
{
return false;
@ -161,6 +168,8 @@ namespace Rokojori
{
isStandard = materialType.isStandard;
shader = materialType.shader;
transparency = materialType.transparency;
blendMode = materialType.blendMode;
cullMode = materialType.cullMode;
@ -186,7 +195,33 @@ namespace Rokojori
return From( sm );
}
return null;
return From( material as ShaderMaterial );
}
public static MaterialType From( ShaderMaterial shaderMaterial )
{
var mt = new MaterialType();
mt.isStandard = Trillean.False;
mt.shader = shaderMaterial.Shader;
// public (?:\w+\.)?\w+ (\w+).*?;
// mt.$1 = standardMaterial3D.$1;
// mt.transparency = standardMaterial3D.;
// mt.blendMode = standardMaterial3D.BlendMode;
// mt.cullMode = standardMaterial3D.CullMode;
// mt.depthDrawMode = standardMaterial3D.DepthDrawMode;
// mt.noDepthTest = standardMaterial3D.NoDepthTest;
// mt.shadingMode = standardMaterial3D.ShadingMode;
// mt.diffuseMode = standardMaterial3D.DiffuseMode;
// mt.specularMode = standardMaterial3D.SpecularMode;
// mt.disableAmbientLight = standardMaterial3D.DisableAmbientLight;
// mt.disableFog = standardMaterial3D.DisableFog;
return mt;
}
public static MaterialType From( StandardMaterial3D standardMaterial3D )

View File

@ -34,6 +34,22 @@ namespace Rokojori
[Export]
public Node3D pivot;
public enum SortMode
{
No_Sorting,
Sort_By_Pivot_Distance,
Randomize
}
[Export]
public SortMode sortMode = SortMode.No_Sorting;
[Export]
public bool reverseSortOrder = false;
[Export]
public int randomSortSeed = 1234;
[ExportGroup( "Material")]
[Export]
public bool combineMaterials = true;
@ -72,7 +88,18 @@ namespace Rokojori
{
if ( ! _meshGeometryCache.Has( surface.mesh, surface.index ) )
{
var mg = MeshGeometry.From( surface.mesh as ArrayMesh, null, surface.index );
// var arrayMesh = surface.mesh as ArrayMesh;
// if ( arrayMesh == null )
// {
// arrayMesh = new ArrayMesh();
// var st = new SurfaceTool();
// st.Begin( Mesh.PrimitiveType.Triangles );
// st.CreateFrom( surface.mesh, surface.index );
// st.Commit( arrayMesh );
// }
var mg = MeshGeometry.From( surface.mesh, null, surface.index );
_meshGeometryCache.Set( surface.mesh, surface.index, mg );
this.LogInfo( "Created mesh with triangles:", mg.numTriangles );
@ -132,6 +159,8 @@ namespace Rokojori
{
MeshExtractor.ExtractSurfacesInHierarchy( n, _surfaces );
}
this.LogInfo( "Surfaces found:", _surfaces.Count );
}
async Task GrabMaterials()
@ -369,6 +398,42 @@ namespace Rokojori
var surfaces = _materiaList[ m ];
if ( SortMode.Sort_By_Pivot_Distance == sortMode )
{
var center = pivot == null ? Vector3.Zero : pivot.GlobalPosition;
surfaces.Sort(
( a, b )=>
{
var distanceA = ( a.transform.Origin - center ).LengthSquared();
var distanceB = ( b.transform.Origin - center ).LengthSquared();
return Mathf.Sign( distanceA - distanceB );
}
);
}
if ( SortMode.Randomize == sortMode )
{
var random = LCG.WithSeed( randomSortSeed );
var randomValues = new Dictionary<Transformable<MeshSurface>,float>();
surfaces.ForEach( s => randomValues[ s ] = random.Next() );
surfaces.Sort(
( a, b )=>
{
var distanceA = randomValues[ a ];
var distanceB = randomValues[ b ];
return Mathf.Sign( distanceA - distanceB );
}
);
}
if ( reverseSortOrder )
{
surfaces.Reverse();
}
this.LogInfo( "Combining for Material", "combined?:",isCombinedMaterial,"material:", usedMaterial, surfaces.Count, "meshes" );
var meshGeometry = new MeshGeometry();
@ -466,12 +531,10 @@ namespace Rokojori
if ( combineMeshes )
{
if ( outputMesh == null )
{
this.LogInfo( "Created outputMesh");
outputMesh = this.CreateChild<MeshInstance3D>();
}
outputMesh = null;
this.DestroyChildren();
outputMesh = this.CreateChild<MeshInstance3D>();
outputMesh.Mesh = arrayMesh;
}

View File

@ -285,10 +285,32 @@ namespace Rokojori
return From( (ArrayMesh)meshInstance3D.Mesh, meshInstance3D.GlobalTransform );
}
public static MeshGeometry From( Mesh mesh, Transform3D? trsf = null, int index = 0 )
{
var arrayMesh = mesh as ArrayMesh;
if ( arrayMesh == null )
{
arrayMesh = new ArrayMesh();
var st = new SurfaceTool();
st.Begin( Mesh.PrimitiveType.Triangles );
st.CreateFrom( mesh, index );
st.Commit( arrayMesh );
}
return From( arrayMesh, trsf, 0 );
}
public static MeshGeometry From( ArrayMesh mesh, Transform3D? trsf = null, int index = 0 )
{
var mg = new MeshGeometry();
if ( mesh == null )
{
return mg;
}
var arrays = mesh.SurfaceGetArrays( index );
var vertices = arrays[ (int) Mesh.ArrayType.Vertex ];

View File

@ -23,12 +23,30 @@ namespace Rokojori
[Export]
public bool getMeshInstanceChild = false;
[ExportGroup("Instancing")]
[Export]
public bool useInstancing = false;
[Export]
public float instancingCullDistance = 1000;
[Export]
public float instancingCullRange = 500;
[Export]
public float instancingSplitSize = 25;
[Export]
public Vector3 instancingSplitScatterNoiseAmount = Vector3.Zero;
[Export]
public Vector3 instancingSplitScatterNoiseFrequency = Vector3.Zero;
[ExportGroup("")]
protected PackedScene _cachedNode3DScene;
public PackedScene GetPackedScene()

View File

@ -64,6 +64,17 @@ namespace Rokojori
p.parent = gs.container != null ? gs.container : container;
p.instanced = gs.useInstancing;
p.instanceSplitSize = gs.instancingSplitSize;
p.instancingSplitScatterNoiseAmount = gs.instancingSplitScatterNoiseAmount;
p.instancingSplitScatterNoiseFrequency = gs.instancingSplitScatterNoiseFrequency;
p.instanceCullDistance = gs.instancingCullDistance;
p.instanceCullRange = gs.instancingCullRange;
if ( gs.node3D != null && gs.node3D is MeshInstance3D mi )
{
p.shadowCasting = mi.CastShadow;
}
}
}

View File

@ -10,7 +10,15 @@ namespace Rokojori
public class ScatterPoint:PointData
{
public bool instanced = false;
public float instanceCullDistance = 200;
public float instanceCullRange = 100;
public float instanceSplitSize = 25;
public Vector3 instancingSplitScatterNoiseAmount = Vector3.Zero;
public Vector3 instancingSplitScatterNoiseFrequency = Vector3.Zero;
public GeometryInstance3D.ShadowCastingSetting shadowCasting = GeometryInstance3D.ShadowCastingSetting.On;
protected Scatterer _creator;
public Scatterer creator => _creator;
protected int _creatorID;

View File

@ -344,6 +344,11 @@ namespace Rokojori
c.materialOveride = mwm.material;
c.mesh = mwm.mesh;
c.multiMeshSplitSize = sp.instanceSplitSize;
c.multiMeshSplitNoiseAmount = sp.instancingSplitScatterNoiseAmount;
c.multiMeshSplitNoiseFrequency = sp.instancingSplitScatterNoiseFrequency;
c.cullDistance = sp.instanceCullDistance;
c.cullRange = sp.instanceCullRange;
c.castShadows = sp.shadowCasting;
_instancedMassRenderers.Add( mwm.mesh, c );

View File

@ -27,6 +27,10 @@ namespace Rokojori
[Export]
public Vector3 positionNoiseOffset = Vector3.Zero;
[Export]
public Vector3 staticOffset = Vector3.Zero;
[ExportGroup( "Rotation" )]
[Export]
public Vector3 rotationOffset = Vector3.Zero;
@ -75,7 +79,7 @@ namespace Rokojori
var scaleRandom = Noise.Perlin3( scalePerlin );
var uniformScaleRandom = Noise.Perlin( scalePerlin + new Vector3( 100002, -10002, 1000 ) );
p.position += positionOffset * positionRandom * positionOffsetScale;
p.position += positionOffset * positionRandom * positionOffsetScale + staticOffset;
p.rotation *= Quaternion.FromEuler( rotationOffset * MathX.DegreesToRadians * rotationRandom * rotationOffsetScale );

View File

@ -252,6 +252,18 @@ namespace Rokojori
return list[ index ];
}
public T From<T>( List<T> list, int start, int end )
{
if ( list.Count == 0 )
{
return default ( T );
}
var index = this.IntegerInclusive( start, end );
return list[ index ];
}
public T RemoveFrom<T>( List<T> list )
{
if ( list.Count == 0 )

View File

@ -229,6 +229,11 @@ namespace Rokojori
}
//this.LogInfo( "Register", s );
if ( ! sensorToRunner.ContainsKey( s ) )
{
return;
}
var sensorRunner = sensorToRunner[ s ];
if ( sensorRunner.listeners.Contains( sih ) )
@ -337,6 +342,28 @@ namespace Rokojori
HashSet<object> _scannedObjects = new HashSet<object>();
bool IsIgnoreType( object obj )
{
var ignoreTypes = new List<Type>()
{
typeof( GpuParticles3D ),
typeof( MeshInstance3D ),
typeof( Node3D ),
typeof( CollisionShape3D ),
typeof( OmniLight3D ),
typeof( DirectionalLight3D ),
typeof( WorldEnvironment ),
typeof( Area3D ),
typeof( CharacterBody3D ),
typeof( AudioStreamPlayer3D ),
typeof( ReflectionProbe )
};
return ignoreTypes.IndexOf( obj.GetType() ) != -1;
}
void AddSensorsFrom( object obj )
{
if ( Engine.IsEditorHint() )
@ -346,13 +373,23 @@ namespace Rokojori
//this.LogInfo( "AddSensorsFrom", obj );
try
{
if ( obj == null || _scannedObjects.Contains( obj ) )
{
return;
}
_scannedObjects.Add( obj );
if ( IsIgnoreType( obj ) )
{
return;
}
var sensors = ReflectionHelper.GetDataMemberValues<Sensor>( obj );
@ -391,6 +428,12 @@ namespace Rokojori
var resources = ReflectionHelper.GetDataMemberValues<Resource>( obj );
resources.ForEach( r => AddSensorsFrom( r ) );
}
catch( System.Exception e )
{
this.LogError( e );
}
}
void CreateRunners()

View File

@ -30,7 +30,7 @@ namespace Rokojori
roots.ForEach(
( r )=>
{
Nodes.ForEach<Node3D>( r, n => CheckWarningsOf( n ) );
Nodes.ForEach<Node>( r, n => CheckWarningsOf( n ) );
}
);

View File

@ -10,6 +10,8 @@ namespace Rokojori
{
public static class DateMath
{
public static float GetDifference( this DateTime a, DateTime b )
{
return (float) ( ( a - b ).TotalSeconds );

View File

@ -27,6 +27,7 @@ namespace Rokojori
[Export]
public bool autoStart = true;
public static float osTime => (float)( Time.GetTicksMsec() / 1000.0 );
public TimeLineRunner runner
{

View File

@ -605,6 +605,42 @@ namespace Rokojori
return copy;
}
public static bool Has<T>( this List<T> list, Func<T,bool> evaluater )
{
foreach ( var t in list )
{
if ( evaluater( t ) )
{
return true;
}
}
return false;
}
public static void SwapTowardsBegin<T>( this List<T> list, int index, int steps = 1 )
{
list.Swap( index, index - steps );
}
public static void SwapTowardsEnd<T>( this List<T> list, int index, int steps = 1 )
{
list.Swap( index, index + steps );
}
public static void Swap<T>( this List<T> list, int indexA, int indexB )
{
if ( list == null || indexA == indexB || indexA < 0 || indexB < 0 || indexA >= list.Count || indexA >= list.Count )
{
return;
}
var buffer = list[ indexA ];
list[ indexA ] = list[ indexB ];
list[ indexB ] = buffer;
}
public static List<U> FilterAndMap<T,U>( List<T> list, Func<T,int,bool> filter, Func<T,U> map)
{
var mapped = new List<U>();

View File

@ -8,6 +8,18 @@ namespace Rokojori
{
public class UIDragging
{
public class MappedEvent
{
public MouseButton mouseButton;
public EditableUIDraggingEvent uiEvent;
}
public class ButtonState
{
public MouseButton mouseButton;
public bool dragging;
}
public class UIDraggingCallbacks: ICustomDisposer
{
public UI ui;
@ -15,13 +27,23 @@ namespace Rokojori
public bool wasDisposed = false;
public bool notValid =>
wasDisposed ||
onMouseClick == null ||
onDragging == null ||
onProcess == null ||
mouseEvents == null || mouseEvents.FilterNulls().Count == 0 ||
mouseEventsDragging == null || mouseEventsDragging.FilterNulls().Count == 0;
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,EditableUIDraggingEvent> mouseEvents = new Dictionary<MouseButton, EditableUIDraggingEvent>();
public Dictionary<MouseButton,bool> mouseEventsDragging = new Dictionary<MouseButton, bool>();
public List<MappedEvent> mouseEvents = new List<MappedEvent>();
public List<ButtonState> mouseEventsDragging = new List<ButtonState>();
// public Dictionary<MouseButton,bool> mouseEventsDragging = new Dictionary<MouseButton, bool>();
public string uid = IDGenerator.GenerateID();
public string GetUID(){ return uid; }
@ -42,10 +64,16 @@ namespace Rokojori
callbacks.onProcess = (float delta )=>
{
foreach ( var m in callbacks.mouseEvents )
callbacks.mouseEvents.ForEach(
( m )=>
{
callback( callbacks.mouseEvents[ m.Key ] );
callback( m.uiEvent );
}
);
// foreach ( var m in callbacks.mouseEvents )
// {
// callback( callbacks.mouseEvents[ m.Key ] );
// }
};
callbacks.onDragging = ( InputEvent ie ) =>
@ -53,11 +81,13 @@ namespace Rokojori
if ( ie is InputEventMouseButton mb && ! mb.Pressed )
{
callbacks.mouseEventsDragging[ mb.ButtonIndex ] = false;
var mdIndex = callbacks.mouseEventsDragging.FindIndex( me => me.mouseButton == mb.ButtonIndex );
var meIndex = callbacks.mouseEvents.FindIndex( md => md.mouseButton == mb.ButtonIndex );
callbacks.mouseEventsDragging[ mdIndex ].dragging = false;
callbacks.mouseEvents[ mb.ButtonIndex ].UpdatePosition( mb.GlobalPosition, true );
callbacks.mouseEvents[ meIndex ].uiEvent.UpdatePosition( mb.GlobalPosition, true );
callback( callbacks.mouseEvents[ mb.ButtonIndex ] );
callback( callbacks.mouseEvents[ meIndex ].uiEvent );
if ( ! callbacks.hasAnyMouseDragging )
{
@ -76,11 +106,18 @@ namespace Rokojori
{
var globalPosition = mo.GlobalPosition;
foreach ( var m in callbacks.mouseEvents )
// foreach ( var m in callbacks.mouseEvents )
// {
// callbacks.mouseEvents[ m.Key ].UpdatePosition( globalPosition );
// // callback( callbacks.mouseEvents[ m.Key ] );
// }
callbacks.mouseEvents.ForEach(
( m )=>
{
callbacks.mouseEvents[ m.Key ].UpdatePosition( globalPosition );
// callback( callbacks.mouseEvents[ m.Key ] );
m.uiEvent.UpdatePosition( globalPosition );
}
);
}
@ -111,7 +148,19 @@ namespace Rokojori
{
sc.GetUISelectorFlags().AddIfNotPresent( UISelectorFlag.Dragging );
}
callbacks.mouseEventsDragging[ button ] = true;
var buttonIndex = callbacks.mouseEventsDragging.FindIndex( bs => bs.mouseButton == button );
if ( buttonIndex == -1 )
{
var bs = new ButtonState();
bs.mouseButton = button;
callbacks.mouseEventsDragging.Add( bs );
buttonIndex = callbacks.mouseEventsDragging.Count - 1;
}
callbacks.mouseEventsDragging[ buttonIndex ].dragging = true;
if ( ! callbacks.hasDraggingCallback )
{
@ -162,7 +211,7 @@ namespace Rokojori
{
foreach ( var mb in mouseEventsDragging )
{
if ( mb.Value )
if ( mb.dragging )
{
return true;
}
@ -177,14 +226,20 @@ namespace Rokojori
public EditableUIDraggingEvent GetMouseEvent( MouseButton mb )
{
if ( ! mouseEvents.ContainsKey( mb ) )
var index = mouseEvents.FindIndex( m => m.mouseButton == mb );
if ( index == -1)
{
mouseEvents[ mb ] = new EditableUIDraggingEvent( mb );
var mappedEvent = new MappedEvent();
mappedEvent.mouseButton = mb;
mappedEvent.uiEvent = new EditableUIDraggingEvent( mb );
mouseEvents.Add( mappedEvent );
index = mouseEvents.Count - 1;
}
mouseEvents[ mb ].SetUI( ui );
mouseEvents[ index ].uiEvent.SetUI( ui );
return mouseEvents[ mb ];
return mouseEvents[ index ].uiEvent;
}
public void Clear()

View File

@ -121,7 +121,7 @@ namespace Rokojori
ui.onProcess.AddAction( UpdatePosition );
( button as UIStylePropertyContainer ).AddUISelectorFlag( UISelectorFlag.Scrolling, scrollID );
( button as UIStylePropertyContainerNode ).SetDirty();
}
};
@ -159,12 +159,25 @@ namespace Rokojori
bool _dragging = false;
bool _updatingPosition = false;
UIDragging.UIDraggingCallbacks leftMouseCallback;
UIDragging.UIDraggingCallbacks leftMouseCallbacks;
UIDragging.UIDraggingCallbacks middleMouseCallbacks;
public override void _Process( double delta )
{
if (
leftMouseCallbacks == null || leftMouseCallbacks.notValid ||
middleMouseCallbacks == null || middleMouseCallbacks.notValid
)
{
AddDraggingListener();
}
}
void AddDraggingListener()
{
leftMouseCallback = UIDragging.OnLeftMouseButton( button,
leftMouseCallbacks = UIDragging.OnLeftMouseButton( button,
( ev )=>
{
if ( ev.isStart )
@ -189,7 +202,7 @@ namespace Rokojori
}
);
UIDragging.OnMiddleMouseButton( scrollContainer,
middleMouseCallbacks = UIDragging.OnMiddleMouseButton( scrollContainer,
( ev )=>
{
if ( ev.isStart )
@ -223,10 +236,12 @@ namespace Rokojori
Vector2 cachedOffset = Vector2.Zero;
void UpdatePosition( float delta )
{
// this.LogInfo( "UpdatePosition" );
var value = Smoothing.Apply( smoothing, nextValue, delta );
var uiStyleContainer = ( UIStylePropertyContainer ) button;
var uiStyleContainer = ( UIStylePropertyContainerNode ) button;
uiStyleContainer.SetLayoutDirtyFlag();
if ( ! _dragging && ( value - nextValue ).Length() < 1 )
{
@ -250,6 +265,7 @@ namespace Rokojori
var left = new UINumber();
left.value = value.X;
uiStyleContainer.SetUIStyleNumberProperty( UIStyleNumberProperty.Left, left );
}
if ( Direction.Both == direction || Direction.Vertical == direction )
@ -268,18 +284,21 @@ namespace Rokojori
var scrollOffset = scrollRange * sliderValue;
var scrollTargetNode = scrollTarget as UIStylePropertyContainerNode;
if ( Direction.Both == direction || Direction.Horizontal == direction )
{
var left = new UINumber();
left.value = -scrollOffset.X;
( scrollTarget as UIStylePropertyContainer ).SetUIStyleNumberProperty( UIStyleNumberProperty.Left, left );
scrollTargetNode.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 );
scrollTargetNode.SetUIStyleNumberProperty( UIStyleNumberProperty.Top, top );
}
}
@ -299,6 +318,7 @@ namespace Rokojori
void SyncScroll()
{
if ( _dragging || _updatingPosition )
{
// this.LogInfo( "SyncScroll blocked" );
@ -307,9 +327,11 @@ namespace Rokojori
// this.LogInfo( "SyncScroll" );
var uiStyleContainer = ( UIStylePropertyContainer ) button;
var uiStyleContainer = ( UIStylePropertyContainerNode ) button;
var value = GetButtonScrollRange() * sliderValue;
uiStyleContainer.SetDirty();
if ( Direction.Both == direction || Direction.Horizontal == direction )
{
var left = new UINumber();

View File

@ -135,6 +135,8 @@ namespace Rokojori
UILayouting.SetPositionInParentAnchor( region );
}
region.CommitUpdateInfo();
Nodes.ForEachDirectChild<Control>( region,
child =>
{
@ -151,6 +153,8 @@ namespace Rokojori
}
);
region.CommitUpdateInfo();
}
static List<Line> CreateLines( UIRegion region )

View File

@ -34,162 +34,26 @@ namespace Rokojori
return;
}
if ( control is UIRegion )
if ( control is UIRegion region )
{
var childUIRegion = (UIRegion) control;
childUIRegion.Layout();
region.Layout();
}
else if ( control is UIImage )
else if ( control is UIImage uiImage )
{
var tw = 0;
var th = 0;
if ( control is UIImage )
{
var uiImage = (UIImage) control;
if ( uiImage.Texture == null )
{
uiImage.Size = new Vector2( 0, 0 );
return;
uiImage.Update();
uiImage.CommitUpdateInfo();
}
tw = uiImage.Texture.GetWidth();
th = uiImage.Texture.GetHeight();
}
var container = (UIStylePropertyContainer) control;
var w = UINumber.Compute( control, UIStyleNumberProperty.Width, tw, tw / 100f );
var h = UINumber.Compute( control, UIStyleNumberProperty.Height, th, th / 100f );
// RJLog.Log( "Set Image Size", w, h );
control.Size = new Vector2( w, h );
if ( control is UIImage )
else if ( control is UIText uiText )
{
var uiImage = (UIImage) control;
if ( uiImage.Material != null )
{
var ui = uiImage.GetUI();
if ( ui == null )
{
RJLog.Log( "No UI Found", HierarchyName.Of( uiImage ) );
return;
}
if ( ui.settings == null )
{
RJLog.Log( "No UI settings Found", HierarchyName.Of( uiImage ) );
return;
}
if ( ui.settings.sizePropertyName == null )
{
// 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.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;
}
}
}
else if ( control is UIText )
{
var text = (UIText) control;
var container = (UIStylePropertyContainer) control;
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 );
text.uiTextLabelSettings.OutlineSize =
UINumber.ComputeInt( control, UIStyleNumberProperty.FontOutlineSize, 0 );
text.uiTextLabelSettings.OutlineColor =
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 );
text.uiTextLabelSettings.ShadowOffset = new Vector2(
UINumber.Compute( control, UIStyleNumberProperty.FontShadowOffsetX, 0 ),
UINumber.Compute( control, UIStyleNumberProperty.FontShadowOffsetY, 0 )
);
control.UpdateMinimumSize();
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();
uiText.Update();
uiText.CommitUpdateInfo();
}
else
{
var minSize = control.GetMinimumSize();
var w = UINumber.Compute( control, UIStyleNumberProperty.Width, minSize.X, minSize.X / 100f );
var h = UINumber.Compute( control, UIStyleNumberProperty.Height, minSize.Y, minSize.Y / 100f );
// RJLog.Log( "Set Image Size", w, h );
control.Size = new Vector2( w, h );
}
}
else
{
// control.UpdateMinimumSize();
// control.Size = control.GetMinimumSize();
}
UILayouting.UpdatePivot( control );
UpdatePivot( control );
}
public static void SetPositionInParentAnchor( UIStylePropertyContainer container )

View File

@ -7,8 +7,8 @@ namespace Rokojori
{
public interface UIHolderControl
{
public void SetUI( UI ui);
public UI GetUI();
public void SetUI( UI ui, bool computeDepth = true );
public UI GetUI( bool computeDepth = true );
}
public class UIHolder

View File

@ -8,7 +8,7 @@ namespace Rokojori
{
[Tool]
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIImage.svg")]
public partial class UIImage:TextureRect, UIStylePropertyContainer, UIHolderControl, IAssemblyReload
public partial class UIImage:TextureRect, UIStylePropertyContainerNode, UIHolderControl, IAssemblyReload
{
UIImageType _imageType;
[Export]
@ -33,28 +33,43 @@ namespace Rokojori
UI ui;
public void SetUI( UI ui )
public void SetUI( UI ui, bool computeDepth = true )
{
this.ui = ui;
if ( computeDepth )
{
ComputeUIAncestorDepth();
}
}
public UI GetUI()
public UI GetUI( bool computeDepth = true )
{
var ui = this.ui != null ? this.ui : Unique<UI>.Get();
if ( this.ui != null )
{
return this.ui;
}
var ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
this._uiAncestorDepth = -1;
this.LogInfo( "No UI in parents >", ui );
return null;
}
if ( computeDepth )
{
ComputeUIAncestorDepth();
}
return ui;
}
@ -64,7 +79,7 @@ namespace Rokojori
if ( _imageType != null )
{
this.LogInfo( "Assigning Image Type:", _imageType );
// this.LogInfo( "Assigning Image Type:", _imageType );
_imageType.Assign( this );
}
}
@ -76,20 +91,29 @@ namespace Rokojori
MouseEntered += ()=>
{
AddUISelectorFlag( UISelectorFlag.Hover, hoverID );
this.SetDirty();
};
MouseExited += ()=>
{
RemoveUISelectorFlag( UISelectorFlag.Hover, hoverID );
this.SetDirty();
};
UpdateImageType();
ComputeUIAncestorDepth();
}
public override void _EnterTree()
{
UpdateImageType();
ComputeUIAncestorDepth();
}
public override void _ExitTree()
{
_uiAncestorDepth = -1;
}
public void OnAssemblyReloaded()
@ -97,6 +121,23 @@ namespace Rokojori
UpdateImageType();
}
int _uiAncestorDepth;
public void ComputeUIAncestorDepth()
{
SetUIAncestorDepth( NodesWalker.Get().GetAncestorDistance( this, GetUI( false ) ) );
}
public void SetUIAncestorDepth( int depth )
{
_uiAncestorDepth = depth;
}
public int GetUIAncestorDepth()
{
return _uiAncestorDepth;
}
void ResetImageType()
{
ExpandMode = TextureRect.ExpandModeEnum.IgnoreSize;
@ -129,12 +170,23 @@ namespace Rokojori
}
else
{
_selectorFlagReferenceCounter.Remove( flag );
_selectorFlagReferenceCounter.Remove( flag, reference );
}
var numFlagsBefore = _selectorFlags.Count;
_selectorFlags = _selectorFlagReferenceCounter.Keys.ToList();
var changed = numFlagsBefore != _selectorFlags.Count;
UISelector.UpdateParentUISelectorFlags( this );
if ( changed )
{
// this.LogInfo( "Changed flag:", flag, reference );
this.SetDirty();
}
}
List<UISelectorFlag> _selectorFlags = [];
@ -444,6 +496,90 @@ namespace Rokojori
case UIStyleNumberProperty.ScaleY: { scaleY = number; } break;
}
this.SetLayoutDirtyFlag();
}
bool _isAnimated = false;
int _isLayoutDirty = 3;
public void ResetDirtyFlags()
{
_isAnimated = false;
_isLayoutDirty = Mathf.Max( 0, _isLayoutDirty - 1 );
}
public void SetAnimatedFlag()
{
_isAnimated = true;
this.SetDirty();
}
public void SetLayoutDirtyFlag()
{
_isLayoutDirty = 3;
this.SetDirty();
}
public bool IsDirty()
{
return _isAnimated || _isLayoutDirty != 0 || this.HasActiveTransitions();
}
public void Update()
{
if ( Texture == null )
{
Size = new Vector2( 0, 0 );
return;
}
var tw = Texture.GetWidth();
var th = Texture.GetHeight();
var w = UINumber.Compute( this, UIStyleNumberProperty.Width, tw, tw / 100f );
var h = UINumber.Compute( this, UIStyleNumberProperty.Height, th, th / 100f );
Size = new Vector2( w, h );
if ( Material == null )
{
return;
}
var ui = GetUI();
if ( ui == null || ui.settings == null || ui.settings.sizePropertyName == null )
{
return;
}
ui.settings.sizePropertyName.Set( Material, Size );
var colorProperties = imageType != null ? imageType.GetColorShaderProperties() : [];
var colorPropertyName = new ColorPropertyName();
foreach ( var c in colorProperties )
{
var color = UIColor.Compute( this, UIStyleColorProperty.ColorShaderProperty, c, Colors.White );
colorPropertyName.propertyName = c;
colorPropertyName.Set( Material, color );
}
var numberProperties = imageType != null ? imageType.GetNumberShaderProperties() : [];
var numberPropertyName = new FloatPropertyName();
foreach ( var n in numberProperties )
{
var value = UINumber.Compute( this, UIStyleNumberProperty.FloatShaderProperty, n );
numberPropertyName.propertyName = n;
numberPropertyName.Set( Material, value );
}
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName, UIStylePropertyContainer source )

View File

@ -7,7 +7,7 @@ namespace Rokojori
{
[Tool]
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIRegion.svg")]
public partial class UIRegion : Control, UIStylePropertyContainer, UIHolderControl
public partial class UIRegion : Control, UIStylePropertyContainerNode, UIHolderControl
{
[Export]
public UIStyle parentStyle;
@ -256,8 +256,37 @@ namespace Rokojori
}
this.SetLayoutDirtyFlag();
}
bool _isAnimated = false;
int _isLayoutDirty = 3;
public void ResetDirtyFlags()
{
_isAnimated = false;
_isLayoutDirty = Mathf.Max( 0, _isLayoutDirty - 1 );
}
public void SetAnimatedFlag()
{
_isAnimated = true;
this.SetDirty();
}
public void SetLayoutDirtyFlag()
{
_isLayoutDirty = 3;
this.SetDirty();
}
public bool IsDirty()
{
return _isAnimated || _isLayoutDirty != 0 || this.HasActiveTransitions();
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
switch ( property )
@ -277,15 +306,44 @@ namespace Rokojori
MouseEntered += ()=>
{
AddUISelectorFlag( UISelectorFlag.Hover, hoverID );
this.SetDirty();
};
MouseExited += ()=>
{
RemoveUISelectorFlag( UISelectorFlag.Hover, hoverID );
this.SetDirty();
};
}
int _uiAncestorDepth;
public void ComputeUIAncestorDepth()
{
SetUIAncestorDepth( NodesWalker.Get().GetAncestorDistance( this, GetUI( false ) ) );
}
public void SetUIAncestorDepth( int depth )
{
_uiAncestorDepth = depth;
}
public int GetUIAncestorDepth()
{
return _uiAncestorDepth;
}
public override void _EnterTree()
{
ComputeUIAncestorDepth();
}
public override void _ExitTree()
{
_uiAncestorDepth = -1;
}
MapList<UISelectorFlag,string> _selectorFlagReferenceCounter = new MapList<UISelectorFlag, string>();
public void AddUISelectorFlag( UISelectorFlag flag, string reference = "" )
@ -311,12 +369,20 @@ namespace Rokojori
}
else
{
_selectorFlagReferenceCounter.Remove( flag );
_selectorFlagReferenceCounter.Remove( flag, reference );
}
var numFlagsBefore = _selectorFlags.Count;
_selectorFlags = _selectorFlagReferenceCounter.Keys.ToList();
var changed = numFlagsBefore != _selectorFlags.Count;
UISelector.UpdateParentUISelectorFlags( this );
if ( changed )
{
this.SetDirty();
}
}
List<UISelectorFlag> _selectorFlags = [];
@ -352,25 +418,37 @@ namespace Rokojori
UI ui;
public void SetUI( UI ui )
public void SetUI( UI ui, bool computeDepth = true )
{
this.ui = ui;
if ( computeDepth )
{
ComputeUIAncestorDepth();
}
}
public UI GetUI()
public UI GetUI( bool computeDepth = true )
{
var ui = this.ui != null ? this.ui : Unique<UI>.Get();
if ( this.ui != null )
{
return this.ui;
}
var ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
_uiAncestorDepth =-1;
this.LogInfo( "No UI in parents >", ui );
return null;
}
if ( computeDepth )
{
ComputeUIAncestorDepth();
}
return ui;

View File

@ -8,7 +8,7 @@ namespace Rokojori
{
[Tool]
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIText.svg")]
public partial class UIText:Label,UIStylePropertyContainer, iLocalizable, UIHolderControl, IAssemblyReload
public partial class UIText:Label,UIStylePropertyContainerNode, iLocalizable, UIHolderControl, IAssemblyReload
{
LocalizedString _locale;
@ -40,6 +40,8 @@ namespace Rokojori
Text = LocalizedString.Get( _locale );
_textDirty = true;
}
public void OnAssemblyReloaded()
@ -69,6 +71,7 @@ namespace Rokojori
set { _font = value; UpdateFont(); }
}
[Export]
public UINumber fontSize;
[Export]
@ -155,6 +158,8 @@ namespace Rokojori
{
RemoveThemeFontOverride( "font" );
AddThemeFontOverride( "font", resolvedFont );
_textDirty = true;
}
}
@ -168,15 +173,44 @@ namespace Rokojori
MouseEntered += ()=>
{
AddUISelectorFlag( UISelectorFlag.Hover, hoverID );
this.SetDirty();
};
MouseExited += ()=>
{
RemoveUISelectorFlag( UISelectorFlag.Hover, hoverID );
this.SetDirty();
};
}
int _uiAncestorDepth;
public void ComputeUIAncestorDepth()
{
SetUIAncestorDepth( NodesWalker.Get().GetAncestorDistance( this, GetUI( false ) ) );
}
public void SetUIAncestorDepth( int depth )
{
_uiAncestorDepth = depth;
}
public int GetUIAncestorDepth()
{
return _uiAncestorDepth;
}
public override void _EnterTree()
{
ComputeUIAncestorDepth();
}
public override void _ExitTree()
{
_uiAncestorDepth = -1;
}
protected override void Dispose( bool disposing)
{
_selectorFlagReferenceCounter.Clear();
@ -196,18 +230,28 @@ namespace Rokojori
void SetSelectorFlagReference( UISelectorFlag flag, string reference, bool enable )
{
if ( enable )
{
_selectorFlagReferenceCounter.AddIfNotPresent( flag, reference );
}
else
{
_selectorFlagReferenceCounter.Remove( flag );
_selectorFlagReferenceCounter.Remove( flag, reference );;
}
var numFlagsBefore = _selectorFlags.Count;
_selectorFlags = _selectorFlagReferenceCounter.Keys.ToList();
var changed = numFlagsBefore != _selectorFlags.Count;
UISelector.UpdateParentUISelectorFlags( this );
if ( changed )
{
this.SetDirty();
}
}
List<UISelectorFlag> _selectorFlags = [];
@ -254,16 +298,6 @@ namespace Rokojori
}
// public List<ActiveStyleTransition<UIColor,ColorPropertyName>> GetActiveShaderUIColorTransitions()
// {
// return null;
// }
// public List<ActiveStyleTransition<UINumber,FloatPropertyName>> GetActiveShaderUINumberTransitions()
// {
// return null;
// }
[ExportGroup("Transitions")]
[Export]
public TransitionSettingsAll transitionSettings;
@ -427,11 +461,11 @@ namespace Rokojori
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.FontSize: { fontSize = number; _textDirty = true; } break;
case UIStyleNumberProperty.FontOutlineSize: { outlineSize = number; _styleDirty = true; } break;
case UIStyleNumberProperty.FontShadowSize: { shadowSize = number; _styleDirty = true; } break;
case UIStyleNumberProperty.FontShadowOffsetX: { shadowOffsetX = number; _styleDirty = true; } break;
case UIStyleNumberProperty.FontShadowOffsetY: { shadowOffsetY = number; _styleDirty = true; } break;
case UIStyleNumberProperty.PivotX: { pivotX = number; } break;
case UIStyleNumberProperty.PivotY: { pivotY = number; } break;
@ -441,6 +475,9 @@ namespace Rokojori
case UIStyleNumberProperty.ScaleX: { scaleX = number; } break;
case UIStyleNumberProperty.ScaleY: { scaleY = number; } break;
}
this.SetLayoutDirtyFlag();
}
public Vector2 GetUISize()
@ -448,6 +485,207 @@ namespace Rokojori
return GetSize();
}
bool _isAnimated = false;
int _isLayoutDirty = 3;
public void ResetDirtyFlags()
{
_isAnimated = false;
_isLayoutDirty = Mathf.Max( 0, _isLayoutDirty - 1 );
}
public void SetAnimatedFlag()
{
_isAnimated = true;
this.SetDirty();
}
public void SetLayoutDirtyFlag()
{
_isLayoutDirty = 3;
this.SetDirty();
}
public bool IsDirty()
{
return _isAnimated || _isLayoutDirty != 0 || this.HasActiveTransitions();
}
bool _styleDirty = false;
bool _textDirty = false;
public class CachedLabelSettings
{
public CachedUINumber fontSize = CachedUINumber.AsInt( UIStyleNumberProperty.FontSize ).SetMin( 1 );
public CachedUINumber outlineSize = CachedUINumber.AsInt( UIStyleNumberProperty.FontOutlineSize );
public CachedUINumber shadowSize = CachedUINumber.AsInt( UIStyleNumberProperty.FontShadowSize );
public CachedUINumber shadowOffsetX = CachedUINumber.AsFloat( UIStyleNumberProperty.FontShadowOffsetX );
public CachedUINumber shadowOffsetY = CachedUINumber.AsFloat( UIStyleNumberProperty.FontShadowOffsetY );
public CachedUIColor fontColor = CachedUIColor.Create( UIStyleColorProperty.FontColor );
public CachedUIColor outlineColor = CachedUIColor.Create( UIStyleColorProperty.FontOutlineColor );
public CachedUIColor shadowColor = CachedUIColor.Create( UIStyleColorProperty.FontShadowColor );
public bool HasChanged()
{
if ( fontSize.changed || outlineSize.changed || shadowSize.changed || fontColor.changed )
{
return true;
}
if ( outlineSize.valueInt > 0 && outlineColor.changed )
{
return true;
}
if ( shadowSize.valueInt > 0 && ( shadowOffsetX.changed || shadowOffsetY.changed || shadowColor.changed ) )
{
return true;
}
return false;
}
bool _wasCreated = false;
public bool wasCreated => _wasCreated;
public LabelSettings CreateLabelSettings()
{
_wasCreated = true;
var l = new LabelSettings();
l.FontSize = fontSize.valueInt;
l.OutlineSize = outlineSize.valueInt;
l.ShadowSize = shadowSize.valueInt;
l.FontColor = fontColor.color;
if ( outlineSize.valueInt > 0 )
{
l.OutlineColor = outlineColor.color;
}
if ( shadowSize.valueInt > 0 )
{
l.ShadowColor = shadowColor.color;
l.ShadowOffset = new Vector2( shadowOffsetX.value, shadowOffsetY.value );
}
return l;
}
}
CachedLabelSettings cachedLabelSettings = new CachedLabelSettings();
public void Update()
{
// FONT SIZE
// VIEW WIDTH/HEIGHT
// PARENT WIDTH/HEIGHT
// PARENT STYLE
// PROP
var ui = GetUI();
var updateTextField = _textDirty || ui.fontSizeChanged || ui.sizeChanged;
if ( ui.fontSizeChanged || ! cachedLabelSettings.wasCreated )
{
cachedLabelSettings.fontSize.alternative = UINumber.em( this );
cachedLabelSettings.fontSize.relative = UINumber.em( this ) / 100f ;
}
cachedLabelSettings.fontSize.Compute( this );
cachedLabelSettings.outlineSize.Compute( this );
cachedLabelSettings.shadowSize.Compute( this );
cachedLabelSettings.fontColor.Compute( this );
if ( cachedLabelSettings.outlineSize.valueInt > 0 )
{
cachedLabelSettings.outlineColor.Compute( this );
}
if ( cachedLabelSettings.shadowSize.valueInt > 0 )
{
cachedLabelSettings.shadowOffsetX.Compute( this );
cachedLabelSettings.shadowOffsetY.Compute( this );
cachedLabelSettings.shadowColor.Compute( this );
}
updateTextField = updateTextField || cachedLabelSettings.fontSize.changed;
if ( cachedLabelSettings.HasChanged() || ! cachedLabelSettings.wasCreated )
{
uiTextLabelSettings = cachedLabelSettings.CreateLabelSettings();
}
// uiTextLabelSettings.FontSize = Mathf.Max( 1,
// UINumber.ComputeInt( this, UIStyleNumberProperty.FontSize, UINumber.em( this ), UINumber.em( this ) / 100f ) );
// uiTextLabelSettings.OutlineSize =
// UINumber.ComputeInt( this, UIStyleNumberProperty.FontOutlineSize, 0 );
// uiTextLabelSettings.ShadowSize =
// UINumber.ComputeInt( this, UIStyleNumberProperty.FontShadowSize, 0 );
// uiTextLabelSettings.ShadowOffset = new Vector2(
// UINumber.Compute( this, UIStyleNumberProperty.FontShadowOffsetX, 0 ),
// UINumber.Compute( this, UIStyleNumberProperty.FontShadowOffsetY, 0 )
// );
// uiTextLabelSettings.FontColor =
// UIColor.Compute( this, UIStyleColorProperty.FontColor, "", Colors.White );
// uiTextLabelSettings.OutlineColor =
// UIColor.Compute( this, UIStyleColorProperty.FontOutlineColor, "", Colors.Transparent );
// uiTextLabelSettings.ShadowColor =
// UIColor.Compute( this, UIStyleColorProperty.FontShadowColor, "", Colors.Black );
if ( ! updateTextField )
{
return;
}
UpdateMinimumSize();
if ( alwaysMinimumSize )
{
if ( AutowrapMode == TextServer.AutowrapMode.Word )
{
AutowrapMode = TextServer.AutowrapMode.Off;
var minSize = GetMinimumSize();
AutowrapMode = TextServer.AutowrapMode.Word;
var w = UINumber.Compute( this, UIStyleNumberProperty.Width, minSize.X, minSize.X / 100f );
var h = UINumber.Compute( this, UIStyleNumberProperty.Height, minSize.Y, minSize.Y / 100f );
CustomMinimumSize = new Vector2( Mathf.Min( minSize.X, w ), 0 );
}
Size = GetMinimumSize();
}
else
{
var minSize = GetMinimumSize();
var w = UINumber.Compute( this, UIStyleNumberProperty.Width, minSize.X, minSize.X / 100f );
var h = UINumber.Compute( this, UIStyleNumberProperty.Height, minSize.Y, minSize.Y / 100f );
// RJLog.Log( "Set Image Size", w, h );
Size = new Vector2( w, h );
}
}
public UIColor GetUIStyleColorProperty( UIStyleColorProperty property, string shaderPropertyName, UIStylePropertyContainer source )
{
switch ( property )
@ -462,25 +700,36 @@ namespace Rokojori
UI ui;
public void SetUI( UI ui )
public void SetUI( UI ui,bool computeDepth = true )
{
this.ui = ui;
if ( computeDepth )
{
ComputeUIAncestorDepth();
}
}
public UI GetUI()
public UI GetUI( bool computeDepth = true )
{
var ui = this.ui != null ? this.ui : Unique<UI>.Get();
if ( ui == null )
{
ui = this.FindParentThatIs<UI>();
if ( this.ui != null )
{
return this.ui;
}
var ui = this.FindParentThatIs<UI>();
if ( ui == null )
{
_uiAncestorDepth = -1;
// this.LogInfo( "No UI in parents >", HierarchyName.Of( this ) );
return null;
}
if ( computeDepth )
{
ComputeUIAncestorDepth();
}
return ui;

View File

@ -0,0 +1,38 @@
using Godot;
using System;
namespace Rokojori
{
public class CachedUIColor
{
public UIStyleColorProperty property;
public string shaderPropertyName;
public bool changed;
public Color defaultColor = Colors.White;
public Color color;
public static CachedUIColor Create( UIStyleColorProperty colorProperty, string shaderPropertyName = "" )
{
var c = new CachedUIColor();
c.property = colorProperty;
c.shaderPropertyName = shaderPropertyName;
c.defaultColor = Colors.White;
return c;
}
public void Compute( Control control )
{
var nextValue = UIColor.Compute( control, property, shaderPropertyName, defaultColor );
changed = color != nextValue;
if ( changed )
{
color = nextValue;
}
}
}
}

View File

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

View File

@ -0,0 +1,85 @@
using Godot;
using System;
namespace Rokojori
{
public class CachedUINumber
{
public UIStyleNumberProperty property;
public string shaderPropertyName;
public bool isInt = false;
public float value = 0;
public int valueInt = 0;
public bool changed = false;
public int minInt = -1000000;
public int maxInt = 1000000;
public CachedUINumber SetMin( int min )
{
minInt = min;
return this;
}
public float alternative;
public float relative;
public static CachedUINumber AsFloat( UIStyleNumberProperty numberProperty, string shaderPropertyName = "" )
{
var n = new CachedUINumber();
n.property = numberProperty;
n.shaderPropertyName = shaderPropertyName;
n.alternative = 0;
return n;
}
public static CachedUINumber AsInt( UIStyleNumberProperty numberProperty, string shaderPropertyName = "" )
{
var n = new CachedUINumber();
n.property = numberProperty;
n.shaderPropertyName = shaderPropertyName;
n.alternative = 0;
n.isInt = true;
return n;
}
public static CachedUINumber AsInt( string shaderPropertyName )
{
return AsInt( UIStyleNumberProperty.FloatShaderProperty, shaderPropertyName );
}
public void Compute( Control control )
{
var nextValue = UINumber.Compute( control, property, shaderPropertyName, alternative, relative );
if ( isInt )
{
var nextInt = Mathf.Max( minInt, Mathf.RoundToInt( nextValue ) );
changed = nextInt != valueInt;
if ( changed )
{
valueInt = nextInt;
}
}
else
{
changed = value != nextValue;
if ( changed )
{
value = nextValue;
}
}
}
}
}

View File

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

View File

@ -39,10 +39,16 @@ namespace Rokojori
public static Color Compute( Control control, UIStyleColorProperty property, string shaderPropertyName, Color defaultColor )
{
var container = control as UIStylePropertyContainer;
var container = control as UIStylePropertyContainerNode;
// Get selected ui color
var uiColor = UIStyle.GetUIColorProperty( container, property, shaderPropertyName, container );
if ( uiColor != null && uiColor.isAnimated )
{
container.SetAnimatedFlag();
}
var computedColor = Compute( control, uiColor, defaultColor );
var transition = UIStyle.GetTransition( container, property, shaderPropertyName );

View File

@ -1,6 +1,8 @@
using Godot;
using Rokojori;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
@ -179,12 +181,17 @@ namespace Rokojori
public static float Compute( Control control, UIStyleNumberProperty property, string shaderPropertyName = "", float alternative = 0, float relative = 100 )
{
var container = control as UIStylePropertyContainer;
var container = control as UIStylePropertyContainerNode;
// Get selected ui number
var uiNumber = UIStyle.GetUINumberProperty( control as UIStylePropertyContainer, property, shaderPropertyName, container );
var uiNumber = UIStyle.GetUINumberProperty( container, property, shaderPropertyName, container );
var computedNumber = Compute( control, uiNumber, alternative, relative );
if ( uiNumber != null && uiNumber.isAnimated )
{
container.SetAnimatedFlag();
}
var transition = UIStyle.GetTransition( container, property, shaderPropertyName );
var transitionAll = UIStyle.GetTransitionSettingsAll( container );
@ -345,7 +352,7 @@ namespace Rokojori
public static float Compute( Control control, UINumber number, float width, float height, float relative )
{
var value = ComputeWithoutAnimation( control, number, width, height, relative );
var value = ComputeFormulaValue( control, number, width, height, relative );
if ( ! number.isAnimated || number.animationCurve == null )
{
@ -375,7 +382,42 @@ namespace Rokojori
"value"
};
static float ComputeWithoutAnimation( Control control, UINumber number, float width, float height, float relative )
static MapList<string,float[]> cached = new MapList<string, float[]>();
class CachedExpressionData
{
public string formula;
public Godot.Collections.Array inputs;
public float result;
public bool Matches( UINumber number, Godot.Collections.Array inputs )
{
if ( number.unit != formula )
{
return false;
}
for ( int i = 0; i < inputs.Count; i++ )
{
if ( (float)inputs.ElementAt( i ) != (float)this.inputs.ElementAt( i ) )
{
return false;
}
}
return true;
}
}
static List<CachedExpressionData> cachedExpressions = new List<CachedExpressionData>();
static int maxCachedExpressions = 50;
static int GetCacheIndex( UINumber number, Godot.Collections.Array inputs )
{
return cachedExpressions.FindIndex( c => c.Matches( number, inputs ) );
}
static float ComputeFormulaValue( Control control, UINumber number, float width, float height, float relative )
{
if ( number == null )
{
@ -389,8 +431,6 @@ namespace Rokojori
return number.value * em( control );
}
case "vw":
{
return number.value * width / 100f;
@ -407,6 +447,12 @@ namespace Rokojori
return number.value / 100f * ( parent == null ? width : parent.Size.X );
}
case "ph":
{
var parent = control.GetParent() as Control;
return number.value / 100f * ( parent == null ? height : parent.Size.Y );
}
case "cw":
{
var parent = control.GetParent() as Control;
@ -442,11 +488,7 @@ namespace Rokojori
}
case "ph":
{
var parent = control.GetParent() as Control;
return number.value / 100f * ( parent == null ? height : parent.Size.Y );
}
case "":
{
@ -459,10 +501,29 @@ namespace Rokojori
}
}
var parentControl = control.GetParent() as Control;;
var inputs = GetInputs( control, number, parentControl, width, height, relative );
var cacheIndex = GetCacheIndex( number, inputs );
if ( cacheIndex != -1 )
{
var cachedResult = cachedExpressions[ cacheIndex ].result;
cachedExpressions.SwapTowardsBegin( cacheIndex );
// control.LogInfo( "Using cached value", cachedExpressions[ cacheIndex ].formula, ">", cachedResult );
return cachedResult;
}
var expression = new Expression();
var expressionText = number.unit == null ? "" : RegexUtility.Replace( number.unit, "%", " * relative " );
expressionText = RegexUtility.Replace( expressionText, @"\b(\d+)\s*(em|v[wh]|p[wh]|c[wh]|c[xy]|ui[wh])\b", "$1*$2" );
if ( ! IsValid( expressionText ) )
{
return 0;
@ -475,8 +536,40 @@ namespace Rokojori
return 0;
}
var parentControl = control.GetParent() as Control;;
var scale = number.unit.IndexOf( "value" ) == -1 ? number.value : 1;
var result = (float) ( scale * expression.Execute( inputs ).AsDouble() );
Cache( number.unit, inputs, result );
return result;
}
static void Cache( string formula, Godot.Collections.Array inputs, float result )
{
CachedExpressionData data = null;
if ( cachedExpressions.Count < maxCachedExpressions )
{
data = new CachedExpressionData();
cachedExpressions.Add( data );
}
else
{
data = GodotRandom.Get().From( cachedExpressions, 4 * maxCachedExpressions / 5, maxCachedExpressions - 1 );
}
data.formula = formula;
data.inputs = inputs;
data.result = result;
}
static Godot.Collections.Array GetInputs( Control control, UINumber number, Control parentControl, float width, float height, float relative )
{
var inputs = new Godot.Collections.Array();
// em
@ -491,7 +584,7 @@ namespace Rokojori
// cw, ch
inputs.Add( ( parentControl == null ? width : UILayouting.GetContentSize( parentControl ).X ) / 100f );
inputs.Add( ( parentControl == null ? width : UILayouting.GetContentSize( parentControl ).Y ) / 100f );
inputs.Add( ( parentControl == null ? height : UILayouting.GetContentSize( parentControl ).Y ) / 100f );
// cx, cy
inputs.Add( ( parentControl == null ? 0 : UILayouting.GetContentOffset( parentControl ).X ) / 100f );
@ -505,15 +598,9 @@ namespace Rokojori
inputs.Add( relative / 100f );
// value
if ( number.unit.IndexOf( "value" ) == -1 )
{
inputs.Add( 0 );
return number.value * (float) expression.Execute( inputs ).AsDouble() ;
}
inputs.Add( number.value );
return (float) expression.Execute( inputs ).AsDouble() ;
return inputs;
}
static bool IsValid( string expressionText )

View File

@ -15,9 +15,9 @@ namespace Rokojori
{
___,
True,
False,
True_For_Any_Parent,
False_For_All_Parents
False
// True_For_Any_Parent,
// False_For_All_Parents
}
[Export]
@ -51,10 +51,10 @@ namespace Rokojori
return container.GetUISelectorFlags().Contains( flag ) == ( Value.True == value );
}
if ( Value.True_For_Any_Parent == value || Value.False_For_All_Parents == value )
{
return container.GetParentUISelectorFlags().Contains( flag ) == ( Value.True_For_Any_Parent == value );
}
// if ( Value.True_For_Any_Parent == value || Value.False_For_All_Parents == value )
// {
// return container.GetParentUISelectorFlags().Contains( flag ) == ( Value.True_For_Any_Parent == value );
// }
return true;
@ -101,8 +101,13 @@ namespace Rokojori
}
public static void UpdateParentUISelectorFlags( UIStylePropertyContainer target )
public static void UpdateParentUISelectorFlags( UIStylePropertyContainerNode target )
{
if ( target != null )
{
return;
}
var node = target as Node;
var walker = NodesWalker.Get();
@ -111,7 +116,7 @@ namespace Rokojori
walker.PruneChildTraversal( node,
( Node n ) =>
{
if ( n != node && n is UIStylePropertyContainer c )
if ( n != node && n is UIStylePropertyContainerNode c )
{
UpdateParentUISelectorFlags( c );
return false;
@ -125,7 +130,7 @@ namespace Rokojori
}
static void CombineParentFlags( UIStylePropertyContainer target )
static void CombineParentFlags( UIStylePropertyContainerNode target )
{
var parentFlags = target.GetParentUISelectorFlags();
parentFlags.Clear();
@ -138,6 +143,9 @@ namespace Rokojori
parentFlags.Union( parent.GetParentUISelectorFlags() );
}
target.SetDirty();
}
}

View File

@ -40,6 +40,76 @@ namespace Rokojori
void AddUISelectorFlag( UISelectorFlag flag, string reference = "" );
void RemoveUISelectorFlag( UISelectorFlag flag, string reference = "" );
}
public interface UIStylePropertyContainerNode:UIStylePropertyContainer
{
public int GetUIAncestorDepth();
public void ResetDirtyFlags();
public void SetAnimatedFlag();
public void SetLayoutDirtyFlag();
public bool IsDirty();
}
public static class UIStylePropertyContainers
{
public static void SetDirty( this UIStylePropertyContainerNode container )
{
if ( ! ( container is UIHolderControl ) )
{
return;
}
var control = container as UIHolderControl;
var ui = control.GetUI();
if ( ui == null )
{
return;
}
ui.SetDirty( container );
}
public static void CommitUpdateInfo( this UIStylePropertyContainerNode container )
{
if ( ! ( container is UIHolderControl ) )
{
return;
}
var control = container as UIHolderControl;
var ui = control.GetUI();
if ( ui == null )
{
return;
}
ui.SetUpdated( container );
}
public static bool HasActiveTransitions( this UIStylePropertyContainer container )
{
var animatedNumber = container.GetActiveUINumberTransitions().Find( n => n != null && n.transitioning );
if ( animatedNumber != null )
{
return true;
}
var animatedColor = container.GetActiveUIColorTransitions().Find( n => n != null && n.transitioning );
if ( animatedColor != null )
{
return true;
}
return false;
}
}
}

View File

@ -20,6 +20,7 @@ namespace Rokojori
public enum UpdateMode
{
Always,
Optimized,
Only_Manual_Updates
}
[Export]
@ -40,8 +41,6 @@ namespace Rokojori
[Export]
public float X_computedFontSizePixels = 1;
List<ICustomDisposer> _customDisposers = [];
public void AddForDisposing( ICustomDisposer customDisposer )
@ -58,6 +57,7 @@ namespace Rokojori
[Export]
public string[] customDisposerIDs = [];
public void MakeStopToPass()
{
var roots = stopToPassRoots;
@ -96,6 +96,8 @@ namespace Rokojori
return UIHolder.GetUI( c );
}
public static UIStylePropertyContainer GetStylePropertyContainerParent( Control c )
{
var it = c as Node;
@ -144,6 +146,14 @@ namespace Rokojori
return ui.settings.defaultTimeline;
}
Vector2 windowSize = new Vector2();
bool _resizeFlag = false;
bool _fontSizeFlag = false;
public bool sizeChanged => _resizeFlag;
public bool fontSizeChanged => _fontSizeFlag;
public override void _Process( double delta )
{
if ( settings == null )
@ -151,6 +161,16 @@ namespace Rokojori
return;
}
_resizeFlag = false;
_fontSizeFlag = false;
var newWindowSize = GetWindowSize();
if ( windowSize != newWindowSize )
{
_resizeFlag = true;
}
if ( useParentSize )
{
var parentSize = GetParent<Control>().Size;
@ -158,13 +178,10 @@ namespace Rokojori
if ( parentSize != cachedSize )
{
Size = parentSize;
cachedSize = parentSize;
// this.LogInfo( "Size Changed" );
_resizeFlag = true;
}
}
onProcess.DispatchEvent( (float)delta );
@ -189,13 +206,6 @@ namespace Rokojori
onInputEvent.DispatchEvent( ie );
}
List<UIHoverable> hoveredControls = new List<UIHoverable>();
public void SetHovered( UIHoverable control )
{
hoveredControls.Add( control );
}
public void BindOwnChildren()
{
BindChildrenOf( this );
@ -244,14 +254,113 @@ namespace Rokojori
}
}
HashSet<UIStylePropertyContainerNode> _dirty = new HashSet<UIStylePropertyContainerNode>();
HashSet<UIStylePropertyContainerNode> _updated = new HashSet<UIStylePropertyContainerNode>();
public void SetDirty( UIStylePropertyContainerNode control )
{
_dirty.Add( control );
}
public void SetUpdated( UIStylePropertyContainerNode control )
{
_updated.Add( control );
}
void UpdateUIElements()
{
if ( UpdateMode.Always != updateMode )
if ( UpdateMode.Always == updateMode )
{
UpdateAllUIRegions();
}
else if ( UpdateMode.Optimized == updateMode )
{
if ( _fontSizeFlag || _resizeFlag )
{
_dirty.Clear();
UpdateAllUIRegions();
}
else
{
UpdateUIElementsOptimized();
}
}
}
float time = 0;
void UpdateUIElementsOptimized()
{
var timeNow = TimeLine.osTime;
var elapsed = timeNow - time;
time = timeNow;
// this.LogInfo( Mathf.RoundToInt( elapsed * 1000f ) );
var parent = GetParent();
var sorted = new List<UIStylePropertyContainerNode>( [ .. _dirty ]);
if ( sorted.Count > 0 )
{
// this.LogInfo( "Updating:", sorted.Count );
}
_updated.Clear();
sorted.Sort(
( a, b ) =>
{
return Mathf.RoundToInt( Mathf.Sign( a.GetUIAncestorDepth() - b.GetUIAncestorDepth() ) );
}
);
sorted.ForEach(
( s )=>
{
if ( _updated.Contains( s ) )
{
return;
}
UpdateAllUIRegions();
// ( s as Control).LogInfo( "Updating:", s );
UpdateElement( s );
}
);
_updated.Clear();
_dirty.RemoveWhere( d => ! d.IsDirty() );
foreach ( var d in _dirty )
{
d.ResetDirtyFlags();
}
}
void UpdateElement( UIStylePropertyContainerNode control )
{
if ( control is UIRegion region )
{
region.Layout();
}
else
{
UILayouting.UpdateChild( control as Control );
if ( UIStyle.Position( control ) == UIPosition.From_Layout )
{
UILayouting.SetPositionInParentAnchor( control );
}
}
}
public void UpdateAllUIRegions()
@ -283,6 +392,21 @@ namespace Rokojori
}
}
public Vector2 GetWindowSize()
{
if ( Engine.IsEditorHint() )
{
var width = ProjectSettings.GetSetting( "display/window/size/viewport_width" ).AsInt32();
var height = ProjectSettings.GetSetting( "display/window/size/viewport_height" ).AsInt32();
return new Vector2( width, height );
}
else
{
return GetWindow().Size;
}
}
}
}

61
Tools/Git/Git.cs Normal file
View File

@ -0,0 +1,61 @@
#if TOOLS
using Godot;
using Rokojori;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Rokojori.Tools
{
public class GitResponse
{
public string rawResponse;
public int exitCode;
}
public class Git
{
public static async Task<GitResponse> GetStatus( string path )
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "git",
Arguments = "status",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = path
}
};
process.Start();
var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();
await Task.WhenAll( outputTask, errorTask );
await process.WaitForExitAsync();
var response = new GitResponse();
response.exitCode = process.ExitCode;
if ( process.ExitCode == 0 )
{
response.rawResponse = outputTask.Result;
}
else
{
response.rawResponse = errorTask.Result;
}
return response;
}
}
}
#endif

1
Tools/Git/Git.cs.uid Normal file
View File

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

30
Tools/Git/GitTest.cs Normal file
View File

@ -0,0 +1,30 @@
#if TOOLS
using Godot;
using Rokojori;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Rokojori.Tools
{
[Tool]
[GlobalClass]
public partial class GitTest:Node
{
[ExportToolButton("Status")]
public Callable StatusButton => Callable.From(
()=>
{
GetStatus();
}
);
async void GetStatus()
{
var response = await Git.GetStatus( ProjectSettings.GlobalizePath( "res://") );
this.LogInfo( response.exitCode, ">>", response.rawResponse );
}
}
}
#endif

1
Tools/Git/GitTest.cs.uid Normal file
View File

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

View File

@ -83,7 +83,7 @@ metadata/_custom_type_script = "uid://cnkyynboxg1qg"
[sub_resource type="ShaderMaterial" id="ShaderMaterial_btdid"]
shader = ExtResource("7_aeebn")
shader_parameter/size = Vector2(1156.56, 137.56)
shader_parameter/size = Vector2(1134.72, 137.56)
shader_parameter/sharpness = 5.0
shader_parameter/borderRadius = 6.048
shader_parameter/strokeSize = 0.0
@ -111,7 +111,7 @@ fill_to = Vector2(0.0811966, 0.0811966)
[sub_resource type="Resource" id="Resource_pyi7r"]
script = ExtResource("5_1tota")
value = 1.0
unit = "100 * pw - 2*1.5em"
unit = "100 pw - 2*1.5em"
isAnimated = false
animationDuration = 0.0
animationOffset = 0.0
@ -566,10 +566,7 @@ number = SubResource("Resource_fcuvy")
[sub_resource type="LabelSettings" id="LabelSettings_x3h2c"]
font_size = 9
font_color = Color(1, 0.467117, 0.467117, 1)
outline_color = Color(1, 1, 1, 0)
shadow_size = 0
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 0)
[sub_resource type="Resource" id="Resource_uulg6"]
script = ExtResource("17_illef")
@ -607,7 +604,7 @@ fill = 1
fill_from = Vector2(0.5, 0.5)
fill_to = Vector2(0.5, 0)
[sub_resource type="LabelSettings" id="LabelSettings_qjby8"]
[sub_resource type="LabelSettings" id="LabelSettings_1jemv"]
[sub_resource type="Resource" id="Resource_jm3cb"]
script = ExtResource("17_illef")
@ -616,21 +613,15 @@ entries = []
context = ""
metadata/_custom_type_script = "uid://bvj322mokkq63"
[sub_resource type="LabelSettings" id="LabelSettings_1jemv"]
[sub_resource type="LabelSettings" id="LabelSettings_1hp7s"]
font_size = 9
font_color = Color(0.75201, 0.831706, 0.90732, 1)
outline_color = Color(1, 1, 1, 0)
shadow_size = 0
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 0)
[sub_resource type="LabelSettings" id="LabelSettings_1hp7s"]
[sub_resource type="LabelSettings" id="LabelSettings_nro64"]
font_size = 17
font_color = Color(1, 1, 1, 0.843137)
outline_color = Color(1, 1, 1, 0)
shadow_size = 0
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 0)
[sub_resource type="Resource" id="Resource_jn787"]
script = ExtResource("17_illef")
@ -639,13 +630,10 @@ entries = []
context = ""
metadata/_custom_type_script = "uid://bvj322mokkq63"
[sub_resource type="LabelSettings" id="LabelSettings_nro64"]
[sub_resource type="LabelSettings" id="LabelSettings_0e03u"]
font_size = 14
font_color = Color(0.2226, 0.710943, 0.914108, 1)
outline_color = Color(1, 1, 1, 0)
shadow_size = 0
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 0)
[sub_resource type="Resource" id="Resource_7rt2a"]
script = ExtResource("17_illef")
@ -654,21 +642,15 @@ entries = []
context = ""
metadata/_custom_type_script = "uid://bvj322mokkq63"
[sub_resource type="LabelSettings" id="LabelSettings_0e03u"]
font_size = 14
font_color = Color(0.289366, 0.771546, 0.496309, 1)
outline_color = Color(1, 1, 1, 0)
shadow_size = 0
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 0)
[sub_resource type="LabelSettings" id="LabelSettings_illef"]
font_size = 14
font_color = Color(0.914108, 0.8403, 0.2226, 1)
outline_color = Color(1, 1, 1, 0)
font_color = Color(0.289366, 0.771546, 0.496309, 1)
shadow_size = 0
[sub_resource type="LabelSettings" id="LabelSettings_qjby8"]
font_size = 14
font_color = Color(0.914108, 0.8403, 0.2226, 1)
shadow_size = 0
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 0)
[sub_resource type="Resource" id="Resource_qjby8"]
script = ExtResource("5_1tota")
@ -706,18 +688,18 @@ animationDuration = 0.0
animationOffset = 0.0
metadata/_custom_type_script = "uid://cnkyynboxg1qg"
[sub_resource type="ShaderMaterial" id="ShaderMaterial_qjby8"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ul0js"]
shader = ExtResource("7_aeebn")
shader_parameter/size = Vector2(34.5601, 34.56)
shader_parameter/size = Vector2(0, 0)
shader_parameter/sharpness = 5.0
shader_parameter/borderRadius = 3.46464
shader_parameter/strokeSize = 8.44128
shader_parameter/offset = 3.51648
shader_parameter/fillColor = Color(1, 1, 1, 1)
shader_parameter/borderRadius = 5.0
shader_parameter/strokeSize = 5.0
shader_parameter/offset = 0.0
shader_parameter/fillColor = Color(0, 0, 0, 1)
shader_parameter/fillUVTransform = Vector4(0, 0, 0, 0)
shader_parameter/screenfillMultiplyUVTransform = Vector4(0, 0, 0, 0)
shader_parameter/screenfillMultiplyUVMovement = Vector2(0, 0)
shader_parameter/strokeColor = Color(1, 1, 1, 1)
shader_parameter/strokeColor = Color(0, 0, 0, 1)
shader_parameter/strokeUVTransform = Vector4(0, 0, 0, 0)
shader_parameter/screenStrokeMultiplyUVTransform = Vector4(0, 0, 0, 0)
shader_parameter/screenStrokeMultiplyUVMovment = Vector2(0, 0)
@ -794,12 +776,7 @@ animationDuration = 0.0
animationOffset = 0.0
metadata/_custom_type_script = "uid://cnkyynboxg1qg"
[sub_resource type="LabelSettings" id="LabelSettings_ul0js"]
font_size = 26
outline_color = Color(1, 1, 1, 0)
shadow_size = 0
shadow_color = Color(0, 0, 0, 1)
shadow_offset = Vector2(0, 0)
[sub_resource type="LabelSettings" id="LabelSettings_hj653"]
[sub_resource type="Resource" id="Resource_btdid"]
script = ExtResource("5_1tota")
@ -882,9 +859,9 @@ nodeLink = NodePath("../Node Link")
[node name="Background" type="TextureRect" parent="."]
material = SubResource("ShaderMaterial_btdid")
layout_mode = 0
offset_right = 1156.56
offset_right = 1134.72
offset_bottom = 137.56
pivot_offset = Vector2(593.28, 68.78)
pivot_offset = Vector2(567.36, 68.78)
texture = SubResource("GradientTexture2D_dmcan")
expand_mode = 1
script = ExtResource("8_gyhi8")
@ -994,7 +971,7 @@ pivot_offset = Vector2(11, 7)
mouse_filter = 1
theme_override_fonts/font = ExtResource("15_nro64")
text = "INFO"
label_settings = SubResource("LabelSettings_qjby8")
label_settings = SubResource("LabelSettings_1jemv")
autowrap_mode = 2
script = ExtResource("16_0e03u")
locale = SubResource("Resource_jm3cb")
@ -1002,16 +979,17 @@ parentStyle = ExtResource("22_aeebn")
metadata/_custom_type_script = "uid://rqs2m0u6yvvf"
[node name="Time Stamp" type="Label" parent="."]
custom_minimum_size = Vector2(1, 0)
custom_minimum_size = Vector2(24, 0)
layout_mode = 0
offset_left = 69.0896
offset_top = 17.28
offset_right = 70.0896
offset_right = 93.0896
offset_bottom = 31.28
pivot_offset = Vector2(0.5, 7)
pivot_offset = Vector2(12, 7)
mouse_filter = 1
theme_override_fonts/font = ExtResource("15_nro64")
label_settings = SubResource("LabelSettings_1jemv")
text = "19:00"
label_settings = SubResource("LabelSettings_1hp7s")
autowrap_mode = 2
script = ExtResource("16_0e03u")
disableLocalization = true
@ -1029,7 +1007,7 @@ pivot_offset = Vector2(220.5, 13)
mouse_filter = 1
theme_override_fonts/font = ExtResource("15_nro64")
text = "Ein etwas anderer Text! Hello das ist eine Nachricht! Huhe!"
label_settings = SubResource("LabelSettings_1hp7s")
label_settings = SubResource("LabelSettings_nro64")
autowrap_mode = 2
script = ExtResource("16_0e03u")
locale = SubResource("Resource_jn787")
@ -1048,7 +1026,7 @@ mouse_filter = 1
mouse_default_cursor_shape = 2
theme_override_fonts/font = ExtResource("15_nro64")
text = "Node3D > Static Environment > SomeThing > MyNodes > SomeNode"
label_settings = SubResource("LabelSettings_nro64")
label_settings = SubResource("LabelSettings_0e03u")
autowrap_mode = 2
script = ExtResource("16_0e03u")
locale = SubResource("Resource_7rt2a")
@ -1074,7 +1052,7 @@ mouse_filter = 1
mouse_default_cursor_shape = 2
theme_override_fonts/font = ExtResource("15_nro64")
text = "Node3D > Static Environment > SomeThing > MyNodes > SomeNode"
label_settings = SubResource("LabelSettings_0e03u")
label_settings = SubResource("LabelSettings_illef")
autowrap_mode = 2
script = ExtResource("16_0e03u")
locale = SubResource("Resource_7rt2a")
@ -1100,7 +1078,7 @@ mouse_filter = 1
mouse_default_cursor_shape = 2
theme_override_fonts/font = ExtResource("15_nro64")
text = "Node3D > Static Environment > SomeThing > MyNodes > SomeNode"
label_settings = SubResource("LabelSettings_illef")
label_settings = SubResource("LabelSettings_qjby8")
autowrap_mode = 2
script = ExtResource("16_0e03u")
locale = SubResource("Resource_7rt2a")
@ -1131,7 +1109,7 @@ right = SubResource("Resource_v6jx4")
metadata/_custom_type_script = "uid://c2hicupu28nbi"
[node name="Info Icon2" type="TextureRect" parent="Close Button"]
material = SubResource("ShaderMaterial_qjby8")
material = SubResource("ShaderMaterial_ul0js")
layout_mode = 0
offset_right = 34.5601
offset_bottom = 34.56
@ -1157,8 +1135,7 @@ offset_right = 34.5601
offset_bottom = 32.721
mouse_filter = 1
theme_override_fonts/font = ExtResource("15_nro64")
text = "x"
label_settings = SubResource("LabelSettings_ul0js")
label_settings = SubResource("LabelSettings_hj653")
horizontal_alignment = 1
vertical_alignment = 1
autowrap_mode = 2

View File

@ -320,6 +320,7 @@ offset_bottom = 584.0
mouse_filter = 1
script = ExtResource("1_op0b4")
settings = ExtResource("2_iufyf")
updateMode = 1
useParentSize = true
X_computedFontSizePixels = 17.28
customDisposerIDs = PackedStringArray("ciOsgmckohhN3Ejw:Messages ▸ UI ▸ Scroller ▸ Vertical Scroller ▸ Button", "9ak1UYtRMpBsDldi:Messages ▸ UI ▸ Scroller")