Hook up Help button to the new Tablet interface

This commit is contained in:
Anthony J. Thibault 2016-12-14 17:05:47 -08:00
parent d4f9d21ce8
commit d2c4417b24
6 changed files with 95 additions and 23 deletions

View file

@ -10,6 +10,27 @@ Item {
width: 480 width: 480
height: 720 height: 720
// called by C++ code when a button should be added to the tablet
function addButtonProxy(properties) {
var component = Qt.createComponent("TabletButton.qml");
var button = component.createObject(flowMain);
if (properties.icon) {
button.icon = properties.icon;
}
if (properties.color) {
button.color = properties.color;
}
if (properties.text) {
button.text = properties.text;
}
return button;
}
// called by C++ code when a button should be removed from the tablet
function removeButtonProxy(properties) {
console.log("TABLET_UI_HACK: removeButtonProxy, NOT IMPLEMENTED!, properties = " + JSON.stringify(properties));
}
Rectangle { Rectangle {
id: bgAudio id: bgAudio
height: 90 height: 90

View file

@ -9,6 +9,8 @@ Item {
width: 132 width: 132
height: 132 height: 132
signal clicked()
Rectangle { Rectangle {
id: buttonBg id: buttonBg
color: tabletButton.color color: tabletButton.color
@ -62,6 +64,7 @@ Item {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: tabletButton.clicked();
onEntered: { onEntered: {
console.log("Tablet Button Hovered!"); console.log("Tablet Button Hovered!");
tabletButton.state = "hover state"; tabletButton.state = "hover state";

View file

@ -261,7 +261,7 @@ void RenderableWebEntityItem::loadSourceURL() {
// TABLET_UI_HACK: move this to overlays as well! // TABLET_UI_HACK: move this to overlays as well!
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tablet") { if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tablet") {
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
tabletScriptingInterface->setupTablet("com.highfidelity.interface.tablet.system", _webSurface->getRootItem()); tabletScriptingInterface->setQmlTablet("com.highfidelity.interface.tablet.system", _webSurface->getRootItem());
} }
} }
} }

View file

@ -27,11 +27,16 @@ QObject* TabletScriptingInterface::getTablet(const QString& tabletId) {
} }
} }
void TabletScriptingInterface::setupTablet(QString tabletId, QQuickItem* qmlTablet) { void TabletScriptingInterface::setQmlTablet(QString tabletId, QQuickItem* qmlTablet) {
// AJT: TODO TabletProxy* tablet = qobject_cast<TabletProxy*>(getTablet(tabletId));
qDebug() << "AJT: setupTablet objname = " << qmlTablet->objectName(); if (tablet) {
tablet->setQmlTablet(qmlTablet);
} else {
qWarning() << "TabletScriptingInterface::setupTablet() bad tablet object";
}
} }
// //
// TabletProxy // TabletProxy
// //
@ -40,10 +45,47 @@ TabletProxy::TabletProxy(QString name) : _name(name) {
; ;
} }
static void addButtonProxyToQmlTablet(QQuickItem* qmlTablet, TabletButtonProxy* buttonProxy) {
QVariant resultVar;
Qt::ConnectionType connectionType = Qt::AutoConnection;
if (QThread::currentThread() != qmlTablet->thread()) {
connectionType = Qt::BlockingQueuedConnection;
}
bool hasResult = QMetaObject::invokeMethod(qmlTablet, "addButtonProxy", connectionType,
Q_RETURN_ARG(QVariant, resultVar), Q_ARG(QVariant, buttonProxy->getProperties()));
if (!hasResult) {
qWarning() << "TabletScriptingInterface addButtonProxyToQmlTablet has no result";
return;
}
QObject* qmlButton = qvariant_cast<QObject *>(resultVar);
if (!qmlButton) {
qWarning() << "TabletScriptingInterface addButtonProxyToQmlTablet result not a QObject";
return;
}
QObject::connect(qmlButton, SIGNAL(clicked()), buttonProxy, SLOT(clickedSlot()));
}
void TabletProxy::setQmlTablet(QQuickItem* qmlTablet) {
if (qmlTablet) {
_qmlTablet = qmlTablet;
std::lock_guard<std::mutex> guard(_tabletButtonProxiesMutex);
for (auto& buttonProxy : _tabletButtonProxies) {
addButtonProxyToQmlTablet(_qmlTablet, buttonProxy.data());
}
} else {
_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(_tabletButtonProxiesMutex);
_tabletButtonProxies.push_back(tabletButtonProxy); _tabletButtonProxies.push_back(tabletButtonProxy);
if (_qmlTablet) {
addButtonProxyToQmlTablet(_qmlTablet, tabletButtonProxy.data());
}
return tabletButtonProxy.data(); return tabletButtonProxy.data();
} }
@ -51,6 +93,9 @@ void TabletProxy::removeButton(QObject* tabletButtonProxy) {
std::lock_guard<std::mutex> guard(_tabletButtonProxiesMutex); std::lock_guard<std::mutex> guard(_tabletButtonProxiesMutex);
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) {
QMetaObject::invokeMethod(_qmlTablet, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getProperties()));
}
_tabletButtonProxies.erase(iter); _tabletButtonProxies.erase(iter);
} else { } else {
qWarning() << "TabletProxy::removeButton() could not find button " << tabletButtonProxy; qWarning() << "TabletProxy::removeButton() could not find button " << tabletButtonProxy;
@ -69,6 +114,8 @@ void TabletButtonProxy::setInitRequestHandler(const QScriptValue& handler) {
_initRequestHandler = handler; _initRequestHandler = handler;
} }
// TABLET_UI_HACK remove
/*
static QString IMAGE_URL_KEY = "imageUrl"; static QString IMAGE_URL_KEY = "imageUrl";
static QString IMAGE_URL_DEFAULT = ""; static QString IMAGE_URL_DEFAULT = "";
@ -81,5 +128,6 @@ void TabletButtonProxy::setImageUrl(QString imageUrl) {
std::lock_guard<std::mutex> guard(_propertiesMutex); std::lock_guard<std::mutex> guard(_propertiesMutex);
_properties[IMAGE_URL_KEY] = imageUrl; _properties[IMAGE_URL_KEY] = imageUrl;
} }
*/
#include "TabletScriptingInterface.moc" #include "TabletScriptingInterface.moc"

