mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 11:28:03 +02:00
Merge pull request #9219 from hyperlogic/tablet-ui
Can now remove and edit buttons on the Tablet
This commit is contained in:
commit
c6d7894f52
6 changed files with 129 additions and 44 deletions
|
@ -10,25 +10,42 @@ Item {
|
||||||
width: 480
|
width: 480
|
||||||
height: 720
|
height: 720
|
||||||
|
|
||||||
|
// used to look up a button by its uuid
|
||||||
|
function findButtonIndex(uuid) {
|
||||||
|
if (!uuid) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in flowMain.children) {
|
||||||
|
var child = flowMain.children[i];
|
||||||
|
if (child.uuid === uuid) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// called by C++ code when a button should be added to the tablet
|
// called by C++ code when a button should be added to the tablet
|
||||||
function addButtonProxy(properties) {
|
function addButtonProxy(properties) {
|
||||||
var component = Qt.createComponent("TabletButton.qml");
|
var component = Qt.createComponent("TabletButton.qml");
|
||||||
var button = component.createObject(flowMain);
|
var button = component.createObject(flowMain);
|
||||||
if (properties.icon) {
|
|
||||||
button.icon = properties.icon;
|
// copy all properites to button
|
||||||
}
|
var keys = Object.keys(properties).forEach(function (key) {
|
||||||
if (properties.color) {
|
button[key] = properties[key];
|
||||||
button.color = properties.color;
|
});
|
||||||
}
|
|
||||||
if (properties.text) {
|
|
||||||
button.text = properties.text;
|
|
||||||
}
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by C++ code when a button should be removed from the tablet
|
// called by C++ code when a button should be removed from the tablet
|
||||||
function removeButtonProxy(properties) {
|
function removeButtonProxy(properties) {
|
||||||
console.log("TABLET_UI_HACK: removeButtonProxy, NOT IMPLEMENTED!, properties = " + JSON.stringify(properties));
|
var index = findButtonIndex(properties.uuid);
|
||||||
|
if (index < 0) {
|
||||||
|
console.log("Warning: Tablet.qml could not find button with uuid = " + properties.uuid);
|
||||||
|
} else {
|
||||||
|
flowMain.children[index].destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
|
@ -6,11 +6,16 @@ Item {
|
||||||
property string color: "#1080B8"
|
property string color: "#1080B8"
|
||||||
property string text: "EDIT"
|
property string text: "EDIT"
|
||||||
property string icon: "icons/edit-icon.svg"
|
property string icon: "icons/edit-icon.svg"
|
||||||
|
property var uuid;
|
||||||
width: 132
|
width: 132
|
||||||
height: 132
|
height: 132
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
|
||||||
|
function changeProperty(key, value) {
|
||||||
|
tabletButton[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: buttonBg
|
id: buttonBg
|
||||||
color: tabletButton.color
|
color: tabletButton.color
|
||||||
|
|
|
@ -361,6 +361,13 @@ void RenderableWebEntityItem::destroyWebSurface() {
|
||||||
--_currentWebCount;
|
--_currentWebCount;
|
||||||
|
|
||||||
QQuickItem* rootItem = _webSurface->getRootItem();
|
QQuickItem* rootItem = _webSurface->getRootItem();
|
||||||
|
|
||||||
|
// TABLET_UI_HACK: move this to overlays as well!
|
||||||
|
if (rootItem && rootItem->objectName() == "tablet") {
|
||||||
|
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||||
|
tabletScriptingInterface->setQmlTablet("com.highfidelity.interface.tablet.system", nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
if (rootItem) {
|
if (rootItem) {
|
||||||
QObject* obj = rootItem->findChild<QObject*>("webEngineView");
|
QObject* obj = rootItem->findChild<QObject*>("webEngineView");
|
||||||
if (obj) {
|
if (obj) {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
QObject* TabletScriptingInterface::getTablet(const QString& tabletId) {
|
QObject* TabletScriptingInterface::getTablet(const QString& tabletId) {
|
||||||
|
|
||||||
std::lock_guard<std::mutex> guard(_tabletProxiesMutex);
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
|
|
||||||
// look up tabletId in the map.
|
// look up tabletId in the map.
|
||||||
auto iter = _tabletProxies.find(tabletId);
|
auto iter = _tabletProxies.find(tabletId);
|
||||||
|
@ -36,7 +36,6 @@ void TabletScriptingInterface::setQmlTablet(QString tabletId, QQuickItem* qmlTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// TabletProxy
|
// TabletProxy
|
||||||
//
|
//
|
||||||
|
@ -64,24 +63,27 @@ static void addButtonProxyToQmlTablet(QQuickItem* qmlTablet, TabletButtonProxy*
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QObject::connect(qmlButton, SIGNAL(clicked()), buttonProxy, SLOT(clickedSlot()));
|
QObject::connect(qmlButton, SIGNAL(clicked()), buttonProxy, SLOT(clickedSlot()));
|
||||||
|
buttonProxy->setQmlButton(qobject_cast<QQuickItem*>(qmlButton));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabletProxy::setQmlTablet(QQuickItem* qmlTablet) {
|
void TabletProxy::setQmlTablet(QQuickItem* qmlTablet) {
|
||||||
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
if (qmlTablet) {
|
if (qmlTablet) {
|
||||||
_qmlTablet = qmlTablet;
|
_qmlTablet = qmlTablet;
|
||||||
std::lock_guard<std::mutex> guard(_tabletButtonProxiesMutex);
|
|
||||||
for (auto& buttonProxy : _tabletButtonProxies) {
|
for (auto& buttonProxy : _tabletButtonProxies) {
|
||||||
addButtonProxyToQmlTablet(_qmlTablet, buttonProxy.data());
|
addButtonProxyToQmlTablet(_qmlTablet, buttonProxy.data());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
for (auto& buttonProxy : _tabletButtonProxies) {
|
||||||
|
buttonProxy->setQmlButton(nullptr);
|
||||||
|
}
|
||||||
_qmlTablet = nullptr;
|
_qmlTablet = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* TabletProxy::addButton(const QVariant& properties) {
|
QObject* TabletProxy::addButton(const QVariant& properties) {
|
||||||
auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap()));
|
auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap()));
|
||||||
std::lock_guard<std::mutex> guard(_tabletButtonProxiesMutex);
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
_tabletButtonProxies.push_back(tabletButtonProxy);
|
_tabletButtonProxies.push_back(tabletButtonProxy);
|
||||||
if (_qmlTablet) {
|
if (_qmlTablet) {
|
||||||
addButtonProxyToQmlTablet(_qmlTablet, tabletButtonProxy.data());
|
addButtonProxyToQmlTablet(_qmlTablet, tabletButtonProxy.data());
|
||||||
|
@ -90,11 +92,12 @@ QObject* TabletProxy::addButton(const QVariant& properties) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabletProxy::removeButton(QObject* tabletButtonProxy) {
|
void TabletProxy::removeButton(QObject* tabletButtonProxy) {
|
||||||
std::lock_guard<std::mutex> guard(_tabletButtonProxiesMutex);
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy);
|
auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy);
|
||||||
if (iter != _tabletButtonProxies.end()) {
|
if (iter != _tabletButtonProxies.end()) {
|
||||||
if (_qmlTablet) {
|
if (_qmlTablet) {
|
||||||
QMetaObject::invokeMethod(_qmlTablet, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getProperties()));
|
(*iter)->setQmlButton(nullptr);
|
||||||
|
QMetaObject::invokeMethod(_qmlTablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getProperties()));
|
||||||
}
|
}
|
||||||
_tabletButtonProxies.erase(iter);
|
_tabletButtonProxies.erase(iter);
|
||||||
} else {
|
} else {
|
||||||
|
@ -106,28 +109,33 @@ void TabletProxy::removeButton(QObject* tabletButtonProxy) {
|
||||||
// TabletButtonProxy
|
// TabletButtonProxy
|
||||||
//
|
//
|
||||||
|
|
||||||
TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) : _properties(properties) {
|
const QString UUID_KEY = "uuid";
|
||||||
;
|
|
||||||
|
TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) : _uuid(QUuid::createUuid()), _properties(properties) {
|
||||||
|
// this is used to uniquely identify this button.
|
||||||
|
_properties[UUID_KEY] = _uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabletButtonProxy::setInitRequestHandler(const QScriptValue& handler) {
|
void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) {
|
||||||
_initRequestHandler = handler;
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
|
_qmlButton = qmlButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TABLET_UI_HACK remove
|
QVariantMap TabletButtonProxy::getProperties() const {
|
||||||
/*
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
static QString IMAGE_URL_KEY = "imageUrl";
|
return _properties;
|
||||||
static QString IMAGE_URL_DEFAULT = "";
|
|
||||||
|
|
||||||
QString TabletButtonProxy::getImageUrl() const {
|
|
||||||
std::lock_guard<std::mutex> guard(_propertiesMutex);
|
|
||||||
return _properties.value(IMAGE_URL_KEY, IMAGE_URL_DEFAULT).toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabletButtonProxy::setImageUrl(QString imageUrl) {
|
void TabletButtonProxy::editProperties(QVariantMap properties) {
|
||||||
std::lock_guard<std::mutex> guard(_propertiesMutex);
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
_properties[IMAGE_URL_KEY] = imageUrl;
|
QVariantMap::const_iterator iter = properties.constBegin();
|
||||||
|
while (iter != properties.constEnd()) {
|
||||||
|
_properties[iter.key()] = iter.value();
|
||||||
|
if (_qmlButton) {
|
||||||
|
QMetaObject::invokeMethod(_qmlButton, "changeProperty", Qt::AutoConnection, Q_ARG(QVariant, QVariant(iter.key())), Q_ARG(QVariant, iter.value()));
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#include "TabletScriptingInterface.moc"
|
#include "TabletScriptingInterface.moc"
|
||||||
|
|
|
@ -11,10 +11,11 @@
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QObject>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QScriptValue>
|
#include <QScriptValue>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ public:
|
||||||
void setQmlTablet(QString tabletId, QQuickItem* qmlTablet);
|
void setQmlTablet(QString tabletId, QQuickItem* qmlTablet);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::mutex _tabletProxiesMutex;
|
std::mutex _mutex;
|
||||||
std::map<QString, QSharedPointer<TabletProxy>> _tabletProxies;
|
std::map<QString, QSharedPointer<TabletProxy>> _tabletProxies;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ public:
|
||||||
QString getName() const { return _name; }
|
QString getName() const { return _name; }
|
||||||
protected:
|
protected:
|
||||||
QString _name;
|
QString _name;
|
||||||
std::mutex _tabletButtonProxiesMutex;
|
std::mutex _mutex;
|
||||||
std::vector<QSharedPointer<TabletButtonProxy>> _tabletButtonProxies;
|
std::vector<QSharedPointer<TabletButtonProxy>> _tabletButtonProxies;
|
||||||
QQuickItem* _qmlTablet { nullptr };
|
QQuickItem* _qmlTablet { nullptr };
|
||||||
};
|
};
|
||||||
|
@ -87,13 +88,21 @@ class TabletButtonProxy : public QObject {
|
||||||
public:
|
public:
|
||||||
TabletButtonProxy(const QVariantMap& properties);
|
TabletButtonProxy(const QVariantMap& properties);
|
||||||
|
|
||||||
/**jsdoc
|
void setQmlButton(QQuickItem* qmlButton);
|
||||||
* @function TabletButtonProxy#setInitRequestHandler
|
|
||||||
* @param handler {Function} A function used by the system to request the current button state from JavaScript.
|
|
||||||
*/
|
|
||||||
Q_INVOKABLE void setInitRequestHandler(const QScriptValue& handler);
|
|
||||||
|
|
||||||
const QVariantMap& getProperties() const { return _properties; }
|
/**jsdoc
|
||||||
|
* Returns the current value of this button's properties
|
||||||
|
* @function TabletButtonProxy#getProperties
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE QVariantMap getProperties() const;
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Replace the values of some of this button's properties
|
||||||
|
* @function TabletButtonProxy#editProperties
|
||||||
|
* @param properties {object} set of properties to change
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void editProperties(QVariantMap properties);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clickedSlot() { emit clicked(); }
|
void clickedSlot() { emit clicked(); }
|
||||||
|
@ -107,9 +116,10 @@ signals:
|
||||||
void clicked();
|
void clicked();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable std::mutex _propertiesMutex;
|
QUuid _uuid;
|
||||||
|
mutable std::mutex _mutex;
|
||||||
|
QQuickItem* _qmlButton { nullptr };
|
||||||
QVariantMap _properties;
|
QVariantMap _properties;
|
||||||
QScriptValue _initRequestHandler;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_TabletScriptingInterface_h
|
#endif // hifi_TabletScriptingInterface_h
|
||||||
|
|
38
scripts/developer/tests/tabletTest.js
Normal file
38
scripts/developer/tests/tabletTest.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
// tabletTest.js
|
||||||
|
//
|
||||||
|
// Created by Anthony J. Thibault on 2016-12-15
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// Adds a BAM! button to the tablet ui.
|
||||||
|
|
||||||
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
var button = tablet.addButton({
|
||||||
|
icon: "https://s3.amazonaws.com/hifi-public/tony/icons/hat-up.svg",
|
||||||
|
color: "#ff6f6f",
|
||||||
|
text: "BAM!!!"
|
||||||
|
});
|
||||||
|
|
||||||
|
// change the color and name every second...
|
||||||
|
var colors = ["#ff6f6f", "#6fff6f", "#6f6fff"];
|
||||||
|
var names = ["BAM!", "BAM!!", "BAM!!!"];
|
||||||
|
var colorIndex = 0;
|
||||||
|
Script.setInterval(function () {
|
||||||
|
colorIndex = (colorIndex + 1) % colors.length;
|
||||||
|
button.editProperties({
|
||||||
|
color: colors[colorIndex],
|
||||||
|
text: names[colorIndex]
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
button.clicked.connect(function () {
|
||||||
|
print("AJT: BAMM!!! CLICK from JS!");
|
||||||
|
});
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(function () {
|
||||||
|
tablet.removeButton(button);
|
||||||
|
});
|
Loading…
Reference in a new issue