fix merge issues

This commit is contained in:
Dante Ruiz 2017-04-06 22:31:47 +01:00
commit a89081601c
30 changed files with 565 additions and 450 deletions

View file

@ -1,5 +1,5 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.2 import QtQuick.Controls 1.4
import QtWebChannel 1.0 import QtWebChannel 1.0
import QtWebEngine 1.2 import QtWebEngine 1.2
@ -7,7 +7,7 @@ import "controls"
import "styles" as HifiStyles import "styles" as HifiStyles
import "styles-uit" import "styles-uit"
import "windows" import "windows"
import HFWebEngineProfile 1.0 import HFTabletWebEngineProfile 1.0
Item { Item {
id: root id: root
@ -27,138 +27,103 @@ Item {
x: 0 x: 0
y: 0 y: 0
function goBack() {
webview.goBack();
}
function goForward() {
webview.goForward();
}
function gotoPage(url) {
webview.url = url;
}
function setProfile(profile) { function setProfile(profile) {
webview.profile = profile; webview.profile = profile;
} }
function reloadPage() { QtObject {
webview.reloadAndBypassCache(); id: eventBridgeWrapper
webview.setActiveFocusOnPress(true); WebChannel.id: "eventBridgeWrapper"
webview.setEnabled(true); property var eventBridge;
} }
Item { WebEngineView {
id:item id: webview
objectName: "webEngineView"
x: 0
y: 0
width: parent.width width: parent.width
implicitHeight: parent.height height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height
profile: HFTabletWebEngineProfile {
QtObject { id: webviewTabletProfile
id: eventBridgeWrapper storageName: "qmlTabletWebEngine"
WebChannel.id: "eventBridgeWrapper"
property var eventBridge;
} }
WebEngineView { property string userScriptUrl: ""
id: webview
objectName: "webEngineView"
x: 0
y: 0
width: parent.width
height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height
profile: HFWebEngineProfile {
id: webviewProfile
storageName: "qmlWebEngine"
}
property string userScriptUrl: "" // creates a global EventBridge object.
WebEngineScript {
// creates a global EventBridge object. id: createGlobalEventBridge
WebEngineScript { sourceCode: eventBridgeJavaScriptToInject
id: createGlobalEventBridge injectionPoint: WebEngineScript.DocumentCreation
sourceCode: eventBridgeJavaScriptToInject worldId: WebEngineScript.MainWorld
injectionPoint: WebEngineScript.DocumentCreation }
worldId: WebEngineScript.MainWorld
}
// detects when to raise and lower virtual keyboard
WebEngineScript {
id: raiseAndLowerKeyboard
injectionPoint: WebEngineScript.Deferred
sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
worldId: WebEngineScript.MainWorld
}
// User script.
WebEngineScript {
id: userScript
sourceUrl: webview.userScriptUrl
injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished.
worldId: WebEngineScript.MainWorld
}
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] // detects when to raise and lower virtual keyboard
WebEngineScript {
property string newUrl: "" id: raiseAndLowerKeyboard
injectionPoint: WebEngineScript.Deferred
webChannel.registeredObjects: [eventBridgeWrapper] sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
worldId: WebEngineScript.MainWorld
}
Component.onCompleted: { // User script.
// Ensure the JS from the web-engine makes it to our logging WebEngineScript {
webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { id: userScript
console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); sourceUrl: webview.userScriptUrl
}); injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished.
worldId: WebEngineScript.MainWorld
webview.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface"; }
web.address = url;
}
onFeaturePermissionRequested: {
grantFeaturePermission(securityOrigin, feature, true);
}
onLoadingChanged: { userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ]
keyboardRaised = false;
punctuationMode = false; property string newUrl: ""
keyboard.resetShiftMode(false);
webChannel.registeredObjects: [eventBridgeWrapper]
// Required to support clicking on "hifi://" links
if (WebEngineView.LoadStartedStatus == loadRequest.status) { Component.onCompleted: {
var url = loadRequest.url.toString(); // Ensure the JS from the web-engine makes it to our logging
if (urlHandler.canHandleUrl(url)) { webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) {
if (urlHandler.handleUrl(url)) { console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message);
root.stop(); });
}
webview.profile.httpUserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36";
web.address = url;
}
onFeaturePermissionRequested: {
grantFeaturePermission(securityOrigin, feature, true);
}
onLoadingChanged: {
keyboardRaised = false;
punctuationMode = false;
keyboard.resetShiftMode(false);
// Required to support clicking on "hifi://" links
if (WebEngineView.LoadStartedStatus == loadRequest.status) {
var url = loadRequest.url.toString();
if (urlHandler.canHandleUrl(url)) {
if (urlHandler.handleUrl(url)) {
root.stop();
} }
} }
} }
}
onNewViewRequested: { onNavigationRequested: {
var component = Qt.createComponent("./TabletBrowser.qml"); if (request.navigationType == WebEngineNavigationRequest.LinkClickedNavigation) {
pagesModel.append({webUrl: request.url.toString()})
if (component.status != Component.Ready) {
if (component.status == Component.Error) {
console.log("Error: " + component.errorString());
}
return;
}
var newWindow = component.createObject();
newWindow.setProfile(webview.profile);
request.openIn(newWindow.webView);
newWindow.eventBridge = web.eventBridge;
stackRoot.push(newWindow);
newWindow.webView.forceActiveFocus();
} }
} }
} // item onNewViewRequested: {
request.openIn(webView);
}
}
Keys.onPressed: { Keys.onPressed: {
switch(event.key) { switch(event.key) {
case Qt.Key_L: case Qt.Key_L:
@ -171,4 +136,4 @@ Item {
} }
} }
} // dialog }

View file

