introduce scriptable presentationMode instead of automatic mode switching windows

This commit is contained in:
Thijs Wenker 2018-07-03 16:49:49 +02:00
parent c6e264edac
commit 7390983721
6 changed files with 219 additions and 139 deletions

View file

@ -9,7 +9,6 @@
// //
import QtQuick 2.3 import QtQuick 2.3
import InteractiveWindowFlags 1.0
import "windows" as Windows import "windows" as Windows
import "controls" import "controls"
@ -47,33 +46,9 @@ Windows.Window {
property bool keyboardRaised: false; property bool keyboardRaised: false;
property bool punctuationMode: false; property bool punctuationMode: false;
readonly property int modeNotSet: 0; property int presentationMode: 0;
readonly property int modeNative: 1;
readonly property int modeVirtual: 2;
property int windowMode: modeNotSet;
property bool forceNative: false;
property bool forceVirtual: false;
property string windowModeText: getModeString();
function getModeString() {
switch (windowMode) {
case modeNotSet:
return "none";
case modeNative:
return "native";
case modeVirtual:
return "virtual";
}
return "unknown";
}
onWindowModeChanged: {
windowModeText = getModeString();
}
property var initialized: false;
onSourceChanged: { onSourceChanged: {
if (dynamicContent) { if (dynamicContent) {
dynamicContent.destroy(); dynamicContent.destroy();
@ -88,117 +63,108 @@ Windows.Window {
} }
function updateInteractiveWindowPositionForMode() { function updateInteractiveWindowPositionForMode() {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
x = interactiveWindowPosition.x; x = interactiveWindowPosition.x;
y = interactiveWindowPosition.y; y = interactiveWindowPosition.y;
} else if (windowMode === modeVirtual && nativeWindow) { } else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
nativeWindow.x = interactiveWindowPosition.x; nativeWindow.x = interactiveWindowPosition.x;
nativeWindow.y = interactiveWindowPosition.y; nativeWindow.y = interactiveWindowPosition.y;
} }
} }
function updateInteractiveWindowSizeForMode() { function updateInteractiveWindowSizeForMode() {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
width = interactiveWindowSize.width; width = interactiveWindowSize.width;
height = interactiveWindowSize.height; height = interactiveWindowSize.height;
} else if (windowMode === modeVirtual && nativeWindow) { } else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
nativeWindow.width = interactiveWindowSize.width; nativeWindow.width = interactiveWindowSize.width;
nativeWindow.height = interactiveWindowSize.heigth; nativeWindow.height = interactiveWindowSize.height;
} }
} }
function trySwitchWindowMode() { function setupPresentationMode() {
if (windowMode !== modeVirtual && (HMD.active || (forceVirtual && !forceNative))) { console.warn(presentationMode);
windowMode = modeVirtual; if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
if (nativeWindow) { if (nativeWindow) {
nativeWindow.setVisible(false); nativeWindow.setVisible(false);
} }
contentHolder.parent = root; contentHolder.parent = root;
updateInteractiveWindowPositionForMode(); updateInteractiveWindowPositionForMode();
shown = interactiveWindowVisible; shown = interactiveWindowVisible;
} else if (windowMode !== modeNative && (!HMD.active || (forceNative && !forceVirtual))) { } else if (presentationMode === Desktop.PresentationMode.NATIVE) {
windowMode = modeNative;
shown = false; shown = false;
if (nativeWindow) { if (nativeWindow) {
contentHolder.parent = nativeWindow.contentItem; contentHolder.parent = nativeWindow.contentItem;
nativeWindow.setVisible(interactiveWindowVisible); nativeWindow.setVisible(interactiveWindowVisible);
updateInteractiveWindowPositionForMode(); updateInteractiveWindowPositionForMode();
} }
} else if (windowMode === modeNotSet) { } else if (presentationMode === modeNotSet) {
console.error("windowMode should be set."); console.error("presentationMode should be set.");
} }
} }
function displayModeChanged(isHMD) {
trySwitchWindowMode();
}
Component.onCompleted: { Component.onCompleted: {
HMD.displayModeChanged.connect(displayModeChanged);
forceVirtual = (flags & InteractiveWindowFlags.ForceVirtual) === InteractiveWindowFlags.ForceVirtual;
forceNative = (flags & InteractiveWindowFlags.ForceNative) === InteractiveWindowFlags.ForceNative;
x = interactiveWindowPosition.x; x = interactiveWindowPosition.x;
y = interactiveWindowPosition.y; y = interactiveWindowPosition.y;
width = interactiveWindowSize.width; width = interactiveWindowSize.width;
height = interactiveWindowSize.height; height = interactiveWindowSize.height;
if (!forceVirtual || (forceVirtual && forceNative)) { nativeWindow = Qt.createQmlObject('
nativeWindow = Qt.createQmlObject(' import QtQuick 2.3;
import QtQuick 2.3; import QtQuick.Window 2.3;
import QtQuick.Window 2.3;
Window { Window {
id: root; id: root;
Rectangle { Rectangle {
color: hifi.colors.baseGray color: hifi.colors.baseGray
anchors.fill: parent anchors.fill: parent
}
}', root, 'InteractiveWindow.qml->nativeWindow');
nativeWindow.title = root.title;
var nativeWindowFlags = Qt.Window |
Qt.WindowTitleHint |
Qt.WindowSystemMenuHint |
Qt.WindowCloseButtonHint |
Qt.WindowMaximizeButtonHint |
Qt.WindowMinimizeButtonHint;
if ((flags & InteractiveWindowFlags.AlwaysOnTop) === InteractiveWindowFlags.AlwaysOnTop) {
nativeWindowFlags |= Qt.WindowStaysOnTopHint;
}
nativeWindow.flags = nativeWindowFlags;
nativeWindow.x = interactiveWindowPosition.x;
nativeWindow.y = interactiveWindowPosition.y;
nativeWindow.width = interactiveWindowSize.width;
nativeWindow.height = interactiveWindowSize.height;
nativeWindow.xChanged.connect(function() {
if (windowMode === modeNative && nativeWindow.visible) {
interactiveWindowPosition = Qt.point(nativeWindow.x, interactiveWindowPosition.y);
} }
}); }', root, 'InteractiveWindow.qml->nativeWindow');
nativeWindow.yChanged.connect(function() { nativeWindow.title = root.title;
if (windowMode === modeNative && nativeWindow.visible) { var nativeWindowFlags = Qt.Window |
interactiveWindowPosition = Qt.point(interactiveWindowPosition.x, nativeWindow.y); Qt.WindowTitleHint |
} Qt.WindowSystemMenuHint |
}); Qt.WindowCloseButtonHint |
Qt.WindowMaximizeButtonHint |
nativeWindow.widthChanged.connect(function() { Qt.WindowMinimizeButtonHint;
if (windowMode === modeNative && nativeWindow.visible) { if ((flags & Desktop.ALWAYS_ON_TOP) === Desktop.ALWAYS_ON_TOP) {
interactiveWindowSize = Qt.size(nativeWindow.width, interactiveWindowSize.height); nativeWindowFlags |= Qt.WindowStaysOnTopHint;
}
});
nativeWindow.heightChanged.connect(function() {
if (windowMode === modeNative && nativeWindow.visible) {
interactiveWindowSize = Qt.size(interactiveWindowSize.width, nativeWindow.height);
}
});
} }
nativeWindow.flags = nativeWindowFlags;
nativeWindow.x = interactiveWindowPosition.x;
nativeWindow.y = interactiveWindowPosition.y;
nativeWindow.width = interactiveWindowSize.width;
nativeWindow.height = interactiveWindowSize.height;
nativeWindow.xChanged.connect(function() {
if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow.visible) {
interactiveWindowPosition = Qt.point(nativeWindow.x, interactiveWindowPosition.y);
}
});
nativeWindow.yChanged.connect(function() {
if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow.visible) {
interactiveWindowPosition = Qt.point(interactiveWindowPosition.x, nativeWindow.y);
}
});
nativeWindow.widthChanged.connect(function() {
if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow.visible) {
interactiveWindowSize = Qt.size(nativeWindow.width, interactiveWindowSize.height);
}
});
nativeWindow.heightChanged.connect(function() {
if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow.visible) {
interactiveWindowSize = Qt.size(interactiveWindowSize.width, nativeWindow.height);
}
});
// finally set the initial window mode: // finally set the initial window mode:
trySwitchWindowMode(); setupPresentationMode();
initialized = true;
} }
// Handle message traffic from the script that launched us to the loaded QML // Handle message traffic from the script that launched us to the loaded QML
@ -214,9 +180,9 @@ Windows.Window {
} }
function raiseWindow() { function raiseWindow() {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
raise(); raise();
} else if (windowMode === modeNative && nativeWindow) { } else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
nativeWindow.raise(); nativeWindow.raise();
} }
} }
@ -231,9 +197,9 @@ Windows.Window {
} }
onInteractiveWindowVisibleChanged: { onInteractiveWindowVisibleChanged: {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
shown = interactiveWindowVisible; shown = interactiveWindowVisible;
} else if (windowMode === modeNative && nativeWindow) { } else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
nativeWindow.setVisible(interactiveWindowVisible); nativeWindow.setVisible(interactiveWindowVisible);
} }
} }
@ -245,35 +211,42 @@ Windows.Window {
} }
onXChanged: { onXChanged: {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
interactiveWindowPosition = Qt.point(x, interactiveWindowPosition.y); interactiveWindowPosition = Qt.point(x, interactiveWindowPosition.y);
} }
} }
onYChanged: { onYChanged: {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
interactiveWindowPosition = Qt.point(interactiveWindowPosition.x, y); interactiveWindowPosition = Qt.point(interactiveWindowPosition.x, y);
} }
} }
onWidthChanged: { onWidthChanged: {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
interactiveWindowSize = Qt.size(width, interactiveWindowSize.height); interactiveWindowSize = Qt.size(width, interactiveWindowSize.height);
} }
} }
onHeightChanged: { onHeightChanged: {
if (windowMode === modeVirtual) { if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
interactiveWindowSize = Qt.size(interactiveWindowSize.width, height); interactiveWindowSize = Qt.size(interactiveWindowSize.width, height);
} }
} }
onInteractiveWindowPositionChanged: { onPresentationModeChanged: {
updateInteractiveWindowPositionForMode(); if (initialized) {
setupPresentationMode();
}
} }
onInteractiveWindowSizeChanged: { onWindowClosed: {
updateInteractiveWindowSizeForMode(); // set invisible on close, to make it not re-appear unintended after switching PresentationMode
interactiveWindowVisible = false;
}
onWindowDestroyed: {
console.warn("destroyed");
} }
Item { Item {

View file

@ -2828,8 +2828,6 @@ void Application::initializeUi() {
qmlRegisterType<Preference>("Hifi", 1, 0, "Preference"); qmlRegisterType<Preference>("Hifi", 1, 0, "Preference");
qmlRegisterType<WebBrowserSuggestionsEngine>("HifiWeb", 1, 0, "WebBrowserSuggestionsEngine"); qmlRegisterType<WebBrowserSuggestionsEngine>("HifiWeb", 1, 0, "WebBrowserSuggestionsEngine");
InteractiveWindowEnums::declareQML();
{ {
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
tabletScriptingInterface->getTablet(SYSTEM_TABLET); tabletScriptingInterface->getTablet(SYSTEM_TABLET);
@ -2978,6 +2976,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
surfaceContext->setContextProperty("Overlays", &_overlays); surfaceContext->setContextProperty("Overlays", &_overlays);
surfaceContext->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data()); surfaceContext->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data());
surfaceContext->setContextProperty("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
surfaceContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); surfaceContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance());
surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance());
surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data()); surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data());

