Merge branch 'master' into hfm_mimetype

This commit is contained in:
sabrina-shanman 2018-11-28 15:06:04 -08:00
commit b809eed01f
25 changed files with 435 additions and 233 deletions

View file

@ -16,9 +16,9 @@ if (HIFI_MEMORY_DEBUGGING)
if (UNIX)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# for clang on Linux
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -shared-libasan -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -shared-libasan -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -shared-libasan -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
else ()
# for gcc on Linux
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer")

View file

@ -19,6 +19,7 @@ import controlsUit 1.0 as HifiControlsUit
import "../../../controls" as HifiControls
import "../wallet" as HifiWallet
import "../common" as HifiCommerceCommon
import "../.." as HifiCommon
// references XXX from root context
@ -31,6 +32,7 @@ Rectangle {
property bool ownershipStatusReceived: false;
property bool balanceReceived: false;
property bool availableUpdatesReceived: false;
property bool itemInfoReceived: false;
property string baseItemName: "";
property string itemName;
property string itemId;
@ -181,11 +183,14 @@ Rectangle {
onItemIdChanged: {
root.ownershipStatusReceived = false;
root.itemInfoReceived = false;
Commerce.alreadyOwned(root.itemId);
root.availableUpdatesReceived = false;
root.currentUpdatesPage = 1;
Commerce.getAvailableUpdates(root.itemId);
itemPreviewImage.source = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/" + itemId + "/thumbnail/hifi-mp-" + itemId + ".jpg";
var MARKETPLACE_API_URL = Account.metaverseServerURL + "/api/v1/marketplace/items/";
http.request({uri: MARKETPLACE_API_URL + root.itemId}, updateCheckoutQMLFromHTTP);
}
onItemTypeChanged: {
@ -279,6 +284,7 @@ Rectangle {
ownershipStatusReceived = false;
balanceReceived = false;
availableUpdatesReceived = false;
itemInfoReceived = false;
Commerce.getWalletStatus();
}
}
@ -355,7 +361,7 @@ Rectangle {
Rectangle {
id: loading;
z: 997;
visible: !root.ownershipStatusReceived || !root.balanceReceived || !root.availableUpdatesReceived;
visible: !root.ownershipStatusReceived || !root.balanceReceived || !root.availableUpdatesReceived || !root.itemInfoReceived;
anchors.fill: parent;
color: hifi.colors.white;
@ -1063,10 +1069,33 @@ Rectangle {
}
}
}
HifiCommon.RootHttpRequest {
id: http;
}
//
// FUNCTION DEFINITIONS START
//
function updateCheckoutQMLFromHTTP(error, result) {
if (error || (result.status !== 'success')) {
// The QML will display a loading spinner forever if the user is stuck here.
console.log("Error in Checkout.qml when getting marketplace item info!");
return;
}
root.itemInfoReceived = true;
root.itemName = result.data.title;
root.itemPrice = result.data.cost;
root.itemHref = Account.metaverseServerURL + result.data.path;
root.itemAuthor = result.data.creator;
root.itemType = result.data.item_type || "unknown";
itemPreviewImage.source = result.data.thumbnail_url;
refreshBuyUI();
}
//
// Function Name: fromScript()
//
@ -1080,18 +1109,24 @@ Rectangle {
// Description:
// Called when a message is received from a script.
//
function fromScript(message) {
switch (message.method) {
case 'updateCheckoutQML':
root.itemId = message.params.itemId;
root.itemName = message.params.itemName.trim();
root.itemPrice = message.params.itemPrice;
root.itemHref = message.params.itemHref;
root.referrer = message.params.referrer;
root.itemAuthor = message.params.itemAuthor;
case 'updateCheckoutQMLItemID':
if (!message.params.itemId) {
console.log("A message with method 'updateCheckoutQMLItemID' was sent without an itemId!");
return;
}
// If we end up following the referrer (i.e. in case the wallet "isn't set up" or the user cancels),
// we want the user to be placed back on the individual item's page - thus we set the
// default of the referrer in this case to "itemPage".
root.referrer = message.params.referrer || "itemPage";
root.itemEdition = message.params.itemEdition || -1;
root.itemType = message.params.itemType || "unknown";
refreshBuyUI();
root.itemId = message.params.itemId;
break;
case 'http.response':
http.handleHttpResponse(message);
break;
default:
console.log('Checkout.qml: Unrecognized message from marketplaces.js');

View file

@ -25,14 +25,15 @@ Item {
id: root;
property bool isDisplayingNearby; // as opposed to 'connections'
// true when sending to 'nearby' or when a script raises the send asset dialog
property bool multiLineDisplay;
property string displayName;
property string userName;
property string profilePic;
property string textColor: hifi.colors.white;
Item {
visible: root.isDisplayingNearby;
visible: root.multiLineDisplay;
anchors.fill: parent;
RalewaySemiBold {
@ -71,7 +72,7 @@ Item {
}
Item {
visible: !root.isDisplayingNearby;
visible: !root.multiLineDisplay;
anchors.fill: parent;
Image {

View file

@ -39,7 +39,7 @@ Item {
property string sendingPubliclyEffectImage;
property var http;
property var listModelName;
property var keyboardContainer: nil;
property var keyboardContainer;
// This object is always used in a popup or full-screen Wallet section.
// This MouseArea is used to prevent a user from being
@ -56,7 +56,7 @@ Item {
// Background
Rectangle {
z: 1;
visible: root.assetName !== "" && sendAssetStep.visible;
visible: root.assetCertID !== "" && sendAssetStep.referrer !== "payIn" && sendAssetStep.visible;
anchors.top: parent.top;
anchors.topMargin: root.parentAppTitleBarHeight;
anchors.left: parent.left;
@ -84,7 +84,6 @@ Item {
if (sendPubliclyCheckbox.checked && sendAssetStep.referrer === "nearby") {
sendSignalToParent({
method: 'sendAsset_sendPublicly',
assetName: root.assetName,
recipient: sendAssetStep.selectedRecipientNodeID,
amount: parseInt(amountTextField.text),
effectImage: root.sendingPubliclyEffectImage
@ -108,6 +107,14 @@ Item {
root.nextActiveView = 'paymentFailure';
}
}
onCertificateInfoResult: {
if (result.status !== 'success') {
console.log("Failed to get certificate info", result.data.message);
} else {
root.assetName = result.data.marketplace_item_name;
}
}
}
Connections {
@ -155,7 +162,7 @@ Item {
Item {
id: userInfoContainer;
visible: root.assetName === "";
visible: root.assetCertID === "";
anchors.top: parent.top;
anchors.left: parent.left;
anchors.right: parent.right;
@ -251,7 +258,7 @@ Item {
LinearGradient {
anchors.fill: parent;
visible: root.assetName === "";
visible: root.assetCertID === "";
start: Qt.point(0, 0);
end: Qt.point(0, height);
gradient: Gradient {
@ -262,7 +269,7 @@ Item {
RalewaySemiBold {
id: sendAssetText;
text: root.assetName === "" ? "Send Money To:" : "Gift \"" + root.assetName + "\" To:";
text: root.assetCertID === "" ? "Send Money To:" : "Gift \"" + root.assetName + "\" To:";
// Anchors
anchors.top: parent.top;
anchors.topMargin: 26;
@ -405,7 +412,7 @@ Item {
HifiModels.PSFListModel {
id: connectionsModel;
http: root.http;
listModelName: root.listModelName;
listModelName: root.listModelName || "";
endpoint: "/api/v1/users?filter=connections";
itemsPerPage: 9;
listView: connectionsList;
@ -441,7 +448,7 @@ Item {
HiFiGlyphs {
id: closeGlyphButton_connections;
text: hifi.glyphs.close;
color: root.assetName === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray;
color: root.assetCertID === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray;
size: 26;
anchors.top: parent.top;
anchors.topMargin: 10;
@ -684,7 +691,7 @@ Item {
HiFiGlyphs {
id: closeGlyphButton_nearby;
text: hifi.glyphs.close;
color: root.assetName === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray;
color: root.assetCertID === "" ? hifi.colors.lightGrayText : hifi.colors.baseGray;
size: 26;
anchors.top: parent.top;
anchors.topMargin: 10;
@ -760,7 +767,7 @@ Item {
RalewaySemiBold {
id: sendToText;
text: root.assetName === "" ? "Send to:" : "Gift to:";
text: root.assetCertID === "" ? "Send to:" : "Gift to:";
// Anchors
anchors.top: parent.top;
anchors.topMargin: 36;
@ -853,7 +860,7 @@ Item {
id: sendAssetStep;
z: 996;
property string referrer; // either "connections" or "nearby"
property string referrer; // either "connections", "nearby", or "payIn"
property string selectedRecipientNodeID;
property string selectedRecipientDisplayName;
property string selectedRecipientUserName;
@ -865,7 +872,8 @@ Item {
RalewaySemiBold {
id: sendAssetText_sendAssetStep;
text: root.assetName === "" ? "Send Money" : "Gift \"" + root.assetName + "\"";
text: sendAssetStep.referrer === "payIn" && root.assetCertID !== "" ? "Send \"" + root.assetName + "\":" :
(root.assetCertID === "" ? "Send Money To:" : "Gift \"" + root.assetName + "\" To:");
// Anchors
anchors.top: parent.top;
anchors.topMargin: 26;
@ -878,7 +886,7 @@ Item {
// Text size
size: 22;
// Style
color: root.assetName === "" ? hifi.colors.white : hifi.colors.black;
color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black;
}
Item {
@ -893,7 +901,7 @@ Item {
RalewaySemiBold {
id: sendToText_sendAssetStep;
text: root.assetName === "" ? "Send to:" : "Gift to:";
text: (root.assetCertID === "" || sendAssetStep.referrer === "payIn") ? "Send to:" : "Gift to:";
// Anchors
anchors.top: parent.top;
anchors.left: parent.left;
@ -902,7 +910,7 @@ Item {
// Text size
size: 18;
// Style
color: root.assetName === "" ? hifi.colors.white : hifi.colors.black;
color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black;
verticalAlignment: Text.AlignVCenter;
}
@ -912,25 +920,26 @@ Item {
anchors.right: changeButton.left;
anchors.rightMargin: 12;
height: parent.height;
textColor: root.assetName === "" ? hifi.colors.white : hifi.colors.black;
textColor: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black;
displayName: sendAssetStep.selectedRecipientDisplayName;
userName: sendAssetStep.selectedRecipientUserName;
profilePic: sendAssetStep.selectedRecipientProfilePic !== "" ? ((0 === sendAssetStep.selectedRecipientProfilePic.indexOf("http")) ?
sendAssetStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendAssetStep.selectedRecipientProfilePic)) : "";
isDisplayingNearby: sendAssetStep.referrer === "nearby";
multiLineDisplay: sendAssetStep.referrer === "nearby" || sendAssetStep.referrer === "payIn";
}
// "CHANGE" button
HifiControlsUit.Button {
id: changeButton;
color: root.assetName === "" ? hifi.buttons.none : hifi.buttons.white;
color: root.assetCertID === "" ? hifi.buttons.none : hifi.buttons.white;
colorScheme: hifi.colorSchemes.dark;
anchors.right: parent.right;
anchors.verticalCenter: parent.verticalCenter;
height: 35;
width: 100;
text: "CHANGE";
visible: sendAssetStep.referrer !== "payIn";
onClicked: {
if (sendAssetStep.referrer === "connections") {
root.nextActiveView = "chooseRecipientConnection";
@ -944,7 +953,7 @@ Item {
Item {
id: amountContainer;
visible: root.assetName === "";
visible: root.assetCertID === "";
anchors.top: sendToContainer.bottom;
anchors.topMargin: 2;
anchors.left: parent.left;
@ -970,8 +979,9 @@ Item {
HifiControlsUit.TextField {
id: amountTextField;
text: root.assetName === "" ? "" : "1";
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
readOnly: sendAssetStep.referrer === "payIn";
text: root.assetCertID === "" ? "" : "1";
colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
inputMethodHints: Qt.ImhDigitsOnly;
// Anchors
anchors.verticalCenter: parent.verticalCenter;
@ -980,8 +990,8 @@ Item {
height: 50;
// Style
leftPermanentGlyph: hifi.glyphs.hfc;
activeFocusOnPress: true;
activeFocusOnTab: true;
activeFocusOnPress: !amountTextField.readOnly;
activeFocusOnTab: !amountTextField.readOnly;
validator: IntValidator { bottom: 0; }
@ -1071,6 +1081,7 @@ Item {
TextArea {
id: optionalMessage;
readOnly: sendAssetStep.referrer === "payIn";
property int maximumLength: 72;
property string previousText: text;
placeholderText: "<i>Optional Public Message (" + maximumLength + " character limit)</i>";
@ -1081,12 +1092,13 @@ Item {
// Style
background: Rectangle {
anchors.fill: parent;
color: root.assetName === "" ? (optionalMessage.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) :
color: (root.assetCertID === "" || sendAssetStep.referrer === "payIn") ?
(optionalMessage.activeFocus && !optionalMessage.readOnly ? hifi.colors.black : hifi.colors.baseGrayShadow) :
(optionalMessage.activeFocus ? "#EFEFEF" : "#EEEEEE");
border.width: optionalMessage.activeFocus ? 1 : 0;
border.color: optionalMessage.activeFocus ? hifi.colors.primaryHighlight : hifi.colors.textFieldLightBackground;
border.width: optionalMessage.activeFocus && !optionalMessage.readOnly ? 1 : 0;
border.color: optionalMessage.activeFocus && !optionalMessage.readOnly ? hifi.colors.primaryHighlight : hifi.colors.textFieldLightBackground;
}
color: root.assetName === "" ? hifi.colors.white : hifi.colors.black;
color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.white : hifi.colors.black;
textFormat: TextEdit.PlainText;
wrapMode: TextEdit.Wrap;
activeFocusOnPress: true;
@ -1122,7 +1134,8 @@ Item {
// Text size
size: 16;
// Style
color: optionalMessage.text.length === optionalMessage.maximumLength ? "#ea89a5" : (root.assetName === "" ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight);
color: optionalMessage.text.length === optionalMessage.maximumLength ? "#ea89a5" :
(root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight);
verticalAlignment: Text.AlignTop;
horizontalAlignment: Text.AlignRight;
}
@ -1167,7 +1180,7 @@ Item {
parent.color = hifi.colors.blueAccent;
}
onClicked: {
lightboxPopup.titleText = (root.assetName === "" ? "Send Effect" : "Gift Effect");
lightboxPopup.titleText = (root.assetCertID === "" ? "Send Effect" : "Gift Effect");
lightboxPopup.bodyImageSource = "sendAsset/images/send-money-effect-sm.jpg"; // Path relative to CommerceLightbox.qml
lightboxPopup.bodyText = "Enabling this option will create a particle effect between you and " +
"your recipient that is visible to everyone nearby.";
@ -1196,7 +1209,7 @@ Item {
// "CANCEL" button
HifiControlsUit.Button {
id: cancelButton_sendAssetStep;
color: root.assetName === "" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray;
color: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray;
colorScheme: hifi.colorSchemes.dark;
anchors.right: sendButton.left;
anchors.rightMargin: 24;
@ -1205,8 +1218,12 @@ Item {
width: 100;
text: "CANCEL";
onClicked: {
resetSendAssetData();
root.nextActiveView = "sendAssetHome";
if (sendAssetStep.referrer === "payIn") {
sendToScript({method: "closeSendAsset"});
} else {
resetSendAssetData();
root.nextActiveView = "sendAssetHome";
}
}
}
@ -1214,7 +1231,7 @@ Item {
HifiControlsUit.Button {
id: sendButton;
color: hifi.buttons.blue;
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
anchors.right: parent.right;
anchors.rightMargin: 0;
anchors.verticalCenter: parent.verticalCenter;
@ -1222,11 +1239,11 @@ Item {
width: 100;
text: "SUBMIT";
onClicked: {
if (root.assetName === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) {
if (root.assetCertID === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) {
amountTextField.focus = true;
amountTextField.error = true;
amountTextFieldError.text = "<i>amount exceeds available funds</i>";
} else if (root.assetName === "" && (amountTextField.text === "" || parseInt(amountTextField.text) < 1)) {
} else if (root.assetCertID === "" && (amountTextField.text === "" || parseInt(amountTextField.text) < 1)) {
amountTextField.focus = true;
amountTextField.error = true;
amountTextFieldError.text = "<i>invalid amount</i>";
@ -1236,7 +1253,7 @@ Item {
root.isCurrentlySendingAsset = true;
amountTextField.focus = false;
optionalMessage.focus = false;
if (sendAssetStep.referrer === "connections") {
if (sendAssetStep.referrer === "connections" || sendAssetStep.referrer === "payIn") {
Commerce.transferAssetToUsername(sendAssetStep.selectedRecipientUserName,
root.assetCertID,
parseInt(amountTextField.text),
@ -1317,18 +1334,18 @@ Item {
Rectangle {
anchors.top: parent.top;
anchors.topMargin: root.assetName === "" ? 15 : 125;
anchors.topMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 125;
anchors.left: parent.left;
anchors.leftMargin: root.assetName === "" ? 15 : 50;
anchors.leftMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50;
anchors.right: parent.right;
anchors.rightMargin: root.assetName === "" ? 15 : 50;
anchors.rightMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50;
anchors.bottom: parent.bottom;
anchors.bottomMargin: root.assetName === "" ? 15 : 125;
anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 125;
color: "#FFFFFF";
RalewaySemiBold {
id: paymentSentText;
text: root.assetName === "" ? "Payment Sent" : "Gift Sent";
text: root.assetCertID === "" ? "Payment Sent" : (sendAssetStep.referrer === "payIn" ? "Item Sent" : "Gift Sent");
// Anchors
anchors.top: parent.top;
anchors.topMargin: 26;
@ -1346,7 +1363,7 @@ Item {
HiFiGlyphs {
id: closeGlyphButton_paymentSuccess;
visible: root.assetName === "";
visible: root.assetCertID === "" && sendAssetStep.referrer !== "payIn";
text: hifi.glyphs.close;
color: hifi.colors.lightGrayText;
size: 26;
@ -1364,10 +1381,14 @@ Item {
parent.text = hifi.glyphs.close;
}
onClicked: {
root.nextActiveView = "sendAssetHome";
resetSendAssetData();
if (root.assetName !== "") {
sendSignalToParent({method: "closeSendAsset"});
if (sendAssetStep.referrer === "payIn") {
sendToScript({method: "closeSendAsset"});
} else {
root.nextActiveView = "sendAssetHome";
resetSendAssetData();
if (root.assetName !== "") {
sendSignalToParent({method: "closeSendAsset"});
}
}
}
}
@ -1409,14 +1430,14 @@ Item {
userName: sendAssetStep.selectedRecipientUserName;
profilePic: sendAssetStep.selectedRecipientProfilePic !== "" ? ((0 === sendAssetStep.selectedRecipientProfilePic.indexOf("http")) ?
sendAssetStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendAssetStep.selectedRecipientProfilePic)) : "";
isDisplayingNearby: sendAssetStep.referrer === "nearby";
multiLineDisplay: sendAssetStep.referrer === "nearby" || sendAssetStep.referrer === "payIn";
}
}
Item {
id: giftContainer_paymentSuccess;
visible: root.assetName !== "";
visible: root.assetCertID !== "";
anchors.top: sendToContainer_paymentSuccess.bottom;
anchors.topMargin: 8;
anchors.left: parent.left;
@ -1427,7 +1448,7 @@ Item {
RalewaySemiBold {
id: gift_paymentSuccess;
text: "Gift:";
text: sendAssetStep.referrer === "payIn" ? "Item:" : "Gift:";
// Anchors
anchors.top: parent.top;
anchors.left: parent.left;
@ -1458,7 +1479,7 @@ Item {
Item {
id: amountContainer_paymentSuccess;
visible: root.assetName === "";
visible: root.assetCertID === "";
anchors.top: sendToContainer_paymentSuccess.bottom;
anchors.topMargin: 16;
anchors.left: parent.left;
@ -1513,7 +1534,7 @@ Item {
RalewaySemiBold {
id: optionalMessage_paymentSuccess;
visible: root.assetName === "";
visible: root.assetCertID === "";
text: optionalMessage.text;
// Anchors
anchors.top: amountContainer_paymentSuccess.visible ? amountContainer_paymentSuccess.bottom : sendToContainer_paymentSuccess.bottom;
@ -1535,18 +1556,22 @@ Item {
HifiControlsUit.Button {
id: closeButton;
color: hifi.buttons.blue;
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
anchors.horizontalCenter: parent.horizontalCenter;
anchors.bottom: parent.bottom;
anchors.bottomMargin: root.assetName === "" ? 80 : 30;
anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 80 : 30;
height: 50;
width: 120;
text: "Close";
onClicked: {
root.nextActiveView = "sendAssetHome";
resetSendAssetData();
if (root.assetName !== "") {
sendSignalToParent({method: "closeSendAsset"});
if (sendAssetStep.referrer === "payIn") {
sendToScript({method: "closeSendAsset"});
} else {
root.nextActiveView = "sendAssetHome";
resetSendAssetData();
if (root.assetName !== "") {
sendSignalToParent({method: "closeSendAsset"});
}
}
}
}
@ -1574,18 +1599,18 @@ Item {
Rectangle {
anchors.top: parent.top;
anchors.topMargin: root.assetName === "" ? 15 : 150;
anchors.topMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 150;
anchors.left: parent.left;
anchors.leftMargin: root.assetName === "" ? 15 : 50;
anchors.leftMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50;
anchors.right: parent.right;
anchors.rightMargin: root.assetName === "" ? 15 : 50;
anchors.rightMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 50;
anchors.bottom: parent.bottom;
anchors.bottomMargin: root.assetName === "" ? 15 : 300;
anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 15 : 300;
color: "#FFFFFF";
RalewaySemiBold {
id: paymentFailureText;
text: root.assetName === "" ? "Payment Failed" : "Failed";
text: root.assetCertID === "" && sendAssetStep.referrer !== "payIn" ? "Payment Failed" : "Failed";
// Anchors
anchors.top: parent.top;
anchors.topMargin: 26;
@ -1603,7 +1628,7 @@ Item {
HiFiGlyphs {
id: closeGlyphButton_paymentFailure;
visible: root.assetName === "";
visible: root.assetCertID === "" && sendAssetStep.referrer !== "payIn";
text: hifi.glyphs.close;
color: hifi.colors.lightGrayText;
size: 26;
@ -1632,7 +1657,8 @@ Item {
RalewaySemiBold {
id: paymentFailureDetailText;
text: "The recipient you specified was unable to receive your " + (root.assetName === "" ? "payment." : "gift.");
text: "The recipient you specified was unable to receive your " +
(root.assetCertID === "" ? "payment." : (sendAssetStep.referrer === "payIn" ? "item." : "gift."));
anchors.top: paymentFailureText.bottom;
anchors.topMargin: 20;
anchors.left: parent.left;
@ -1650,7 +1676,7 @@ Item {
Item {
id: sendToContainer_paymentFailure;
visible: root.assetName === "";
visible: root.assetCertID === "" || sendAssetStep.referrer === "payIn";
anchors.top: paymentFailureDetailText.bottom;
anchors.topMargin: 8;
anchors.left: parent.left;
@ -1685,13 +1711,13 @@ Item {
userName: sendAssetStep.selectedRecipientUserName;
profilePic: sendAssetStep.selectedRecipientProfilePic !== "" ? ((0 === sendAssetStep.selectedRecipientProfilePic.indexOf("http")) ?
sendAssetStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendAssetStep.selectedRecipientProfilePic)) : "";
isDisplayingNearby: sendAssetStep.referrer === "nearby";
multiLineDisplay: sendAssetStep.referrer === "nearby" || sendAssetStep.referrer === "payIn";
}
}
Item {
id: amountContainer_paymentFailure;
visible: root.assetName === "";
visible: root.assetCertID === "";
anchors.top: sendToContainer_paymentFailure.bottom;
anchors.topMargin: 16;
anchors.left: parent.left;
@ -1746,7 +1772,7 @@ Item {
RalewaySemiBold {
id: optionalMessage_paymentFailure;
visible: root.assetName === "";
visible: root.assetCertID === "" || sendAssetStep.referrer === "payIn";
text: optionalMessage.text;
// Anchors
anchors.top: amountContainer_paymentFailure.visible ? amountContainer_paymentFailure.bottom : sendToContainer_paymentFailure.bottom;
@ -1768,19 +1794,23 @@ Item {
HifiControlsUit.Button {
id: closeButton_paymentFailure;
color: hifi.buttons.noneBorderless;
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
anchors.right: retryButton_paymentFailure.left;
anchors.rightMargin: 12;
anchors.bottom: parent.bottom;
anchors.bottomMargin: root.assetName === "" ? 80 : 30;
anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 80 : 30;
height: 50;
width: 120;
text: "Cancel";
onClicked: {
root.nextActiveView = "sendAssetHome";
resetSendAssetData();
if (root.assetName !== "") {
sendSignalToParent({method: "closeSendAsset"});
if (sendAssetStep.referrer === "payIn") {
sendToScript({method: "closeSendAsset"});
} else {
root.nextActiveView = "sendAssetHome";
resetSendAssetData();
if (root.assetName !== "") {
sendSignalToParent({method: "closeSendAsset"});
}
}
}
}
@ -1789,17 +1819,17 @@ Item {
HifiControlsUit.Button {
id: retryButton_paymentFailure;
color: hifi.buttons.blue;
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
colorScheme: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
anchors.right: parent.right;
anchors.rightMargin: 12;
anchors.bottom: parent.bottom;
anchors.bottomMargin: root.assetName === "" ? 80 : 30;
anchors.bottomMargin: root.assetCertID === "" || sendAssetStep.referrer === "payIn" ? 80 : 30;
height: 50;
width: 120;
text: "Retry";
onClicked: {
root.isCurrentlySendingAsset = true;
if (sendAssetStep.referrer === "connections") {
if (sendAssetStep.referrer === "connections" || sendAssetStep.referrer === "payIn") {
Commerce.transferAssetToUsername(sendAssetStep.selectedRecipientUserName,
root.assetCertID,
parseInt(amountTextField.text),
@ -1866,11 +1896,32 @@ Item {
case 'updateSelectedRecipientUsername':
sendAssetStep.selectedRecipientUserName = message.userName;
break;
case 'updateSendAssetQML':
root.assetName = "";
root.assetCertID = message.assetCertID || "";
if (root.assetCertID === "") {
amountTextField.text = message.amount || 1;
} else {
amountTextField.text = "";
Commerce.certificateInfo(root.assetCertID);
}
sendAssetStep.referrer = "payIn";
sendAssetStep.selectedRecipientNodeID = "";
sendAssetStep.selectedRecipientDisplayName = "Determined by script:";
sendAssetStep.selectedRecipientUserName = message.username;
optionalMessage.text = message.message || "No Message Provided";
root.nextActiveView = "sendAssetStep";
break;
case 'inspectionCertificate_resetCert':
// NOP
break;
default:
console.log('SendAsset: Unrecognized message from wallet.js');
}
}
signal sendSignalToParent(var msg);
signal sendToScript(var message);
//
// FUNCTION DEFINITIONS END
//

View file

@ -927,7 +927,9 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
#endif
DependencyManager::set<DiscoverabilityManager>();
DependencyManager::set<SceneScriptingInterface>();
#if !defined(DISABLE_QML)
DependencyManager::set<OffscreenUi>();
#endif
DependencyManager::set<Midi>();
DependencyManager::set<PathUtils>();
DependencyManager::set<InterfaceDynamicFactory>();
@ -1000,6 +1002,14 @@ const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false;
const QString DEFAULT_CURSOR_NAME = "DEFAULT";
const bool DEFAULT_MINI_TABLET_ENABLED = true;
QSharedPointer<OffscreenUi> getOffscreenUI() {
#if !defined(DISABLE_QML)
return DependencyManager::get<OffscreenUi>();
#else
return nullptr;
#endif
}
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runningMarkerExisted) :
QApplication(argc, argv),
_window(new MainWindow(desktop())),
@ -1604,7 +1614,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
auto userInputMapper = DependencyManager::get<UserInputMapper>();
connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) {
using namespace controller;
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
{
auto actionEnum = static_cast<Action>(action);
@ -1743,7 +1752,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
return qApp->getMyAvatar()->getCharacterController()->onGround() ? 1 : 0;
});
_applicationStateDevice->setInputVariant(STATE_NAV_FOCUSED, []() -> float {
return DependencyManager::get<OffscreenUi>()->navigationFocused() ? 1 : 0;
auto offscreenUi = getOffscreenUI();
return offscreenUi ? (offscreenUi->navigationFocused() ? 1 : 0) : 0;
});
_applicationStateDevice->setInputVariant(STATE_PLATFORM_WINDOWS, []() -> float {
#if defined(Q_OS_WIN)
@ -1809,9 +1819,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// Now that we've loaded the menu and thus switched to the previous display plugin
// we can unlock the desktop repositioning code, since all the positions will be
// relative to the desktop size for this plugin
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto offscreenUi = getOffscreenUI();
connect(offscreenUi.data(), &OffscreenUi::desktopReady, []() {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto offscreenUi = getOffscreenUI();
auto desktop = offscreenUi->getDesktop();
if (desktop) {
desktop->setProperty("repositionLocked", false);
@ -2372,6 +2382,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(&AndroidHelper::instance(), &AndroidHelper::enterForeground, this, &Application::enterForeground);
AndroidHelper::instance().notifyLoadComplete();
#else
#if !defined(DISABLE_QML)
// Do not show login dialog if requested not to on the command line
const QString HIFI_NO_LOGIN_COMMAND_LINE_KEY = "--no-login-suggestion";
int index = arguments().indexOf(HIFI_NO_LOGIN_COMMAND_LINE_KEY);
@ -2396,6 +2407,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
checkLoginTimer->start();
}
#endif
#endif
}
void Application::updateVerboseLogging() {
@ -2546,7 +2558,9 @@ void Application::onAboutToQuit() {
DependencyManager::get<CloseEventSender>()->startThread();
// Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown.
DependencyManager::get<OffscreenUi>()->hide("RunningScripts");
#if !defined(DISABLE_QML)
getOffscreenUI()->hide("RunningScripts");
#endif
_aboutToQuit = true;
@ -2784,10 +2798,10 @@ void Application::initializeGL() {
_glWidget->windowHandle()->setFormat(getDefaultOpenGLSurfaceFormat());
// When loading QtWebEngineWidgets, it creates a global share context on startup.
// We have to account for this possibility by checking here for an existing
// We have to account for this possibility by checking here for an existing
// global share context
auto globalShareContext = qt_gl_global_share_context();
#if !defined(DISABLE_QML)
// Build a shared canvas / context for the Chromium processes
if (!globalShareContext) {
@ -2974,7 +2988,9 @@ void Application::initializeRenderEngine() {
}
extern void setupPreferences();
#if !defined(DISABLE_QML)
static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, int index, bool active = false);
#endif
void Application::initializeUi() {
AddressBarDialog::registerType();
@ -3024,12 +3040,13 @@ void Application::initializeUi() {
tabletScriptingInterface->getTablet(SYSTEM_TABLET);
}
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto offscreenUi = getOffscreenUI();
connect(offscreenUi.data(), &hifi::qml::OffscreenSurface::rootContextCreated,
this, &Application::onDesktopRootContextCreated);
connect(offscreenUi.data(), &hifi::qml::OffscreenSurface::rootItemCreated,
this, &Application::onDesktopRootItemCreated);
#if !defined(DISABLE_QML)
offscreenUi->setProxyWindow(_window->windowHandle());
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
// support the window management and scripting proxies for VR use
@ -3039,9 +3056,13 @@ void Application::initializeUi() {
// FIXME either expose so that dialogs can set this themselves or
// do better detection in the offscreen UI of what has focus
offscreenUi->setNavigationFocused(false);
#else
_window->setMenuBar(new Menu());
#endif
setupPreferences();
#if !defined(DISABLE_QML)
_glWidget->installEventFilter(offscreenUi.data());
offscreenUi->setMouseTranslator([=](const QPointF& pt) {
QPointF result = pt;
@ -3054,6 +3075,7 @@ void Application::initializeUi() {
return result.toPoint();
});
offscreenUi->resume();
#endif
connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){
resizeGL();
if (_touchscreenVirtualPadDevice) {
@ -3092,6 +3114,7 @@ void Application::initializeUi() {
}
});
#if !defined(DISABLE_QML)
// Pre-create a couple of Web3D overlays to speed up tablet UI
auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
offscreenSurfaceCache->setOnRootContextCreated([&](const QString& rootObject, QQmlContext* surfaceContext) {
@ -3105,9 +3128,11 @@ void Application::initializeUi() {
offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1);
offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
#endif
flushMenuUpdates();
#if !defined(DISABLE_QML)
// Now that the menu is instantiated, ensure the display plugin menu is properly updated
{
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
@ -3126,6 +3151,7 @@ void Application::initializeUi() {
auto parent = getPrimaryMenu()->getMenu(MenuOption::OutputMenu);
parent->addSeparator();
}
#endif
// The display plugins are created before the menu now, so we need to do this here to hide the menu bar
// now that it exists
@ -3230,12 +3256,12 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
Stats::show();
AnimStats::show();
auto surfaceContext = DependencyManager::get<OffscreenUi>()->getSurfaceContext();
auto surfaceContext = getOffscreenUI()->getSurfaceContext();
surfaceContext->setContextProperty("Stats", Stats::getInstance());
surfaceContext->setContextProperty("AnimStats", AnimStats::getInstance());
#if !defined(Q_OS_ANDROID)
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto offscreenUi = getOffscreenUI();
auto qml = PathUtils::qmlUrl("AvatarInputsBar.qml");
offscreenUi->show(qml, "AvatarInputsBar");
#endif
@ -3418,7 +3444,7 @@ void Application::setPreferredCursor(const QString& cursorName) {
void Application::setSettingConstrainToolbarPosition(bool setting) {
_constrainToolbarPosition.set(setting);
DependencyManager::get<OffscreenUi>()->setConstrainToolbarToCenterX(setting);
getOffscreenUI()->setConstrainToolbarToCenterX(setting);
}
void Application::setMiniTabletEnabled(bool enabled) {
@ -3512,7 +3538,9 @@ void Application::resizeGL() {
_myCamera.loadViewFrustum(_viewFrustum);
}
DependencyManager::get<OffscreenUi>()->resize(fromGlm(displayPlugin->getRecommendedUiSize()));
#if !defined(DISABLE_QML)
getOffscreenUI()->resize(fromGlm(displayPlugin->getRecommendedUiSize()));
#endif
}
void Application::handleSandboxStatus(QNetworkReply* reply) {
@ -3912,10 +3940,12 @@ bool Application::eventFilter(QObject* object, QEvent* event) {
}
if (event->type() == QEvent::ShortcutOverride) {
if (DependencyManager::get<OffscreenUi>()->shouldSwallowShortcut(event)) {
#if !defined(DISABLE_QML)
if (getOffscreenUI()->shouldSwallowShortcut(event)) {
event->accept();
return true;
}
#endif
// Filter out captured keys before they're used for shortcut actions.
if (_controllerScriptingInterface->isKeyCaptured(static_cast<QKeyEvent*>(event))) {
@ -3998,7 +4028,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_X:
if (isShifted && isMeta) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto offscreenUi = getOffscreenUI();
offscreenUi->togglePinned();
//offscreenUi->getSurfaceContext()->engine()->clearComponentCache();
//OffscreenUi::information("Debugging", "Component cache cleared");
@ -4014,7 +4044,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_B:
if (isMeta) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto offscreenUi = getOffscreenUI();
offscreenUi->load("Browser.qml");
} else if (isOption) {
controller::InputRecorder* inputRecorder = controller::InputRecorder::getInstance();
@ -4036,7 +4066,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_R:
if (isMeta && !event->isAutoRepeat()) {
DependencyManager::get<ScriptEngines>()->reloadAllScripts();
DependencyManager::get<OffscreenUi>()->clearCache();
getOffscreenUI()->clearCache();
}
break;
@ -4233,9 +4263,13 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
return; // bail
}
auto offscreenUi = DependencyManager::get<OffscreenUi>();
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
auto eventPosition = compositor.getMouseEventPosition(event);
QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition);
QPointF transformedPos = offscreenUi ? offscreenUi->mapToVirtualScreen(eventPosition) : QPointF();
#else
QPointF transformedPos;
#endif
auto button = event->button();
auto buttons = event->buttons();
// Determine if the ReticleClick Action is 1 and if so, fake include the LeftMouseButton
@ -4273,7 +4307,8 @@ void Application::mousePressEvent(QMouseEvent* event) {
// Inhibit the menu if the user is using alt-mouse dragging
_altPressed = false;
auto offscreenUi = DependencyManager::get<OffscreenUi>();
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
// If we get a mouse press event it means it wasn't consumed by the offscreen UI,
// hence, we should defocus all of the offscreen UI windows, in order to allow
// keyboard shortcuts not to be swallowed by them. In particular, WebEngineViews
@ -4282,6 +4317,9 @@ void Application::mousePressEvent(QMouseEvent* event) {
auto eventPosition = getApplicationCompositor().getMouseEventPosition(event);
QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition);
#else
QPointF transformedPos;
#endif
QMouseEvent mappedEvent(event->type(),
transformedPos,
event->screenPos(), event->button(),
@ -4318,9 +4356,13 @@ void Application::mousePressEvent(QMouseEvent* event) {
}
void Application::mouseDoublePressEvent(QMouseEvent* event) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
auto eventPosition = getApplicationCompositor().getMouseEventPosition(event);
QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition);
#else
QPointF transformedPos;
#endif
QMouseEvent mappedEvent(event->type(),
transformedPos,
event->screenPos(), event->button(),
@ -4341,9 +4383,13 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) {
void Application::mouseReleaseEvent(QMouseEvent* event) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
auto eventPosition = getApplicationCompositor().getMouseEventPosition(event);
QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition);
#else
QPointF transformedPos;
#endif
QMouseEvent mappedEvent(event->type(),
transformedPos,
event->screenPos(), event->button(),
@ -4739,7 +4785,8 @@ void Application::idle() {
// Update the deadlock watchdog
updateHeartbeat();
auto offscreenUi = DependencyManager::get<OffscreenUi>();
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
// These tasks need to be done on our first idle, because we don't want the showing of
// overlay subwindows to do a showDesktop() until after the first time through
@ -4748,6 +4795,7 @@ void Application::idle() {
firstIdle = false;
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
}
#endif
#ifdef Q_OS_WIN
// If tracing is enabled then monitor the CPU in a separate thread
@ -4764,6 +4812,7 @@ void Application::idle() {
#endif
auto displayPlugin = getActiveDisplayPlugin();
#if !defined(DISABLE_QML)
if (displayPlugin) {
auto uiSize = displayPlugin->getRecommendedUiSize();
// Bit of a hack since there's no device pixel ratio change event I can find.
@ -4772,6 +4821,7 @@ void Application::idle() {
offscreenUi->resize(fromGlm(uiSize));
}
}
#endif
if (displayPlugin) {
PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
@ -4806,6 +4856,7 @@ void Application::idle() {
float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND;
_lastTimeUpdated.start();
#if !defined(DISABLE_QML)
// If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus.
if (offscreenUi && offscreenUi->getWindow()) {
auto activeFocusItem = offscreenUi->getWindow()->activeFocusItem();
@ -4817,9 +4868,11 @@ void Application::idle() {
_keyboardDeviceHasFocus = true;
}
}
#endif
checkChangeCursor();
#if !defined(DISABLE_QML)
auto stats = Stats::getInstance();
if (stats) {
stats->updateStats();
@ -4828,6 +4881,7 @@ void Application::idle() {
if (animStats) {
animStats->updateStats();
}
#endif
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
@ -5163,7 +5217,9 @@ QVector<EntityItemID> Application::pasteEntities(float x, float y, float z) {
void Application::init() {
// Make sure Login state is up to date
#if !defined(DISABLE_QML)
DependencyManager::get<DialogsManager>()->toggleLoginDialog();
#endif
if (!DISABLE_DEFERRED) {
DependencyManager::get<DeferredLightingEffect>()->init();
}
@ -6702,8 +6758,9 @@ void Application::nodeActivated(SharedNodePointer node) {
if (node->getType() == NodeType::AssetServer) {
// asset server just connected - check if we have the asset browser showing
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto assetDialog = offscreenUi->getRootItem()->findChild<QQuickItem*>("AssetServer");
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
auto assetDialog = offscreenUi ? offscreenUi->getRootItem()->findChild<QQuickItem*>("AssetServer") : nullptr;
if (assetDialog) {
auto nodeList = DependencyManager::get<NodeList>();
@ -6716,6 +6773,7 @@ void Application::nodeActivated(SharedNodePointer node) {
assetDialog->setVisible(false);
}
}
#endif
}
// If we get a new EntityServer activated, reset lastQueried time
@ -6773,13 +6831,15 @@ void Application::nodeKilled(SharedNodePointer node) {
} else if (node->getType() == NodeType::AssetServer) {
// asset server going away - check if we have the asset browser showing
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto assetDialog = offscreenUi->getRootItem()->findChild<QQuickItem*>("AssetServer");
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
auto assetDialog = offscreenUi ? offscreenUi->getRootItem()->findChild<QQuickItem*>("AssetServer") : nullptr;
if (assetDialog) {
// call reload on the shown asset browser dialog
QMetaObject::invokeMethod(assetDialog, "clear");
}
#endif
}
}
@ -6886,8 +6946,10 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue,
RayToOverlayIntersectionResultFromScriptValue);
scriptEngine->registerGlobalObject("OffscreenFlags", DependencyManager::get<OffscreenUi>()->getFlags());
#if !defined(DISABLE_QML)
scriptEngine->registerGlobalObject("OffscreenFlags", getOffscreenUI()->getFlags());
scriptEngine->registerGlobalObject("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
#endif
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<ToolbarProxy>, wrapperFromScriptValue<ToolbarProxy>);
qScriptRegisterMetaType(scriptEngine.data(),
@ -6913,14 +6975,16 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
bool clientScript = scriptEngine->isClientScript();
scriptEngine->registerFunction("OverlayWindow", clientScript ? QmlWindowClass::constructor : QmlWindowClass::restricted_constructor);
#if !defined(Q_OS_ANDROID)
#if !defined(Q_OS_ANDROID) && !defined(DISABLE_QML)
scriptEngine->registerFunction("OverlayWebWindow", clientScript ? QmlWebWindowClass::constructor : QmlWebWindowClass::restricted_constructor);
#endif
scriptEngine->registerFunction("QmlFragment", clientScript ? QmlFragmentClass::constructor : QmlFragmentClass::restricted_constructor);
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("DesktopPreviewProvider", DependencyManager::get<DesktopPreviewProvider>().data());
#if !defined(DISABLE_QML)
scriptEngine->registerGlobalObject("Stats", Stats::getInstance());
#endif
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("Snapshot", DependencyManager::get<Snapshot>().data());
scriptEngine->registerGlobalObject("AudioStats", DependencyManager::get<AudioClient>()->getStats().data());
@ -7116,7 +7180,7 @@ bool Application::askToSetAvatarUrl(const QString& url) {
qCDebug(interfaceapp) << "Declined to agree to avatar license";
}
//auto offscreenUi = DependencyManager::get<OffscreenUi>();
//auto offscreenUi = getOffscreenUI();
});
} else {
setAvatar(url, modelName);
@ -7314,7 +7378,9 @@ void Application::showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const
toggleTabletUI(true);
}
} else {
DependencyManager::get<OffscreenUi>()->show(widgetUrl, name);
#if !defined(DISABLE_QML)
getOffscreenUI()->show(widgetUrl, name);
#endif
}
}
@ -7339,10 +7405,10 @@ void Application::showAssetServerWidget(QString filePath) {
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet(SYSTEM_TABLET));
auto hmd = DependencyManager::get<HMDScriptingInterface>();
if (tablet->getToolbarMode()) {
DependencyManager::get<OffscreenUi>()->show(url, "AssetServer", startUpload);
getOffscreenUI()->show(url, "AssetServer", startUpload);
} else {
if (!hmd->getShouldShowTablet() && !isHMDMode()) {
DependencyManager::get<OffscreenUi>()->show(url, "AssetServer", startUpload);
getOffscreenUI()->show(url, "AssetServer", startUpload);
} else {
static const QUrl url("hifi/dialogs/TabletAssetServer.qml");
if (!tablet->isPathLoaded(url)) {
@ -7697,7 +7763,7 @@ void Application::addAssetToWorldInfo(QString modelName, QString infoText) {
if (!_addAssetToWorldErrorTimer.isActive()) {
if (!_addAssetToWorldMessageBox) {
_addAssetToWorldMessageBox = DependencyManager::get<OffscreenUi>()->createMessageBox(OffscreenUi::ICON_INFORMATION,
_addAssetToWorldMessageBox = getOffscreenUI()->createMessageBox(OffscreenUi::ICON_INFORMATION,
"Downloading Model", "", QMessageBox::NoButton, QMessageBox::NoButton);
connect(_addAssetToWorldMessageBox, SIGNAL(destroyed()), this, SLOT(onAssetToWorldMessageBoxClosed()));
}
@ -7780,7 +7846,7 @@ void Application::addAssetToWorldError(QString modelName, QString errorText) {
addAssetToWorldInfoClear(modelName);
if (!_addAssetToWorldMessageBox) {
_addAssetToWorldMessageBox = DependencyManager::get<OffscreenUi>()->createMessageBox(OffscreenUi::ICON_INFORMATION,
_addAssetToWorldMessageBox = getOffscreenUI()->createMessageBox(OffscreenUi::ICON_INFORMATION,
"Downloading Model", "", QMessageBox::NoButton, QMessageBox::NoButton);
connect(_addAssetToWorldMessageBox, SIGNAL(destroyed()), this, SLOT(onAssetToWorldMessageBoxClosed()));
}
@ -8274,6 +8340,8 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const {
return _displayPlugin;
}
#if !defined(DISABLE_QML)
static const char* EXCLUSION_GROUP_KEY = "exclusionGroup";
static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, int index, bool active) {
@ -8314,6 +8382,7 @@ static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, in
action->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(displayPluginGroup));
Q_ASSERT(menu->menuItemExists(MenuOption::OutputMenu, name));
}
#endif
void Application::updateDisplayMode() {
// Unsafe to call this method from anything but the main thread
@ -8358,8 +8427,8 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
// instead emit a signal that the display plugin is changing and let
// the desktop lock itself. Reduces coupling between the UI and display
// plugins
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto desktop = offscreenUi->getDesktop();
auto offscreenUi = getOffscreenUI();
auto desktop = offscreenUi ? offscreenUi->getDesktop() : nullptr;
auto menu = Menu::getInstance();
// Make the switch atomic from the perspective of other threads
@ -8405,7 +8474,9 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
}
}
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
if (offscreenUi) {
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
}
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
_displayPlugin = newDisplayPlugin;
connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent, Qt::DirectConnection);

View file

@ -156,12 +156,14 @@ void Application::paintGL() {
renderArgs._blitFramebuffer.reset();
renderArgs._context->enableStereo(false);
#if !defined(DISABLE_QML)
{
auto stats = Stats::getInstance();
if (stats) {
stats->setRenderDetails(renderArgs._details);
}
}
#endif
uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
_frameTimingsScriptingInterface.addValue(lastPaintDuration);

View file

@ -48,7 +48,9 @@ void ConnectionMonitor::init() {
emit setRedirectErrorState(REDIRECT_HIFI_ADDRESS, "", 5);
} else {
qDebug() << "ConnectionMonitor: Showing connection failure window";
#if !defined(DISABLE_QML)
DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(true);
#endif
}
});
}
@ -59,8 +61,10 @@ void ConnectionMonitor::startTimer() {
void ConnectionMonitor::stopTimer() {
_timer.stop();
#if !defined(DISABLE_QML)
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
if (!enableInterstitial) {
DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(false);
}
#endif
}

View file

@ -83,7 +83,9 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
// Now render the overlay components together into a single texture
renderDomainConnectionStatusBorder(renderArgs); // renders the connected domain line
renderOverlays(renderArgs); // renders Scripts Overlay and AudioScope
#if !defined(DISABLE_QML)
renderQmlUi(renderArgs); // renders a unit quad with the QML UI texture, and the text overlays from scripts
#endif
});
renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch

View file

@ -60,7 +60,7 @@ static const float MALLET_TOUCH_Y_OFFSET = 0.050f;
static const float MALLET_Y_OFFSET = 0.160f;
static const glm::quat MALLET_ROTATION_OFFSET{0.70710678f, 0.0f, -0.70710678f, 0.0f};
static const glm::vec3 MALLET_MODEL_DIMENSIONS{0.03f, MALLET_LENGTH, 0.03f};
static const glm::vec3 MALLET_MODEL_DIMENSIONS{0.01f, MALLET_LENGTH, 0.01f};
static const glm::vec3 MALLET_POSITION_OFFSET{0.0f, -MALLET_Y_OFFSET / 2.0f, 0.0f};
static const glm::vec3 MALLET_TIP_OFFSET{0.0f, MALLET_LENGTH - MALLET_TOUCH_Y_OFFSET, 0.0f};

View file

@ -74,6 +74,7 @@ void OverlayConductor::centerUI() {
}
void OverlayConductor::update(float dt) {
#if !defined(DISABLE_QML)
auto offscreenUi = DependencyManager::get<OffscreenUi>();
if (!offscreenUi) {
return;
@ -115,4 +116,5 @@ void OverlayConductor::update(float dt) {
if (shouldRecenter && !_suppressedByHead) {
centerUI();
}
#endif
}

View file

@ -25,8 +25,10 @@ private:
bool headOutsideOverlay() const;
bool updateAvatarIsAtRest();
#if !defined(DISABLE_QML)
bool _suppressedByHead { false };
bool _hmdMode { false };
#endif
// used by updateAvatarIsAtRest
uint64_t _desiredAtRestTimer { 0 };

View file

@ -232,11 +232,15 @@ OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties)
*/
if (type == ImageOverlay::TYPE) {
#if !defined(DISABLE_QML)
thisOverlay = Overlay::Pointer(new ImageOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
#endif
} else if (type == Image3DOverlay::TYPE || type == "billboard") { // "billboard" for backwards compatibility
thisOverlay = Overlay::Pointer(new Image3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
} else if (type == TextOverlay::TYPE) {
#if !defined(DISABLE_QML)
thisOverlay = Overlay::Pointer(new TextOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
#endif
} else if (type == Text3DOverlay::TYPE) {
thisOverlay = Overlay::Pointer(new Text3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
} else if (type == Shape3DOverlay::TYPE) {

View file

@ -223,8 +223,8 @@ void SunSkyStage::setSunDirection(const Vec3& direction) {
}
}
// THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun
double evalSunDeclinaison(double dayNumber) {
// The sun declination calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun
double evalSunDeclination(double dayNumber) {
return -(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(dayNumber + 10.0)));
}
@ -235,8 +235,8 @@ void SunSkyStage::updateGraphicsObject() const {
float sunLongitude = _earthSunModel.getLongitude() + (MAX_LONGITUDE * signedNormalizedDayTime);
_earthSunModel.setSunLongitude(sunLongitude);
// And update the sunLAtitude as the declinaison depending of the time of the year
_earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime));
// And update the sunLatitude as the declination depending of the time of the year
_earthSunModel.setSunLatitude(evalSunDeclination(_yearTime));
if (isSunModelEnabled()) {
Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir();

View file

@ -134,6 +134,7 @@ void SendQueue::stop() {
}
int SendQueue::sendPacket(const Packet& packet) {
_lastPacketSentAt = std::chrono::high_resolution_clock::now();
return _socket->writeDatagram(packet.getData(), packet.getDataSize(), _destination);
}
@ -501,12 +502,31 @@ bool SendQueue::isInactive(bool attemptedToSendPacket) {
// We think the client is still waiting for data (based on the sequence number gap)
// Let's wait either for a response from the client or until the estimated timeout
// (plus the sync interval to allow the client to respond) has elapsed
auto waitDuration = std::chrono::microseconds(_estimatedTimeout + _syncInterval);
auto estimatedTimeout = std::chrono::microseconds(_estimatedTimeout);
// cap our maximum estimated timeout to the already unreasonable 5 seconds
const auto MAXIMUM_ESTIMATED_TIMEOUT = std::chrono::seconds(5);
if (estimatedTimeout > MAXIMUM_ESTIMATED_TIMEOUT) {
estimatedTimeout = MAXIMUM_ESTIMATED_TIMEOUT;
}
// use our condition_variable_any to wait
auto cvStatus = _emptyCondition.wait_for(locker, waitDuration);
if (cvStatus == std::cv_status::timeout && (_packets.isEmpty() || isFlowWindowFull()) && _naks.isEmpty()
auto cvStatus = _emptyCondition.wait_for(locker, estimatedTimeout);
// when we wake-up check if we're "stuck" either if we've slept for the estimated timeout
// or it has been that long since the last time we sent a packet
// we are stuck if all of the following are true
// - there are no new packets to send or the flow window is full and we can't send any new packets
// - there are no packets to resend
// - the client has yet to ACK some sent packets
auto now = std::chrono::high_resolution_clock::now();
if ((cvStatus == std::cv_status::timeout || (now - _lastPacketSentAt > estimatedTimeout))
&& (_packets.isEmpty() || isFlowWindowFull())
&& _naks.isEmpty()
&& SequenceNumber(_lastACKSequenceNumber) < _currentSequenceNumber) {
// after a timeout if we still have sent packets that the client hasn't ACKed we
// add them to the loss list

View file

@ -68,7 +68,6 @@ public:
void setPacketSendPeriod(int newPeriod) { _packetSendPeriod = newPeriod; }
void setEstimatedTimeout(int estimatedTimeout) { _estimatedTimeout = estimatedTimeout; }
void setSyncInterval(int syncInterval) { _syncInterval = syncInterval; }
public slots:
void stop();
@ -124,7 +123,6 @@ private:
std::atomic<State> _state { State::NotStarted };
std::atomic<int> _estimatedTimeout { 0 }; // Estimated timeout, set from CC
std::atomic<int> _syncInterval { udt::DEFAULT_SYN_INTERVAL_USECS }; // Sync interval, set from CC
std::atomic<int> _flowWindowSize { 0 }; // Flow control window size (number of packets that can be on wire) - set from CC
@ -140,6 +138,8 @@ private:
std::condition_variable _handshakeACKCondition;
std::condition_variable_any _emptyCondition;
std::chrono::high_resolution_clock::time_point _lastPacketSentAt;
};
}

View file

@ -191,7 +191,6 @@ void ScriptEngines::shutdownScripting() {
// Gracefully stop the engine's scripting thread
scriptEngine->stop();
removeScriptEngine(scriptEngine);
// We need to wait for the engine to be done running before we proceed, because we don't
// want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing
@ -370,13 +369,10 @@ QStringList ScriptEngines::getRunningScripts() {
}
void ScriptEngines::stopAllScripts(bool restart) {
QVector<QString> toReload;
QReadLocker lock(&_scriptEnginesHashLock);
if (_isReloading) {
return;
} else {
_isReloading = true;
}
for (QHash<QUrl, ScriptEnginePointer>::const_iterator it = _scriptEnginesHash.constBegin();
@ -389,29 +385,27 @@ void ScriptEngines::stopAllScripts(bool restart) {
// queue user scripts if restarting
if (restart && scriptEngine->isUserLoaded()) {
toReload << it.key().toString();
_isReloading = true;
bool lastScript = (it == _scriptEnginesHash.constEnd() - 1);
ScriptEngine::Type type = scriptEngine->getType();
connect(scriptEngine.data(), &ScriptEngine::finished, this, [this, type, lastScript] (QString scriptName) {
reloadScript(scriptName, true)->setType(type);
if (lastScript) {
_isReloading = false;
}
});
}
// stop all scripts
scriptEngine->stop();
removeScriptEngine(scriptEngine);
}
// wait for engines to stop (ie: providing time for .scriptEnding cleanup handlers to run) before
// triggering reload of any Client scripts / Entity scripts
QTimer::singleShot(1000, this, [=]() {
for(const auto &scriptName : toReload) {
auto scriptEngine = getScriptEngine(scriptName);
if (scriptEngine && !scriptEngine->isFinished()) {
scriptEngine->waitTillDoneRunning();
}
reloadScript(scriptName);
}
if (restart) {
qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";
emit scriptsReloading();
}
_isReloading = false;
});
if (restart) {
qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";
emit scriptsReloading();
}
}
bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) {
@ -439,7 +433,6 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) {
}
}
scriptEngine->stop();
removeScriptEngine(scriptEngine);
stoppedScript = true;
}
}

View file

@ -27,16 +27,16 @@
class Dependency {
public:
typedef std::function<void(Dependency* pointer)> DeleterFunction;
protected:
virtual ~Dependency() {}
virtual void customDeleter() {
_customDeleter(this);
}
void setCustomDeleter(DeleterFunction customDeleter) { _customDeleter = customDeleter; }
DeleterFunction _customDeleter = [](Dependency* pointer) { delete pointer; };
friend class DependencyManager;
};
@ -49,10 +49,10 @@ class DependencyManager {
public:
template<typename T>
static QSharedPointer<T> get();
template<typename T>
static bool isSet();
template<typename T, typename ...Args>
static QSharedPointer<T> set(Args&&... args);
@ -61,10 +61,10 @@ public:
template<typename T>
static void destroy();
template<typename Base, typename Derived>
static void registerInheritance();
template <typename T>
static size_t typeHash() {
#ifdef Q_OS_ANDROID
@ -79,9 +79,9 @@ private:
template<typename T>
size_t getHashCode();
QSharedPointer<Dependency>& safeGet(size_t hashCode);
QHash<size_t, QSharedPointer<Dependency>> _instanceHash;
QHash<size_t, size_t> _inheritanceHash;
};
@ -90,15 +90,17 @@ template <typename T>
QSharedPointer<T> DependencyManager::get() {
static size_t hashCode = manager().getHashCode<T>();
static QWeakPointer<T> instance;
if (instance.isNull()) {
instance = qSharedPointerCast<T>(manager().safeGet(hashCode));
#ifndef QT_NO_DEBUG
if (instance.isNull()) {
qWarning() << "DependencyManager::get(): No instance available for" << typeid(T).name();
}
#endif
}
return instance.toStrongRef();
}
@ -159,12 +161,12 @@ template<typename T>
size_t DependencyManager::getHashCode() {
size_t hashCode = typeHash<T>();
auto derivedHashCode = _inheritanceHash.find(hashCode);
while (derivedHashCode != _inheritanceHash.end()) {
hashCode = derivedHashCode.value();
derivedHashCode = _inheritanceHash.find(hashCode);
}
return hashCode;
}

View file

@ -616,7 +616,9 @@ bool OffscreenUi::navigationFocused() {
}
void OffscreenUi::setNavigationFocused(bool focused) {
offscreenFlags->setNavigationFocused(focused);
if (offscreenFlags) {
offscreenFlags->setNavigationFocused(focused);
}
}
// FIXME HACK....

View file

@ -422,9 +422,11 @@ void Menu::removeMenu(const QString& menuName) {
} else {
QMenuBar::removeAction(action);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->removeAction(action);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->removeAction(action);
});
}
}
QMenuBar::repaint();
@ -532,9 +534,11 @@ void Menu::setGroupingIsVisible(const QString& grouping, bool isVisible) {
MenuWrapper::MenuWrapper(ui::Menu& rootMenu, QMenu* menu) : _rootMenu(rootMenu), _realMenu(menu) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addMenu(menu);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addMenu(menu);
});
}
_rootMenu._backMap[menu] = this;
}
@ -553,50 +557,62 @@ void MenuWrapper::setEnabled(bool enabled) {
QAction* MenuWrapper::addSeparator() {
QAction* action = _realMenu->addSeparator();
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addSeparator(_realMenu);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addSeparator(_realMenu);
});
}
return action;
}
void MenuWrapper::addAction(QAction* action) {
_realMenu->addAction(action);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
}
}
QAction* MenuWrapper::addAction(const QString& menuName) {
QAction* action = _realMenu->addAction(menuName);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
}
return action;
}
QAction* MenuWrapper::addAction(const QString& menuName, const QObject* receiver, const char* member, const QKeySequence& shortcut) {
QAction* action = _realMenu->addAction(menuName, receiver, member, shortcut);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
}
return action;
}
void MenuWrapper::removeAction(QAction* action) {
_realMenu->removeAction(action);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->removeAction(action);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->removeAction(action);
});
}
}
void MenuWrapper::insertAction(QAction* before, QAction* action) {
_realMenu->insertAction(before, action);
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->insertAction(before, action);
});
if (offscreenUi) {
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
vrMenu->insertAction(before, action);
});
}
}

View file

@ -366,6 +366,7 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
if (toolbarMode) {
#if !defined(DISABLE_QML)
// create new desktop window
auto tabletRootWindow = new TabletRootWindow();
tabletRootWindow->initQml(QVariantMap());
@ -379,6 +380,7 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
// forward qml surface events to interface js
connect(tabletRootWindow, &QmlWindowClass::fromQml, this, &TabletProxy::fromQml);
#endif
} else {
if (_currentPathLoaded != TABLET_HOME_SOURCE_URL) {
loadHomeScreen(true);

View file

@ -83,12 +83,17 @@ class VcpkgRepo:
self.sourcePortsPath = os.path.join(scriptPath, 'cmake', 'ports')
# FIXME Revert to ports hash before release
self.id = hashFolder(self.sourcePortsPath)[:8]
# OS dependent information
system = platform.system()
if args.vcpkg_root is not None:
print("override vcpkg path with " + args.vcpkg_root)
self.path = args.vcpkg_root
else:
defaultBasePath = os.path.join(tempfile.gettempdir(), 'hifi', 'vcpkg')
if 'Darwin' == system:
defaultBasePath = os.path.expanduser('~/hifi/vcpkg')
else:
defaultBasePath = os.path.join(tempfile.gettempdir(), 'hifi', 'vcpkg')
basePath = os.getenv('HIFI_VCPKG_BASE', defaultBasePath)
if (not os.path.isdir(basePath)):
os.makedirs(basePath)
@ -101,8 +106,6 @@ class VcpkgRepo:
self.tagContents = "{}_{}".format(self.id, self.version)
print("prebuild path: " + self.path)
# OS dependent information
system = platform.system()
if 'Windows' == system:
self.exe = os.path.join(self.path, 'vcpkg.exe')
self.vcpkgUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/vcpkg-win32.tar.gz?versionId=YZYkDejDRk7L_hrK_WVFthWvisAhbDzZ'

View file

@ -539,6 +539,9 @@ function fromQml(message) {
case 'http.request':
// Handled elsewhere, don't log.
break;
case 'closeSendAsset':
ui.close();
break;
default:
print('wallet.js: Unrecognized message from QML');
}
@ -663,6 +666,7 @@ function uninstallMarketplaceItemTester() {
var BUTTON_NAME = "INVENTORY";
var WALLET_QML_SOURCE = "hifi/commerce/wallet/Wallet.qml";
var SENDASSET_QML_SOURCE = "hifi/commerce/common/sendAsset/SendAsset.qml";
var NOTIFICATION_POLL_TIMEOUT = 300000;
var ui;
function startup() {
@ -686,6 +690,7 @@ function startup() {
buttonName: BUTTON_NAME,
sortOrder: 10,
home: WALLET_QML_SOURCE,
additionalAppScreens: SENDASSET_QML_SOURCE,
onOpened: walletOpened,
onClosed: walletClosed,
onMessage: fromQml,

View file

@ -219,17 +219,12 @@
});
}
function buyButtonClicked(id, name, author, price, href, referrer, edition, type) {
function buyButtonClicked(id, referrer, edition) {
EventBridge.emitWebEvent(JSON.stringify({
type: "CHECKOUT",
itemId: id,
itemName: name,
itemPrice: price ? parseInt(price, 10) : 0,
itemHref: href,
referrer: referrer,
itemAuthor: author,
itemEdition: edition,
itemType: type.trim()
itemEdition: edition
}));
}
@ -313,13 +308,8 @@
return false;
}
buyButtonClicked($(this).closest('.grid-item').attr('data-item-id'),
$(this).closest('.grid-item').find('.item-title').text(),
$(this).closest('.grid-item').find('.creator').find('.value').text(),
$(this).closest('.grid-item').find('.item-cost').text(),
$(this).attr('data-href'),
"mainPage",
-1,
$(this).closest('.grid-item').find('.item-type').text());
-1);
});
}
@ -427,13 +417,8 @@
purchaseButton.on('click', function () {
if ('available' === availability || isUpdating) {
buyButtonClicked(window.location.pathname.split("/")[3],
$('#top-center').find('h1').text(),
$('#creator').find('.value').text(),
cost,
href,
"itemPage",
urlParams.get('edition'),
type);
urlParams.get('edition'));
}
});
}

View file

@ -471,7 +471,7 @@ function onWebEventReceived(message) {
wireQmlEventBridge(true);
ui.open(MARKETPLACE_CHECKOUT_QML_PATH);
ui.tablet.sendToQml({
method: 'updateCheckoutQML',
method: 'updateCheckoutQMLItemID',
params: message
});
} else if (message.type === "REQUEST_SETTING") {
@ -649,8 +649,8 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
case 'purchases_openGoTo':
case 'purchases_itemInfoClicked':
case 'purchases_itemCertificateClicked':
case 'clearShouldShowDotHistory':
case 'giftAsset':
case 'clearShouldShowDotHistory':
case 'giftAsset':
break;
default:
print('marketplaces.js: Unrecognized message from Checkout.qml');

View file

@ -39,9 +39,9 @@ p_hfudt.fields = {
local control_types = {
[0] = { "ACK", "Acknowledgement" },
[5] = { "Handshake", "Handshake" },
[6] = { "HandshakeACK", "Acknowledgement of Handshake" },
[8] = { "HandshakeRequest", "Request a Handshake" }
[1] = { "Handshake", "Handshake" },
[2] = { "HandshakeACK", "Acknowledgement of Handshake" },
[3] = { "HandshakeRequest", "Request a Handshake" }
}
local message_positions = {