View file

@ -36,7 +36,8 @@ public:
*/ */
Q_INVOKABLE QObject* getTablet(const QString& tabletId); Q_INVOKABLE QObject* getTablet(const QString& tabletId);
void setupTablet(QString tabletId, QQuickItem* qmlTablet); void setQmlTablet(QString tabletId, QQuickItem* qmlTablet);
protected: protected:
std::mutex _tabletProxiesMutex; std::mutex _tabletProxiesMutex;
std::map<QString, QSharedPointer<TabletProxy>> _tabletProxies; std::map<QString, QSharedPointer<TabletProxy>> _tabletProxies;
@ -52,10 +53,12 @@ class TabletProxy : public QObject {
public: public:
TabletProxy(QString name); TabletProxy(QString name);
void setQmlTablet(QQuickItem* qmlTablet);
/**jsdoc /**jsdoc
* @function TabletProxy#addButton * @function TabletProxy#addButton
* Creates a new button, adds it to this and returns it. * Creates a new button, adds it to this and returns it.
* @param properties {Object} button properties AJT: TODO: enumerate these... * @param properties {Object} button properties UI_TABLET_HACK: enumerate these when we figure out what they should be!
* @returns {TabletButtonProxy} * @returns {TabletButtonProxy}
*/ */
Q_INVOKABLE QObject* addButton(const QVariant& properties); Q_INVOKABLE QObject* addButton(const QVariant& properties);
@ -72,6 +75,7 @@ protected:
QString _name; QString _name;
std::mutex _tabletButtonProxiesMutex; std::mutex _tabletButtonProxiesMutex;
std::vector<QSharedPointer<TabletButtonProxy>> _tabletButtonProxies; std::vector<QSharedPointer<TabletButtonProxy>> _tabletButtonProxies;
QQuickItem* _qmlTablet { nullptr };
}; };
/**jsdoc /**jsdoc
@ -80,7 +84,6 @@ protected:
*/ */
class TabletButtonProxy : public QObject { class TabletButtonProxy : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString imageUrl READ getImageUrl WRITE setImageUrl)
public: public:
TabletButtonProxy(const QVariantMap& properties); TabletButtonProxy(const QVariantMap& properties);
@ -90,16 +93,19 @@ public:
*/ */
Q_INVOKABLE void setInitRequestHandler(const QScriptValue& handler); Q_INVOKABLE void setInitRequestHandler(const QScriptValue& handler);
QString getImageUrl() const; const QVariantMap& getProperties() const { return _properties; }
void setImageUrl(QString imageUrl);
public slots:
void clickedSlot() { emit clicked(); }
signals: signals:
/**jsdoc /**jsdoc
* Signaled when this button has been clicked on by the user. * Signaled when this button has been clicked on by the user.
* @function TabletButtonProxy#onClick * @function TabletButtonProxy#clicked
* @returns {Signal} * @returns {Signal}
*/ */
void onClick(); void clicked();
protected: protected:
mutable std::mutex _propertiesMutex; mutable std::mutex _propertiesMutex;
QVariantMap _properties; QVariantMap _properties;

View file

@ -13,20 +13,14 @@
(function() { // BEGIN LOCAL_SCOPE (function() { // BEGIN LOCAL_SCOPE
var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var buttonName = "help"; // matching location reserved in Desktop.qml var button = tablet.addButton({
var button = toolBar.addButton({ //icon: "help.svg",
objectName: buttonName, color: "#ff6f6f",
imageURL: Script.resolvePath("assets/images/tools/help.svg"), text: "HELP"
visible: true,
hoverState: 2,
defaultState: 1,
buttonState: 1,
alpha: 0.9
}); });
// TODO: make button state reflect whether the window is opened or closed (independently from us). // TODO: make button state reflect whether the window is opened or closed (independently from us).
function onClicked(){ function onClicked(){
Menu.triggerOption('Help...') Menu.triggerOption('Help...')
} }
@ -34,7 +28,7 @@
button.clicked.connect(onClicked); button.clicked.connect(onClicked);
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
toolBar.removeButton(buttonName); tablet.removeButton(buttonName);
button.clicked.disconnect(onClicked); button.clicked.disconnect(onClicked);
}); });