View file

@ -31,6 +31,14 @@ int DesktopScriptingInterface::getHeight() {
return size.height(); return size.height();
} }
QVariantMap DesktopScriptingInterface::getPresentationMode() {
static QVariantMap presentationModes {
{ "VIRTUAL", Virtual },
{ "NATIVE", Native }
};
return presentationModes;
}
void DesktopScriptingInterface::setHUDAlpha(float alpha) { void DesktopScriptingInterface::setHUDAlpha(float alpha) {
qApp->getApplicationCompositor().setAlpha(alpha); qApp->getApplicationCompositor().setAlpha(alpha);
} }

View file

@ -19,16 +19,20 @@
#include "InteractiveWindow.h" #include "InteractiveWindow.h"
/**jsdoc
* @namespace Desktop
*
* @hifi-interface
* @hifi-client-entity
*/
class DesktopScriptingInterface : public QObject, public Dependency { class DesktopScriptingInterface : public QObject, public Dependency {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int width READ getWidth) // Physical width of screen(s) including task bars and system menus Q_PROPERTY(int width READ getWidth) // Physical width of screen(s) including task bars and system menus
Q_PROPERTY(int height READ getHeight) // Physical height of screen(s) including task bars and system menus Q_PROPERTY(int height READ getHeight) // Physical height of screen(s) including task bars and system menus
Q_PROPERTY(int ForceNative READ flagForceNative) Q_PROPERTY(QVariantMap PresentationMode READ getPresentationMode CONSTANT FINAL)
Q_PROPERTY(int ForceVirtual READ flagForceVirtual) Q_PROPERTY(int ALWAYS_ON_TOP READ flagAlwaysOnTop CONSTANT FINAL)
Q_PROPERTY(int AlwaysOnTop READ flagAlwaysOnTop) Q_PROPERTY(int CLOSE_BUTTON_HIDES READ flagCloseButtonHides CONSTANT FINAL)
Q_PROPERTY(int CloseButtonHides READ flagCloseButtonHides)
public: public:
Q_INVOKABLE void setHUDAlpha(float alpha); Q_INVOKABLE void setHUDAlpha(float alpha);
@ -41,10 +45,11 @@ public:
private: private:
int flagForceNative() { return ForceNative; } static int flagAlwaysOnTop() { return AlwaysOnTop; }
int flagForceVirtual() { return ForceVirtual; } static int flagCloseButtonHides() { return CloseButtonHides; }
int flagAlwaysOnTop() { return AlwaysOnTop; }
int flagCloseButtonHides() { return CloseButtonHides; } Q_INVOKABLE static QVariantMap getPresentationMode();
}; };
#endif // hifi_DesktopScriptingInterface_h #endif // hifi_DesktopScriptingInterface_h

