Expose stage and element on Window (Flash and HTML5), restore AIR multi-window support

This commit is contained in:
Joshua Granick
2018-07-12 12:20:08 -07:00
parent c4e3224c00
commit 8a6a0922eb
6 changed files with 114 additions and 63 deletions

View File

@@ -9,10 +9,12 @@ import flash.display.NativeWindowSystemChrome;
import flash.events.Event;
import flash.html.HTMLLoader;
import flash.Lib;
import lime._internal.backend.flash.FlashApplication;
import lime._internal.backend.flash.FlashWindow;
import lime.app.Application;
import lime.ui.Window;
@:access(lime._internal.backend.flash.FlashApplication)
@:access(lime.ui.Window)
@@ -85,45 +87,52 @@ class AIRWindow extends FlashWindow {
var minimized = false;
var resizable = false;
var frameRate = 60.0;
var width = 0;
var height = 0;
if (Reflect.hasField (attributes, "alwaysOnTop") && attributes.alwaysOnTop) alwaysOnTop = true;
if (Reflect.hasField (attributes, "borderless") && attributes.borderless) borderless = true;
if (Reflect.hasField (attributes, "fullscreen") && attributes.fullscreen) fullscreen;
if (Reflect.hasField (attributes, "fullscreen") && attributes.fullscreen) fullscreen = true;
if (Reflect.hasField (attributes, "context") && Reflect.hasField (attributes.context, "hardware") && attributes.context.hardware) hardware = true;
if (Reflect.hasField (attributes, "hidden") && attributes.hidden) hidden = true;
if (Reflect.hasField (attributes, "maximized") && attributes.maximized) maximized = true;
if (Reflect.hasField (attributes, "minimized") && attributes.minimized) minimized = true;
if (Reflect.hasField (attributes, "resizable") && attributes.resizable) resizable;
if (Reflect.hasField (attributes, "resizable") && attributes.resizable) resizable = true;
// if (parent.config != null && (parent.config == application.config.windows[0])) {
if (Reflect.hasField (attributes, "frameRate")) frameRate = attributes.frameRate;
if (Reflect.hasField (attributes, "width")) width = attributes.width;
if (Reflect.hasField (attributes, "height")) height = attributes.height;
if (FlashApplication.createFirstWindow) {
nativeWindow = Lib.current.stage.nativeWindow;
// TODO
// } else {
} else {
// var options = new NativeWindowInitOptions ();
// options.systemChrome = borderless ? NativeWindowSystemChrome.NONE : NativeWindowSystemChrome.STANDARD;
// options.renderMode = hardware ? NativeWindowRenderMode.DIRECT : NativeWindowRenderMode.CPU;
// options.transparent = false;
// options.maximizable = true;
// options.minimizable = true;
// options.resizable = resizable;
var options = new NativeWindowInitOptions ();
options.systemChrome = borderless ? NativeWindowSystemChrome.NONE : NativeWindowSystemChrome.STANDARD;
options.renderMode = hardware ? NativeWindowRenderMode.DIRECT : NativeWindowRenderMode.CPU;
options.transparent = false;
options.maximizable = maximized;
options.minimizable = minimized;
options.resizable = resizable;
// nativeWindow = new NativeWindow (options);
// nativeWindow.stage.frameRate = application.frameRate;
nativeWindow = new NativeWindow (options);
nativeWindow.stage.frameRate = frameRate;
// if (parent.width > 0) nativeWindow.width = parent.width;
// if (parent.height > 0) nativeWindow.height = parent.height;
if (width > 0) nativeWindow.width = width;
if (height > 0) nativeWindow.height = height;
// }
}
if (nativeWindow != null) {
parent.stage = nativeWindow.stage;
nativeWindow.addEventListener (Event.CLOSING, handleNativeWindowEvent);
nativeWindow.addEventListener (Event.CLOSE, handleNativeWindowEvent);
// nativeWindow.addEventListener (Event.RESIZE, handleWindowEvent);
nativeWindow.visible = !hidden;
//nativeWindow.activate ();
@@ -154,12 +163,20 @@ class AIRWindow extends FlashWindow {
parent.__height = Std.int (nativeWindow.height);
parent.__x = Math.round (nativeWindow.x);
parent.__y = Math.round (nativeWindow.y);
stage = nativeWindow.stage;
parent.stage = nativeWindow.stage;
}
super.create ();
if (hardware) {
parent.context.attributes.hardware = true;
parent.context.attributes.depth = true;
parent.context.attributes.stencil = true;
}
}
@@ -194,6 +211,18 @@ class AIRWindow extends FlashWindow {
closing = true;
parent.onClose.dispatch ();
// case Event.RESIZE:
// // TODO: Should this be the inner (stageWidth) or outer (nativeWindow width) size?
// parent.__width = parent.stage.stageWidth;
// parent.__height = parent.stage.stageHeight;
// // parent.__width = nativeWindow.width;
// // parent.__height = nativeWindow.height;
// parent.onResize.dispatch (parent.__width, parent.__height);
default:
}

View File

@@ -13,6 +13,8 @@ import lime.ui.Window;
class FlashApplication {
private static var createFirstWindow:Bool;
private var parent:Application;
private var requestedWindow:Bool;
@@ -23,8 +25,10 @@ class FlashApplication {
AudioManager.init ();
createFirstWindow = true;
// Initial window is already created
parent.createWindow ({});
createFirstWindow = false;
}

View File

@@ -29,6 +29,7 @@ import lime.system.DisplayMode;
import lime.system.System;
import lime.ui.Window;
@:access(lime._internal.backend.flash.FlashApplication)
@:access(lime.app.Application)
@:access(lime.graphics.RenderContext)
@:access(lime.ui.Window)
@@ -47,7 +48,6 @@ class FlashWindow {
private var frameRate:Float;
private var mouseLeft:Bool;
private var parent:Window;
private var stage:Stage;
private var textInputEnabled:Bool;
private var unusedTouchesPool = new List<Touch> ();
@@ -156,13 +156,14 @@ class FlashWindow {
private function create ():Void {
if (#if air true #else parent.application.__window == null #end) {
if (#if air true #else FlashApplication.createFirstWindow #end) {
var attributes = parent.__attributes;
parent.id = windowID++;
if (stage == null) stage = Lib.current.stage;
if (parent.stage == null) parent.stage = Lib.current.stage;
var stage = parent.stage;
parent.__width = stage.stageWidth;
parent.__height = stage.stageHeight;
@@ -189,7 +190,10 @@ class FlashWindow {
stage.addEventListener (FocusEvent.FOCUS_IN, handleWindowEvent);
stage.addEventListener (FocusEvent.FOCUS_OUT, handleWindowEvent);
stage.addEventListener (Event.MOUSE_LEAVE, handleWindowEvent);
// #if !air
stage.addEventListener (Event.RESIZE, handleWindowEvent);
// #end
var context = new RenderContext ();
context.flash = Lib.current;
@@ -471,8 +475,8 @@ class FlashWindow {
case Event.RESIZE:
parent.__width = stage.stageWidth;
parent.__height = stage.stageHeight;
parent.__width = parent.stage.stageWidth;
parent.__height = parent.stage.stageHeight;
parent.onResize.dispatch (parent.__width, parent.__height);
@@ -487,11 +491,11 @@ class FlashWindow {
if (rect == null) {
rect = new Rectangle (0, 0, stage.stageWidth, stage.stageHeight);
rect = new Rectangle (0, 0, parent.stage.stageWidth, parent.stage.stageHeight);
} else {
rect.__contract (0, 0, stage.stageWidth, stage.stageHeight);
rect.__contract (0, 0, parent.stage.stageWidth, parent.stage.stageHeight);
}
@@ -503,7 +507,7 @@ class FlashWindow {
matrix.tx = -rect.x;
matrix.ty = -rect.y;
bitmapData.draw (stage, matrix);
bitmapData.draw (parent.stage, matrix);
return Image.fromBitmapData (bitmapData);
@@ -612,7 +616,7 @@ class FlashWindow {
public function setFrameRate (value:Float):Float {
frameRate = value;
if (stage != null) stage.frameRate = value;
if (parent.stage != null) parent.stage.frameRate = value;
return value;
}
@@ -620,7 +624,7 @@ class FlashWindow {
public function setFullscreen (value:Bool):Bool {
stage.displayState = (value ? FULL_SCREEN_INTERACTIVE : NORMAL);
parent.stage.displayState = (value ? FULL_SCREEN_INTERACTIVE : NORMAL);
return value;
}

View File

@@ -54,7 +54,6 @@ class HTML5Window {
public var canvas:CanvasElement;
public var div:DivElement;
public var element:Element;
#if stats
public var stats:Dynamic;
#end
@@ -91,10 +90,12 @@ class HTML5Window {
if (Reflect.hasField (attributes, "element")) {
element = attributes.element;
parent.element = attributes.element;
}
var element = parent.element;
#if dom
attributes.context.type = DOM;
attributes.context.version = "";
@@ -587,7 +588,7 @@ class HTML5Window {
if (event.type != "wheel") {
if (element != null) {
if (parent.element != null) {
if (canvas != null) {
@@ -605,7 +606,7 @@ class HTML5Window {
} else {
var rect = element.getBoundingClientRect ();
var rect = parent.element.getBoundingClientRect ();
x = (event.clientX - rect.left) * (parent.__width / rect.width);
y = (event.clientY - rect.top) * (parent.__height / rect.height);
@@ -622,7 +623,7 @@ class HTML5Window {
case "mousedown":
if (event.currentTarget == element) {
if (event.currentTarget == parent.element) {
// Release outside browser window
Browser.window.addEventListener ("mouseup", handleMouseEvent);
@@ -639,7 +640,7 @@ class HTML5Window {
case "mouseenter":
if (event.target == element) {
if (event.target == parent.element) {
parent.onEnter.dispatch ();
@@ -653,7 +654,7 @@ class HTML5Window {
case "mouseleave":
if (event.target == element) {
if (event.target == parent.element) {
parent.onLeave.dispatch ();
@@ -669,7 +670,7 @@ class HTML5Window {
Browser.window.removeEventListener ("mouseup", handleMouseEvent);
if (event.currentTarget == element) {
if (event.currentTarget == parent.element) {
event.stopPropagation ();
@@ -754,7 +755,7 @@ class HTML5Window {
var rect = null;
if (element != null) {
if (parent.element != null) {
if (canvas != null) {
@@ -766,7 +767,7 @@ class HTML5Window {
} else {
rect = element.getBoundingClientRect ();
rect = parent.element.getBoundingClientRect ();
}
@@ -916,11 +917,11 @@ class HTML5Window {
private function isDescendent (node:Node):Bool {
if (node == element) return true;
if (node == parent.element) return true;
while (node != null) {
if (node.parentNode == element) {
if (node.parentNode == parent.element) {
return true;
@@ -1021,11 +1022,11 @@ class HTML5Window {
if (value == null) {
element.style.cursor = null;
parent.element.style.cursor = null;
} else {
element.style.cursor = switch (value) {
parent.element.style.cursor = switch (value) {
case ARROW: "default";
case CROSSHAIR: "crosshair";
@@ -1095,29 +1096,29 @@ class HTML5Window {
untyped {
if (element.requestFullscreen) {
if (parent.element.requestFullscreen) {
document.addEventListener ("fullscreenchange", handleFullscreenEvent, false);
document.addEventListener ("fullscreenerror", handleFullscreenEvent, false);
element.requestFullscreen ();
parent.element.requestFullscreen ();
} else if (element.mozRequestFullScreen) {
} else if (parent.element.mozRequestFullScreen) {
document.addEventListener ("mozfullscreenchange", handleFullscreenEvent, false);
document.addEventListener ("mozfullscreenerror", handleFullscreenEvent, false);
element.mozRequestFullScreen ();
parent.element.mozRequestFullScreen ();
} else if (element.webkitRequestFullscreen) {
} else if (parent.element.webkitRequestFullscreen) {
document.addEventListener ("webkitfullscreenchange", handleFullscreenEvent, false);
document.addEventListener ("webkitfullscreenerror", handleFullscreenEvent, false);
element.webkitRequestFullscreen ();
parent.element.webkitRequestFullscreen ();
} else if (element.msRequestFullscreen) {
} else if (parent.element.msRequestFullscreen) {
document.addEventListener ("MSFullscreenChange", handleFullscreenEvent, false);
document.addEventListener ("MSFullscreenError", handleFullscreenEvent, false);
element.msRequestFullscreen ();
parent.element.msRequestFullscreen ();
}
@@ -1247,7 +1248,7 @@ class HTML5Window {
if (textInput.parentNode == null) {
element.appendChild (textInput);
parent.element.appendChild (textInput);
}
@@ -1319,10 +1320,10 @@ class HTML5Window {
var elementWidth, elementHeight;
if (element != null) {
if (parent.element != null) {
elementWidth = element.clientWidth;
elementHeight = element.clientHeight;
elementWidth = parent.element.clientWidth;
elementHeight = parent.element.clientHeight;
} else {
@@ -1338,7 +1339,7 @@ class HTML5Window {
var stretch = resizeElement || (setWidth == 0 && setHeight == 0);
if (element != null && (div == null || (div != null && stretch))) {
if (parent.element != null && (div == null || (div != null && stretch))) {
if (stretch) {
@@ -1349,7 +1350,7 @@ class HTML5Window {
if (canvas != null) {
if (element != cast canvas) {
if (parent.element != cast canvas) {
canvas.width = Math.round (elementWidth * scale);
canvas.height = Math.round (elementHeight * scale);
@@ -1394,7 +1395,7 @@ class HTML5Window {
if (canvas != null) {
if (element != cast canvas) {
if (parent.element != cast canvas) {
canvas.style.width = targetWidth + "px";
canvas.style.height = targetHeight + "px";

View File

@@ -18,6 +18,10 @@ import flash.display.Stage;
typedef Stage = Dynamic;
#end
#if (js && html5)
import js.html.Element;
#end
#if hl
@:keep
#end
@@ -38,6 +42,10 @@ class Window {
public var display (get, null):Display;
public var displayMode (get, set):DisplayMode;
#if (!lime_doc_gen || (js && html5))
public var element (default, null):#if (js && html5) Element #else Dynamic #end;
#end
/**
* The current frame rate (measured in frames-per-second) of the window.
*
@@ -83,7 +91,11 @@ class Window {
public var parameters:Dynamic;
public var resizable (get, set):Bool;
public var scale (get, null):Float;
// public var stage:Stage;
#if (!lime_doc_gen || flash || openfl)
public var stage (default, null):Stage;
#end
public var textInputEnabled (get, set):Bool;
public var title (get, set):String;
public var width (get, set):Int;

View File

@@ -33,11 +33,7 @@ import ::APP_MAIN::;
app.meta.set ("name", "::meta.title::");
app.meta.set ("packageName", "::meta.packageName::");
#if (flash && !air)
app.window.context.attributes.background = ::WIN_BACKGROUND::;
app.window.frameRate = ::WIN_FPS::;
#else
#if !flash
::foreach windows::
var attributes:lime.ui.WindowAttributes = {
@@ -102,6 +98,11 @@ import ::APP_MAIN::;
app.createWindow (attributes);
::end::
#elseif flash
app.window.context.attributes.background = ::WIN_BACKGROUND::;
app.window.frameRate = ::WIN_FPS::;
#end
#end