Merge branch 'master' into feature/ant-man

This commit is contained in:
Anthony J. Thibault 2017-08-31 18:10:39 -07:00
commit 6618ba12e9
56 changed files with 1165 additions and 483 deletions

View file

@ -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.";
}

View file

@ -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

View file

@ -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

View 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
//
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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();
}
}

View file

@ -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 {

View file

@ -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;
}

View file

@ -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) : "");

View file

@ -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";

View file

@ -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
//

View file

@ -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;
}
}
}

View file

@ -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

View file

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

View file

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View file

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

View file

@ -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

View file

@ -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);

View file

@ -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());
}

View file

@ -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);

View file

@ -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();
}

View file

@ -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

View file

@ -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();
}

View file

@ -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);
};

View 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";
}
}

View 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

View file

@ -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) {

View file

@ -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

View file

@ -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);

View file

@ -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()); }

View file

@ -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;

View file

@ -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([&] {

View file

@ -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();

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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:

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -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) {

View file

@ -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;
};

View file

@ -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()));

View file

@ -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));
}

View file

@ -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"),
});
}

View file

@ -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(),

View file

@ -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));
}