using Godot; using System; using System.Collections.Generic; namespace Rokojori { [Tool] [GlobalClass] public partial class SceneFileReader:Node { [Export] public string path = ""; [Export] public bool load = false; [Export] public bool exportJSON = false; [Export] public bool exportHTML = false; public override void _Process( double delta ) { LoadScene(); } void LoadScene() { if ( ! load ) { return; } load = false; var text = FilesSync.LoadUTF8( path ); var parser = new SceneFileParser(); parser.Parse( text ); if ( exportJSON ) { FilesSync.SaveJSON( path + ".json", parser.sceneFile.GetSerializableJSONVersion() ); } if ( exportHTML ) { var nodes = parser.sceneFile.nodes; RJLog.Log( "Nodes:", nodes.Count ); var doc = new XMLDocument(); var html = doc.documentElement; var body = html.querySelector( HTMLElementName.body ); var head = html.querySelector( HTMLElementName.head ); head.AddHTMLScript( @" function main() { let elements = document.querySelectorAll( '.closeable' ); for ( let i = 0; i < elements.length; i++ ) { let element = elements[ i ]; element.addEventListener( 'click', ( ev )=> { let target = element.getAttribute( 'data-close-target' ); let targetElement = element; let parentRegex = /^\.\.\s/; while ( parentRegex.test( target ) ) { target = target.replace( parentRegex, '' ); targetElement = targetElement.parentElement; } let rootRegex = /^\.\.\.\s/; if ( rootRegex.test( target ) ) { target = target.replace( rootRegex, '' ); targetElement = document.documentElement; } let closeTarget = element.parentElement.querySelector( target ); console.log( ev, target, closeTarget); closeTarget.style.display = closeTarget.style.display === 'none' ? 'block' : 'none'; element.setAttribute( 'data-close-state', closeTarget.style.display ); ev.preventDefault(); return false; }, true ); } } window.addEventListener( 'load', () => { main(); }); " ); head.AddHTMLStyle( @" body { overflow-x: hidden; margin: 2em 0em; font-family: Helvetica, Arial, sans; background: hsl(0,0%,10%); color: hsl(0,0%,80%) } .closeable { cursor: pointer; opacity:1; transition: opacity 300ms ease; } .closeable[data-close-state='none'] { opacity: 0.7; } .node { display: block; position: relative; left: 2em; } gd-name { border-radius: 0.5em; padding: 1em 1em; background-color: hsl(0,0%,20%); margin: 0.5em 1em; display: inline-block; font-weight: bold; } gd-type { display: inline-block; opacity: 0.5; } " ); var elementMap = new Dictionary(); var GD_Node = XMLElementNodeName.Create( "gd-node" ); var GD_Name = XMLElementNodeName.Create( "gd-name" ); var GD_Type = XMLElementNodeName.Create( "gd-type" ); var GD_Children = XMLElementNodeName.Create( "gd-children" ); for ( int i = 0; i < nodes.Count; i++ ) { var node = nodes[ i ]; //RJLog.Log( i, node.name.value ); var attachmentElement = body; var elementPath = node.elementPath; var parent = node.parent.value; if ( parent != null && elementMap.ContainsKey( parent ) ) { attachmentElement = elementMap[ parent ].querySelector( GD_Children ); } var nodeElement = doc.Create( GD_Node ); nodeElement.SetAttribute( "class", "node" ); var nameElement = nodeElement.AddElement( GD_Name, node.name.value ); nameElement.SetAttribute( "class", "closeable" ); nameElement.SetAttribute( "data-close-target", ".. " + GD_Children.selector ); nodeElement.AddElement( GD_Type, node.type.value ); nodeElement.AddElement( GD_Children ); elementMap[ elementPath ] = nodeElement; // RJLog.Log( "'" + elementPath + "'", node.name.value ); attachmentElement.AppendChild( nodeElement ); } FilesSync.SaveUTF8( path + ".html", new XMLSerializer().SerializeHtml( doc.documentElement ) ); } } } }