View file

@ -32,7 +32,7 @@ static const char* const INTERACTIVE_WINDOW_SIZE_PROPERTY = "interactiveWindowSi
static const char* const VISIBLE_PROPERTY = "visible"; static const char* const VISIBLE_PROPERTY = "visible";
static const char* const INTERACTIVE_WINDOW_VISIBLE_PROPERTY = "interactiveWindowVisible"; static const char* const INTERACTIVE_WINDOW_VISIBLE_PROPERTY = "interactiveWindowVisible";
static const char* const EVENT_BRIDGE_PROPERTY = "eventBridge"; static const char* const EVENT_BRIDGE_PROPERTY = "eventBridge";
static const char* const WINDOW_MODE_TEXT_PROPERTY = "windowModeText"; static const char* const PRESENTATION_MODE_PROPERTY = "presentationMode";
static const QStringList KNOWN_SCHEMES = QStringList() << "http" << "https" << "file" << "about" << "atp" << "qrc"; static const QStringList KNOWN_SCHEMES = QStringList() << "http" << "https" << "file" << "about" << "atp" << "qrc";
@ -60,6 +60,9 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
if (properties.contains(FLAGS_PROPERTY)) { if (properties.contains(FLAGS_PROPERTY)) {
object->setProperty(FLAGS_PROPERTY, properties[FLAGS_PROPERTY].toUInt()); object->setProperty(FLAGS_PROPERTY, properties[FLAGS_PROPERTY].toUInt());
} }
if (properties.contains(PRESENTATION_MODE_PROPERTY)) {
object->setProperty(PRESENTATION_MODE_PROPERTY, properties[PRESENTATION_MODE_PROPERTY].toInt());
}
if (properties.contains(TITLE_PROPERTY)) { if (properties.contains(TITLE_PROPERTY)) {
object->setProperty(TITLE_PROPERTY, properties[TITLE_PROPERTY].toString()); object->setProperty(TITLE_PROPERTY, properties[TITLE_PROPERTY].toString());
} }
@ -79,9 +82,10 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
connect(object, SIGNAL(interactiveWindowPositionChanged()), this, SIGNAL(positionChanged()), Qt::QueuedConnection); connect(object, SIGNAL(interactiveWindowPositionChanged()), this, SIGNAL(positionChanged()), Qt::QueuedConnection);
connect(object, SIGNAL(interactiveWindowSizeChanged()), this, SIGNAL(sizeChanged()), Qt::QueuedConnection); connect(object, SIGNAL(interactiveWindowSizeChanged()), this, SIGNAL(sizeChanged()), Qt::QueuedConnection);
connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection); connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection);
connect(object, SIGNAL(windowModeChanged()), this, SIGNAL(modeChanged()), Qt::QueuedConnection); connect(object, SIGNAL(presentationModeChanged()), this, SIGNAL(presentationModeChanged()), Qt::QueuedConnection);
connect(object, SIGNAL(titleChanged()), this, SIGNAL(titleChanged()), Qt::QueuedConnection); connect(object, SIGNAL(titleChanged()), this, SIGNAL(titleChanged()), Qt::QueuedConnection);
QUrl sourceURL{ sourceUrl }; QUrl sourceURL{ sourceUrl };
// If the passed URL doesn't correspond to a known scheme, assume it's a local file path // If the passed URL doesn't correspond to a known scheme, assume it's a local file path
if (!KNOWN_SCHEMES.contains(sourceURL.scheme(), Qt::CaseInsensitive)) { if (!KNOWN_SCHEMES.contains(sourceURL.scheme(), Qt::CaseInsensitive)) {
@ -188,7 +192,7 @@ bool InteractiveWindow::isVisible() const {
glm::vec2 InteractiveWindow::getPosition() const { glm::vec2 InteractiveWindow::getPosition() const {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
vec2 result; glm::vec2 result;
BLOCKING_INVOKE_METHOD(const_cast<InteractiveWindow*>(this), "getPosition", Q_RETURN_ARG(glm::vec2, result)); BLOCKING_INVOKE_METHOD(const_cast<InteractiveWindow*>(this), "getPosition", Q_RETURN_ARG(glm::vec2, result));
return result; return result;
} }
@ -208,12 +212,13 @@ void InteractiveWindow::setPosition(const glm::vec2& position) {
if (!_qmlWindow.isNull()) { if (!_qmlWindow.isNull()) {
_qmlWindow->setProperty(INTERACTIVE_WINDOW_POSITION_PROPERTY, QPointF(position.x, position.y)); _qmlWindow->setProperty(INTERACTIVE_WINDOW_POSITION_PROPERTY, QPointF(position.x, position.y));
QMetaObject::invokeMethod(_qmlWindow, "updateInteractiveWindowPositionForMode", Qt::DirectConnection);
} }
} }
glm::vec2 InteractiveWindow::getSize() const { glm::vec2 InteractiveWindow::getSize() const {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
vec2 result; glm::vec2 result;
BLOCKING_INVOKE_METHOD(const_cast<InteractiveWindow*>(this), "getSize", Q_RETURN_ARG(glm::vec2, result)); BLOCKING_INVOKE_METHOD(const_cast<InteractiveWindow*>(this), "getSize", Q_RETURN_ARG(glm::vec2, result));
return result; return result;
} }
@ -232,18 +237,55 @@ void InteractiveWindow::setSize(const glm::vec2& size) {
if (!_qmlWindow.isNull()) { if (!_qmlWindow.isNull()) {
_qmlWindow->setProperty(INTERACTIVE_WINDOW_SIZE_PROPERTY, QSize(size.x, size.y)); _qmlWindow->setProperty(INTERACTIVE_WINDOW_SIZE_PROPERTY, QSize(size.x, size.y));
QMetaObject::invokeMethod(_qmlWindow, "updateInteractiveWindowSizeForMode", Qt::DirectConnection);
} }
} }
QString InteractiveWindow::getMode() const { QString InteractiveWindow::getTitle() const {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
QString result; QString result;
BLOCKING_INVOKE_METHOD(const_cast<InteractiveWindow*>(this), "getMode", Q_RETURN_ARG(QString, result)); BLOCKING_INVOKE_METHOD(const_cast<InteractiveWindow*>(this), "getTitle", Q_RETURN_ARG(QString, result));
return result; return result;
} }
if (_qmlWindow.isNull()) { if (_qmlWindow.isNull()) {
return QString(); return QString();
} }
return _qmlWindow->property(WINDOW_MODE_TEXT_PROPERTY).toString(); return _qmlWindow->property(TITLE_PROPERTY).toString();
}
void InteractiveWindow::setTitle(const QString& title) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setTitle", Q_ARG(const QString&, title));
return;
}
if (!_qmlWindow.isNull()) {
_qmlWindow->setProperty(TITLE_PROPERTY, title);
}
}
int InteractiveWindow::getPresentationMode() const {
if (QThread::currentThread() != thread()) {
int result;
BLOCKING_INVOKE_METHOD(const_cast<InteractiveWindow*>(this), "getPresentationMode",
Q_RETURN_ARG(int, result));
return result;
}
if (_qmlWindow.isNull()) {
return Virtual;
}
return _qmlWindow->property(PRESENTATION_MODE_PROPERTY).toInt();
}
void InteractiveWindow::setPresentationMode(int presentationMode) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setPresentationMode", Q_ARG(int, presentationMode));
return;
}
if (!_qmlWindow.isNull()) {
_qmlWindow->setProperty(PRESENTATION_MODE_PROPERTY, presentationMode);
}
} }

