Merge branch 'master' into feature/ant-man
|
@ -28,19 +28,31 @@ Rectangle {
|
|||
property string activeView: "initialize";
|
||||
property bool purchasesReceived: false;
|
||||
property bool balanceReceived: false;
|
||||
property bool securityImageResultReceived: false;
|
||||
property bool keyFilePathIfExistsResultReceived: false;
|
||||
property string itemId: "";
|
||||
property string itemHref: "";
|
||||
property double balanceAfterPurchase: 0;
|
||||
property bool alreadyOwned: false;
|
||||
property int itemPriceFull: 0;
|
||||
property bool itemIsJson: true;
|
||||
property bool securityImageResultReceived: false;
|
||||
property bool keyFilePathIfExistsResultReceived: false;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
commerce.balance();
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
|
@ -107,6 +119,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: titleBarContainer;
|
||||
visible: !needsLogIn.visible;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
|
@ -147,6 +160,16 @@ Rectangle {
|
|||
cache: false;
|
||||
source: "image://security/securityImage";
|
||||
}
|
||||
Image {
|
||||
id: securityImageOverlay;
|
||||
source: "../wallet/images/lockOverlay.png";
|
||||
width: securityImage.width * 0.45;
|
||||
height: securityImage.height * 0.45;
|
||||
anchors.bottom: securityImage.bottom;
|
||||
anchors.right: securityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
// Separator
|
||||
HifiControlsUit.Separator {
|
||||
|
@ -169,10 +192,36 @@ Rectangle {
|
|||
color: hifi.colors.baseGray;
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
securityImageResultReceived = false;
|
||||
purchasesReceived = false;
|
||||
balanceReceived = false;
|
||||
keyFilePathIfExistsResultReceived = false;
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
HifiWallet.NeedsLogIn {
|
||||
id: needsLogIn;
|
||||
visible: root.activeView === "needsLogIn";
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: GlobalServices
|
||||
onMyUsernameChanged: {
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// "WALLET NOT SET UP" START
|
||||
|
@ -268,13 +317,6 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.balance();
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ITEM DESCRIPTION START
|
||||
//
|
||||
|
@ -877,7 +919,7 @@ Rectangle {
|
|||
if (root.purchasesReceived && root.balanceReceived) {
|
||||
if (root.balanceAfterPurchase < 0) {
|
||||
if (root.alreadyOwned) {
|
||||
buyText.text = "You do not have enough HFC to purchase this item again. Go to your Purchases to view the copy you own.";
|
||||
buyText.text = "You do not have enough HFC to purchase this item again. Go to your <b>Purchases</b> to view the copy you own.";
|
||||
} else {
|
||||
buyText.text = "You do not have enough HFC to purchase this item.";
|
||||
}
|
||||
|
|
|
@ -29,12 +29,24 @@ Rectangle {
|
|||
property string referrerURL: "";
|
||||
property bool securityImageResultReceived: false;
|
||||
property bool keyFilePathIfExistsResultReceived: false;
|
||||
property bool purchasesReceived: false;
|
||||
property bool punctuationMode: false;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
|
@ -58,10 +70,13 @@ Rectangle {
|
|||
}
|
||||
|
||||
onInventoryResult: {
|
||||
purchasesReceived = true;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +91,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: titleBarContainer;
|
||||
visible: !needsLogIn.visible;
|
||||
// Size
|
||||
height: 50;
|
||||
// Anchors
|
||||
|
@ -116,6 +132,16 @@ Rectangle {
|
|||
cache: false;
|
||||
source: "image://security/securityImage";
|
||||
}
|
||||
Image {
|
||||
id: securityImageOverlay;
|
||||
source: "../wallet/images/lockOverlay.png";
|
||||
width: securityImage.width * 0.45;
|
||||
height: securityImage.height * 0.45;
|
||||
anchors.bottom: securityImage.bottom;
|
||||
anchors.right: securityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
// Separator
|
||||
HifiControlsUit.Separator {
|
||||
|
@ -138,8 +164,31 @@ Rectangle {
|
|||
color: hifi.colors.baseGray;
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
securityImageResultReceived = false;
|
||||
purchasesReceived = false;
|
||||
keyFilePathIfExistsResultReceived = false;
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
HifiWallet.NeedsLogIn {
|
||||
id: needsLogIn;
|
||||
visible: root.activeView === "needsLogIn";
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: GlobalServices
|
||||
onMyUsernameChanged: {
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,14 +289,7 @@ Rectangle {
|
|||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: actionButtonsContainer.top;
|
||||
anchors.bottomMargin: 8;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.balance();
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
anchors.bottomMargin: 8;
|
||||
|
||||
//
|
||||
// FILTER BAR START
|
||||
|
@ -258,7 +300,9 @@ Rectangle {
|
|||
height: 40;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
|
||||
|
@ -304,6 +348,7 @@ Rectangle {
|
|||
|
||||
ListView {
|
||||
id: purchasesContentsList;
|
||||
visible: purchasesModel.count !== 0;
|
||||
clip: true;
|
||||
model: filteredPurchasesModel;
|
||||
// Anchors
|
||||
|
@ -329,6 +374,52 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noPurchasesAlertContainer;
|
||||
visible: !purchasesContentsList.visible && root.purchasesReceived;
|
||||
anchors.top: filterBarContainer.bottom;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width;
|
||||
|
||||
// Explanitory text
|
||||
RalewayRegular {
|
||||
id: haventPurchasedYet;
|
||||
text: "<b>You haven't purchased anything yet!</b><br><br>Get an item from <b>Marketplace</b> to add it to your <b>Purchases</b>.";
|
||||
// Text size
|
||||
size: 22;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 150;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 24;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 24;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
// "Set Up" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: haventPurchasedYet.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
width: parent.width * 2 / 3;
|
||||
height: 50;
|
||||
text: "Visit Marketplace";
|
||||
onClicked: {
|
||||
sendToScript({method: 'purchases_goToMarketplaceClicked'});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// PURCHASES CONTENTS END
|
||||
|
|
|
@ -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
|
||||
|
|
188
interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml
Normal file
|
@ -0,0 +1,188 @@
|
|||
//
|
||||
// NeedsLogIn.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// NeedsLogIn
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-18
|
||||
// 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 Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
}
|
||||
|
||||
//
|
||||
// LOGIN PAGE START
|
||||
//
|
||||
Item {
|
||||
id: loginPageContainer;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
||||
Item {
|
||||
id: loginTitle;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
text: "HIFI COMMERCE - LOGIN";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
RalewaySemiBold {
|
||||
id: loginTitleHelper;
|
||||
text: "Please Log In to High Fidelity";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: loginTitle.bottom;
|
||||
anchors.topMargin: 100;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Text below helper text
|
||||
RalewayRegular {
|
||||
id: loginDetailText;
|
||||
text: "To buy/sell items on the <b>Marketplace</b>, or to use your <b>Wallet</b>, you must first log in to High Fidelity.";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: loginTitleHelper.bottom;
|
||||
anchors.topMargin: 25;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item {
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 70;
|
||||
// Anchors
|
||||
anchors.top: loginDetailText.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: parent.left;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
id: cancelButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendToScript({method: 'needsLogIn_cancelClicked'});
|
||||
}
|
||||
}
|
||||
|
||||
// "Set Up" button
|
||||
HifiControlsUit.Button {
|
||||
id: setUpButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
text: "Log In"
|
||||
onClicked: {
|
||||
sendToScript({method: 'needsLogIn_loginClicked'});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// LOGIN PAGE END
|
||||
//
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
// Relevant Variables:
|
||||
// None
|
||||
//
|
||||
// Arguments:
|
||||
// message: The message sent from the JavaScript.
|
||||
// Messages are in format "{method, params}", like json-rpc.
|
||||
//
|
||||
// Description:
|
||||
// Called when a message is received from a script.
|
||||
//
|
||||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
default:
|
||||
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
signal sendSignalToWallet(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
|
@ -80,7 +80,7 @@ Item {
|
|||
|
||||
// "Set Up" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 150;
|
||||
|
|
|
@ -45,9 +45,16 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// This will cause a bug -- if you bring up passphrase selection in HUD mode while
|
||||
// in HMD while having HMD preview enabled, then move, then finish passphrase selection,
|
||||
// HMD preview will stay off.
|
||||
// TODO: Fix this unlikely bug
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
passphraseField.focus = true;
|
||||
sendMessageToLightbox({method: 'disableHmdPreview'});
|
||||
} else {
|
||||
sendMessageToLightbox({method: 'maybeEnableHmdPreview'});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,11 +73,25 @@ Item {
|
|||
echoMode: TextInput.Password;
|
||||
placeholderText: "passphrase";
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
text = "";
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'});
|
||||
} else if (!passphraseFieldAgain.focus) {
|
||||
sendMessageToLightbox({method: 'walletSetup_lowerKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
passphraseFieldAgain.focus = true;
|
||||
}
|
||||
}
|
||||
HifiControlsUit.TextField {
|
||||
id: passphraseFieldAgain;
|
||||
|
@ -82,11 +103,25 @@ Item {
|
|||
echoMode: TextInput.Password;
|
||||
placeholderText: "re-enter passphrase";
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
text = "";
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'});
|
||||
} else if (!passphraseField.focus) {
|
||||
sendMessageToLightbox({method: 'walletSetup_lowerKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
focus = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Security Image
|
||||
|
@ -111,9 +146,19 @@ Item {
|
|||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
// "Security picture" text below pic
|
||||
Image {
|
||||
id: topSecurityImageOverlay;
|
||||
source: "images/lockOverlay.png";
|
||||
width: passphrasePageSecurityImage.width * 0.45;
|
||||
height: passphrasePageSecurityImage.height * 0.45;
|
||||
anchors.bottom: passphrasePageSecurityImage.bottom;
|
||||
anchors.right: passphrasePageSecurityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
text: "security picture";
|
||||
text: "security image";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
|
@ -228,5 +273,11 @@ Item {
|
|||
errorText.text = text;
|
||||
}
|
||||
|
||||
function clearPassphraseFields() {
|
||||
passphraseField.text = "";
|
||||
passphraseFieldAgain.text = "";
|
||||
setErrorText("");
|
||||
}
|
||||
|
||||
signal sendMessageToLightbox(var msg);
|
||||
}
|
||||
|
|
|
@ -27,29 +27,6 @@ Rectangle {
|
|||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
root.resetSubmitButton();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: passphraseSelection;
|
||||
onSendMessageToLightbox: {
|
||||
if (msg.method === 'statusResult') {
|
||||
if (msg.status) {
|
||||
// Success submitting new passphrase
|
||||
root.resetSubmitButton();
|
||||
root.visible = false;
|
||||
} else {
|
||||
// Error submitting new passphrase
|
||||
root.resetSubmitButton();
|
||||
passphraseSelection.setErrorText("Backend error");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SECURE PASSPHRASE SELECTION START
|
||||
//
|
||||
|
@ -113,6 +90,24 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: passphraseNavBar.top;
|
||||
|
||||
Connections {
|
||||
onSendMessageToLightbox: {
|
||||
if (msg.method === 'statusResult') {
|
||||
if (msg.status) {
|
||||
// Success submitting new passphrase
|
||||
root.resetSubmitButton();
|
||||
root.visible = false;
|
||||
} else {
|
||||
// Error submitting new passphrase
|
||||
root.resetSubmitButton();
|
||||
passphraseSelection.setErrorText("Backend error");
|
||||
}
|
||||
} else {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
|
@ -168,8 +163,14 @@ Rectangle {
|
|||
// SECURE PASSPHRASE SELECTION END
|
||||
//
|
||||
|
||||
signal sendSignalToWallet(var msg);
|
||||
|
||||
function resetSubmitButton() {
|
||||
passphraseSubmitButton.enabled = true;
|
||||
passphraseSubmitButton.text = "Submit";
|
||||
}
|
||||
|
||||
function clearPassphraseFields() {
|
||||
passphraseSelection.clearPassphraseFields();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
|
@ -35,8 +36,6 @@ Item {
|
|||
topSecurityImage.source = path;
|
||||
changeSecurityImageImage.source = "";
|
||||
changeSecurityImageImage.source = path;
|
||||
changePassphraseImage.source = "";
|
||||
changePassphraseImage.source = path;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,9 +91,19 @@ Item {
|
|||
source: "image://security/securityImage";
|
||||
cache: false;
|
||||
}
|
||||
// "Security picture" text below pic
|
||||
Image {
|
||||
id: topSecurityImageMask;
|
||||
source: "images/lockOverlay.png";
|
||||
width: topSecurityImage.width * 0.45;
|
||||
height: topSecurityImage.height * 0.45;
|
||||
anchors.bottom: topSecurityImage.bottom;
|
||||
anchors.right: topSecurityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
text: "security picture";
|
||||
text: "security image";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
|
@ -148,10 +157,16 @@ Item {
|
|||
anchors.left: parent.left;
|
||||
height: parent.height;
|
||||
width: height;
|
||||
source: "image://security/securityImage";
|
||||
source: "images/lockOverlay.png";
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
visible: false;
|
||||
}
|
||||
ColorOverlay {
|
||||
anchors.fill: changePassphraseImage;
|
||||
source: changePassphraseImage;
|
||||
color: "white"
|
||||
}
|
||||
// "Change Passphrase" button
|
||||
HifiControlsUit.Button {
|
||||
|
|
|
@ -16,27 +16,27 @@ import QtQuick 2.5
|
|||
ListModel {
|
||||
id: root;
|
||||
ListElement{
|
||||
sourcePath: "images/01cat.jpg"
|
||||
sourcePath: "images/01.jpg"
|
||||
securityImageEnumValue: 1;
|
||||
}
|
||||
ListElement{
|
||||
sourcePath: "images/02car.jpg"
|
||||
sourcePath: "images/02.jpg"
|
||||
securityImageEnumValue: 2;
|
||||
}
|
||||
ListElement{
|
||||
sourcePath: "images/03dog.jpg"
|
||||
sourcePath: "images/03.jpg"
|
||||
securityImageEnumValue: 3;
|
||||
}
|
||||
ListElement{
|
||||
sourcePath: "images/04stars.jpg"
|
||||
sourcePath: "images/04.jpg"
|
||||
securityImageEnumValue: 4;
|
||||
}
|
||||
ListElement{
|
||||
sourcePath: "images/05plane.jpg"
|
||||
sourcePath: "images/05.jpg"
|
||||
securityImageEnumValue: 5;
|
||||
}
|
||||
ListElement{
|
||||
sourcePath: "images/06gingerbread.jpg"
|
||||
sourcePath: "images/06.jpg"
|
||||
securityImageEnumValue: 6;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,16 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
onSecurityImageResult: {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This will cause a bug -- if you bring up security image selection in HUD mode while
|
||||
// in HMD while having HMD preview enabled, then move, then finish passphrase selection,
|
||||
// HMD preview will stay off.
|
||||
// TODO: Fix this unlikely bug
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getSecurityImage();
|
||||
sendSignalToWallet({method: 'disableHmdPreview'});
|
||||
} else {
|
||||
sendSignalToWallet({method: 'maybeEnableHmdPreview'});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ Item {
|
|||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
signal sendToScript(var message);
|
||||
signal sendSignalToWallet(var msg);
|
||||
|
||||
function getImagePathFromImageID(imageID) {
|
||||
return (imageID ? gridModel.getImagePathFromImageID(imageID) : "");
|
||||
|
|
|
@ -28,12 +28,6 @@ Rectangle {
|
|||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
root.resetSubmitButton();
|
||||
}
|
||||
}
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
|
@ -116,6 +110,12 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 280;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text below security images
|
||||
|
@ -193,6 +193,8 @@ Rectangle {
|
|||
// SECURITY IMAGE SELECTION END
|
||||
//
|
||||
|
||||
signal sendSignalToWallet(var msg);
|
||||
|
||||
function resetSubmitButton() {
|
||||
securityImageSubmitButton.enabled = true;
|
||||
securityImageSubmitButton.text = "Submit";
|
||||
|
|
|
@ -28,12 +28,23 @@ Rectangle {
|
|||
property string activeView: "initialize";
|
||||
property bool securityImageResultReceived: false;
|
||||
property bool keyFilePathIfExistsResultReceived: false;
|
||||
property bool keyboardRaised: false;
|
||||
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
|
@ -57,27 +68,6 @@ Rectangle {
|
|||
id: securityImageModel;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: walletSetupLightbox;
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_cancelClicked') {
|
||||
walletSetupLightbox.visible = false;
|
||||
} else if (msg.method === 'walletSetup_finished') {
|
||||
root.activeView = "walletHome";
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: notSetUp;
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'setUpClicked') {
|
||||
walletSetupLightbox.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: walletSetupLightboxContainer;
|
||||
visible: walletSetupLightbox.visible || passphraseSelectionLightbox.visible || securityImageSelectionLightbox.visible;
|
||||
|
@ -89,26 +79,60 @@ Rectangle {
|
|||
WalletSetupLightbox {
|
||||
id: walletSetupLightbox;
|
||||
visible: false;
|
||||
z: 999;
|
||||
z: 998;
|
||||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_cancelClicked') {
|
||||
walletSetupLightbox.visible = false;
|
||||
} else if (msg.method === 'walletSetup_finished') {
|
||||
root.activeView = "walletHome";
|
||||
} else if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
} else if (msg.method === 'walletSetup_lowerKeyboard') {
|
||||
root.keyboardRaised = false;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PassphraseSelectionLightbox {
|
||||
id: passphraseSelectionLightbox;
|
||||
visible: false;
|
||||
z: 999;
|
||||
z: 998;
|
||||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
} else if (msg.method === 'walletSetup_lowerKeyboard') {
|
||||
root.keyboardRaised = false;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SecurityImageSelectionLightbox {
|
||||
id: securityImageSelectionLightbox;
|
||||
visible: false;
|
||||
z: 999;
|
||||
z: 998;
|
||||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,6 +141,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: titleBarContainer;
|
||||
visible: !needsLogIn.visible;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
|
@ -168,8 +193,28 @@ Rectangle {
|
|||
color: hifi.colors.baseGray;
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
NeedsLogIn {
|
||||
id: needsLogIn;
|
||||
visible: root.activeView === "needsLogIn";
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: GlobalServices
|
||||
onMyUsernameChanged: {
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +225,14 @@ Rectangle {
|
|||
anchors.bottom: tabButtonsContainer.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'setUpClicked') {
|
||||
walletSetupLightbox.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WalletHome {
|
||||
|
@ -219,14 +272,15 @@ Rectangle {
|
|||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
}
|
||||
Connections {
|
||||
target: security;
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSecurity_changePassphrase') {
|
||||
passphraseSelectionLightbox.visible = true;
|
||||
} else if (msg.method === 'walletSecurity_changeSecurityImage') {
|
||||
securityImageSelectionLightbox.visible = true;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSecurity_changePassphrase') {
|
||||
passphraseSelectionLightbox.visible = true;
|
||||
passphraseSelectionLightbox.clearPassphraseFields();
|
||||
} else if (msg.method === 'walletSecurity_changeSecurityImage') {
|
||||
securityImageSelectionLightbox.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +296,14 @@ Rectangle {
|
|||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletReset') {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -254,6 +316,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: tabButtonsContainer;
|
||||
visible: !needsLogIn.visible;
|
||||
property int numTabs: 5;
|
||||
// Size
|
||||
width: root.width;
|
||||
|
@ -457,6 +520,46 @@ Rectangle {
|
|||
// TAB BUTTONS END
|
||||
//
|
||||
|
||||
Item {
|
||||
id: keyboardContainer;
|
||||
z: 999;
|
||||
visible: keyboard.raised;
|
||||
property bool punctuationMode: false;
|
||||
anchors {
|
||||
bottom: parent.bottom;
|
||||
left: parent.left;
|
||||
right: parent.right;
|
||||
}
|
||||
|
||||
Image {
|
||||
id: lowerKeyboardButton;
|
||||
source: "images/lowerKeyboard.png";
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.bottom: keyboard.top;
|
||||
height: 30;
|
||||
width: 120;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
||||
onClicked: {
|
||||
root.keyboardRaised = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Keyboard {
|
||||
id: keyboard;
|
||||
raised: HMD.mounted && root.keyboardRaised;
|
||||
numeric: parent.punctuationMode;
|
||||
anchors {
|
||||
bottom: parent.bottom;
|
||||
left: parent.left;
|
||||
right: parent.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
|
|
@ -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("<hr>");
|
||||
transactionHistoryText.text = txt;
|
||||
transactionHistoryModel.clear();
|
||||
transactionHistoryModel.append(result.data.history);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +113,7 @@ Item {
|
|||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
historyReceived = false;
|
||||
commerce.balance();
|
||||
commerce.history();
|
||||
}
|
||||
|
@ -182,9 +185,19 @@ Item {
|
|||
cache: false;
|
||||
source: "image://security/securityImage";
|
||||
}
|
||||
// "Security picture" text below pic
|
||||
Image {
|
||||
id: securityImageOverlay;
|
||||
source: "images/lockOverlay.png";
|
||||
width: securityImage.width * 0.45;
|
||||
height: securityImage.height * 0.45;
|
||||
anchors.bottom: securityImage.bottom;
|
||||
anchors.right: securityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
text: "security picture";
|
||||
text: "security image";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
|
@ -208,8 +221,7 @@ Item {
|
|||
anchors.topMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: homeMessage.visible ? homeMessage.top : root.bottom;
|
||||
anchors.bottomMargin: 10;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
RalewayRegular {
|
||||
id: recentActivityText;
|
||||
|
@ -224,111 +236,66 @@ Item {
|
|||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: transactionHistoryModel;
|
||||
}
|
||||
Rectangle {
|
||||
id: transactionHistory;
|
||||
anchors.top: recentActivityText.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: toggleFullHistoryButton.top;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
// some placeholder stuff
|
||||
TextArea {
|
||||
id: transactionHistoryText;
|
||||
text: "<hr>history unavailable<hr>";
|
||||
textFormat: TextEdit.AutoText;
|
||||
font.pointSize: 10;
|
||||
anchors.fill: parent;
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: toggleFullHistoryButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
width: 250;
|
||||
height: 40;
|
||||
text: homeMessage.visible ? "See Full Transaction History" : "Collapse Transaction History";
|
||||
onClicked: {
|
||||
if (homeMessage.visible) {
|
||||
homeMessage.visible = false;
|
||||
} else {
|
||||
homeMessage.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Item for "messages" - like "Welcome"
|
||||
Item {
|
||||
id: homeMessage;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
height: childrenRect.height;
|
||||
|
||||
RalewayRegular {
|
||||
id: messageText;
|
||||
text: "<b>Welcome! Let's get you some spending money.</b><br><br>" +
|
||||
"Now that your account is all set up, click the button below to request your starter money. " +
|
||||
"A robot will promptly review your request and put money into your account.";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 130;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
color: "white";
|
||||
|
||||
Item {
|
||||
id: homeMessageButtons;
|
||||
anchors.top: messageText.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 40;
|
||||
HifiControlsUit.Button {
|
||||
id: noThanksButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
width: 100;
|
||||
text: "No Thanks"
|
||||
onClicked: {
|
||||
messageText.text = "Okay...weird. Who doesn't like free money? If you change your mind, too bad. Sorry."
|
||||
homeMessageButtons.visible = false;
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: freeMoneyButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
width: 210;
|
||||
text: "Free Money Please"
|
||||
onClicked: {
|
||||
messageText.text = "Go, MoneyRobots, Go!"
|
||||
homeMessageButtons.visible = false;
|
||||
}
|
||||
|
||||
// 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.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,21 +24,13 @@ Rectangle {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string lastPage: "login";
|
||||
property string lastPage: "initialize";
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (isLoggedIn) {
|
||||
securityImageContainer.visible = true;
|
||||
} else {
|
||||
loginPageContainer.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (!exists && root.lastPage === "securityImage") {
|
||||
// ERROR! Invalid security image.
|
||||
|
@ -61,151 +53,14 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LOGIN PAGE START
|
||||
//
|
||||
Item {
|
||||
id: loginPageContainer;
|
||||
visible: false;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
|
||||
Item {
|
||||
id: loginTitle;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
text: "WALLET SETUP - LOGIN";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
RalewaySemiBold {
|
||||
id: loginTitleHelper;
|
||||
text: "Please Log In to High Fidelity";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: loginTitle.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Text below helper text
|
||||
RalewaySemiBold {
|
||||
id: loginDetailText;
|
||||
text: "To set up your wallet, you must first log in to High Fidelity.";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: loginTitleHelper.bottom;
|
||||
anchors.topMargin: 25;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: loginDetailText.bottom;
|
||||
anchors.topMargin: 25;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
width: 150;
|
||||
height: 50;
|
||||
text: "Log In"
|
||||
onClicked: {
|
||||
sendSignalToWallet({method: 'walletSetup_loginClicked'});
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 100;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 100;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendSignalToWallet({method: 'walletSetup_cancelClicked'});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// LOGIN PAGE END
|
||||
//
|
||||
|
||||
//
|
||||
// SECURITY IMAGE SELECTION START
|
||||
//
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
visible: false;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: securityImageTitle;
|
||||
// Size
|
||||
|
@ -262,6 +117,12 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 280;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text below security images
|
||||
|
@ -329,6 +190,7 @@ Rectangle {
|
|||
commerce.chooseSecurityImage(securityImagePath);
|
||||
securityImageContainer.visible = false;
|
||||
choosePassphraseContainer.visible = true;
|
||||
passphraseSelection.clearPassphraseFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -407,6 +269,15 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: passphraseNavBar.top;
|
||||
|
||||
Connections {
|
||||
onSendMessageToLightbox: {
|
||||
if (msg.method === 'statusResult') {
|
||||
} else {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
|
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
BIN
interface/resources/qml/hifi/commerce/wallet/images/02.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
BIN
interface/resources/qml/hifi/commerce/wallet/images/04.jpg
Normal file
After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 86 KiB |
BIN
interface/resources/qml/hifi/commerce/wallet/images/05.jpg
Normal file
After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 721 B |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -183,7 +184,6 @@
|
|||
#include "ui/UpdateDialog.h"
|
||||
#include "ui/overlays/Overlays.h"
|
||||
#include "ui/DomainConnectionModel.h"
|
||||
#include "ui/ImageProvider.h"
|
||||
#include "Util.h"
|
||||
#include "InterfaceParentFinder.h"
|
||||
#include "ui/OctreeStatsProvider.h"
|
||||
|
@ -264,7 +264,7 @@ private:
|
|||
switch ((int)event->type()) {
|
||||
case ApplicationEvent::Render:
|
||||
render();
|
||||
// Ensure we never back up the render events. Each render should be triggered only in response
|
||||
// Ensure we never back up the render events. Each render should be triggered only in response
|
||||
// to the NEXT render event after the last render occured
|
||||
QCoreApplication::removePostedEvents(this, ApplicationEvent::Render);
|
||||
return true;
|
||||
|
@ -676,6 +676,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
|||
DependencyManager::set<Snapshot>();
|
||||
DependencyManager::set<CloseEventSender>();
|
||||
DependencyManager::set<ResourceManager>();
|
||||
DependencyManager::set<SelectionScriptingInterface>();
|
||||
DependencyManager::set<ContextOverlayInterface>();
|
||||
DependencyManager::set<Ledger>();
|
||||
DependencyManager::set<Wallet>();
|
||||
|
@ -2246,8 +2247,6 @@ void Application::initializeUi() {
|
|||
qApp->quit();
|
||||
});
|
||||
|
||||
// register the pixmap image provider (used only for security image, for now)
|
||||
engine->addImageProvider(ImageProvider::PROVIDER_NAME, new ImageProvider());
|
||||
|
||||
setupPreferences();
|
||||
|
||||
|
@ -2321,6 +2320,7 @@ void Application::initializeUi() {
|
|||
surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor());
|
||||
|
||||
surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
|
||||
surfaceContext->setContextProperty("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
|
||||
|
||||
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
||||
|
@ -5187,7 +5187,7 @@ void Application::update(float deltaTime) {
|
|||
}
|
||||
} else {
|
||||
// update the rendering without any simulation
|
||||
getEntities()->update(false);
|
||||
getEntities()->update(false);
|
||||
}
|
||||
|
||||
// AvatarManager update
|
||||
|
@ -5661,17 +5661,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<ContextOverlayInterface>();
|
||||
if (contextOverlayInterface->getEnabled()) {
|
||||
if (DependencyManager::get<ContextOverlayInterface>()->getIsInMarketplaceInspectionMode()) {
|
||||
renderOutlineFlags = RenderArgs::RENDER_OUTLINE_MARKETPLACE_MODE;
|
||||
} else {
|
||||
renderOutlineFlags = RenderArgs::RENDER_OUTLINE_WIREFRAMES;
|
||||
}
|
||||
}
|
||||
renderArgs->_outlineFlags = renderOutlineFlags;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6138,6 +6127,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
auto entityScriptServerLog = DependencyManager::get<EntityScriptServerLogClient>();
|
||||
scriptEngine->registerGlobalObject("EntityScriptServerLog", entityScriptServerLog.data());
|
||||
scriptEngine->registerGlobalObject("AvatarInputs", AvatarInputs::getInstance());
|
||||
scriptEngine->registerGlobalObject("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
||||
scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
|
||||
|
||||
qScriptRegisterMetaType(scriptEngine, OverlayIDtoScriptValue, OverlayIDfromScriptValue);
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -85,3 +85,10 @@ void QmlCommerce::getKeyFilePathIfExists() {
|
|||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->sendKeyFilePathIfExists();
|
||||
}
|
||||
|
||||
void QmlCommerce::reset() {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
ledger->reset();
|
||||
wallet->reset();
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Wallet.h"
|
||||
#include "Application.h"
|
||||
#include "ui/ImageProvider.h"
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <OffscreenUi.h>
|
||||
|
@ -224,6 +225,12 @@ void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArra
|
|||
memcpy(ckey, hash.data(), 32);
|
||||
}
|
||||
|
||||
Wallet::~Wallet() {
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
}
|
||||
}
|
||||
|
||||
void Wallet::setPassphrase(const QString& passphrase) {
|
||||
if (_passphrase) {
|
||||
delete _passphrase;
|
||||
|
@ -411,6 +418,13 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) {
|
|||
return QString();
|
||||
}
|
||||
|
||||
void Wallet::updateImageProvider() {
|
||||
// inform the image provider. Note it doesn't matter which one you inform, as the
|
||||
// images are statics
|
||||
auto engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
|
||||
auto imageProvider = reinterpret_cast<ImageProvider*>(engine->imageProvider(ImageProvider::PROVIDER_NAME));
|
||||
imageProvider->setSecurityImage(_securityImage);
|
||||
}
|
||||
|
||||
void Wallet::chooseSecurityImage(const QString& filename) {
|
||||
|
||||
|
@ -431,10 +445,7 @@ void Wallet::chooseSecurityImage(const QString& filename) {
|
|||
if (encryptFile(path, imageFilePath())) {
|
||||
qCDebug(commerce) << "emitting pixmap";
|
||||
|
||||
// inform the image provider
|
||||
auto engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
|
||||
auto imageProvider = reinterpret_cast<ImageProvider*>(engine->imageProvider(ImageProvider::PROVIDER_NAME));
|
||||
imageProvider->setSecurityImage(_securityImage);
|
||||
updateImageProvider();
|
||||
|
||||
emit securityImageResult(true);
|
||||
} else {
|
||||
|
@ -454,16 +465,15 @@ 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");
|
||||
qCDebug(commerce) << "created pixmap from encrypted file";
|
||||
|
||||
// inform the image provider
|
||||
auto engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
|
||||
auto imageProvider = reinterpret_cast<ImageProvider*>(engine->imageProvider(ImageProvider::PROVIDER_NAME));
|
||||
imageProvider->setSecurityImage(_securityImage);
|
||||
updateImageProvider();
|
||||
|
||||
delete[] data;
|
||||
emit securityImageResult(true);
|
||||
|
@ -481,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();
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ class Wallet : public QObject, public Dependency {
|
|||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
|
||||
~Wallet();
|
||||
// These are currently blocking calls, although they might take a moment.
|
||||
bool createIfNeeded();
|
||||
bool generateKeyPair();
|
||||
|
@ -38,27 +40,19 @@ public:
|
|||
void setPassphrase(const QString& passphrase);
|
||||
QString* getPassphrase() { return _passphrase; }
|
||||
|
||||
void reset();
|
||||
|
||||
signals:
|
||||
void securityImageResult(bool exists) ;
|
||||
void keyFilePathIfExistsResult(const QString& path);
|
||||
|
||||
protected:
|
||||
enum SecurityImage {
|
||||
NONE = 0,
|
||||
Cat,
|
||||
Car,
|
||||
Dog,
|
||||
Stars,
|
||||
Plane,
|
||||
Gingerbread
|
||||
};
|
||||
|
||||
private:
|
||||
QStringList _publicKeys{};
|
||||
QPixmap* _securityImage { nullptr };
|
||||
QByteArray _salt {"iamsalt!"};
|
||||
QString* _passphrase { new QString("pwd") };
|
||||
|
||||
void updateImageProvider();
|
||||
bool encryptFile(const QString& inputFilePath, const QString& outputFilePath);
|
||||
bool decryptFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
|
||||
};
|
||||
|
|
195
interface/src/scripting/SelectionScriptingInterface.cpp
Normal file
|
@ -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 <QDebug>
|
||||
#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 <class T> 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 <class T> 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<SelectionScriptingInterface>()->getList(_listName);
|
||||
render::Transaction transaction;
|
||||
render::ItemIDs finalList;
|
||||
render::ItemID currentID;
|
||||
auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||
auto& overlays = qApp->getOverlays();
|
||||
|
||||
for (QUuid& currentAvatarID : thisList.getAvatarIDs()) {
|
||||
auto avatar = std::static_pointer_cast<Avatar>(DependencyManager::get<AvatarManager>()->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";
|
||||
}
|
||||
}
|
91
interface/src/scripting/SelectionScriptingInterface.h
Normal file
|
@ -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 <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include <AbstractViewStateInterface.h>
|
||||
|
||||
#include "RenderableEntityItem.h"
|
||||
#include "ui/overlays/Overlay.h"
|
||||
#include <avatar/AvatarManager.h>
|
||||
|
||||
class GameplayObjects {
|
||||
public:
|
||||
GameplayObjects();
|
||||
|
||||
bool getContainsData() { return containsData; }
|
||||
|
||||
std::vector<QUuid> getAvatarIDs() { return _avatarIDs; }
|
||||
bool addToGameplayObjects(const QUuid& avatarID);
|
||||
bool removeFromGameplayObjects(const QUuid& avatarID);
|
||||
|
||||
std::vector<EntityItemID> getEntityIDs() { return _entityIDs; }
|
||||
bool addToGameplayObjects(const EntityItemID& entityID);
|
||||
bool removeFromGameplayObjects(const EntityItemID& entityID);
|
||||
|
||||
std::vector<OverlayID> getOverlayIDs() { return _overlayIDs; }
|
||||
bool addToGameplayObjects(const OverlayID& overlayID);
|
||||
bool removeFromGameplayObjects(const OverlayID& overlayID);
|
||||
|
||||
private:
|
||||
bool containsData { false };
|
||||
std::vector<QUuid> _avatarIDs;
|
||||
std::vector<EntityItemID> _entityIDs;
|
||||
std::vector<OverlayID> _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<QString, GameplayObjects> _selectedItemsListMap;
|
||||
|
||||
template <class T> bool addToGameplayObjects(const QString& listName, T idToAdd);
|
||||
template <class T> 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
|
|
@ -13,6 +13,7 @@
|
|||
#include "Application.h"
|
||||
|
||||
#include <EntityTreeRenderer.h>
|
||||
#include <NetworkingConstants.h>
|
||||
|
||||
static const float CONTEXT_OVERLAY_TABLET_OFFSET = 30.0f; // Degrees
|
||||
static const float CONTEXT_OVERLAY_TABLET_ORIENTATION = 210.0f; // Degrees
|
||||
|
@ -27,6 +28,9 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
|||
_entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
_hmdScriptingInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||
_tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
_selectionScriptingInterface = DependencyManager::get<SelectionScriptingInterface>();
|
||||
|
||||
_selectionToSceneHandler.initialize("contextOverlayHighlightList");
|
||||
|
||||
_entityPropertyFlags += PROP_POSITION;
|
||||
_entityPropertyFlags += PROP_ROTATION;
|
||||
|
@ -57,6 +61,8 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
|||
});
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>().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;
|
||||
|
@ -242,7 +248,7 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI
|
|||
}
|
||||
}
|
||||
|
||||
static const QString MARKETPLACE_BASE_URL = "https://metaverse.highfidelity.com/marketplace/items/";
|
||||
static const QString MARKETPLACE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace/items/";
|
||||
|
||||
void ContextOverlayInterface::openMarketplace() {
|
||||
// lets open the tablet and go to the current item in
|
||||
|
@ -260,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) {
|
||||
|
|
|
@ -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> _hmdScriptingInterface;
|
||||
QSharedPointer<TabletScriptingInterface> _tabletScriptingInterface;
|
||||
QSharedPointer<SelectionScriptingInterface> _selectionScriptingInterface;
|
||||
OverlayID _contextOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
std::shared_ptr<Image3DOverlay> _contextOverlay { nullptr };
|
||||
public:
|
||||
|
@ -81,6 +83,8 @@ private:
|
|||
void disableEntityHighlight(const EntityItemID& entityItemID);
|
||||
|
||||
void deletingEntity(const EntityItemID& entityItemID);
|
||||
|
||||
SelectionToSceneHandler _selectionToSceneHandler;
|
||||
};
|
||||
|
||||
#endif // hifi_ContextOverlayInterface_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);
|
||||
|
|
|
@ -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()); }
|
||||
|
||||
|
|
|
@ -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<GeometryCache>()->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;
|
||||
|
|
|
@ -95,7 +95,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;
|
||||
|
@ -241,7 +240,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());
|
||||
|
@ -793,10 +791,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);
|
||||
|
@ -2777,20 +2771,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([&] {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<PacketVersion>(EntityQueryPacketVersion::JSONFilterWithFamilyTree);
|
||||
case PacketType::AvatarIdentity:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -210,6 +210,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
}
|
||||
|
||||
task.addJob<DebugZoneLighting>("DrawZoneStack", deferredFrameTransform);
|
||||
|
||||
// Render.getConfig("RenderMainView.DrawSelectionBounds").enabled = true
|
||||
const auto selectedMetas = task.addJob<SelectItems>("PassTestSelection", metas, "contextOverlayHighlightList");
|
||||
task.addJob<DrawBounds>("DrawSelectionBounds", selectedMetas);
|
||||
}
|
||||
|
||||
// AA job to be revisited
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -10,13 +10,39 @@
|
|||
//
|
||||
|
||||
#include "ImageProvider.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include <QReadLocker>
|
||||
#include <QWriteLocker>
|
||||
|
||||
const QString ImageProvider::PROVIDER_NAME = "security";
|
||||
QReadWriteLock ImageProvider::_rwLock;
|
||||
QPixmap* ImageProvider::_securityImage = nullptr;
|
||||
|
||||
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);
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
}
|
||||
if (pixmap) {
|
||||
_securityImage = new QPixmap(*pixmap);
|
||||
} else {
|
||||
_securityImage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
|
||||
|
||||
// adjust the internal pixmap to have the requested size
|
||||
QReadLocker lock(&_rwLock);
|
||||
if (id == "securityImage" && _securityImage) {
|
||||
*size = _securityImage->size();
|
||||
if (requestedSize.width() > 0 && requestedSize.height() > 0) {
|
|
@ -13,19 +13,20 @@
|
|||
#define hifi_ImageProvider_h
|
||||
|
||||
#include <QQuickImageProvider>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
class ImageProvider: public QQuickImageProvider {
|
||||
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) { _securityImage = pixmap; }
|
||||
|
||||
void setSecurityImage(const QPixmap* pixmap);
|
||||
protected:
|
||||
QPixmap* _securityImage { nullptr };
|
||||
static QReadWriteLock _rwLock;
|
||||
static QPixmap* _securityImage;
|
||||
|
||||
};
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "OffscreenQmlSurface.h"
|
||||
#include "ImageProvider.h"
|
||||
|
||||
// Has to come before Qt GL includes
|
||||
#include <gl/Config.h>
|
||||
|
@ -184,7 +185,7 @@ private:
|
|||
GLuint texture = textureAndFence.first;
|
||||
uvec2 size = _textureSizes[texture];
|
||||
auto sizeKey = uvec2ToUint64(size);
|
||||
// Textures can be returned after all surfaces of the given size have been destroyed,
|
||||
// Textures can be returned after all surfaces of the given size have been destroyed,
|
||||
// in which case we just destroy the texture
|
||||
if (!_textures.count(sizeKey)) {
|
||||
destroy(textureAndFence);
|
||||
|
@ -305,6 +306,9 @@ static size_t globalEngineRefCount{ 0 };
|
|||
#endif
|
||||
|
||||
void initializeQmlEngine(QQmlEngine* engine, QQuickWindow* window) {
|
||||
// register the pixmap image provider (used only for security image, for now)
|
||||
engine->addImageProvider(ImageProvider::PROVIDER_NAME, new ImageProvider());
|
||||
|
||||
engine->setNetworkAccessManagerFactory(new QmlNetworkAccessManagerFactory);
|
||||
auto importList = engine->importPathList();
|
||||
importList.insert(importList.begin(), PathUtils::resourcesPath());
|
||||
|
@ -464,8 +468,8 @@ std::function<void(uint32_t, void*)> OffscreenQmlSurface::getDiscardLambda() {
|
|||
}
|
||||
|
||||
bool OffscreenQmlSurface::allowNewFrame(uint8_t fps) {
|
||||
// If we already have a pending texture, don't render another one
|
||||
// i.e. don't render faster than the consumer context, since it wastes
|
||||
// If we already have a pending texture, don't render another one
|
||||
// i.e. don't render faster than the consumer context, since it wastes
|
||||
// GPU cycles on producing output that will never be seen
|
||||
if (0 != _latestTextureAndFence.first) {
|
||||
return false;
|
||||
|
@ -526,6 +530,7 @@ void OffscreenQmlSurface::create() {
|
|||
|
||||
// Create a QML engine.
|
||||
auto qmlEngine = acquireEngine(_quickWindow);
|
||||
|
||||
_qmlContext = new QQmlContext(qmlEngine->rootContext());
|
||||
|
||||
_qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
||||
|
|
|
@ -53,14 +53,27 @@
|
|||
// Description:
|
||||
// -Called when a message is received from SpectatorCamera.qml. The "message" argument is what is sent from the QML
|
||||
// in the format "{method, params}", like json-rpc. See also sendToQml().
|
||||
var isHmdPreviewDisabled = true;
|
||||
function fromQml(message) {
|
||||
switch (message.method) {
|
||||
case 'walletSetup_cancelClicked':
|
||||
case 'needsLogIn_cancelClicked':
|
||||
tablet.gotoHomeScreen();
|
||||
break;
|
||||
case 'walletSetup_loginClicked':
|
||||
case 'needsLogIn_loginClicked':
|
||||
openLoginWindow();
|
||||
break;
|
||||
case 'disableHmdPreview':
|
||||
isHmdPreviewDisabled = Menu.isOptionChecked("Disable Preview");
|
||||
Menu.setIsOptionChecked("Disable Preview", true);
|
||||
break;
|
||||
case 'maybeEnableHmdPreview':
|
||||
Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled);
|
||||
break;
|
||||
case 'walletReset':
|
||||
onButtonClicked();
|
||||
onButtonClicked();
|
||||
break;
|
||||
default:
|
||||
print('Unrecognized message from QML:', JSON.stringify(message));
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
@ -789,6 +791,7 @@ function handleDomainChange() {
|
|||
var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp());
|
||||
createButton.editProperties({
|
||||
icon: (hasRezPermissions ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON),
|
||||
captionColorOverride: (hasRezPermissions ? "" : "#888888"),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -127,9 +127,15 @@
|
|||
$(this).attr('data-href', $(this).attr('href'));
|
||||
$(this).attr('href', '#');
|
||||
cost = $(this).closest('.col-xs-3').find('.item-cost').text();
|
||||
|
||||
$(this).closest('.col-xs-3').prev().attr("class", 'col-xs-6');
|
||||
$(this).closest('.col-xs-3').attr("class", 'col-xs-6');
|
||||
|
||||
if (parseInt(cost) > 0) {
|
||||
$(this).find('.price').text("BUY");
|
||||
var priceElement = $(this).find('.price')
|
||||
priceElement.css({ "width": "auto", "padding": "3px 5px", "height": "26px" });
|
||||
priceElement.text(parseFloat(cost / 100).toFixed(2) + ' HFC');
|
||||
priceElement.css({ "min-width": priceElement.width() + 10 });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -160,23 +166,23 @@
|
|||
|
||||
// Try this here in case it works (it will if the user just pressed the "back" button,
|
||||
// since that doesn't trigger another AJAX request.
|
||||
injectBuyButtonOnMainPage;
|
||||
injectBuyButtonOnMainPage();
|
||||
addPurchasesButton();
|
||||
}
|
||||
}
|
||||
|
||||
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('.btn').html('<span class="glyphicon glyphicon-download"></span>Buy Item ');
|
||||
if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
||||
$('#side-info').find('.btn').first().html('<span class="glyphicon glyphicon-download" id="buyItemButton"></span>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(),
|
||||
|
|
|
@ -228,6 +228,15 @@
|
|||
case 'purchases_backClicked':
|
||||
tablet.gotoWebScreen(message.referrerURL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'purchases_goToMarketplaceClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'needsLogIn_cancelClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'needsLogIn_loginClicked':
|
||||
openLoginWindow();
|
||||
break;
|
||||
default:
|
||||
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
|
||||
}
|
||||
|
|