mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #6780 from jherico/z_order
Address some z-ordering issues in overlay windows
This commit is contained in:
commit
a78d5274e7
7 changed files with 217 additions and 33 deletions
|
@ -8,33 +8,6 @@ qmlWindow = new OverlayWindow({
|
|||
visible: true
|
||||
});
|
||||
|
||||
//qmlWindow.eventBridge.webEventReceived.connect(function(data) {
|
||||
// print("JS Side event received: " + data);
|
||||
//});
|
||||
//
|
||||
//var titles = ["A", "B", "C"];
|
||||
//var titleIndex = 0;
|
||||
//
|
||||
//Script.setInterval(function() {
|
||||
// qmlWindow.eventBridge.emitScriptEvent("JS Event sent");
|
||||
// var size = qmlWindow.size;
|
||||
// var position = qmlWindow.position;
|
||||
// print("Window visible: " + qmlWindow.visible)
|
||||
// if (qmlWindow.visible) {
|
||||
// print("Window size: " + size.x + "x" + size.y)
|
||||
// print("Window pos: " + position.x + "x" + position.y)
|
||||
// qmlWindow.setVisible(false);
|
||||
// } else {
|
||||
// qmlWindow.setVisible(true);
|
||||
// qmlWindow.setTitle(titles[titleIndex]);
|
||||
// qmlWindow.setSize(320 + Math.random() * 100, 240 + Math.random() * 100);
|
||||
// titleIndex += 1;
|
||||
// titleIndex %= titles.length;
|
||||
// }
|
||||
//}, 2 * 1000);
|
||||
//
|
||||
//Script.setTimeout(function() {
|
||||
// print("Closing script");
|
||||
// qmlWindow.close();
|
||||
// Script.stop();
|
||||
//}, 15 * 1000)
|
||||
Script.setInterval(function() {
|
||||
qmlWindow.raise();
|
||||
}, 2 * 1000);
|
||||
|
|
|
@ -16,6 +16,7 @@ import "styles"
|
|||
DialogContainer {
|
||||
id: root
|
||||
HifiConstants { id: hifi }
|
||||
z: 1000
|
||||
|
||||
objectName: "AddressBarDialog"
|
||||
|
||||
|
@ -150,6 +151,17 @@ DialogContainer {
|
|||
addressLine.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
running: root.enabled
|
||||
interval: 500
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (root.enabled && !addressLine.activeFocus) {
|
||||
addressLine.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
|
|
165
interface/resources/qml/Global.js
Normal file
165
interface/resources/qml/Global.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
var OFFSCREEN_ROOT_OBJECT_NAME = "desktopRoot"
|
||||
var OFFSCREEN_WINDOW_OBJECT_NAME = "topLevelWindow"
|
||||
|
||||
function findChild(item, name) {
|
||||
for (var i = 0; i < item.children.length; ++i) {
|
||||
if (item.children[i].objectName === name) {
|
||||
return item.children[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function findParent(item, name) {
|
||||
while (item) {
|
||||
if (item.objectName === name) {
|
||||
return item;
|
||||
}
|
||||
item = item.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getDesktop(item) {
|
||||
return findParent(item, OFFSCREEN_ROOT_OBJECT_NAME);
|
||||
}
|
||||
|
||||
function findRootMenu(item) {
|
||||
item = getDesktop(item);
|
||||
return item ? item.rootMenu : null;
|
||||
}
|
||||
|
||||
|
||||
function getTopLevelWindows(item) {
|
||||
var desktop = getDesktop(item);
|
||||
var currentWindows = [];
|
||||
if (!desktop) {
|
||||
console.log("Could not find desktop for " + item)
|
||||
return currentWindows;
|
||||
}
|
||||
|
||||
for (var i = 0; i < desktop.children.length; ++i) {
|
||||
var child = desktop.children[i];
|
||||
if (Global.OFFSCREEN_WINDOW_OBJECT_NAME === child.objectName) {
|
||||
var windowId = child.toString();
|
||||
currentWindows.push(child)
|
||||
}
|
||||
}
|
||||
return currentWindows;
|
||||
}
|
||||
|
||||
|
||||
function getDesktopWindow(item) {
|
||||
item = findParent(item, OFFSCREEN_WINDOW_OBJECT_NAME);
|
||||
return item;
|
||||
}
|
||||
|
||||
function closeWindow(item) {
|
||||
item = findDialog(item);
|
||||
if (item) {
|
||||
item.enabled = false
|
||||
} else {
|
||||
console.warn("Could not find top level dialog")
|
||||
}
|
||||
}
|
||||
|
||||
function findMenuChild(menu, childName) {
|
||||
if (!menu) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (menu.type !== 2) {
|
||||
console.warn("Tried to find child of a non-menu");
|
||||
return null;
|
||||
}
|
||||
|
||||
var items = menu.items;
|
||||
var count = items.length;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
var child = items[i];
|
||||
var name;
|
||||
switch (child.type) {
|
||||
case 2:
|
||||
name = child.title;
|
||||
break;
|
||||
case 1:
|
||||
name = child.text;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (name && name === childName) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findMenu(rootMenu, path) {
|
||||
if ('string' === typeof(path)) {
|
||||
path = [ path ]
|
||||
}
|
||||
|
||||
var currentMenu = rootMenu;
|
||||
for (var i = 0; currentMenu && i < path.length; ++i) {
|
||||
currentMenu = findMenuChild(currentMenu, path[i]);
|
||||
}
|
||||
|
||||
return currentMenu;
|
||||
}
|
||||
|
||||
function findInRootMenu(item, path) {
|
||||
return findMenu(findRootMenu(item), path);
|
||||
}
|
||||
|
||||
|
||||
function menuItemsToListModel(parent, items) {
|
||||
var newListModel = Qt.createQmlObject('import QtQuick 2.5; ListModel {}', parent);
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
var item = items[i];
|
||||
switch (item.type) {
|
||||
case 2:
|
||||
newListModel.append({"type":item.type, "name": item.title, "item": item})
|
||||
break;
|
||||
case 1:
|
||||
newListModel.append({"type":item.type, "name": item.text, "item": item})
|
||||
break;
|
||||
case 0:
|
||||
newListModel.append({"type":item.type, "name": "-----", "item": item})
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newListModel;
|
||||
}
|
||||
|
||||
function raiseWindow(item) {
|
||||
var targetWindow = getDesktopWindow(item);
|
||||
if (!targetWindow) {
|
||||
console.warn("Could not find top level window for " + item);
|
||||
return;
|
||||
}
|
||||
|
||||
var desktop = getDesktop(targetWindow);
|
||||
if (!desktop) {
|
||||
//console.warn("Could not find desktop for window " + targetWindow);
|
||||
return;
|
||||
}
|
||||
|
||||
var maxZ = 0;
|
||||
var minZ = 100000;
|
||||
var windows = desktop.windows;
|
||||
windows.sort(function(a, b){
|
||||
return a.z - b.z;
|
||||
});
|
||||
var lastZ = -1;
|
||||
var lastTargetZ = -1;
|
||||
for (var i = 0; i < windows.length; ++i) {
|
||||
var window = windows[i];
|
||||
if (window.z > lastZ) {
|
||||
lastZ = window.z;
|
||||
++lastTargetZ;
|
||||
}
|
||||
window.z = lastTargetZ;
|
||||
}
|
||||
targetWindow.z = lastTargetZ + 1;
|
||||
}
|
|
@ -5,6 +5,8 @@ import QtWebChannel 1.0
|
|||
import QtWebSockets 1.0
|
||||
import "qrc:///qtwebchannel/qwebchannel.js" as WebChannel
|
||||
|
||||
import "Global.js" as Global
|
||||
|
||||
import "controls"
|
||||
import "styles"
|
||||
|
||||
|
@ -23,6 +25,10 @@ VrDialog {
|
|||
contentImplicitWidth: clientArea.implicitWidth
|
||||
contentImplicitHeight: clientArea.implicitHeight
|
||||
property alias source: pageLoader.source
|
||||
|
||||
function raiseWindow() {
|
||||
Global.raiseWindow(root)
|
||||
}
|
||||
|
||||
Item {
|
||||
id: clientArea
|
||||
|
|
|
@ -2,16 +2,23 @@ import Hifi 1.0
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
import "Global.js" as Global
|
||||
|
||||
// This is our primary 'window' object to which all dialogs and controls will
|
||||
// be childed.
|
||||
Root {
|
||||
id: root
|
||||
objectName: "desktopRoot"
|
||||
anchors.fill: parent
|
||||
objectName: Global.OFFSCREEN_ROOT_OBJECT_NAME
|
||||
anchors.fill: parent;
|
||||
property var windows: [];
|
||||
property var rootMenu: Menu {
|
||||
objectName: "rootMenu"
|
||||
}
|
||||
|
||||
onChildrenChanged: {
|
||||
windows = Global.getTopLevelWindows(root);
|
||||
}
|
||||
|
||||
onParentChanged: {
|
||||
forceActiveFocus();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ import QtQuick.Controls 1.2
|
|||
import "."
|
||||
import "../styles"
|
||||
|
||||
import "../Global.js" as Global
|
||||
|
||||
/*
|
||||
* FIXME Need to create a client property here so that objects can be
|
||||
* placed in it without having to think about positioning within the outer
|
||||
|
@ -45,9 +47,18 @@ DialogBase {
|
|||
// trigger making it visible.
|
||||
if (enabled) {
|
||||
visible = true;
|
||||
if (root.parent) {
|
||||
Global.raiseWindow(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onParentChanged: {
|
||||
if (enabled && parent) {
|
||||
Global.raiseWindow(root);
|
||||
}
|
||||
}
|
||||
|
||||
// The actual animator
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
|
@ -60,6 +71,12 @@ DialogBase {
|
|||
onOpacityChanged: {
|
||||
visible = (opacity != 0.0);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (visible) {
|
||||
Global.raiseWindow(root);
|
||||
}
|
||||
}
|
||||
|
||||
// Some dialogs should be destroyed when they become invisible,
|
||||
// so handle that
|
||||
|
@ -118,6 +135,7 @@ DialogBase {
|
|||
y: root.titleY
|
||||
width: root.titleWidth
|
||||
height: root.titleHeight
|
||||
onClicked: Global.raiseWindow(root)
|
||||
|
||||
drag {
|
||||
target: root
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include <QtQuick/QQuickItem>
|
||||
#include <QtQml/QQmlContext>
|
||||
#include <QtQml/QQmlEngine>
|
||||
|
||||
#include <QtWebSockets/QWebSocketServer>
|
||||
#include <QtWebSockets/QWebSocket>
|
||||
|
@ -140,6 +142,7 @@ QScriptValue QmlWindowClass::internalConstructor(const QString& qmlSource,
|
|||
Q_ARG(std::function<void(QQmlContext*, QObject*)>, [&](QQmlContext* context, QObject* object) {
|
||||
setupServer();
|
||||
retVal = function(context, object);
|
||||
context->engine()->setObjectOwnership(retVal->_qmlWindow, QQmlEngine::CppOwnership);
|
||||
registerObject(url.toLower(), retVal);
|
||||
if (!title.isEmpty()) {
|
||||
retVal->setTitle(title);
|
||||
|
@ -273,7 +276,7 @@ void QmlWindowClass::hasClosed() {
|
|||
}
|
||||
|
||||
void QmlWindowClass::raise() {
|
||||
// FIXME
|
||||
QMetaObject::invokeMethod(_qmlWindow, "raiseWindow", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
#include "QmlWindowClass.moc"
|
||||
|
|
Loading…
Reference in a new issue