View file

@ -19,33 +19,76 @@
#include <QtScript/QScriptValue> #include <QtScript/QScriptValue>
#include <QQmlEngine> #include <QQmlEngine>
#include <glm/glm.hpp>
#include <GLMHelpers.h> #include <GLMHelpers.h>
namespace InteractiveWindowEnums { namespace InteractiveWindowEnums {
Q_NAMESPACE Q_NAMESPACE
enum InteractiveWindowFlags : uint8_t { enum InteractiveWindowFlags : uint8_t {
ForceNative = 1 << 0, AlwaysOnTop = 1 << 0,
ForceVirtual = 1 << 1, CloseButtonHides = 1 << 1
AlwaysOnTop = 1 << 2,
CloseButtonHides = 1 << 3
}; };
Q_ENUM_NS(InteractiveWindowFlags); Q_ENUM_NS(InteractiveWindowFlags);
inline void declareQML() { enum InteractiveWindowPresentationMode {
qmlRegisterUncreatableMetaObject(staticMetaObject, "InteractiveWindowFlags", 1, 0, Virtual,
"InteractiveWindowFlags", "Error: enums only"); Native
} };
Q_ENUM_NS(InteractiveWindowPresentationMode);
} }
using namespace InteractiveWindowEnums; using namespace InteractiveWindowEnums;
/**jsdoc
* @class InteractiveWindow
* @hideconstructor
*
* @hifi-interface
* @hifi-client-en
*
* @property {string} mode
*/
class InteractiveWindow : public QObject { class InteractiveWindow : public QObject {
Q_OBJECT Q_OBJECT
/**jsdoc
* title of the window
*
* @name InteractiveWindow#title
* @type string
* @default "InteractiveWindow"
*/
Q_PROPERTY(QString title READ getTitle WRITE setTitle)
/**jsdoc
* window position on current desktop
*
* @name InteractiveWindow#position
* @type Vec2
*/
Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition) Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition)
/**jsdoc
* window size
*
* @name InteractiveWindow#size
* @type Vec2
*/
Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize) Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize)
/**jsdoc
* visibility of the window
*
* @name InteractiveWindow#visible
* @type boolean
* @default true
* @example
* // Toggle window visiblity;
* interactiveWindow.visible = !interactiveWindow.visible;
*/
Q_PROPERTY(bool visible READ isVisible WRITE setVisible) Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
Q_PROPERTY(QString mode READ getMode) Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
public: public:
InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties); InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties);
@ -54,6 +97,9 @@ public:
private: private:
// define property getters and setters as private to not expose them to the JS API // define property getters and setters as private to not expose them to the JS API
Q_INVOKABLE QString getTitle() const;
Q_INVOKABLE void setTitle(const QString& title);
Q_INVOKABLE glm::vec2 getPosition() const; Q_INVOKABLE glm::vec2 getPosition() const;
Q_INVOKABLE void setPosition(const glm::vec2& position); Q_INVOKABLE void setPosition(const glm::vec2& position);
@ -63,7 +109,8 @@ private:
Q_INVOKABLE void setVisible(bool visible); Q_INVOKABLE void setVisible(bool visible);
Q_INVOKABLE bool isVisible() const; Q_INVOKABLE bool isVisible() const;
Q_INVOKABLE QString getMode() const; Q_INVOKABLE void setPresentationMode(int presentationMode);
Q_INVOKABLE int getPresentationMode() const;
public slots: public slots:
@ -123,10 +170,10 @@ signals:
void sizeChanged(); void sizeChanged();
/**jsdoc /**jsdoc
* @function InteractiveWindow.modeChanged * @function InteractiveWindow.presentationModeChanged
* @returns {Signal} * @returns {Signal}
*/ */
void modeChanged(); void presentationModeChanged();
/**jsdoc /**jsdoc
* @function InteractiveWindow.titleChanged * @function InteractiveWindow.titleChanged
@ -134,6 +181,12 @@ signals:
*/ */
void titleChanged(); void titleChanged();
/**jsdoc
* @function InteractiveWindow.closed
* @returns {Signal}
*/
void closed();
/**jsdoc /**jsdoc
* @function InteractiveWindow.fromQml * @function InteractiveWindow.fromQml
* @param {object} message * @param {object} message