mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 19:34:02 +02:00
Merge branch 'master' into flickable_web_pages
This commit is contained in:
commit
dd6d530853
61 changed files with 1373 additions and 740 deletions
|
@ -35,7 +35,7 @@ void ScriptableAvatar::startAnimation(const QString& url, float fps, float prior
|
|||
return;
|
||||
}
|
||||
_animation = DependencyManager::get<AnimationCache>()->getAnimation(url);
|
||||
_animationDetails = AnimationDetails("", QUrl(url), fps, 0, loop, hold, false, firstFrame, lastFrame, true, firstFrame);
|
||||
_animationDetails = AnimationDetails("", QUrl(url), fps, 0, loop, hold, false, firstFrame, lastFrame, true, firstFrame, false);
|
||||
_maskedJoints = maskedJoints;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,14 @@
|
|||
<title>Welcome to Interface</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
@font-face {
|
||||
font-family: 'Raleway Light';
|
||||
src: url('../fonts/Raleway-Light.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
background: black;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
|
@ -15,6 +22,14 @@
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
a:link {color:inherit}
|
||||
a:active {color:inherit}
|
||||
a:visited {color:inherit}
|
||||
a:hover {
|
||||
color:inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#left_button {
|
||||
position: absolute;
|
||||
left: 70;
|
||||
|
@ -38,6 +53,15 @@
|
|||
position: absolute;
|
||||
top: 0; left: 0; bottom: 0; right: 0;
|
||||
}
|
||||
|
||||
#report_problem {
|
||||
position: fixed;
|
||||
top: 10;
|
||||
right: 10;
|
||||
font-family: "Raleway Light", sans-serif;
|
||||
text-decoration: none;
|
||||
color: #ddd;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var handControllerImageURL = null;
|
||||
|
@ -152,6 +176,7 @@
|
|||
<a href="#" id="left_button" onmousedown="cycleLeft()"></a>
|
||||
<a href="#" id="right_button" onmousedown="cycleRight()"></a>
|
||||
</div>
|
||||
<a href="mailto:support@highfidelity.com" id="report_problem">Report Problem</a>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 643 B |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 909 B |
|
@ -29,7 +29,6 @@ Rectangle {
|
|||
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;
|
||||
|
@ -46,10 +45,15 @@ Rectangle {
|
|||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
commerce.balance();
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,8 +61,8 @@ Rectangle {
|
|||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
root.activeView = "notSetUp";
|
||||
} else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") {
|
||||
root.activeView = "checkoutMain";
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
} else if (exists) {
|
||||
// just set the source again (to be sure the change was noticed)
|
||||
securityImage.source = "";
|
||||
|
@ -66,12 +70,17 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePathIfExistsResultReceived = true;
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
} else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") {
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && !passphraseModal.visible) {
|
||||
passphraseModal.visible = true;
|
||||
} else if (isAuthenticated) {
|
||||
root.activeView = "checkoutMain";
|
||||
if (!balanceReceived) {
|
||||
commerce.balance();
|
||||
}
|
||||
if (!purchasesReceived) {
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,8 +98,8 @@ Rectangle {
|
|||
console.log("Failed to get balance", result.data.message);
|
||||
} else {
|
||||
root.balanceReceived = true;
|
||||
hfcBalanceText.text = (parseFloat(result.data.balance/100).toFixed(2)) + " HFC";
|
||||
balanceAfterPurchase = parseFloat(result.data.balance/100) - root.itemPriceFull/100;
|
||||
hfcBalanceText.text = result.data.balance + " HFC";
|
||||
balanceAfterPurchase = result.data.balance - root.itemPriceFull;
|
||||
root.setBuyText();
|
||||
}
|
||||
}
|
||||
|
@ -110,10 +119,6 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
HifiWallet.SecurityImageModel {
|
||||
id: securityImageModel;
|
||||
}
|
||||
|
||||
//
|
||||
// TITLE BAR START
|
||||
//
|
||||
|
@ -195,7 +200,6 @@ Rectangle {
|
|||
securityImageResultReceived = false;
|
||||
purchasesReceived = false;
|
||||
balanceReceived = false;
|
||||
keyFilePathIfExistsResultReceived = false;
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +225,20 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
HifiWallet.PassphraseModal {
|
||||
id: passphraseModal;
|
||||
visible: false;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// "WALLET NOT SET UP" START
|
||||
|
@ -553,7 +570,7 @@ Rectangle {
|
|||
}
|
||||
RalewayRegular {
|
||||
id: balanceAfterPurchaseText;
|
||||
text: balanceAfterPurchase.toFixed(2) + " HFC";
|
||||
text: balanceAfterPurchase + " HFC";
|
||||
// Text size
|
||||
size: balanceAfterPurchaseTextLabel.size;
|
||||
// Anchors
|
||||
|
@ -648,7 +665,7 @@ Rectangle {
|
|||
sendToScript({method: 'checkout_goToPurchases'});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RalewayRegular {
|
||||
id: buyText;
|
||||
// Text size
|
||||
|
@ -687,7 +704,7 @@ Rectangle {
|
|||
anchors.bottom: root.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
|
||||
RalewayRegular {
|
||||
id: completeText;
|
||||
text: "<b>Purchase Complete!</b><br><br>You bought <b>" + (itemNameText.text) + "</b> by <b>" + (itemAuthorText.text) + "</b>";
|
||||
|
@ -706,7 +723,7 @@ Rectangle {
|
|||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id: checkoutSuccessActionButtonsContainer;
|
||||
// Size
|
||||
|
@ -756,7 +773,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id: continueShoppingButtonContainer;
|
||||
// Size
|
||||
|
@ -799,7 +816,7 @@ Rectangle {
|
|||
anchors.bottom: root.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
|
||||
RalewayRegular {
|
||||
id: failureHeaderText;
|
||||
text: "<b>Purchase Failed.</b><br>Your Purchases and HFC balance haven't changed.";
|
||||
|
@ -818,7 +835,7 @@ Rectangle {
|
|||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
|
||||
RalewayRegular {
|
||||
id: failureErrorText;
|
||||
// Text size
|
||||
|
@ -836,7 +853,7 @@ Rectangle {
|
|||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id: backToMarketplaceButtonContainer;
|
||||
// Size
|
||||
|
@ -892,7 +909,7 @@ Rectangle {
|
|||
itemNameText.text = message.params.itemName;
|
||||
itemAuthorText.text = message.params.itemAuthor;
|
||||
root.itemPriceFull = message.params.itemPrice;
|
||||
itemPriceText.text = root.itemPriceFull === 0 ? "Free" : "<b>" + (parseFloat(root.itemPriceFull/100).toFixed(2)) + " HFC</b>";
|
||||
itemPriceText.text = root.itemPriceFull === 0 ? "Free" : "<b>" + root.itemPriceFull + " HFC</b>";
|
||||
itemHref = message.params.itemHref;
|
||||
if (itemHref.indexOf('.json') === -1) {
|
||||
root.itemIsJson = false;
|
||||
|
|
|
@ -28,7 +28,6 @@ Rectangle {
|
|||
property string activeView: "initialize";
|
||||
property string referrerURL: "";
|
||||
property bool securityImageResultReceived: false;
|
||||
property bool keyFilePathIfExistsResultReceived: false;
|
||||
property bool purchasesReceived: false;
|
||||
property bool punctuationMode: false;
|
||||
// Style
|
||||
|
@ -41,9 +40,15 @@ Rectangle {
|
|||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.getSecurityImage();
|
||||
commerce.getKeyFilePathIfExists();
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,8 +56,8 @@ Rectangle {
|
|||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
root.activeView = "notSetUp";
|
||||
} else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") {
|
||||
root.activeView = "purchasesMain";
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
} else if (exists) {
|
||||
// just set the source again (to be sure the change was noticed)
|
||||
securityImage.source = "";
|
||||
|
@ -60,12 +65,12 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePathIfExistsResultReceived = true;
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
} else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") {
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && !passphraseModal.visible) {
|
||||
passphraseModal.visible = true;
|
||||
} else if (isAuthenticated) {
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +79,9 @@ Rectangle {
|
|||
if (result.status !== 'success') {
|
||||
console.log("Failed to get purchases", result.message);
|
||||
} else {
|
||||
purchasesModel.clear();
|
||||
purchasesModel.append(result.data.assets);
|
||||
filteredPurchasesModel.clear();
|
||||
filteredPurchasesModel.append(result.data.assets);
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +171,6 @@ Rectangle {
|
|||
Component.onCompleted: {
|
||||
securityImageResultReceived = false;
|
||||
purchasesReceived = false;
|
||||
keyFilePathIfExistsResultReceived = false;
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
@ -189,6 +195,21 @@ Rectangle {
|
|||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
HifiWallet.PassphraseModal {
|
||||
id: passphraseModal;
|
||||
visible: false;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// "WALLET NOT SET UP" START
|
||||
|
|
|
@ -31,6 +31,7 @@ Item {
|
|||
|
||||
// "Unavailable"
|
||||
RalewayRegular {
|
||||
id: helpText;
|
||||
text: "Help me!";
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
@ -43,6 +44,34 @@ Item {
|
|||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: resetButton.top;
|
||||
anchors.bottomMargin: 15;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: 50;
|
||||
width: 250;
|
||||
text: "DEBUG: Clear Cached Passphrase";
|
||||
onClicked: {
|
||||
commerce.setPassphrase("");
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: resetButton;
|
||||
color: hifi.buttons.red;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: helpText.bottom;
|
||||
anchors.bottomMargin: 15;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: 50;
|
||||
width: 250;
|
||||
text: "DEBUG: Reset Wallet!";
|
||||
onClicked: {
|
||||
commerce.reset();
|
||||
sendSignalToWallet({method: 'walletReset'});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
|
|
304
interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml
Normal file
304
interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml
Normal file
|
@ -0,0 +1,304 @@
|
|||
//
|
||||
// PassphraseModal.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// PassphraseModal
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-31
|
||||
// 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;
|
||||
z: 998;
|
||||
property bool keyboardRaised: false;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onSecurityImageResult: {
|
||||
passphraseModalSecurityImage.source = "";
|
||||
passphraseModalSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
submitPassphraseInputButton.enabled = true;
|
||||
if (!isAuthenticated) {
|
||||
errorText.text = "Authentication failed - please try again.";
|
||||
} else {
|
||||
root.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This object is always used in a popup.
|
||||
// This MouseArea is used to prevent a user from being
|
||||
// able to click on a button/mouseArea underneath the popup.
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
propagateComposedEvents: false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
sendSignalToParent({method: 'disableHmdPreview'});
|
||||
} else {
|
||||
sendSignalToParent({method: 'maybeEnableHmdPreview'});
|
||||
}
|
||||
}
|
||||
|
||||
// Background rectangle
|
||||
Rectangle {
|
||||
anchors.fill: parent;
|
||||
color: "black";
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 250;
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: instructionsText;
|
||||
text: "Enter Wallet Passphrase";
|
||||
size: 16;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 30;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
width: passphraseField.width;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
}
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: passphraseField;
|
||||
anchors.top: instructionsText.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: instructionsText.left;
|
||||
width: 280;
|
||||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: "passphrase";
|
||||
|
||||
onFocusChanged: {
|
||||
root.keyboardRaised = focus;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
root.keyboardRaised = true;
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
submitPassphraseInputButton.enabled = false;
|
||||
commerce.setPassphrase(passphraseField.text);
|
||||
}
|
||||
}
|
||||
|
||||
// Show passphrase text
|
||||
HifiControlsUit.CheckBox {
|
||||
id: showPassphrase;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.left: passphraseField.left;
|
||||
anchors.top: passphraseField.bottom;
|
||||
anchors.topMargin: 8;
|
||||
height: 30;
|
||||
text: "Show passphrase as plain text";
|
||||
boxSize: 24;
|
||||
onClicked: {
|
||||
passphraseField.echoMode = checked ? TextInput.Normal : TextInput.Password;
|
||||
}
|
||||
}
|
||||
|
||||
// Security Image
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
// Anchors
|
||||
anchors.top: instructionsText.top;
|
||||
anchors.left: passphraseField.right;
|
||||
anchors.leftMargin: 12;
|
||||
anchors.right: parent.right;
|
||||
Image {
|
||||
id: passphraseModalSecurityImage;
|
||||
anchors.top: parent.top;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: 75;
|
||||
width: height;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
source: "image://security/securityImage";
|
||||
cache: false;
|
||||
onVisibleChanged: {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: passphraseModalSecurityImageOverlay;
|
||||
source: "images/lockOverlay.png";
|
||||
width: passphraseModalSecurityImage.width * 0.45;
|
||||
height: passphraseModalSecurityImage.height * 0.45;
|
||||
anchors.bottom: passphraseModalSecurityImage.bottom;
|
||||
anchors.right: passphraseModalSecurityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
text: "security image";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.top: passphraseModalSecurityImage.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: securityImageContainer.left;
|
||||
anchors.right: securityImageContainer.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Error text above buttons
|
||||
RalewaySemiBold {
|
||||
id: errorText;
|
||||
text: "";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.bottom: passphrasePopupActionButtonsContainer.top;
|
||||
anchors.bottomMargin: 4;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 30;
|
||||
// Style
|
||||
color: hifi.colors.redHighlight;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
//
|
||||
// ACTION BUTTONS START
|
||||
//
|
||||
Item {
|
||||
id: passphrasePopupActionButtonsContainer;
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 10;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
id: cancelPassphraseInputButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
height: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendSignalToParent({method: 'passphrasePopup_cancelClicked'});
|
||||
}
|
||||
}
|
||||
|
||||
// "Submit" button
|
||||
HifiControlsUit.Button {
|
||||
id: submitPassphraseInputButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
height: 40;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
text: "Submit"
|
||||
onClicked: {
|
||||
submitPassphraseInputButton.enabled = false;
|
||||
commerce.setPassphrase(passphraseField.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signal sendSignalToParent(var msg);
|
||||
}
|
|
@ -40,8 +40,8 @@ Item {
|
|||
passphrasePageSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
|
||||
onPassphraseSetupStatusResult: {
|
||||
sendMessageToLightbox({method: 'statusResult', status: passphraseIsSetup});
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
sendMessageToLightbox({method: 'statusResult', status: isAuthenticated});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,10 +58,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
SecurityImageModel {
|
||||
id: gridModel;
|
||||
}
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: passphraseField;
|
||||
anchors.top: parent.top;
|
||||
|
@ -199,7 +195,7 @@ Item {
|
|||
// Text below TextFields
|
||||
RalewaySemiBold {
|
||||
id: passwordReqs;
|
||||
text: "Passphrase must be at least 4 characters";
|
||||
text: "Passphrase must be at least 3 characters";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
|
@ -256,7 +252,7 @@ Item {
|
|||
}
|
||||
|
||||
function validateAndSubmitPassphrase() {
|
||||
if (passphraseField.text.length < 4) {
|
||||
if (passphraseField.text.length < 3) {
|
||||
setErrorText("Passphrase too short.");
|
||||
return false;
|
||||
} else if (passphraseField.text !== passphraseFieldAgain.text) {
|
||||
|
|
|
@ -26,8 +26,6 @@ Rectangle {
|
|||
id: root;
|
||||
|
||||
property string activeView: "initialize";
|
||||
property bool securityImageResultReceived: false;
|
||||
property bool keyFilePathIfExistsResultReceived: false;
|
||||
property bool keyboardRaised: false;
|
||||
|
||||
// Style
|
||||
|
@ -40,25 +38,30 @@ Rectangle {
|
|||
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"
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
} else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") {
|
||||
root.activeView = "walletHome";
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePathIfExistsResultReceived = true;
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
onSecurityImageResult: {
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
root.activeView = "notSetUp";
|
||||
} else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") {
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && passphraseModal && !passphraseModal.visible) {
|
||||
passphraseModal.visible = true;
|
||||
} else if (isAuthenticated) {
|
||||
root.activeView = "walletHome";
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +92,8 @@ Rectangle {
|
|||
if (msg.method === 'walletSetup_cancelClicked') {
|
||||
walletSetupLightbox.visible = false;
|
||||
} else if (msg.method === 'walletSetup_finished') {
|
||||
root.activeView = "walletHome";
|
||||
root.activeView = "initialize";
|
||||
commerce.getLoginStatus();
|
||||
} else if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
} else if (msg.method === 'walletSetup_lowerKeyboard') {
|
||||
|
@ -107,7 +111,7 @@ Rectangle {
|
|||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
|
@ -127,7 +131,7 @@ Rectangle {
|
|||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendToScript(msg);
|
||||
|
@ -196,7 +200,7 @@ Rectangle {
|
|||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NeedsLogIn {
|
||||
id: needsLogIn;
|
||||
visible: root.activeView === "needsLogIn";
|
||||
|
@ -218,6 +222,21 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
PassphraseModal {
|
||||
id: passphraseModal;
|
||||
visible: false;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotSetUp {
|
||||
id: notSetUp;
|
||||
visible: root.activeView === "notSetUp";
|
||||
|
@ -225,7 +244,7 @@ Rectangle {
|
|||
anchors.bottom: tabButtonsContainer.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'setUpClicked') {
|
||||
|
@ -296,6 +315,14 @@ Rectangle {
|
|||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletReset') {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -510,7 +537,7 @@ Rectangle {
|
|||
}
|
||||
//
|
||||
// TAB BUTTONS END
|
||||
//
|
||||
//
|
||||
|
||||
Item {
|
||||
id: keyboardContainer;
|
||||
|
|
|
@ -24,6 +24,7 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property bool historyReceived: false;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
@ -37,13 +38,14 @@ Item {
|
|||
}
|
||||
|
||||
onBalanceResult : {
|
||||
balanceText.text = parseFloat(result.data.balance/100).toFixed(2);
|
||||
balanceText.text = result.data.balance;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,13 +88,14 @@ Item {
|
|||
height: 60;
|
||||
Rectangle {
|
||||
id: hfcBalanceField;
|
||||
color: hifi.colors.darkGray;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: parent.height - 15;
|
||||
|
||||
// "HFC" balance label
|
||||
RalewayRegular {
|
||||
FiraSansRegular {
|
||||
id: balanceLabel;
|
||||
text: "HFC";
|
||||
// Text size
|
||||
|
@ -104,13 +107,14 @@ Item {
|
|||
anchors.rightMargin: 4;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
color: hifi.colors.lightGrayText;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
historyReceived = false;
|
||||
commerce.balance();
|
||||
commerce.history();
|
||||
}
|
||||
|
@ -118,7 +122,7 @@ Item {
|
|||
}
|
||||
|
||||
// Balance Text
|
||||
FiraSansRegular {
|
||||
FiraSansSemiBold {
|
||||
id: balanceText;
|
||||
text: "--";
|
||||
// Text size
|
||||
|
@ -130,7 +134,7 @@ Item {
|
|||
anchors.right: balanceLabel.left;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
color: hifi.colors.lightGrayText;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
@ -233,24 +237,66 @@ Item {
|
|||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: transactionHistoryModel;
|
||||
}
|
||||
Rectangle {
|
||||
id: transactionHistory;
|
||||
anchors.top: recentActivityText.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
color: "white";
|
||||
|
||||
// some placeholder stuff
|
||||
TextArea {
|
||||
id: transactionHistoryText;
|
||||
text: "<hr>history unavailable<hr>";
|
||||
textFormat: TextEdit.AutoText;
|
||||
font.pointSize: 10;
|
||||
ListView {
|
||||
id: transactionHistory;
|
||||
anchors.centerIn: parent;
|
||||
width: parent.width - 12;
|
||||
height: parent.height - 12;
|
||||
visible: transactionHistoryModel.count !== 0;
|
||||
clip: true;
|
||||
model: transactionHistoryModel;
|
||||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: transactionText.height + 30;
|
||||
FiraSansRegular {
|
||||
id: transactionText;
|
||||
text: model.text;
|
||||
// Style
|
||||
size: 18;
|
||||
width: parent.width;
|
||||
height: paintedHeight;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
color: "black";
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
}
|
||||
}
|
||||
onAtYEndChanged: {
|
||||
if (transactionHistory.atYEnd) {
|
||||
console.log("User scrolled to the bottom of 'Recent Activity'.");
|
||||
// Grab next page of results and append to model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This should never be visible (since you immediately get 100 HFC)
|
||||
FiraSansRegular {
|
||||
id: emptyTransationHistory;
|
||||
size: 24;
|
||||
visible: !transactionHistory.visible && root.historyReceived;
|
||||
text: "Recent Activity Unavailable";
|
||||
anchors.fill: parent;
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ Rectangle {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string lastPage: "securityImage";
|
||||
property string lastPage: "initialize";
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
|
@ -39,9 +39,9 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onPassphraseSetupStatusResult: {
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
securityImageContainer.visible = false;
|
||||
if (passphraseIsSetup) {
|
||||
if (isAuthenticated) {
|
||||
privateKeysReadyContainer.visible = true;
|
||||
} else {
|
||||
choosePassphraseContainer.visible = true;
|
||||
|
@ -58,16 +58,9 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
visible: false;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: securityImageTitle;
|
||||
// Size
|
||||
|
@ -124,7 +117,7 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 280;
|
||||
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendSignalToWallet(msg);
|
||||
|
@ -217,7 +210,7 @@ Rectangle {
|
|||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getPassphraseSetupStatus();
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import "../../styles-uit"
|
||||
import "../audio" as HifiAudio
|
||||
|
@ -109,15 +110,45 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: usernameText
|
||||
text: tabletRoot.username
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Item {
|
||||
width: 150
|
||||
height: 50
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 20
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: 20
|
||||
color: "#afafaf"
|
||||
anchors.rightMargin: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RalewaySemiBold {
|
||||
text: Account.loggedIn ? qsTr("Log out") : qsTr("Log in")
|
||||
horizontalAlignment: Text.AlignRight
|
||||
anchors.right: parent.right
|
||||
font.pixelSize: 20
|
||||
color: "#afafaf"
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
visible: Account.loggedIn
|
||||
height: Account.loggedIn ? parent.height/2 - parent.spacing/2 : 0
|
||||
text: Account.loggedIn ? "[" + tabletRoot.usernameShort + "]" : ""
|
||||
horizontalAlignment: Text.AlignRight
|
||||
anchors.right: parent.right
|
||||
font.pixelSize: 20
|
||||
color: "#afafaf"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if (!Account.loggedIn) {
|
||||
DialogsManager.showLoginDialog()
|
||||
} else {
|
||||
Account.logOut()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ Item {
|
|||
id: tabletRoot
|
||||
objectName: "tabletRoot"
|
||||
property string username: "Unknown user"
|
||||
property string usernameShort: "Unknown user"
|
||||
property var rootMenu;
|
||||
property var openModal: null;
|
||||
property var openMessage: null;
|
||||
|
@ -157,6 +158,11 @@ Item {
|
|||
|
||||
function setUsername(newUsername) {
|
||||
username = newUsername;
|
||||
usernameShort = newUsername.substring(0, 8);
|
||||
|
||||
if (newUsername.length > 8) {
|
||||
usernameShort = usernameShort + "..."
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
|
|
|
@ -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
|
||||
|
@ -675,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>();
|
||||
|
@ -2318,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()) {
|
||||
|
@ -5641,17 +5644,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
}
|
||||
renderArgs->_debugFlags = renderDebugFlags;
|
||||
//ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, transaction);
|
||||
|
||||
RenderArgs::OutlineFlags renderOutlineFlags = RenderArgs::RENDER_OUTLINE_NONE;
|
||||
auto contextOverlayInterface = DependencyManager::get<ContextOverlayInterface>();
|
||||
if (contextOverlayInterface->getEnabled()) {
|
||||
if (DependencyManager::get<ContextOverlayInterface>()->getIsInMarketplaceInspectionMode()) {
|
||||
renderOutlineFlags = RenderArgs::RENDER_OUTLINE_MARKETPLACE_MODE;
|
||||
} else {
|
||||
renderOutlineFlags = RenderArgs::RENDER_OUTLINE_WIREFRAMES;
|
||||
}
|
||||
}
|
||||
renderArgs->_outlineFlags = renderOutlineFlags;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6118,6 +6110,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
auto entityScriptServerLog = DependencyManager::get<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);
|
||||
|
|
|
@ -1912,6 +1912,17 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) {
|
|||
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
||||
if (shouldDrawHead != _prevShouldDrawHead) {
|
||||
_skeletonModel->setEnableCauterization(!shouldDrawHead);
|
||||
|
||||
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||
if (_attachmentData[i].jointName.compare("Head", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("Neck", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("LeftEye", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("RightEye", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("HeadTop_End", Qt::CaseInsensitive) == 0 ||
|
||||
_attachmentData[i].jointName.compare("Face", Qt::CaseInsensitive) == 0) {
|
||||
_attachmentModels[i]->setVisibleInScene(shouldDrawHead, qApp->getMain3DScene());
|
||||
}
|
||||
}
|
||||
}
|
||||
_prevShouldDrawHead = shouldDrawHead;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QTimeZone>
|
||||
#include <QJsonDocument>
|
||||
#include "AccountManager.h"
|
||||
#include "Wallet.h"
|
||||
|
@ -45,7 +46,6 @@ Handler(buy)
|
|||
Handler(receiveAt)
|
||||
Handler(balance)
|
||||
Handler(inventory)
|
||||
Handler(history)
|
||||
|
||||
void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request) {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
@ -108,6 +108,71 @@ void Ledger::inventory(const QStringList& keys) {
|
|||
keysQuery("inventory", "inventorySuccess", "inventoryFailure");
|
||||
}
|
||||
|
||||
QString nameFromKey(const QString& key, const QStringList& publicKeys) {
|
||||
if (key.isNull() || key.isEmpty()) {
|
||||
return "<b>Marketplace</b>";
|
||||
}
|
||||
if (publicKeys.contains(key)) {
|
||||
return "You";
|
||||
}
|
||||
return "<b>Someone</b>";
|
||||
}
|
||||
|
||||
void Ledger::historySuccess(QNetworkReply& reply) {
|
||||
// here we send a historyResult with some extra stuff in it
|
||||
// Namely, the styled text we'd like to show. The issue is the
|
||||
// QML cannot do that easily since it doesn't know what the wallet
|
||||
// public key(s) are. Let's keep it that way
|
||||
QByteArray response = reply.readAll();
|
||||
QJsonObject data = QJsonDocument::fromJson(response).object();
|
||||
|
||||
// we will need the array of public keys from the wallet
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
auto keys = wallet->listPublicKeys();
|
||||
|
||||
// now we need to loop through the transactions and add fancy text...
|
||||
auto historyArray = data.find("data").value().toObject().find("history").value().toArray();
|
||||
QJsonArray newHistoryArray;
|
||||
|
||||
// TODO: do this with 0 copies if possible
|
||||
for(auto it = historyArray.begin(); it != historyArray.end(); it++) {
|
||||
auto valueObject = (*it).toObject();
|
||||
QString from = nameFromKey(valueObject["sender_key"].toString(), keys);
|
||||
QString to = nameFromKey(valueObject["recipient_key"].toString(), keys);
|
||||
// turns out on my machine, toLocalTime convert to some weird timezone, yet the
|
||||
// systemTimeZone is correct. To avoid a strange bug with other's systems too, lets
|
||||
// be explicit
|
||||
#ifdef Q_OS_MAC
|
||||
QDateTime createdAt = QDateTime::fromTime_t(valueObject["created_at"].toInt(), Qt::UTC);
|
||||
#else
|
||||
QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC);
|
||||
#endif
|
||||
QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone());
|
||||
valueObject["text"] = QString("%1 sent %2 <b>%3 %4</b> on %5 with message \"%6\"").
|
||||
arg(from, to, QString::number(valueObject["quantity"].toInt()), valueObject["asset_title"].toString(), localCreatedAt.toString(Qt::SystemLocaleShortDate), valueObject["message"].toString());
|
||||
newHistoryArray.push_back(valueObject);
|
||||
}
|
||||
// now copy the rest of the json -- this is inefficient
|
||||
// TODO: try to do this without making copies
|
||||
QJsonObject newData;
|
||||
newData["status"] = "success";
|
||||
QJsonObject newDataData;
|
||||
newDataData["history"] = newHistoryArray;
|
||||
newData["data"] = newDataData;
|
||||
emit historyResult(newData);
|
||||
}
|
||||
|
||||
void Ledger::historyFailure(QNetworkReply& reply) {
|
||||
failResponse("history", reply);
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -29,6 +29,30 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) {
|
|||
connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult);
|
||||
}
|
||||
|
||||
void QmlCommerce::getLoginStatus() {
|
||||
emit loginStatusResult(DependencyManager::get<AccountManager>()->isLoggedIn());
|
||||
}
|
||||
|
||||
void QmlCommerce::getKeyFilePathIfExists() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->sendKeyFilePathIfExists();
|
||||
}
|
||||
|
||||
void QmlCommerce::getWalletAuthenticatedStatus() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
emit walletAuthenticatedStatusResult(wallet->walletIsAuthenticatedWithPassphrase());
|
||||
}
|
||||
|
||||
void QmlCommerce::getSecurityImage() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->getSecurityImage();
|
||||
}
|
||||
|
||||
void QmlCommerce::chooseSecurityImage(const QString& imageFile) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->chooseSecurityImage(imageFile);
|
||||
}
|
||||
|
||||
void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUsername) {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
|
@ -60,28 +84,19 @@ void QmlCommerce::history() {
|
|||
ledger->history(wallet->listPublicKeys());
|
||||
}
|
||||
|
||||
void QmlCommerce::chooseSecurityImage(const QString& imageFile) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->chooseSecurityImage(imageFile);
|
||||
}
|
||||
|
||||
void QmlCommerce::getSecurityImage() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->getSecurityImage();
|
||||
}
|
||||
|
||||
void QmlCommerce::getLoginStatus() {
|
||||
emit loginStatusResult(DependencyManager::get<AccountManager>()->isLoggedIn());
|
||||
}
|
||||
|
||||
void QmlCommerce::setPassphrase(const QString& passphrase) {
|
||||
emit passphraseSetupStatusResult(true);
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
if (wallet->getPassphrase() && !wallet->getPassphrase()->isEmpty()) {
|
||||
wallet->changePassphrase(passphrase);
|
||||
} else {
|
||||
wallet->setPassphrase(passphrase);
|
||||
}
|
||||
getWalletAuthenticatedStatus();
|
||||
}
|
||||
|
||||
void QmlCommerce::getPassphraseSetupStatus() {
|
||||
emit passphraseSetupStatusResult(false);
|
||||
}
|
||||
void QmlCommerce::getKeyFilePathIfExists() {
|
||||
void QmlCommerce::reset() {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->sendKeyFilePathIfExists();
|
||||
ledger->reset();
|
||||
wallet->reset();
|
||||
}
|
||||
|
|
|
@ -28,28 +28,33 @@ public:
|
|||
QmlCommerce(QQuickItem* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void loginStatusResult(bool isLoggedIn);
|
||||
void keyFilePathIfExistsResult(const QString& path);
|
||||
void securityImageResult(bool exists);
|
||||
void walletAuthenticatedStatusResult(bool isAuthenticated);
|
||||
|
||||
void buyResult(QJsonObject result);
|
||||
// Balance and Inventory are NOT properties, because QML can't change them (without risk of failure), and
|
||||
// because we can't scalably know of out-of-band changes (e.g., another machine interacting with the block chain).
|
||||
void balanceResult(QJsonObject result);
|
||||
void inventoryResult(QJsonObject result);
|
||||
void securityImageResult(bool exists);
|
||||
void loginStatusResult(bool isLoggedIn);
|
||||
void passphraseSetupStatusResult(bool passphraseIsSetup);
|
||||
void historyResult(QJsonObject result);
|
||||
void keyFilePathIfExistsResult(const QString& path);
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void getLoginStatus();
|
||||
Q_INVOKABLE void getKeyFilePathIfExists();
|
||||
Q_INVOKABLE void getSecurityImage();
|
||||
Q_INVOKABLE void getWalletAuthenticatedStatus();
|
||||
|
||||
Q_INVOKABLE void chooseSecurityImage(const QString& imageFile);
|
||||
Q_INVOKABLE void setPassphrase(const QString& passphrase);
|
||||
|
||||
Q_INVOKABLE void buy(const QString& assetId, int cost, const QString& buyerUsername = "");
|
||||
Q_INVOKABLE void balance();
|
||||
Q_INVOKABLE void inventory();
|
||||
Q_INVOKABLE void history();
|
||||
Q_INVOKABLE void chooseSecurityImage(const QString& imageFile);
|
||||
Q_INVOKABLE void getSecurityImage();
|
||||
Q_INVOKABLE void getLoginStatus();
|
||||
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>
|
||||
|
@ -55,16 +56,72 @@ QString imageFilePath() {
|
|||
int passwordCallback(char* password, int maxPasswordSize, int rwFlag, void* u) {
|
||||
// just return a hardcoded pwd for now
|
||||
auto passphrase = DependencyManager::get<Wallet>()->getPassphrase();
|
||||
if (passphrase) {
|
||||
if (passphrase && !passphrase->isEmpty()) {
|
||||
strcpy(password, passphrase->toLocal8Bit().constData());
|
||||
return static_cast<int>(passphrase->size());
|
||||
} else {
|
||||
// ok gotta bring up modal dialog... But right now lets just
|
||||
// just keep it empty
|
||||
// this shouldn't happen - so lets log it to tell us we have
|
||||
// a problem with the flow...
|
||||
qCCritical(commerce) << "no cached passphrase while decrypting!";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
RSA* readKeys(const char* filename) {
|
||||
FILE* fp;
|
||||
RSA* key = NULL;
|
||||
if ((fp = fopen(filename, "rt"))) {
|
||||
// file opened successfully
|
||||
qCDebug(commerce) << "opened key file" << filename;
|
||||
if ((key = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL))) {
|
||||
// now read private key
|
||||
|
||||
qCDebug(commerce) << "read public key";
|
||||
|
||||
if ((key = PEM_read_RSAPrivateKey(fp, &key, passwordCallback, NULL))) {
|
||||
qCDebug(commerce) << "read private key";
|
||||
fclose(fp);
|
||||
return key;
|
||||
}
|
||||
qCDebug(commerce) << "failed to read private key";
|
||||
} else {
|
||||
qCDebug(commerce) << "failed to read public key";
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
qCDebug(commerce) << "failed to open key file" << filename;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
bool writeKeys(const char* filename, RSA* keys) {
|
||||
FILE* fp;
|
||||
bool retval = false;
|
||||
if ((fp = fopen(filename, "wt"))) {
|
||||
if (!PEM_write_RSAPublicKey(fp, keys)) {
|
||||
fclose(fp);
|
||||
qCDebug(commerce) << "failed to write public key";
|
||||
QFile(QString(filename)).remove();
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (!PEM_write_RSAPrivateKey(fp, keys, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) {
|
||||
fclose(fp);
|
||||
qCDebug(commerce) << "failed to write private key";
|
||||
QFile(QString(filename)).remove();
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = true;
|
||||
qCDebug(commerce) << "wrote keys successfully";
|
||||
fclose(fp);
|
||||
} else {
|
||||
qCDebug(commerce) << "failed to open key file" << filename;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// BEGIN copied code - this will be removed/changed at some point soon
|
||||
// copied (without emits for various signals) from libraries/networking/src/RSAKeypairGenerator.cpp.
|
||||
// We will have a different implementation in practice, but this gives us a start for now
|
||||
|
@ -123,25 +180,9 @@ QPair<QByteArray*, QByteArray*> generateRSAKeypair() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// now lets persist them to files
|
||||
// FIXME: for now I'm appending to the file if it exists. As long as we always put
|
||||
// the keys in the same order, this works fine. TODO: verify this will skip over
|
||||
// anything else (like an embedded image)
|
||||
FILE* fp;
|
||||
if ((fp = fopen(keyFilePath().toStdString().c_str(), "at"))) {
|
||||
if (!PEM_write_RSAPublicKey(fp, keyPair)) {
|
||||
fclose(fp);
|
||||
qCDebug(commerce) << "failed to write public key";
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (!PEM_write_RSAPrivateKey(fp, keyPair, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) {
|
||||
fclose(fp);
|
||||
qCDebug(commerce) << "failed to write private key";
|
||||
return retval;
|
||||
}
|
||||
fclose(fp);
|
||||
if (!writeKeys(keyFilePath().toStdString().c_str(), keyPair)) {
|
||||
qCDebug(commerce) << "couldn't save keys!";
|
||||
return retval;
|
||||
}
|
||||
|
||||
RSA_free(keyPair);
|
||||
|
@ -200,9 +241,6 @@ RSA* readPrivateKey(const char* filename) {
|
|||
// file opened successfully
|
||||
qCDebug(commerce) << "opened key file" << filename;
|
||||
if ((key = PEM_read_RSAPrivateKey(fp, &key, passwordCallback, NULL))) {
|
||||
// cleanup
|
||||
fclose(fp);
|
||||
|
||||
qCDebug(commerce) << "parsed private key file successfully";
|
||||
|
||||
} else {
|
||||
|
@ -214,7 +252,6 @@ RSA* readPrivateKey(const char* filename) {
|
|||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
static const unsigned char IVEC[16] = "IAmAnIVecYay123";
|
||||
|
||||
void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArray& salt) {
|
||||
|
@ -235,6 +272,10 @@ void Wallet::setPassphrase(const QString& passphrase) {
|
|||
delete _passphrase;
|
||||
}
|
||||
_passphrase = new QString(passphrase);
|
||||
|
||||
// no matter what, we now need to clear the keys as they
|
||||
// need to be read using this passphrase
|
||||
_publicKeys.clear();
|
||||
}
|
||||
|
||||
// encrypt some stuff
|
||||
|
@ -340,6 +381,38 @@ bool Wallet::decryptFile(const QString& inputFilePath, unsigned char** outputBuf
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Wallet::walletIsAuthenticatedWithPassphrase() {
|
||||
// try to read existing keys if they exist...
|
||||
|
||||
// FIXME: initialize OpenSSL elsewhere soon
|
||||
initialize();
|
||||
|
||||
// this should always be false if we don't have a passphrase
|
||||
// cached yet
|
||||
if (!_passphrase || _passphrase->isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (_publicKeys.count() > 0) {
|
||||
// we _must_ be authenticated if the publicKeys are there
|
||||
return true;
|
||||
}
|
||||
|
||||
// otherwise, we have a passphrase but no keys, so we have to check
|
||||
auto publicKey = readPublicKey(keyFilePath().toStdString().c_str());
|
||||
|
||||
if (publicKey.size() > 0) {
|
||||
if (auto key = readPrivateKey(keyFilePath().toStdString().c_str())) {
|
||||
RSA_free(key);
|
||||
|
||||
// be sure to add the public key so we don't do this over and over
|
||||
_publicKeys.push_back(publicKey.toBase64());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Wallet::createIfNeeded() {
|
||||
if (_publicKeys.count() > 0) return false;
|
||||
|
||||
|
@ -464,7 +537,9 @@ void Wallet::getSecurityImage() {
|
|||
}
|
||||
|
||||
// decrypt and return
|
||||
if (decryptFile(imageFilePath(), &data, &dataLen)) {
|
||||
QString filePath(imageFilePath());
|
||||
QFileInfo fileInfo(filePath);
|
||||
if (fileInfo.exists() && decryptFile(filePath, &data, &dataLen)) {
|
||||
// create the pixmap
|
||||
_securityImage = new QPixmap();
|
||||
_securityImage->loadFromData(data, dataLen, "jpg");
|
||||
|
@ -488,3 +563,51 @@ 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();
|
||||
}
|
||||
|
||||
bool Wallet::changePassphrase(const QString& newPassphrase) {
|
||||
qCDebug(commerce) << "changing passphrase";
|
||||
RSA* keys = readKeys(keyFilePath().toStdString().c_str());
|
||||
if (keys) {
|
||||
// we read successfully, so now write to a new temp file
|
||||
// save old passphrase just in case
|
||||
// TODO: force re-enter?
|
||||
QString oldPassphrase = *_passphrase;
|
||||
setPassphrase(newPassphrase);
|
||||
QString tempFileName = QString("%1.%2").arg(keyFilePath(), QString("temp"));
|
||||
if (writeKeys(tempFileName.toStdString().c_str(), keys)) {
|
||||
// ok, now move the temp file to the correct spot
|
||||
QFile(QString(keyFilePath())).remove();
|
||||
QFile(tempFileName).rename(QString(keyFilePath()));
|
||||
qCDebug(commerce) << "passphrase changed successfully";
|
||||
return true;
|
||||
} else {
|
||||
qCDebug(commerce) << "couldn't write keys";
|
||||
QFile(tempFileName).remove();
|
||||
setPassphrase(oldPassphrase);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
qCDebug(commerce) << "couldn't read keys";
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -39,16 +39,21 @@ public:
|
|||
|
||||
void setPassphrase(const QString& passphrase);
|
||||
QString* getPassphrase() { return _passphrase; }
|
||||
bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); }
|
||||
bool walletIsAuthenticatedWithPassphrase();
|
||||
bool changePassphrase(const QString& newPassphrase);
|
||||
|
||||
void reset();
|
||||
|
||||
signals:
|
||||
void securityImageResult(bool exists) ;
|
||||
void securityImageResult(bool exists);
|
||||
void keyFilePathIfExistsResult(const QString& path);
|
||||
|
||||
private:
|
||||
QStringList _publicKeys{};
|
||||
QPixmap* _securityImage { nullptr };
|
||||
QByteArray _salt {"iamsalt!"};
|
||||
QString* _passphrase { new QString("pwd") };
|
||||
QString* _passphrase { new QString("") };
|
||||
|
||||
void updateImageProvider();
|
||||
bool encryptFile(const QString& inputFilePath, const QString& outputFilePath);
|
||||
|
|
|
@ -18,6 +18,8 @@ AccountScriptingInterface* AccountScriptingInterface::getInstance() {
|
|||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
QObject::connect(accountManager.data(), &AccountManager::profileChanged,
|
||||
&sharedInstance, &AccountScriptingInterface::usernameChanged);
|
||||
QObject::connect(accountManager.data(), &AccountManager::usernameChanged,
|
||||
&sharedInstance, &AccountScriptingInterface::onUsernameChanged);
|
||||
return &sharedInstance;
|
||||
}
|
||||
|
||||
|
@ -31,6 +33,21 @@ bool AccountScriptingInterface::checkAndSignalForAccessToken() {
|
|||
return accountManager->checkAndSignalForAccessToken();
|
||||
}
|
||||
|
||||
void AccountScriptingInterface::logOut() {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
return accountManager->logout();
|
||||
}
|
||||
|
||||
AccountScriptingInterface::AccountScriptingInterface(QObject *parent): QObject(parent) {
|
||||
m_loggedIn = isLoggedIn();
|
||||
emit loggedInChanged(m_loggedIn);
|
||||
}
|
||||
|
||||
void AccountScriptingInterface::onUsernameChanged(QString username) {
|
||||
m_loggedIn = (username != QString());
|
||||
emit loggedInChanged(m_loggedIn);
|
||||
}
|
||||
|
||||
QString AccountScriptingInterface::getUsername() {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
if (accountManager->isLoggedIn()) {
|
||||
|
|
|
@ -18,6 +18,7 @@ class AccountScriptingInterface : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
|
||||
Q_PROPERTY(bool loggedIn READ loggedIn NOTIFY loggedInChanged)
|
||||
|
||||
/**jsdoc
|
||||
* @namespace Account
|
||||
|
@ -32,6 +33,7 @@ signals:
|
|||
* @return {Signal}
|
||||
*/
|
||||
void usernameChanged();
|
||||
void loggedInChanged(bool loggedIn);
|
||||
|
||||
public slots:
|
||||
static AccountScriptingInterface* getInstance();
|
||||
|
@ -50,6 +52,20 @@ public slots:
|
|||
*/
|
||||
bool isLoggedIn();
|
||||
bool checkAndSignalForAccessToken();
|
||||
void logOut();
|
||||
|
||||
public:
|
||||
AccountScriptingInterface(QObject* parent = nullptr);
|
||||
bool loggedIn() const {
|
||||
return m_loggedIn;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void onUsernameChanged(QString username);
|
||||
|
||||
private:
|
||||
bool m_loggedIn { false };
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_AccountScriptingInterface_h
|
||||
|
|
|
@ -33,7 +33,12 @@ void DialogsManagerScriptingInterface::showAddressBar() {
|
|||
|
||||
void DialogsManagerScriptingInterface::hideAddressBar() {
|
||||
QMetaObject::invokeMethod(DependencyManager::get<DialogsManager>().data(),
|
||||
"hideAddressBar", Qt::QueuedConnection);
|
||||
"hideAddressBar", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void DialogsManagerScriptingInterface::showLoginDialog() {
|
||||
QMetaObject::invokeMethod(DependencyManager::get<DialogsManager>().data(),
|
||||
"showLoginDialog", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void DialogsManagerScriptingInterface::showFeed() {
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
public slots:
|
||||
void showAddressBar();
|
||||
void hideAddressBar();
|
||||
void showLoginDialog();
|
||||
|
||||
signals:
|
||||
void addressBarShown(bool visible);
|
||||
|
|
195
interface/src/scripting/SelectionScriptingInterface.cpp
Normal file
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
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
|
|
@ -28,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;
|
||||
|
@ -58,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;
|
||||
|
@ -261,25 +266,11 @@ void ContextOverlayInterface::openMarketplace() {
|
|||
}
|
||||
|
||||
void ContextOverlayInterface::enableEntityHighlight(const EntityItemID& entityItemID) {
|
||||
auto entityTree = qApp->getEntities()->getTree();
|
||||
entityTree->withReadLock([&] {
|
||||
auto entityItem = entityTree->findEntityByEntityItemID(entityItemID);
|
||||
if ((entityItem != NULL) && !entityItem->getShouldHighlight()) {
|
||||
qCDebug(context_overlay) << "Setting 'shouldHighlight' to 'true' for Entity ID:" << entityItemID;
|
||||
entityItem->setShouldHighlight(true);
|
||||
}
|
||||
});
|
||||
_selectionScriptingInterface->addToSelectedItemsList("contextOverlayHighlightList", "entity", entityItemID);
|
||||
}
|
||||
|
||||
void ContextOverlayInterface::disableEntityHighlight(const EntityItemID& entityItemID) {
|
||||
auto entityTree = qApp->getEntities()->getTree();
|
||||
entityTree->withReadLock([&] {
|
||||
auto entityItem = entityTree->findEntityByEntityItemID(entityItemID);
|
||||
if ((entityItem != NULL) && entityItem->getShouldHighlight()) {
|
||||
qCDebug(context_overlay) << "Setting 'shouldHighlight' to 'false' for Entity ID:" << entityItemID;
|
||||
entityItem->setShouldHighlight(false);
|
||||
}
|
||||
});
|
||||
_selectionScriptingInterface->removeFromSelectedItemsList("contextOverlayHighlightList", "entity", entityItemID);
|
||||
}
|
||||
|
||||
void ContextOverlayInterface::deletingEntity(const EntityItemID& entityID) {
|
||||
|
|
|
@ -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()); }
|
||||
|
||||
|
|
|
@ -910,6 +910,8 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
|||
|
||||
const QVector<FBXAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy
|
||||
auto& fbxJoints = _animation->getGeometry().joints;
|
||||
auto& originalFbxJoints = _model->getFBXGeometry().joints;
|
||||
bool allowTranslation = entity->getAnimationAllowTranslation();
|
||||
int frameCount = frames.size();
|
||||
if (frameCount <= 0) {
|
||||
return;
|
||||
|
@ -952,7 +954,9 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
|||
int index = _jointMapping[j];
|
||||
if (index >= 0) {
|
||||
glm::mat4 translationMat;
|
||||
if (index < translations.size()) {
|
||||
if (!allowTranslation){
|
||||
translationMat = glm::translate(originalFbxJoints[index].translation);
|
||||
} else if (index < translations.size()) {
|
||||
translationMat = glm::translate(translations[index]);
|
||||
}
|
||||
glm::mat4 rotationMat;
|
||||
|
@ -1080,7 +1084,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
}
|
||||
|
||||
_marketplaceEntity = entity->getMarketplaceID().length() != 0;
|
||||
_shouldHighlight = entity->getShouldHighlight();
|
||||
_animating = entity->isAnimatingSomething();
|
||||
|
||||
withWriteLock([&] {
|
||||
|
@ -1207,17 +1210,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;
|
||||
|
|
|
@ -33,6 +33,7 @@ bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b
|
|||
|
||||
void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, Animation, animation, Running, running);
|
||||
|
@ -46,6 +47,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire
|
|||
void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, allowTranslation, bool, setAllowTranslation);
|
||||
|
||||
// legacy property support
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationURL, QString, setURL, getURL);
|
||||
|
@ -67,6 +69,7 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo
|
|||
|
||||
void AnimationPropertyGroup::merge(const AnimationPropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(url);
|
||||
COPY_PROPERTY_IF_CHANGED(allowTranslation);
|
||||
COPY_PROPERTY_IF_CHANGED(fps);
|
||||
COPY_PROPERTY_IF_CHANGED(currentFrame);
|
||||
COPY_PROPERTY_IF_CHANGED(running);
|
||||
|
@ -88,6 +91,7 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
|
|||
float lastFrame = getLastFrame();
|
||||
bool loop = getLoop();
|
||||
bool hold = getHold();
|
||||
bool allowTranslation = getAllowTranslation();
|
||||
|
||||
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
|
||||
QJsonObject settingsAsJsonObject = settingsAsJson.object();
|
||||
|
@ -122,6 +126,11 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
|
|||
running = settingsMap["hold"].toBool();
|
||||
}
|
||||
|
||||
if (settingsMap.contains("allowTranslation")) {
|
||||
allowTranslation = settingsMap["allowTranslation"].toBool();
|
||||
}
|
||||
|
||||
setAllowTranslation(allowTranslation);
|
||||
setFPS(fps);
|
||||
setCurrentFrame(currentFrame);
|
||||
setRunning(running);
|
||||
|
@ -137,6 +146,7 @@ void AnimationPropertyGroup::debugDump() const {
|
|||
qCDebug(entities) << " url:" << getURL() << " has changed:" << urlChanged();
|
||||
qCDebug(entities) << " fps:" << getFPS() << " has changed:" << fpsChanged();
|
||||
qCDebug(entities) << "currentFrame:" << getCurrentFrame() << " has changed:" << currentFrameChanged();
|
||||
qCDebug(entities) << "allowTranslation:" << getAllowTranslation() << " has changed:" << allowTranslationChanged();
|
||||
}
|
||||
|
||||
void AnimationPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
|
@ -149,6 +159,9 @@ void AnimationPropertyGroup::listChangedProperties(QList<QString>& out) {
|
|||
if (currentFrameChanged()) {
|
||||
out << "animation-currentFrame";
|
||||
}
|
||||
if (allowTranslationChanged()) {
|
||||
out << "animation-allowTranslation";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,6 +175,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
|||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, getAllowTranslation());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning());
|
||||
|
@ -181,6 +195,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF
|
|||
bool somethingChanged = false;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, setAllowTranslation);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame);
|
||||
|
@ -198,7 +213,8 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF
|
|||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
@ -215,6 +231,7 @@ void AnimationPropertyGroup::markAllChanged() {
|
|||
_firstFrameChanged = true;
|
||||
_lastFrameChanged = true;
|
||||
_holdChanged = true;
|
||||
_allowTranslationChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
|
||||
|
@ -228,12 +245,14 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_ALLOW_TRANSLATION, allowTranslation);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, AllowTranslation, getAllowTranslation);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning);
|
||||
|
@ -247,6 +266,7 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie
|
|||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, AllowTranslation, allowTranslation, setAllowTranslation);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning);
|
||||
|
@ -268,6 +288,7 @@ EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamP
|
|||
requestedProperties += PROP_ANIMATION_FIRST_FRAME;
|
||||
requestedProperties += PROP_ANIMATION_LAST_FRAME;
|
||||
requestedProperties += PROP_ANIMATION_HOLD;
|
||||
requestedProperties += PROP_ANIMATION_ALLOW_TRANSLATION;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
@ -283,6 +304,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En
|
|||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, getAllowTranslation());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning());
|
||||
|
@ -301,6 +323,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char
|
|||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, setAllowTranslation);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning);
|
||||
|
|
|
@ -85,6 +85,7 @@ public:
|
|||
DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float, 0.0f); // was animationSettings.firstFrame
|
||||
DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame
|
||||
DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold
|
||||
DEFINE_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation, allowTranslation, bool, true);
|
||||
|
||||
protected:
|
||||
friend bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b);
|
||||
|
|
|
@ -94,7 +94,6 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
|||
requestedProperties += PROP_LOCKED;
|
||||
requestedProperties += PROP_USER_DATA;
|
||||
requestedProperties += PROP_MARKETPLACE_ID;
|
||||
requestedProperties += PROP_SHOULD_HIGHLIGHT;
|
||||
requestedProperties += PROP_NAME;
|
||||
requestedProperties += PROP_HREF;
|
||||
requestedProperties += PROP_DESCRIPTION;
|
||||
|
@ -240,7 +239,6 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked());
|
||||
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, getUserData());
|
||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, getMarketplaceID());
|
||||
APPEND_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, getShouldHighlight());
|
||||
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HREF, getHref());
|
||||
|
@ -792,10 +790,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
||||
}
|
||||
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT) {
|
||||
READ_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, bool, setShouldHighlight);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
|
||||
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
|
||||
READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref);
|
||||
|
@ -2772,20 +2766,6 @@ void EntityItem::setMarketplaceID(const QString& value) {
|
|||
});
|
||||
}
|
||||
|
||||
bool EntityItem::getShouldHighlight() const {
|
||||
bool result;
|
||||
withReadLock([&] {
|
||||
result = _shouldHighlight;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void EntityItem::setShouldHighlight(const bool value) {
|
||||
withWriteLock([&] {
|
||||
_shouldHighlight = value;
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t EntityItem::getDirtyFlags() const {
|
||||
uint32_t result;
|
||||
withReadLock([&] {
|
||||
|
|
|
@ -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);
|
||||
|
@ -1036,6 +1033,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_URL, Skybox, skybox, URL, url);
|
||||
|
@ -1337,7 +1335,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 +1633,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 +1747,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;
|
||||
|
|
|
@ -40,6 +40,7 @@ enum EntityPropertyList {
|
|||
PROP_ANIMATION_FPS,
|
||||
PROP_ANIMATION_FRAME_INDEX,
|
||||
PROP_ANIMATION_PLAYING,
|
||||
PROP_ANIMATION_ALLOW_TRANSLATION,
|
||||
|
||||
// these properties are supported by the EntityItem base class
|
||||
PROP_REGISTRATION_POINT,
|
||||
|
@ -78,7 +79,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
|
||||
|
|
|
@ -330,6 +330,10 @@ void ModelEntityItem::setAnimationSettings(const QString& value) {
|
|||
setAnimationHold(hold);
|
||||
}
|
||||
|
||||
if (settingsMap.contains("allowTranslation")) {
|
||||
bool allowTranslation = settingsMap["allowTranslation"].toBool();
|
||||
setAnimationAllowTranslation(allowTranslation);
|
||||
}
|
||||
_dirtyFlags |= Simulation::DIRTY_UPDATEABLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,10 @@ public:
|
|||
|
||||
void setAnimationCurrentFrame(float value);
|
||||
void setAnimationIsPlaying(bool value);
|
||||
void setAnimationFPS(float value);
|
||||
void setAnimationFPS(float value);
|
||||
|
||||
void setAnimationAllowTranslation(bool value) { _animationProperties.setAllowTranslation(value); };
|
||||
bool getAnimationAllowTranslation() const { return _animationProperties.getAllowTranslation(); };
|
||||
|
||||
void setAnimationLoop(bool loop);
|
||||
bool getAnimationLoop() const;
|
||||
|
|
|
@ -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_ANIMATION_ALLOW_TRANSLATION_PROPERTIES;
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::JSONFilterWithFamilyTree);
|
||||
case PacketType::AvatarIdentity:
|
||||
|
|
|
@ -259,6 +259,8 @@ 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;
|
||||
const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 73;
|
||||
|
||||
enum class EntityQueryPacketVersion: PacketVersion {
|
||||
JSONFilter = 18,
|
||||
|
|
|
@ -92,6 +92,7 @@ void EntityMotionState::updateServerPhysicsVariables() {
|
|||
|
||||
Transform localTransform;
|
||||
_entity->getLocalTransformAndVelocities(localTransform, _serverVelocity, _serverAngularVelocity);
|
||||
_serverVariablesSet = true;
|
||||
_serverPosition = localTransform.getTranslation();
|
||||
_serverRotation = localTransform.getRotation();
|
||||
_serverAcceleration = _entity->getAcceleration();
|
||||
|
@ -99,18 +100,19 @@ void EntityMotionState::updateServerPhysicsVariables() {
|
|||
}
|
||||
|
||||
void EntityMotionState::handleDeactivation() {
|
||||
// copy _server data to entity
|
||||
bool success;
|
||||
_entity->setPosition(_serverPosition, success, false);
|
||||
_entity->setOrientation(_serverRotation, success, false);
|
||||
_entity->setVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
_entity->setAngularVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
// and also to RigidBody
|
||||
btTransform worldTrans;
|
||||
worldTrans.setOrigin(glmToBullet(_serverPosition));
|
||||
worldTrans.setRotation(glmToBullet(_serverRotation));
|
||||
_body->setWorldTransform(worldTrans);
|
||||
// no need to update velocities... should already be zero
|
||||
if (_serverVariablesSet) {
|
||||
// copy _server data to entity
|
||||
Transform localTransform = _entity->getLocalTransform();
|
||||
localTransform.setTranslation(_serverPosition);
|
||||
localTransform.setRotation(_serverRotation);
|
||||
_entity->setLocalTransformAndVelocities(localTransform, ENTITY_ITEM_ZERO_VEC3, ENTITY_ITEM_ZERO_VEC3);
|
||||
// and also to RigidBody
|
||||
btTransform worldTrans;
|
||||
worldTrans.setOrigin(glmToBullet(_entity->getPosition()));
|
||||
worldTrans.setRotation(glmToBullet(_entity->getRotation()));
|
||||
_body->setWorldTransform(worldTrans);
|
||||
// no need to update velocities... should already be zero
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
@ -339,6 +341,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
|||
// if we've never checked before, our _lastStep will be 0, and we need to initialize our state
|
||||
if (_lastStep == 0) {
|
||||
btTransform xform = _body->getWorldTransform();
|
||||
_serverVariablesSet = true;
|
||||
_serverPosition = worldToLocal.transform(bulletToGLM(xform.getOrigin()));
|
||||
_serverRotation = worldToLocal.getRotation() * bulletToGLM(xform.getRotation());
|
||||
_serverVelocity = worldVelocityToLocal.transform(getBodyLinearVelocityGTSigma());
|
||||
|
|
|
@ -107,6 +107,7 @@ protected:
|
|||
// Meanwhile we also keep a raw EntityItem* for internal stuff where the pointer is guaranteed valid.
|
||||
EntityItem* _entity;
|
||||
|
||||
bool _serverVariablesSet { false };
|
||||
glm::vec3 _serverPosition; // in simulation-frame (not world-frame)
|
||||
glm::quat _serverRotation;
|
||||
glm::vec3 _serverVelocity;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -827,10 +827,10 @@ AnimationDetails::AnimationDetails() :
|
|||
}
|
||||
|
||||
AnimationDetails::AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop,
|
||||
bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame) :
|
||||
bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame, bool allowTranslation) :
|
||||
role(role), url(url), fps(fps), priority(priority), loop(loop), hold(hold),
|
||||
startAutomatically(startAutomatically), firstFrame(firstFrame), lastFrame(lastFrame),
|
||||
running(running), currentFrame(currentFrame) {
|
||||
running(running), currentFrame(currentFrame), allowTranslation(allowTranslation) {
|
||||
}
|
||||
|
||||
|
||||
|
@ -847,6 +847,7 @@ QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const Animatio
|
|||
obj.setProperty("lastFrame", details.lastFrame);
|
||||
obj.setProperty("running", details.running);
|
||||
obj.setProperty("currentFrame", details.currentFrame);
|
||||
obj.setProperty("allowTranslation", details.allowTranslation);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ class AnimationDetails {
|
|||
public:
|
||||
AnimationDetails();
|
||||
AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop,
|
||||
bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame);
|
||||
bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame, bool allowTranslation);
|
||||
|
||||
QString role;
|
||||
QUrl url;
|
||||
|
@ -210,6 +210,7 @@ public:
|
|||
float lastFrame;
|
||||
bool running;
|
||||
float currentFrame;
|
||||
bool allowTranslation;
|
||||
};
|
||||
Q_DECLARE_METATYPE(AnimationDetails);
|
||||
QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event);
|
||||
|
|
|
@ -731,7 +731,7 @@ void SpatiallyNestable::setScale(float value) {
|
|||
}
|
||||
}
|
||||
|
||||
const Transform SpatiallyNestable::getLocalTransform() const {
|
||||
Transform SpatiallyNestable::getLocalTransform() const {
|
||||
Transform result;
|
||||
_transformLock.withReadLock([&] {
|
||||
result =_transform;
|
||||
|
|
|
@ -121,7 +121,7 @@ public:
|
|||
virtual glm::vec3 getScale(int jointIndex) const;
|
||||
|
||||
// object's parent's frame
|
||||
virtual const Transform getLocalTransform() const;
|
||||
virtual Transform getLocalTransform() const;
|
||||
virtual void setLocalTransform(const Transform& transform);
|
||||
|
||||
virtual glm::vec3 getLocalPosition() const;
|
||||
|
|
|
@ -18,10 +18,25 @@ const QString ImageProvider::PROVIDER_NAME = "security";
|
|||
QReadWriteLock ImageProvider::_rwLock;
|
||||
QPixmap* ImageProvider::_securityImage = nullptr;
|
||||
|
||||
void ImageProvider::setSecurityImage(QPixmap* pixmap) {
|
||||
ImageProvider::~ImageProvider() {
|
||||
QWriteLocker lock(&_rwLock);
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
_securityImage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageProvider::setSecurityImage(const QPixmap* pixmap) {
|
||||
// no need to delete old one, that is managed by the wallet
|
||||
QWriteLocker lock(&_rwLock);
|
||||
_securityImage = pixmap;
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
}
|
||||
if (pixmap) {
|
||||
_securityImage = new QPixmap(*pixmap);
|
||||
} else {
|
||||
_securityImage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
|
||||
|
|
|
@ -20,10 +20,10 @@ public:
|
|||
static const QString PROVIDER_NAME;
|
||||
|
||||
ImageProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) {}
|
||||
|
||||
virtual ~ImageProvider();
|
||||
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
|
||||
|
||||
void setSecurityImage(QPixmap* pixmap);
|
||||
void setSecurityImage(const QPixmap* pixmap);
|
||||
protected:
|
||||
static QReadWriteLock _rwLock;
|
||||
static QPixmap* _securityImage;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
var isHmdPreviewDisabled = true;
|
||||
function fromQml(message) {
|
||||
switch (message.method) {
|
||||
case 'passphrasePopup_cancelClicked':
|
||||
case 'walletSetup_cancelClicked':
|
||||
case 'needsLogIn_cancelClicked':
|
||||
tablet.gotoHomeScreen();
|
||||
|
@ -70,6 +71,10 @@
|
|||
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"),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -446,6 +446,10 @@
|
|||
<input type="checkbox" id="property-model-animation-hold">
|
||||
<label for="property-model-animation-hold">Animation hold</label>
|
||||
</div>
|
||||
<div class="property checkbox indent">
|
||||
<input type="checkbox" id="property-model-animation-allow-translation">
|
||||
<label for="property-model-animation-allow-translation">Animation Allow Translation</label>
|
||||
</div>
|
||||
<div id="animation-fps" class="property number">
|
||||
<label>Animation FPS</label>
|
||||
<input type="number" id="property-model-animation-fps">
|
||||
|
@ -642,10 +646,6 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<fieldset id="polyvox" class="major">
|
||||
<legend class="section-header spatial-group poly-vox-section property xyz">
|
||||
Voxel volume size <span>m</span>
|
||||
|
|
|
@ -611,6 +611,7 @@ function loaded() {
|
|||
var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame");
|
||||
var elModelAnimationLoop = document.getElementById("property-model-animation-loop");
|
||||
var elModelAnimationHold = document.getElementById("property-model-animation-hold");
|
||||
var elModelAnimationAllowTranslation = document.getElementById("property-model-animation-allow-translation");
|
||||
var elModelTextures = document.getElementById("property-model-textures");
|
||||
var elModelOriginalTextures = document.getElementById("property-model-original-textures");
|
||||
|
||||
|
@ -926,6 +927,7 @@ function loaded() {
|
|||
elModelAnimationLastFrame.value = properties.animation.lastFrame;
|
||||
elModelAnimationLoop.checked = properties.animation.loop;
|
||||
elModelAnimationHold.checked = properties.animation.hold;
|
||||
elModelAnimationAllowTranslation.checked = properties.animation.allowTranslation;
|
||||
elModelTextures.value = properties.textures;
|
||||
setTextareaScrolling(elModelTextures);
|
||||
elModelOriginalTextures.value = properties.originalTextures;
|
||||
|
@ -1276,6 +1278,7 @@ function loaded() {
|
|||
elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame'));
|
||||
elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop'));
|
||||
elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold'));
|
||||
elModelAnimationAllowTranslation.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'allowTranslation'));
|
||||
|
||||
elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures'));
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
var isPreparing = false; // Explicitly track download request status.
|
||||
|
||||
var confirmAllPurchases = false; // Set this to "true" to cause Checkout.qml to popup for all items, even if free
|
||||
|
||||
|
||||
function injectCommonCode(isDirectoryPage) {
|
||||
|
||||
// Supporting styles from marketplaces.css.
|
||||
|
@ -122,7 +122,7 @@
|
|||
|
||||
function injectBuyButtonOnMainPage() {
|
||||
var cost;
|
||||
|
||||
|
||||
$('.grid-item').find('#price-or-edit').find('a').each(function() {
|
||||
$(this).attr('data-href', $(this).attr('href'));
|
||||
$(this).attr('href', '#');
|
||||
|
@ -130,16 +130,16 @@
|
|||
|
||||
$(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) {
|
||||
var priceElement = $(this).find('.price')
|
||||
priceElement.css({ "width": "auto", "padding": "3px 5px", "height": "26px" });
|
||||
priceElement.text(parseFloat(cost / 100).toFixed(2) + ' HFC');
|
||||
priceElement.text(cost + ' HFC');
|
||||
priceElement.css({ "min-width": priceElement.width() + 10 });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
$('.grid-item').find('#price-or-edit').find('a').on('click', function () {
|
||||
buyButtonClicked($(this).closest('.grid-item').attr('data-item-id'),
|
||||
$(this).closest('.grid-item').find('.item-title').text(),
|
||||
|
@ -173,16 +173,17 @@
|
|||
|
||||
function injectHiFiItemPageCode() {
|
||||
if (confirmAllPurchases) {
|
||||
var href = $('#side-info').find('.btn').attr('href');
|
||||
$('#side-info').find('.btn').attr('href', '#');
|
||||
|
||||
var href = $('#side-info').find('.btn').first().attr('href');
|
||||
$('#side-info').find('.btn').first().attr('href', '#');
|
||||
|
||||
var cost = $('.item-cost').text();
|
||||
|
||||
if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
||||
$('#side-info').find('.btn').html('<span class="glyphicon glyphicon-download" id="buyItemButton"></span>Own Item: ' + (parseFloat(cost / 100).toFixed(2)) + ' HFC');
|
||||
$('#side-info').find('.btn').first().html('<span class="glyphicon glyphicon-download" id="buyItemButton"></span>Own Item: ' + cost + ' 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(),
|
||||
|
@ -264,7 +265,7 @@
|
|||
// Reference: https://clara.io/learn/sdk/api/export
|
||||
|
||||
//var XMLHTTPREQUEST_URL = "https://clara.io/api/scenes/{uuid}/export/fbx?zip=true¢erScene=true&alignSceneGround=true&fbxUnit=Meter&fbxVersion=7&fbxEmbedTextures=true&imageFormat=WebGL";
|
||||
// 13 Jan 2017: Specify FBX version 5 and remove some options in order to make Clara.io site more likely to
|
||||
// 13 Jan 2017: Specify FBX version 5 and remove some options in order to make Clara.io site more likely to
|
||||
// be successful in generating zip files.
|
||||
var XMLHTTPREQUEST_URL = "https://clara.io/api/scenes/{uuid}/export/fbx?fbxUnit=Meter&fbxVersion=5&fbxEmbedTextures=true&imageFormat=WebGL";
|
||||
|
||||
|
@ -447,7 +448,7 @@
|
|||
cancelClaraDownload();
|
||||
} else {
|
||||
var parsedJsonMessage = JSON.parse(message);
|
||||
|
||||
|
||||
if (parsedJsonMessage.type === "marketplaces") {
|
||||
if (parsedJsonMessage.action === "inspectionModeSetting") {
|
||||
confirmAllPurchases = !!parsedJsonMessage.data;
|
||||
|
|
|
@ -197,6 +197,7 @@
|
|||
// Description:
|
||||
// -Called when a message is received from Checkout.qml. The "message" argument is what is sent from the Checkout QML
|
||||
// in the format "{method, params}", like json-rpc.
|
||||
var isHmdPreviewDisabled = true;
|
||||
function fromQml(message) {
|
||||
switch (message.method) {
|
||||
case 'checkout_setUpClicked':
|
||||
|
@ -231,12 +232,20 @@
|
|||
case 'purchases_goToMarketplaceClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'passphrasePopup_cancelClicked':
|
||||
case 'needsLogIn_cancelClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue