// // Created by Anthony J. Thibault on 2016-12-12 // Copyright 2013-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 // #ifndef hifi_TabletScriptingInterface_h #define hifi_TabletScriptingInterface_h #include #include #include #include #include #include #include #include #include #include #include class TabletProxy; class TabletButtonProxy; /**jsdoc * @namespace Tablet */ class TabletScriptingInterface : public QObject, public Dependency { Q_OBJECT public: TabletScriptingInterface(); void setToolbarScriptingInterface(QObject* toolbarScriptingInterface) { _toolbarScriptingInterface = toolbarScriptingInterface; } QObject* getSystemToolbarProxy(); /**jsdoc * Creates or retruns a new TabletProxy and returns it. * @function Tablet.getTablet * @param name {String} tablet name * @return {TabletProxy} tablet instance */ Q_INVOKABLE QObject* getTablet(const QString& tabletId); void setQmlTabletRoot(QString tabletId, QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface); void processEvent(const QKeyEvent* event); QQuickWindow* getTabletWindow(); QObject* getFlags(); private: void processMenuEvents(QObject* object, const QKeyEvent* event); void processTabletEvents(QObject* object, const QKeyEvent* event); protected: std::mutex _mutex; std::map> _tabletProxies; QObject* _toolbarScriptingInterface { nullptr }; }; /**jsdoc * @class TabletProxy * @property name {string} READ_ONLY: name of this tablet * @property toolbarMode {bool} - used to transition this tablet into and out of toolbar mode. * When tablet is in toolbar mode, all its buttons will appear in a floating toolbar. */ class TabletProxy : public QObject { Q_OBJECT Q_PROPERTY(QString name READ getName) Q_PROPERTY(bool toolbarMode READ getToolbarMode WRITE setToolbarMode) public: TabletProxy(QString name); void setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface); Q_INVOKABLE void gotoMenuScreen(const QString& submenu = ""); QString getName() const { return _name; } bool getToolbarMode() const { return _toolbarMode; } void setToolbarMode(bool toolbarMode); /**jsdoc * transition to the home screen * @function TabletProxy#gotoHomeScreen */ Q_INVOKABLE void gotoHomeScreen(); /**jsdoc * show the specified web url on the tablet. * @function TabletProxy#gotoWebScreen * @param url {string} url of web page. * @param [injectedJavaScriptUrl] {string} optional url to an additional JS script to inject into the web page. */ Q_INVOKABLE void gotoWebScreen(const QString& url); Q_INVOKABLE void gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl); Q_INVOKABLE void loadQMLSource(const QVariant& path); /**jsdoc * Creates a new button, adds it to this and returns it. * @function TabletProxy#addButton * @param properties {Object} button properties UI_TABLET_HACK: enumerate these when we figure out what they should be! * @returns {TabletButtonProxy} */ Q_INVOKABLE QObject* addButton(const QVariant& properties); /**jsdoc * removes button from the tablet * @function TabletProxy.removeButton * @param tabletButtonProxy {TabletButtonProxy} button to be removed */ Q_INVOKABLE void removeButton(QObject* tabletButtonProxy); /**jsdoc * Updates the tablet's mic enabled state * @function TabletProxy#updateMicEnabled * @param micEnabled {bool} mic enabled state */ Q_INVOKABLE void updateMicEnabled(const bool micEnabled); /**jsdoc * Updates the audio bar in tablet to reflect latest mic level * @function TabletProxy#updateAudioBar * @param micLevel {double} mic level value between 0 and 1 */ Q_INVOKABLE void updateAudioBar(const double micLevel); /**jsdoc * Used to send an event to the html/js embedded in the tablet * @function TabletProxy#emitScriptEvent * @param msg {object|string} */ Q_INVOKABLE void emitScriptEvent(QVariant msg); /**jsdoc * Used to send an event to the qml embedded in the tablet * @function TabletProxy#sendToQml * @param msg {object|string} */ Q_INVOKABLE void sendToQml(QVariant msg); Q_INVOKABLE bool onHomeScreen(); QObject* getTabletSurface(); QQuickItem* getQmlTablet() const; QQuickItem* getQmlMenu() const; signals: /**jsdoc * Signaled when this tablet receives an event from the html/js embedded in the tablet * @function TabletProxy#webEventReceived * @param msg {object|string} * @returns {Signal} */ void webEventReceived(QVariant msg); /**jsdoc * Signaled when this tablet receives an event from the qml embedded in the tablet * @function TabletProxy#fromQml * @param msg {object|string} * @returns {Signal} */ void fromQml(QVariant msg); /**jsdoc * Signales when this tablet screen changes. * @function TabletProxy#screenChanged * @param type {string} - "Home", "Web", "Menu", "QML", "Closed" * @param url {string} - only valid for Web and QML. */ void screenChanged(QVariant type, QVariant url); protected slots: void addButtonsToHomeScreen(); void addButtonsToMenuScreen(); void desktopWindowClosed(); protected: void removeButtonsFromHomeScreen(); void addButtonsToToolbar(); void removeButtonsFromToolbar(); QString _name; std::mutex _mutex; std::vector> _tabletButtonProxies; QQuickItem* _qmlTabletRoot { nullptr }; QObject* _qmlOffscreenSurface { nullptr }; QQuickItem* _desktopWindow { nullptr }; bool _toolbarMode { false }; enum class State { Uninitialized, Home, Web, Menu, QML }; State _state { State::Uninitialized }; }; /**jsdoc * @class TabletButtonProxy * @property uuid {QUuid} READ_ONLY: uniquely identifies this button */ class TabletButtonProxy : public QObject { Q_OBJECT Q_PROPERTY(QUuid uuid READ getUuid) public: TabletButtonProxy(const QVariantMap& properties); void setQmlButton(QQuickItem* qmlButton); void setToolbarButtonProxy(QObject* toolbarButtonProxy); QUuid getUuid() const { return _uuid; } /**jsdoc * Returns the current value of this button's properties * @function TabletButtonProxy#getProperties * @returns {ButtonProperties} */ Q_INVOKABLE QVariantMap getProperties() const; /**jsdoc * Replace the values of some of this button's properties * @function TabletButtonProxy#editProperties * @param {ButtonProperties} properties - set of properties to change */ Q_INVOKABLE void editProperties(QVariantMap properties); public slots: void clickedSlot() { emit clicked(); } signals: /**jsdoc * Signaled when this button has been clicked on by the user. * @function TabletButtonProxy#clicked * @returns {Signal} */ void clicked(); protected: QUuid _uuid; int _stableOrder; mutable std::mutex _mutex; QQuickItem* _qmlButton { nullptr }; QObject* _toolbarButtonProxy { nullptr }; QVariantMap _properties; }; /**jsdoc * @typedef TabletButtonProxy.ButtonProperties * @property {string} icon - url to button icon. (50 x 50) * @property {string} hoverIcon - url to button icon, displayed during mouse hover. (50 x 50) * @property {string} activeHoverIcon - url to button icon used when button is active, and during mouse hover. (50 x 50) * @property {string} activeIcon - url to button icon used when button is active. (50 x 50) * @property {string} text - button caption * @property {string} hoverText - button caption when button is not-active but during mouse hover. * @property {string} activeText - button caption when button is active * @property {string} activeHoverText - button caption when button is active and during mouse hover. * @property {string} isActive - true when button is active. * @property {number} sortOrder - determines sort order on tablet. lower numbers will appear before larger numbers. default is 100 */ #endif // hifi_TabletScriptingInterface_h