Merge branch 'master' of https://github.com/highfidelity/hifi into ambient

This commit is contained in:
samcake 2017-04-18 11:05:04 -07:00
commit c008a6dd14
19 changed files with 468 additions and 360 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 150" style="enable-background:new 0 0 50 150;" xml:space="preserve">
<style type="text/css">
.st0{fill:#414042;}
@ -8,21 +8,16 @@
.st2{fill:#1398BB;}
.st3{fill:#31D8FF;}
</style>
<g id="Layer_1">
<path class="st0" d="M33.72,85.08l-9.15-9.15l-0.74-0.74l0.74-0.74l9.35-9.35c0.59-0.59,0.59-1.56,0-2.15
c-0.29-0.29-0.67-0.45-1.08-0.45c-0.41,0-0.79,0.16-1.08,0.45L19.52,75.19l12.04,12.04c0.29,0.29,0.67,0.45,1.08,0.45
c0.41,0,0.79-0.16,1.08-0.45C34.31,86.64,34.31,85.67,33.72,85.08z"/>
<path class="st1" d="M33.72,33.45l-9.15-9.15l-0.74-0.74l0.74-0.74l9.35-9.35c0.59-0.59,0.59-1.56,0-2.15
c-0.29-0.29-0.67-0.45-1.08-0.45c-0.41,0-0.79,0.16-1.08,0.45L19.52,23.56L31.56,35.6c0.29,0.29,0.67,0.45,1.08,0.45
c0.41,0,0.79-0.16,1.08-0.45C34.31,35.01,34.31,34.04,33.72,33.45z"/>
<path class="st2" d="M17.99,124.82l12.78,12.78c1,1,2.63,1,3.63,0c1-1,1-2.63,0-3.63l-9.15-9.15l9.35-9.35c1-1,1-2.63,0-3.63
c-1-1-2.63-1-3.63,0L17.99,124.82z"/>
<path class="st3" d="M32.79,112.13c0.41,0,0.79,0.16,1.08,0.45c0.59,0.59,0.59,1.56,0,2.15l-9.35,9.35l-0.74,0.74l0.74,0.74
l9.15,9.15c0.59,0.59,0.59,1.56,0,2.15c-0.29,0.29-0.67,0.45-1.08,0.45c-0.41,0-0.79-0.16-1.08-0.45l-12.04-12.04l12.24-12.24
C32,112.29,32.38,112.13,32.79,112.13 M32.79,111.08c-0.66,0-1.31,0.25-1.82,0.75l-12.98,12.98l12.78,12.78
c0.5,0.5,1.16,0.75,1.82,0.75c0.66,0,1.31-0.25,1.82-0.75c1-1,1-2.63,0-3.63l-9.15-9.15l9.35-9.35c1-1,1-2.63,0-3.63
C34.1,111.34,33.44,111.08,32.79,111.08L32.79,111.08z"/>
</g>
<path class="st0" d="M33.4,87.4L22.1,76.1l-0.9-0.9l0.9-0.9l11.5-11.5c0.7-0.7,0.7-1.9,0-2.7c-0.3-0.3-0.8-0.5-1.3-0.5
s-1,0.2-1.3,0.5L15.9,75.2l14.9,14.9c0.4,0.4,0.8,0.6,1.3,0.6c0.5,0,1-0.2,1.3-0.6C34.2,89.3,34.2,88.2,33.4,87.4z"/>
<path class="st1" d="M33.4,37.1L22.1,25.8l-0.9-0.9l0.9-0.9l11.5-11.5c0.7-0.7,0.7-1.9,0-2.7c-0.3-0.4-0.8-0.6-1.3-0.6
s-1,0.2-1.3,0.6L15.9,24.9l14.9,14.9c0.4,0.4,0.8,0.5,1.3,0.5c0.5,0,1-0.2,1.3-0.5C34.2,39,34.2,37.8,33.4,37.1z"/>
<path class="st2" d="M14.1,124.8l15.8,15.8c1.2,1.2,3.2,1.2,4.5,0c1.2-1.2,1.2-3.2,0-4.5L23,124.8l11.5-11.5c1.2-1.2,1.2-3.2,0-4.5
c-1.2-1.2-3.2-1.2-4.5,0L14.1,124.8z"/>
<path class="st3" d="M32.4,109.2c0.5,0,1,0.2,1.3,0.6c0.7,0.7,0.7,1.9,0,2.7l-11.5,11.5l-0.9,0.9l0.9,0.9l11.3,11.3
c0.7,0.7,0.7,1.9,0,2.7c-0.4,0.4-0.8,0.6-1.3,0.6s-1-0.2-1.3-0.6l-14.9-14.9L31,109.7C31.4,109.4,31.9,109.2,32.4,109.2 M32.4,107.9
c-0.8,0-1.6,0.3-2.2,0.9l-16,16l15.8,15.8c0.6,0.6,1.4,0.9,2.2,0.9s1.6-0.3,2.2-0.9c1.2-1.2,1.2-3.2,0-4.5l-11.3-11.3l11.5-11.6
c1.2-1.2,1.2-3.2,0-4.5C34,108.2,33.2,107.9,32.4,107.9L32.4,107.9z"/>
<g id="Layer_2">
</g>
</svg>

Before

(image error) Size: 1.7 KiB

After

(image error) Size: 1.5 KiB

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 150" style="enable-background:new 0 0 50 150;" xml:space="preserve">
<style type="text/css">
.st0{fill:#414042;}
@ -8,21 +8,16 @@
.st2{fill:#1398BB;}
.st3{fill:#31D8FF;}
</style>
<g id="Layer_1">
<path class="st0" d="M21.12,62.95c-0.29-0.29-0.67-0.45-1.08-0.45c-0.41,0-0.79,0.16-1.08,0.45c-0.59,0.59-0.59,1.56,0,2.15
l9.35,9.35l0.74,0.74l-0.74,0.74l-9.15,9.15c-0.59,0.59-0.59,1.56,0,2.15c0.29,0.29,0.67,0.45,1.08,0.45
c0.41,0,0.79-0.16,1.08-0.45l12.04-12.04L21.12,62.95z"/>
<path class="st1" d="M21.12,11.32c-0.29-0.29-0.67-0.45-1.08-0.45c-0.41,0-0.79,0.16-1.08,0.45c-0.59,0.59-0.59,1.56,0,2.15
l9.35,9.35l0.74,0.74l-0.74,0.74l-9.15,9.15c-0.59,0.59-0.59,1.56,0,2.15c0.29,0.29,0.67,0.45,1.08,0.45
c0.41,0,0.79-0.16,1.08-0.45l12.04-12.04L21.12,11.32z"/>
<path class="st2" d="M34.9,124.82L22.11,137.6c-1,1-2.63,1-3.63,0c-1-1-1-2.63,0-3.63l9.15-9.15l-9.35-9.35c-1-1-1-2.63,0-3.63
c1-1,2.63-1,3.63,0L34.9,124.82z"/>
<path class="st3" d="M20.1,112.13c0.41,0,0.79,0.16,1.08,0.45l12.24,12.24l-12.04,12.04c-0.29,0.29-0.67,0.45-1.08,0.45
c-0.41,0-0.79-0.16-1.08-0.45c-0.59-0.59-0.59-1.56,0-2.15l9.15-9.15l0.74-0.74l-0.74-0.74l-9.35-9.35c-0.59-0.59-0.59-1.56,0-2.15
C19.31,112.29,19.69,112.13,20.1,112.13 M20.1,111.08c-0.66,0-1.31,0.25-1.82,0.75c-1,1-1,2.63,0,3.63l9.35,9.35l-9.15,9.15
c-1,1-1,2.63,0,3.63c0.5,0.5,1.16,0.75,1.82,0.75s1.31-0.25,1.82-0.75l12.78-12.78l-12.98-12.98
C21.41,111.34,20.76,111.08,20.1,111.08L20.1,111.08z"/>
</g>
<path class="st0" d="M21.1,60.1c-0.4-0.4-0.8-0.5-1.3-0.5s-1,0.2-1.3,0.5c-0.7,0.7-0.7,1.9,0,2.7l11.5,11.5l0.9,0.9l-0.9,0.9
L18.6,87.4c-0.7,0.7-0.7,1.9,0,2.7c0.4,0.3,0.8,0.6,1.3,0.6s1-0.2,1.3-0.6l14.9-14.9L21.1,60.1z"/>
<path class="st1" d="M21.1,9.8c-0.4-0.4-0.8-0.6-1.3-0.6s-1,0.2-1.3,0.6c-0.7,0.7-0.7,1.9,0,2.7L29.9,24l0.9,0.9l-0.9,0.9L18.6,37.1
c-0.7,0.7-0.7,1.9,0,2.7c0.4,0.4,0.8,0.5,1.3,0.5s1-0.2,1.3-0.5l14.9-14.9L21.1,9.8z"/>
<path class="st2" d="M38,124.8l-15.8,15.8c-1.2,1.2-3.2,1.2-4.5,0c-1.2-1.2-1.2-3.2,0-4.5L29,124.8l-11.5-11.5
c-1.2-1.2-1.2-3.2,0-4.5c1.2-1.2,3.2-1.2,4.5,0L38,124.8z"/>
<path class="st3" d="M19.7,109.2c0.5,0,1,0.2,1.3,0.6l15.1,15.1l-14.9,14.9c-0.4,0.4-0.8,0.6-1.3,0.6s-1-0.2-1.3-0.6
c-0.7-0.7-0.7-1.9,0-2.7l11.3-11.3l0.9-0.9l-0.9-0.9l-11.5-11.5c-0.7-0.7-0.7-1.9,0-2.7C18.8,109.4,19.2,109.2,19.7,109.2
M19.7,107.9c-0.8,0-1.6,0.3-2.2,0.9c-1.2,1.2-1.2,3.2,0,4.5L29,124.8l-11.3,11.3c-1.2,1.2-1.2,3.2,0,4.5c0.6,0.6,1.4,0.9,2.2,0.9
s1.6-0.3,2.2-0.9L38,124.8l-16-16C21.4,108.2,20.5,107.9,19.7,107.9L19.7,107.9z"/>
<g id="Layer_2">
</g>
</svg>

Before

(image error) Size: 1.7 KiB

After

(image error) Size: 1.5 KiB

View file

@ -0,0 +1,53 @@
//
// TabletWebButton.qml
//
// Created by Dante Ruiz on 2017/4/13
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import Hifi 1.0
import QtQuick 2.4
import "../styles-uit"
Rectangle {
property alias text: label.text
property alias pixelSize: label.font.pixelSize;
property bool selected: false
property bool hovered: false
property bool enabled: false
property int spacing: 2
property var action: function () {}
property string enabledColor: hifi.colors.blueHighlight
property string disabledColor: hifi.colors.blueHighlight
property string highlightColor: hifi.colors.blueHighlight;
width: label.width + 64
height: 32
color: hifi.colors.white
HifiConstants { id: hifi }
RalewaySemiBold {
id: label;
color: enabledColor
font.pixelSize: 15;
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter;
}
}
Rectangle {
id: indicator
width: parent.width
height: selected ? 3 : 1
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
color: hifi.colors.blueHighlight
visible: parent.selected || hovered
}
}

View file

@ -2,97 +2,81 @@ import QtQuick 2.5
import QtQuick.Controls 1.4
import QtWebEngine 1.2
import QtWebChannel 1.0
import HFTabletWebEngineProfile 1.0
import "../controls-uit" as HiFiControls
import "../styles" as HifiStyles
import "../styles-uit"
import HFWebEngineProfile 1.0
import HFTabletWebEngineProfile 1.0
import "../"
import "."
Item {
id: web
HifiConstants { id: hifi }
width: parent.width
height: parent.height
property var parentStackItem: null
property int headerHeight: 38
property int headerHeight: 70
property string url
property string address: url //for compatibility
property alias address: displayUrl.text //for compatibility
property string scriptURL
property alias eventBridge: eventBridgeWrapper.eventBridge
property bool keyboardEnabled: HMD.active
property bool keyboardRaised: false
property bool punctuationMode: false
property bool isDesktop: false
property WebEngineView view: loader.currentView
property int currentPage: -1 // used as a model for repeater
property alias pagesModel: pagesModel
Row {
Rectangle {
id: buttons
HifiConstants { id: hifi }
HifiStyles.HifiConstants { id: hifistyles }
height: headerHeight
spacing: 4
anchors.top: parent.top
anchors.topMargin: 8
anchors.left: parent.left
anchors.leftMargin: 8
HiFiGlyphs {
id: back;
enabled: currentPage >= 0
text: hifi.glyphs.backward
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
size: 48
MouseArea { anchors.fill: parent; onClicked: goBack() }
}
HiFiGlyphs {
id: forward;
enabled: currentPage < pagesModel.count - 1
text: hifi.glyphs.forward
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
size: 48
MouseArea { anchors.fill: parent; onClicked: goForward() }
}
HiFiGlyphs {
id: reload;
enabled: view != null;
text: (view !== null && view.loading) ? hifi.glyphs.close : hifi.glyphs.reload
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
size: 48
MouseArea { anchors.fill: parent; onClicked: reloadPage(); }
}
}
width: parent.width
height: parent.headerHeight
color: hifi.colors.white
TextField {
id: addressBar
height: 30
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: buttons.right
anchors.leftMargin: 0
anchors.verticalCenter: buttons.verticalCenter
focus: true
text: address
Component.onCompleted: ScriptDiscoveryService.scriptsModelFilter.filterRegExp = new RegExp("^.*$", "i")
Row {
id: nav
anchors {
top: parent.top
topMargin: 10
horizontalCenter: parent.horizontalCenter
}
spacing: 120
TabletWebButton {
id: back
enabledColor: hifi.colors.baseGray
enabled: false
text: "BACK"
Keys.onPressed: {
switch (event.key) {
case Qt.Key_Enter:
case Qt.Key_Return:
event.accepted = true;
if (text.indexOf("http") != 0) {
text = "http://" + text;
}
//root.hidePermissionsBar();
web.keyboardRaised = false;
gotoPage(text);
break;
MouseArea {
anchors.fill: parent
onClicked: goBack()
hoverEnabled: true
}
}
TabletWebButton {
id: close
enabledColor: hifi.colors.darkGray
text: "CLOSE"
MouseArea {
anchors.fill: parent
onClicked: closeWebEngine()
}
}
}
RalewaySemiBold {
id: displayUrl
color: hifi.colors.baseGray
font.pixelSize: 12
anchors {
top: nav.bottom
horizontalCenter: parent.horizontalCenter;
}
}
}
@ -100,15 +84,30 @@ Item {
ListModel {
id: pagesModel
onCountChanged: {
currentPage = count - 1
currentPage = count - 1;
if (currentPage > 0) {
back.enabledColor = hifi.colors.darkGray;
} else {
back.enabledColor = hifi.colors.baseGray;
}
}
}
function goBack() {
if (currentPage > 0) {
currentPage--;
} else if (parentStackItem) {
if (webview.canGoBack) {
pagesModel.remove(currentPage);
webview.goBack();
} else if (currentPage > 0) {
pagesModel.remove(currentPage);
}
}
function closeWebEngine() {
if (parentStackItem) {
parentStackItem.pop();
} else {
web.visible = false;
}
}
@ -130,18 +129,20 @@ Item {
function urlAppend(url) {
var lurl = decodeURIComponent(url)
if (lurl[lurl.length - 1] !== "/")
if (lurl[lurl.length - 1] !== "/") {
lurl = lurl + "/"
if (currentPage === -1 || pagesModel.get(currentPage).webUrl !== lurl) {
pagesModel.append({webUrl: lurl})
}
if (currentPage === -1 || (pagesModel.get(currentPage).webUrl !== lurl && !timer.running)) {
timer.start();
pagesModel.append({webUrl: lurl});
}
}
onCurrentPageChanged: {
if (currentPage >= 0 && currentPage < pagesModel.count && loader.item !== null) {
loader.item.url = pagesModel.get(currentPage).webUrl
web.url = loader.item.url
web.address = loader.item.url
if (currentPage >= 0 && currentPage < pagesModel.count) {
webview.url = pagesModel.get(currentPage).webUrl;
web.url = webview.url;
web.address = webview.url;
}
}
@ -155,45 +156,110 @@ Item {
property var eventBridge;
}
Loader {
id: loader
Timer {
id: timer
interval: 100
running: false
repeat: false
onTriggered: timer.stop();
}
property WebEngineView currentView: null
WebEngineView {
id: webview
objectName: "webEngineView"
x: 0
y: 0
width: parent.width
height: parent.height - web.headerHeight
asynchronous: true
height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height - web.headerHeight : parent.height - web.headerHeight
anchors.top: buttons.bottom
active: false
source: "../TabletBrowser.qml"
onStatusChanged: {
if (loader.status === Loader.Ready) {
currentView = item.webView
item.webView.userScriptUrl = web.scriptURL
if (currentPage >= 0) {
//we got something to load already
item.url = pagesModel.get(currentPage).webUrl
web.address = loader.item.url
profile: HFTabletWebEngineProfile {
id: webviewTabletProfile
storageName: "qmlTabletWebEngine"
}
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: webview.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
webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) {
console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message);
});
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) {
urlAppend(loadRequest.url.toString())
var url = loadRequest.url.toString();
if (urlHandler.canHandleUrl(url)) {
if (urlHandler.handleUrl(url)) {
root.stop();
}
}
}
}
}
onNewViewRequested: {
request.openIn(webview);
}
}
Component.onCompleted: {
web.isDesktop = (typeof desktop !== "undefined");
address = url;
loader.active = true
}
Keys.onPressed: {
Keys.onPressed: {
switch(event.key) {
case Qt.Key_L:
if (event.modifiers == Qt.ControlModifier) {
event.accepted = true
addressBar.selectAll()
addressBar.forceActiveFocus()
}
break;
case Qt.Key_L:
if (event.modifiers == Qt.ControlModifier) {
event.accepted = true
}
break;
}
}
}

View file

@ -20,8 +20,10 @@ import "../toolbars"
import "../../styles-uit" as HifiStyles
import "../../controls-uit" as HifiControls
// references HMD, AddressManager, AddressBarDialog from root context
StackView {
id: root
id: root;
HifiConstants { id: hifi }
HifiStyles.HifiConstants { id: hifiStyleConstants }
initialItem: addressBarDialog
@ -34,24 +36,16 @@ StackView {
property string metaverseBase: addressBarDialog.metaverseServerUrl + "/api/v1/";
property var tablet: null;
property bool isDesktop: false;
Component { id: tabletStoryCard; TabletStoryCard {} }
Component { id: tabletWebView; TabletWebView {} }
Component.onCompleted: {
root.currentItem.focus = true;
root.currentItem.forceActiveFocus();
addressLine.focus = true;
addressLine.forceActiveFocus();
fillDestinations();
updateLocationText(false);
fillDestinations();
addressLine.focus = !HMD.active;
root.parentChanged.connect(center);
center();
isDesktop = (typeof desktop !== "undefined");
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
if (desktop) {
root.title = "GOTO";
}
}
Component.onDestruction: {
root.parentChanged.disconnect(center);
@ -68,9 +62,9 @@ StackView {
}
function goCard(targetString) {
if (0 !== targetString.indexOf('hifi://')) {
var card = tabletStoryCard.createObject();
card.setUrl(addressBarDialog.metaverseServerUrl + targetString);
card.eventBridge = root.eventBridge;
var card = tabletWebView.createObject();
card.url = addressBarDialog.metaverseServerUrl + targetString;
card.parentStackItem = root;
root.push(card);
return;
}
@ -78,8 +72,6 @@ StackView {
toggleOrGo(true, targetString);
clearAddressLineTimer.start();
}
property bool isCursorVisible: false // Override default cursor visibility.
AddressBarDialog {
@ -102,16 +94,11 @@ StackView {
onMetaverseServerUrlChanged: updateLocationTextTimer.start();
Rectangle {
id: navBar
width: 480
height: 70
width: parent.width
height: 50;
color: hifiStyleConstants.colors.white
anchors {
top: parent.top
right: parent.right
rightMargin: 0
left: parent.left
leftMargin: 0
}
anchors.top: parent.top;
anchors.left: parent.left;
ToolbarButton {
id: homeButton
@ -129,8 +116,14 @@ StackView {
}
ToolbarButton {
id: backArrow;
buttonState: addressBarDialog.backEnabled;
imageURL: "../../../images/backward.svg";
onClicked: addressBarDialog.loadBack();
buttonEnabled: addressBarDialog.backEnabled;
onClicked: {
if (buttonEnabled) {
addressBarDialog.loadBack();
}
}
anchors {
left: homeButton.right
verticalCenter: parent.verticalCenter
@ -138,8 +131,14 @@ StackView {
}
ToolbarButton {
id: forwardArrow;
buttonState: addressBarDialog.forwardEnabled;
imageURL: "../../../images/forward.svg";
onClicked: addressBarDialog.loadForward();
buttonEnabled: addressBarDialog.forwardEnabled;
onClicked: {
if (buttonEnabled) {
addressBarDialog.loadForward();
}
}
anchors {
left: backArrow.right
verticalCenter: parent.verticalCenter
@ -149,85 +148,80 @@ StackView {
Rectangle {
id: addressBar
width: 480
width: parent.width
height: 70
color: hifiStyleConstants.colors.white
anchors {
top: navBar.bottom
right: parent.right
rightMargin: 16
left: parent.left
leftMargin: 16
top: navBar.bottom;
left: parent.left;
}
property int inputAreaHeight: 70
property int inputAreaStep: (height - inputAreaHeight) / 2
HifiStyles.RalewayLight {
id: notice;
font.pixelSize: hifi.fonts.pixelSize * 0.50;
font.pixelSize: hifi.fonts.pixelSize * 0.7;
anchors {
top: parent.top
topMargin: parent.inputAreaStep + 12
left: addressLine.left
right: addressLine.right
top: parent.top;
left: addressLineContainer.left;
right: addressLineContainer.right;
}
}
HifiStyles.FiraSansRegular {
id: location;
anchors {
left: addressLineContainer.left;
leftMargin: 8;
verticalCenter: addressLineContainer.verticalCenter;
}
font.pixelSize: addressLine.font.pixelSize;
color: "gray";
clip: true;
anchors.fill: addressLine;
visible: addressLine.text.length === 0
}
TextInput {
id: addressLine
focus: true
width: addressLineContainer.width - addressLineContainer.anchors.leftMargin - addressLineContainer.anchors.rightMargin;
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
leftMargin: 16
rightMargin: 16
topMargin: parent.inputAreaStep + (2 * hifi.layout.spacing)
bottomMargin: parent.inputAreaStep
left: addressLineContainer.left;
leftMargin: 8;
verticalCenter: addressLineContainer.verticalCenter;
}
font.pixelSize: hifi.fonts.pixelSize * 0.75
cursorVisible: false
onTextChanged: {
filterChoicesByText();
updateLocationText(text.length > 0);
if (!isCursorVisible && text.length > 0) {
isCursorVisible = true;
cursorVisible = true;
}
}
onAccepted: {
addressBarDialog.keyboardEnabled = false;
}
onActiveFocusChanged: {
cursorVisible = isCursorVisible && focus;
}
MouseArea {
// If user clicks in address bar show cursor to indicate ability to enter address.
anchors.fill: parent
onClicked: {
isCursorVisible = true;
parent.cursorVisible = true;
parent.focus = true;
parent.forceActiveFocus();
addressBarDialog.keyboardEnabled = HMD.active
tabletRoot.playButtonClickSound();
}
toggleOrGo();
}
}
Rectangle {
anchors.fill: addressLine
id: addressLineContainer;
height: 40;
anchors {
top: notice.bottom;
topMargin: 2;
left: parent.left;
leftMargin: 16;
right: parent.right;
rightMargin: 16;
}
color: hifiStyleConstants.colors.lightGray
opacity: 0.1
MouseArea {
anchors.fill: parent;
onClicked: {
if (!addressLine.focus || !HMD.active) {
addressLine.focus = true;
addressLine.forceActiveFocus();
addressBarDialog.keyboardEnabled = HMD.active;
}
tabletRoot.playButtonClickSound();
}
}
}
}
Rectangle {
@ -347,13 +341,12 @@ StackView {
Timer {
// Delay clearing address line so as to avoid flicker of "not connected" being displayed after entering an address.
id: clearAddressLineTimer
running: false
interval: 100 // ms
repeat: false
id: clearAddressLineTimer;
running: false;
interval: 100; // ms
repeat: false;
onTriggered: {
addressLine.text = "";
isCursorVisible = false;
}
}
@ -535,7 +528,7 @@ StackView {
function updateLocationText(enteringAddress) {
if (enteringAddress) {
notice.text = "Go to a place, @user, path or network address";
notice.text = "Go To a place, @user, path, or network address:";
notice.color = hifiStyleConstants.colors.baseGrayHighlight;
} else {
notice.text = AddressManager.isConnected ? "Your location:" : "Not Connected";
@ -545,46 +538,14 @@ StackView {
}
}
onVisibleChanged: {
updateLocationText(false);
if (visible) {
addressLine.forceActiveFocus();
fillDestinations();
}
}
function toggleOrGo(fromSuggestions, address) {
if (address !== undefined && address !== "") {
addressBarDialog.loadAddress(address, fromSuggestions)
}
if (addressLine.text !== "") {
addressBarDialog.loadAddress(addressLine.text, fromSuggestions)
}
if (isDesktop) {
tablet.gotoHomeScreen();
} else {
HMD.closeTablet();
}
tabletRoot.shown = false;
}
Keys.onPressed: {
switch (event.key) {
case Qt.Key_Escape:
case Qt.Key_Back:
tabletRoot.shown = false
clearAddressLineTimer.start();
event.accepted = true
break
case Qt.Key_Enter:
case Qt.Key_Return:
toggleOrGo()
clearAddressLineTimer.start();
event.accepted = true
break
addressBarDialog.loadAddress(address, fromSuggestions);
clearAddressLineTimer.start();
} else if (addressLine.text !== "") {
addressBarDialog.loadAddress(addressLine.text, fromSuggestions);
clearAddressLineTimer.start();
}
DialogsManager.hideAddressBar();
}
}

View file

@ -1,46 +0,0 @@
//
// TabletAddressDialog.qml
//
// Created by Dante Ruiz on 2017/04/24
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import Hifi 1.0
import QtQuick 2.4
import QtGraphicalEffects 1.0
import "../../controls"
import "../../styles"
import "../../windows"
import "../"
import "../toolbars"
import "../../styles-uit" as HifiStyles
import "../../controls-uit" as HifiControlsUit
import "../../controls" as HifiControls
Rectangle {
id: cardRoot
HifiStyles.HifiConstants { id: hifi }
width: parent.width
height: parent.height
property string address: ""
property alias eventBridge: webview.eventBridge
function setUrl(url) {
cardRoot.address = url;
webview.url = url;
}
HifiControls.TabletWebView {
id: webview
parentStackItem: root
anchors {
top: parent.top
right: parent.right
left: parent.left
bottom: parent.bottom
}
}
}

View file

@ -3,6 +3,8 @@ import QtQuick.Controls 1.4
StateImage {
id: button
property bool buttonEnabled: true
property bool isActive: false
property bool isEntered: false
@ -39,30 +41,37 @@ StateImage {
}
function updateState() {
if (!button.isEntered && !button.isActive) {
buttonState = imageOffOut;
} else if (!button.isEntered && button.isActive) {
buttonState = imageOnOut;
} else if (button.isEntered && !button.isActive) {
buttonState = imageOffIn;
if (buttonEnabled) {
if (!button.isEntered && !button.isActive) {
buttonState = imageOffOut;
} else if (!button.isEntered && button.isActive) {
buttonState = imageOnOut;
} else if (button.isEntered && !button.isActive) {
buttonState = imageOffIn;
} else {
buttonState = imageOnIn;
}
} else {
buttonState = imageOnIn;
buttonState = 0;
}
}
onIsActiveChanged: updateState();
onButtonEnabledChanged: updateState();
Timer {
id: asyncClickSender
interval: 10
repeat: false
running: false
onTriggered: button.clicked();
onTriggered: {
button.clicked();
}
}
MouseArea {
id: mouseArea
hoverEnabled: true
hoverEnabled: buttonEnabled
anchors.fill: parent
onClicked: asyncClickSender.start();
onEntered: {

View file

@ -1420,11 +1420,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(DependencyManager::get<AudioClient>().data(), &AudioClient::mutedByMixer, this, onMutedByMixer);
// Track when the address bar is opened
auto onAddressBarToggled = [this]() {
auto onAddressBarShown = [this]() {
// Record time
UserActivityLogger::getInstance().logAction("opened_address_bar", { { "uptime_ms", _sessionRunTimer.elapsed() } });
};
connect(DependencyManager::get<DialogsManager>().data(), &DialogsManager::addressBarToggled, this, onAddressBarToggled);
connect(DependencyManager::get<DialogsManager>().data(), &DialogsManager::addressBarShown, this, onAddressBarShown);
// Make sure we don't time out during slow operations at startup
updateHeartbeat();

View file

@ -254,7 +254,7 @@ Menu::Menu() {
// Navigate > Show Address Bar
addActionToQMenuAndActionHash(navigateMenu, MenuOption::AddressBar, Qt::CTRL | Qt::Key_L,
dialogsManager.data(), SLOT(toggleAddressBar()));
dialogsManager.data(), SLOT(showAddressBar()));
// Navigate > Bookmark related menus -- Note: the Bookmark class adds its own submenus here.
qApp->getBookmarks()->setupMenus(this, navigateMenu);

View file

@ -96,6 +96,14 @@ Avatar::Avatar(RigPointer rig) :
_lastOrientation(),
_worldUpDirection(DEFAULT_UP_DIRECTION),
_moving(false),
_smoothPositionTime(SMOOTH_TIME_POSITION),
_smoothPositionTimer(std::numeric_limits<float>::max()),
_smoothOrientationTime(SMOOTH_TIME_ORIENTATION),
_smoothOrientationTimer(std::numeric_limits<float>::max()),
_smoothPositionInitial(),
_smoothPositionTarget(),
_smoothOrientationInitial(),
_smoothOrientationTarget(),
_initialized(false),
_voiceSphereID(GeometryCache::UNKNOWN_ID)
{
@ -349,6 +357,33 @@ void Avatar::simulate(float deltaTime, bool inView) {
_simulationInViewRate.increment();
}
if (!isMyAvatar()) {
if (_smoothPositionTimer < _smoothPositionTime) {
// Smooth the remote avatar movement.
_smoothPositionTimer += deltaTime;
if (_smoothPositionTimer < _smoothPositionTime) {
AvatarData::setPosition(
lerp(_smoothPositionInitial,
_smoothPositionTarget,
easeInOutQuad(glm::clamp(_smoothPositionTimer / _smoothPositionTime, 0.0f, 1.0f)))
);
updateAttitude();
}
}
if (_smoothOrientationTimer < _smoothOrientationTime) {
// Smooth the remote avatar movement.
_smoothOrientationTimer += deltaTime;
if (_smoothOrientationTimer < _smoothOrientationTime) {
AvatarData::setOrientation(
slerp(_smoothOrientationInitial,
_smoothOrientationTarget,
easeInOutQuad(glm::clamp(_smoothOrientationTimer / _smoothOrientationTime, 0.0f, 1.0f)))
);
updateAttitude();
}
}
}
PerformanceTimer perfTimer("simulate");
{
@ -1361,13 +1396,31 @@ glm::quat Avatar::getUncachedRightPalmRotation() const {
}
void Avatar::setPosition(const glm::vec3& position) {
AvatarData::setPosition(position);
updateAttitude();
if (isMyAvatar()) {
// This is the local avatar, no need to handle any position smoothing.
AvatarData::setPosition(position);
updateAttitude();
return;
}
// Whether or not there is an existing smoothing going on, just reset the smoothing timer and set the starting position as the avatar's current position, then smooth to the new position.
_smoothPositionInitial = getPosition();
_smoothPositionTarget = position;
_smoothPositionTimer = 0.0f;
}
void Avatar::setOrientation(const glm::quat& orientation) {
AvatarData::setOrientation(orientation);
updateAttitude();
if (isMyAvatar()) {
// This is the local avatar, no need to handle any position smoothing.
AvatarData::setOrientation(orientation);
updateAttitude();
return;
}
// Whether or not there is an existing smoothing going on, just reset the smoothing timer and set the starting position as the avatar's current position, then smooth to the new position.
_smoothOrientationInitial = getOrientation();
_smoothOrientationTarget = orientation;
_smoothOrientationTimer = 0.0f;
}
void Avatar::updatePalms() {

View file

@ -230,6 +230,16 @@ public:
bool hasNewJointData() const { return _hasNewJointData; }
inline float easeInOutQuad(float lerpValue) {
assert(!((lerpValue < 0.0f) || (lerpValue > 1.0f)));
if (lerpValue < 0.5f) {
return (2.0f * lerpValue * lerpValue);
}
return (lerpValue*(4.0f - 2.0f * lerpValue) - 1.0f);
}
public slots:
// FIXME - these should be migrated to use Pose data instead
@ -244,6 +254,9 @@ public slots:
protected:
friend class AvatarManager;
const float SMOOTH_TIME_POSITION = 0.125f;
const float SMOOTH_TIME_ORIENTATION = 0.075f;
virtual const QString& getSessionDisplayNameForTransport() const override { return _empty; } // Save a tiny bit of bandwidth. Mixer won't look at what we send.
QString _empty{};
virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) override { _sessionDisplayName = sessionDisplayName; } // don't use no-op setter!
@ -313,6 +326,15 @@ protected:
RateCounter<> _skeletonModelSimulationRate;
RateCounter<> _jointDataSimulationRate;
// Smoothing data for blending from one position/orientation to another on remote agents.
float _smoothPositionTime;
float _smoothPositionTimer;
float _smoothOrientationTime;
float _smoothOrientationTimer;
glm::vec3 _smoothPositionInitial;
glm::vec3 _smoothPositionTarget;
glm::quat _smoothOrientationInitial;
glm::quat _smoothOrientationTarget;
private:
class AvatarEntityDataHash {

View file

@ -34,9 +34,13 @@ void HFTabletWebEngineRequestInterceptor::interceptRequest(QWebEngineUrlRequestI
QString bearerTokenString = "Bearer " + accountManager->getAccountInfo().getAccessToken().token;
info.setHttpHeader(OAUTH_AUTHORIZATION_HEADER.toLocal8Bit(), bearerTokenString.toLocal8Bit());
}
}
static const QString USER_AGENT = "User-Agent";
QString tokenString = "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";
info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit());
static const QString USER_AGENT = "User-Agent";
QString tokenString = "Chrome/48.0 (HighFidelityInterface)";
info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit());
} else {
static const QString USER_AGENT = "User-Agent";
QString tokenString = "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";
info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit());
}
}

View file

@ -16,15 +16,24 @@
#include "ui/DialogsManager.h"
DialogsManagerScriptingInterface::DialogsManagerScriptingInterface() {
connect(DependencyManager::get<DialogsManager>().data(), &DialogsManager::addressBarToggled,
this, &DialogsManagerScriptingInterface::addressBarToggled);
connect(DependencyManager::get<DialogsManager>().data(), &DialogsManager::addressBarShown,
this, &DialogsManagerScriptingInterface::addressBarShown);
}
void DialogsManagerScriptingInterface::toggleAddressBar() {
DialogsManagerScriptingInterface* DialogsManagerScriptingInterface::getInstance() {
static DialogsManagerScriptingInterface sharedInstance;
return &sharedInstance;
}
void DialogsManagerScriptingInterface::showAddressBar() {
QMetaObject::invokeMethod(DependencyManager::get<DialogsManager>().data(),
"toggleAddressBar", Qt::QueuedConnection);
"showAddressBar", Qt::QueuedConnection);
}
void DialogsManagerScriptingInterface::hideAddressBar() {
QMetaObject::invokeMethod(DependencyManager::get<DialogsManager>().data(),
"hideAddressBar", Qt::QueuedConnection);
}
void DialogsManagerScriptingInterface::showFeed() {

View file

@ -18,13 +18,14 @@ class DialogsManagerScriptingInterface : public QObject {
Q_OBJECT
public:
DialogsManagerScriptingInterface();
static DialogsManagerScriptingInterface* getInstance();
Q_INVOKABLE void showFeed();
public slots:
void toggleAddressBar();
void showAddressBar();
void hideAddressBar();
signals:
void addressBarToggled();
void addressBarShown(bool visible);
};

View file

@ -46,49 +46,32 @@ void DialogsManager::maybeCreateDialog(QPointer<T>& member) {
}
}
void DialogsManager::toggleAddressBar() {
auto hmd = DependencyManager::get<HMDScriptingInterface>();
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
if (tablet->getToolbarMode()) {
if (tablet->isPathLoaded(TABLET_ADDRESS_DIALOG)) {
tablet->gotoHomeScreen();
emit addressBarToggled();
} else {
tablet->loadQMLSource(TABLET_ADDRESS_DIALOG);
emit addressBarToggled();
}
} else {
if (hmd->getShouldShowTablet()) {
if (tablet->isPathLoaded(TABLET_ADDRESS_DIALOG) && _closeAddressBar) {
tablet->gotoHomeScreen();
hmd->closeTablet();
_closeAddressBar = false;
emit addressBarToggled();
} else {
tablet->loadQMLSource(TABLET_ADDRESS_DIALOG);
_closeAddressBar = true;
emit addressBarToggled();
}
} else {
tablet->loadQMLSource(TABLET_ADDRESS_DIALOG);
hmd->openTablet();
_closeAddressBar = true;
emit addressBarToggled();
}
}
}
void DialogsManager::showAddressBar() {
auto hmd = DependencyManager::get<HMDScriptingInterface>();
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
tablet->loadQMLSource(TABLET_ADDRESS_DIALOG);
if (!tablet->isPathLoaded(TABLET_ADDRESS_DIALOG)) {
tablet->loadQMLSource(TABLET_ADDRESS_DIALOG);
}
if (!hmd->getShouldShowTablet()) {
hmd->openTablet();
}
qApp->setKeyboardFocusOverlay(hmd->getCurrentTabletScreenID());
emit addressBarShown(true);
}
void DialogsManager::hideAddressBar() {
auto hmd = DependencyManager::get<HMDScriptingInterface>();
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
if (tablet->isPathLoaded(TABLET_ADDRESS_DIALOG)) {
tablet->gotoHomeScreen();
hmd->closeTablet();
}
qApp->setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
emit addressBarShown(false);
}
void DialogsManager::showFeed() {

View file

@ -41,8 +41,8 @@ public:
void emitAddressBarShown(bool visible) { emit addressBarShown(visible); }
public slots:
void toggleAddressBar();
void showAddressBar();
void hideAddressBar();
void showFeed();
void setDomainConnectionFailureVisibility(bool visible);
void toggleLoginDialog();
@ -57,7 +57,6 @@ public slots:
void showUpdateDialog();
signals:
void addressBarToggled();
void addressBarShown(bool visible);
void setUseFeed(bool useFeed);

View file

@ -40,6 +40,9 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) {
QJsonObject userStoryObject;
QJsonObject detailsObject;
detailsObject.insert("image_url", imageUrl);
if (dataObject.contains("shareable_url")) {
detailsObject.insert("shareable_url", dataObject.value("shareable_url").toString());
}
QString pickledDetails = QJsonDocument(detailsObject).toJson();
userStoryObject.insert("details", pickledDetails);
userStoryObject.insert("thumbnail_url", thumbnailUrl);

View file

@ -198,6 +198,7 @@ void Web3DOverlay::loadSourceURL() {
_webSurface->getRootContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
_webSurface->getRootContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance());
_webSurface->getRootContext()->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data());
_webSurface->getRootContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance());
_webSurface->getRootContext()->setContextProperty("pathToFonts", "../../");
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data());

View file

@ -41,7 +41,7 @@ public:
Q_INVOKABLE QVector<QUuid> getAvatarIdentifiers();
// Null/Default-constructed QUuids will return MyAvatar
virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); }
int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters);