From 9ec14057f01a67f98fa9bb27bdef3dcddec8d9b3 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sat, 29 Jul 2017 21:51:19 +0300 Subject: [PATCH 01/15] Opened up setForceFaceTrackerConnected --- libraries/avatars/src/AvatarData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 16768ec62a..c41b53cb45 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -547,7 +547,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; } From 4e81ebf85cafce1d7deebac1311dc110bbe4d404 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Thu, 10 Aug 2017 22:53:35 +0100 Subject: [PATCH 02/15] Added Assets for Web Browser MP Script --- .../qml/controls-uit/WebGlyphButton.qml | 48 ++++ interface/resources/qml/hifi/WebBrowser.qml | 253 ++++++++++++++++++ 2 files changed, 301 insertions(+) create mode 100644 interface/resources/qml/controls-uit/WebGlyphButton.qml create mode 100644 interface/resources/qml/hifi/WebBrowser.qml 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/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 + } + } +} From 3bc185e67cefb7fb007442ae306f72c45cf39018 Mon Sep 17 00:00:00 2001 From: Anshuman Dewangan Date: Fri, 11 Aug 2017 15:37:55 -0700 Subject: [PATCH 03/15] Correct desktop icon name --- cmake/macros/SetPackagingParameters.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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") From 9120e678f1b26c5fda9038d55c54dd5046aba19e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 11 Aug 2017 16:17:13 -0700 Subject: [PATCH 04/15] Use asynchronous commerce API --- .../resources/qml/hifi/commerce/Checkout.qml | 65 +++++++++---------- .../resources/qml/hifi/commerce/Inventory.qml | 18 ++++- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml index a0a5af88ab..458e417654 100644 --- a/interface/resources/qml/hifi/commerce/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/Checkout.qml @@ -24,40 +24,43 @@ 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 string itemId: ""; + property string itemHref: ""; + property int hfcBalance: 0; + property int balanceAfterPurchase: 0; + property bool alreadyOwned: false; // Style color: hifi.colors.baseGray; Hifi.QmlCommerce { id: commerce; onBuyResult: { - /* - if (buyFailed) { + if (failureMessage.length) { 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 (urlHandler.canHandleUrl(itemHref)) { + urlHandler.handleUrl(itemHref); } } - */ - - if (failureMessage.length) { - console.log('buy failed', failureMessage); - //fixme sendToScript({method: 'checkout_cancelClicked', params: itemId}); - } else { - console.log('buy ok'); - //fixme sendToScript({method: 'checkout_buyClicked', success: , itemId: itemId, itemHref: itemHref}); - } } - // 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 { + hfcBalance = balance; + balanceAfterPurchase = hfcBalance - parseInt(itemPriceText.text, 10); + } + } + onInventoryResult: { + if (failureMessage.length) { + console.log("Failed to get inventory", failureMessage); + } else { + if (inventory.indexOf(itemId) !== -1) { + alreadyOwned = true; + } else { + alreadyOwned = false; + } + } + } } // @@ -229,7 +232,7 @@ Rectangle { } RalewayRegular { id: hfcBalanceText; - text: commerce.balance(); + text: hfcBalance; // Text size size: hfcBalanceTextLabel.size; // Anchors @@ -397,16 +400,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() // @@ -429,6 +422,8 @@ Rectangle { itemPriceText.text = message.params.itemPrice; itemHref = message.params.itemHref; buyButton.buyFailed = false; + commerce.balance(); + commerce.inventory(); break; case 'buyFailed': buyButton.text = "Buy Failed"; diff --git a/interface/resources/qml/hifi/commerce/Inventory.qml b/interface/resources/qml/hifi/commerce/Inventory.qml index 91fa3b9126..7ed43e6f9e 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; + } + } } // @@ -101,7 +115,6 @@ Rectangle { } RalewayRegular { id: hfcBalanceText; - text: commerce.balance(); // Text size size: hfcBalanceTextLabel.size; // Anchors @@ -158,7 +171,6 @@ Rectangle { anchors.left: parent.left; anchors.bottom: parent.bottom; width: parent.width; - model: commerce.inventory(); delegate: Item { width: parent.width; height: 30; @@ -247,6 +259,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)); From c38837c20021bfc5e758f040be8a563a3483545f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 11 Aug 2017 16:21:39 -0700 Subject: [PATCH 05/15] Remove fixmes --- interface/resources/qml/hifi/commerce/Checkout.qml | 12 ++++-------- scripts/system/marketplaces/marketplaces.js | 8 ++------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml index 458e417654..cfa8f82fd9 100644 --- a/interface/resources/qml/hifi/commerce/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/Checkout.qml @@ -35,11 +35,13 @@ Rectangle { id: commerce; onBuyResult: { if (failureMessage.length) { - sendToScript({method: 'checkout_cancelClicked', params: itemId}); + buyButton.text = "Buy Failed"; + buyButton.enabled = false; } else { if (urlHandler.canHandleUrl(itemHref)) { urlHandler.handleUrl(itemHref); } + sendToScript({method: 'checkout_buySuccess', params: itemId}); } } onBalanceResult: { @@ -369,13 +371,12 @@ 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; color: hifi.buttons.black; @@ -421,14 +422,9 @@ Rectangle { itemAuthorText.text = message.params.itemAuthor; itemPriceText.text = message.params.itemPrice; itemHref = message.params.itemHref; - buyButton.buyFailed = false; commerce.balance(); commerce.inventory(); break; - case 'buyFailed': - buyButton.text = "Buy Failed"; - buyButton.buyFailed = true; - break; default: console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message)); } 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': From d8e5f7a067155e5d2c9c8f468b3426e0605bee9a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 11 Aug 2017 16:28:08 -0700 Subject: [PATCH 06/15] Small improvements --- .../resources/qml/hifi/commerce/Checkout.qml | 15 +++++++++------ .../resources/qml/hifi/commerce/Inventory.qml | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml index cfa8f82fd9..e40e2ce67f 100644 --- a/interface/resources/qml/hifi/commerce/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/Checkout.qml @@ -24,9 +24,10 @@ Rectangle { HifiConstants { id: hifi; } id: checkoutRoot; + property bool inventoryReceived: false; + property bool balanceReceived: false; property string itemId: ""; property string itemHref: ""; - property int hfcBalance: 0; property int balanceAfterPurchase: 0; property bool alreadyOwned: false; // Style @@ -48,14 +49,16 @@ Rectangle { if (failureMessage.length) { console.log("Failed to get balance", failureMessage); } else { - hfcBalance = balance; - balanceAfterPurchase = hfcBalance - parseInt(itemPriceText.text, 10); + 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 (inventory.indexOf(itemId) !== -1) { alreadyOwned = true; } else { @@ -234,7 +237,7 @@ Rectangle { } RalewayRegular { id: hfcBalanceText; - text: hfcBalance; + text: "--"; // Text size size: hfcBalanceTextLabel.size; // Anchors @@ -378,7 +381,7 @@ Rectangle { // "Buy" button HifiControlsUit.Button { id: buyButton; - enabled: balanceAfterPurchase >= 0 && !alreadyOwned; + enabled: balanceAfterPurchase >= 0 && !alreadyOwned && inventoryReceived && balanceReceived; color: hifi.buttons.black; colorScheme: hifi.colorSchemes.dark; anchors.top: parent.top; @@ -388,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)); } diff --git a/interface/resources/qml/hifi/commerce/Inventory.qml b/interface/resources/qml/hifi/commerce/Inventory.qml index 7ed43e6f9e..a562d00218 100644 --- a/interface/resources/qml/hifi/commerce/Inventory.qml +++ b/interface/resources/qml/hifi/commerce/Inventory.qml @@ -115,6 +115,7 @@ Rectangle { } RalewayRegular { id: hfcBalanceText; + text: "--"; // Text size size: hfcBalanceTextLabel.size; // Anchors From 0835b7b8e6be09ae59af39cbd0aa825e0d46d138 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 11 Aug 2017 16:36:26 -0700 Subject: [PATCH 07/15] Bugfix --- interface/resources/qml/hifi/commerce/Checkout.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml index e40e2ce67f..7c2d6b56a5 100644 --- a/interface/resources/qml/hifi/commerce/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/Checkout.qml @@ -42,7 +42,7 @@ Rectangle { if (urlHandler.canHandleUrl(itemHref)) { urlHandler.handleUrl(itemHref); } - sendToScript({method: 'checkout_buySuccess', params: itemId}); + sendToScript({method: 'checkout_buySuccess', itemId: itemId}); } } onBalanceResult: { From 8c9f3ae9775d15101b2b6f966f6a4195c651dc58 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Sat, 12 Aug 2017 01:35:48 +0100 Subject: [PATCH 08/15] Skybox Changer PR --- .../resources/qml/hifi/SkyboxChanger.qml | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 interface/resources/qml/hifi/SkyboxChanger.qml diff --git a/interface/resources/qml/hifi/SkyboxChanger.qml b/interface/resources/qml/hifi/SkyboxChanger.qml new file mode 100644 index 0000000000..9d7fc39157 --- /dev/null +++ b/interface/resources/qml/hifi/SkyboxChanger.qml @@ -0,0 +1,184 @@ +// +// 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 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: ""; + + 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: "You can set the current Skybox of the Zone you're standing in by clicking on any of the 6 pre-determined skyboxes below."; + wrapMode: Text.Wrap + // Text size + size: 14; + // Anchors + anchors.fill: parent; + anchors.topMargin: 56; + anchors.leftMargin: 16; + anchors.rightMargin: 16; + // Style + color: hifi.colors.lightGrayText; + // Alignment + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; + } + } + 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); + +} From 185c8da491bb790be50af33aba73d388b9587264 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Sat, 12 Aug 2017 18:52:54 +0100 Subject: [PATCH 09/15] Changed 6 to six, cause wording. No functionality changes. --- interface/resources/qml/hifi/SkyboxChanger.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/SkyboxChanger.qml b/interface/resources/qml/hifi/SkyboxChanger.qml index 9d7fc39157..a677af2f07 100644 --- a/interface/resources/qml/hifi/SkyboxChanger.qml +++ b/interface/resources/qml/hifi/SkyboxChanger.qml @@ -56,7 +56,7 @@ Rectangle { } RalewaySemiBold { id: titleBarDesc; - text: "You can set the current Skybox of the Zone you're standing in by clicking on any of the 6 pre-determined skyboxes below."; + text: "You can set the current Skybox of the Zone you're standing in by clicking on any of the six pre-determined skyboxes below."; wrapMode: Text.Wrap // Text size size: 14; From 28c81534c4ff18d8a832fb7ae6cb34147873c7cb Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Mon, 14 Aug 2017 05:11:53 +0100 Subject: [PATCH 10/15] Updated Text at Top --- interface/resources/qml/hifi/SkyboxChanger.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/SkyboxChanger.qml b/interface/resources/qml/hifi/SkyboxChanger.qml index 9d7fc39157..6291a1c103 100644 --- a/interface/resources/qml/hifi/SkyboxChanger.qml +++ b/interface/resources/qml/hifi/SkyboxChanger.qml @@ -56,7 +56,7 @@ Rectangle { } RalewaySemiBold { id: titleBarDesc; - text: "You can set the current Skybox of the Zone you're standing in by clicking on any of the 6 pre-determined skyboxes below."; + text: "Click an image to choose a new Skybox."; wrapMode: Text.Wrap // Text size size: 14; From 199ba3bff0312f874733709e0e44f2a5e26c3902 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 14 Aug 2017 11:55:21 -0700 Subject: [PATCH 11/15] Use new JSON inventory format --- interface/resources/qml/hifi/commerce/Checkout.qml | 11 ++++++++++- interface/resources/qml/hifi/commerce/Inventory.qml | 6 +++--- interface/src/commerce/Ledger.cpp | 13 ++++++++++--- interface/src/commerce/Ledger.h | 6 ++++-- interface/src/commerce/QmlCommerce.h | 2 +- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml index 7c2d6b56a5..865bb72921 100644 --- a/interface/resources/qml/hifi/commerce/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/Checkout.qml @@ -59,7 +59,7 @@ Rectangle { console.log("Failed to get inventory", failureMessage); } else { inventoryReceived = true; - if (inventory.indexOf(itemId) !== -1) { + if (inventoryContains(inventory.assets, itemId)) { alreadyOwned = true; } else { alreadyOwned = false; @@ -434,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 a562d00218..298abebdab 100644 --- a/interface/resources/qml/hifi/commerce/Inventory.qml +++ b/interface/resources/qml/hifi/commerce/Inventory.qml @@ -40,7 +40,7 @@ Rectangle { if (failureMessage.length) { console.log("Failed to get inventory", failureMessage); } else { - inventoryContentsList.model = inventory; + inventoryContentsList.model = inventory.assets; } } } @@ -181,7 +181,7 @@ Rectangle { size: 20; // Style color: hifi.colors.blueAccent; - text: modelData; + text: modelData.title; // Alignment horizontalAlignment: Text.AlignHLeft; } @@ -189,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; 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 = ""); From c1d771842d5b198e96b324508b761bc1fd1d71df Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 14 Aug 2017 13:37:50 -0700 Subject: [PATCH 12/15] Remove context overlay (if present) when removing entity --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 8 ++++++++ interface/src/ui/overlays/ContextOverlayInterface.h | 1 + 2 files changed, 9 insertions(+) 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 From e7a4bff705a8764ab72bbc4edb37a009a664ee4c Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Mon, 14 Aug 2017 22:47:18 +0100 Subject: [PATCH 13/15] Made Changes per Review, added js --- .../resources/qml/hifi/SkyboxChanger.qml | 21 +--- .../skyboxChanger/skyboxchanger.js | 118 ++++++++++++++++++ 2 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 unpublishedScripts/marketplace/skyboxChanger/skyboxchanger.js diff --git a/interface/resources/qml/hifi/SkyboxChanger.qml b/interface/resources/qml/hifi/SkyboxChanger.qml index 6291a1c103..a4798ba959 100644 --- a/interface/resources/qml/hifi/SkyboxChanger.qml +++ b/interface/resources/qml/hifi/SkyboxChanger.qml @@ -9,26 +9,11 @@ // 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: ""; - color: hifi.colors.baseGray; Item { @@ -62,7 +47,7 @@ Rectangle { size: 14; // Anchors anchors.fill: parent; - anchors.topMargin: 56; + anchors.top: titleBarText.bottom anchors.leftMargin: 16; anchors.rightMargin: 16; // Style @@ -72,6 +57,10 @@ Rectangle { 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 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 From 99617600c47c7e8eb613ae1f28bc73cf1a1b9f63 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 14 Aug 2017 15:58:28 -0700 Subject: [PATCH 14/15] fix selection issue for TreeView.qml --- interface/resources/qml/controls-uit/Tree.qml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/resources/qml/controls-uit/Tree.qml b/interface/resources/qml/controls-uit/Tree.qml index 8bce092947..6c9533a40c 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) { From 459f2c5cdcaf9240573df5b0732f3e62ae6451c4 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 14 Aug 2017 16:03:12 -0700 Subject: [PATCH 15/15] fixed tab issue --- interface/resources/qml/controls-uit/Tree.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/controls-uit/Tree.qml b/interface/resources/qml/controls-uit/Tree.qml index 6c9533a40c..53f66fa67c 100644 --- a/interface/resources/qml/controls-uit/Tree.qml +++ b/interface/resources/qml/controls-uit/Tree.qml @@ -27,7 +27,7 @@ TreeView { model: treeModel selection: ItemSelectionModel { - id: selectionModel + id: selectionModel model: treeModel } @@ -217,7 +217,7 @@ TreeView { onDoubleClicked: isExpanded(index) ? collapse(index) : expand(index) onClicked: { - selectionModel.setCurrentIndex(index, ItemSelectionModel.ClearAndSelect); + selectionModel.setCurrentIndex(index, ItemSelectionModel.ClearAndSelect); } onActivated: {