diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index cff42971b4..fea244873c 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -118,7 +118,7 @@ macro(SET_PACKAGING_PARAMETERS) set(CONSOLE_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION}") endif () - set(INTERFACE_HF_SHORTCUT_NAME "High Fidelity ${INTERFACE_SHORTCUT_NAME}") + set(INTERFACE_HF_SHORTCUT_NAME "${INTERFACE_SHORTCUT_NAME}") set(CONSOLE_HF_SHORTCUT_NAME "High Fidelity ${CONSOLE_SHORTCUT_NAME}") set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "High Fidelity") diff --git a/interface/resources/qml/controls-uit/Tree.qml b/interface/resources/qml/controls-uit/Tree.qml index 8bce092947..53f66fa67c 100644 --- a/interface/resources/qml/controls-uit/Tree.qml +++ b/interface/resources/qml/controls-uit/Tree.qml @@ -27,6 +27,7 @@ TreeView { model: treeModel selection: ItemSelectionModel { + id: selectionModel model: treeModel } @@ -215,6 +216,10 @@ TreeView { onDoubleClicked: isExpanded(index) ? collapse(index) : expand(index) + onClicked: { + selectionModel.setCurrentIndex(index, ItemSelectionModel.ClearAndSelect); + } + onActivated: { var path = scriptsModel.data(index, 0x100) if (path) { diff --git a/interface/resources/qml/controls-uit/WebGlyphButton.qml b/interface/resources/qml/controls-uit/WebGlyphButton.qml new file mode 100644 index 0000000000..15524e4188 --- /dev/null +++ b/interface/resources/qml/controls-uit/WebGlyphButton.qml @@ -0,0 +1,48 @@ +// +// GlyphButton.qml +// +// Created by Vlad Stelmahovsky on 2017-06-21 +// 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" + +Original.Button { + id: control + + property int colorScheme: hifi.colorSchemes.light + property string glyph: "" + property int size: 32 + //colors + readonly property color normalColor: "#AFAFAF" + readonly property color hoverColor: "#00B4EF" + readonly property color clickedColor: "#FFFFFF" + readonly property color disabledColor: "#575757" + + style: ButtonStyle { + background: Item {} + + + label: HiFiGlyphs { + color: control.enabled ? (control.pressed ? control.clickedColor : + (control.hovered ? control.hoverColor : control.normalColor)) : + control.disabledColor + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + anchors { + // Tweak horizontal alignment so that it looks right. + left: parent.left + leftMargin: -0.5 + } + text: control.glyph + size: control.size + } + } +} diff --git a/interface/resources/qml/hifi/SkyboxChanger.qml b/interface/resources/qml/hifi/SkyboxChanger.qml new file mode 100644 index 0000000000..a4798ba959 --- /dev/null +++ b/interface/resources/qml/hifi/SkyboxChanger.qml @@ -0,0 +1,173 @@ +// +// skyboxchanger.qml +// +// +// Created by Cain Kilgore on 9th August 2017 +// 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 +// + +import QtQuick.Layouts 1.3 + +Rectangle { + id: root; + + color: hifi.colors.baseGray; + + Item { + id: titleBarContainer; + // Size + width: parent.width; + height: 50; + // Anchors + anchors.left: parent.left; + anchors.top: parent.top; + + RalewaySemiBold { + id: titleBarText; + text: "Skybox Changer"; + // Text size + size: hifi.fontSizes.overlayTitle; + // Anchors + anchors.fill: parent; + anchors.leftMargin: 16; + // Style + color: hifi.colors.lightGrayText; + // Alignment + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; + } + RalewaySemiBold { + id: titleBarDesc; + text: "Click an image to choose a new Skybox."; + wrapMode: Text.Wrap + // Text size + size: 14; + // Anchors + anchors.fill: parent; + anchors.top: titleBarText.bottom + anchors.leftMargin: 16; + anchors.rightMargin: 16; + // Style + color: hifi.colors.lightGrayText; + // Alignment + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; + } + } + + // This RowLayout could be a GridLayout instead for further expandability. + // As this SkyboxChanger task only required 6 images, implementing GridLayout wasn't necessary. + // In the future if this is to be expanded to add more Skyboxes, it might be worth changing this. + RowLayout { + id: row1 + anchors.top: titleBarContainer.bottom + anchors.left: parent.left + anchors.leftMargin: 30 + Layout.fillWidth: true + anchors.topMargin: 30 + spacing: 10 + Image { + width: 200; height: 200 + fillMode: Image.Stretch + source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg" + clip: true + id: preview1 + MouseArea { + anchors.fill: parent + onClicked: { + sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg'}); + } + } + Layout.fillWidth: true + } + Image { + width: 200; height: 200 + fillMode: Image.Stretch + source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_2.jpg" + clip: true + id: preview2 + MouseArea { + anchors.fill: parent + onClicked: { + sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/2.png'}); + } + } + } + } + RowLayout { + id: row2 + anchors.top: row1.bottom + anchors.topMargin: 10 + anchors.left: parent.left + Layout.fillWidth: true + anchors.leftMargin: 30 + spacing: 10 + Image { + width: 200; height: 200 + fillMode: Image.Stretch + source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_3.jpg" + clip: true + id: preview3 + MouseArea { + anchors.fill: parent + onClicked: { + sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/3.jpg'}); + } + } + } + Image { + width: 200; height: 200 + fillMode: Image.Stretch + source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_4.jpg" + clip: true + id: preview4 + MouseArea { + anchors.fill: parent + onClicked: { + sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/4.jpg'}); + } + } + } + } + RowLayout { + id: row3 + anchors.top: row2.bottom + anchors.topMargin: 10 + anchors.left: parent.left + Layout.fillWidth: true + anchors.leftMargin: 30 + spacing: 10 + Image { + width: 200; height: 200 + fillMode: Image.Stretch + source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_5.jpg" + clip: true + id: preview5 + MouseArea { + anchors.fill: parent + onClicked: { + sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/5.png'}); + } + } + } + Image { + width: 200; height: 200 + fillMode: Image.Stretch + source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_6.jpg" + clip: true + id: preview6 + MouseArea { + anchors.fill: parent + onClicked: { + sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/6.jpg'}); + } + } + } + } + + signal sendToScript(var message); + +} diff --git a/interface/resources/qml/hifi/WebBrowser.qml b/interface/resources/qml/hifi/WebBrowser.qml new file mode 100644 index 0000000000..f639586668 --- /dev/null +++ b/interface/resources/qml/hifi/WebBrowser.qml @@ -0,0 +1,253 @@ +// +// WebBrowser.qml +// +// +// Created by Vlad Stelmahovsky on 06/22/2017 +// 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.5 as QQControls +import QtQuick.Layouts 1.3 +import QtQuick.Controls.Styles 1.4 + +import QtWebEngine 1.2 +import QtWebChannel 1.0 + +import "../styles-uit" +import "../controls-uit" as HifiControls +import "../windows" +import "../controls" + +Rectangle { + id: root; + + HifiConstants { id: hifi; } + + property string title: ""; + signal sendToScript(var message); + property bool keyboardEnabled: true // FIXME - Keyboard HMD only: Default to false + property bool keyboardRaised: false + property bool punctuationMode: false + + + color: hifi.colors.baseGray; + + // only show the title if loaded through a "loader" + + Column { + spacing: 2 + width: parent.width; + + RowLayout { + width: parent.width; + height: 48 + + HifiControls.WebGlyphButton { + enabled: webEngineView.canGoBack + glyph: hifi.glyphs.backward; + anchors.verticalCenter: parent.verticalCenter; + size: 38; + onClicked: { + webEngineView.goBack() + } + } + + HifiControls.WebGlyphButton { + enabled: webEngineView.canGoForward + glyph: hifi.glyphs.forward; + anchors.verticalCenter: parent.verticalCenter; + size: 38; + onClicked: { + webEngineView.goForward() + } + } + + QQControls.TextField { + id: addressBar + + Image { + anchors.verticalCenter: addressBar.verticalCenter; + x: 5 + z: 2 + id: faviconImage + width: 16; height: 16 + sourceSize: Qt.size(width, height) + source: webEngineView.icon + } + + HifiControls.WebGlyphButton { + glyph: webEngineView.loading ? hifi.glyphs.closeSmall : hifi.glyphs.reloadSmall; + anchors.verticalCenter: parent.verticalCenter; + width: hifi.dimensions.controlLineHeight + z: 2 + x: addressBar.width - 28 + onClicked: { + if (webEngineView.loading) { + webEngineView.stop() + } else { + reloadTimer.start() + } + } + } + + style: TextFieldStyle { + padding { + left: 26; + right: 26 + } + } + focus: true + Layout.fillWidth: true + text: webEngineView.url + onAccepted: webEngineView.url = text + } + HifiControls.WebGlyphButton { + checkable: true + //only QtWebEngine 1.3 + //checked: webEngineView.audioMuted + glyph: checked ? hifi.glyphs.unmuted : hifi.glyphs.muted + anchors.verticalCenter: parent.verticalCenter; + width: hifi.dimensions.controlLineHeight + onClicked: { + webEngineView.triggerWebAction(WebEngineView.ToggleMediaMute) + } + } + } + + QQControls.ProgressBar { + id: loadProgressBar + style: ProgressBarStyle { + background: Rectangle { + color: "#6A6A6A" + } + progress: Rectangle{ + color: "#00B4EF" + } + } + + width: parent.width; + minimumValue: 0 + maximumValue: 100 + value: webEngineView.loadProgress + height: 2 + } + + HifiControls.BaseWebView { + id: webEngineView + focus: true + objectName: "tabletWebEngineView" + + url: "http://www.highfidelity.com" + property real webViewHeight: root.height - loadProgressBar.height - 48 - 4 + + width: parent.width; + height: keyboardEnabled && keyboardRaised ? webViewHeight - keyboard.height : webViewHeight + + profile: HFTabletWebEngineProfile; + + property string userScriptUrl: "" + + // creates a global EventBridge object. + WebEngineScript { + id: createGlobalEventBridge + sourceCode: eventBridgeJavaScriptToInject + injectionPoint: WebEngineScript.DocumentCreation + worldId: WebEngineScript.MainWorld + } + + // detects when to raise and lower virtual keyboard + WebEngineScript { + id: raiseAndLowerKeyboard + injectionPoint: WebEngineScript.Deferred + sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" + worldId: WebEngineScript.MainWorld + } + + // User script. + WebEngineScript { + id: userScript + sourceUrl: webEngineView.userScriptUrl + injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. + worldId: WebEngineScript.MainWorld + } + + userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] + + settings.autoLoadImages: true + settings.javascriptEnabled: true + settings.errorPageEnabled: true + settings.pluginsEnabled: true + settings.fullScreenSupportEnabled: false + //from WebEngine 1.3 + // settings.autoLoadIconsForPage: false + // settings.touchIconsEnabled: false + + onCertificateError: { + error.defer(); + } + + Component.onCompleted: { + webChannel.registerObject("eventBridge", eventBridge); + webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper); + webEngineView.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface)"; + } + + onFeaturePermissionRequested: { + grantFeaturePermission(securityOrigin, feature, true); + } + + onNewViewRequested: { + if (!request.userInitiated) { + print("Warning: Blocked a popup window."); + } + } + + onRenderProcessTerminated: { + var status = ""; + switch (terminationStatus) { + case WebEngineView.NormalTerminationStatus: + status = "(normal exit)"; + break; + case WebEngineView.AbnormalTerminationStatus: + status = "(abnormal exit)"; + break; + case WebEngineView.CrashedTerminationStatus: + status = "(crashed)"; + break; + case WebEngineView.KilledTerminationStatus: + status = "(killed)"; + break; + } + + print("Render process exited with code " + exitCode + " " + status); + reloadTimer.running = true; + } + + onWindowCloseRequested: { + } + + Timer { + id: reloadTimer + interval: 0 + running: false + repeat: false + onTriggered: webEngineView.reload() + } + } + } + + HifiControls.Keyboard { + id: keyboard + raised: parent.keyboardEnabled && parent.keyboardRaised + numeric: parent.punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + } +} diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml index a0a5af88ab..865bb72921 100644 --- a/interface/resources/qml/hifi/commerce/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/Checkout.qml @@ -24,40 +24,48 @@ Rectangle { HifiConstants { id: hifi; } id: checkoutRoot; - property string itemId; - property string itemHref; - property int balanceAfterPurchase: commerce.balance() - parseInt(itemPriceText.text, 10); - property bool alreadyOwned: checkAlreadyOwned(itemId); + property bool inventoryReceived: false; + property bool balanceReceived: false; + property string itemId: ""; + property string itemHref: ""; + property int balanceAfterPurchase: 0; + property bool alreadyOwned: false; // Style color: hifi.colors.baseGray; Hifi.QmlCommerce { id: commerce; onBuyResult: { - /* - if (buyFailed) { - sendToScript({method: 'checkout_cancelClicked', params: itemId}); - } else { - var success = commerce.buy(itemId, parseInt(itemPriceText.text)); - sendToScript({method: 'checkout_buyClicked', success: success, itemId: itemId, itemHref: itemHref}); - if (success) { - if (urlHandler.canHandleUrl(itemHref)) { - urlHandler.handleUrl(itemHref); - } - } - } - */ - if (failureMessage.length) { - console.log('buy failed', failureMessage); - //fixme sendToScript({method: 'checkout_cancelClicked', params: itemId}); + buyButton.text = "Buy Failed"; + buyButton.enabled = false; } else { - console.log('buy ok'); - //fixme sendToScript({method: 'checkout_buyClicked', success: , itemId: itemId, itemHref: itemHref}); + if (urlHandler.canHandleUrl(itemHref)) { + urlHandler.handleUrl(itemHref); + } + sendToScript({method: 'checkout_buySuccess', itemId: itemId}); } } - // FIXME: remove these two after testing - onBalanceResult: console.log('balance', balance, failureMessage); - onInventoryResult: console.log('inventory', inventory, failureMessage); + onBalanceResult: { + if (failureMessage.length) { + console.log("Failed to get balance", failureMessage); + } else { + balanceReceived = true; + hfcBalanceText.text = balance; + balanceAfterPurchase = balance - parseInt(itemPriceText.text, 10); + } + } + onInventoryResult: { + if (failureMessage.length) { + console.log("Failed to get inventory", failureMessage); + } else { + inventoryReceived = true; + if (inventoryContains(inventory.assets, itemId)) { + alreadyOwned = true; + } else { + alreadyOwned = false; + } + } + } } // @@ -229,7 +237,7 @@ Rectangle { } RalewayRegular { id: hfcBalanceText; - text: commerce.balance(); + text: "--"; // Text size size: hfcBalanceTextLabel.size; // Anchors @@ -366,15 +374,14 @@ Rectangle { width: parent.width/2 - anchors.leftMargin*2; text: "Cancel" onClicked: { - sendToScript({method: 'checkout_cancelClicked', params: itemId}); //fixme + sendToScript({method: 'checkout_cancelClicked', params: itemId}); } } // "Buy" button HifiControlsUit.Button { - property bool buyFailed: false; // fixme id: buyButton; - enabled: balanceAfterPurchase >= 0 && !alreadyOwned; + enabled: balanceAfterPurchase >= 0 && !alreadyOwned && inventoryReceived && balanceReceived; color: hifi.buttons.black; colorScheme: hifi.colorSchemes.dark; anchors.top: parent.top; @@ -384,7 +391,7 @@ Rectangle { anchors.right: parent.right; anchors.rightMargin: 20; width: parent.width/2 - anchors.rightMargin*2; - text: alreadyOwned ? "Already Owned" : "Buy"; + text: (inventoryReceived && balanceReceived) ? (alreadyOwned ? "Already Owned" : "Buy") : "--"; onClicked: { commerce.buy(itemId, parseInt(itemPriceText.text)); } @@ -397,16 +404,6 @@ Rectangle { // // FUNCTION DEFINITIONS START // - - function checkAlreadyOwned(idToCheck) { - var inventory = commerce.inventory(); - if (inventory.indexOf(idToCheck) !== -1) { - return true; - } else { - return false; - } - } - // // Function Name: fromScript() // @@ -428,11 +425,8 @@ Rectangle { itemAuthorText.text = message.params.itemAuthor; itemPriceText.text = message.params.itemPrice; itemHref = message.params.itemHref; - buyButton.buyFailed = false; - break; - case 'buyFailed': - buyButton.text = "Buy Failed"; - buyButton.buyFailed = true; + commerce.balance(); + commerce.inventory(); break; default: console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message)); @@ -440,6 +434,15 @@ Rectangle { } signal sendToScript(var message); + function inventoryContains(inventoryJson, id) { + for (var idx = 0; idx < inventoryJson.length; idx++) { + if(inventoryJson[idx].id === id) { + return true; + } + } + return false; + } + // // FUNCTION DEFINITIONS END // diff --git a/interface/resources/qml/hifi/commerce/Inventory.qml b/interface/resources/qml/hifi/commerce/Inventory.qml index 91fa3b9126..298abebdab 100644 --- a/interface/resources/qml/hifi/commerce/Inventory.qml +++ b/interface/resources/qml/hifi/commerce/Inventory.qml @@ -29,6 +29,20 @@ Rectangle { color: hifi.colors.baseGray; Hifi.QmlCommerce { id: commerce; + onBalanceResult: { + if (failureMessage.length) { + console.log("Failed to get balance", failureMessage); + } else { + hfcBalanceText.text = balance; + } + } + onInventoryResult: { + if (failureMessage.length) { + console.log("Failed to get inventory", failureMessage); + } else { + inventoryContentsList.model = inventory.assets; + } + } } // @@ -101,7 +115,7 @@ Rectangle { } RalewayRegular { id: hfcBalanceText; - text: commerce.balance(); + text: "--"; // Text size size: hfcBalanceTextLabel.size; // Anchors @@ -158,7 +172,6 @@ Rectangle { anchors.left: parent.left; anchors.bottom: parent.bottom; width: parent.width; - model: commerce.inventory(); delegate: Item { width: parent.width; height: 30; @@ -168,7 +181,7 @@ Rectangle { size: 20; // Style color: hifi.colors.blueAccent; - text: modelData; + text: modelData.title; // Alignment horizontalAlignment: Text.AlignHLeft; } @@ -176,7 +189,7 @@ Rectangle { anchors.fill: parent; hoverEnabled: enabled; onClicked: { - sendToScript({method: 'inventory_itemClicked', itemId: thisItemId.text}); + sendToScript({method: 'inventory_itemClicked', itemId: modelData.id}); } onEntered: { thisItemId.color = hifi.colors.blueHighlight; @@ -247,6 +260,8 @@ Rectangle { switch (message.method) { case 'updateInventory': referrerURL = message.referrerURL; + commerce.balance(); + commerce.inventory(); break; default: console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message)); diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index b8f9277a2a..ad79a836ad 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -44,7 +44,11 @@ void Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, cons return emit buyResult("Insufficient funds."); } _balance -= cost; - _inventory.push_back(asset_id); + QJsonObject inventoryAdditionObject; + inventoryAdditionObject["id"] = asset_id; + inventoryAdditionObject["title"] = "Test Title"; + inventoryAdditionObject["preview"] = "https://www.aspca.org/sites/default/files/cat-care_cat-nutrition-tips_overweight_body4_left.jpg"; + _inventory.push_back(inventoryAdditionObject); emit buyResult(""); } @@ -69,6 +73,9 @@ void Ledger::balance(const QStringList& keys) { void Ledger::inventory(const QStringList& keys) { // FIXME: talk to server instead - qCInfo(commerce) << "Inventory:" << _inventory; - emit inventoryResult(_inventory, ""); + QJsonObject inventoryObject; + inventoryObject.insert("success", true); + inventoryObject.insert("assets", _inventory); + qCInfo(commerce) << "Inventory:" << inventoryObject; + emit inventoryResult(inventoryObject, ""); } \ No newline at end of file diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index 4cf6aec4ff..74ed8c1ab3 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -15,6 +15,8 @@ #define hifi_Ledger_h #include +#include +#include class Ledger : public QObject, public Dependency { Q_OBJECT @@ -30,12 +32,12 @@ signals: void buyResult(const QString& failureReason); void receiveAtResult(const QString& failureReason); void balanceResult(int balance, const QString& failureReason); - void inventoryResult(QStringList inventory, const QString& failureReason); + void inventoryResult(QJsonObject inventory, const QString& failureReason); private: // These in-memory caches is temporary, until we start sending things to the server. int _balance{ -1 }; - QStringList _inventory{}; + QJsonArray _inventory{}; int initializedBalance() { if (_balance < 0) _balance = 100; return _balance; } }; diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index 050371a801..0b1d232fd7 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -29,7 +29,7 @@ signals: // Balance and Inventory are NOT properties, because QML can't change them (without risk of failure), and // because we can't scalably know of out-of-band changes (e.g., another machine interacting with the block chain). void balanceResult(int balance, const QString& failureMessage); - void inventoryResult(QStringList inventory, const QString& failureMessage); + void inventoryResult(QJsonObject inventory, const QString& failureMessage); protected: Q_INVOKABLE void buy(const QString& assetId, int cost, const QString& buyerUsername = ""); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 03a75c71dd..46fb2df007 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -55,6 +55,8 @@ ContextOverlayInterface::ContextOverlayInterface() { _contextOverlayJustClicked = false; } }); + auto entityScriptingInterface = DependencyManager::get().data(); + connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity); } static const uint32_t LEFT_HAND_HW_ID = 1; @@ -278,3 +280,9 @@ void ContextOverlayInterface::disableEntityHighlight(const EntityItemID& entityI } }); } + +void ContextOverlayInterface::deletingEntity(const EntityItemID& entityID) { + if (_currentEntityWithContextOverlay == entityID) { + destroyContextOverlay(_currentEntityWithContextOverlay, PointerEvent()); + } +} diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index ba9cb68575..b386de08cc 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -80,6 +80,7 @@ private: void enableEntityHighlight(const EntityItemID& entityItemID); void disableEntityHighlight(const EntityItemID& entityItemID); + void deletingEntity(const EntityItemID& entityItemID); }; #endif // hifi_ContextOverlayInterface_h diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 0e936c49e0..322dbe9be5 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -544,7 +544,7 @@ public: Q_INVOKABLE void updateAvatarEntity(const QUuid& entityID, const QByteArray& entityData); Q_INVOKABLE void clearAvatarEntity(const QUuid& entityID); - void setForceFaceTrackerConnected(bool connected) { _forceFaceTrackerConnected = connected; } + Q_INVOKABLE void setForceFaceTrackerConnected(bool connected) { _forceFaceTrackerConnected = connected; } // key state void setKeyState(KeyState s) { _keyState = s; } diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index e44e9fda94..9378a1d95b 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -204,12 +204,8 @@ // I don't think this is trivial to do since we also want to inject some JS into the DOM. //tablet.popFromStack(); break; - case 'checkout_buyClicked': - if (message.success === true) { - tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL); - } else { - tablet.sendToQml({ method: 'buyFailed' }); - } + case 'checkout_buySuccess': + tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL); //tablet.popFromStack(); break; case 'inventory_itemClicked': diff --git a/unpublishedScripts/marketplace/skyboxChanger/skyboxchanger.js b/unpublishedScripts/marketplace/skyboxChanger/skyboxchanger.js new file mode 100644 index 0000000000..e7a135ec9e --- /dev/null +++ b/unpublishedScripts/marketplace/skyboxChanger/skyboxchanger.js @@ -0,0 +1,118 @@ +"use strict"; + +// +// skyboxchanger.js +// +// Created by Cain Kilgore on 9th August 2017 +// 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 +// + +(function() { + var TABLET_BUTTON_NAME = "SKYBOX"; + + var ICONS = { + icon: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxedit-i.svg", + activeIcon: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxedit-i.svg" + }; + + var onSkyboxChangerScreen = false; + + function onClicked() { + if (onSkyboxChangerScreen) { + tablet.gotoHomeScreen(); + } else { + tablet.loadQMLSource("../SkyboxChanger.qml"); + } + } + + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + var button = tablet.addButton({ + icon: ICONS.icon, + activeIcon: ICONS.activeIcon, + text: TABLET_BUTTON_NAME, + sortOrder: 1 + }); + + var hasEventBridge = false; + + function wireEventBridge(on) { + if (!tablet) { + print("Warning in wireEventBridge(): 'tablet' undefined!"); + return; + } + if (on) { + if (!hasEventBridge) { + tablet.fromQml.connect(fromQml); + hasEventBridge = true; + } + } else { + if (hasEventBridge) { + tablet.fromQml.disconnect(fromQml); + hasEventBridge = false; + } + } + } + + function onScreenChanged(type, url) { + if (url === "../SkyboxChanger.qml") { + onSkyboxChangerScreen = true; + } else { + onSkyboxChangerScreen = false; + } + + button.editProperties({isActive: onSkyboxChangerScreen}); + wireEventBridge(onSkyboxChangerScreen); + } + + function fromQml(message) { + switch (message.method) { + case 'changeSkybox': // changeSkybox Code + var standingZone; + if (!Entities.canRez()) { + Window.alert("You need to have rez permissions to change the Skybox."); + break; + } + + var nearbyEntities = Entities.findEntities(MyAvatar.position, 5); + for (var i = 0; i < nearbyEntities.length; i++) { + if (Entities.getEntityProperties(nearbyEntities[i]).type === "Zone") { + standingZone = nearbyEntities[i]; + } + } + + if (Entities.getEntityProperties(standingZone).locked) { + Window.alert("This zone is currently locked; the Skybox can't be changed."); + break; + } + + var newSkybox = { + skybox: { + url: message.url + }, + keyLight: { + ambientURL: message.url + } + }; + + Entities.editEntity(standingZone, newSkybox); + break; + default: + print('Unrecognized message from QML: ' + JSON.stringify(message)); + } + } + + button.clicked.connect(onClicked); + tablet.screenChanged.connect(onScreenChanged); + + Script.scriptEnding.connect(function () { + if (onSkyboxChangerScreen) { + tablet.gotoHomeScreen(); + } + button.clicked.disconnect(onClicked); + tablet.screenChanged.disconnect(onScreenChanged); + tablet.removeButton(button); + }); +}()); \ No newline at end of file