diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 3cf8eb9b29..bc843a140d 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -74,7 +74,9 @@ Rectangle { if (result.status !== 'success') { console.log("Failed to get purchases", result.message); } else { + purchasesModel.clear(); purchasesModel.append(result.data.assets); + filteredPurchasesModel.clear(); filteredPurchasesModel.append(result.data.assets); } } diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml index 2252cbfb59..47b3f6daf6 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Help.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml @@ -31,6 +31,7 @@ Item { // "Unavailable" RalewayRegular { + id: helpText; text: "Help me!"; // Anchors anchors.fill: parent; @@ -43,6 +44,19 @@ Item { horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter; } + HifiControlsUit.Button { + color: hifi.buttons.black; + colorScheme: hifi.colorSchemes.dark; + anchors.bottom: helpText.bottom; + anchors.horizontalCenter: parent.horizontalCenter; + height: 50; + width: 250; + text: "Testing: Reset Wallet!"; + onClicked: { + commerce.reset(); + sendSignalToWallet({method: 'walletReset'}); + } + } // // FUNCTION DEFINITIONS START diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 0d46077f2a..53838fa58c 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -107,7 +107,7 @@ Rectangle { anchors.centerIn: walletSetupLightboxContainer; width: walletSetupLightboxContainer.width - 50; height: walletSetupLightboxContainer.height - 50; - + Connections { onSendSignalToWallet: { if (msg.method === 'walletSetup_raiseKeyboard') { @@ -127,7 +127,7 @@ Rectangle { anchors.centerIn: walletSetupLightboxContainer; width: walletSetupLightboxContainer.width - 50; height: walletSetupLightboxContainer.height - 50; - + Connections { onSendSignalToWallet: { sendToScript(msg); @@ -196,7 +196,7 @@ Rectangle { commerce.getLoginStatus(); } } - + NeedsLogIn { id: needsLogIn; visible: root.activeView === "needsLogIn"; @@ -225,7 +225,7 @@ Rectangle { anchors.bottom: tabButtonsContainer.top; anchors.left: parent.left; anchors.right: parent.right; - + Connections { onSendSignalToWallet: { if (msg.method === 'setUpClicked') { @@ -296,6 +296,14 @@ Rectangle { anchors.leftMargin: 16; anchors.right: parent.right; anchors.rightMargin: 16; + + Connections { + onSendSignalToWallet: { + if (msg.method === 'walletReset') { + sendToScript(msg); + } + } + } } @@ -510,7 +518,7 @@ Rectangle { } // // TAB BUTTONS END - // + // Item { id: keyboardContainer; diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index c69610d494..b55f7f800a 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -24,6 +24,7 @@ Item { HifiConstants { id: hifi; } id: root; + property bool historyReceived: false; Hifi.QmlCommerce { id: commerce; @@ -41,9 +42,10 @@ Item { } onHistoryResult : { + historyReceived = true; if (result.status === 'success') { - var txt = result.data.history.map(function (h) { return h.text; }).join("
"); - transactionHistoryText.text = txt; + transactionHistoryModel.clear(); + transactionHistoryModel.append(result.data.history); } } } @@ -111,6 +113,7 @@ Item { onVisibleChanged: { if (visible) { + historyReceived = false; commerce.balance(); commerce.history(); } @@ -233,24 +236,66 @@ Item { // Style color: hifi.colors.faintGray; } - + ListModel { + id: transactionHistoryModel; + } Rectangle { - id: transactionHistory; anchors.top: recentActivityText.bottom; anchors.topMargin: 4; anchors.bottom: parent.bottom; anchors.left: parent.left; anchors.right: parent.right; + color: "white"; - // some placeholder stuff - TextArea { - id: transactionHistoryText; - text: "
history unavailable
"; - textFormat: TextEdit.AutoText; - font.pointSize: 10; + ListView { + id: transactionHistory; + anchors.centerIn: parent; + width: parent.width - 12; + height: parent.height - 12; + visible: transactionHistoryModel.count !== 0; + clip: true; + model: transactionHistoryModel; + delegate: Item { + width: parent.width; + height: transactionText.height + 30; + RalewayRegular { + id: transactionText; + text: model.text; + // Style + size: 18; + width: parent.width; + height: paintedHeight; + anchors.verticalCenter: parent.verticalCenter; + color: "black"; + wrapMode: Text.WordWrap; + // Alignment + horizontalAlignment: Text.AlignLeft; + verticalAlignment: Text.AlignVCenter; + } + + HifiControlsUit.Separator { + anchors.left: parent.left; + anchors.right: parent.right; + anchors.bottom: parent.bottom; + } + } + onAtYEndChanged: { + if (transactionHistory.atYEnd) { + console.log("User scrolled to the bottom of 'Recent Activity'."); + // Grab next page of results and append to model + } + } + } + + // This should never be visible (since you immediately get 100 HFC) + RalewayRegular { + id: emptyTransationHistory; + size: 24; + visible: !transactionHistory.visible && root.historyReceived; + text: "Recent Activity Unavailable"; anchors.fill: parent; - horizontalAlignment: Text.AlignLeft; - verticalAlignment: Text.AlignTop; + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml index f36529e6c1..4470ec7a75 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml @@ -24,7 +24,7 @@ Rectangle { HifiConstants { id: hifi; } id: root; - property string lastPage: "securityImage"; + property string lastPage: "initialize"; // Style color: hifi.colors.baseGray; @@ -58,16 +58,9 @@ Rectangle { // Item { id: securityImageContainer; - visible: false; // Anchors anchors.fill: parent; - onVisibleChanged: { - if (visible) { - commerce.getSecurityImage(); - } - } - Item { id: securityImageTitle; // Size diff --git a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml index 3d4231ced7..bbf2d019fb 100644 --- a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml +++ b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml @@ -4,6 +4,7 @@ import QtQuick.Controls 1.4 StateImage { id: button + property string captionColorOverride: "" property bool buttonEnabled: true property bool isActive: false property bool isEntered: false @@ -97,7 +98,7 @@ StateImage { Text { id: caption - color: button.isActive ? "#000000" : "#ffffff" + color: captionColorOverride !== "" ? captionColorOverride: (button.isActive ? "#000000" : "#ffffff") text: button.isActive ? (button.isEntered ? button.activeHoverText : button.activeText) : (button.isEntered ? button.hoverText : button.text) font.bold: false font.pixelSize: 9 diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 423f60b1a0..a526fd5bb4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -166,6 +166,7 @@ #include "scripting/WindowScriptingInterface.h" #include "scripting/ControllerScriptingInterface.h" #include "scripting/RatesScriptingInterface.h" +#include "scripting/SelectionScriptingInterface.h" #if defined(Q_OS_MAC) || defined(Q_OS_WIN) #include "SpeechRecognizer.h" #endif @@ -675,6 +676,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -2318,6 +2320,7 @@ void Application::initializeUi() { surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); + surfaceContext->setContextProperty("Selection", DependencyManager::get().data()); surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get().data()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { @@ -5641,17 +5644,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se } renderArgs->_debugFlags = renderDebugFlags; //ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, transaction); - - RenderArgs::OutlineFlags renderOutlineFlags = RenderArgs::RENDER_OUTLINE_NONE; - auto contextOverlayInterface = DependencyManager::get(); - if (contextOverlayInterface->getEnabled()) { - if (DependencyManager::get()->getIsInMarketplaceInspectionMode()) { - renderOutlineFlags = RenderArgs::RENDER_OUTLINE_MARKETPLACE_MODE; - } else { - renderOutlineFlags = RenderArgs::RENDER_OUTLINE_WIREFRAMES; - } - } - renderArgs->_outlineFlags = renderOutlineFlags; } } @@ -6118,6 +6110,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri auto entityScriptServerLog = DependencyManager::get(); scriptEngine->registerGlobalObject("EntityScriptServerLog", entityScriptServerLog.data()); scriptEngine->registerGlobalObject("AvatarInputs", AvatarInputs::getInstance()); + scriptEngine->registerGlobalObject("Selection", DependencyManager::get().data()); scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get().data()); qScriptRegisterMetaType(scriptEngine, OverlayIDtoScriptValue, OverlayIDfromScriptValue); diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index dddfae6455..08eb79017f 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -111,3 +111,10 @@ void Ledger::inventory(const QStringList& keys) { void Ledger::history(const QStringList& keys) { keysQuery("history", "historySuccess", "historyFailure"); } + +// The api/failResponse is called just for the side effect of logging. +void Ledger::resetSuccess(QNetworkReply& reply) { apiResponse("reset", reply); } +void Ledger::resetFailure(QNetworkReply& reply) { failResponse("reset", reply); } +void Ledger::reset() { + send("reset_user_hfc_account", "resetSuccess", "resetFailure", QNetworkAccessManager::PutOperation, QJsonObject()); +} \ No newline at end of file diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index 7d3fdef0c0..55b648aa4c 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -29,6 +29,7 @@ public: void balance(const QStringList& keys); void inventory(const QStringList& keys); void history(const QStringList& keys); + void reset(); signals: void buyResult(QJsonObject result); @@ -48,6 +49,8 @@ public slots: void inventoryFailure(QNetworkReply& reply); void historySuccess(QNetworkReply& reply); void historyFailure(QNetworkReply& reply); + void resetSuccess(QNetworkReply& reply); + void resetFailure(QNetworkReply& reply); private: QJsonObject apiResponse(const QString& label, QNetworkReply& reply); diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index bf6bcc221c..655f228672 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -85,3 +85,10 @@ void QmlCommerce::getKeyFilePathIfExists() { auto wallet = DependencyManager::get(); wallet->sendKeyFilePathIfExists(); } + +void QmlCommerce::reset() { + auto ledger = DependencyManager::get(); + auto wallet = DependencyManager::get(); + ledger->reset(); + wallet->reset(); +} \ No newline at end of file diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index fd913ae4b7..deb11b7714 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -50,6 +50,7 @@ protected: Q_INVOKABLE void setPassphrase(const QString& passphrase); Q_INVOKABLE void getPassphraseSetupStatus(); Q_INVOKABLE void getKeyFilePathIfExists(); + Q_INVOKABLE void reset(); }; #endif // hifi_QmlCommerce_h diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 4cbcb5f1d3..32852602d7 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -14,6 +14,7 @@ #include "Wallet.h" #include "Application.h" #include "ui/ImageProvider.h" +#include "scripting/HMDScriptingInterface.h" #include #include @@ -464,7 +465,9 @@ void Wallet::getSecurityImage() { } // decrypt and return - if (decryptFile(imageFilePath(), &data, &dataLen)) { + QString filePath(imageFilePath()); + QFileInfo fileInfo(filePath); + if (fileInfo.exists() && decryptFile(filePath, &data, &dataLen)) { // create the pixmap _securityImage = new QPixmap(); _securityImage->loadFromData(data, dataLen, "jpg"); @@ -488,3 +491,24 @@ void Wallet::sendKeyFilePathIfExists() { emit keyFilePathIfExistsResult(""); } } + +void Wallet::reset() { + _publicKeys.clear(); + + delete _securityImage; + _securityImage = nullptr; + + // tell the provider we got nothing + updateImageProvider(); + delete _passphrase; + + // for now we need to maintain the hard-coded passphrase. + // FIXME: remove this line as part of wiring up the passphrase + // and probably set it to nullptr + _passphrase = new QString("pwd"); + + QFile keyFile(keyFilePath()); + QFile imageFile(imageFilePath()); + keyFile.remove(); + imageFile.remove(); +} diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 478a35625d..4acd913181 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -40,6 +40,8 @@ public: void setPassphrase(const QString& passphrase); QString* getPassphrase() { return _passphrase; } + void reset(); + signals: void securityImageResult(bool exists) ; void keyFilePathIfExistsResult(const QString& path); diff --git a/interface/src/scripting/SelectionScriptingInterface.cpp b/interface/src/scripting/SelectionScriptingInterface.cpp new file mode 100644 index 0000000000..808396c901 --- /dev/null +++ b/interface/src/scripting/SelectionScriptingInterface.cpp @@ -0,0 +1,195 @@ +// +// SelectionScriptingInterface.cpp +// interface/src/scripting +// +// Created by Zach Fox on 2017-08-22. +// Copyright 2017 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 +// + +#include "SelectionScriptingInterface.h" +#include +#include "Application.h" + +GameplayObjects::GameplayObjects() { +} + +bool GameplayObjects::addToGameplayObjects(const QUuid& avatarID) { + containsData = true; + _avatarIDs.push_back(avatarID); + return true; +} +bool GameplayObjects::removeFromGameplayObjects(const QUuid& avatarID) { + _avatarIDs.erase(std::remove(_avatarIDs.begin(), _avatarIDs.end(), avatarID), _avatarIDs.end()); + return true; +} + +bool GameplayObjects::addToGameplayObjects(const EntityItemID& entityID) { + containsData = true; + _entityIDs.push_back(entityID); + return true; +} +bool GameplayObjects::removeFromGameplayObjects(const EntityItemID& entityID) { + _entityIDs.erase(std::remove(_entityIDs.begin(), _entityIDs.end(), entityID), _entityIDs.end()); + return true; +} + +bool GameplayObjects::addToGameplayObjects(const OverlayID& overlayID) { + containsData = true; + _overlayIDs.push_back(overlayID); + return true; +} +bool GameplayObjects::removeFromGameplayObjects(const OverlayID& overlayID) { + _overlayIDs.erase(std::remove(_overlayIDs.begin(), _overlayIDs.end(), overlayID), _overlayIDs.end()); + return true; +} + + +SelectionScriptingInterface::SelectionScriptingInterface() { +} + +bool SelectionScriptingInterface::addToSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id) { + if (itemType == "avatar") { + return addToGameplayObjects(listName, (QUuid)id); + } else if (itemType == "entity") { + return addToGameplayObjects(listName, (EntityItemID)id); + } else if (itemType == "overlay") { + return addToGameplayObjects(listName, (OverlayID)id); + } + return false; +} +bool SelectionScriptingInterface::removeFromSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id) { + if (itemType == "avatar") { + return removeFromGameplayObjects(listName, (QUuid)id); + } else if (itemType == "entity") { + return removeFromGameplayObjects(listName, (EntityItemID)id); + } else if (itemType == "overlay") { + return removeFromGameplayObjects(listName, (OverlayID)id); + } + return false; +} + +template bool SelectionScriptingInterface::addToGameplayObjects(const QString& listName, T idToAdd) { + GameplayObjects currentList = _selectedItemsListMap.value(listName); + currentList.addToGameplayObjects(idToAdd); + _selectedItemsListMap.insert(listName, currentList); + + emit selectedItemsListChanged(listName); + return true; +} +template bool SelectionScriptingInterface::removeFromGameplayObjects(const QString& listName, T idToRemove) { + GameplayObjects currentList = _selectedItemsListMap.value(listName); + if (currentList.getContainsData()) { + currentList.removeFromGameplayObjects(idToRemove); + _selectedItemsListMap.insert(listName, currentList); + + emit selectedItemsListChanged(listName); + return true; + } else { + return false; + } +} +// +// END HANDLING GENERIC ITEMS +// + +GameplayObjects SelectionScriptingInterface::getList(const QString& listName) { + return _selectedItemsListMap.value(listName); +} + +void SelectionScriptingInterface::printList(const QString& listName) { + GameplayObjects currentList = _selectedItemsListMap.value(listName); + if (currentList.getContainsData()) { + + qDebug() << "Avatar IDs:"; + for (auto i : currentList.getAvatarIDs()) { + qDebug() << i << ';'; + } + qDebug() << ""; + + qDebug() << "Entity IDs:"; + for (auto j : currentList.getEntityIDs()) { + qDebug() << j << ';'; + } + qDebug() << ""; + + qDebug() << "Overlay IDs:"; + for (auto k : currentList.getOverlayIDs()) { + qDebug() << k << ';'; + } + qDebug() << ""; + } else { + qDebug() << "List named" << listName << "doesn't exist."; + } +} + +bool SelectionScriptingInterface::removeListFromMap(const QString& listName) { + if (_selectedItemsListMap.remove(listName)) { + emit selectedItemsListChanged(listName); + return true; + } else { + return false; + } +} + + +SelectionToSceneHandler::SelectionToSceneHandler() { +} + +void SelectionToSceneHandler::initialize(const QString& listName) { + _listName = listName; +} + +void SelectionToSceneHandler::selectedItemsListChanged(const QString& listName) { + if (listName == _listName) { + updateSceneFromSelectedList(); + } +} + +void SelectionToSceneHandler::updateSceneFromSelectedList() { + auto mainScene = qApp->getMain3DScene(); + if (mainScene) { + GameplayObjects thisList = DependencyManager::get()->getList(_listName); + render::Transaction transaction; + render::ItemIDs finalList; + render::ItemID currentID; + auto entityTreeRenderer = DependencyManager::get(); + auto& overlays = qApp->getOverlays(); + + for (QUuid& currentAvatarID : thisList.getAvatarIDs()) { + auto avatar = std::static_pointer_cast(DependencyManager::get()->getAvatarBySessionID(currentAvatarID)); + if (avatar) { + currentID = avatar->getRenderItemID(); + if (currentID != render::Item::INVALID_ITEM_ID) { + finalList.push_back(currentID); + } + } + } + + for (EntityItemID& currentEntityID : thisList.getEntityIDs()) { + currentID = entityTreeRenderer->renderableIdForEntityId(currentEntityID); + if (currentID != render::Item::INVALID_ITEM_ID) { + finalList.push_back(currentID); + } + } + + for (OverlayID& currentOverlayID : thisList.getOverlayIDs()) { + auto overlay = overlays.getOverlay(currentOverlayID); + if (overlay != NULL) { + currentID = overlay->getRenderItemID(); + if (currentID != render::Item::INVALID_ITEM_ID) { + finalList.push_back(currentID); + } + } + } + + render::Selection selection(_listName.toStdString(), finalList); + transaction.resetSelection(selection); + + mainScene->enqueueTransaction(transaction); + } else { + qWarning() << "SelectionToSceneHandler::updateRendererSelectedList(), Unexpected null scene, possibly during application shutdown"; + } +} diff --git a/interface/src/scripting/SelectionScriptingInterface.h b/interface/src/scripting/SelectionScriptingInterface.h new file mode 100644 index 0000000000..d1a372c5c4 --- /dev/null +++ b/interface/src/scripting/SelectionScriptingInterface.h @@ -0,0 +1,91 @@ + +// SelectionScriptingInterface.h +// interface/src/scripting +// +// Created by Zach Fox on 2017-08-22. +// Copyright 2017 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_SelectionScriptingInterface_h +#define hifi_SelectionScriptingInterface_h + +#include +#include +#include + +#include + +#include "RenderableEntityItem.h" +#include "ui/overlays/Overlay.h" +#include + +class GameplayObjects { +public: + GameplayObjects(); + + bool getContainsData() { return containsData; } + + std::vector getAvatarIDs() { return _avatarIDs; } + bool addToGameplayObjects(const QUuid& avatarID); + bool removeFromGameplayObjects(const QUuid& avatarID); + + std::vector getEntityIDs() { return _entityIDs; } + bool addToGameplayObjects(const EntityItemID& entityID); + bool removeFromGameplayObjects(const EntityItemID& entityID); + + std::vector getOverlayIDs() { return _overlayIDs; } + bool addToGameplayObjects(const OverlayID& overlayID); + bool removeFromGameplayObjects(const OverlayID& overlayID); + +private: + bool containsData { false }; + std::vector _avatarIDs; + std::vector _entityIDs; + std::vector _overlayIDs; +}; + + +class SelectionScriptingInterface : public QObject, public Dependency { + Q_OBJECT + +public: + SelectionScriptingInterface(); + + GameplayObjects getList(const QString& listName); + + Q_INVOKABLE void printList(const QString& listName); + Q_INVOKABLE bool removeListFromMap(const QString& listName); + + Q_INVOKABLE bool addToSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id); + Q_INVOKABLE bool removeFromSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id); + +signals: + void selectedItemsListChanged(const QString& listName); + +private: + QMap _selectedItemsListMap; + + template bool addToGameplayObjects(const QString& listName, T idToAdd); + template bool removeFromGameplayObjects(const QString& listName, T idToRemove); +}; + + +class SelectionToSceneHandler : public QObject { + Q_OBJECT +public: + SelectionToSceneHandler(); + void initialize(const QString& listName); + + void updateSceneFromSelectedList(); + +public slots: + void selectedItemsListChanged(const QString& listName); + +private: + QString _listName { "" }; +}; + +#endif // hifi_SelectionScriptingInterface_h diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 6704e81706..34aae37175 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -28,6 +28,9 @@ ContextOverlayInterface::ContextOverlayInterface() { _entityScriptingInterface = DependencyManager::get(); _hmdScriptingInterface = DependencyManager::get(); _tabletScriptingInterface = DependencyManager::get(); + _selectionScriptingInterface = DependencyManager::get(); + + _selectionToSceneHandler.initialize("contextOverlayHighlightList"); _entityPropertyFlags += PROP_POSITION; _entityPropertyFlags += PROP_ROTATION; @@ -58,6 +61,8 @@ ContextOverlayInterface::ContextOverlayInterface() { }); auto entityScriptingInterface = DependencyManager::get().data(); connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity); + + connect(_selectionScriptingInterface.data(), &SelectionScriptingInterface::selectedItemsListChanged, &_selectionToSceneHandler, &SelectionToSceneHandler::selectedItemsListChanged); } static const uint32_t LEFT_HAND_HW_ID = 1; @@ -261,25 +266,11 @@ void ContextOverlayInterface::openMarketplace() { } void ContextOverlayInterface::enableEntityHighlight(const EntityItemID& entityItemID) { - auto entityTree = qApp->getEntities()->getTree(); - entityTree->withReadLock([&] { - auto entityItem = entityTree->findEntityByEntityItemID(entityItemID); - if ((entityItem != NULL) && !entityItem->getShouldHighlight()) { - qCDebug(context_overlay) << "Setting 'shouldHighlight' to 'true' for Entity ID:" << entityItemID; - entityItem->setShouldHighlight(true); - } - }); + _selectionScriptingInterface->addToSelectedItemsList("contextOverlayHighlightList", "entity", entityItemID); } void ContextOverlayInterface::disableEntityHighlight(const EntityItemID& entityItemID) { - auto entityTree = qApp->getEntities()->getTree(); - entityTree->withReadLock([&] { - auto entityItem = entityTree->findEntityByEntityItemID(entityItemID); - if ((entityItem != NULL) && entityItem->getShouldHighlight()) { - qCDebug(context_overlay) << "Setting 'shouldHighlight' to 'false' for Entity ID:" << entityItemID; - entityItem->setShouldHighlight(false); - } - }); + _selectionScriptingInterface->removeFromSelectedItemsList("contextOverlayHighlightList", "entity", entityItemID); } void ContextOverlayInterface::deletingEntity(const EntityItemID& entityID) { diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index b386de08cc..c14262029e 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -25,6 +25,7 @@ #include "ui/overlays/Image3DOverlay.h" #include "ui/overlays/Overlays.h" #include "scripting/HMDScriptingInterface.h" +#include "scripting/SelectionScriptingInterface.h" #include "EntityTree.h" #include "ContextOverlayLogging.h" @@ -42,6 +43,7 @@ class ContextOverlayInterface : public QObject, public Dependency { EntityPropertyFlags _entityPropertyFlags; QSharedPointer _hmdScriptingInterface; QSharedPointer _tabletScriptingInterface; + QSharedPointer _selectionScriptingInterface; OverlayID _contextOverlayID { UNKNOWN_OVERLAY_ID }; std::shared_ptr _contextOverlay { nullptr }; public: @@ -81,6 +83,8 @@ private: void disableEntityHighlight(const EntityItemID& entityItemID); void deletingEntity(const EntityItemID& entityItemID); + + SelectionToSceneHandler _selectionToSceneHandler; }; #endif // hifi_ContextOverlayInterface_h diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 94d328ee56..d35d6ceba0 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -242,6 +242,7 @@ public: void addToScene(AvatarSharedPointer self, const render::ScenePointer& scene); void ensureInScene(AvatarSharedPointer self, const render::ScenePointer& scene); bool isInScene() const { return render::Item::isValidID(_renderItemID); } + render::ItemID getRenderItemID() { return _renderItemID; } bool isMoving() const { return _moving; } void setPhysicsCallback(AvatarPhysicsCallback cb); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 429bb629c6..0950974347 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -147,6 +147,7 @@ public slots: void setDisplayModelBounds(bool value) { _displayModelBounds = value; } void setPrecisionPicking(bool value) { _setPrecisionPickingOperator(_mouseRayPickID, value); } EntityRendererPointer renderableForEntityId(const EntityItemID& id) const; + render::ItemID renderableIdForEntityId(const EntityItemID& id) const; protected: virtual OctreePointer createTree() override { @@ -156,7 +157,6 @@ protected: } private: - render::ItemID renderableIdForEntityId(const EntityItemID& id) const; EntityRendererPointer renderableForEntity(const EntityItemPointer& entity) const { return renderableForEntityId(entity->getID()); } render::ItemID renderableIdForEntity(const EntityItemPointer& entity) const { return renderableIdForEntityId(entity->getID()); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 5ec0a1408a..277f6898d1 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1080,7 +1080,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } _marketplaceEntity = entity->getMarketplaceID().length() != 0; - _shouldHighlight = entity->getShouldHighlight(); _animating = entity->isAnimatingSomething(); withWriteLock([&] { @@ -1207,17 +1206,6 @@ void ModelEntityRenderer::doRender(RenderArgs* args) { model = _model; }); - // this simple logic should say we set showingEntityHighlight to true whenever we are in marketplace mode and we have a marketplace id, or - // whenever we are not set to none and shouldHighlight is true. - bool showingEntityHighlight = ((bool)(args->_outlineFlags & (int)RenderArgs::RENDER_OUTLINE_MARKETPLACE_MODE) && _marketplaceEntity != 0) || - (args->_outlineFlags != RenderArgs::RENDER_OUTLINE_NONE && _shouldHighlight); - if (showingEntityHighlight) { - static glm::vec4 yellowColor(1.0f, 1.0f, 0.0f, 1.0f); - gpu::Batch& batch = *args->_batch; - batch.setModelTransform(_modelTransform); // we want to include the scale as well - DependencyManager::get()->renderWireCubeInstance(args, batch, yellowColor); - } - if (_model && _model->didVisualGeometryRequestFail()) { static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f); gpu::Batch& batch = *args->_batch; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 0c120d586c..5f9bd7e7ea 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -94,7 +94,6 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_LOCKED; requestedProperties += PROP_USER_DATA; requestedProperties += PROP_MARKETPLACE_ID; - requestedProperties += PROP_SHOULD_HIGHLIGHT; requestedProperties += PROP_NAME; requestedProperties += PROP_HREF; requestedProperties += PROP_DESCRIPTION; @@ -240,7 +239,6 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked()); APPEND_ENTITY_PROPERTY(PROP_USER_DATA, getUserData()); APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, getMarketplaceID()); - APPEND_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, getShouldHighlight()); APPEND_ENTITY_PROPERTY(PROP_NAME, getName()); APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL()); APPEND_ENTITY_PROPERTY(PROP_HREF, getHref()); @@ -792,10 +790,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); } - if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT) { - READ_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, bool, setShouldHighlight); - } - READ_ENTITY_PROPERTY(PROP_NAME, QString, setName); READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL); READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref); @@ -2772,20 +2766,6 @@ void EntityItem::setMarketplaceID(const QString& value) { }); } -bool EntityItem::getShouldHighlight() const { - bool result; - withReadLock([&] { - result = _shouldHighlight; - }); - return result; -} - -void EntityItem::setShouldHighlight(const bool value) { - withWriteLock([&] { - _shouldHighlight = value; - }); -} - uint32_t EntityItem::getDirtyFlags() const { uint32_t result; withReadLock([&] { diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 1bd75f78d4..20b541f563 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -289,7 +289,6 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_RADIUS_START, radiusStart); CHECK_PROPERTY_CHANGE(PROP_RADIUS_FINISH, radiusFinish); CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID); - CHECK_PROPERTY_CHANGE(PROP_SHOULD_HIGHLIGHT, shouldHighlight); CHECK_PROPERTY_CHANGE(PROP_NAME, name); CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode); CHECK_PROPERTY_CHANGE(PROP_SOURCE_URL, sourceUrl); @@ -407,7 +406,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCKED, locked); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USER_DATA, userData); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MARKETPLACE_ID, marketplaceID); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SHOULD_HIGHLIGHT, shouldHighlight); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL); @@ -984,7 +982,6 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_RADIUS_START, RadiusStart, radiusStart, float); ADD_PROPERTY_TO_MAP(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float); ADD_PROPERTY_TO_MAP(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString); - ADD_PROPERTY_TO_MAP(PROP_SHOULD_HIGHLIGHT, ShouldHighlight, shouldHighlight, bool); ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor); ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float); ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_AMBIENT_INTENSITY, KeyLightAmbientIntensity, keyLightAmbientIntensity, float); @@ -1337,7 +1334,6 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_SHAPE, properties.getShape()); } APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID()); - APPEND_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, properties.getShouldHighlight()); APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL()); APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, properties.getActionData()); @@ -1636,7 +1632,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHOULD_HIGHLIGHT, bool, setShouldHighlight); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACTION_DATA, QByteArray, setActionData); @@ -1751,7 +1746,6 @@ void EntityItemProperties::markAllChanged() { //_alphaFinishChanged = true; _marketplaceIDChanged = true; - _shouldHighlightChanged = true; _keyLight.markAllChanged(); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index b04c3e7dc7..dd8ce952d3 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -171,7 +171,6 @@ public: DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float, particle::DEFAULT_RADIUS_FINISH); DEFINE_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, EmitterShouldTrail, emitterShouldTrail, bool, particle::DEFAULT_EMITTER_SHOULD_TRAIL); DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID); - DEFINE_PROPERTY_REF(PROP_SHOULD_HIGHLIGHT, ShouldHighlight, shouldHighlight, bool, ENTITY_ITEM_DEFAULT_SHOULD_HIGHLIGHT); DEFINE_PROPERTY_GROUP(KeyLight, keyLight, KeyLightPropertyGroup); DEFINE_PROPERTY_REF(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3, PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE); DEFINE_PROPERTY_REF(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray, PolyVoxEntityItem::DEFAULT_VOXEL_DATA); diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index 43d0e33ba6..d52c5d9aab 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -27,7 +27,6 @@ const glm::vec3 ENTITY_ITEM_HALF_VEC3 = glm::vec3(0.5f); const bool ENTITY_ITEM_DEFAULT_LOCKED = false; const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString(""); const QString ENTITY_ITEM_DEFAULT_MARKETPLACE_ID = QString(""); -const bool ENTITY_ITEM_DEFAULT_SHOULD_HIGHLIGHT = false; const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid(); const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f; diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 9600d0d4fe..b3cfc143c2 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -78,7 +78,6 @@ enum EntityPropertyList { PROP_COMPOUND_SHAPE_URL, // used by Model + zones entities PROP_MARKETPLACE_ID, // all entities - PROP_SHOULD_HIGHLIGHT, // all entities PROP_ACCELERATION, // all entities PROP_SIMULATION_OWNER, // formerly known as PROP_SIMULATOR_ID PROP_NAME, // all entities diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index f44beb6d74..c9961cc53a 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT; + return VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE; case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::JSONFilterWithFamilyTree); case PacketType::AvatarIdentity: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index e8b74a74d5..3ba2b96dfc 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -259,6 +259,7 @@ const PacketVersion VERSION_ENTITIES_ZONE_FILTERS = 68; const PacketVersion VERSION_ENTITIES_HINGE_CONSTRAINT = 69; const PacketVersion VERSION_ENTITIES_BULLET_DYNAMICS = 70; const PacketVersion VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT = 71; +const PacketVersion VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE = 72; enum class EntityQueryPacketVersion: PacketVersion { JSONFilter = 18, diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 68c0250bec..27abc8c282 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -210,6 +210,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren } task.addJob("DrawZoneStack", deferredFrameTransform); + + // Render.getConfig("RenderMainView.DrawSelectionBounds").enabled = true + const auto selectedMetas = task.addJob("PassTestSelection", metas, "contextOverlayHighlightList"); + task.addJob("DrawSelectionBounds", selectedMetas); } // AA job to be revisited diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index 12f9506286..7070a4def5 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -63,12 +63,6 @@ namespace render { public: enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE, SECONDARY_CAMERA_RENDER_MODE }; enum DisplayMode { MONO, STEREO_MONITOR, STEREO_HMD }; - enum OutlineFlags { - RENDER_OUTLINE_NONE = 0, - RENDER_OUTLINE_WIREFRAMES = 1, - RENDER_OUTLINE_MARKETPLACE_MODE = 2, - RENDER_OUTLINE_SHADER = 4 - }; enum DebugFlags { RENDER_DEBUG_NONE = 0, RENDER_DEBUG_HULLS = 1 @@ -115,7 +109,6 @@ namespace render { int _boundaryLevelAdjust { 0 }; RenderMode _renderMode { DEFAULT_RENDER_MODE }; DisplayMode _displayMode { MONO }; - OutlineFlags _outlineFlags{ RENDER_OUTLINE_NONE }; DebugFlags _debugFlags { RENDER_DEBUG_NONE }; gpu::Batch* _batch = nullptr; diff --git a/libraries/ui/src/ui/ImageProvider.cpp b/libraries/ui/src/ui/ImageProvider.cpp index 6398e6fad2..c74ed0cb44 100644 --- a/libraries/ui/src/ui/ImageProvider.cpp +++ b/libraries/ui/src/ui/ImageProvider.cpp @@ -18,10 +18,25 @@ const QString ImageProvider::PROVIDER_NAME = "security"; QReadWriteLock ImageProvider::_rwLock; QPixmap* ImageProvider::_securityImage = nullptr; -void ImageProvider::setSecurityImage(QPixmap* pixmap) { +ImageProvider::~ImageProvider() { + QWriteLocker lock(&_rwLock); + if (_securityImage) { + delete _securityImage; + _securityImage = nullptr; + } +} + +void ImageProvider::setSecurityImage(const QPixmap* pixmap) { // no need to delete old one, that is managed by the wallet QWriteLocker lock(&_rwLock); - _securityImage = pixmap; + if (_securityImage) { + delete _securityImage; + } + if (pixmap) { + _securityImage = new QPixmap(*pixmap); + } else { + _securityImage = nullptr; + } } QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) { diff --git a/libraries/ui/src/ui/ImageProvider.h b/libraries/ui/src/ui/ImageProvider.h index 5bd2e254e7..0093b60655 100644 --- a/libraries/ui/src/ui/ImageProvider.h +++ b/libraries/ui/src/ui/ImageProvider.h @@ -20,10 +20,10 @@ public: static const QString PROVIDER_NAME; ImageProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) {} - + virtual ~ImageProvider(); QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override; - void setSecurityImage(QPixmap* pixmap); + void setSecurityImage(const QPixmap* pixmap); protected: static QReadWriteLock _rwLock; static QPixmap* _securityImage; diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 34c602513e..a7b7b50379 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -70,6 +70,10 @@ case 'maybeEnableHmdPreview': Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled); break; + case 'walletReset': + onButtonClicked(); + onButtonClicked(); + break; default: print('Unrecognized message from QML:', JSON.stringify(message)); } diff --git a/scripts/system/edit.js b/scripts/system/edit.js index b2abda96cb..e714ee15ff 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -405,9 +405,11 @@ var toolBar = (function () { } }); - var createButtonIconRsrc = ((Entities.canRez() || Entities.canRezTmp()) ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON); + var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp()); + var createButtonIconRsrc = (hasRezPermissions ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON); tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); activeButton = tablet.addButton({ + captionColorOverride: hasRezPermissions ? "" : "#888888", icon: createButtonIconRsrc, activeIcon: "icons/tablet-icons/edit-a.svg", text: "CREATE", @@ -780,6 +782,7 @@ function handleDomainChange() { var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp()); createButton.editProperties({ icon: (hasRezPermissions ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON), + captionColorOverride: (hasRezPermissions ? "" : "#888888"), }); } diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 2675bb97b6..28d116d3ec 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -173,16 +173,16 @@ function injectHiFiItemPageCode() { if (confirmAllPurchases) { - var href = $('#side-info').find('.btn').attr('href'); - $('#side-info').find('.btn').attr('href', '#'); + var href = $('#side-info').find('.btn').first().attr('href'); + $('#side-info').find('.btn').first().attr('href', '#'); var cost = $('.item-cost').text(); if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) { - $('#side-info').find('.btn').html('Own Item: ' + (parseFloat(cost / 100).toFixed(2)) + ' HFC'); + $('#side-info').find('.btn').first().html('Own Item: ' + (parseFloat(cost / 100).toFixed(2)) + ' HFC'); } - $('#side-info').find('.btn').on('click', function () { + $('#side-info').find('.btn').first().on('click', function () { buyButtonClicked(window.location.pathname.split("/")[3], $('#top-center').find('h1').text(), $('#creator').find('.value').text(),