diff --git a/Kha/Backends/Krom/Krom.hx b/Kha/Backends/Krom/Krom.hx index f8c5d82f..eb0e7fd3 100644 --- a/Kha/Backends/Krom/Krom.hx +++ b/Kha/Backends/Krom/Krom.hx @@ -159,4 +159,45 @@ extern class Krom { static function getConstantLocationCompute(shader: Dynamic, name: String): Dynamic; static function getTextureUnitCompute(shader: Dynamic, name: String): Dynamic; static function compute(x: Int, y: Int, z: Int): Void; + static function webviewCreate(options: Dynamic): Int; + static function webviewLoadHTML(id: Int, html: String): Void; + static function webviewLoadURL(id: Int, url: String): Void; + static function webviewEvalJS(id: Int, js: String): Void; + static function webviewEvalJSAsync(id: Int, js: String, callback: String->Void): Void; + static function webviewShow(id: Int): Void; + static function webviewHide(id: Int): Void; + static function webviewDestroy(id: Int): Void; + static function webviewResize(id: Int, width: Int, height: Int): Void; + static function webviewMove(id: Int, x: Int, y: Int): Void; + static function webviewSetBounds(id: Int, x: Int, y: Int, width: Int, height: Int): Void; + static function webviewGetX(id: Int): Int; + static function webviewGetY(id: Int): Int; + static function webviewGetWidth(id: Int): Int; + static function webviewGetHeight(id: Int): Int; + static function webviewSetTransparent(id: Int, transparent: Bool): Void; + static function webviewSetClickThrough(id: Int, enabled: Bool): Void; + static function webviewSetTitle(id: Int, title: String): Void; + static function webviewSend(id: Int, message: String): Void; + static function webviewSetOnMessage(id: Int, callback: String->Void): Void; + static function webviewSetOnLoad(id: Int, callback: Void->Void): Void; + static function webviewSetOnError(id: Int, callback: String->Void): Void; + static function webviewSetOnClose(id: Int, callback: Void->Void): Void; + static function webviewCount(): Int; + static function webviewIsValid(id: Int): Bool; + static function webviewSetActiveDOM(id: Int): Void; + static function webviewGetActiveDOM(): Int; + static function webviewGoBack(id: Int): Void; + static function webviewGoForward(id: Int): Void; + static function webviewReload(id: Int): Void; + static function webviewCanGoBack(id: Int): Bool; + static function webviewCanGoForward(id: Int): Bool; + static function webviewGetURL(id: Int): String; + static function webviewGetPageTitle(id: Int): String; + static function webviewMinimize(id: Int): Void; + static function webviewMaximize(id: Int): Void; + static function webviewRestore(id: Int): Void; + static function webviewSetFullscreen(id: Int, fullscreen: Bool): Void; + static function webviewIsFullscreen(id: Int): Bool; + static function webviewEnableDevTools(id: Int, enabled: Bool): Void; + static function webviewSetContextMenu(id: Int, enabled: Bool): Void; } diff --git a/Krom/Krom.app/Contents/MacOS/Krom b/Krom/Krom.app/Contents/MacOS/Krom index 89c631a4..e0b30211 100755 Binary files a/Krom/Krom.app/Contents/MacOS/Krom and b/Krom/Krom.app/Contents/MacOS/Krom differ diff --git a/leenkx/Sources/leenkx/logicnode/AlertNode.hx b/leenkx/Sources/leenkx/logicnode/AlertNode.hx index f82ce7c2..e53a0081 100644 --- a/leenkx/Sources/leenkx/logicnode/AlertNode.hx +++ b/leenkx/Sources/leenkx/logicnode/AlertNode.hx @@ -8,7 +8,7 @@ class AlertNode extends LogicNode { override function run(from: Int) { - #if kha_html5 + #if js js.Browser.window.alert(inputs[1].get()); #end diff --git a/leenkx/Sources/leenkx/logicnode/ConfirmNode.hx b/leenkx/Sources/leenkx/logicnode/ConfirmNode.hx index 8168252a..42600055 100644 --- a/leenkx/Sources/leenkx/logicnode/ConfirmNode.hx +++ b/leenkx/Sources/leenkx/logicnode/ConfirmNode.hx @@ -2,19 +2,31 @@ package leenkx.logicnode; class ConfirmNode extends LogicNode { + var result: Dynamic; + public function new(tree: LogicTree) { super(tree); } override function run(from: Int) { - - #if kha_html5 - var answer: Bool = js.Browser.window.confirm(inputs[1].get()); - if(answer) - return runOutput(0); - else - return runOutput(1); + #if js + result = js.Browser.window.confirm(inputs[1].get()); + if (Reflect.field(result, "loaded") != null) { + tree.notifyOnUpdate(poll); + } else { + if (result) runOutput(0); + else runOutput(1); + } #end + } + function poll() { + #if js + if (result.loaded) { + tree.removeUpdate(poll); + if (result.data) runOutput(0); + else runOutput(1); + } + #end } } diff --git a/leenkx/Sources/leenkx/logicnode/GetElementPropertyNode.hx b/leenkx/Sources/leenkx/logicnode/GetElementPropertyNode.hx index 7de050cb..c2ec744f 100644 --- a/leenkx/Sources/leenkx/logicnode/GetElementPropertyNode.hx +++ b/leenkx/Sources/leenkx/logicnode/GetElementPropertyNode.hx @@ -11,12 +11,11 @@ class GetElementPropertyNode extends LogicNode { override function get(from: Int): Dynamic { return switch (from) { case 0: - var object: Dynamic = inputs[0].get(); - var property = inputs[1].get(); - - value = Reflect.field(object, property); - - //value = object.getAttribute(property.toString()); + #if js + var element: Dynamic = inputs[0].get(); + var property = inputs[1].get(); + value = Reflect.field(element, property); + #end default: throw "Unreachable"; } } diff --git a/leenkx/Sources/leenkx/logicnode/KromCopyToClipboardNode.hx b/leenkx/Sources/leenkx/logicnode/KromCopyToClipboardNode.hx new file mode 100644 index 00000000..04773581 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromCopyToClipboardNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class KromCopyToClipboardNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var text: String = inputs[1].get(); + js.Syntax.code("Krom.copyToClipboard({0})", text); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromDelayIdleSleepNode.hx b/leenkx/Sources/leenkx/logicnode/KromDelayIdleSleepNode.hx new file mode 100644 index 00000000..d2005dcb --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromDelayIdleSleepNode.hx @@ -0,0 +1,15 @@ +package leenkx.logicnode; + +class KromDelayIdleSleepNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + js.Syntax.code("Krom.delayIdleSleep()"); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromDeleteFileNode.hx b/leenkx/Sources/leenkx/logicnode/KromDeleteFileNode.hx new file mode 100644 index 00000000..b2aee7f1 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromDeleteFileNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class KromDeleteFileNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var path: String = inputs[1].get(); + js.Syntax.code("Krom.deleteFile({0})", path); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromFileExistsNode.hx b/leenkx/Sources/leenkx/logicnode/KromFileExistsNode.hx new file mode 100644 index 00000000..292a0074 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromFileExistsNode.hx @@ -0,0 +1,17 @@ +package leenkx.logicnode; + +class KromFileExistsNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + var path: String = inputs[0].get(); + return js.Syntax.code("Krom.fileExists({0})", path); + #else + return false; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromGetArgCountNode.hx b/leenkx/Sources/leenkx/logicnode/KromGetArgCountNode.hx new file mode 100644 index 00000000..3c1da8c1 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromGetArgCountNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class KromGetArgCountNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + return Krom.getArgCount(); + #else + return 0; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromGetArgNode.hx b/leenkx/Sources/leenkx/logicnode/KromGetArgNode.hx new file mode 100644 index 00000000..3938dcd8 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromGetArgNode.hx @@ -0,0 +1,17 @@ +package leenkx.logicnode; + +class KromGetArgNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + var index: Int = inputs[0].get(); + return Krom.getArg(index); + #else + return ""; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromGetFilesLocationNode.hx b/leenkx/Sources/leenkx/logicnode/KromGetFilesLocationNode.hx new file mode 100644 index 00000000..72f45742 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromGetFilesLocationNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class KromGetFilesLocationNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + return Krom.getFilesLocation(); + #else + return ""; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromSavePathNode.hx b/leenkx/Sources/leenkx/logicnode/KromSavePathNode.hx new file mode 100644 index 00000000..0b4d9cf9 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromSavePathNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class KromSavePathNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + return Krom.savePath(); + #else + return ""; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromSetApplicationNameNode.hx b/leenkx/Sources/leenkx/logicnode/KromSetApplicationNameNode.hx new file mode 100644 index 00000000..4dab30d4 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromSetApplicationNameNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class KromSetApplicationNameNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var name: String = inputs[1].get(); + js.Syntax.code("Krom.setApplicationName({0})", name); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromShowKeyboardNode.hx b/leenkx/Sources/leenkx/logicnode/KromShowKeyboardNode.hx new file mode 100644 index 00000000..0dc5a961 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromShowKeyboardNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class KromShowKeyboardNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var show: Bool = inputs[1].get(); + js.Syntax.code("Krom.showKeyboard({0})", show); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/KromSysCommandNode.hx b/leenkx/Sources/leenkx/logicnode/KromSysCommandNode.hx new file mode 100644 index 00000000..185b0a0c --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/KromSysCommandNode.hx @@ -0,0 +1,28 @@ +package leenkx.logicnode; + +class KromSysCommandNode extends LogicNode { + + var exitCode: Int = 0; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var cmd: String = inputs[1].get(); + var args: Dynamic = inputs[2].get(); + if (args != null) { + exitCode = Krom.sysCommand(cmd, args); + } else { + exitCode = Krom.sysCommand(cmd); + } + #end + runOutput(0); + } + + override function get(from: Int): Dynamic { + if (from == 1) return exitCode; + return null; + } +} diff --git a/leenkx/Sources/leenkx/logicnode/LoadUrlNode.hx b/leenkx/Sources/leenkx/logicnode/LoadUrlNode.hx index 9ef08442..d21724a5 100644 --- a/leenkx/Sources/leenkx/logicnode/LoadUrlNode.hx +++ b/leenkx/Sources/leenkx/logicnode/LoadUrlNode.hx @@ -13,7 +13,7 @@ class LoadUrlNode extends LogicNode { override function run(from: Int) { //System.loadUrl(inputs[1].get()); - #if kha_html5 + #if js if (inputs[2].get()){ var window = inputs[3].get() ? js.Browser.window.open(inputs[1].get(), "_blank", "width="+inputs[4].get()+",height="+inputs[5].get()+",left="+inputs[6].get()+",top="+inputs[7].get()) : js.Browser.window.open(inputs[1].get(), "_blank"); diff --git a/leenkx/Sources/leenkx/logicnode/PromptNode.hx b/leenkx/Sources/leenkx/logicnode/PromptNode.hx index 6d066155..2d71d1c5 100644 --- a/leenkx/Sources/leenkx/logicnode/PromptNode.hx +++ b/leenkx/Sources/leenkx/logicnode/PromptNode.hx @@ -3,18 +3,32 @@ package leenkx.logicnode; class PromptNode extends LogicNode { var input: String = null; + var result: Dynamic; public function new(tree: LogicTree) { super(tree); } override function run(from: Int) { - #if kha_html5 - input = js.Browser.window.prompt(inputs[1].get(), inputs[2].get()); - - runOutput(0); + #if js + result = js.Browser.window.prompt(inputs[1].get(), inputs[2].get()); + if (Reflect.field(result, "loaded") != null) { + tree.notifyOnUpdate(poll); + } else { + input = result; + runOutput(0); + } #end + } + function poll() { + #if js + if (result.loaded) { + tree.removeUpdate(poll); + input = result.data; + runOutput(0); + } + #end } override function get(from: Int): Dynamic { diff --git a/leenkx/Sources/leenkx/logicnode/RenderElementNode.hx b/leenkx/Sources/leenkx/logicnode/RenderElementNode.hx index 635cc278..9edb4050 100644 --- a/leenkx/Sources/leenkx/logicnode/RenderElementNode.hx +++ b/leenkx/Sources/leenkx/logicnode/RenderElementNode.hx @@ -40,12 +40,14 @@ class RenderElementNode extends LogicNode { tarElem.prepend(element); runOutput(0); case "innerHTML": - var tarElem = js.Browser.document.querySelector(selector); - tarElem.innerHTML = element.innerHTML; + var html: String = inputs[2].get(); + if (html == null) { return; } + element.innerHTML = html; runOutput(0); case "innerText": - var tarElem = js.Browser.document.querySelector(selector); - tarElem.innerText = element.innerText; + var html: String = inputs[2].get(); + if (html == null){ return; } + element.innerText = html; runOutput(0); case "insertAdjacentHTML": var tarElem = js.Browser.document.querySelector(selector); diff --git a/leenkx/Sources/leenkx/logicnode/RunJavascriptNode.hx b/leenkx/Sources/leenkx/logicnode/RunJavascriptNode.hx index 6bab0d53..9f18e154 100644 --- a/leenkx/Sources/leenkx/logicnode/RunJavascriptNode.hx +++ b/leenkx/Sources/leenkx/logicnode/RunJavascriptNode.hx @@ -12,28 +12,7 @@ class RunJavascriptNode extends LogicNode { #if js var script = inputs[1].get(); js.Syntax.code('(1, eval)({0})', script.toString()); - - var promise:Dynamic = null;//js.Syntax.code('(1, eval)({0})', script.toString()); - if (promise != null) { - promise.then( - function(_) { - //if(leenkx.network.Leenkx.data.get(element) != 'undefined'){return} - haxe.Timer.delay(function () { - //promiseResult(element,html); - return; - }, 100); - return; - }).then(null, function(error) { - trace("JS SYNTAX ERROR:" + error.toString()); - haxe.Timer.delay(function () { - //promiseResult(element,html); - return; - }, 100); - } - ); - } - - runOutput(0); + runOutput(0); #end } diff --git a/leenkx/Sources/leenkx/logicnode/WebviewCountNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewCountNode.hx new file mode 100644 index 00000000..e17b21bb --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewCountNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class WebviewCountNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + return Krom.webviewCount(); + #else + return 0; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewCreateNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewCreateNode.hx new file mode 100644 index 00000000..f719797d --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewCreateNode.hx @@ -0,0 +1,50 @@ +package leenkx.logicnode; + +class WebviewCreateNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + var parentWindow: Int = (property0 == "embedded") ? 0 : -1; + var x: Int = inputs[1].get(); + var y: Int = inputs[2].get(); + var width: Int = inputs[3].get(); + var height: Int = inputs[4].get(); + var transparent: Bool = inputs[5].get(); + var title: String = inputs[6].get(); + var html: String = inputs[7].get(); + var url: String = inputs[8].get(); + var show: Bool = inputs[9].get(); + + #if kha_krom + var options: Dynamic = { + parentWindow: parentWindow, + x: x, + y: y, + width: width, + height: height, + transparent: transparent, + title: title + }; + var id: Int = Krom.webviewCreate(options); + if (html != null && html != "") Krom.webviewLoadHTML(id, html); + if (url != null && url != "") Krom.webviewLoadURL(id, url); + if (show) Krom.webviewShow(id); + #else + var id: Int = -1; + #end + + this.id = id; + runOutput(0); + } + + var id: Int = -1; + + override function get(from: Int): Dynamic { + return id; + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewDOMNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewDOMNode.hx new file mode 100644 index 00000000..31630913 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewDOMNode.hx @@ -0,0 +1,31 @@ +package leenkx.logicnode; + +class WebviewDOMNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + if (property0 == "set") { + var id: Int = inputs[1].get(); + Krom.webviewSetActiveDOM(id); + } + #end + runOutput(0); + } + + override function get(from: Int): Dynamic { + #if kha_krom + if (property0 == "get") { + return Krom.webviewGetActiveDOM(); + } + #else + return -1; + #end + return -1; + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewDestroyNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewDestroyNode.hx new file mode 100644 index 00000000..0e4f6833 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewDestroyNode.hx @@ -0,0 +1,16 @@ +package leenkx.logicnode; + +class WebviewDestroyNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + Krom.webviewDestroy(id); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewDevSettingsNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewDevSettingsNode.hx new file mode 100644 index 00000000..2e9591c8 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewDevSettingsNode.hx @@ -0,0 +1,24 @@ +package leenkx.logicnode; + +class WebviewDevSettingsNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + var enabled: Bool = inputs[2].get(); + if (property0 == "devtools") { + Krom.webviewEnableDevTools(id, enabled); + } + else { + Krom.webviewSetContextMenu(id, enabled); + } + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewEvalJSNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewEvalJSNode.hx new file mode 100644 index 00000000..99dca201 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewEvalJSNode.hx @@ -0,0 +1,17 @@ +package leenkx.logicnode; + +class WebviewEvalJSNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + var jsCode: String = inputs[2].get(); + Krom.webviewEvalJS(id, jsCode); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewFullscreenNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewFullscreenNode.hx new file mode 100644 index 00000000..68d00891 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewFullscreenNode.hx @@ -0,0 +1,31 @@ +package leenkx.logicnode; + +class WebviewFullscreenNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + if (property0 == "set") { + var id: Int = inputs[1].get(); + var fullscreen: Bool = inputs[2].get(); + Krom.webviewSetFullscreen(id, fullscreen); + } + #end + runOutput(0); + } + + override function get(from: Int): Dynamic { + #if kha_krom + if (property0 == "get") { + var id: Int = inputs[0].get(); + return Krom.webviewIsFullscreen(id); + } + #end + return false; + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewGetDimensionsNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewGetDimensionsNode.hx new file mode 100644 index 00000000..af1a0ff5 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewGetDimensionsNode.hx @@ -0,0 +1,26 @@ +package leenkx.logicnode; + +class WebviewGetDimensionsNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + var id: Int = inputs[0].get(); + if (property0 == "position") { + if (from == 0) return Krom.webviewGetX(id); + else return Krom.webviewGetY(id); + } + else { + if (from == 0) return Krom.webviewGetWidth(id); + else return Krom.webviewGetHeight(id); + } + #else + return 0; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewIsValidNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewIsValidNode.hx new file mode 100644 index 00000000..0ab573f5 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewIsValidNode.hx @@ -0,0 +1,17 @@ +package leenkx.logicnode; + +class WebviewIsValidNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + var id: Int = inputs[0].get(); + return Krom.webviewIsValid(id); + #else + return false; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewLoadNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewLoadNode.hx new file mode 100644 index 00000000..8eb3e0e2 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewLoadNode.hx @@ -0,0 +1,25 @@ +package leenkx.logicnode; + +class WebviewLoadNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + if (property0 == "html") { + var html: String = inputs[2].get(); + Krom.webviewLoadHTML(id, html); + } + else { + var url: String = inputs[2].get(); + Krom.webviewLoadURL(id, url); + } + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewNavigationNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewNavigationNode.hx new file mode 100644 index 00000000..b3ef59fe --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewNavigationNode.hx @@ -0,0 +1,22 @@ +package leenkx.logicnode; + +class WebviewNavigationNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + switch (property0) { + case "go_back": Krom.webviewGoBack(id); + case "go_forward": Krom.webviewGoForward(id); + case "reload": Krom.webviewReload(id); + } + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewNavigationStateNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewNavigationStateNode.hx new file mode 100644 index 00000000..716adfc3 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewNavigationStateNode.hx @@ -0,0 +1,20 @@ +package leenkx.logicnode; + +class WebviewNavigationStateNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + var id: Int = inputs[0].get(); + if (property0 == "can_go_back") return Krom.webviewCanGoBack(id); + else return Krom.webviewCanGoForward(id); + #else + return false; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewOnEventNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewOnEventNode.hx new file mode 100644 index 00000000..ef46642c --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewOnEventNode.hx @@ -0,0 +1,46 @@ +package leenkx.logicnode; + +class WebviewOnEventNode extends LogicNode { + + public var property0: String; + + var message: String = ""; + var error: String = ""; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[0].get(); + var self = this; + switch (property0) { + case "message": + Krom.webviewSetOnMessage(id, function(msg) { self.onEvent(msg); }); + case "load": + Krom.webviewSetOnLoad(id, function() { self.onEvent(null); }); + case "error": + Krom.webviewSetOnError(id, function(err) { self.onEvent(err); }); + case "close": + Krom.webviewSetOnClose(id, function() { self.onEvent(null); }); + } + #end + } + + function onEvent(data: String) { + if (data != null) { + if (property0 == "message") this.message = data; + else if (property0 == "error") this.error = data; + } + runOutput(0); + } + + override function get(from: Int): Dynamic { + if (from == 1) { + if (property0 == "message") return message; + if (property0 == "error") return error; + } + return null; + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewPageInfoNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewPageInfoNode.hx new file mode 100644 index 00000000..fd469948 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewPageInfoNode.hx @@ -0,0 +1,20 @@ +package leenkx.logicnode; + +class WebviewPageInfoNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + #if kha_krom + var id: Int = inputs[0].get(); + if (property0 == "url") return Krom.webviewGetURL(id); + else return Krom.webviewGetPageTitle(id); + #else + return ""; + #end + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewSendNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewSendNode.hx new file mode 100644 index 00000000..c810e69e --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewSendNode.hx @@ -0,0 +1,17 @@ +package leenkx.logicnode; + +class WebviewSendNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + var message: String = inputs[2].get(); + Krom.webviewSend(id, message); + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewSetDimensionsNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewSetDimensionsNode.hx new file mode 100644 index 00000000..278e9fbc --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewSetDimensionsNode.hx @@ -0,0 +1,33 @@ +package leenkx.logicnode; + +class WebviewSetDimensionsNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + switch (property0) { + case "resize": + var width: Int = inputs[2].get(); + var height: Int = inputs[3].get(); + Krom.webviewResize(id, width, height); + case "move": + var x: Int = inputs[2].get(); + var y: Int = inputs[3].get(); + Krom.webviewMove(id, x, y); + case "set_bounds": + var x: Int = inputs[2].get(); + var y: Int = inputs[3].get(); + var width: Int = inputs[4].get(); + var height: Int = inputs[5].get(); + Krom.webviewSetBounds(id, x, y, width, height); + } + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewSetPropertyNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewSetPropertyNode.hx new file mode 100644 index 00000000..9e32ce57 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewSetPropertyNode.hx @@ -0,0 +1,28 @@ +package leenkx.logicnode; + +class WebviewSetPropertyNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + switch (property0) { + case "transparent": + var value: Bool = inputs[2].get(); + Krom.webviewSetTransparent(id, value); + case "click_through": + var value: Bool = inputs[2].get(); + Krom.webviewSetClickThrough(id, value); + case "title": + var value: String = inputs[2].get(); + Krom.webviewSetTitle(id, value); + } + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewVisibilityNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewVisibilityNode.hx new file mode 100644 index 00000000..2a55f224 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewVisibilityNode.hx @@ -0,0 +1,23 @@ +package leenkx.logicnode; + +class WebviewVisibilityNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + if (property0 == "show") { + Krom.webviewShow(id); + } + else { + Krom.webviewHide(id); + } + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/logicnode/WebviewWindowActionsNode.hx b/leenkx/Sources/leenkx/logicnode/WebviewWindowActionsNode.hx new file mode 100644 index 00000000..931adb29 --- /dev/null +++ b/leenkx/Sources/leenkx/logicnode/WebviewWindowActionsNode.hx @@ -0,0 +1,22 @@ +package leenkx.logicnode; + +class WebviewWindowActionsNode extends LogicNode { + + public var property0: String; + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + #if kha_krom + var id: Int = inputs[1].get(); + switch (property0) { + case "minimize": Krom.webviewMinimize(id); + case "maximize": Krom.webviewMaximize(id); + case "restore": Krom.webviewRestore(id); + } + #end + runOutput(0); + } +} diff --git a/leenkx/Sources/leenkx/system/Starter.hx b/leenkx/Sources/leenkx/system/Starter.hx index fcab2ecd..9220486d 100644 --- a/leenkx/Sources/leenkx/system/Starter.hx +++ b/leenkx/Sources/leenkx/system/Starter.hx @@ -48,6 +48,21 @@ class Starter { mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) { iron.App.init(function() { + // TODO: Currently breaks after a second + // TODO: Figure out why full width and height need a math operation like /2 or -1 + //#if (lnx_webview && kha_krom) + //var wvOptions: Dynamic = { + // parentWindow: 0, + // x: 0, + // y: 0, + // width: c.window_w - 1, + // height: c.window_h - 1, + // transparent: true, + // title: Main.projectName + //}; + //var wvId: Int = Krom.webviewCreate(wvOptions); + //Krom.webviewShow(wvId); + //#end #if lnx_loadscreen function load(g: kha.graphics2.Graphics) { if (iron.Scene.active != null && iron.Scene.active.ready) iron.App.removeRender2D(load); diff --git a/leenkx/blender/lnx/logicnode/__init__.py b/leenkx/blender/lnx/logicnode/__init__.py index 6ca09b70..2c21aa46 100644 --- a/leenkx/blender/lnx/logicnode/__init__.py +++ b/leenkx/blender/lnx/logicnode/__init__.py @@ -33,8 +33,10 @@ def init_categories(): lnx_nodes.add_category('Input', icon='GREASEPENCIL', section="basic") lnx_nodes.add_category('Native', icon='MEMORY', section="basic", description="The Native category contains nodes which interact with the system (Input/Output functionality, etc.) or Haxe.") - lnx_nodes.add_category('Browser', icon='URL', section="basic") + lnx_nodes.add_category('Krom Runtime', icon='WINDOW', section="basic", + description="Krom specific nodes for WebView, Networking, Window, Display, File and System operations etc.") + lnx_nodes.add_category('Camera', icon='OUTLINER_OB_CAMERA', section="data") lnx_nodes.add_category('Material', icon='MATERIAL', section="data") lnx_nodes.add_category('Light', icon='LIGHT', section="data") diff --git a/leenkx/blender/lnx/logicnode/krom/LN_copy_to_clipboard.py b/leenkx/blender/lnx/logicnode/krom/LN_copy_to_clipboard.py new file mode 100644 index 00000000..1ba5a09f --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_copy_to_clipboard.py @@ -0,0 +1,16 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromCopyToClipboardNode(LnxLogicTreeNode): + """Copies the given text to the system clipboard""" + bl_idname = 'LNKromCopyToClipboardNode' + bl_label = 'Copy To Clipboard' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxStringSocket', 'Text') + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_delay_idle_sleep.py b/leenkx/blender/lnx/logicnode/krom/LN_delay_idle_sleep.py new file mode 100644 index 00000000..c34da182 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_delay_idle_sleep.py @@ -0,0 +1,15 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromDelayIdleSleepNode(LnxLogicTreeNode): + """Delays idle sleep on mobile platforms to keep the runtime active""" + bl_idname = 'LNKromDelayIdleSleepNode' + bl_label = 'Delay Idle Sleep' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_delete_file.py b/leenkx/blender/lnx/logicnode/krom/LN_delete_file.py new file mode 100644 index 00000000..e815590e --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_delete_file.py @@ -0,0 +1,16 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromDeleteFileNode(LnxLogicTreeNode): + """Deletes the file at the given path.""" + bl_idname = 'LNKromDeleteFileNode' + bl_label = 'Delete File' + lnx_category = 'Krom Runtime' + lnx_section = 'file' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxStringSocket', 'Path') + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_file_exists.py b/leenkx/blender/lnx/logicnode/krom/LN_file_exists.py new file mode 100644 index 00000000..4266bd06 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_file_exists.py @@ -0,0 +1,15 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromFileExistsNode(LnxLogicTreeNode): + """Checks whether a file exists at the given path""" + bl_idname = 'LNKromFileExistsNode' + bl_label = 'File Exists' + lnx_category = 'Krom Runtime' + lnx_section = 'file' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxStringSocket', 'Path') + + self.add_output('LnxBoolSocket', 'Exists') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_get_arg.py b/leenkx/blender/lnx/logicnode/krom/LN_get_arg.py new file mode 100644 index 00000000..86f9b3ec --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_get_arg.py @@ -0,0 +1,15 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromGetArgNode(LnxLogicTreeNode): + """Returns the command-line argument at the given index""" + bl_idname = 'LNKromGetArgNode' + bl_label = 'Get Arg' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxIntSocket', 'Index') + + self.add_output('LnxStringSocket', 'Arg') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_get_arg_count.py b/leenkx/blender/lnx/logicnode/krom/LN_get_arg_count.py new file mode 100644 index 00000000..7862edd9 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_get_arg_count.py @@ -0,0 +1,13 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromGetArgCountNode(LnxLogicTreeNode): + """Returns the number of command line arguments passed to the application""" + bl_idname = 'LNKromGetArgCountNode' + bl_label = 'Get Arg Count' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_output('LnxIntSocket', 'Count') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_get_files_location.py b/leenkx/blender/lnx/logicnode/krom/LN_get_files_location.py new file mode 100644 index 00000000..43220d60 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_get_files_location.py @@ -0,0 +1,13 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromGetFilesLocationNode(LnxLogicTreeNode): + """Returns the files location path for the application""" + bl_idname = 'LNKromGetFilesLocationNode' + bl_label = 'Get Files Location' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_output('LnxStringSocket', 'Path') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_save_path.py b/leenkx/blender/lnx/logicnode/krom/LN_save_path.py new file mode 100644 index 00000000..51c6248d --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_save_path.py @@ -0,0 +1,13 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromSavePathNode(LnxLogicTreeNode): + """Returns the save path for the application.""" + bl_idname = 'LNKromSavePathNode' + bl_label = 'Save Path' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_output('LnxStringSocket', 'Path') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_set_application_name.py b/leenkx/blender/lnx/logicnode/krom/LN_set_application_name.py new file mode 100644 index 00000000..b89fe9ef --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_set_application_name.py @@ -0,0 +1,16 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromSetApplicationNameNode(LnxLogicTreeNode): + """Sets the application name used for save paths""" + bl_idname = 'LNKromSetApplicationNameNode' + bl_label = 'Set Application Name' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxStringSocket', 'Name') + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_show_keyboard.py b/leenkx/blender/lnx/logicnode/krom/LN_show_keyboard.py new file mode 100644 index 00000000..00b5aa43 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_show_keyboard.py @@ -0,0 +1,16 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromShowKeyboardNode(LnxLogicTreeNode): + """Shows or hides the onscreen keyboard for mobile platforms""" + bl_idname = 'LNKromShowKeyboardNode' + bl_label = 'Show Keyboard' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxBoolSocket', 'Show', default_value=True) + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_sys_command.py b/leenkx/blender/lnx/logicnode/krom/LN_sys_command.py new file mode 100644 index 00000000..e257bc80 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_sys_command.py @@ -0,0 +1,18 @@ +from lnx.logicnode.lnx_nodes import * + + +class KromSysCommandNode(LnxLogicTreeNode): + """Executes a system command and returns the exit code""" + bl_idname = 'LNKromSysCommandNode' + bl_label = 'System Command' + lnx_category = 'Krom Runtime' + lnx_section = 'system' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxStringSocket', 'Command') + self.add_input('LnxDynamicSocket', 'Args') + + self.add_output('LnxNodeSocketAction', 'Out') + self.add_output('LnxIntSocket', 'Exit Code') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_count.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_count.py new file mode 100644 index 00000000..71741342 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_count.py @@ -0,0 +1,13 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewCountNode(LnxLogicTreeNode): + """Returns the number of active WebViews""" + bl_idname = 'LNWebviewCountNode' + bl_label = 'Webview Count' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def lnx_init(self, context): + self.add_output('LnxIntSocket', 'Count') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_create.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_create.py new file mode 100644 index 00000000..d2288577 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_create.py @@ -0,0 +1,34 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewCreateNode(LnxLogicTreeNode): + """Creates a WebView window and returns its ID""" + bl_idname = 'LNWebviewCreateNode' + bl_label = 'Webview Create' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + property0: HaxeEnumProperty( + 'property0', + items=[('embedded', 'Embedded', 'Embed webview in the engine window'), + ('external', 'External', 'Detached OS window')], + name='Window Mode', default='external') + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'X', default_value=0) + self.add_input('LnxIntSocket', 'Y', default_value=0) + self.add_input('LnxIntSocket', 'Width', default_value=800) + self.add_input('LnxIntSocket', 'Height', default_value=600) + self.add_input('LnxBoolSocket', 'Transparent', default_value=True) + self.add_input('LnxStringSocket', 'Title', default_value='WebView') + self.add_input('LnxStringSocket', 'HTML') + self.add_input('LnxStringSocket', 'URL') + self.add_input('LnxBoolSocket', 'Show', default_value=True) + + self.add_output('LnxNodeSocketAction', 'Out') + self.add_output('LnxIntSocket', 'ID') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_destroy.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_destroy.py new file mode 100644 index 00000000..2a12b5ef --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_destroy.py @@ -0,0 +1,16 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewDestroyNode(LnxLogicTreeNode): + """Destroys the given WebView and frees its resources""" + bl_idname = 'LNWebviewDestroyNode' + bl_label = 'Webview Destroy' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_dev_settings.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_dev_settings.py new file mode 100644 index 00000000..0827dc01 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_dev_settings.py @@ -0,0 +1,26 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewDevSettingsNode(LnxLogicTreeNode): + """Enables or disables developer settings for the given WebView""" + bl_idname = 'LNWebviewDevSettingsNode' + bl_label = 'Webview Dev Settings' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + property0: HaxeEnumProperty( + 'property0', + items=[('devtools', 'DevTools', 'Enable/disable developer tools'), + ('context_menu', 'Context Menu', 'Enable/disable right-click context menu')], + name='Setting', default='devtools') + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxBoolSocket', 'Enabled', default_value=True) + + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_dom.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_dom.py new file mode 100644 index 00000000..ddef64ed --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_dom.py @@ -0,0 +1,37 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewDOMNode(LnxLogicTreeNode): + """Sets or gets the active DOM WebView""" + bl_idname = 'LNWebviewDOMNode' + bl_label = 'Webview DOM' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def update_sockets(self, context): + for i in self.inputs: + self.inputs.remove(i) + for o in self.outputs: + self.outputs.remove(o) + + if self.property0 == 'set': + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_output('LnxNodeSocketAction', 'Out') + else: + self.add_output('LnxIntSocket', 'ID') + + property0: HaxeEnumProperty( + 'property0', + items=[('set', 'Set Active', 'Set the active DOM WebView'), + ('get', 'Get Active', 'Get the active DOM WebView ID')], + name='Mode', default='set', update=update_sockets) + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_eval_js.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_eval_js.py new file mode 100644 index 00000000..f2d7f79e --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_eval_js.py @@ -0,0 +1,17 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewEvalJSNode(LnxLogicTreeNode): + """Evaluates JavaScript code in the given WebView""" + bl_idname = 'LNWebviewEvalJSNode' + bl_label = 'Webview Eval JS' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxStringSocket', 'JS') + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_fullscreen.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_fullscreen.py new file mode 100644 index 00000000..50324c78 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_fullscreen.py @@ -0,0 +1,40 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewFullscreenNode(LnxLogicTreeNode): + """Sets or gets the fullscreen state of the given WebView's detached window""" + bl_idname = 'LNWebviewFullscreenNode' + bl_label = 'Webview Fullscreen' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def update_sockets(self, context): + for i in self.inputs: + self.inputs.remove(i) + for o in self.outputs: + self.outputs.remove(o) + + if self.property0 == 'set': + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxBoolSocket', 'Fullscreen', default_value=True) + self.add_output('LnxNodeSocketAction', 'Out') + else: + self.add_input('LnxIntSocket', 'ID') + self.add_output('LnxBoolSocket', 'Is Fullscreen') + + property0: HaxeEnumProperty( + 'property0', + items=[('set', 'Set', 'Set fullscreen state'), + ('get', 'Get', 'Get fullscreen state')], + name='Mode', default='set', update=update_sockets) + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxBoolSocket', 'Fullscreen', default_value=True) + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_get_dimensions.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_get_dimensions.py new file mode 100644 index 00000000..0dce2bc3 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_get_dimensions.py @@ -0,0 +1,36 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewGetDimensionsNode(LnxLogicTreeNode): + """Gets the position or size of the given WebView""" + bl_idname = 'LNWebviewGetDimensionsNode' + bl_label = 'Webview Get Dimensions' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def update_sockets(self, context): + for o in self.outputs: + self.outputs.remove(o) + + if self.property0 == 'position': + self.add_output('LnxIntSocket', 'X') + self.add_output('LnxIntSocket', 'Y') + else: + self.add_output('LnxIntSocket', 'Width') + self.add_output('LnxIntSocket', 'Height') + + property0: HaxeEnumProperty( + 'property0', + items=[('position', 'Position', 'Get X and Y position'), + ('size', 'Size', 'Get width and height')], + name='Mode', default='position', update=update_sockets) + + def lnx_init(self, context): + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxIntSocket', 'X') + self.add_output('LnxIntSocket', 'Y') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_is_valid.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_is_valid.py new file mode 100644 index 00000000..b348b125 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_is_valid.py @@ -0,0 +1,15 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewIsValidNode(LnxLogicTreeNode): + """Checks whether the given WebView ID is valid""" + bl_idname = 'LNWebviewIsValidNode' + bl_label = 'Webview Is Valid' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxBoolSocket', 'Valid') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_load.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_load.py new file mode 100644 index 00000000..44a26964 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_load.py @@ -0,0 +1,37 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewLoadNode(LnxLogicTreeNode): + """Loads HTML content or a URL into the given WebView""" + bl_idname = 'LNWebviewLoadNode' + bl_label = 'Webview Load' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def update_sockets(self, context): + for i in self.inputs: + self.inputs.remove(i) + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + if self.property0 == 'html': + self.add_input('LnxStringSocket', 'HTML') + else: + self.add_input('LnxStringSocket', 'URL') + self.add_output('LnxNodeSocketAction', 'Out') + + property0: HaxeEnumProperty( + 'property0', + items=[('html', 'HTML', 'Load HTML content'), + ('url', 'URL', 'Load a URL')], + name='Load Type', default='url', update=update_sockets) + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxStringSocket', 'URL') + + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_navigation.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_navigation.py new file mode 100644 index 00000000..6cf0c915 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_navigation.py @@ -0,0 +1,26 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewNavigationNode(LnxLogicTreeNode): + """Performs a navigation action on the given WebView""" + bl_idname = 'LNWebviewNavigationNode' + bl_label = 'Webview Navigation' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + property0: HaxeEnumProperty( + 'property0', + items=[('go_back', 'Go Back', 'Navigate back in history'), + ('go_forward', 'Go Forward', 'Navigate forward in history'), + ('reload', 'Reload', 'Reload the current page')], + name='Action', default='reload') + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_navigation_state.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_navigation_state.py new file mode 100644 index 00000000..109b9ea4 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_navigation_state.py @@ -0,0 +1,24 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewNavigationStateNode(LnxLogicTreeNode): + """Checks the navigation state of the given WebView""" + bl_idname = 'LNWebviewNavigationStateNode' + bl_label = 'Webview Navigation State' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + property0: HaxeEnumProperty( + 'property0', + items=[('can_go_back', 'Can Go Back', 'Check if can navigate back'), + ('can_go_forward', 'Can Go Forward', 'Check if can navigate forward')], + name='Check', default='can_go_back') + + def lnx_init(self, context): + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxBoolSocket', 'State') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_on_event.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_on_event.py new file mode 100644 index 00000000..0f13a15c --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_on_event.py @@ -0,0 +1,35 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewOnEventNode(LnxLogicTreeNode): + """Triggers when the given WebView fires an event message, load, error, or close""" + bl_idname = 'LNWebviewOnEventNode' + bl_label = 'Webview On Event' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def update_sockets(self, context): + for o in self.outputs: + self.outputs.remove(o) + + self.add_output('LnxNodeSocketAction', 'Out') + if self.property0 in ('message', 'error'): + self.add_output('LnxStringSocket', 'Data') + + property0: HaxeEnumProperty( + 'property0', + items=[('message', 'On Message', 'Triggered when a message is received'), + ('load', 'On Load', 'Triggered when the page finishes loading'), + ('error', 'On Error', 'Triggered when a load error occurs'), + ('close', 'On Close', 'Triggered when the WebView is closed')], + name='Event', default='message', update=update_sockets) + + def lnx_init(self, context): + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxNodeSocketAction', 'Out') + self.add_output('LnxStringSocket', 'Data') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_page_info.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_page_info.py new file mode 100644 index 00000000..aaecc7f2 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_page_info.py @@ -0,0 +1,24 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewPageInfoNode(LnxLogicTreeNode): + """Gets the current URL or page title of the given WebView""" + bl_idname = 'LNWebviewPageInfoNode' + bl_label = 'Webview Page Info' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + property0: HaxeEnumProperty( + 'property0', + items=[('url', 'URL', 'Get the current URL'), + ('title', 'Title', 'Get the page title')], + name='Info', default='url') + + def lnx_init(self, context): + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxStringSocket', 'Value') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_send.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_send.py new file mode 100644 index 00000000..ccfa9f10 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_send.py @@ -0,0 +1,17 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewSendNode(LnxLogicTreeNode): + """Sends a message to the given WebView received via window.onMessage""" + bl_idname = 'LNWebviewSendNode' + bl_label = 'Webview Send' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxStringSocket', 'Message') + + self.add_output('LnxNodeSocketAction', 'Out') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_set_dimensions.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_set_dimensions.py new file mode 100644 index 00000000..ba825cf2 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_set_dimensions.py @@ -0,0 +1,47 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewSetDimensionsNode(LnxLogicTreeNode): + """Sets dimensions of the given WebView for resize, move, or setting bounds""" + bl_idname = 'LNWebviewSetDimensionsNode' + bl_label = 'Webview Set Dimensions' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def update_sockets(self, context): + remove_list = [] + for i in range(2, len(self.inputs)): + remove_list.append(self.inputs[i]) + for i in remove_list: + self.inputs.remove(i) + + if self.property0 == 'resize': + self.add_input('LnxIntSocket', 'Width', default_value=800) + self.add_input('LnxIntSocket', 'Height', default_value=600) + elif self.property0 == 'move': + self.add_input('LnxIntSocket', 'X', default_value=0) + self.add_input('LnxIntSocket', 'Y', default_value=0) + else: + self.add_input('LnxIntSocket', 'X', default_value=0) + self.add_input('LnxIntSocket', 'Y', default_value=0) + self.add_input('LnxIntSocket', 'Width', default_value=800) + self.add_input('LnxIntSocket', 'Height', default_value=600) + + property0: HaxeEnumProperty( + 'property0', + items=[('resize', 'Resize', 'Set width and height'), + ('move', 'Move', 'Set X and Y position'), + ('set_bounds', 'Set Bounds', 'Set X, Y, width and height')], + name='Mode', default='resize', update=update_sockets) + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxIntSocket', 'Width', default_value=800) + self.add_input('LnxIntSocket', 'Height', default_value=600) + + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_set_property.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_set_property.py new file mode 100644 index 00000000..4ff17ce1 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_set_property.py @@ -0,0 +1,39 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewSetPropertyNode(LnxLogicTreeNode): + """Sets a property of the given WebView""" + bl_idname = 'LNWebviewSetPropertyNode' + bl_label = 'Webview Set Property' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + def update_sockets(self, context): + remove_list = [] + for i in range(2, len(self.inputs)): + remove_list.append(self.inputs[i]) + for i in remove_list: + self.inputs.remove(i) + + if self.property0 == 'title': + self.add_input('LnxStringSocket', 'Title', default_value='WebView') + else: + self.add_input('LnxBoolSocket', 'Value', default_value=True) + + property0: HaxeEnumProperty( + 'property0', + items=[('transparent', 'Transparent', 'Set background transparency'), + ('click_through', 'Click Through', 'Set click-through mode'), + ('title', 'Title', 'Set window title')], + name='Property', default='transparent', update=update_sockets) + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + self.add_input('LnxBoolSocket', 'Value', default_value=True) + + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_visibility.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_visibility.py new file mode 100644 index 00000000..17276760 --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_visibility.py @@ -0,0 +1,25 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewVisibilityNode(LnxLogicTreeNode): + """Shows or hides the given WebView""" + bl_idname = 'LNWebviewVisibilityNode' + bl_label = 'Webview Visibility' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + property0: HaxeEnumProperty( + 'property0', + items=[('show', 'Show', 'Show the WebView'), + ('hide', 'Hide', 'Hide the WebView')], + name='Action', default='show') + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/LN_webview_window_actions.py b/leenkx/blender/lnx/logicnode/krom/LN_webview_window_actions.py new file mode 100644 index 00000000..78f7093d --- /dev/null +++ b/leenkx/blender/lnx/logicnode/krom/LN_webview_window_actions.py @@ -0,0 +1,26 @@ +from lnx.logicnode.lnx_nodes import * + + +class WebviewWindowActionsNode(LnxLogicTreeNode): + """Performs a window action on the given WebView's detached window""" + bl_idname = 'LNWebviewWindowActionsNode' + bl_label = 'Webview Window Actions' + lnx_category = 'Krom Runtime' + lnx_section = 'webview' + lnx_version = 1 + + property0: HaxeEnumProperty( + 'property0', + items=[('minimize', 'Minimize', 'Minimize the window'), + ('maximize', 'Maximize', 'Maximize the window'), + ('restore', 'Restore', 'Restore the window')], + name='Action', default='restore') + + def lnx_init(self, context): + self.add_input('LnxNodeSocketAction', 'In') + self.add_input('LnxIntSocket', 'ID') + + self.add_output('LnxNodeSocketAction', 'Out') + + def draw_buttons(self, context, layout): + layout.prop(self, 'property0') diff --git a/leenkx/blender/lnx/logicnode/krom/__init__.py b/leenkx/blender/lnx/logicnode/krom/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/leenkx/blender/lnx/props.py b/leenkx/blender/lnx/props.py index 2420a1d9..b00c4e29 100644 --- a/leenkx/blender/lnx/props.py +++ b/leenkx/blender/lnx/props.py @@ -364,6 +364,7 @@ def init_properties(): bpy.types.World.lnx_dce = BoolProperty(name="DCE", description="Enable dead code elimination for publish builds", default=True, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_asset_compression = BoolProperty(name="Asset Compression", description="Enable scene data compression with LZ4 when publishing. Warning: This will slow down export!", default=False, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_single_data_file = BoolProperty(name="Single Data File", description="Pack exported meshes and materials into single file", default=False, update=assets.invalidate_compiler_cache) + bpy.types.World.lnx_webview = BoolProperty(name="Enable Webview", description="Create a default embedded webview for DOM interaction", default=False, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_write_config = BoolProperty(name="Write Config", description="Allow this project to be configured at runtime via a JSON file", default=False, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_compiler_inline = BoolProperty(name="Compiler Inline", description="Favor speed over size", default=True, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_winmode = EnumProperty( diff --git a/leenkx/blender/lnx/props_ui.py b/leenkx/blender/lnx/props_ui.py index f9a26f40..bdaed3c3 100644 --- a/leenkx/blender/lnx/props_ui.py +++ b/leenkx/blender/lnx/props_ui.py @@ -1201,6 +1201,7 @@ class LNX_PT_ProjectFlagsPanel(bpy.types.Panel): col.prop(wrd, 'lnx_live_patch') col.prop(wrd, 'lnx_stream_scene') col.prop(wrd, 'lnx_loadscreen') + col.prop(wrd, 'lnx_webview') col.prop(wrd, 'lnx_write_config') col = column_with_heading(layout, 'Renderer', align=True) diff --git a/leenkx/blender/lnx/write_data.py b/leenkx/blender/lnx/write_data.py index e95aaeca..deb1f8c1 100644 --- a/leenkx/blender/lnx/write_data.py +++ b/leenkx/blender/lnx/write_data.py @@ -509,6 +509,9 @@ let project = new Project('""" + lnx.utils.safesrc(wrd.lnx_project_name + '-' + if lnx.utils.get_viewport_controls() == 'azerty': assets.add_khafile_def('lnx_azerty') + if wrd.lnx_webview: + assets.add_khafile_def('lnx_webview') + if os.path.exists(project_path + '/Bundled/config.lnx'): assets.add_khafile_def('lnx_config')