Better AIR windowing, support for AIR backend methods

This commit is contained in:
Joshua Granick
2017-10-10 13:09:21 -07:00
parent c3e49e01ed
commit a3dce7ef3b
8 changed files with 385 additions and 372 deletions

View File

@@ -25,6 +25,9 @@ extern class Event {
static var CHANNEL_STATE(default,never) : String;
@:require(flash10) static var CLEAR(default,never) : String;
static var CLOSE(default,never) : String;
#if air
static var CLOSING(default,never) : String;
#end
static var COMPLETE(default,never) : String;
static var CONNECT(default,never) : String;
@:require(flash11) static var CONTEXT3D_CREATE(default,never) : String;

View File

@@ -2,10 +2,6 @@ package lime._backend.flash;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TouchEvent;
import flash.ui.MultitouchInputMode;
import flash.ui.Multitouch;
import flash.Lib;
@@ -13,9 +9,6 @@ import lime.app.Application;
import lime.app.Config;
import lime.media.AudioManager;
import lime.graphics.Renderer;
import lime.ui.KeyCode;
import lime.ui.KeyModifier;
import lime.ui.Touch;
import lime.ui.Window;
@:access(lime.app.Application)
@@ -25,13 +18,8 @@ import lime.ui.Window;
class FlashApplication {
private var cacheMouseX:Float;
private var cacheMouseY:Float;
private var cacheTime:Int;
private var currentTouches = new Map<Int, Touch> ();
private var mouseLeft:Bool;
private var parent:Application;
private var unusedTouchesPool = new List<Touch> ();
public function new (parent:Application):Void {
@@ -39,90 +27,11 @@ class FlashApplication {
this.parent = parent;
Lib.current.stage.frameRate = 60;
cacheMouseX = 0;
cacheMouseY = 0;
AudioManager.init ();
}
private function convertKeyCode (keyCode:Int):KeyCode {
if (keyCode >= 65 && keyCode <= 90) {
return keyCode + 32;
}
switch (keyCode) {
case 16: return KeyCode.LEFT_SHIFT;
case 17: return KeyCode.LEFT_CTRL;
case 18: return KeyCode.LEFT_ALT;
case 20: return KeyCode.CAPS_LOCK;
case 33: return KeyCode.PAGE_UP;
case 34: return KeyCode.PAGE_DOWN;
case 35: return KeyCode.END;
case 36: return KeyCode.HOME;
case 37: return KeyCode.LEFT;
case 38: return KeyCode.UP;
case 39: return KeyCode.RIGHT;
case 40: return KeyCode.DOWN;
case 45: return KeyCode.INSERT;
case 46: return KeyCode.DELETE;
case 96: return KeyCode.NUMPAD_0;
case 97: return KeyCode.NUMPAD_1;
case 98: return KeyCode.NUMPAD_2;
case 99: return KeyCode.NUMPAD_3;
case 100: return KeyCode.NUMPAD_4;
case 101: return KeyCode.NUMPAD_5;
case 102: return KeyCode.NUMPAD_6;
case 103: return KeyCode.NUMPAD_7;
case 104: return KeyCode.NUMPAD_8;
case 105: return KeyCode.NUMPAD_9;
case 106: return KeyCode.NUMPAD_MULTIPLY;
case 107: return KeyCode.NUMPAD_PLUS;
case 108: return KeyCode.NUMPAD_ENTER;
case 109: return KeyCode.NUMPAD_MINUS;
case 110: return KeyCode.NUMPAD_PERIOD;
case 111: return KeyCode.NUMPAD_DIVIDE;
case 112: return KeyCode.F1;
case 113: return KeyCode.F2;
case 114: return KeyCode.F3;
case 115: return KeyCode.F4;
case 116: return KeyCode.F5;
case 117: return KeyCode.F6;
case 118: return KeyCode.F7;
case 119: return KeyCode.F8;
case 120: return KeyCode.F9;
case 121: return KeyCode.F10;
case 122: return KeyCode.F11;
case 123: return KeyCode.F12;
case 124: return KeyCode.F13;
case 125: return KeyCode.F14;
case 126: return KeyCode.F15;
case 144: return KeyCode.NUM_LOCK;
case 186: return KeyCode.SEMICOLON;
case 187: return KeyCode.EQUALS;
case 188: return KeyCode.COMMA;
case 189: return KeyCode.MINUS;
case 190: return KeyCode.PERIOD;
case 191: return KeyCode.SLASH;
case 192: return KeyCode.GRAVE;
case 219: return KeyCode.LEFT_BRACKET;
case 220: return KeyCode.BACKSLASH;
case 221: return KeyCode.RIGHT_BRACKET;
case 222: return KeyCode.SINGLE_QUOTE;
}
return keyCode;
}
public function create (config:Config):Void {
@@ -132,29 +41,8 @@ class FlashApplication {
public function exec ():Int {
Lib.current.stage.addEventListener (KeyboardEvent.KEY_DOWN, handleKeyEvent);
Lib.current.stage.addEventListener (KeyboardEvent.KEY_UP, handleKeyEvent);
var events = [ "mouseDown", "mouseMove", "mouseUp", "mouseWheel", "middleMouseDown", "middleMouseMove", "middleMouseUp" #if ((!openfl && !disable_flash_right_click) || enable_flash_right_click) , "rightMouseDown", "rightMouseMove", "rightMouseUp" #end ];
for (event in events) {
Lib.current.stage.addEventListener (event, handleMouseEvent);
}
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Lib.current.stage.addEventListener (TouchEvent.TOUCH_BEGIN, handleTouchEvent);
Lib.current.stage.addEventListener (TouchEvent.TOUCH_MOVE, handleTouchEvent);
Lib.current.stage.addEventListener (TouchEvent.TOUCH_END, handleTouchEvent);
Lib.current.stage.addEventListener (Event.ACTIVATE, handleWindowEvent);
Lib.current.stage.addEventListener (Event.DEACTIVATE, handleWindowEvent);
Lib.current.stage.addEventListener (FocusEvent.FOCUS_IN, handleWindowEvent);
Lib.current.stage.addEventListener (FocusEvent.FOCUS_OUT, handleWindowEvent);
Lib.current.stage.addEventListener (Event.MOUSE_LEAVE, handleWindowEvent);
Lib.current.stage.addEventListener (Event.RESIZE, handleWindowEvent);
cacheTime = Lib.getTimer ();
handleApplicationEvent (null);
@@ -197,231 +85,23 @@ class FlashApplication {
}
private function handleKeyEvent (event:KeyboardEvent):Void {
if (parent.window != null) {
var keyCode = convertKeyCode (event.keyCode);
var modifier = (event.shiftKey ? (KeyModifier.SHIFT) : 0) | (event.ctrlKey ? (KeyModifier.CTRL) : 0) | (event.altKey ? (KeyModifier.ALT) : 0);
if (event.type == KeyboardEvent.KEY_DOWN) {
parent.window.onKeyDown.dispatch (keyCode, modifier);
if (parent.window != null && parent.window.enableTextEvents) {
parent.window.onTextInput.dispatch (String.fromCharCode (event.charCode));
}
} else {
parent.window.onKeyUp.dispatch (keyCode, modifier);
}
}
}
private function handleMouseEvent (event:MouseEvent):Void {
if (parent.window != null) {
var button = switch (event.type) {
case "middleMouseDown", "middleMouseUp": 1;
case "rightMouseDown", "rightMouseUp": 2;
default: 0;
}
switch (event.type) {
case "mouseDown", "middleMouseDown", "rightMouseDown":
parent.window.onMouseDown.dispatch (event.stageX, event.stageY, button);
case "mouseMove":
if (mouseLeft) {
mouseLeft = false;
parent.window.onEnter.dispatch ();
}
var mouseX = event.stageX;
var mouseY = event.stageY;
parent.window.onMouseMove.dispatch (mouseX, mouseY);
parent.window.onMouseMoveRelative.dispatch (mouseX - cacheMouseX, mouseY - cacheMouseY);
cacheMouseX = mouseX;
cacheMouseY = mouseY;
case "mouseUp", "middleMouseUp", "rightMouseUp":
parent.window.onMouseUp.dispatch (event.stageX, event.stageY, button);
case "mouseWheel":
parent.window.onMouseWheel.dispatch (0, event.delta);
default:
}
}
}
private function handleTouchEvent (event:TouchEvent):Void {
if (parent.window != null) {
var x = event.stageX;
var y = event.stageY;
switch (event.type) {
case TouchEvent.TOUCH_BEGIN:
var touch = unusedTouchesPool.pop ();
if (touch == null) {
touch = new Touch (x / parent.window.width, y / parent.window.height, event.touchPointID, 0, 0, event.pressure, 0);
} else {
touch.x = x / parent.window.width;
touch.y = y / parent.window.height;
touch.id = event.touchPointID;
touch.dx = 0;
touch.dy = 0;
touch.pressure = event.pressure;
touch.device = 0;
}
currentTouches.set (event.touchPointID, touch);
Touch.onStart.dispatch (touch);
if (event.isPrimaryTouchPoint) {
parent.window.onMouseDown.dispatch (x, y, 0);
}
case TouchEvent.TOUCH_END:
var touch = currentTouches.get (event.touchPointID);
if (touch != null) {
var cacheX = touch.x;
var cacheY = touch.y;
touch.x = x / parent.window.width;
touch.y = y / parent.window.height;
touch.dx = touch.x - cacheX;
touch.dy = touch.y - cacheY;
touch.pressure = event.pressure;
Touch.onEnd.dispatch (touch);
currentTouches.remove (event.touchPointID);
unusedTouchesPool.add (touch);
if (event.isPrimaryTouchPoint) {
parent.window.onMouseUp.dispatch (x, y, 0);
}
}
case TouchEvent.TOUCH_MOVE:
var touch = currentTouches.get (event.touchPointID);
if (touch != null) {
var cacheX = touch.x;
var cacheY = touch.y;
touch.x = x / parent.window.width;
touch.y = y / parent.window.height;
touch.dx = touch.x - cacheX;
touch.dy = touch.y - cacheY;
touch.pressure = event.pressure;
Touch.onMove.dispatch (touch);
if (event.isPrimaryTouchPoint) {
parent.window.onMouseMove.dispatch (x, y);
}
}
}
}
}
private function handleWindowEvent (event:Event):Void {
if (parent.window != null) {
switch (event.type) {
case Event.ACTIVATE:
parent.window.onActivate.dispatch ();
case Event.DEACTIVATE:
parent.window.onDeactivate.dispatch ();
case FocusEvent.FOCUS_IN:
parent.window.onFocusIn.dispatch ();
case FocusEvent.FOCUS_OUT:
parent.window.onFocusOut.dispatch ();
case Event.MOUSE_LEAVE:
mouseLeft = true;
parent.window.onLeave.dispatch ();
default:
parent.window.width = Lib.current.stage.stageWidth;
parent.window.height = Lib.current.stage.stageHeight;
parent.window.onResize.dispatch (parent.window.width, parent.window.height);
}
}
}
public function setFrameRate (value:Float):Float {
return Lib.current.stage.frameRate = value;
if (parent.windows.length > 0) {
for (window in parent.windows) {
window.stage.frameRate = value;
}
} else {
Lib.current.stage.frameRate = value;
}
return value;
}

View File

@@ -3,9 +3,17 @@ package lime._backend.flash;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TouchEvent;
import flash.Lib;
import lime.app.Application;
import lime.graphics.Image;
import lime.ui.KeyCode;
import lime.ui.KeyModifier;
import lime.ui.Touch;
import lime.system.Display;
import lime.system.DisplayMode;
import lime.system.System;
@@ -18,14 +26,24 @@ import lime.ui.Window;
class FlashWindow {
private static var windowID = 0;
private var cacheMouseX:Float;
private var cacheMouseY:Float;
private var currentTouches = new Map<Int, Touch> ();
private var enableTextEvents:Bool;
private var mouseLeft:Bool;
private var parent:Window;
private var unusedTouchesPool = new List<Touch> ();
public function new (parent:Window) {
this.parent = parent;
cacheMouseX = 0;
cacheMouseY = 0;
}
@@ -43,13 +61,111 @@ class FlashWindow {
}
private function convertKeyCode (keyCode:Int):KeyCode {
if (keyCode >= 65 && keyCode <= 90) {
return keyCode + 32;
}
switch (keyCode) {
case 16: return KeyCode.LEFT_SHIFT;
case 17: return KeyCode.LEFT_CTRL;
case 18: return KeyCode.LEFT_ALT;
case 20: return KeyCode.CAPS_LOCK;
case 33: return KeyCode.PAGE_UP;
case 34: return KeyCode.PAGE_DOWN;
case 35: return KeyCode.END;
case 36: return KeyCode.HOME;
case 37: return KeyCode.LEFT;
case 38: return KeyCode.UP;
case 39: return KeyCode.RIGHT;
case 40: return KeyCode.DOWN;
case 45: return KeyCode.INSERT;
case 46: return KeyCode.DELETE;
case 96: return KeyCode.NUMPAD_0;
case 97: return KeyCode.NUMPAD_1;
case 98: return KeyCode.NUMPAD_2;
case 99: return KeyCode.NUMPAD_3;
case 100: return KeyCode.NUMPAD_4;
case 101: return KeyCode.NUMPAD_5;
case 102: return KeyCode.NUMPAD_6;
case 103: return KeyCode.NUMPAD_7;
case 104: return KeyCode.NUMPAD_8;
case 105: return KeyCode.NUMPAD_9;
case 106: return KeyCode.NUMPAD_MULTIPLY;
case 107: return KeyCode.NUMPAD_PLUS;
case 108: return KeyCode.NUMPAD_ENTER;
case 109: return KeyCode.NUMPAD_MINUS;
case 110: return KeyCode.NUMPAD_PERIOD;
case 111: return KeyCode.NUMPAD_DIVIDE;
case 112: return KeyCode.F1;
case 113: return KeyCode.F2;
case 114: return KeyCode.F3;
case 115: return KeyCode.F4;
case 116: return KeyCode.F5;
case 117: return KeyCode.F6;
case 118: return KeyCode.F7;
case 119: return KeyCode.F8;
case 120: return KeyCode.F9;
case 121: return KeyCode.F10;
case 122: return KeyCode.F11;
case 123: return KeyCode.F12;
case 124: return KeyCode.F13;
case 125: return KeyCode.F14;
case 126: return KeyCode.F15;
case 144: return KeyCode.NUM_LOCK;
case 186: return KeyCode.SEMICOLON;
case 187: return KeyCode.EQUALS;
case 188: return KeyCode.COMMA;
case 189: return KeyCode.MINUS;
case 190: return KeyCode.PERIOD;
case 191: return KeyCode.SLASH;
case 192: return KeyCode.GRAVE;
case 219: return KeyCode.LEFT_BRACKET;
case 220: return KeyCode.BACKSLASH;
case 221: return KeyCode.RIGHT_BRACKET;
case 222: return KeyCode.SINGLE_QUOTE;
}
return keyCode;
}
public function create (application:Application):Void {
Lib.current.stage.align = StageAlign.TOP_LEFT;
Lib.current.stage.scaleMode = StageScaleMode.NO_SCALE;
parent.id = windowID++;
parent.id = 0;
parent.stage = Lib.current.stage;
if (parent.stage == null) parent.stage = Lib.current.stage;
var stage = parent.stage;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener (KeyboardEvent.KEY_DOWN, handleKeyEvent);
stage.addEventListener (KeyboardEvent.KEY_UP, handleKeyEvent);
var events = [ "mouseDown", "mouseMove", "mouseUp", "mouseWheel", "middleMouseDown", "middleMouseMove", "middleMouseUp" #if ((!openfl && !disable_flash_right_click) || enable_flash_right_click) , "rightMouseDown", "rightMouseMove", "rightMouseUp" #end ];
for (event in events) {
stage.addEventListener (event, handleMouseEvent);
}
stage.addEventListener (TouchEvent.TOUCH_BEGIN, handleTouchEvent);
stage.addEventListener (TouchEvent.TOUCH_MOVE, handleTouchEvent);
stage.addEventListener (TouchEvent.TOUCH_END, handleTouchEvent);
stage.addEventListener (Event.ACTIVATE, handleWindowEvent);
stage.addEventListener (Event.DEACTIVATE, handleWindowEvent);
stage.addEventListener (FocusEvent.FOCUS_IN, handleWindowEvent);
stage.addEventListener (FocusEvent.FOCUS_OUT, handleWindowEvent);
stage.addEventListener (Event.MOUSE_LEAVE, handleWindowEvent);
stage.addEventListener (Event.RESIZE, handleWindowEvent);
}
@@ -75,6 +191,214 @@ class FlashWindow {
}
private function handleKeyEvent (event:KeyboardEvent):Void {
var keyCode = convertKeyCode (event.keyCode);
var modifier = (event.shiftKey ? (KeyModifier.SHIFT) : 0) | (event.ctrlKey ? (KeyModifier.CTRL) : 0) | (event.altKey ? (KeyModifier.ALT) : 0);
if (event.type == KeyboardEvent.KEY_DOWN) {
parent.onKeyDown.dispatch (keyCode, modifier);
if (parent.enableTextEvents) {
parent.onTextInput.dispatch (String.fromCharCode (event.charCode));
}
} else {
parent.onKeyUp.dispatch (keyCode, modifier);
}
}
private function handleMouseEvent (event:MouseEvent):Void {
var button = switch (event.type) {
case "middleMouseDown", "middleMouseUp": 1;
case "rightMouseDown", "rightMouseUp": 2;
default: 0;
}
switch (event.type) {
case "mouseDown", "middleMouseDown", "rightMouseDown":
parent.onMouseDown.dispatch (event.stageX, event.stageY, button);
case "mouseMove":
if (mouseLeft) {
mouseLeft = false;
parent.onEnter.dispatch ();
}
var mouseX = event.stageX;
var mouseY = event.stageY;
parent.onMouseMove.dispatch (mouseX, mouseY);
parent.onMouseMoveRelative.dispatch (mouseX - cacheMouseX, mouseY - cacheMouseY);
cacheMouseX = mouseX;
cacheMouseY = mouseY;
case "mouseUp", "middleMouseUp", "rightMouseUp":
parent.onMouseUp.dispatch (event.stageX, event.stageY, button);
case "mouseWheel":
parent.onMouseWheel.dispatch (0, event.delta);
default:
}
}
private function handleTouchEvent (event:TouchEvent):Void {
var x = event.stageX;
var y = event.stageY;
switch (event.type) {
case TouchEvent.TOUCH_BEGIN:
var touch = unusedTouchesPool.pop ();
if (touch == null) {
touch = new Touch (x / parent.__width, y / parent.__height, event.touchPointID, 0, 0, event.pressure, parent.id);
} else {
touch.x = x / parent.__width;
touch.y = y / parent.__height;
touch.id = event.touchPointID;
touch.dx = 0;
touch.dy = 0;
touch.pressure = event.pressure;
touch.device = parent.id;
}
currentTouches.set (event.touchPointID, touch);
Touch.onStart.dispatch (touch);
if (event.isPrimaryTouchPoint) {
parent.onMouseDown.dispatch (x, y, 0);
}
case TouchEvent.TOUCH_END:
var touch = currentTouches.get (event.touchPointID);
if (touch != null) {
var cacheX = touch.x;
var cacheY = touch.y;
touch.x = x / parent.__width;
touch.y = y / parent.__height;
touch.dx = touch.x - cacheX;
touch.dy = touch.y - cacheY;
touch.pressure = event.pressure;
Touch.onEnd.dispatch (touch);
currentTouches.remove (event.touchPointID);
unusedTouchesPool.add (touch);
if (event.isPrimaryTouchPoint) {
parent.onMouseUp.dispatch (x, y, 0);
}
}
case TouchEvent.TOUCH_MOVE:
var touch = currentTouches.get (event.touchPointID);
if (touch != null) {
var cacheX = touch.x;
var cacheY = touch.y;
touch.x = x / parent.__width;
touch.y = y / parent.__height;
touch.dx = touch.x - cacheX;
touch.dy = touch.y - cacheY;
touch.pressure = event.pressure;
Touch.onMove.dispatch (touch);
if (event.isPrimaryTouchPoint) {
parent.onMouseMove.dispatch (x, y);
}
}
}
}
private function handleWindowEvent (event:Event):Void {
switch (event.type) {
case Event.ACTIVATE:
parent.onActivate.dispatch ();
case Event.DEACTIVATE:
parent.onDeactivate.dispatch ();
case FocusEvent.FOCUS_IN:
parent.onFocusIn.dispatch ();
case FocusEvent.FOCUS_OUT:
parent.onFocusOut.dispatch ();
case Event.MOUSE_LEAVE:
mouseLeft = true;
parent.onLeave.dispatch ();
case Event.RESIZE:
parent.__width = parent.stage.stageWidth;
parent.__height = parent.stage.stageHeight;
parent.onResize.dispatch (parent.__width, parent.__height);
default:
}
}
public function setDisplayMode (value:DisplayMode):DisplayMode {
return value;
@@ -119,6 +443,7 @@ class FlashWindow {
public function setFullscreen (value:Bool):Bool {
parent.stage.displayState = (value ? FULL_SCREEN_INTERACTIVE : NORMAL);
return value;
}

View File

@@ -2,16 +2,7 @@ package lime.app;
import lime.graphics.Renderer;
import lime.graphics.RenderContext;
import lime.system.System;
import lime.ui.Gamepad;
import lime.ui.GamepadAxis;
import lime.ui.GamepadButton;
import lime.ui.Joystick;
import lime.ui.JoystickHatPosition;
import lime.ui.KeyCode;
import lime.ui.KeyModifier;
import lime.ui.Touch;
import lime.ui.Window;
#if !lime_debug
@@ -198,7 +189,7 @@ class Application extends Module {
var window = new Window (windowConfig);
createWindow (window);
#if (flash || html5)
#if ((flash && !air) || html5)
break;
#end
@@ -402,7 +393,9 @@ class Application extends Module {
}
#if flash
#if air
@:noCompletion private typedef ApplicationBackend = lime._backend.air.AIRApplication;
#elseif flash
@:noCompletion private typedef ApplicationBackend = lime._backend.flash.FlashApplication;
#elseif (js && html5)
@:noCompletion private typedef ApplicationBackend = lime._backend.html5.HTML5Application;

View File

@@ -16,6 +16,10 @@ import flash.system.Capabilities;
import flash.Lib;
#end
#if air
import flash.desktop.NativeApplication;
#end
#if (js && html5)
import js.html.Element;
import js.Browser;
@@ -163,12 +167,9 @@ class System {
public static function exit (code:Int):Void {
#if (sys && !macro)
#if ((sys || air) && !macro)
if (Application.current != null) {
// TODO: Clean exit?
Application.current.onExit.dispatch (code);
if (Application.current.onExit.canceled) {
@@ -178,9 +179,12 @@ class System {
}
}
#end
#if sys
Sys.exit (code);
#elseif air
NativeApplication.nativeApplication.exit (code);
#end
}

View File

@@ -1,6 +1,7 @@
package lime.system;
import haxe.Constraints.Function;
import lime.app.Application;
import lime.app.Event;
@@ -22,13 +23,13 @@ class ThreadPool {
public var currentThreads (default, null):Int;
public var doWork = new Event<Dynamic->Void> ();
public var doWork = new Event<Function->Void> ();
public var maxThreads:Int;
public var minThreads:Int;
public var onComplete = new Event<Dynamic->Void> ();
public var onError = new Event<Dynamic->Void> ();
public var onProgress = new Event<Dynamic->Void> ();
public var onRun = new Event<Dynamic->Void> ();
public var onComplete = new Event<Function->Void> ();
public var onError = new Event<Function->Void> ();
public var onProgress = new Event<Function->Void> ();
public var onRun = new Event<Function->Void> ();
#if (cpp || neko)
private var __synchronous:Bool;

View File

@@ -603,7 +603,9 @@ class Window {
}
#if flash
#if air
@:noCompletion private typedef WindowBackend = lime._backend.air.AIRWindow;
#elseif flash
@:noCompletion private typedef WindowBackend = lime._backend.flash.FlashWindow;
#elseif (js && html5)
@:noCompletion private typedef WindowBackend = lime._backend.html5.HTML5Window;

View File

@@ -10,21 +10,26 @@
<initialWindow>
<title>::APP_TITLE::</title>
<content>::APP_FILE::.swf</content>
<systemChrome>standard</systemChrome>
<systemChrome>::if (WIN_BORDERLESS)::none::else::standard::end::</systemChrome>
<transparent>false</transparent>
<visible>true</visible>
<visible>::if (WIN_HIDDEN)::false::else::true::end::</visible>
<minimizable>true</minimizable>
<maximizable>false</maximizable>
<maximizable>true</maximizable>
<resizable>::WIN_RESIZABLE::</resizable>
<!-- <width>::WIN_WIDTH::</width>
<height>::WIN_HEIGHT::</height>
<minSize>320 240</minSize>
::if (WIN_WIDTH != 0)::<width>::WIN_WIDTH::</width>::end::
::if (WIN_HEIGHT != 0)::<height>::WIN_HEIGHT::</height>::end::
<!-- <minSize>320 240</minSize>
<maxSize>1280 960</maxSize> -->
<renderMode>direct</renderMode>
<!-- <autoOrients>false</autoOrients>
<aspectRatio>landscape</aspectRatio>
<fullScreen>true</fullScreen> -->
<depthAndStencil>true</depthAndStencil>
<renderMode>::if (WIN_HARDWARE)::direct::else::cpu::end::</renderMode>
::if (WIN_ORIENTATION == "auto")::
<autoOrients>true</autoOrients>
<aspectRatio>any</aspectRatio>
::else::
<autoOrients>false</autoOrients>
<aspectRatio>::if (WIN_ORIENTATION == "portrait")::portrait::else::landscape::end::</aspectRatio>
::end::
<fullScreen>::WIN_FULLSCREEN::</fullScreen>
::if (WIN_HARDWARE)::<depthAndStencil>true</depthAndStencil>::end::
</initialWindow>
<installFolder>::APP_COMPANY::/::APP_TITLE::</installFolder>
<programMenuFolder>::APP_TITLE::</programMenuFolder>