@ -1,6 +1,6 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtWebEngine 1.1 import QtWebEngine 1.2
import QtWebChannel 1.0 import QtWebChannel 1.0
import "../controls-uit" as HiFiControls import "../controls-uit" as HiFiControls
import "../styles" as HifiStyles import "../styles" as HifiStyles
@ -14,17 +14,20 @@ Item {
height: parent.height height: parent.height
property var parentStackItem: null property var parentStackItem: null
property int headerHeight: 38 property int headerHeight: 38
property alias url: root.url property string url
property string address: url property string address: url //for compatibility
property alias scriptURL: root.userScriptUrl property string scriptURL
property alias eventBridge: eventBridgeWrapper.eventBridge property alias eventBridge: eventBridgeWrapper.eventBridge
property bool keyboardEnabled: HMD.active property bool keyboardEnabled: HMD.active
property bool keyboardRaised: false property bool keyboardRaised: false
property bool punctuationMode: false property bool punctuationMode: false
property bool isDesktop: false property bool isDesktop: false
property WebEngineView view: root property WebEngineView view: loader.currentView
property int currentPage: -1 // used as a model for repeater
property alias pagesModel: pagesModel
Row { Row {
id: buttons id: buttons
HifiConstants { id: hifi } HifiConstants { id: hifi }
@ -37,29 +40,29 @@ Item {
anchors.leftMargin: 8 anchors.leftMargin: 8
HiFiGlyphs { HiFiGlyphs {
id: back; id: back;
enabled: true; enabled: currentPage > 0
text: hifi.glyphs.backward text: hifi.glyphs.backward
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
size: 48 size: 48
MouseArea { anchors.fill: parent; onClicked: stackRoot.goBack() } MouseArea { anchors.fill: parent; onClicked: goBack() }
} }
HiFiGlyphs { HiFiGlyphs {
id: forward; id: forward;
enabled: stackRoot.currentItem.canGoForward; enabled: currentPage < pagesModel.count - 1
text: hifi.glyphs.forward text: hifi.glyphs.forward
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
size: 48 size: 48
MouseArea { anchors.fill: parent; onClicked: stackRoot.currentItem.goForward() } MouseArea { anchors.fill: parent; onClicked: goForward() }
} }
HiFiGlyphs { HiFiGlyphs {
id: reload; id: reload;
enabled: true; enabled: view != null;
text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload text: (view !== null && view.loading) ? hifi.glyphs.close : hifi.glyphs.reload
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
size: 48 size: 48
MouseArea { anchors.fill: parent; onClicked: stackRoot.currentItem.reloadPage(); } MouseArea { anchors.fill: parent; onClicked: reloadPage(); }
} }
} }
@ -86,7 +89,7 @@ Item {
} }
//root.hidePermissionsBar(); //root.hidePermissionsBar();
web.keyboardRaised = false; web.keyboardRaised = false;
stackRoot.currentItem.gotoPage(text); gotoPage(text);
break; break;
@ -94,157 +97,78 @@ Item {
} }
} }
ListModel {
id: pagesModel
onCountChanged: {
currentPage = count - 1
}
}
function goBack() {
if (currentPage > 0) {
currentPage--;
}
}
function goForward() {
if (currentPage < pagesModel.count - 1) {
currentPage++;
}
}
function gotoPage(url) {
pagesModel.append({webUrl: url})
}
function reloadPage() {
view.reloadAndBypassCache()
view.setActiveFocusOnPress(true);
view.setEnabled(true);
}
onCurrentPageChanged: {
if (currentPage >= 0 && currentPage < pagesModel.count && loader.item !== null) {
loader.item.url = pagesModel.get(currentPage).webUrl
}
}
onUrlChanged: {
gotoPage(url)
}
QtObject {
id: eventBridgeWrapper
WebChannel.id: "eventBridgeWrapper"
property var eventBridge;
}
Loader {
id: loader
property WebEngineView currentView: null
StackView {
id: stackRoot
width: parent.width width: parent.width
height: parent.height - web.headerHeight height: parent.height - web.headerHeight
asynchronous: true
anchors.top: buttons.bottom anchors.top: buttons.bottom
//property var goBack: currentItem.goBack(); active: false
property WebEngineView view: root source: "../TabletBrowser.qml"
onStatusChanged: {
initialItem: root; if (loader.status === Loader.Ready) {
currentView = item.webView
function goBack() { item.webView.userScriptUrl = web.scriptURL
if (depth > 1 ) { if (currentPage >= 0) {
if (currentItem.canGoBack) { //we got something to load already
currentItem.goBack(); item.url = pagesModel.get(currentPage).webUrl
} else {
stackRoot.pop();
currentItem.webView.focus = true;
currentItem.webView.forceActiveFocus();
web.address = currentItem.webView.url;
}
} else {
if (currentItem.canGoBack) {
currentItem.goBack();
} else if (parentStackItem) {
web.parentStackItem.pop();
} }
} }
} }
QtObject {
id: eventBridgeWrapper
WebChannel.id: "eventBridgeWrapper"
property var eventBridge;
}
WebEngineView {
id: root
objectName: "webEngineView"
x: 0
y: 0
width: parent.width
height: keyboardEnabled && keyboardRaised ? (parent.height - keyboard.height) : parent.height
profile: HFTabletWebEngineProfile {
id: webviewTabletProfile
storageName: "qmlTabletWebEngine"
}
property WebEngineView webView: root
function reloadPage() {
root.reload();
}
function gotoPage(url) {
root.url = url;
}
property string userScriptUrl: ""
// creates a global EventBridge object.
WebEngineScript {
id: createGlobalEventBridge
sourceCode: eventBridgeJavaScriptToInject
injectionPoint: WebEngineScript.DocumentCreation
worldId: WebEngineScript.MainWorld
}
// detects when to raise and lower virtual keyboard
WebEngineScript {
id: raiseAndLowerKeyboard
injectionPoint: WebEngineScript.Deferred
sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js"
worldId: WebEngineScript.MainWorld
}
// User script.
WebEngineScript {
id: userScript
sourceUrl: root.userScriptUrl
injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished.
worldId: WebEngineScript.MainWorld
}
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ]
property string newUrl: ""
webChannel.registeredObjects: [eventBridgeWrapper]
Component.onCompleted: {
// Ensure the JS from the web-engine makes it to our logging
root.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) {
console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message);
});
root.profile.httpUserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"
}
onFeaturePermissionRequested: {
grantFeaturePermission(securityOrigin, feature, true);
}
onLoadingChanged: {
keyboardRaised = false;
punctuationMode = false;
keyboard.resetShiftMode(false);
// Required to support clicking on "hifi://" links
if (WebEngineView.LoadStartedStatus == loadRequest.status) {
var url = loadRequest.url.toString();
if (urlHandler.canHandleUrl(url)) {
if (urlHandler.handleUrl(url)) {
root.stop();
}
}
}
}
onNewViewRequested:{
var component = Qt.createComponent("../TabletBrowser.qml");
if (component.status != Component.Ready) {
if (component.status == Component.Error) {
console.log("Error: " + component.errorString());
}
return;
}
var newWindow = component.createObject();
newWindow.setProfile(root.profile);
request.openIn(newWindow.webView);
newWindow.eventBridge = web.eventBridge;
stackRoot.push(newWindow);
}
}
HiFiControls.Keyboard {
id: keyboard
raised: web.keyboardEnabled && web.keyboardRaised
numeric: web.punctuationMode
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
}
} }
Component.onCompleted: { Component.onCompleted: {
web.isDesktop = (typeof desktop !== "undefined"); web.isDesktop = (typeof desktop !== "undefined");
address = url; address = url;
loader.active = true
} }
Keys.onPressed: { Keys.onPressed: {

View file

@ -127,7 +127,7 @@ Rectangle {
text: hifi.glyphs.mic text: hifi.glyphs.mic
color: hifi.colors.primaryHighlight color: hifi.colors.primaryHighlight
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
font.pointSize: 27 size: 32
} }
RalewayRegular { RalewayRegular {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -182,7 +182,7 @@ Rectangle {
text: hifi.glyphs.unmuted text: hifi.glyphs.unmuted
color: hifi.colors.primaryHighlight color: hifi.colors.primaryHighlight
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
font.pointSize: 27 size: 32
} }
RalewayRegular { RalewayRegular {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View file

@ -14,6 +14,7 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
import "../styles-uit" import "../styles-uit"
import "../controls-uit" as HifiControls
import "toolbars" import "toolbars"
// references Users, UserActivityLogger, MyAvatar, Vec3, Quat, AddressManager from root context // references Users, UserActivityLogger, MyAvatar, Vec3, Quat, AddressManager from root context
@ -42,8 +43,9 @@ Item {
property bool selected: false property bool selected: false
property bool isAdmin: false property bool isAdmin: false
property bool isPresent: true property bool isPresent: true
property string placeName: ""
property string profilePicBorderColor: (connectionStatus == "connection" ? hifi.colors.indigoAccent : (connectionStatus == "friend" ? hifi.colors.greenHighlight : "transparent")) property string profilePicBorderColor: (connectionStatus == "connection" ? hifi.colors.indigoAccent : (connectionStatus == "friend" ? hifi.colors.greenHighlight : "transparent"))
property alias avImage: avatarImage
Item { Item {
id: avatarImage id: avatarImage
visible: profileUrl !== "" && userName !== ""; visible: profileUrl !== "" && userName !== "";
@ -79,25 +81,6 @@ Item {
anchors.fill: parent; anchors.fill: parent;
visible: userImage.status != Image.Ready; visible: userImage.status != Image.Ready;
} }
StateImage {
id: infoHoverImage;
visible: false;
imageURL: "../../images/info-icon-2-state.svg";
size: 32;
buttonState: 1;
anchors.centerIn: parent;
}
MouseArea {
anchors.fill: parent
enabled: selected || isMyCard;
hoverEnabled: enabled
onClicked: {
userInfoViewer.url = defaultBaseUrl + "/users/" + userName;
userInfoViewer.visible = true;
}
onEntered: infoHoverImage.visible = true;
onExited: infoHoverImage.visible = false;
}
} }
// Colored border around avatarImage // Colored border around avatarImage
@ -316,9 +299,10 @@ Item {
visible: thisNameCard.userName !== ""; visible: thisNameCard.userName !== "";
// Size // Size
width: parent.width width: parent.width
height: pal.activeTab == "nearbyTab" || isMyCard ? usernameTextPixelSize + 4 : parent.height; height: usernameTextPixelSize + 4
// Anchors // Anchors
anchors.top: isMyCard ? myDisplayName.bottom : (pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : parent.top); anchors.top: isMyCard ? myDisplayName.bottom : pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : undefined //(parent.height - displayNameTextPixelSize/2));
anchors.verticalCenter: pal.activeTab == "connectionsTab" ? avatarImage.verticalCenter : undefined
anchors.left: avatarImage.right; anchors.left: avatarImage.right;
anchors.leftMargin: avatarImage.visible ? 5 : 0; anchors.leftMargin: avatarImage.visible ? 5 : 0;
anchors.rightMargin: 5; anchors.rightMargin: 5;
@ -346,6 +330,92 @@ Item {
} }
} }
} }
StateImage {
id: nameCardConnectionInfoImage
visible: selected && !isMyCard && pal.activeTab == "connectionsTab"
imageURL: "../../images/info-icon-2-state.svg" // PLACEHOLDER!!!
size: 32;
buttonState: 0;
anchors.left: avatarImage.right
anchors.bottom: parent.bottom
}
MouseArea {
anchors.fill:nameCardConnectionInfoImage
enabled: selected
hoverEnabled: true
onClicked: {
userInfoViewer.url = defaultBaseUrl + "/users/" + userName;
userInfoViewer.visible = true;
}
onEntered: {
nameCardConnectionInfoImage.buttonState = 1;
}
onExited: {
nameCardConnectionInfoImage.buttonState = 0;
}
}
FiraSansRegular {
id: nameCardConnectionInfoText
visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard
width: parent.width
height: displayNameTextPixelSize
size: displayNameTextPixelSize - 4
anchors.left: nameCardConnectionInfoImage.right
anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter
anchors.leftMargin: 5
verticalAlignment: Text.AlignVCenter
text: "Info"
color: hifi.colors.baseGray
}
HiFiGlyphs {
id: nameCardRemoveConnectionImage
visible: selected && !isMyCard && pal.activeTab == "connectionsTab"
text: hifi.glyphs.close
size: 28;
x: 120
anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter
}
MouseArea {
anchors.fill:nameCardRemoveConnectionImage
enabled: selected
hoverEnabled: true
onClicked: {
// send message to pal.js to forgetConnection
pal.sendToScript({method: 'removeConnection', params: thisNameCard.userName});
}
onEntered: {
nameCardRemoveConnectionImage.text = hifi.glyphs.closeInverted;
}
onExited: {
nameCardRemoveConnectionImage.text = hifi.glyphs.close;
}
}
FiraSansRegular {
id: nameCardRemoveConnectionText
visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard
width: parent.width
height: displayNameTextPixelSize
size: displayNameTextPixelSize - 4
anchors.left: nameCardRemoveConnectionImage.right
anchors.verticalCenter: nameCardRemoveConnectionImage.verticalCenter
anchors.leftMargin: 5
verticalAlignment: Text.AlignVCenter
text: "Forget"
color: hifi.colors.baseGray
}
HifiControls.Button {
id: visitConnectionButton
visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard
text: "Visit"
enabled: thisNameCard.placeName !== ""
anchors.verticalCenter: nameCardRemoveConnectionImage.verticalCenter
x: 240
onClicked: {
AddressManager.goToUser(thisNameCard.userName);
UserActivityLogger.palAction("go_to_user", thisNameCard.userName);
}
}
// VU Meter // VU Meter
Rectangle { Rectangle {
id: nameCardVUMeter id: nameCardVUMeter
@ -484,7 +554,7 @@ Item {
} }
} }
} }
function updateGainFromQML(avatarUuid, sliderValue, isReleased) { function updateGainFromQML(avatarUuid, sliderValue, isReleased) {
Users.setAvatarGain(avatarUuid, sliderValue); Users.setAvatarGain(avatarUuid, sliderValue);
if (isReleased) { if (isReleased) {

View file

@ -52,6 +52,13 @@ Rectangle {
id: letterboxMessage; id: letterboxMessage;
z: 999; // Force the popup on top of everything else z: 999; // Force the popup on top of everything else
} }
Connections {
target: GlobalServices
onMyUsernameChanged: {
myData.userName = Account.username;
myDataChanged(); // Setting a property within an object isn't enough to update dependencies. This will do it.
}
}
// The ComboDialog used for setting availability // The ComboDialog used for setting availability
ComboDialog { ComboDialog {
id: comboDialog; id: comboDialog;
@ -763,7 +770,7 @@ Rectangle {
// This Rectangle refers to each Row in the connectionsTable. // This Rectangle refers to each Row in the connectionsTable.
rowDelegate: Rectangle { rowDelegate: Rectangle {
// Size // Size
height: rowHeight; height: rowHeight + (styleData.selected ? 15 : 0);
color: rowColor(styleData.selected, styleData.alternate); color: rowColor(styleData.selected, styleData.alternate);
} }
@ -779,6 +786,7 @@ Rectangle {
profileUrl: (model && model.profileUrl) || ""; profileUrl: (model && model.profileUrl) || "";
displayName: ""; displayName: "";
userName: model ? model.userName : ""; userName: model ? model.userName : "";
placeName: model ? model.placeName : ""
connectionStatus : model ? model.connection : ""; connectionStatus : model ? model.connection : "";
selected: styleData.selected; selected: styleData.selected;
// Size // Size
@ -797,12 +805,16 @@ Rectangle {
elide: Text.ElideRight; elide: Text.ElideRight;
// Size // Size
width: parent.width; width: parent.width;
// Anchors // you would think that this would work:
anchors.fill: parent; // anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter
// but no! you cannot anchor to a non-sibling or parent. So I will
// align with the friends checkbox, where I did the manual alignment
anchors.verticalCenter: friendsCheckBox.verticalCenter
// Text Size // Text Size
size: 16; size: 16;
// Text Positioning // Text Positioning
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
// Style // Style
color: hifi.colors.blueAccent; color: hifi.colors.blueAccent;
font.underline: true; font.underline: true;
@ -822,8 +834,12 @@ Rectangle {
// "Friends" checkbox // "Friends" checkbox
HifiControlsUit.CheckBox { HifiControlsUit.CheckBox {
id: friendsCheckBox; id: friendsCheckBox;
visible: styleData.role === "friends" && model.userName !== myData.userName; visible: styleData.role === "friends" && model && model.userName !== myData.userName;
anchors.centerIn: parent; // you would think that this would work:
// anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter
// but no! you cannot anchor to a non-sibling or parent. So:
x: parent.width/2 - boxSize/2
y: connectionsNameCard.avImage.y + connectionsNameCard.avImage.height/2 - boxSize/2
checked: model ? (model["connection"] === "friend" ? true : false) : false; checked: model ? (model["connection"] === "friend" ? true : false) : false;
boxSize: 24; boxSize: 24;
onClicked: { onClicked: {
@ -901,7 +917,7 @@ Rectangle {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
textFormat: Text.StyledText; textFormat: Text.StyledText;
// Text // Text
text: HMD.active ? text: HMD.isMounted ?
"<b>When you meet someone you want to remember later, you can <font color='purple'>connect</font> with a handshake:</b><br><br>" + "<b>When you meet someone you want to remember later, you can <font color='purple'>connect</font> with a handshake:</b><br><br>" +
"1. Put your hand out onto their hand and squeeze your controller's grip button on its side.<br>" + "1. Put your hand out onto their hand and squeeze your controller's grip button on its side.<br>" +
"2. Once the other person puts their hand onto yours, you'll see your connection form.<br>" + "2. Once the other person puts their hand onto yours, you'll see your connection form.<br>" +
@ -960,7 +976,6 @@ Rectangle {
// Text size // Text size
size: hifi.fontSizes.tabularData; size: hifi.fontSizes.tabularData;
// Anchors // Anchors
anchors.top: myCard.top;
anchors.left: parent.left; anchors.left: parent.left;
// Style // Style
color: hifi.colors.baseGrayHighlight; color: hifi.colors.baseGrayHighlight;

View file

@ -21,6 +21,9 @@ Rectangle {
id: root id: root
objectName: "AssetServer" objectName: "AssetServer"
property string title: "Asset Browser"
property bool keyboardRaised: false
property var eventBridge; property var eventBridge;
signal sendToScript(var message); signal sendToScript(var message);
property bool isHMD: false property bool isHMD: false
@ -415,7 +418,6 @@ Rectangle {
Column { Column {
width: parent.width width: parent.width
y: hifi.dimensions.tabletMenuHeader //-bgNavBar
spacing: 10 spacing: 10
HifiControls.TabletContentSection { HifiControls.TabletContentSection {

View file

@ -20,7 +20,7 @@ import "../../windows"
Rectangle { Rectangle {
id: root id: root
objectName: "RunningScripts" objectName: "RunningScripts"
property var title: "Running Scripts" property string title: "Running Scripts"
HifiConstants { id: hifi } HifiConstants { id: hifi }
signal sendToScript(var message); signal sendToScript(var message);
property var eventBridge; property var eventBridge;
@ -81,9 +81,9 @@ Rectangle {
Flickable { Flickable {
id: flickable id: flickable
width: parent.width width: tabletRoot.width
height: parent.height - (keyboard.raised ? keyboard.raisedHeight : 0) height: parent.height - (keyboard.raised ? keyboard.raisedHeight : 0)
contentWidth: parent.width contentWidth: column.width
contentHeight: column.childrenRect.height contentHeight: column.childrenRect.height
clip: true clip: true
@ -121,9 +121,8 @@ Rectangle {
model: runningScriptsModel model: runningScriptsModel
id: table id: table
height: 185 height: 185
width: parent.width
colorScheme: hifi.colorSchemes.dark colorScheme: hifi.colorSchemes.dark
anchors.left: parent.left
anchors.right: parent.right
expandSelectedRow: true expandSelectedRow: true
itemDelegate: Item { itemDelegate: Item {

View file

@ -202,7 +202,7 @@ Item {
RalewaySemiBold { RalewaySemiBold {
id: usernameText id: usernameText
text: tablet.parent.parent.username text: tabletRoot.username
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 20 anchors.rightMargin: 20

View file

@ -25,6 +25,8 @@ StackView {
HifiConstants { id: hifi } HifiConstants { id: hifi }
HifiStyles.HifiConstants { id: hifiStyleConstants } HifiStyles.HifiConstants { id: hifiStyleConstants }
initialItem: addressBarDialog initialItem: addressBarDialog
width: parent !== null ? parent.width : undefined
height: parent !== null ? parent.height : undefined
property var eventBridge; property var eventBridge;
property var allStories: []; property var allStories: [];
property int cardWidth: 460; property int cardWidth: 460;
@ -116,6 +118,7 @@ StackView {
imageURL: "../../../images/home.svg" imageURL: "../../../images/home.svg"
onClicked: { onClicked: {
addressBarDialog.loadHome(); addressBarDialog.loadHome();
tabletRoot.shown = false;
} }
anchors { anchors {
left: parent.left left: parent.left
@ -150,7 +153,9 @@ StackView {
anchors { anchors {
top: navBar.bottom top: navBar.bottom
right: parent.right right: parent.right
rightMargin: 16
left: parent.left left: parent.left
leftMargin: 16
} }
property int inputAreaHeight: 70 property int inputAreaHeight: 70
@ -554,20 +559,21 @@ StackView {
if (addressLine.text !== "") { if (addressLine.text !== "") {
addressBarDialog.loadAddress(addressLine.text, fromSuggestions) addressBarDialog.loadAddress(addressLine.text, fromSuggestions)
} }
if (root.desktop) { if (root.desktop) {
tablet.gotoHomeScreen(); tablet.gotoHomeScreen();
} else { } else {
HMD.closeTablet(); HMD.closeTablet();
} }
tabletRoot.shown = false;
} }
Keys.onPressed: { Keys.onPressed: {
switch (event.key) { switch (event.key) {
case Qt.Key_Escape: case Qt.Key_Escape:
case Qt.Key_Back: case Qt.Key_Back:
root.shown = false tabletRoot.shown = false
clearAddressLineTimer.start(); clearAddressLineTimer.start();
event.accepted = true event.accepted = true
break break

View file

@ -13,6 +13,7 @@ Item {
property var openMessage: null; property var openMessage: null;
property string subMenu: "" property string subMenu: ""
signal showDesktop(); signal showDesktop();
property bool shown: true
function setOption(value) { function setOption(value) {
option = value; option = value;

View file

@ -76,8 +76,8 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) {
return; return;
} }
if (_scriptEngine != NULL) { if (_scriptEngine != NULL) {
disconnect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &JSConsole::handlePrint);
disconnect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError);
if (_ownScriptEngine) { if (_ownScriptEngine) {
_scriptEngine->deleteLater(); _scriptEngine->deleteLater();
} }
@ -87,8 +87,8 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) {
_ownScriptEngine = scriptEngine == NULL; _ownScriptEngine = scriptEngine == NULL;
_scriptEngine = _ownScriptEngine ? DependencyManager::get<ScriptEngines>()->loadScript(QString(), false) : scriptEngine; _scriptEngine = _ownScriptEngine ? DependencyManager::get<ScriptEngines>()->loadScript(QString(), false) : scriptEngine;
connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); connect(_scriptEngine, &ScriptEngine::printedMessage, this, &JSConsole::handlePrint);
connect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); connect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError);
} }
void JSConsole::executeCommand(const QString& command) { void JSConsole::executeCommand(const QString& command) {
@ -134,11 +134,13 @@ void JSConsole::commandFinished() {
resetCurrentCommandHistory(); resetCurrentCommandHistory();
} }
void JSConsole::handleError(const QString& message) { void JSConsole::handleError(const QString& scriptName, const QString& message) {
Q_UNUSED(scriptName);
appendMessage(GUTTER_ERROR, "<span style='" + RESULT_ERROR_STYLE + "'>" + message.toHtmlEscaped() + "</span>"); appendMessage(GUTTER_ERROR, "<span style='" + RESULT_ERROR_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
} }
void JSConsole::handlePrint(const QString& message) { void JSConsole::handlePrint(const QString& scriptName, const QString& message) {
Q_UNUSED(scriptName);
appendMessage("", message); appendMessage("", message);
} }

View file

@ -47,8 +47,8 @@ protected:
protected slots: protected slots:
void scrollToBottom(); void scrollToBottom();
void resizeTextInput(); void resizeTextInput();
void handlePrint(const QString& message); void handlePrint(const QString& scriptName, const QString& message);
void handleError(const QString& message); void handleError(const QString& scriptName, const QString& message);
void commandFinished(); void commandFinished();
private: private:

View file

@ -158,6 +158,22 @@ namespace controller {
LEFT_HAND_PINKY2, LEFT_HAND_PINKY2,
LEFT_HAND_PINKY3, LEFT_HAND_PINKY3,
LEFT_HAND_PINKY4, LEFT_HAND_PINKY4,
TRACKED_OBJECT_00,
TRACKED_OBJECT_01,
TRACKED_OBJECT_02,
TRACKED_OBJECT_03,
TRACKED_OBJECT_04,
TRACKED_OBJECT_05,
TRACKED_OBJECT_06,
TRACKED_OBJECT_07,
TRACKED_OBJECT_08,
TRACKED_OBJECT_09,
TRACKED_OBJECT_10,
TRACKED_OBJECT_11,
TRACKED_OBJECT_12,
TRACKED_OBJECT_13,
TRACKED_OBJECT_14,
TRACKED_OBJECT_15,
NUM_STANDARD_POSES NUM_STANDARD_POSES
}; };

View file

@ -60,6 +60,7 @@ bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) {
bool OffscreenGLCanvas::makeCurrent() { bool OffscreenGLCanvas::makeCurrent() {
bool result = _context->makeCurrent(_offscreenSurface); bool result = _context->makeCurrent(_offscreenSurface);
Q_ASSERT(result); Q_ASSERT(result);
std::call_once(_reportOnce, [this]{ std::call_once(_reportOnce, [this]{
qCDebug(glLogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); qCDebug(glLogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
qCDebug(glLogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); qCDebug(glLogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));

View file

@ -278,11 +278,9 @@ void OffscreenQmlSurface::cleanup() {
} }
void OffscreenQmlSurface::render() { void OffscreenQmlSurface::render() {
#ifdef HIFI_ENABLE_NSIGHT_DEBUG #ifdef HIFI_ENABLE_NSIGHT_DEBUG
return; return;
#endif #endif
if (_paused) { if (_paused) {
return; return;
} }
@ -614,7 +612,11 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::function<void(QQmlContext*, QOb
return nullptr; return nullptr;
} }
connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant))); //check if the item contains sendToScript signal
int sendToScriptIndex = newItem->metaObject()->indexOfSignal("sendToScript");
if (sendToScriptIndex != -1) {
connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant)));
}
// The root item is ready. Associate it with the window. // The root item is ready. Associate it with the window.
_rootItem = newItem; _rootItem = newItem;

View file

@ -61,6 +61,16 @@ void UserActivityLoggerScriptingInterface::palOpened(float secondsOpened) {
}); });
} }
void UserActivityLoggerScriptingInterface::makeUserConnection(QString otherID, bool success, QString detailsString) {
QJsonObject payload;
payload["otherUser"] = otherID;
payload["success"] = success;
if (detailsString.length() > 0) {
payload["details"] = detailsString;
}
logAction("makeUserConnection", payload);
}
void UserActivityLoggerScriptingInterface::logAction(QString action, QJsonObject details) { void UserActivityLoggerScriptingInterface::logAction(QString action, QJsonObject details) {
QMetaObject::invokeMethod(&UserActivityLogger::getInstance(), "logAction", QMetaObject::invokeMethod(&UserActivityLogger::getInstance(), "logAction",
Q_ARG(QString, action), Q_ARG(QString, action),

View file

@ -29,6 +29,7 @@ public:
float tutorialElapsedTime, QString tutorialRunID = "", int tutorialVersion = 0, QString controllerType = ""); float tutorialElapsedTime, QString tutorialRunID = "", int tutorialVersion = 0, QString controllerType = "");
Q_INVOKABLE void palAction(QString action, QString target); Q_INVOKABLE void palAction(QString action, QString target);
Q_INVOKABLE void palOpened(float secondsOpen); Q_INVOKABLE void palOpened(float secondsOpen);
Q_INVOKABLE void makeUserConnection(QString otherUser, bool success, QString details="");
private: private:
void logAction(QString action, QJsonObject details = {}); void logAction(QString action, QJsonObject details = {});
}; };

View file

@ -28,6 +28,12 @@
#include "skin_model_shadow_vert.h" #include "skin_model_shadow_vert.h"
#include "skin_model_normal_map_vert.h" #include "skin_model_normal_map_vert.h"
#include "simple_vert.h"
#include "simple_textured_frag.h"
#include "simple_textured_unlit_frag.h"
#include "simple_transparent_textured_frag.h"
#include "simple_transparent_textured_unlit_frag.h"
#include "model_frag.h" #include "model_frag.h"
#include "model_unlit_frag.h" #include "model_unlit_frag.h"
#include "model_shadow_frag.h" #include "model_shadow_frag.h"
@ -135,6 +141,7 @@ void initOverlay3DPipelines(ShapePlumber& plumber) {
void initDeferredPipelines(render::ShapePlumber& plumber) { void initDeferredPipelines(render::ShapePlumber& plumber) {
// Vertex shaders // Vertex shaders
auto simpleVertex = gpu::Shader::createVertex(std::string(simple_vert));
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert)); auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert)); auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert)); auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert));
@ -145,6 +152,10 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
auto skinModelShadowVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert)); auto skinModelShadowVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
// Pixel shaders // Pixel shaders
auto simplePixel = gpu::Shader::createPixel(std::string(simple_textured_frag));
auto simpleUnlitPixel = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag));
auto simpleTranslucentPixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_frag));
auto simpleTranslucentUnlitPixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_unlit_frag));
auto modelPixel = gpu::Shader::createPixel(std::string(model_frag)); auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
auto modelUnlitPixel = gpu::Shader::createPixel(std::string(model_unlit_frag)); auto modelUnlitPixel = gpu::Shader::createPixel(std::string(model_unlit_frag));
auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag)); auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
@ -167,13 +178,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
modelVertex, modelPixel); modelVertex, modelPixel);
addPipeline( addPipeline(
Key::Builder(), Key::Builder(),
modelVertex, modelPixel); simpleVertex, simplePixel);
addPipeline( addPipeline(
Key::Builder().withMaterial().withUnlit(), Key::Builder().withMaterial().withUnlit(),
modelVertex, modelUnlitPixel); modelVertex, modelUnlitPixel);
addPipeline( addPipeline(
Key::Builder().withUnlit(), Key::Builder().withUnlit(),
modelVertex, modelUnlitPixel); simpleVertex, simpleUnlitPixel);
addPipeline( addPipeline(
Key::Builder().withMaterial().withTangents(), Key::Builder().withMaterial().withTangents(),
modelNormalMapVertex, modelNormalMapPixel); modelNormalMapVertex, modelNormalMapPixel);
@ -189,13 +200,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
modelVertex, modelTranslucentPixel); modelVertex, modelTranslucentPixel);
addPipeline( addPipeline(
Key::Builder().withTranslucent(), Key::Builder().withTranslucent(),
modelVertex, modelTranslucentPixel); simpleVertex, simpleTranslucentPixel);
addPipeline( addPipeline(
Key::Builder().withMaterial().withTranslucent().withUnlit(), Key::Builder().withMaterial().withTranslucent().withUnlit(),
modelVertex, modelTranslucentUnlitPixel); modelVertex, modelTranslucentUnlitPixel);
addPipeline( addPipeline(
Key::Builder().withTranslucent().withUnlit(), Key::Builder().withTranslucent().withUnlit(),
modelVertex, modelTranslucentUnlitPixel); simpleVertex, simpleTranslucentUnlitPixel);
addPipeline( addPipeline(
Key::Builder().withMaterial().withTranslucent().withTangents(), Key::Builder().withMaterial().withTranslucent().withTangents(),
modelNormalMapVertex, modelTranslucentPixel); modelNormalMapVertex, modelTranslucentPixel);

View file

@ -26,15 +26,17 @@ in vec2 _texCoord0;
void main(void) { void main(void) {
vec4 texel = texture(originalTexture, _texCoord0); vec4 texel = texture(originalTexture, _texCoord0);
float colorAlpha = _color.a;
if (_color.a <= 0.0) { if (_color.a <= 0.0) {
texel = colorToLinearRGBA(texel); texel = colorToLinearRGBA(texel);
colorAlpha = -_color.a;
} }
const float ALPHA_THRESHOLD = 0.999; const float ALPHA_THRESHOLD = 0.999;
if (_color.a * texel.a < ALPHA_THRESHOLD) { if (colorAlpha * texel.a < ALPHA_THRESHOLD) {
packDeferredFragmentTranslucent( packDeferredFragmentTranslucent(
normalize(_normal), normalize(_normal),
_color.a * texel.a, colorAlpha * texel.a,
_color.rgb * texel.rgb, _color.rgb * texel.rgb,
DEFAULT_FRESNEL, DEFAULT_FRESNEL,
DEFAULT_ROUGHNESS); DEFAULT_ROUGHNESS);

View file

@ -2,7 +2,7 @@
<$VERSION_HEADER$> <$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$> // Generated on <$_SCRIBE_DATE$>
// //
// simple.frag // simple_textured_unlit.frag
// fragment shader // fragment shader
// //
// Created by Clément Brisset on 5/29/15. // Created by Clément Brisset on 5/29/15.
@ -25,15 +25,17 @@ in vec2 _texCoord0;
void main(void) { void main(void) {
vec4 texel = texture(originalTexture, _texCoord0.st); vec4 texel = texture(originalTexture, _texCoord0.st);
float colorAlpha = _color.a;
if (_color.a <= 0.0) { if (_color.a <= 0.0) {
texel = colorToLinearRGBA(texel); texel = colorToLinearRGBA(texel);
colorAlpha = -_color.a;
} }
const float ALPHA_THRESHOLD = 0.999; const float ALPHA_THRESHOLD = 0.999;
if (_color.a * texel.a < ALPHA_THRESHOLD) { if (colorAlpha * texel.a < ALPHA_THRESHOLD) {
packDeferredFragmentTranslucent( packDeferredFragmentTranslucent(
normalize(_normal), normalize(_normal),
_color.a * texel.a, colorAlpha * texel.a,
_color.rgb * texel.rgb, _color.rgb * texel.rgb,
DEFAULT_FRESNEL, DEFAULT_FRESNEL,
DEFAULT_ROUGHNESS); DEFAULT_ROUGHNESS);

View file

@ -0,0 +1,62 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// simple_transparent_textured.slf
// fragment shader
//
// Created by Sam Gateau on 4/3/17.
// 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 gpu/Color.slh@>
<@include DeferredBufferWrite.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalGlobalLightingAlphaBlended()$>
<@include gpu/Transform.slh@>
<$declareStandardCameraTransform()$>
// the albedo texture
uniform sampler2D originalTexture;
// the interpolated normal
in vec4 _position;
in vec3 _normal;
in vec4 _color;
in vec2 _texCoord0;
void main(void) {
vec4 texel = texture(originalTexture, _texCoord0.st);
float opacity = _color.a;
if (_color.a <= 0.0) {
texel = colorToLinearRGBA(texel);
opacity = -_color.a;
}
opacity *= texel.a;
vec3 albedo = _color.rgb * texel.rgb;
vec3 fragPosition = _position.xyz;
vec3 fragNormal = normalize(_normal);
TransformCamera cam = getTransformCamera();
_fragColor0 = vec4(evalGlobalLightingAlphaBlended(
cam._viewInverse,
1.0,
1.0,
fragPosition,
fragNormal,
albedo,
DEFAULT_FRESNEL,
0.0,
vec3(0.0f),
DEFAULT_ROUGHNESS,
opacity),
opacity);
}

View file

@ -0,0 +1,36 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// simple_transparent_textured_unlit.slf
// fragment shader
//
// Created by Sam Gateau on 4/3/17.
// 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 gpu/Color.slh@>
// the albedo texture
uniform sampler2D originalTexture;
// the interpolated normal
in vec3 _normal;
in vec4 _color;
in vec2 _texCoord0;
layout(location = 0) out vec4 _fragColor0;
void main(void) {
vec4 texel = texture(originalTexture, _texCoord0.st);
float colorAlpha = _color.a;
if (_color.a <= 0.0) {
texel = colorToLinearRGBA(texel);
colorAlpha = -_color.a;
}
_fragColor0 = vec4(_color.rgb * texel.rgb, colorAlpha * texel.a);
}

View file

@ -122,12 +122,15 @@ void QmlWindowClass::initQml(QVariantMap properties) {
object->setProperty(OFFSCREEN_VISIBILITY_PROPERTY, visible); object->setProperty(OFFSCREEN_VISIBILITY_PROPERTY, visible);
object->setProperty(SOURCE_PROPERTY, _source); object->setProperty(SOURCE_PROPERTY, _source);
const QMetaObject *metaObject = _qmlWindow->metaObject();
// Forward messages received from QML on to the script // Forward messages received from QML on to the script
connect(_qmlWindow, SIGNAL(sendToScript(QVariant)), this, SLOT(qmlToScript(const QVariant&)), Qt::QueuedConnection); connect(_qmlWindow, SIGNAL(sendToScript(QVariant)), this, SLOT(qmlToScript(const QVariant&)), Qt::QueuedConnection);
connect(_qmlWindow, SIGNAL(visibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection); connect(_qmlWindow, SIGNAL(visibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection);
connect(_qmlWindow, SIGNAL(resized(QSizeF)), this, SIGNAL(resized(QSizeF)), Qt::QueuedConnection); if (metaObject->indexOfSignal("resized") >= 0)
connect(_qmlWindow, SIGNAL(moved(QVector2D)), this, SLOT(hasMoved(QVector2D)), Qt::QueuedConnection); connect(_qmlWindow, SIGNAL(resized(QSizeF)), this, SIGNAL(resized(QSizeF)), Qt::QueuedConnection);
if (metaObject->indexOfSignal("moved") >= 0)
connect(_qmlWindow, SIGNAL(moved(QVector2D)), this, SLOT(hasMoved(QVector2D)), Qt::QueuedConnection);
connect(_qmlWindow, SIGNAL(windowClosed()), this, SLOT(hasClosed()), Qt::QueuedConnection); connect(_qmlWindow, SIGNAL(windowClosed()), this, SLOT(hasClosed()), Qt::QueuedConnection);
}); });
} }

View file

@ -63,59 +63,6 @@ bool ViveControllerManager::activate() {
enableOpenVrKeyboard(_container); enableOpenVrKeyboard(_container);
// OpenVR provides 3d mesh representations of the controllers
// Disabled controller rendering code
/*
auto renderModels = vr::VRRenderModels();
vr::RenderModel_t model;
if (!_system->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) {
qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING);
} else {
model::Mesh* mesh = new model::Mesh();
model::MeshPointer meshPtr(mesh);
_modelGeometry.setMesh(meshPtr);
auto indexBuffer = new gpu::Buffer(3 * model.unTriangleCount * sizeof(uint16_t), (gpu::Byte*)model.rIndexData);
auto indexBufferPtr = gpu::BufferPointer(indexBuffer);
auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT16, gpu::RAW));
mesh->setIndexBuffer(*indexBufferView);
auto vertexBuffer = new gpu::Buffer(model.unVertexCount * sizeof(vr::RenderModel_Vertex_t),
(gpu::Byte*)model.rVertexData);
auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer);
auto vertexBufferView = new gpu::BufferView(vertexBufferPtr,
0,
vertexBufferPtr->getSize() - sizeof(float) * 3,
sizeof(vr::RenderModel_Vertex_t),
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW));
mesh->setVertexBuffer(*vertexBufferView);
mesh->addAttribute(gpu::Stream::NORMAL,
gpu::BufferView(vertexBufferPtr,
sizeof(float) * 3,
vertexBufferPtr->getSize() - sizeof(float) * 3,
sizeof(vr::RenderModel_Vertex_t),
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
//mesh->addAttribute(gpu::Stream::TEXCOORD,
// gpu::BufferView(vertexBufferPtr,
// 2 * sizeof(float) * 3,
// vertexBufferPtr->getSize() - sizeof(float) * 2,
// sizeof(vr::RenderModel_Vertex_t),
// gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW)));
gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
_texture = gpu::TexturePointer(
gpu::Texture::create2D(formatGPU, model.diffuseTexture.unWidth, model.diffuseTexture.unHeight,
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
_texture->assignStoredMip(0, formatMip, model.diffuseTexture.unWidth * model.diffuseTexture.unHeight * 4 * sizeof(uint8_t), model.diffuseTexture.rubTextureMapData);
_texture->autoGenerateMips(-1);
_modelLoaded = true;
_renderControllers = true;
}
*/
// register with UserInputMapper // register with UserInputMapper
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>(); auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
userInputMapper->registerDevice(_inputDevice); userInputMapper->registerDevice(_inputDevice);
@ -145,70 +92,6 @@ void ViveControllerManager::deactivate() {
_registeredWithInputMapper = false; _registeredWithInputMapper = false;
} }
void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges) {
PerformanceTimer perfTimer("ViveControllerManager::updateRendering");
/*
if (_modelLoaded) {
//auto controllerPayload = new render::Payload<ViveControllerManager>(this);
//auto controllerPayloadPointer = ViveControllerManager::PayloadPointer(controllerPayload);
//if (_leftHandRenderID == 0) {
// _leftHandRenderID = scene->allocateID();
// pendingChanges.resetItem(_leftHandRenderID, controllerPayloadPointer);
//}
//pendingChanges.updateItem(_leftHandRenderID, );
controller::Pose leftHand = _inputDevice->_poseStateMap[controller::StandardPoseChannel::LEFT_HAND];
controller::Pose rightHand = _inputDevice->_poseStateMap[controller::StandardPoseChannel::RIGHT_HAND];
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->useSimpleDrawPipeline(batch);
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
auto mesh = _modelGeometry.getMesh();
batch.setInputFormat(mesh->getVertexFormat());
//batch._glBindTexture(GL_TEXTURE_2D, _uexture);
if (leftHand.isValid()) {
renderHand(leftHand, batch, 1);
}
if (rightHand.isValid()) {
renderHand(rightHand, batch, -1);
}
});
}
*/
}
void ViveControllerManager::renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign) {
/*
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
Transform transform(userInputMapper->getSensorToWorldMat());
transform.postTranslate(pose.getTranslation() + pose.getRotation() * glm::vec3(0, 0, CONTROLLER_LENGTH_OFFSET));
glm::quat rotation = pose.getRotation() * glm::angleAxis(PI, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(sign * PI_OVER_TWO, glm::vec3(0.0f, 0.0f, 1.0f));
transform.postRotate(rotation);
batch.setModelTransform(transform);
auto mesh = _modelGeometry.getMesh();
batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer());
batch.setInputBuffer(gpu::Stream::NORMAL,
mesh->getVertexBuffer()._buffer,
sizeof(float) * 3,
mesh->getVertexBuffer()._stride);
//batch.setInputBuffer(gpu::Stream::TEXCOORD,
// mesh->getVertexBuffer()._buffer,
// 2 * 3 * sizeof(float),
// mesh->getVertexBuffer()._stride);
batch.setIndexBuffer(gpu::UINT16, mesh->getIndexBuffer()._buffer, 0);
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
*/
}
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
if (!_system) { if (!_system) {
@ -257,6 +140,11 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true); handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true);
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false); handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
// collect raw poses
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
handleTrackedObject(i, inputCalibrationData);
}
// handle haptics // handle haptics
{ {
Locker locker(_lock); Locker locker(_lock);
@ -278,6 +166,30 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
_trackedControllers = numTrackedControllers; _trackedControllers = numTrackedControllers;
} }
void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData) {
uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex;
if (_system->IsTrackedDeviceConnected(deviceIndex) &&
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid &&
poseIndex <= controller::TRACKED_OBJECT_15) {
// process pose
const mat4& mat = _nextSimPoseData.poses[deviceIndex];
const vec3 linearVelocity = _nextSimPoseData.linearVelocities[deviceIndex];
const vec3 angularVelocity = _nextSimPoseData.angularVelocities[deviceIndex];
controller::Pose pose(extractTranslation(mat), glmExtractRotation(mat), linearVelocity, angularVelocity);
// transform into avatar frame
glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
_poseStateMap[poseIndex] = pose.transform(controllerToAvatar);
} else {
controller::Pose invalidPose;
_poseStateMap[poseIndex] = invalidPose;
}
}
void ViveControllerManager::InputDevice::handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand) { void ViveControllerManager::InputDevice::handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand) {
if (_system->IsTrackedDeviceConnected(deviceIndex) && if (_system->IsTrackedDeviceConnected(deviceIndex) &&
@ -492,6 +404,24 @@ controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableI
makePair(LEFT_HAND, "LeftHand"), makePair(LEFT_HAND, "LeftHand"),
makePair(RIGHT_HAND, "RightHand"), makePair(RIGHT_HAND, "RightHand"),
// 16 tracked poses
makePair(TRACKED_OBJECT_00, "TrackedObject00"),
makePair(TRACKED_OBJECT_01, "TrackedObject01"),
makePair(TRACKED_OBJECT_02, "TrackedObject02"),
makePair(TRACKED_OBJECT_03, "TrackedObject03"),
makePair(TRACKED_OBJECT_04, "TrackedObject04"),
makePair(TRACKED_OBJECT_05, "TrackedObject05"),
makePair(TRACKED_OBJECT_06, "TrackedObject06"),
makePair(TRACKED_OBJECT_07, "TrackedObject07"),
makePair(TRACKED_OBJECT_08, "TrackedObject08"),
makePair(TRACKED_OBJECT_09, "TrackedObject09"),
makePair(TRACKED_OBJECT_10, "TrackedObject10"),
makePair(TRACKED_OBJECT_11, "TrackedObject11"),
makePair(TRACKED_OBJECT_12, "TrackedObject12"),
makePair(TRACKED_OBJECT_13, "TrackedObject13"),
makePair(TRACKED_OBJECT_14, "TrackedObject14"),
makePair(TRACKED_OBJECT_15, "TrackedObject15"),
// app button above trackpad. // app button above trackpad.
Input::NamedPair(Input(_deviceID, LEFT_APP_MENU, ChannelType::BUTTON), "LeftApplicationMenu"), Input::NamedPair(Input(_deviceID, LEFT_APP_MENU, ChannelType::BUTTON), "LeftApplicationMenu"),
Input::NamedPair(Input(_deviceID, RIGHT_APP_MENU, ChannelType::BUTTON), "RightApplicationMenu"), Input::NamedPair(Input(_deviceID, RIGHT_APP_MENU, ChannelType::BUTTON), "RightApplicationMenu"),

View file

@ -43,8 +43,6 @@ public:
void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges);
void setRenderControllers(bool renderControllers) { _renderControllers = renderControllers; } void setRenderControllers(bool renderControllers) { _renderControllers = renderControllers; }
private: private:
@ -62,6 +60,7 @@ private:
void hapticsHelper(float deltaTime, bool leftHand); void hapticsHelper(float deltaTime, bool leftHand);
void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand); void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand);
void handleTrackedObject(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData);
void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand); void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand);
void handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand); void handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand);
void handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const mat4& mat, void handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const mat4& mat,

View file

@ -18,6 +18,9 @@ Rectangle {
width: parent ? parent.width : 100 width: parent ? parent.width : 100
height: parent ? parent.height : 100 height: parent ? parent.height : 100
signal moved(vector2d position);
signal resized(size size);
property var channel; property var channel;
TextArea { TextArea {

View file

@ -0,0 +1,36 @@
var TRACKED_OBJECT_POSES = [
"TrackedObject00", "TrackedObject01", "TrackedObject02", "TrackedObject03",
"TrackedObject04", "TrackedObject05", "TrackedObject06", "TrackedObject07",
"TrackedObject08", "TrackedObject09", "TrackedObject10", "TrackedObject11",
"TrackedObject12", "TrackedObject13", "TrackedObject14", "TrackedObject15"
];
function init() {
Script.update.connect(update);
}
function shutdown() {
Script.update.disconnect(update);
TRACKED_OBJECT_POSES.forEach(function (key) {
DebugDraw.removeMyAvatarMarker(key);
});
}
var WHITE = {x: 1, y: 1, z: 1, w: 1};
function update(dt) {
if (Controller.Hardware.Vive) {
TRACKED_OBJECT_POSES.forEach(function (key) {
var pose = Controller.getPoseValue(Controller.Hardware.Vive[key]);
if (pose.valid) {
DebugDraw.addMyAvatarMarker(key, pose.rotation, pose.translation, WHITE);
} else {
DebugDraw.removeMyAvatarMarker(key);
}
});
}
}
init();

View file

@ -297,8 +297,9 @@ function Teleporter() {
} else if (teleportLocationType === TARGET.SURFACE) { } else if (teleportLocationType === TARGET.SURFACE) {
var offset = getAvatarFootOffset(); var offset = getAvatarFootOffset();
intersection.intersection.y += offset; intersection.intersection.y += offset;
MyAvatar.position = intersection.intersection; MyAvatar.goToLocation(intersection.intersection, false, {x: 0, y: 0, z: 0, w: 1}, false);
HMD.centerUI(); HMD.centerUI();
MyAvatar.centerBody();
} }
} }
}; };

View file

@ -543,12 +543,14 @@ function connectionRequestCompleted() { // Final result is in. Do effects.
// don't change state (so animation continues while gripped) // don't change state (so animation continues while gripped)
// but do send a notification, by calling the slot that emits the signal for it // but do send a notification, by calling the slot that emits the signal for it
Window.makeConnection(true, result.connection.new_connection ? "You and " + result.connection.username + " are now connected!" : result.connection.username); Window.makeConnection(true, result.connection.new_connection ? "You and " + result.connection.username + " are now connected!" : result.connection.username);
UserActivityLogger.makeUserConnection(connectingId, true, result.connection.new_connection ? "new connection" : "already connected");
return; return;
} // failed } // failed
endHandshake(); endHandshake();
debug("failing with result data", result); debug("failing with result data", result);
// IWBNI we also did some fail sound/visual effect. // IWBNI we also did some fail sound/visual effect.
Window.makeConnection(false, result.connection); Window.makeConnection(false, result.connection);
UserActivityLogger.makeUserConnection(connectingId, false, result.connection);
} }
var POLL_INTERVAL_MS = 200, POLL_LIMIT = 5; var POLL_INTERVAL_MS = 200, POLL_LIMIT = 5;
function handleConnectionResponseAndMaybeRepeat(error, response) { function handleConnectionResponseAndMaybeRepeat(error, response) {
@ -573,6 +575,7 @@ function handleConnectionResponseAndMaybeRepeat(error, response) {
} else if (error || (response.status !== 'success')) { } else if (error || (response.status !== 'success')) {
debug('server fail', error, response.status); debug('server fail', error, response.status);
result = error ? {status: 'error', connection: error} : response; result = error ? {status: 'error', connection: error} : response;
UserActivityLogger.makeUserConnection(connectingId, false, error || response);
connectionRequestCompleted(); connectionRequestCompleted();
} else { } else {
debug('server success', result); debug('server success', result);

View file

@ -269,13 +269,26 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
getConnectionData(); getConnectionData();
UserActivityLogger.palAction("refresh_connections", ""); UserActivityLogger.palAction("refresh_connections", "");
break; break;
case 'removeConnection':
connectionUserName = message.params;
request({
uri: METAVERSE_BASE + '/api/v1/user/connections/' + connectionUserName,
method: 'DELETE'
}, function (error, response) {
if (error || (response.status !== 'success')) {
print("Error: unable to remove connection", connectionUserName, error || response.status);
return;
}
getConnectionData();
});
break
case 'removeFriend': case 'removeFriend':
friendUserName = message.params; friendUserName = message.params;
request({ request({
uri: METAVERSE_BASE + '/api/v1/user/friends/' + friendUserName, uri: METAVERSE_BASE + '/api/v1/user/friends/' + friendUserName,
method: 'DELETE' method: 'DELETE'
}, function (error, response) { }, function (error, response) {
print(JSON.stringify(response));
if (error || (response.status !== 'success')) { if (error || (response.status !== 'success')) {
print("Error: unable to unfriend", friendUserName, error || response.status); print("Error: unable to unfriend", friendUserName, error || response.status);
return; return;