12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739 |
- package hide;
- class IdeCache {
- public var getTextureCache : Map<String, h3d.mat.Texture> = [];
- public function new() {};
- }
- @:expose
- class Ide extends hide.tools.IdeData {
- public var initializing(default,null) : Bool;
- public var mouseX : Int = 0;
- public var mouseY : Int = 0;
- public var isWindows(get, never) : Bool;
- public var isFocused(get, never) : Bool;
- public var shaderLoader : hide.tools.ShaderLoader;
- public var isCDB = false;
- public var isDebugger = false;
- public var gamePad(default,null) : hxd.Pad;
- public var localStorage(get,never) : js.html.Storage;
- var window : nw.Window;
- var saveMenu : nw.Menu;
- var layout : golden.Layout;
- var currentLayout : { name : String, state : Config.LayoutState };
- var defaultLayout : { name : String, state : Config.LayoutState };
- var currentFullScreen(default,set) : hide.ui.View<Dynamic>;
- var maximized : Bool;
- var fullscreen : Bool;
- var updates : Array<Void->Void> = [];
- var views : Array<hide.ui.View<Dynamic>> = [];
- var lastClosedTabStates : Array<Dynamic> = [];
- var renderers : Array<h3d.mat.MaterialSetup>;
- var subView : { component : String, state : Dynamic, events : {} };
- var scripts : Map<String,Array<Void->Void>> = new Map();
- var hasReloaded = false;
- var hideRoot : hide.Element;
- var statusBar : hide.Element;
- var goldenContainer : hide.Element;
- var statusIcons : hide.Element;
- public var show3DIcons = true;
- public var show3DIconsCategory : Map<hrt.impl.EditorTools.IconCategory, Bool> = new Map();
- static var firstInit = true;
- var customMenus : Array<nw.MenuItem> = [];
- var filePickerElement : hide.Element;
- function new() {
- super();
- initPad();
- isCDB = Sys.getEnv("HIDE_START_CDB") == "1" || nw.App.manifest.name == "CDB";
- isDebugger = Sys.getEnv("HIDE_DEBUG") == "1";
- function wait() {
- if( monaco.ScriptEditor == null ) {
- haxe.Timer.delay(wait, 10);
- return;
- }
- startup();
- }
- wait();
- }
- function get_localStorage() {
- return js.Browser.window.localStorage;
- }
- override function getAppDataPath() {
- return nw.App.dataPath;
- }
- function initPad() {
- gamePad = hxd.Pad.createDummy();
- hxd.Pad.wait((p) -> gamePad = p);
- }
- function startup() {
- inst = this;
- window = nw.Window.get();
- var cwd = Sys.getCwd();
- initConfig(cwd);
- var current = ideConfig.currentProject;
- if( StringTools.endsWith(cwd,"package.nw") && sys.FileSystem.exists(cwd.substr(0,-10)+"res") )
- cwd = cwd.substr(0,-11);
- if( current == "" ) cwd;
- var args = js.Browser.document.URL.split("?")[1];
- if( args != null ) {
- var parts = args.split("&");
- var vars = new Map();
- for( p in parts ) {
- var p = p.split("=");
- vars.set(p[0],StringTools.urlDecode(p[1]));
- }
- var sub = vars.get("subView");
- if( sub != null ) {
- var obj = untyped global.sharedRefs.get(Std.parseInt(vars.get("sid")));
- subView = { component : sub, state : obj.state, events : obj.events };
- }
- }
- nw.Screen.Init();
- var xMax = 1;
- var yMax = 1;
- for( s in nw.Screen.screens ) {
- if( s.work_area.x + s.work_area.width > xMax )
- xMax = s.work_area.x + s.work_area.width;
- if( s.work_area.y + s.work_area.height > yMax )
- yMax = s.work_area.y + s.work_area.height;
- }
- if( subView == null ) {
- var wp = ideConfig.windowPos;
- if( wp != null ) {
- if( wp.w > 400 && wp.h > 300 )
- window.resizeBy(wp.w - Std.int(window.window.outerWidth), wp.h - Std.int(window.window.outerHeight));
- if( wp.x >= 0 && wp.y >= 0 && wp.x < xMax && wp.y < yMax)
- window.moveTo(wp.x, wp.y);
- if( wp.max ) {
- window.maximize();
- maximized = true;
- }
- }
- }
- window.show(true);
- if( config.global.get("hide") == null )
- error("Failed to load defaultProps.json");
- if( !sys.FileSystem.exists(current) || !sys.FileSystem.isDirectory(current) ) {
- if( current != "" ) js.Browser.alert(current+" no longer exists");
- current = cwd;
- }
- setProject(current);
- loadProject();
- window.window.document.addEventListener("mousedown", function(e) {
- mouseX = e.x;
- mouseY = e.y;
- });
- window.window.document.addEventListener("mousemove", function(e) {
- mouseX = e.x;
- mouseY = e.y;
- });
- window.on('maximize', function() {
- if(fullscreen) return;
- maximized = true;
- onWindowChange();
- });
- window.on('restore', function() {
- if(fullscreen) return;
- maximized = false;
- onWindowChange();
- });
- window.on('move', function() haxe.Timer.delay(onWindowChange,100));
- window.on('resize', function() haxe.Timer.delay(onWindowChange,100));
- window.on('close', function() {
- if( hasReloaded ) return;
- if( !isDebugger )
- for( v in views )
- if( !v.onBeforeClose() )
- return;
- window.close(true);
- });
- window.on("blur", function() { if( h3d.Engine.getCurrent() != null && !hasReloaded ) hxd.Key.initialize(); });
- // handle commandline parameters
- nw.App.on("open", function(cmd) {
- if( hasReloaded ) return;
- ~/"([^"]+)"/g.map(cmd, function(r) {
- var file = r.matched(1);
- if( sys.FileSystem.exists(file) ) openFile(file);
- return "";
- });
- });
- var body = window.window.document.body;
- window.on("focus", function() {
- // handle cancel on type=file
- if (filePickerElement != null && filePickerElement.data("allownull") != null) {
- haxe.Timer.delay(() -> {
- if (filePickerElement != null) {
- filePickerElement.change();
- }
- }, 100);
- }
- if(fileExists(databaseFile) && getFileText(databaseFile) != lastDBContent) {
- if(js.Browser.window.confirm(databaseFile + " has changed outside of Hide. Do you want to reload?")) {
- loadDatabase(true);
- hide.comp.cdb.Editor.refreshAll(true);
- };
- }
- });
- function dragFunc(drop : Bool, e:js.html.DragEvent) {
- syncMousePosition(e);
- var view = getViewAt(mouseX, mouseY);
- var items : Array<String> = [for(f in e.dataTransfer.files) Reflect.field(f, "path")];
- if(view != null && view.onDragDrop(items, drop, e)) {
- e.preventDefault();
- e.stopPropagation();
- return true;
- }
- return false;
- }
- body.ondragover = function(e:js.html.DragEvent) {
- dragFunc(false, e);
- return false;
- };
- body.ondrop = function(e:js.html.DragEvent) {
- if(!dragFunc(true, e)) {
- for( f in e.dataTransfer.files )
- openFile(Reflect.field(f,"path"));
- e.preventDefault();
- }
- return false;
- }
- if( subView != null ) body.className +=" hide-subview";
- // Listen to FileTree dnd
- function treeDragFun(data,drop, event) {
- var nodeIds : Array<String> = cast data.data.nodes;
- if(data.data.jstree == null) return false;
- for( ft in getViews(hide.view.FileTree) ) {
- var paths = [];
- @:privateAccess {
- if (ft.tree == null || data.data.origin == null) continue;
- if(ft.tree.element[0] != data.data.origin.element[0]) continue;
- for(id in nodeIds) {
- var item = ft.tree.map.get(id);
- if(item != null)
- paths.push(item.value);
- }
- }
- if(paths.length == 0)
- continue;
- var view = getViewAt(mouseX, mouseY);
- if(view != null)
- return view.onDragDrop(paths, drop, event);
- }
- return false;
- }
- new Element(window.window.document).on("dnd_move.vakata.jstree", function(e, data:Dynamic) {
- var el = (data.helper:hide.Element);
- var drag = treeDragFun(data,false,data.event.originalEvent);
- var icon = el.find(new Element(".jstree-icon"));
- el.css(drag ? { filter : "brightness(120%)", opacity : 1 } : { filter : "", opacity : 0.5 });
- icon.toggleClass("jstree-er", !drag);
- icon.toggleClass("jstree-ok", drag);
- });
- new Element(window.window.document).on("dnd_stop.vakata.jstree", function(e, data:Dynamic) {
- treeDragFun(data,true, data.event.originalEvent);
- });
- // dispatch global keys based on mouse position
- new Element(body).keydown(function(e) {
- var view = getViewAt(mouseX, mouseY);
- if(view != null) view.processKeyEvent(e);
- });
- hrt.impl.EditorTools.setupIconCategories();
- refreshFont();
- }
- public function getViews<K,T:hide.ui.View<K>>( cl : Class<T> ) {
- return [for( v in views ) { var t = Std.downcast(v,cl); if( t != null ) t; }];
- }
- function getViewAt(x : Float, y : Float) {
- var pickedEl = js.Browser.document.elementFromPoint(x, y);
- for( v in views ) {
- var viewEl = v.element[0];
- var el = pickedEl;
- while(el != null) {
- if(el == viewEl) return v;
- el = el.parentElement;
- }
- }
- return null;
- }
- function syncMousePosition(e:js.html.MouseEvent) {
- mouseX = e.clientX;
- mouseY = e.clientY;
- for( c in new Element("canvas") ) {
- var s : hide.comp.Scene = (c:Dynamic).__scene;
- if( s != null ) @:privateAccess {
- if (s.window != null) {
- s.window.curMouseX = mouseX;
- s.window.curMouseY = mouseY;
- }
- }
- }
- }
- function get_isWindows() {
- return Sys.systemName() == "Windows";
- }
- function get_isFocused() {
- return js.Browser.document.hasFocus();
- }
- public function focus() {
- window.focus();
- }
- public function blur() {
- window.blur();
- }
- function onWindowChange() {
- if( hasReloaded )
- return;
- if( ideConfig.windowPos == null ) ideConfig.windowPos = { x : 0, y : 0, w : 0, h : 0, max : false };
- ideConfig.windowPos.max = maximized;
- if( !maximized ) {
- ideConfig.windowPos.x = window.x;
- ideConfig.windowPos.y = window.y;
- ideConfig.windowPos.w = Std.int(window.window.outerWidth);
- ideConfig.windowPos.h = Std.int(window.window.outerHeight);
- }
- if( subView == null )
- config.global.save();
- for (v in views)
- v.onResize();
- }
- function initLayout( ?state : { name : String, state : Config.LayoutState } ) {
- initializing = true;
- if( layout != null ) {
- layout.destroy();
- layout = null;
- }
- defaultLayout = null;
- var layoutName = isCDB ? "CDB" : "Default";
- var emptyLayout : Config.LayoutState = { content : [], fullScreen : null };
- for( p in projectConfig.layouts )
- if( p.name == layoutName ) {
- if( p.state.content == null ) continue; // old version
- defaultLayout = p;
- break;
- }
- if( defaultLayout == null ) {
- defaultLayout = { name : layoutName, state : emptyLayout };
- projectConfig.layouts.push(defaultLayout);
- config.current.sync();
- config.user.save();
- }
- if( state == null )
- state = defaultLayout;
- if( subView != null )
- state = { name : "SubView", state : emptyLayout };
- this.currentLayout = state;
- var config : golden.Config = {
- content: state.state.content,
- settings: {
- // Default to false
- reorderEnabled : config.user.get('layout.reorderEnabled', true) == true,
- constrainDragToHeader : config.user.get('layout.constrainDragToHeader', true) == true,
- showPopoutIcon : config.user.get('layout.showPopoutIcon') == true,
- showMaximiseIcon : config.user.get('layout.showMaximiseIcon') == true
- }
- };
- var comps = new Map();
- for( vcl in hide.ui.View.viewClasses )
- comps.set(vcl.name, true);
- function checkRec(i:golden.Config.ItemConfig) {
- if( i.componentName != null && !comps.exists(i.componentName) ) {
- i.componentState.deletedComponent = i.componentName;
- i.componentName = "hide.view.Unknown";
- }
- if( i.content != null ) for( i in i.content ) checkRec(i);
- }
- for( i in config.content ) checkRec(i);
- if (hideRoot != null) {
- hideRoot.remove();
- hideRoot = null;
- }
- hideRoot = new Element('<div class="hide-root"></div>').appendTo(new Element("body"));
- goldenContainer = new Element('<div class="golden-layout-root"></div>').appendTo(hideRoot);
- statusBar = new Element('<div class="status-bar"></div>').appendTo(hideRoot);
- statusIcons = new Element('<div id="status-icons"></div>').appendTo(statusBar);
- var commitHash = getGitCommitHashAndDate();
- if (commitHash.length > 0) {
- new Element('<span class="build">hide $commitHash</span>').appendTo(statusBar);
- }
- layout = new golden.Layout(config, goldenContainer.get(0));
- var resizeTimer : haxe.Timer = null;
- var observer = new hide.comp.ResizeObserver((elts, observer) -> {
- if (resizeTimer != null) {
- resizeTimer.stop();
- }
- resizeTimer = new haxe.Timer(20);
- resizeTimer.run = () -> {
- var rect = goldenContainer.get(0).getBoundingClientRect();
- layout.updateSize(Std.int(rect.width), Std.int(rect.height));
- resizeTimer.stop();
- resizeTimer = null;
- };
- });
- observer.observe(goldenContainer.get(0));
- var initViews = [];
- function initView(view:hide.ui.View<Dynamic>) {
- if( isDebugger ) view.rebuild() else try view.rebuild() catch( e : Dynamic ) error(view+":"+e);
- }
- for( vcl in hide.ui.View.viewClasses )
- layout.registerComponent(vcl.name,function(cont,state) {
- var view = Type.createInstance(vcl.cl,[state]);
- view.setContainer(cont);
- if( initializing )
- initViews.push(view);
- else
- initView(view);
- });
- layout.init();
- layout.on('stateChanged', onLayoutChanged);
- var waitCount = 0;
- function waitInit() {
- waitCount++;
- if( !layout.isInitialised ) {
- if( waitCount > 20 ) {
- // timeout : error recovery if invalid component
- state.state = emptyLayout;
- initLayout();
- return;
- }
- haxe.Timer.delay(waitInit, 50);
- return;
- }
- if( state.state.fullScreen != null ) {
- var fs = state.state.fullScreen;
- var found = [for( v in views ) if( v.viewClass == fs.name ) v];
- if( found.length == 1 )
- found[0].fullScreen = true;
- else {
- for( f in found )
- if( haxe.Json.stringify(f.state) == haxe.Json.stringify(fs.state) ) {
- f.fullScreen = true;
- break;
- }
- }
- }
- initializing = false;
- for( v in initViews )
- initView(v);
- initViews = null;
- if( subView == null && views.length == 0 ) {
- if( isCDB )
- open("hide.view.CdbTable",{}, function(v) v.fullScreen = true);
- else
- open("hide.view.FileTree",{path:""});
- }
- if( firstInit ) {
- firstInit = false;
- for( file in nw.App.argv ) {
- if( !sys.FileSystem.exists(file) ) continue;
- openFile(file);
- }
- if( subView != null )
- open(subView.component, subView.state);
- }
- };
- waitInit();
- hxd.System.setLoop(mainLoop);
- }
- function mainLoop() {
- hxd.Timer.update();
- @:privateAccess hxd.Pad.syncPads();
- for( f in updates )
- f();
- }
- public function setFullscreen(b : Bool) {
- if (b) {
- fullscreen = true;
- window.maximize();
- saveMenu = window.menu;
- window.menu = null;
- window.enterFullscreen();
- } else {
- window.menu = saveMenu;
- window.leaveFullscreen();
- // NWJS bug: changing fullscreen triggers spurious "restore" events
- haxe.Timer.delay(function() {
- fullscreen = false;
- if(maximized)
- window.maximize();
- }, 150);
- }
- }
- function set_currentFullScreen(v) {
- var old = currentFullScreen;
- currentFullScreen = v;
- if( old != null ) old.fullScreen = false;
- onLayoutChanged();
- return v;
- }
- function onLayoutChanged() {
- if( initializing || !ideConfig.autoSaveLayout || isCDB )
- return;
- defaultLayout.state = saveLayout();
- if( subView == null ) this.config.user.save();
- }
- function saveLayout() : Config.LayoutState {
- return {
- content : layout.toConfig().content,
- fullScreen : currentFullScreen == null ? null : { name : currentFullScreen.viewClass, state : currentFullScreen.state }
- };
- }
- public function setClipboard( data : String, type: nw.Clipboard.ClipboardType = Text ) {
- nw.Clipboard.get().set([{data: data, type: type }]);
- }
- public function setClipboardMultiple( datas: Array<nw.Clipboard.ClipboardData> ) {
- nw.Clipboard.get().set(datas);
- }
- public function getClipboard(type: nw.Clipboard.ClipboardType = Text) {
- return nw.Clipboard.get().get(type);
- }
- public function registerUpdate( updateFun ) {
- updates.push(updateFun);
- }
- public function unregisterUpdate( updateFun ) {
- for( u in updates )
- if( Reflect.compareMethods(u,updateFun) ) {
- updates.remove(u);
- return true;
- }
- return false;
- }
- public function makeSignature( content : String ) {
- var sign = js.node.Crypto.createHash(js.node.Crypto.CryptoAlgorithm.MD5);
- return sign.update(content).digest("base64");
- }
- public function cleanObject( v : Dynamic ) {
- for( f in Reflect.fields(v) )
- if( Reflect.field(v, f) == null )
- Reflect.deleteField(v, f);
- }
- static var textureCacheKey = "TextureCache";
- public function getHideResPath(basePath:String) {
- return getPath("${HIDE}/res/" + basePath);
- }
- // Get a texture from a file on disk. Cache the results
- public function getTexture(fullPath:String) {
- if (fullPath == null)
- return null;
- var engine = h3d.Engine.getCurrent();
- var cache : IdeCache = cast @:privateAccess engine.resCache.get(IdeCache);
- if(cache == null) {
- cache = new IdeCache();
- @:privateAccess engine.resCache.set(IdeCache, cache);
- }
- var texCache = cache.getTextureCache;
- var tex = texCache[fullPath];
- if (tex != null)
- return tex;
- var data = sys.io.File.getBytes(fullPath);
- var res = hxd.res.Any.fromBytes(fullPath, data);
- tex = res.toImage().toTexture();
- texCache.set(fullPath, tex);
- return tex;
- }
- var showErrors = true;
- var errorWindow :Element = null;
- override function error( e : Dynamic ) {
- if( showErrors ) {
- onIdeError(e);
- if( !js.Browser.window.confirm(e) )
- showErrors = false;
- }
- if (!showErrors) {
- if (errorWindow == null) {
- statusBar.toggleClass("error");
- errorWindow = new Element('<div class="error-suppressed">
- <button class="reload"><i class="icon ico ico-refresh"></i>Reload</button>
- <span>Errors are currently suppressed in the editor. Please save your work and reload.</span>
- </div>
- ');
- errorWindow.insertAfter(statusIcons);
- var btnSaveReload = errorWindow.find(".reload");
- btnSaveReload.click(function(_) {
- this.reload();
- });
- }
- }
- js.Browser.console.error(e);
- }
- public function quickError( msg : Dynamic, timeoutSeconds : Float = 5.0 ) {
- var str = StringTools.htmlEscape(Std.string(msg));
- str = StringTools.replace(str, "\n", "<br/>");
- var e = new Element('
- <div class="message error">
- <div class="icon ico ico-warning"></div>
- <div class="text">${str}</div>
- </div>');
- js.Browser.console.error(msg);
- globalMessage(e, timeoutSeconds);
- }
- function loadProject() {
- var dir = ideConfig.currentProject;
- setProgress();
- shaderLoader = new hide.tools.ShaderLoader();
- hxsl.Cache.clear();
- var localDir = sys.FileSystem.exists(resourceDir) ? resourceDir : projectDir;
- var fsconf = config.current.get("fs.config", "default");
- hxd.res.Loader.currentInstance = new CustomLoader(new hxd.fs.LocalFileSystem(localDir,fsconf));
- hxd.res.Image.ASYNC_LOADER = new hxd.impl.AsyncLoader.NodeLoader();
- renderers = [
- new hide.Renderer.MaterialSetup("Default"),
- new hide.Renderer.PbrSetup("PBR"),
- ];
- var plugins : Array<String> = config.current.get("plugins");
- for ( plugin in plugins )
- loadPlugin(plugin, function() {});
- loadDatabase();
- if( config.project.get("debug.displayErrors") ) {
- js.Browser.window.onerror = function(msg, url, line, col, error) {
- if( error == null ) return true; // some internal chrome errors are only a msg, skip
- var e = error.stack;
- e = ~/\(?chrome-extension:\/\/[a-z0-9\-\.\/]+.js:[0-9]+:[0-9]+\)?/g.replace(e,"");
- e = ~/at ([A-Za-z0-9_\.\$]+)/g.map(e,function(r) { var path = r.matched(1); path = path.split("$hx_exports.").pop().split("$hxClasses.").pop(); return path; });
- e = e.split("\t").join(" ");
- this.error(e);
- return true;
- };
- } else
- Reflect.deleteField(js.Browser.window, "onerror");
- waitScripts(function() {
- var extraRenderers = config.current.get("renderers");
- for( name in Reflect.fields(extraRenderers) ) {
- var clName = Reflect.field(extraRenderers, name);
- var cl = try js.Lib.eval(clName) catch( e : Dynamic ) null;
- if( cl == null ) {
- error(clName+" could not be found");
- return;
- }
- renderers.push(Type.createInstance(cl,[]));
- }
- var render = renderers[0];
- if( projectConfig.renderer == null )
- projectConfig.renderer = config.current.get("defaultRenderer");
- for( r in renderers ) {
- var name = r.displayName == null ? r.name : r.displayName;
- if( name == projectConfig.renderer ) {
- render = r;
- break;
- }
- }
- h3d.mat.MaterialSetup.current = render;
- initMenu();
- initLayout();
- });
- }
- function waitScripts( f : Void -> Void ) {
- if( !isScriptLoading() ) {
- f();
- return;
- }
- var wait = scripts.get("");
- if( wait == null ) {
- wait = [];
- scripts.set("",wait);
- }
- wait.push(f);
- }
- function isScriptLoading() {
- for( s in scripts.keys() )
- if( s != "" && scripts.get(s).length > 0 )
- return true;
- return false;
- }
- public function injectCss(data: String) {
- var head = new Element("head");
- var style = new Element("<style>").appendTo(head);
- style.text(data);
- }
- function loadPlugin( file : String, callb : Void -> Void, ?forceType : String ) {
- file = getPath(file);
- var wait = scripts.get(file);
- if( wait != null ) {
- if( wait.length == 0 )
- callb();
- else
- wait.push(callb);
- return;
- }
- wait = [callb];
- scripts.set(file, wait);
- function onLoad() {
- scripts.set(file, []);
- for( w in wait )
- w();
- if( !isScriptLoading() ) {
- wait = scripts.get("");
- scripts.set("",[]);
- for( w in wait ) w();
- }
- }
- function onError() {
- error("Error while loading "+file);
- }
- var type = forceType == null ? haxe.io.Path.extension(file).toLowerCase() : forceType;
- switch ( type ) {
- case "js":
- var e = js.Browser.document.createScriptElement();
- e.addEventListener("load", onLoad);
- e.addEventListener("error", onError);
- e.async = false;
- e.type = "text/javascript";
- e.src = "file://"+file.split("\\").join("/");
- js.Browser.document.body.appendChild(e);
- fileWatcher.register(file,reload);
- case "css":
- var e = js.Browser.document.createLinkElement();
- e.addEventListener("load", onLoad);
- e.addEventListener("error", onError);
- e.rel = "stylesheet";
- e.type = "text/css";
- e.href = "file://" + file.split("\\").join("/");
- js.Browser.document.body.appendChild(e);
- fileWatcher.register(file, () -> reloadCss());
- default: error('Unknown plugin type $type for file $file');
- }
- }
- inline function loadScript( file : String, callb : Void -> Void ) {
- loadPlugin(file, callb);
- }
- public function reload() {
- hasReloaded = true;
- fileWatcher.dispose();
- hide.view.RemoteConsoleView.onBeforeReload();
- js.Browser.location.reload();
- }
- public function reloadCss(path: String = null) {
- var css = new js.jquery.JQuery('link[type="text/css"]');
- css.each(function(i, e) : Void {
- var link : js.html.LinkElement = cast e;
- if (path == null || StringTools.contains(link.href, path)) {
- link.href = link.href + "?" + haxe.Timer.stamp();
- }
- });
- }
- public function getCDBContent<T>( sheetName : String ) : Array<T> {
- for( s in database.sheets )
- if( s.name == sheetName ) {
- var s = Reflect.copy(@:privateAccess s.realSheet.sheet);
- s.lines = [for( l in s.lines ) Reflect.copy(l)];
- @:privateAccess cdb.Types.Index.initLines(s);
- return cast s.lines;
- }
- return null;
- }
- public function getUnCachedUrl( path : String ) {
- return "file://" + getPath(path) + "?t=" + fileWatcher.getVersion(path);
- }
- public static var IMG_EXTS = ["jpg", "jpeg", "gif", "png", "raw", "dds", "hdr", "tga"];
- public function chooseImage( onSelect, allowNull=false ) {
- chooseFile(IMG_EXTS, onSelect, allowNull);
- }
- public function chooseFileOptions(onSelect: Null<Array<String>> -> Void, options: {
- ?exts : Array<String>,
- ?workingDir: String,
- ?onlyDirectory: Bool,
- ?saveAs: String,
- ?isAbsolute: Bool,
- ?allowNull: Bool,
- ?multiple: Bool,
- } = null) {
- options = options ?? {};
- function callback() {
- if (filePickerElement != null)
- filePickerElement.remove();
- var args : Array<String> = [];
- if (options.allowNull == true)
- args.push("data-allownull='true'");
- if (options.saveAs != null)
- args.push('nwsaveas="${options.saveAs}"');
- if (options.exts != null)
- args.push('accept="${[for( e in options.exts ) "."+e].join(",")}"');
- if (options.onlyDirectory == true)
- args.push("nwdirectory");
- if (options.multiple == true)
- args.push('multiple="multiple"');
- if (options.workingDir != null && options.workingDir != "#MISSING") {
- var pathArray = getPath(options.workingDir).split("/");
- var c = isWindows ? "\\" : "/";
- var workingDirPath = pathArray.join(c);
- args.push('nwworkingdir="$workingDirPath"');
- }
- var argsString = args.join(" ");
- var buildString = '<input type="file" style="visibility:hidden; position:fixed; top:0px;" value="" $argsString/>';
- filePickerElement = new Element(buildString).appendTo(window.window.document.body);
- filePickerElement.change(function(_) {
- var file = filePickerElement.val();
- filePickerElement.remove();
- filePickerElement = null;
- if( file == "" && !options.allowNull ) return;
- if (file == "") {
- onSelect(null);
- } else {
- var files = file.split(";");
- if (options.isAbsolute != true) {
- for (i => file in files) {
- files[i] = makeRelative(file);
- }
- }
- onSelect(files);
- }
- });
- filePickerElement.click();
- }
- if (options.allowNull) {
- haxe.Timer.delay(callback, 100);
- }
- else {
- callback();
- }
- }
- /**
- Adds an element to the ide status bar
- **/
- public function addStatusIcon(e: hide.Element) {
- function wait() {
- if( statusIcons == null ) {
- haxe.Timer.delay(wait, 10);
- return;
- }
- var wrapper = new hide.Element('<div class="statusbar-icon"></div>').appendTo(statusIcons);
- wrapper.append(e);
- }
- wait();
- }
- public function chooseFiles( exts : Array<String>, onSelect : Array<String> -> Void, allowNull=false ) {
- chooseFileOptions(onSelect, {exts: exts, allowNull: allowNull, multiple: true});
- }
- public function chooseFile( exts : Array<String>, onSelect : Null<String> -> Void, allowNull = false, workingdir:String = null) {
- chooseFileOptions((files) -> onSelect(files != null ? files.pop() : null), {exts: exts, allowNull: allowNull, workingDir: workingdir});
- }
- public function chooseFileSave( defaultPath : String, onSelect : String -> Void, allowNull=false ) {
- chooseFileOptions((files) -> onSelect(files != null ? files.pop() : null),{saveAs: defaultPath,allowNull: allowNull,});
- }
- public function chooseDirectory( onSelect : String -> Void, ?isAbsolute = false, allowNull=false ) {
- chooseFileOptions((files) -> onSelect(files != null ? files.pop() : null),{isAbsolute: isAbsolute,onlyDirectory: true,allowNull: allowNull,});
- }
- public function findPathRefs(path: String) {
- var refs : Array<{str: String, ?goto: () -> Void}> = [];
- function filter(ctx: FilterPathContext) {
- if (ctx.valueCurrent == path) {
- refs.push(ctx.getRef());
- }
- }
- filterPaths(filter);
- open("hide.view.RefViewer", null, null, function(view) {
- var refViewer : hide.view.RefViewer = cast view;
- refViewer.showRefs(refs, 'Number of references to "$path"');
- });
- }
- /**
- Iterate throught all the strings in the project that could contain a path, replacing
- the value by what `callb` returns. The callb must call `changed()` if it changed the path.
- **/
- public function filterPaths(callb: (ctx : FilterPathContext) -> Void) {
- var context = new FilterPathContext(callb);
- var adaptedFilter = function(obj: String) {
- return context.filter(obj);
- }
- function filterContent(content:Dynamic) {
- var visited = new Map<Dynamic, Bool>();
- function browseRec(obj:Dynamic) : Dynamic {
- switch( Type.typeof(obj) ) {
- case TObject:
- if( visited.exists(obj)) return null;
- visited.set(obj, true);
- for( f in Reflect.fields(obj) ) {
- var v : Dynamic = Reflect.field(obj, f);
- v = browseRec(v);
- if( v != null ) Reflect.setField(obj, f, v);
- }
- case TClass(Array):
- if( visited.exists(obj)) return null;
- visited.set(obj, true);
- var arr : Array<Dynamic> = obj;
- for( i in 0...arr.length ) {
- var v : Dynamic = arr[i];
- v = browseRec(v);
- if( v != null ) arr[i] = v;
- }
- case TClass(String):
- return context.filter(obj);
- default:
- }
- return null;
- }
- for( f in Reflect.fields(content) ) {
- if (f == "children")
- continue;
- var v = browseRec(Reflect.field(content,f));
- if( v != null ) Reflect.setField(content,f,v);
- }
- }
- {
- var currentPath : String = null;
- var currentPrefab: hrt.prefab.Prefab = null;
- context.getRef = () -> {
- var p = currentPath; // needed capture
- var cp = currentPrefab; // needed capture
- return {str: '$p:${cp.getAbsPath()}', goto: () -> openFile(getPath(p), null, (view) -> {
- var pref = Std.downcast(view, hide.view.Prefab);
- if (pref != null) {
- pref.delaySceneEditor(() -> {
- pref.sceneEditor.selectElementsIndirect([cp]);
- });
- }
- else {
- var fx = Std.downcast(view, hide.view.FXEditor);
- fx.delaySceneEditor(() -> {
- @:privateAccess fx.sceneEditor.selectElementsIndirect([cp]);
- });
- }
- })};
- };
- filterPrefabs(function(p:hrt.prefab.Prefab, path: String) {
- context.changed = false;
- currentPath = path;
- currentPrefab = p;
- p.source = context.filter(p.source);
- var h = p.getHideProps();
- if( h.onResourceRenamed != null )
- h.onResourceRenamed(adaptedFilter);
- else {
- filterContent(p);
- }
- return context.changed;
- });
- }
- {
- var currentPath : String = null;
- context.getRef = () -> {
- var p = currentPath;
- return {str: p, goto : Ide.showFileInExplorer.bind(getPath(p))};
- }
- filterProps(function(content:Dynamic, path: String) {
- context.changed = false;
- currentPath = path;
- filterContent(content);
- return context.changed;
- });
- }
- context.changed = false;
- var tmpSheets = [];
- var currentSheet : cdb.Sheet = null;
- var currentColumn : String = null;
- var currentObject : Dynamic = null;
- context.getRef = () -> {
- var cs = currentSheet;
- var cc = currentColumn;
- var sheets = cdb.Sheet.getSheetPath(cs, cc);
- var path = hide.comp.cdb.Editor.splitPath({s: sheets, o: currentObject});
- return {str: sheets[0].s.name+"."+path.pathNames.join("."), goto: hide.comp.cdb.Editor.openReference2.bind(sheets[0].s, path.pathParts)};
- };
- for( sheet in database.sheets ) {
- if( sheet.props.dataFiles != null && sheet.lines == null ) {
- // we already updated prefabs, no need to load data files
- tmpSheets.push(sheet);
- @:privateAccess sheet.sheet.lines = [];
- }
- for( c in sheet.columns ) {
- switch( c.type ) {
- case TFile:
- var sheets = cdb.Sheet.getSheetPath(sheet, c.name);
- for( obj in sheet.getObjects() ) {
- currentSheet = sheet;
- currentColumn = c.name;
- currentObject = obj;
- var path = Reflect.field(obj.path[obj.path.length - 1], c.name);
- var v : Dynamic = context.filter(path);
- if( v != null ) Reflect.setField(obj.path[obj.path.length - 1], c.name, v);
- }
- case TTilePos:
- var sheets = cdb.Sheet.getSheetPath(sheet, c.name);
- for( obj in sheet.getObjects() ) {
- currentSheet = sheet;
- currentColumn = c.name;
- currentObject = obj;
- var tilePos : cdb.Types.TilePos = Reflect.field(obj.path[obj.path.length - 1], c.name);
- if (tilePos != null) {
- var v : Dynamic = context.filter(tilePos.file);
- if (v != null) Reflect.setField(tilePos, 'file', v);
- }
- }
- default:
- }
- }
- }
- if( context.changed ) {
- saveDatabase();
- hide.comp.cdb.Editor.refreshAll(true);
- }
- for( sheet in tmpSheets )
- @:privateAccess sheet.sheet.lines = null;
- for (customFilter in customFilepathRefFilters) {
- customFilter(context);
- }
- }
- public var customFilepathRefFilters : Array<(ctx : FilterPathContext) -> Void> = [];
- public function refreshFont() {
- var font = ideConfig.useAlternateFont ? "Verdana" : "Inter";
- var size = ideConfig.useAlternateFont ? "9pt" : "9.5pt";
- js.Browser.document.documentElement.style.setProperty("--default-font", font);
- js.Browser.document.documentElement.style.setProperty("--default-font-size", size);
- }
- public function filterPrefabs( callb : (hrt.prefab.Prefab, path: String) -> Bool) {
- var exts = Lambda.array({iterator : @:privateAccess hrt.prefab.Prefab.extensionRegistry.keys });
- exts.push("prefab");
- var todo = [];
- browseFiles(function(path) {
- var ext = path.split(".").pop();
- if( exts.indexOf(ext) < 0 ) return;
- var prefab = loadPrefab(path);
- var changed = false;
- function filterRec(p) {
- if( callb(p, path) ) changed = true;
- for( ps in p.children )
- filterRec(ps);
- }
- filterRec(prefab);
- if( !changed ) return;
- @:privateAccess todo.push(function() sys.io.File.saveContent(getPath(path), toJSON(prefab.serialize())));
- });
- for( t in todo )
- t();
- }
- public function filterProps( callb : (data: Dynamic, path: String) -> Bool ) {
- var exts = ["props", "json"];
- var todo = [];
- browseFiles(function(path) {
- var ext = path.split(".").pop();
- if( exts.indexOf(ext) < 0 ) return;
- try {
- var content = parseJSON(sys.io.File.getContent(getPath(path)));
- var changed = callb(content, path);
- if( !changed ) return;
- todo.push(function() sys.io.File.saveContent(getPath(path), toJSON(content)));
- } catch (e) {};
- });
- for( t in todo )
- t();
- }
- function browseFiles( callb : String -> Void ) {
- function browseRec(path) {
- if( path == ".tmp" ) return;
- for( p in sys.FileSystem.readDirectory(resourceDir + "/" + path) ) {
- var p = path == "" ? p : path + "/" + p;
- if( sys.FileSystem.isDirectory(resourceDir+"/"+p) ) {
- browseRec(p);
- continue;
- }
- callb(p);
- }
- }
- browseRec("");
- }
- public function setProgress( ?text : String ) {
- if( text != null ) {
- window.title = text;
- return;
- }
- var title = config.current.get("hide.windowTitle");
- window.title = title != null ? title : ((isCDB ? "CastleDB" : "HIDE") + " - " + projectDir);
- }
- public function runCommand(cmd, ?callb:String->Void) {
- var c = cmd.split("%PROJECTDIR%").join(projectDir);
- var slash = isWindows ? "\\" : "/";
- c = c.split("/").join(slash);
- js.node.ChildProcess.exec(c, function(e:js.node.ChildProcess.ChildProcessExecError,_,_) callb(e == null ? null : e.message));
- }
- public function addCustomMenu(item: nw.MenuItem) {
- customMenus.push(item);
- }
- public function initMenu() {
- if( subView != null ) return;
- var menuHTML = "<content>"+new Element("#mainmenu").html() + config.project.get("menu.extra")+"</content>";
- var menu = new Element(menuHTML);
- // project
- if( ideConfig.recentProjects.length > 0 )
- menu.find(".project .recents").html("");
- for( v in ideConfig.recentProjects.copy() ) {
- if( !sys.FileSystem.exists(v) ) {
- ideConfig.recentProjects.remove(v);
- config.global.save();
- continue;
- }
- new Element("<menu>").attr("label",v).appendTo(menu.find(".project .recents")).click(function(_){
- var dir = v;
- setProject(dir);
- reload(); // Reload stylesheets
- });
- }
- menu.find(".project .open").click(function(_) {
- chooseDirectory(function(dir) {
- if( dir == null ) return;
- if( StringTools.endsWith(dir,"/res") || StringTools.endsWith(dir,"\\res") )
- dir = dir.substr(0,-4);
- setProject(dir);
- reload();
- }, true);
- });
- menu.find(".project .clear").click(function(_) {
- ideConfig.recentProjects = [];
- config.global.save();
- initMenu();
- });
- menu.find(".project .exit").click(function(_) {
- Sys.exit(0);
- });
- menu.find(".project .clear-local").click(function(_) {
- js.Browser.window.localStorage.clear();
- nw.App.clearCache();
- try sys.FileSystem.deleteFile(Ide.inst.appPath + "/props.json") catch( e : Dynamic ) {};
- untyped chrome.runtime.reload();
- });
- menu.find(".build-files").click(function(_) {
- hrt.impl.BuildTools.buildAllFiles(resourceDir + "/", function(percent, currentFile) {
- setProgress('($percent%) $currentFile');
- }, function(msg) {
- error(msg);
- }, function(count, errCount) {
- setProgress();
- });
- });
- for( r in renderers ) {
- var name = r.displayName != null ? r.displayName : r.name;
- new Element("<menu type='checkbox'>").attr("label", name).prop("checked",r == h3d.mat.MaterialSetup.current).appendTo(menu.find(".project .renderers")).click(function(_) {
- if( r != h3d.mat.MaterialSetup.current ) {
- projectConfig.renderer = name;
- config.user.save();
- reload();
- }
- });
- }
- // view
- if( !sys.FileSystem.exists(resourceDir) )
- menu.find(".view").remove();
- menu.find(".debug").click(function(_) window.showDevTools());
- var comps = menu.find("[component]");
- for( c in comps.elements() ) {
- var cname = c.attr("component");
- var cl = Type.resolveClass(cname);
- if( cl == null ) error("Missing component class "+cname);
- var state = c.attr("state");
- if( state != null ) try haxe.Json.parse(state) catch( e : Dynamic ) error("Invalid state "+state+" ("+e+")");
- c.click(function(_) {
- open(cname, state == null ? null : haxe.Json.parse(state));
- });
- }
- // database
- var db = menu.find(".database");
- db.find(".dbView").click(function(_) {
- open("hide.view.CdbTable",{});
- });
- db.find(".dbCompress").prop("checked",database.compress).click(function(_) {
- database.compress = !database.compress;
- saveDatabase();
- });
- db.find(".dbExport").click(function(_) {
- hide.comp.cdb.DataFiles.load();
- var lang = new cdb.Lang(@:privateAccess database.data);
- var xml = lang.buildXML();
- xml = String.fromCharCode(0xFEFF) + xml; // prefix with BOM
- chooseFileSave("export.xml", function(f) {
- if( f != null ) sys.io.File.saveContent(getPath(f), xml);
- });
- });
- db.find(".dbImport").click(function(_) {
- chooseFile(["xml"], function(file) {
- hide.comp.cdb.DataFiles.load();
- var lang = new cdb.Lang(@:privateAccess database.data);
- var xml = sys.io.File.getContent(getPath(file));
- lang.apply(xml);
- saveDatabase(true);
- for( file in @:privateAccess hide.comp.cdb.DataFiles.watching.keys() ) {
- if( sys.FileSystem.isDirectory(getPath(file)) )
- continue;
- var p = loadPrefab(file);
- lang.applyPrefab(p);
- savePrefab(file, p);
- }
- hide.comp.cdb.Editor.refreshAll();
- message("Import completed");
- });
- });
- var proofing = projectConfig.dbProofread == true;
- db.find(".dbProofread").prop("checked", proofing).click(function(_) {
- projectConfig.dbProofread = !proofing;
- config.global.save();
- for( v in getViews(hide.view.CdbTable) )
- v.applyProofing();
- initMenu();
- });
- function setDiff(f) {
- databaseDiff = f;
- config.user.set("cdb.databaseDiff", f);
- config.user.save();
- loadDatabase();
- hide.comp.cdb.Editor.refreshAll();
- initMenu();
- for( v in getViews(hide.view.CdbTable) )
- v.rebuild();
- }
- db.find(".dbCreateDiff").click(function(_) {
- chooseFileSave("cdb.diff", function(name) {
- if( name == null ) return;
- if( name.indexOf(".") < 0 ) name += ".diff";
- sys.io.File.saveContent(getPath(name),"{}");
- setDiff(name);
- });
- });
- db.find(".dbLoadDiff").click(function(_) {
- chooseFile(["diff"], function(f) {
- if( f == null ) return;
- setDiff(f);
- });
- });
- db.find(".dbCloseDiff").click(function(_) {
- setDiff(null);
- }).attr("disabled", databaseDiff == null ? "disabled" : null);
- db.find(".dbCustom").click(function(_) {
- open("hide.view.CdbCustomTypes",{});
- });
- db.find(".dbFormulas").click(function(_) {
- open("hide.comp.cdb.FormulasView",{ path : config.current.get("cdb.formulasFile") });
- });
- // Categories
- {
- function applyCategories() {
- for( v in getViews(hide.view.CdbTable) )
- v.applyCategories(projectConfig.dbCategories);
- initMenu();
- }
- var allCats = hide.comp.cdb.Editor.getCategories(database);
- var showAll = db.find(".dbCatShowAll");
- for(cat in allCats) {
- var isShown = projectConfig.dbCategories == null || projectConfig.dbCategories.indexOf(cat) >= 0;
- new Element("<menu type='checkbox'>").attr("label",cat).prop("checked", isShown).insertBefore(showAll).click(function(_){
- if(projectConfig.dbCategories == null)
- projectConfig.dbCategories = allCats; // Init with all cats
- if(isShown)
- projectConfig.dbCategories.remove(cat);
- else
- projectConfig.dbCategories.push(cat);
- config.user.save();
- applyCategories();
- });
- }
- new Element("<separator>").insertBefore(showAll);
- db.find(".dbCatShowAll").click(function(_) {
- projectConfig.dbCategories = null;
- config.user.save();
- applyCategories();
- });
- db.find(".dbCatHideAll").click(function(_) {
- projectConfig.dbCategories = [];
- config.user.save();
- applyCategories();
- });
- }
- // layout
- var layouts = menu.find(".layout .content");
- layouts.html("");
- if(projectConfig.layouts == null)
- projectConfig.layouts = [];
- for( l in projectConfig.layouts ) {
- if( l.name == "Default" ) continue;
- new Element("<menu>").attr("label",l.name).addClass(l.name).appendTo(layouts).click(function(_) {
- initLayout(l);
- });
- }
- menu.find(".layout .autosave").click(function(_) {
- ideConfig.autoSaveLayout = !ideConfig.autoSaveLayout;
- config.global.save();
- }).prop("checked",ideConfig.autoSaveLayout);
- menu.find(".layout .saveas").click(function(_) {
- var name = ask("Please enter a layout name:");
- if( name == null || name == "" ) return;
- projectConfig.layouts.push({ name : name, state : saveLayout() });
- config.user.save();
- initMenu();
- });
- menu.find(".layout .save").click(function(_) {
- currentLayout.state = saveLayout();
- config.global.save();
- });
- // analysis
- var analysis = menu.find(".analysis");
- analysis.find(".memprof").click(function(_) {
- #if (hashlink >= "1.15.0")
- open("hide.view.MemProfiler",{});
- #else
- quickMessage("Memory Profiler not available. Please update hashlink to version 1.15.0 or later.");
- #end
- });
- analysis.find(".remoteconsole").click(function(_) {
- open("hide.view.RemoteConsoleView",{});
- });
- analysis.find(".devtools").click(function(_) {
- open("hide.view.DevTools",{});
- });
- analysis.find(".gpudump").click(function(_) {
- var path = hide.tools.MemDump.gpudump();
- quickMessage('Gpu mem dumped at ${path}.');
- });
- var settings = menu.find(".settings");
- settings.find('.user-settings').click(function(_) {
- open("hide.view.settings.UserSettings", {});
- });
- settings.find('.project-settings').click(function(_) {
- open("hide.view.settings.ProjectSettings", {});
- });
- var finalMenu = new hide.ui.Menu(menu).root;
- for (custom in customMenus) {
- finalMenu.append(custom);
- }
- window.menu = finalMenu;
- }
- public function showFileInResources(path: String) {
- var filetree = getViews(hide.view.FileTree)[0];
- if( filetree != null) {
- if (@:privateAccess filetree.tree == null)
- filetree.onDisplay();
- filetree.activate();
- filetree.revealNode(path);
- }
- }
- public static function showFileInExplorer(path : String) {
- if(!haxe.io.Path.isAbsolute(path)) {
- path = Ide.inst.getPath(path);
- }
- switch(Sys.systemName()) {
- case "Windows": {
- var cmd = "explorer.exe /select," + '"' + StringTools.replace(path, "/", "\\") + '"';
- trace("OpenInExplorer: " + cmd);
- Sys.command(cmd);
- };
- case "Mac": Sys.command("open " + haxe.io.Path.directory(path));
- default: throw "Exploration not implemented on this platform";
- }
- }
- public function openFile( file : String, ?onCreate, ?onOpen) {
- var ext = @:privateAccess hide.view.FileTree.getExtension(file);
- if( ext == null ) return;
- // look if already open
- var path = makeRelative(file);
- for( v in views )
- if( Type.getClassName(Type.getClass(v)) == ext.component && v.state.path == path ) {
- if( v.container.tab != null ) {
- v.container.parent.parent.setActiveContentItem(v.container.parent);
- if (onOpen != null ) onOpen(v);
- }
- return;
- }
- open(ext.component, { path : path }, onCreate, onOpen);
- }
- public function openSubView<T>( component : Class<hide.ui.View<T>>, state : T, events : {} ) {
- var sharedRefs : Map<Int,Dynamic> = untyped global.sharedRefs;
- if( sharedRefs == null ) {
- sharedRefs = new Map();
- untyped global.sharedRefs = sharedRefs;
- }
- var id = 0;
- while( sharedRefs.exists(id) ) id++;
- sharedRefs.set(id,{ state : state, events : events });
- var compName = Type.getClassName(component);
- nw.Window.open("app.html?subView="+compName+"&sid="+id,{ id : compName });
- }
- public function callParentView( name : String, param : Dynamic ) {
- if( subView != null ) Reflect.callMethod(subView.events,Reflect.field(subView.events,name),[param]);
- }
- public function open( component : String, state : Dynamic, ?onCreate : hide.ui.View<Dynamic> -> Void, ?onOpen : hide.ui.View<Dynamic> -> Void ) {
- if( state == null ) state = {};
- var c = hide.ui.View.viewClasses.get(component);
- if( c == null )
- throw "Unknown component " + component;
- state.componentName = component;
- for( v in views ) {
- if( v.viewClass == component && haxe.Json.stringify(v.state) == haxe.Json.stringify(state) ) {
- v.activate();
- if( onCreate != null ) onCreate(v);
- if ( onOpen != null ) onOpen(v);
- return;
- }
- }
- var options = c.options;
- var bestTarget : golden.Container = null;
- for( v in views )
- if( v.defaultOptions.position == options.position ) {
- if( bestTarget == null || bestTarget.width * bestTarget.height < v.container.width * v.container.height )
- bestTarget = v.container;
- }
- var index : Null<Int> = null;
- var target;
- if( bestTarget != null )
- target = bestTarget.parent.parent;
- else {
- target = layout.root.contentItems[0];
- if( target == null ) {
- layout.root.addChild({ type : Row, isClosable: false });
- target = layout.root.contentItems[0];
- }
- target.config.isClosable = false;
- }
- var needResize = options.width != null;
- target.on("componentCreated", function(c) {
- target.off("componentCreated");
- var view : hide.ui.View<Dynamic> = untyped c.origin.__view;
- if( onCreate != null ) onCreate(view);
- if ( onOpen != null ) onOpen(view);
- if( needResize ) {
- // when opening restricted size after free size
- haxe.Timer.delay(function() {
- view.container.setSize(options.width, view.container.height);
- },0);
- } else {
- // when opening free size after restricted size
- var v0 = views[0];
- if( views.length == 2 && views[1] == view && v0.defaultOptions.width != null )
- haxe.Timer.delay(function() {
- v0.container.setSize(v0.defaultOptions.width, v0.container.height);
- },0);
- }
- });
- var config : golden.Config.ItemConfig = {
- type : Component,
- componentName : component,
- componentState : state
- };
- if( options.position == Left ) index = 0;
- if( index == null )
- target.addChild(config);
- else
- target.addChild(config, index);
- }
- public function reopenLastClosedTab() {
- var state = lastClosedTabStates.pop();
- if( state != null && state.componentName != null ) {
- open(state.componentName, state);
- }
- }
- public function globalMessage(element: Element, timeoutSeconds : Float = 5.0) {
- var body = new Element('body');
- var messages = body.find("#message-container");
- if (messages.length == 0) {
- messages = new Element('<div id="message-container"></div>');
- body.append(messages);
- }
- messages.append(element);
- // envie de prendre le raccourci vers le rez de chaussée la
- haxe.Timer.delay(() -> {
- element.addClass("show");
- }, 10);
- if (timeoutSeconds > 0.0) {
- haxe.Timer.delay(() -> {
- element.get(0).ontransitionend = function(_){
- element.remove();
- };
- element.removeClass("show");
- }, Std.int(timeoutSeconds * 1000.0));
- }
- }
- public function quickMessage( text : String, timeoutSeconds : Float = 5.0 ) {
- var str = StringTools.htmlEscape(text);
- str = StringTools.replace(str, "\n", "<br/>");
- var e = new Element('
- <div class="message">
- <div class="icon ico ico-info-circle"></div>
- <div class="text">${str}</div>
- </div>');
- js.Browser.console.log(text);
- globalMessage(e, timeoutSeconds);
- }
- public function message( text : String ) {
- js.Browser.window.alert(text);
- }
- public function confirm( text : String ) {
- return js.Browser.window.confirm(text);
- }
- public function ask( text : String, ?defaultValue = "" ) {
- return js.Browser.window.prompt(text, defaultValue);
- }
- public static dynamic function onIdeError(e: Dynamic) {}
- public static var inst : Ide;
- static function main() {
- h3d.impl.RenderContext.STRICT = false; // prevent errors with bad renderer
- new Ide();
- }
- public static function getGitCommitHashAndDate():String {
- // Check if there is changes in git. If thats the case, we are certainly on a dev machine
- var out = "";
- try {
- out = js.node.ChildProcess.execSync('git status --porcelain=v1');
- } catch (_) {
- return "";
- }
- if (out.length > 0) {
- return "dev";
- }
- try {
- out = js.node.ChildProcess.execSync('git log --pretty=format:"%h(%cs)" -n 1');
- } catch (_) {
- return "";
- }
- return out;
- }
- }
- class CustomLoader extends hxd.res.Loader {
- var pathKeys = new Map<String,{}>();
- function getKey( path : String ) {
- var k = pathKeys.get(path);
- if( k == null ) {
- k = {};
- pathKeys.set(path, k);
- }
- return k;
- }
- override function loadCache<T:hxd.res.Resource>( path : String, c : Class<T> ) : T {
- var engine = h3d.Engine.getCurrent();
- var i = Std.downcast(@:privateAccess engine.resCache.get(getKey(path)), c);
- if( i == null ) {
- i = Type.createInstance(c, [fs.get(path)]);
- // i = new hxd.res.Image(fs.get(path));
- @:privateAccess engine.resCache.set(getKey(path), i);
- }
- return i;
- }
- }
- @:allow(hide.Ide)
- class FilterPathContext {
- public var valueCurrent: String;
- var valueChanged: String;
- public var filterFn: (FilterPathContext) -> Void;
- var changed = false;
- public function new(filterFn: (FilterPathContext) -> Void) {
- this.filterFn = filterFn;
- };
- public function change(newValue) : Void {
- changed = true;
- valueChanged = newValue;
- }
- public function filter(valueCurrent: String) {
- this.valueCurrent = valueCurrent;
- valueChanged = null;
- filterFn(this);
- return changed ? valueChanged : valueCurrent;
- }
- public var getRef : () -> {str: String, ?goto: () -> Void};
- }
|