mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 15:24:03 +02:00
Working on new-UI implementations of address bar and login
This commit is contained in:
parent
fe482b35ff
commit
d14d5f3d29
45 changed files with 1844 additions and 728 deletions
|
@ -92,6 +92,15 @@ else ()
|
||||||
if (NOT QT_CMAKE_PREFIX_PATH)
|
if (NOT QT_CMAKE_PREFIX_PATH)
|
||||||
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
|
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
|
||||||
endif ()
|
endif ()
|
||||||
|
if (NOT QT_CMAKE_PREFIX_PATH)
|
||||||
|
get_filename_component(QT_CMAKE_PREFIX_PATH "${Qt5_DIR}/.." REALPATH)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
if (NOT EXISTS ${QT_CMAKE_PREFIX_PATH})
|
||||||
|
message(FATAL_ERROR "Could not determine QT_CMAKE_PREFIX_PATH.")
|
||||||
|
endif ()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# figure out where the qt dir is
|
# figure out where the qt dir is
|
||||||
|
|
|
@ -54,7 +54,7 @@ else ()
|
||||||
list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP})
|
list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
find_package(Qt5 COMPONENTS Gui Multimedia Network OpenGL Script Svg WebKitWidgets)
|
find_package(Qt5 COMPONENTS Gui Multimedia Network OpenGL Qml Quick Script Svg WebKitWidgets)
|
||||||
|
|
||||||
# grab the ui files in resources/ui
|
# grab the ui files in resources/ui
|
||||||
file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
|
file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
|
||||||
|
|
84
interface/resources/qml/AddressBarDialog.qml
Normal file
84
interface/resources/qml/AddressBarDialog.qml
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import Hifi 1.0
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
|
||||||
|
AddressBarDialog {
|
||||||
|
id: addressBarDialog
|
||||||
|
objectName: "AddressBarDialog"
|
||||||
|
SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
|
||||||
|
height: 128
|
||||||
|
width: 512
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (!visible) {
|
||||||
|
reset();
|
||||||
|
} else {
|
||||||
|
addressLine.focus = true
|
||||||
|
addressLine.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
addressLine.focus = true
|
||||||
|
addressLine.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
addressLine.text = ""
|
||||||
|
goButton.source = "../images/address-bar-submit.svg"
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomDialog {
|
||||||
|
id: dialog
|
||||||
|
anchors.fill: parent
|
||||||
|
title: "Go to..."
|
||||||
|
|
||||||
|
// The client area
|
||||||
|
Item {
|
||||||
|
id: item1
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: parent.margins
|
||||||
|
anchors.topMargin: parent.topMargin
|
||||||
|
|
||||||
|
CustomBorder {
|
||||||
|
height: 64
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
anchors.right: goButton.left
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
CustomTextInput {
|
||||||
|
id: addressLine
|
||||||
|
anchors.fill: parent
|
||||||
|
helperText: "domain, location, @user, /x,y,z"
|
||||||
|
anchors.margins: 8
|
||||||
|
onAccepted: {
|
||||||
|
addressBarDialog.loadAddress(addressLine.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: goButton
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
source: "../images/address-bar-submit.svg"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
parent.source = "../images/address-bar-submit-active.svg"
|
||||||
|
addressBarDialog.loadAddress(addressLine.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
12
interface/resources/qml/CustomBorder.qml
Normal file
12
interface/resources/qml/CustomBorder.qml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
|
||||||
|
property int margin: 5
|
||||||
|
color: myPalette.window
|
||||||
|
border.color: myPalette.dark
|
||||||
|
border.width: 5
|
||||||
|
radius: border.width * 2
|
||||||
|
}
|
||||||
|
|
23
interface/resources/qml/CustomButton.qml
Normal file
23
interface/resources/qml/CustomButton.qml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.3
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
|
||||||
|
Button {
|
||||||
|
SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
|
||||||
|
text: "Text"
|
||||||
|
width: 128
|
||||||
|
height: 64
|
||||||
|
style: ButtonStyle {
|
||||||
|
background: CustomBorder {
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
label: CustomText {
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: control.text
|
||||||
|
color: control.enabled ? myPalette.text : myPalette.dark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
interface/resources/qml/CustomDialog.qml
Normal file
98
interface/resources/qml/CustomDialog.qml
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
import "hifiConstants.js" as HifiConstants
|
||||||
|
|
||||||
|
Item {
|
||||||
|
SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
|
||||||
|
|
||||||
|
id: dialog
|
||||||
|
width: 256
|
||||||
|
height: 256
|
||||||
|
property rect clientArea: clientBorder
|
||||||
|
property int topMargin: dialog.height - clientBorder.height + 8
|
||||||
|
property int margins: 8
|
||||||
|
property string title
|
||||||
|
property int titleSize: titleBorder.height + 12
|
||||||
|
property string frameColor: HifiConstants.color
|
||||||
|
property string backgroundColor: myPalette.window
|
||||||
|
property string headerBackgroundColor: myPalette.dark
|
||||||
|
|
||||||
|
CustomBorder {
|
||||||
|
id: windowBorder
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: dialog.frameColor
|
||||||
|
color: dialog.backgroundColor
|
||||||
|
|
||||||
|
CustomBorder {
|
||||||
|
id: titleBorder
|
||||||
|
height: 48
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
border.color: dialog.frameColor
|
||||||
|
color: dialog.headerBackgroundColor
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: titleText
|
||||||
|
color: "white"
|
||||||
|
text: dialog.title
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: titleDrag
|
||||||
|
property int startX
|
||||||
|
property int startY
|
||||||
|
anchors.right: closeButton.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.rightMargin: 4
|
||||||
|
drag {
|
||||||
|
target: dialog.parent
|
||||||
|
minimumX: 0
|
||||||
|
minimumY: 0
|
||||||
|
maximumX: dialog.parent.parent.width - dialog.parent.width
|
||||||
|
maximumY: dialog.parent.parent.height - dialog.parent.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: closeButton
|
||||||
|
x: 360
|
||||||
|
height: 16
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: 16
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 12
|
||||||
|
source: "../styles/close.svg"
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
dialog.parent.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // header border
|
||||||
|
|
||||||
|
CustomBorder {
|
||||||
|
id: clientBorder
|
||||||
|
border.color: dialog.frameColor
|
||||||
|
color: "#00000000"
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 0
|
||||||
|
anchors.top: titleBorder.bottom
|
||||||
|
anchors.topMargin: -titleBorder.border.width
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
} // client border
|
||||||
|
} // window border
|
||||||
|
}
|
7
interface/resources/qml/CustomText.qml
Normal file
7
interface/resources/qml/CustomText.qml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
|
||||||
|
Text {
|
||||||
|
font.family: "Helvetica"
|
||||||
|
font.pointSize: 18
|
||||||
|
}
|
||||||
|
|
10
interface/resources/qml/CustomTextArea.qml
Normal file
10
interface/resources/qml/CustomTextArea.qml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
font.family: "Helvetica"
|
||||||
|
font.pointSize: 18
|
||||||
|
backgroundVisible: false
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
|
7
interface/resources/qml/CustomTextEdit.qml
Normal file
7
interface/resources/qml/CustomTextEdit.qml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
font.family: "Helvetica"
|
||||||
|
font.pointSize: 18
|
||||||
|
}
|
||||||
|
|
34
interface/resources/qml/CustomTextInput.qml
Normal file
34
interface/resources/qml/CustomTextInput.qml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
|
||||||
|
property string helperText: ""
|
||||||
|
font.family: "Helvetica"
|
||||||
|
font.pointSize: 18
|
||||||
|
width: 256
|
||||||
|
height: 64
|
||||||
|
color: myPalette.text
|
||||||
|
clip: true
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
if (text == "") {
|
||||||
|
helperText.visible = true;
|
||||||
|
} else {
|
||||||
|
helperText.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: helperText
|
||||||
|
anchors.fill: parent
|
||||||
|
font.pointSize: parent.font.pointSize
|
||||||
|
font.family: "Helvetica"
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
text: parent.helperText
|
||||||
|
color: myPalette.dark
|
||||||
|
clip: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
8
interface/resources/qml/Icon.qml
Normal file
8
interface/resources/qml/Icon.qml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import QtQuick 1.0
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: icon
|
||||||
|
width: 64
|
||||||
|
height: 64
|
||||||
|
source: "file.svg"
|
||||||
|
}
|
24
interface/resources/qml/IconControl.qml
Normal file
24
interface/resources/qml/IconControl.qml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.3
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Text"
|
||||||
|
style: ButtonStyle {
|
||||||
|
background: Item { anchors.fill: parent }
|
||||||
|
label: Text {
|
||||||
|
id: icon
|
||||||
|
width: height
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
font.family: iconFont.name
|
||||||
|
font.pointSize: 18
|
||||||
|
property alias unicode: icon.text
|
||||||
|
FontLoader { id: iconFont; source: "/fonts/fontawesome-webfont.ttf"; }
|
||||||
|
text: control.text
|
||||||
|
color: control.enabled ? "white" : "dimgray"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
191
interface/resources/qml/LoginDialog.qml
Normal file
191
interface/resources/qml/LoginDialog.qml
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
import Hifi 1.0
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
import "hifiConstants.js" as HifiConstants
|
||||||
|
|
||||||
|
LoginDialog {
|
||||||
|
SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
|
||||||
|
id: loginDialog
|
||||||
|
objectName: "LoginDialog"
|
||||||
|
height: 512
|
||||||
|
width: 384
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (!visible) {
|
||||||
|
reset()
|
||||||
|
} else {
|
||||||
|
username.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
username.text = ""
|
||||||
|
password.text = ""
|
||||||
|
loginDialog.statusText = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomDialog {
|
||||||
|
anchors.fill: parent
|
||||||
|
title: "Login"
|
||||||
|
Item {
|
||||||
|
id: item1
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: parent.margins
|
||||||
|
anchors.topMargin: parent.topMargin
|
||||||
|
Column {
|
||||||
|
anchors.topMargin: 8
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Image {
|
||||||
|
height: 64
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: 64
|
||||||
|
source: "../images/hifi-logo.svg"
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomBorder {
|
||||||
|
width: 304
|
||||||
|
height: 64
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
CustomTextInput {
|
||||||
|
id: username
|
||||||
|
anchors.fill: parent
|
||||||
|
helperText: "Username or Email"
|
||||||
|
anchors.margins: 8
|
||||||
|
KeyNavigation.tab: password
|
||||||
|
KeyNavigation.backtab: password
|
||||||
|
onAccepted: {
|
||||||
|
password.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomBorder {
|
||||||
|
width: 304
|
||||||
|
height: 64
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
CustomTextInput {
|
||||||
|
id: password
|
||||||
|
anchors.fill: parent
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
helperText: "Password"
|
||||||
|
anchors.margins: 8
|
||||||
|
KeyNavigation.tab: username
|
||||||
|
KeyNavigation.backtab: username
|
||||||
|
onAccepted: {
|
||||||
|
if (username.text == "") {
|
||||||
|
username.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
loginDialog.login(username.text, password.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onFocusChanged: {
|
||||||
|
if (password.focus) {
|
||||||
|
password.selectAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
width: parent.width
|
||||||
|
height: 96
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: loginDialog.statusText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.bottomMargin: 5
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 192
|
||||||
|
height: 64
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: HifiConstants.color
|
||||||
|
border.width: 0
|
||||||
|
radius: 10
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 0
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.left: parent.left
|
||||||
|
onClicked: {
|
||||||
|
loginDialog.login(username.text, password.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 8
|
||||||
|
Image {
|
||||||
|
id: loginIcon
|
||||||
|
height: 32
|
||||||
|
width: 32
|
||||||
|
source: "../images/login.svg"
|
||||||
|
}
|
||||||
|
CustomText {
|
||||||
|
text: "Login"
|
||||||
|
color: "white"
|
||||||
|
width: 64
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
width: parent.width
|
||||||
|
height: 24
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
text:"Create Account"
|
||||||
|
font.pointSize: 12
|
||||||
|
font.bold: true
|
||||||
|
color: HifiConstants.color
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
loginDialog.openUrl(loginDialog.rootUrl + "/signup")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
width: parent.width
|
||||||
|
height: 24
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pointSize: 12
|
||||||
|
text: "Recover Password"
|
||||||
|
color: HifiConstants.color
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
loginDialog.openUrl(loginDialog.rootUrl + "/users/password/new")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
interface/resources/qml/Root.qml
Normal file
14
interface/resources/qml/Root.qml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import "componentCreation.js" as Creator
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
width: 1280
|
||||||
|
height: 720
|
||||||
|
|
||||||
|
function loadChild(url) {
|
||||||
|
Creator.createObject(root, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
interface/resources/qml/componentCreation.js
Normal file
27
interface/resources/qml/componentCreation.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
var component;
|
||||||
|
var instance;
|
||||||
|
var parent;
|
||||||
|
|
||||||
|
function createObject(parentObject, url) {
|
||||||
|
parent = parentObject;
|
||||||
|
component = Qt.createComponent(url);
|
||||||
|
if (component.status == Component.Ready)
|
||||||
|
finishCreation();
|
||||||
|
else
|
||||||
|
component.statusChanged.connect(finishCreation);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishCreation() {
|
||||||
|
if (component.status == Component.Ready) {
|
||||||
|
instance = component.createObject(parent, {"x": 100, "y": 100});
|
||||||
|
if (instance == null) {
|
||||||
|
// Error Handling
|
||||||
|
console.log("Error creating object");
|
||||||
|
} else {
|
||||||
|
instance.focus = true;
|
||||||
|
}
|
||||||
|
} else if (component.status == Component.Error) {
|
||||||
|
// Error Handling
|
||||||
|
console.log("Error loading component:", component.errorString());
|
||||||
|
}
|
||||||
|
}
|
4
interface/resources/qml/hifiConstants.js
Normal file
4
interface/resources/qml/hifiConstants.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
var color = "#0e7077"
|
||||||
|
var Colors = {
|
||||||
|
hifiBlue: "#0e7077"
|
||||||
|
}
|
|
@ -137,6 +137,7 @@
|
||||||
#include "ui/Snapshot.h"
|
#include "ui/Snapshot.h"
|
||||||
#include "ui/StandAloneJSConsole.h"
|
#include "ui/StandAloneJSConsole.h"
|
||||||
#include "ui/Stats.h"
|
#include "ui/Stats.h"
|
||||||
|
#include "ui/AddressBarDialog.h"
|
||||||
|
|
||||||
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
|
@ -211,6 +212,10 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
|
||||||
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
|
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
|
||||||
|
|
||||||
if (!logMessage.isEmpty()) {
|
if (!logMessage.isEmpty()) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
OutputDebugStringA(logMessage.toLocal8Bit().constData());
|
||||||
|
OutputDebugStringA("\n");
|
||||||
|
#endif
|
||||||
Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage + "\n"));
|
Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage + "\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,6 +265,7 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
#endif
|
#endif
|
||||||
auto discoverabilityManager = DependencyManager::set<DiscoverabilityManager>();
|
auto discoverabilityManager = DependencyManager::set<DiscoverabilityManager>();
|
||||||
auto sceneScriptingInterface = DependencyManager::set<SceneScriptingInterface>();
|
auto sceneScriptingInterface = DependencyManager::set<SceneScriptingInterface>();
|
||||||
|
auto offscreenUi = DependencyManager::set<OffscreenUi>();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +323,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
installNativeEventFilter(&MyNativeEventFilter::getInstance());
|
installNativeEventFilter(&MyNativeEventFilter::getInstance());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
_logger = new FileLogger(this); // After setting organization name in order to get correct directory
|
_logger = new FileLogger(this); // After setting organization name in order to get correct directory
|
||||||
|
|
||||||
qInstallMessageHandler(messageHandler);
|
qInstallMessageHandler(messageHandler);
|
||||||
|
|
||||||
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "styles/Inconsolata.otf");
|
QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "styles/Inconsolata.otf");
|
||||||
|
@ -562,8 +570,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->installEventFilter(this);
|
this->installEventFilter(this);
|
||||||
|
// The offscreen UI needs to intercept the mouse and keyboard
|
||||||
|
// events coming from the onscreen window
|
||||||
|
_glWidget->installEventFilter(
|
||||||
|
DependencyManager::get<OffscreenUi>().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Application::aboutToQuit() {
|
void Application::aboutToQuit() {
|
||||||
emit beforeAboutToQuit();
|
emit beforeAboutToQuit();
|
||||||
|
|
||||||
|
@ -721,9 +734,34 @@ void Application::initializeGL() {
|
||||||
// update before the first render
|
// update before the first render
|
||||||
update(1.0f / _fps);
|
update(1.0f / _fps);
|
||||||
|
|
||||||
|
// The UI can't be created until the primary OpenGL
|
||||||
|
// context is created, because it needs to share
|
||||||
|
// texture resources
|
||||||
|
initializeUi();
|
||||||
|
|
||||||
InfoView::showFirstTime(INFO_HELP_PATH);
|
InfoView::showFirstTime(INFO_HELP_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::initializeUi() {
|
||||||
|
AddressBarDialog::registerType();
|
||||||
|
LoginDialog::registerType();
|
||||||
|
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
offscreenUi->create(_glWidget->context()->contextHandle());
|
||||||
|
offscreenUi->resize(_glWidget->size());
|
||||||
|
offscreenUi->setProxyWindow(_window->windowHandle());
|
||||||
|
auto rootQml = PathUtils::resourcesPath() + "qml/Root.qml";
|
||||||
|
offscreenUi->loadQml(QUrl::fromLocalFile(rootQml));
|
||||||
|
offscreenUi->setMouseTranslator([this](const QPointF& p){
|
||||||
|
if (OculusManager::isConnected()) {
|
||||||
|
glm::vec2 pos = _applicationOverlay.screenToOverlay(toGlm(p));
|
||||||
|
return QPointF(pos.x, pos.y);
|
||||||
|
}
|
||||||
|
return QPointF(p);
|
||||||
|
});
|
||||||
|
offscreenUi->resume();
|
||||||
|
}
|
||||||
|
|
||||||
void Application::paintGL() {
|
void Application::paintGL() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
PerformanceTimer perfTimer("paintGL");
|
PerformanceTimer perfTimer("paintGL");
|
||||||
|
@ -818,7 +856,7 @@ void Application::paintGL() {
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("renderOverlay");
|
PerformanceTimer perfTimer("renderOverlay");
|
||||||
_applicationOverlay.renderOverlay(true);
|
_applicationOverlay.renderOverlay();
|
||||||
_applicationOverlay.displayOverlayTexture();
|
_applicationOverlay.displayOverlayTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -863,6 +901,9 @@ void Application::resizeGL(int width, int height) {
|
||||||
updateProjectionMatrix();
|
updateProjectionMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
offscreenUi->resize(QSize(width, height));
|
||||||
|
|
||||||
// update Stats width
|
// update Stats width
|
||||||
// let's set horizontal offset to give stats some margin to mirror
|
// let's set horizontal offset to give stats some margin to mirror
|
||||||
int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
|
int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
|
||||||
|
@ -911,6 +952,44 @@ bool Application::importSVOFromURL(const QString& urlString) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::event(QEvent* event) {
|
bool Application::event(QEvent* event) {
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::MouseMove:
|
||||||
|
mouseMoveEvent((QMouseEvent*)event);
|
||||||
|
return true;
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
mousePressEvent((QMouseEvent*)event);
|
||||||
|
return true;
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
mouseReleaseEvent((QMouseEvent*)event);
|
||||||
|
return true;
|
||||||
|
case QEvent::KeyPress:
|
||||||
|
keyPressEvent((QKeyEvent*)event);
|
||||||
|
return true;
|
||||||
|
case QEvent::KeyRelease:
|
||||||
|
keyReleaseEvent((QKeyEvent*)event);
|
||||||
|
return true;
|
||||||
|
case QEvent::FocusOut:
|
||||||
|
focusOutEvent((QFocusEvent*)event);
|
||||||
|
return true;
|
||||||
|
case QEvent::TouchBegin:
|
||||||
|
touchBeginEvent(static_cast<QTouchEvent*>(event));
|
||||||
|
event->accept();
|
||||||
|
return true;
|
||||||
|
case QEvent::TouchEnd:
|
||||||
|
touchEndEvent(static_cast<QTouchEvent*>(event));
|
||||||
|
return true;
|
||||||
|
case QEvent::TouchUpdate:
|
||||||
|
touchUpdateEvent(static_cast<QTouchEvent*>(event));
|
||||||
|
return true;
|
||||||
|
case QEvent::Wheel:
|
||||||
|
wheelEvent(static_cast<QWheelEvent*>(event));
|
||||||
|
return true;
|
||||||
|
case QEvent::Drop:
|
||||||
|
dropEvent(static_cast<QDropEvent*>(event));
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// handle custom URL
|
// handle custom URL
|
||||||
if (event->type() == QEvent::FileOpen) {
|
if (event->type() == QEvent::FileOpen) {
|
||||||
|
@ -963,13 +1042,16 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
bool isShifted = event->modifiers().testFlag(Qt::ShiftModifier);
|
bool isShifted = event->modifiers().testFlag(Qt::ShiftModifier);
|
||||||
bool isMeta = event->modifiers().testFlag(Qt::ControlModifier);
|
bool isMeta = event->modifiers().testFlag(Qt::ControlModifier);
|
||||||
bool isOption = event->modifiers().testFlag(Qt::AltModifier);
|
bool isOption = event->modifiers().testFlag(Qt::AltModifier);
|
||||||
|
bool isKeypad = event->modifiers().testFlag(Qt::KeypadModifier);
|
||||||
switch (event->key()) {
|
switch (event->key()) {
|
||||||
break;
|
break;
|
||||||
case Qt::Key_L:
|
case Qt::Key_L:
|
||||||
if (isShifted) {
|
if (isShifted && isMeta) {
|
||||||
Menu::getInstance()->triggerOption(MenuOption::LodTools);
|
|
||||||
} else if (isMeta) {
|
|
||||||
Menu::getInstance()->triggerOption(MenuOption::Log);
|
Menu::getInstance()->triggerOption(MenuOption::Log);
|
||||||
|
} else if (isMeta) {
|
||||||
|
Menu::getInstance()->triggerOption(MenuOption::AddressBar);
|
||||||
|
} else if (isShifted) {
|
||||||
|
Menu::getInstance()->triggerOption(MenuOption::LodTools);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1030,11 +1112,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_Return:
|
|
||||||
case Qt::Key_Enter:
|
|
||||||
Menu::getInstance()->triggerOption(MenuOption::AddressBar);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_Backslash:
|
case Qt::Key_Backslash:
|
||||||
Menu::getInstance()->triggerOption(MenuOption::Chat);
|
Menu::getInstance()->triggerOption(MenuOption::Chat);
|
||||||
break;
|
break;
|
||||||
|
@ -1494,6 +1571,17 @@ void Application::dropEvent(QDropEvent *event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::dragEnterEvent(QDragEnterEvent* event) {
|
||||||
|
const QMimeData* mimeData = event->mimeData();
|
||||||
|
foreach(QUrl url, mimeData->urls()) {
|
||||||
|
auto urlString = url.toString();
|
||||||
|
if (canAcceptURL(urlString)) {
|
||||||
|
event->acceptProposedAction();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Application::acceptSnapshot(const QString& urlString) {
|
bool Application::acceptSnapshot(const QString& urlString) {
|
||||||
QUrl url(urlString);
|
QUrl url(urlString);
|
||||||
QString snapshotPath = url.toLocalFile();
|
QString snapshotPath = url.toLocalFile();
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <NetworkPacket.h>
|
#include <NetworkPacket.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <OctreeQuery.h>
|
#include <OctreeQuery.h>
|
||||||
|
#include <OffscreenUi.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <PhysicsEngine.h>
|
#include <PhysicsEngine.h>
|
||||||
#include <ScriptEngine.h>
|
#include <ScriptEngine.h>
|
||||||
|
@ -151,6 +152,7 @@ public:
|
||||||
void setPreviousScriptLocation(const QString& previousScriptLocation);
|
void setPreviousScriptLocation(const QString& previousScriptLocation);
|
||||||
void clearScriptsBeforeRunning();
|
void clearScriptsBeforeRunning();
|
||||||
void initializeGL();
|
void initializeGL();
|
||||||
|
void initializeUi();
|
||||||
void paintGL();
|
void paintGL();
|
||||||
void resizeGL(int width, int height);
|
void resizeGL(int width, int height);
|
||||||
|
|
||||||
|
@ -170,6 +172,7 @@ public:
|
||||||
|
|
||||||
void wheelEvent(QWheelEvent* event);
|
void wheelEvent(QWheelEvent* event);
|
||||||
void dropEvent(QDropEvent *event);
|
void dropEvent(QDropEvent *event);
|
||||||
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
|
||||||
bool event(QEvent* event);
|
bool event(QEvent* event);
|
||||||
bool eventFilter(QObject* object, QEvent* event);
|
bool eventFilter(QObject* object, QEvent* event);
|
||||||
|
|
|
@ -82,30 +82,6 @@ void GLCanvas::resizeGL(int width, int height) {
|
||||||
Application::getInstance()->resizeGL(width, height);
|
Application::getInstance()->resizeGL(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas::keyPressEvent(QKeyEvent* event) {
|
|
||||||
Application::getInstance()->keyPressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::keyReleaseEvent(QKeyEvent* event) {
|
|
||||||
Application::getInstance()->keyReleaseEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::focusOutEvent(QFocusEvent* event) {
|
|
||||||
Application::getInstance()->focusOutEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::mouseMoveEvent(QMouseEvent* event) {
|
|
||||||
Application::getInstance()->mouseMoveEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::mousePressEvent(QMouseEvent* event) {
|
|
||||||
Application::getInstance()->mousePressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::mouseReleaseEvent(QMouseEvent* event) {
|
|
||||||
Application::getInstance()->mouseReleaseEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::activeChanged(Qt::ApplicationState state) {
|
void GLCanvas::activeChanged(Qt::ApplicationState state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case Qt::ApplicationActive:
|
case Qt::ApplicationActive:
|
||||||
|
@ -151,40 +127,37 @@ void GLCanvas::throttleRender() {
|
||||||
int updateTime = 0;
|
int updateTime = 0;
|
||||||
bool GLCanvas::event(QEvent* event) {
|
bool GLCanvas::event(QEvent* event) {
|
||||||
switch (event->type()) {
|
switch (event->type()) {
|
||||||
|
case QEvent::MouseMove:
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
case QEvent::KeyPress:
|
||||||
|
case QEvent::KeyRelease:
|
||||||
|
case QEvent::FocusIn:
|
||||||
|
case QEvent::FocusOut:
|
||||||
|
case QEvent::Resize:
|
||||||
case QEvent::TouchBegin:
|
case QEvent::TouchBegin:
|
||||||
Application::getInstance()->touchBeginEvent(static_cast<QTouchEvent*>(event));
|
|
||||||
event->accept();
|
|
||||||
return true;
|
|
||||||
case QEvent::TouchEnd:
|
case QEvent::TouchEnd:
|
||||||
Application::getInstance()->touchEndEvent(static_cast<QTouchEvent*>(event));
|
|
||||||
return true;
|
|
||||||
case QEvent::TouchUpdate:
|
case QEvent::TouchUpdate:
|
||||||
Application::getInstance()->touchUpdateEvent(static_cast<QTouchEvent*>(event));
|
case QEvent::Wheel:
|
||||||
|
case QEvent::DragEnter:
|
||||||
|
case QEvent::Drop:
|
||||||
|
if (QCoreApplication::sendEvent(QCoreApplication::instance(), event)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QEvent::Paint:
|
||||||
|
// Ignore paint events that occur after we've decided to quit
|
||||||
|
if (Application::getInstance()->isAboutToQuit()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return QGLWidget::event(event);
|
return QGLWidget::event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas::wheelEvent(QWheelEvent* event) {
|
|
||||||
Application::getInstance()->wheelEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::dragEnterEvent(QDragEnterEvent* event) {
|
|
||||||
const QMimeData* mimeData = event->mimeData();
|
|
||||||
foreach (QUrl url, mimeData->urls()) {
|
|
||||||
auto urlString = url.toString();
|
|
||||||
if (Application::getInstance()->canAcceptURL(urlString)) {
|
|
||||||
event->acceptProposedAction();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::dropEvent(QDropEvent* event) {
|
|
||||||
Application::getInstance()->dropEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
|
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
|
||||||
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
|
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
|
||||||
|
|
|
@ -40,23 +40,8 @@ protected:
|
||||||
virtual void initializeGL();
|
virtual void initializeGL();
|
||||||
virtual void paintGL();
|
virtual void paintGL();
|
||||||
virtual void resizeGL(int width, int height);
|
virtual void resizeGL(int width, int height);
|
||||||
|
|
||||||
virtual void keyPressEvent(QKeyEvent* event);
|
|
||||||
virtual void keyReleaseEvent(QKeyEvent* event);
|
|
||||||
|
|
||||||
virtual void focusOutEvent(QFocusEvent* event);
|
|
||||||
|
|
||||||
virtual void mouseMoveEvent(QMouseEvent* event);
|
|
||||||
virtual void mousePressEvent(QMouseEvent* event);
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* event);
|
|
||||||
|
|
||||||
virtual bool event(QEvent* event);
|
virtual bool event(QEvent* event);
|
||||||
|
|
||||||
virtual void wheelEvent(QWheelEvent* event);
|
|
||||||
|
|
||||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
|
||||||
virtual void dropEvent(QDropEvent* event);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void activeChanged(Qt::ApplicationState state);
|
void activeChanged(Qt::ApplicationState state);
|
||||||
void throttleRender();
|
void throttleRender();
|
||||||
|
|
|
@ -97,7 +97,7 @@ Menu::Menu() {
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(fileMenu,
|
addActionToQMenuAndActionHash(fileMenu,
|
||||||
MenuOption::AddressBar,
|
MenuOption::AddressBar,
|
||||||
Qt::Key_Enter,
|
Qt::CTRL | Qt::Key_L,
|
||||||
dialogsManager.data(),
|
dialogsManager.data(),
|
||||||
SLOT(toggleAddressBar()));
|
SLOT(toggleAddressBar()));
|
||||||
auto addressManager = DependencyManager::get<AddressManager>();
|
auto addressManager = DependencyManager::get<AddressManager>();
|
||||||
|
@ -151,7 +151,8 @@ Menu::Menu() {
|
||||||
connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));
|
connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, Qt::Key_Backslash,
|
addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat,
|
||||||
|
0, // QML Qt::Key_Backslash,
|
||||||
dialogsManager.data(), SLOT(showIRCLink()));
|
dialogsManager.data(), SLOT(showIRCLink()));
|
||||||
addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0,
|
addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0,
|
||||||
qApp, SLOT(showFriendsWindow()));
|
qApp, SLOT(showFriendsWindow()));
|
||||||
|
@ -194,7 +195,7 @@ Menu::Menu() {
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(toolsMenu,
|
addActionToQMenuAndActionHash(toolsMenu,
|
||||||
MenuOption::ResetSensors,
|
MenuOption::ResetSensors,
|
||||||
Qt::Key_Apostrophe,
|
0, // QML Qt::Key_Apostrophe,
|
||||||
qApp,
|
qApp,
|
||||||
SLOT(resetSensors()));
|
SLOT(resetSensors()));
|
||||||
|
|
||||||
|
@ -207,17 +208,17 @@ Menu::Menu() {
|
||||||
QMenu* avatarSizeMenu = avatarMenu->addMenu("Size");
|
QMenu* avatarSizeMenu = avatarMenu->addMenu("Size");
|
||||||
addActionToQMenuAndActionHash(avatarSizeMenu,
|
addActionToQMenuAndActionHash(avatarSizeMenu,
|
||||||
MenuOption::IncreaseAvatarSize,
|
MenuOption::IncreaseAvatarSize,
|
||||||
Qt::Key_Plus,
|
0, // QML Qt::Key_Plus,
|
||||||
avatar,
|
avatar,
|
||||||
SLOT(increaseSize()));
|
SLOT(increaseSize()));
|
||||||
addActionToQMenuAndActionHash(avatarSizeMenu,
|
addActionToQMenuAndActionHash(avatarSizeMenu,
|
||||||
MenuOption::DecreaseAvatarSize,
|
MenuOption::DecreaseAvatarSize,
|
||||||
Qt::Key_Minus,
|
0, // QML Qt::Key_Minus,
|
||||||
avatar,
|
avatar,
|
||||||
SLOT(decreaseSize()));
|
SLOT(decreaseSize()));
|
||||||
addActionToQMenuAndActionHash(avatarSizeMenu,
|
addActionToQMenuAndActionHash(avatarSizeMenu,
|
||||||
MenuOption::ResetAvatarSize,
|
MenuOption::ResetAvatarSize,
|
||||||
Qt::Key_Equal,
|
0, // QML Qt::Key_Equal,
|
||||||
avatar,
|
avatar,
|
||||||
SLOT(resetSize()));
|
SLOT(resetSize()));
|
||||||
|
|
||||||
|
@ -250,13 +251,17 @@ Menu::Menu() {
|
||||||
qApp,
|
qApp,
|
||||||
SLOT(setFullscreen(bool)));
|
SLOT(setFullscreen(bool)));
|
||||||
#endif
|
#endif
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true,
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson,
|
||||||
qApp,SLOT(cameraMenuChanged()));
|
0, // QML Qt::Key_P,
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true);
|
true, qApp, SLOT(cameraMenuChanged()));
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false,
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror,
|
||||||
qApp, SLOT(cameraMenuChanged()));
|
0, //QML Qt::SHIFT | Qt::Key_H,
|
||||||
|
true);
|
||||||
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror,
|
||||||
|
0, // QML Qt::Key_H,
|
||||||
|
false, qApp, SLOT(cameraMenuChanged()));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, Qt::META | Qt::Key_H,
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, Qt::CTRL | Qt::SHIFT | Qt::Key_H,
|
||||||
false,
|
false,
|
||||||
dialogsManager.data(),
|
dialogsManager.data(),
|
||||||
SLOT(hmdTools(bool)));
|
SLOT(hmdTools(bool)));
|
||||||
|
@ -283,8 +288,12 @@ Menu::Menu() {
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false);
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false);
|
||||||
|
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash);
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats,
|
||||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, qApp, SLOT(toggleLogDialog()));
|
0); // QML Qt::Key_Slash);
|
||||||
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats);
|
||||||
|
addActionToQMenuAndActionHash(viewMenu, MenuOption::Log,
|
||||||
|
Qt::CTRL | Qt::SHIFT | Qt::Key_L,
|
||||||
|
qApp, SLOT(toggleLogDialog()));
|
||||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0,
|
addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0,
|
||||||
dialogsManager.data(), SLOT(bandwidthDetails()));
|
dialogsManager.data(), SLOT(bandwidthDetails()));
|
||||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0,
|
addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0,
|
||||||
|
@ -294,7 +303,9 @@ Menu::Menu() {
|
||||||
QMenu* developerMenu = addMenu("Developer");
|
QMenu* developerMenu = addMenu("Developer");
|
||||||
|
|
||||||
QMenu* renderOptionsMenu = developerMenu->addMenu("Render");
|
QMenu* renderOptionsMenu = developerMenu->addMenu("Render");
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, Qt::SHIFT | Qt::Key_A, true);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere,
|
||||||
|
0, // QML Qt::SHIFT | Qt::Key_A,
|
||||||
|
true);
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AmbientOcclusion);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AmbientOcclusion);
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DontFadeOnOctreeServerChanges);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DontFadeOnOctreeServerChanges);
|
||||||
|
|
||||||
|
@ -346,12 +357,15 @@ Menu::Menu() {
|
||||||
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionThird, 0, false));
|
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionThird, 0, false));
|
||||||
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionQuarter, 0, false));
|
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionQuarter, 0, false));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, Qt::Key_Asterisk, true);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars,
|
||||||
|
0, // QML Qt::Key_Asterisk,
|
||||||
|
true);
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableGlowEffect, 0, true,
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableGlowEffect, 0, true,
|
||||||
DependencyManager::get<GlowEffect>().data(), SLOT(toggleGlowEffect(bool)));
|
DependencyManager::get<GlowEffect>().data(), SLOT(toggleGlowEffect(bool)));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, Qt::ALT | Qt::Key_W, false);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, Qt::ALT | Qt::Key_W, false);
|
||||||
addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L,
|
addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools,
|
||||||
|
0, // QML Qt::SHIFT | Qt::Key_L,
|
||||||
dialogsManager.data(), SLOT(lodTools()));
|
dialogsManager.data(), SLOT(lodTools()));
|
||||||
|
|
||||||
QMenu* avatarDebugMenu = developerMenu->addMenu("Avatar");
|
QMenu* avatarDebugMenu = developerMenu->addMenu("Avatar");
|
||||||
|
|
|
@ -114,9 +114,12 @@ void OculusManager::initSdk() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusManager::shutdownSdk() {
|
void OculusManager::shutdownSdk() {
|
||||||
|
if (_ovrHmd) {
|
||||||
ovrHmd_Destroy(_ovrHmd);
|
ovrHmd_Destroy(_ovrHmd);
|
||||||
|
_ovrHmd = nullptr;
|
||||||
ovr_Shutdown();
|
ovr_Shutdown();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OculusManager::init() {
|
void OculusManager::init() {
|
||||||
#ifdef OVR_DIRECT_MODE
|
#ifdef OVR_DIRECT_MODE
|
||||||
|
@ -124,6 +127,12 @@ void OculusManager::init() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OculusManager::deinit() {
|
||||||
|
#ifdef OVR_DIRECT_MODE
|
||||||
|
shutdownSdk();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void OculusManager::connect() {
|
void OculusManager::connect() {
|
||||||
#ifndef OVR_DIRECT_MODE
|
#ifndef OVR_DIRECT_MODE
|
||||||
initSdk();
|
initSdk();
|
||||||
|
@ -515,7 +524,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
|
|
||||||
// We only need to render the overlays to a texture once, then we just render the texture on the hemisphere
|
// We only need to render the overlays to a texture once, then we just render the texture on the hemisphere
|
||||||
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
|
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
|
||||||
applicationOverlay.renderOverlay(true);
|
applicationOverlay.renderOverlay();
|
||||||
|
|
||||||
//Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it
|
//Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ class Text3DOverlay;
|
||||||
class OculusManager {
|
class OculusManager {
|
||||||
public:
|
public:
|
||||||
static void init();
|
static void init();
|
||||||
|
static void deinit();
|
||||||
static void connect();
|
static void connect();
|
||||||
static void disconnect();
|
static void disconnect();
|
||||||
static bool isConnected();
|
static bool isConnected();
|
||||||
|
|
|
@ -103,7 +103,7 @@ void TV3DManager::display(Camera& whichCamera) {
|
||||||
|
|
||||||
// We only need to render the overlays to a texture once, then we just render the texture as a quad
|
// We only need to render the overlays to a texture once, then we just render the texture as a quad
|
||||||
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
|
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
|
||||||
applicationOverlay.renderOverlay(true);
|
applicationOverlay.renderOverlay();
|
||||||
|
|
||||||
DependencyManager::get<GlowEffect>()->prepare();
|
DependencyManager::get<GlowEffect>()->prepare();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
|
@ -112,6 +112,7 @@ int main(int argc, const char* argv[]) {
|
||||||
exitCode = app.exec();
|
exitCode = app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OculusManager::deinit();
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
ReleaseMutex(mutex);
|
ReleaseMutex(mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,148 +1,50 @@
|
||||||
//
|
//
|
||||||
// AddressBarDialog.cpp
|
// AddressBarDialog.cpp
|
||||||
// interface/src/ui
|
|
||||||
//
|
//
|
||||||
// Created by Stojce Slavkovski on 9/22/14.
|
// Created by Bradley Austin Davis on 2015/04/14
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "AddressBarDialog.h"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include <PathUtils.h>
|
#include "DependencyManager.h"
|
||||||
|
|
||||||
#include "AddressBarDialog.h"
|
|
||||||
#include "AddressManager.h"
|
#include "AddressManager.h"
|
||||||
#include "Application.h"
|
|
||||||
#include "MainWindow.h"
|
|
||||||
|
|
||||||
const QString ADDRESSBAR_GO_BUTTON_ICON = "images/address-bar-submit.svg";
|
QML_DIALOG_DEF(AddressBarDialog)
|
||||||
const QString ADDRESSBAR_GO_BUTTON_ACTIVE_ICON = "images/address-bar-submit-active.svg";
|
|
||||||
|
|
||||||
AddressBarDialog::AddressBarDialog(QWidget* parent) :
|
|
||||||
FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP)
|
|
||||||
{
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
|
||||||
setupUI();
|
|
||||||
|
|
||||||
|
AddressBarDialog::AddressBarDialog(QQuickItem *parent) : QQuickItem(parent) {
|
||||||
auto addressManager = DependencyManager::get<AddressManager>();
|
auto addressManager = DependencyManager::get<AddressManager>();
|
||||||
|
|
||||||
connect(addressManager.data(), &AddressManager::lookupResultIsOffline, this, &AddressBarDialog::displayAddressOfflineMessage);
|
connect(addressManager.data(), &AddressManager::lookupResultIsOffline, this, &AddressBarDialog::displayAddressOfflineMessage);
|
||||||
connect(addressManager.data(), &AddressManager::lookupResultIsNotFound, this, &AddressBarDialog::displayAddressNotFoundMessage);
|
connect(addressManager.data(), &AddressManager::lookupResultIsNotFound, this, &AddressBarDialog::displayAddressNotFoundMessage);
|
||||||
|
connect(addressManager.data(), &AddressManager::lookupResultsFinished, this, &AddressBarDialog::hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBarDialog::setupUI() {
|
|
||||||
|
|
||||||
const QString DIALOG_STYLESHEET = "font-family: Helvetica, Arial, sans-serif;";
|
void AddressBarDialog::hide() {
|
||||||
const QString ADDRESSBAR_PLACEHOLDER = "Go to: domain, location, @user, /x,y,z";
|
setEnabled(false);
|
||||||
const QString ADDRESSBAR_STYLESHEET = "padding: 5px 10px; font-size: 20px;";
|
setVisible(false);
|
||||||
|
|
||||||
const int ADDRESSBAR_MIN_WIDTH = 200;
|
|
||||||
const int ADDRESSBAR_MAX_WIDTH = 615;
|
|
||||||
const int ADDRESSBAR_HEIGHT = 42;
|
|
||||||
const int ADDRESSBAR_STRETCH = 60;
|
|
||||||
|
|
||||||
const int BUTTON_SPACER_SIZE = 5;
|
|
||||||
const int DEFAULT_SPACER_SIZE = 20;
|
|
||||||
const int ADDRESS_LAYOUT_RIGHT_MARGIN = 10;
|
|
||||||
|
|
||||||
const int GO_BUTTON_SIZE = 42;
|
|
||||||
const int CLOSE_BUTTON_SIZE = 16;
|
|
||||||
const QString CLOSE_BUTTON_ICON = "styles/close.svg";
|
|
||||||
|
|
||||||
const int DIALOG_HEIGHT = 62;
|
|
||||||
const int DIALOG_INITIAL_WIDTH = 560;
|
|
||||||
|
|
||||||
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
||||||
setSizePolicy(sizePolicy);
|
|
||||||
setMinimumSize(QSize(DIALOG_INITIAL_WIDTH, DIALOG_HEIGHT));
|
|
||||||
setMaximumHeight(DIALOG_HEIGHT);
|
|
||||||
setStyleSheet(DIALOG_STYLESHEET);
|
|
||||||
|
|
||||||
_verticalLayout = new QVBoxLayout(this);
|
|
||||||
_verticalLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
|
|
||||||
_addressLayout = new QHBoxLayout();
|
|
||||||
_addressLayout->setContentsMargins(0, 0, ADDRESS_LAYOUT_RIGHT_MARGIN, 0);
|
|
||||||
|
|
||||||
_leftSpacer = new QSpacerItem(DEFAULT_SPACER_SIZE,
|
|
||||||
DEFAULT_SPACER_SIZE,
|
|
||||||
QSizePolicy::MinimumExpanding,
|
|
||||||
QSizePolicy::Minimum);
|
|
||||||
|
|
||||||
_addressLayout->addItem(_leftSpacer);
|
|
||||||
|
|
||||||
_addressLineEdit = new QLineEdit(this);
|
|
||||||
_addressLineEdit->setAttribute(Qt::WA_MacShowFocusRect, 0);
|
|
||||||
_addressLineEdit->setPlaceholderText(ADDRESSBAR_PLACEHOLDER);
|
|
||||||
QSizePolicy sizePolicyLineEdit(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
|
||||||
sizePolicyLineEdit.setHorizontalStretch(ADDRESSBAR_STRETCH);
|
|
||||||
_addressLineEdit->setSizePolicy(sizePolicyLineEdit);
|
|
||||||
_addressLineEdit->setMinimumSize(QSize(ADDRESSBAR_MIN_WIDTH, ADDRESSBAR_HEIGHT));
|
|
||||||
_addressLineEdit->setMaximumSize(QSize(ADDRESSBAR_MAX_WIDTH, ADDRESSBAR_HEIGHT));
|
|
||||||
_addressLineEdit->setStyleSheet(ADDRESSBAR_STYLESHEET);
|
|
||||||
_addressLayout->addWidget(_addressLineEdit);
|
|
||||||
|
|
||||||
_buttonSpacer = new QSpacerItem(BUTTON_SPACER_SIZE, BUTTON_SPACER_SIZE, QSizePolicy::Fixed, QSizePolicy::Minimum);
|
|
||||||
_addressLayout->addItem(_buttonSpacer);
|
|
||||||
|
|
||||||
_goButton = new QPushButton(this);
|
|
||||||
_goButton->setSizePolicy(sizePolicy);
|
|
||||||
_goButton->setMinimumSize(QSize(GO_BUTTON_SIZE, GO_BUTTON_SIZE));
|
|
||||||
_goButton->setMaximumSize(QSize(GO_BUTTON_SIZE, GO_BUTTON_SIZE));
|
|
||||||
_goButton->setIcon(QIcon(PathUtils::resourcesPath() + ADDRESSBAR_GO_BUTTON_ICON));
|
|
||||||
_goButton->setIconSize(QSize(GO_BUTTON_SIZE, GO_BUTTON_SIZE));
|
|
||||||
_goButton->setDefault(true);
|
|
||||||
_goButton->setFlat(true);
|
|
||||||
_addressLayout->addWidget(_goButton);
|
|
||||||
|
|
||||||
_rightSpacer = new QSpacerItem(DEFAULT_SPACER_SIZE,
|
|
||||||
DEFAULT_SPACER_SIZE,
|
|
||||||
QSizePolicy::MinimumExpanding,
|
|
||||||
QSizePolicy::Minimum);
|
|
||||||
|
|
||||||
_addressLayout->addItem(_rightSpacer);
|
|
||||||
|
|
||||||
_closeButton = new QPushButton(this);
|
|
||||||
_closeButton->setSizePolicy(sizePolicy);
|
|
||||||
_closeButton->setMinimumSize(QSize(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE));
|
|
||||||
_closeButton->setMaximumSize(QSize(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE));
|
|
||||||
QIcon icon(PathUtils::resourcesPath() + CLOSE_BUTTON_ICON);
|
|
||||||
_closeButton->setIcon(icon);
|
|
||||||
_closeButton->setIconSize(QSize(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE));
|
|
||||||
_closeButton->setFlat(true);
|
|
||||||
_addressLayout->addWidget(_closeButton, 0, Qt::AlignRight);
|
|
||||||
|
|
||||||
_verticalLayout->addLayout(_addressLayout);
|
|
||||||
|
|
||||||
connect(_goButton, &QPushButton::clicked, this, &AddressBarDialog::accept);
|
|
||||||
connect(_closeButton, &QPushButton::clicked, this, &QDialog::close);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBarDialog::showEvent(QShowEvent* event) {
|
void AddressBarDialog::loadAddress(const QString & address) {
|
||||||
_goButton->setIcon(QIcon(PathUtils::resourcesPath() + ADDRESSBAR_GO_BUTTON_ICON));
|
qDebug() << "Called LoadAddress with address " << address;
|
||||||
_addressLineEdit->setText(QString());
|
if (!address.isEmpty()) {
|
||||||
_addressLineEdit->setFocus();
|
DependencyManager::get<AddressManager>()->handleLookupString(address);
|
||||||
FramelessDialog::showEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddressBarDialog::accept() {
|
|
||||||
if (!_addressLineEdit->text().isEmpty()) {
|
|
||||||
_goButton->setIcon(QIcon(PathUtils::resourcesPath() + ADDRESSBAR_GO_BUTTON_ACTIVE_ICON));
|
|
||||||
auto addressManager = DependencyManager::get<AddressManager>();
|
|
||||||
connect(addressManager.data(), &AddressManager::lookupResultsFinished, this, &QDialog::hide);
|
|
||||||
addressManager->handleLookupString(_addressLineEdit->text());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO port to a QML based message box
|
||||||
void AddressBarDialog::displayAddressOfflineMessage() {
|
void AddressBarDialog::displayAddressOfflineMessage() {
|
||||||
QMessageBox::information(Application::getInstance()->getWindow(), "Address offline",
|
QMessageBox::information(nullptr, "Address offline",
|
||||||
"That user or place is currently offline.");
|
"That user or place is currently offline.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO port to a QML based message box
|
||||||
void AddressBarDialog::displayAddressNotFoundMessage() {
|
void AddressBarDialog::displayAddressNotFoundMessage() {
|
||||||
QMessageBox::information(Application::getInstance()->getWindow(), "Address not found",
|
QMessageBox::information(nullptr, "Address not found",
|
||||||
"There is no address information for that user or place.");
|
"There is no address information for that user or place.");
|
||||||
}
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
//
|
//
|
||||||
// AddressBarDialog.h
|
// AddressBarDialog.h
|
||||||
// interface/src/ui
|
|
||||||
//
|
//
|
||||||
// Created by Stojce Slavkovski on 9/22/14.
|
// Created by Bradley Austin Davis on 2015/04/14
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
@ -12,36 +11,25 @@
|
||||||
#ifndef hifi_AddressBarDialog_h
|
#ifndef hifi_AddressBarDialog_h
|
||||||
#define hifi_AddressBarDialog_h
|
#define hifi_AddressBarDialog_h
|
||||||
|
|
||||||
#include "FramelessDialog.h"
|
#pragma once
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
#include <QLineEdit>
|
#include "OffscreenUi.h"
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QSpacerItem>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
class AddressBarDialog : public FramelessDialog {
|
class AddressBarDialog : public QQuickItem
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
QML_DIALOG_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AddressBarDialog(QWidget* parent);
|
AddressBarDialog(QQuickItem *parent = 0);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void setupUI();
|
|
||||||
void showEvent(QShowEvent* event);
|
|
||||||
|
|
||||||
QVBoxLayout *_verticalLayout;
|
|
||||||
QHBoxLayout *_addressLayout;
|
|
||||||
QSpacerItem *_leftSpacer;
|
|
||||||
QSpacerItem *_rightSpacer;
|
|
||||||
QSpacerItem *_buttonSpacer;
|
|
||||||
QPushButton *_goButton;
|
|
||||||
QPushButton *_closeButton;
|
|
||||||
QLineEdit *_addressLineEdit;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void accept();
|
|
||||||
void displayAddressOfflineMessage();
|
void displayAddressOfflineMessage();
|
||||||
void displayAddressNotFoundMessage();
|
void displayAddressNotFoundMessage();
|
||||||
|
void hide();
|
||||||
|
|
||||||
|
Q_INVOKABLE void loadAddress(const QString & address);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AddressBarDialog_h
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
#include <OffscreenUi.h>
|
||||||
|
|
||||||
#include "AudioClient.h"
|
#include "AudioClient.h"
|
||||||
#include "audio/AudioIOStatsRenderer.h"
|
#include "audio/AudioIOStatsRenderer.h"
|
||||||
|
@ -161,13 +162,27 @@ ApplicationOverlay::ApplicationOverlay() :
|
||||||
_domainStatusBorder = geometryCache->allocateID();
|
_domainStatusBorder = geometryCache->allocateID();
|
||||||
_magnifierBorder = geometryCache->allocateID();
|
_magnifierBorder = geometryCache->allocateID();
|
||||||
|
|
||||||
|
// Once we move UI rendering and screen rendering to different
|
||||||
|
// threads, we need to use a sync object to deteremine when
|
||||||
|
// the current UI texture is no longer being read from, and only
|
||||||
|
// then release it back to the UI for re-use
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
connect(offscreenUi.data(), &OffscreenUi::textureUpdated, this, [&](GLuint textureId) {
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
offscreenUi->lockTexture(textureId);
|
||||||
|
assert(!glGetError());
|
||||||
|
std::swap(_newUiTexture, textureId);
|
||||||
|
if (textureId) {
|
||||||
|
offscreenUi->releaseTexture(textureId);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationOverlay::~ApplicationOverlay() {
|
ApplicationOverlay::~ApplicationOverlay() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renders the overlays either to a texture or to the screen
|
// Renders the overlays either to a texture or to the screen
|
||||||
void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
void ApplicationOverlay::renderOverlay() {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
||||||
Overlays& overlays = qApp->getOverlays();
|
Overlays& overlays = qApp->getOverlays();
|
||||||
auto glCanvas = Application::getInstance()->getGLWidget();
|
auto glCanvas = Application::getInstance()->getGLWidget();
|
||||||
|
@ -183,11 +198,9 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
if (renderToTexture) {
|
|
||||||
_overlays.buildFramebufferObject();
|
_overlays.buildFramebufferObject();
|
||||||
_overlays.bind();
|
_overlays.bind();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
|
||||||
|
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
const float NEAR_CLIP = -10000;
|
const float NEAR_CLIP = -10000;
|
||||||
|
@ -218,9 +231,25 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||||
|
|
||||||
if (renderToTexture) {
|
|
||||||
_overlays.release();
|
_overlays.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A quick and dirty solution for compositing the old overlay
|
||||||
|
// texture with the new one
|
||||||
|
template <typename F>
|
||||||
|
void with_each_texture(GLuint a, GLuint b, F f) {
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
if (a) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, a);
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
if (b) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, b);
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws the FBO texture for the screen
|
// Draws the FBO texture for the screen
|
||||||
|
@ -229,30 +258,24 @@ void ApplicationOverlay::displayOverlayTexture() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto glCanvas = Application::getInstance()->getGLWidget();
|
auto glCanvas = Application::getInstance()->getGLWidget();
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
_overlays.bindTexture();
|
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight(), 0, -1.0, 1.0);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
if (_alpha < 1.0) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec2 topLeft(0.0f, 0.0f);
|
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||||
glm::vec2 bottomRight(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
|
static const glm::vec2 topLeft(-1, 1);
|
||||||
glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
static const glm::vec2 bottomRight(1, -1);
|
||||||
glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
static const glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||||
|
static const glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||||
glm::vec4(1.0f, 1.0f, 1.0f, _alpha));
|
glm::vec4(1.0f, 1.0f, 1.0f, _alpha));
|
||||||
|
});
|
||||||
} glPopMatrix();
|
} glPopMatrix();
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws the FBO texture for Oculus rift.
|
// Draws the FBO texture for Oculus rift.
|
||||||
|
@ -260,9 +283,6 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
||||||
if (_alpha == 0.0f) {
|
if (_alpha == 0.0f) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
_overlays.bindTexture();
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||||
|
@ -303,8 +323,9 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
||||||
//Render magnifier, but dont show border for mouse magnifier
|
//Render magnifier, but dont show border for mouse magnifier
|
||||||
glm::vec2 projection = screenToOverlay(glm::vec2(_reticlePosition[MOUSE].x(),
|
glm::vec2 projection = screenToOverlay(glm::vec2(_reticlePosition[MOUSE].x(),
|
||||||
_reticlePosition[MOUSE].y()));
|
_reticlePosition[MOUSE].y()));
|
||||||
|
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||||
renderMagnifier(projection, _magSizeMult[i], i != MOUSE);
|
renderMagnifier(projection, _magSizeMult[i], i != MOUSE);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,12 +340,15 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
||||||
|
|
||||||
_overlays.buildVBO(_textureFov, _textureAspectRatio, 80, 80);
|
_overlays.buildVBO(_textureFov, _textureAspectRatio, 80, 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||||
_overlays.render();
|
_overlays.render();
|
||||||
|
});
|
||||||
|
|
||||||
if (!Application::getInstance()->isMouseHidden()) {
|
if (!Application::getInstance()->isMouseHidden()) {
|
||||||
renderPointersOculus(myAvatar->getDefaultEyePosition());
|
renderPointersOculus(myAvatar->getDefaultEyePosition());
|
||||||
}
|
}
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
_overlays.releaseTexture();
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||||
|
@ -341,14 +365,10 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
|
||||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
const glm::vec3& viewMatrixTranslation = qApp->getViewMatrixTranslation();
|
const glm::vec3& viewMatrixTranslation = qApp->getViewMatrixTranslation();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||||
_overlays.bindTexture();
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
@ -382,6 +402,7 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
|
||||||
GLfloat y = -halfQuadHeight;
|
GLfloat y = -halfQuadHeight;
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(glm::vec3(x, y + quadHeight, -distance),
|
DependencyManager::get<GeometryCache>()->renderQuad(glm::vec3(x, y + quadHeight, -distance),
|
||||||
glm::vec3(x + quadWidth, y + quadHeight, -distance),
|
glm::vec3(x + quadWidth, y + quadHeight, -distance),
|
||||||
glm::vec3(x + quadWidth, y, -distance),
|
glm::vec3(x + quadWidth, y, -distance),
|
||||||
|
@ -389,6 +410,7 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
|
||||||
glm::vec2(0.0f, 1.0f), glm::vec2(1.0f, 1.0f),
|
glm::vec2(0.0f, 1.0f), glm::vec2(1.0f, 1.0f),
|
||||||
glm::vec2(1.0f, 0.0f), glm::vec2(0.0f, 0.0f),
|
glm::vec2(1.0f, 0.0f), glm::vec2(0.0f, 0.0f),
|
||||||
overlayColor);
|
overlayColor);
|
||||||
|
});
|
||||||
|
|
||||||
auto glCanvas = Application::getInstance()->getGLWidget();
|
auto glCanvas = Application::getInstance()->getGLWidget();
|
||||||
if (_crosshairTexture == 0) {
|
if (_crosshairTexture == 0) {
|
||||||
|
@ -993,14 +1015,6 @@ void ApplicationOverlay::TexturedHemisphere::release() {
|
||||||
_framebufferObject->release();
|
_framebufferObject->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::TexturedHemisphere::bindTexture() {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApplicationOverlay::TexturedHemisphere::releaseTexture() {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApplicationOverlay::TexturedHemisphere::buildVBO(const float fov,
|
void ApplicationOverlay::TexturedHemisphere::buildVBO(const float fov,
|
||||||
const float aspectRatio,
|
const float aspectRatio,
|
||||||
const int slices,
|
const int slices,
|
||||||
|
@ -1099,14 +1113,14 @@ void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_framebufferObject = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::Depth);
|
_framebufferObject = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::Depth);
|
||||||
bindTexture();
|
glBindTexture(GL_TEXTURE_2D, getTexture());
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
GLfloat borderColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
GLfloat borderColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
releaseTexture();
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Renders a hemisphere with texture coordinates.
|
//Renders a hemisphere with texture coordinates.
|
||||||
|
@ -1137,6 +1151,10 @@ void ApplicationOverlay::TexturedHemisphere::render() {
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint ApplicationOverlay::TexturedHemisphere::getTexture() {
|
||||||
|
return _framebufferObject->texture();
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec2 ApplicationOverlay::directionToSpherical(glm::vec3 direction) const {
|
glm::vec2 ApplicationOverlay::directionToSpherical(glm::vec3 direction) const {
|
||||||
glm::vec2 result;
|
glm::vec2 result;
|
||||||
// Compute yaw
|
// Compute yaw
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
ApplicationOverlay();
|
ApplicationOverlay();
|
||||||
~ApplicationOverlay();
|
~ApplicationOverlay();
|
||||||
|
|
||||||
void renderOverlay(bool renderToTexture = false);
|
void renderOverlay();
|
||||||
void displayOverlayTexture();
|
void displayOverlayTexture();
|
||||||
void displayOverlayTextureOculus(Camera& whichCamera);
|
void displayOverlayTextureOculus(Camera& whichCamera);
|
||||||
void displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov);
|
void displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov);
|
||||||
|
@ -75,8 +75,7 @@ private:
|
||||||
|
|
||||||
void bind();
|
void bind();
|
||||||
void release();
|
void release();
|
||||||
void bindTexture();
|
GLuint getTexture();
|
||||||
void releaseTexture();
|
|
||||||
|
|
||||||
void buildFramebufferObject();
|
void buildFramebufferObject();
|
||||||
void buildVBO(const float fov, const float aspectRatio, const int slices, const int stacks);
|
void buildVBO(const float fov, const float aspectRatio, const int slices, const int stacks);
|
||||||
|
@ -122,6 +121,9 @@ private:
|
||||||
float _trailingAudioLoudness;
|
float _trailingAudioLoudness;
|
||||||
|
|
||||||
GLuint _crosshairTexture;
|
GLuint _crosshairTexture;
|
||||||
|
// TODO, move divide up the rendering, displaying and input handling
|
||||||
|
// facilities of this class
|
||||||
|
GLuint _newUiTexture{ 0 };
|
||||||
|
|
||||||
int _reticleQuad;
|
int _reticleQuad;
|
||||||
int _magnifierQuad;
|
int _magnifierQuad;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "DialogsManager.h"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include <AccountManager.h>
|
#include <AccountManager.h>
|
||||||
|
@ -28,14 +30,9 @@
|
||||||
#include "PreferencesDialog.h"
|
#include "PreferencesDialog.h"
|
||||||
#include "ScriptEditorWindow.h"
|
#include "ScriptEditorWindow.h"
|
||||||
|
|
||||||
#include "DialogsManager.h"
|
|
||||||
|
|
||||||
void DialogsManager::toggleAddressBar() {
|
void DialogsManager::toggleAddressBar() {
|
||||||
maybeCreateDialog(_addressBarDialog);
|
AddressBarDialog::toggle();
|
||||||
|
|
||||||
if (!_addressBarDialog->isVisible()) {
|
|
||||||
_addressBarDialog->show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsManager::toggleDiskCacheEditor() {
|
void DialogsManager::toggleDiskCacheEditor() {
|
||||||
|
@ -44,13 +41,11 @@ void DialogsManager::toggleDiskCacheEditor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsManager::toggleLoginDialog() {
|
void DialogsManager::toggleLoginDialog() {
|
||||||
maybeCreateDialog(_loginDialog);
|
LoginDialog::toggleAction();
|
||||||
_loginDialog->toggleQAction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsManager::showLoginDialog() {
|
void DialogsManager::showLoginDialog() {
|
||||||
maybeCreateDialog(_loginDialog);
|
LoginDialog::show();
|
||||||
_loginDialog->showLoginForCurrentDomain();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsManager::octreeStatsDetails() {
|
void DialogsManager::octreeStatsDetails() {
|
||||||
|
@ -170,3 +165,4 @@ void DialogsManager::showIRCLink() {
|
||||||
|
|
||||||
_ircInfoBox->raise();
|
_ircInfoBox->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
//
|
|
||||||
// FramelessDialog.cpp
|
|
||||||
// interface/src/ui
|
|
||||||
//
|
|
||||||
// Created by Stojce Slavkovski on 2/20/14.
|
|
||||||
// Copyright 2014 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 <QScreen>
|
|
||||||
#include <QWindow>
|
|
||||||
|
|
||||||
#include <PathUtils.h>
|
|
||||||
|
|
||||||
#include "Application.h"
|
|
||||||
#include "FramelessDialog.h"
|
|
||||||
#include "Menu.h"
|
|
||||||
|
|
||||||
const int RESIZE_HANDLE_WIDTH = 7;
|
|
||||||
|
|
||||||
FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags, Position position) :
|
|
||||||
QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint),
|
|
||||||
_allowResize(true),
|
|
||||||
_isResizing(false),
|
|
||||||
_resizeInitialWidth(0),
|
|
||||||
_selfHidden(false),
|
|
||||||
_position(position),
|
|
||||||
_hideOnBlur(true) {
|
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
// handle rezize and move events
|
|
||||||
parentWidget()->installEventFilter(this);
|
|
||||||
|
|
||||||
// handle minimize, restore and focus events
|
|
||||||
Application::getInstance()->installEventFilter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FramelessDialog::eventFilter(QObject* sender, QEvent* event) {
|
|
||||||
switch (event->type()) {
|
|
||||||
case QEvent::Move:
|
|
||||||
if (sender == parentWidget()) {
|
|
||||||
resizeAndPosition(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case QEvent::Resize:
|
|
||||||
if (sender == parentWidget()) {
|
|
||||||
resizeAndPosition(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case QEvent::WindowStateChange:
|
|
||||||
if (_hideOnBlur && parentWidget()->isMinimized()) {
|
|
||||||
if (isVisible()) {
|
|
||||||
_selfHidden = true;
|
|
||||||
setHidden(true);
|
|
||||||
}
|
|
||||||
} else if (_selfHidden) {
|
|
||||||
_selfHidden = false;
|
|
||||||
setHidden(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case QEvent::ApplicationDeactivate:
|
|
||||||
// hide on minimize and focus lost
|
|
||||||
if (_hideOnBlur && isVisible()) {
|
|
||||||
_selfHidden = true;
|
|
||||||
setHidden(true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case QEvent::ApplicationActivate:
|
|
||||||
if (_selfHidden) {
|
|
||||||
_selfHidden = false;
|
|
||||||
setHidden(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessDialog::setStyleSheetFile(const QString& fileName) {
|
|
||||||
QFile globalStyleSheet(PathUtils::resourcesPath() + "styles/global.qss");
|
|
||||||
QFile styleSheet(PathUtils::resourcesPath() + fileName);
|
|
||||||
if (styleSheet.open(QIODevice::ReadOnly) && globalStyleSheet.open(QIODevice::ReadOnly) ) {
|
|
||||||
QDir::setCurrent(PathUtils::resourcesPath());
|
|
||||||
setStyleSheet(globalStyleSheet.readAll() + styleSheet.readAll());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessDialog::showEvent(QShowEvent* event) {
|
|
||||||
resizeAndPosition();
|
|
||||||
QDialog::showEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessDialog::resizeAndPosition(bool resizeParent) {
|
|
||||||
QRect parentGeometry = Application::getInstance()->getDesirableApplicationGeometry();
|
|
||||||
QSize parentSize = parentGeometry.size();
|
|
||||||
|
|
||||||
// keep full app height or width depending on position
|
|
||||||
if (_position == POSITION_LEFT || _position == POSITION_RIGHT) {
|
|
||||||
setFixedHeight(parentSize.height());
|
|
||||||
} else {
|
|
||||||
setFixedWidth(parentSize.width());
|
|
||||||
}
|
|
||||||
|
|
||||||
// resize parrent if width is smaller than this dialog
|
|
||||||
if (resizeParent && parentSize.width() < size().width()) {
|
|
||||||
parentWidget()->resize(size().width(), parentSize.height());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_position == POSITION_LEFT || _position == POSITION_TOP) {
|
|
||||||
// move to upper left corner
|
|
||||||
move(parentGeometry.topLeft());
|
|
||||||
} else if (_position == POSITION_RIGHT) {
|
|
||||||
// move to upper right corner
|
|
||||||
QPoint pos = parentGeometry.topRight();
|
|
||||||
pos.setX(pos.x() - size().width());
|
|
||||||
move(pos);
|
|
||||||
}
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) {
|
|
||||||
if (_allowResize && mouseEvent->button() == Qt::LeftButton) {
|
|
||||||
if (_position == POSITION_LEFT || _position == POSITION_RIGHT) {
|
|
||||||
bool hitLeft = (_position == POSITION_LEFT) && (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH);
|
|
||||||
bool hitRight = (_position == POSITION_RIGHT) && (mouseEvent->pos().x() < RESIZE_HANDLE_WIDTH);
|
|
||||||
if (hitLeft || hitRight) {
|
|
||||||
_isResizing = true;
|
|
||||||
_resizeInitialWidth = size().width();
|
|
||||||
setCursor(Qt::SizeHorCursor);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bool hitTop = (_position == POSITION_TOP) && (abs(mouseEvent->pos().y() - size().height()) < RESIZE_HANDLE_WIDTH);
|
|
||||||
if (hitTop) {
|
|
||||||
_isResizing = true;
|
|
||||||
_resizeInitialWidth = size().height();
|
|
||||||
setCursor(Qt::SizeHorCursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessDialog::mouseReleaseEvent(QMouseEvent* mouseEvent) {
|
|
||||||
unsetCursor();
|
|
||||||
_isResizing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessDialog::mouseMoveEvent(QMouseEvent* mouseEvent) {
|
|
||||||
if (_isResizing) {
|
|
||||||
if (_position == POSITION_LEFT) {
|
|
||||||
resize(mouseEvent->pos().x(), size().height());
|
|
||||||
} else if (_position == POSITION_RIGHT) {
|
|
||||||
setUpdatesEnabled(false);
|
|
||||||
resize(_resizeInitialWidth - mouseEvent->pos().x(), size().height());
|
|
||||||
resizeAndPosition();
|
|
||||||
_resizeInitialWidth = size().width();
|
|
||||||
setUpdatesEnabled(true);
|
|
||||||
} else if (_position == POSITION_TOP) {
|
|
||||||
resize(size().width(), mouseEvent->pos().y());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
//
|
|
||||||
// FramelessDialog.h
|
|
||||||
// interface/src/ui
|
|
||||||
//
|
|
||||||
// Created by Stojce Slavkovski on 2/20/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef hifi_FramelessDialog_h
|
|
||||||
#define hifi_FramelessDialog_h
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
class FramelessDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum Position { POSITION_LEFT, POSITION_RIGHT, POSITION_TOP };
|
|
||||||
|
|
||||||
FramelessDialog(QWidget* parent, Qt::WindowFlags flags = 0, Position position = POSITION_LEFT);
|
|
||||||
void setStyleSheetFile(const QString& fileName);
|
|
||||||
void setAllowResize(bool allowResize) { _allowResize = allowResize; }
|
|
||||||
bool getAllowResize() { return _allowResize; }
|
|
||||||
void setHideOnBlur(bool hideOnBlur) { _hideOnBlur = hideOnBlur; }
|
|
||||||
bool getHideOnBlur() { return _hideOnBlur; }
|
|
||||||
void resizeAndPosition(bool resizeParent = true);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void mouseMoveEvent(QMouseEvent* mouseEvent);
|
|
||||||
virtual void mousePressEvent(QMouseEvent* mouseEvent);
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* mouseEvent);
|
|
||||||
virtual void showEvent(QShowEvent* event);
|
|
||||||
|
|
||||||
bool eventFilter(QObject* sender, QEvent* event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _allowResize;
|
|
||||||
bool _isResizing;
|
|
||||||
int _resizeInitialWidth;
|
|
||||||
bool _selfHidden; ///< true when the dialog itself because of a window event (deactivation or minimization)
|
|
||||||
Position _position;
|
|
||||||
bool _hideOnBlur;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // hifi_FramelessDialog_h
|
|
|
@ -1,118 +1,33 @@
|
||||||
//
|
//
|
||||||
|
//
|
||||||
// LoginDialog.cpp
|
// LoginDialog.cpp
|
||||||
// interface/src/ui
|
|
||||||
//
|
//
|
||||||
// Created by Ryan Huffman on 4/23/14.
|
// Created by Bradley Austin Davis on 2015/04/14
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QPixmap>
|
|
||||||
|
|
||||||
#include <NetworkingConstants.h>
|
|
||||||
#include <PathUtils.h>
|
|
||||||
|
|
||||||
#include "Application.h"
|
|
||||||
#include "Menu.h"
|
|
||||||
#include "AccountManager.h"
|
|
||||||
#include "ui_loginDialog.h"
|
|
||||||
#include "LoginDialog.h"
|
#include "LoginDialog.h"
|
||||||
#include "UIUtil.h"
|
|
||||||
|
|
||||||
const QString CREATE_ACCOUNT_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/signup";
|
#include "DependencyManager.h"
|
||||||
const QString FORGOT_PASSWORD_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/users/password/new";
|
#include "AccountManager.h"
|
||||||
|
#include "Menu.h"
|
||||||
|
#include <NetworkingConstants.h>
|
||||||
|
|
||||||
LoginDialog::LoginDialog(QWidget* parent) :
|
QML_DIALOG_DEF(LoginDialog)
|
||||||
FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP),
|
|
||||||
_ui(new Ui::LoginDialog) {
|
|
||||||
|
|
||||||
_ui->setupUi(this);
|
|
||||||
reset();
|
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
|
||||||
|
|
||||||
|
LoginDialog::LoginDialog(QQuickItem *parent) : QQuickItem(parent), _rootUrl(NetworkingConstants::METAVERSE_SERVER_URL.toString()) {
|
||||||
connect(&AccountManager::getInstance(), &AccountManager::loginComplete,
|
connect(&AccountManager::getInstance(), &AccountManager::loginComplete,
|
||||||
this, &LoginDialog::handleLoginCompleted);
|
this, &LoginDialog::handleLoginCompleted);
|
||||||
connect(&AccountManager::getInstance(), &AccountManager::loginFailed,
|
connect(&AccountManager::getInstance(), &AccountManager::loginFailed,
|
||||||
this, &LoginDialog::handleLoginFailed);
|
this, &LoginDialog::handleLoginFailed);
|
||||||
connect(_ui->loginButton, &QPushButton::clicked,
|
|
||||||
this, &LoginDialog::handleLoginClicked);
|
|
||||||
connect(_ui->closeButton, &QPushButton::clicked,
|
|
||||||
this, &LoginDialog::close);
|
|
||||||
|
|
||||||
UIUtil::scaleWidgetFontSizes(this);
|
|
||||||
_ui->accountLabel->setText(_ui->accountLabel->text().arg(CREATE_ACCOUNT_URL, FORGOT_PASSWORD_URL));
|
|
||||||
|
|
||||||
// Initialize toggle connection
|
|
||||||
toggleQAction();
|
|
||||||
};
|
|
||||||
|
|
||||||
LoginDialog::~LoginDialog() {
|
|
||||||
delete _ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
void LoginDialog::reset() {
|
|
||||||
_ui->errorLabel->hide();
|
|
||||||
_ui->emailLineEdit->setFocus();
|
|
||||||
_ui->logoLabel->setPixmap(QPixmap(PathUtils::resourcesPath() + "images/hifi-logo.svg"));
|
|
||||||
_ui->loginButton->setIcon(QIcon(PathUtils::resourcesPath() + "images/login.svg"));
|
|
||||||
_ui->closeButton->setIcon(QIcon(PathUtils::resourcesPath() + "images/close.svg"));
|
|
||||||
_ui->infoLabel->setVisible(false);
|
|
||||||
_ui->errorLabel->setVisible(false);
|
|
||||||
|
|
||||||
_ui->emailLineEdit->setText("");
|
|
||||||
_ui->passwordLineEdit->setText("");
|
|
||||||
_ui->loginArea->setDisabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoginDialog::handleLoginCompleted(const QUrl& authURL) {
|
void LoginDialog::toggleAction() {
|
||||||
reset();
|
|
||||||
close();
|
|
||||||
};
|
|
||||||
|
|
||||||
void LoginDialog::handleLoginFailed() {
|
|
||||||
_ui->infoLabel->setVisible(false);
|
|
||||||
_ui->errorLabel->setVisible(true);
|
|
||||||
|
|
||||||
_ui->errorLabel->show();
|
|
||||||
_ui->loginArea->setDisabled(false);
|
|
||||||
|
|
||||||
// Move focus to password and select the entire line
|
|
||||||
_ui->passwordLineEdit->setFocus();
|
|
||||||
_ui->passwordLineEdit->setSelection(0, _ui->emailLineEdit->maxLength());
|
|
||||||
};
|
|
||||||
|
|
||||||
void LoginDialog::handleLoginClicked() {
|
|
||||||
// If the email or password inputs are empty, move focus to them, otherwise attempt to login.
|
|
||||||
if (_ui->emailLineEdit->text().isEmpty()) {
|
|
||||||
_ui->emailLineEdit->setFocus();
|
|
||||||
} else if (_ui->passwordLineEdit->text().isEmpty()) {
|
|
||||||
_ui->passwordLineEdit->setFocus();
|
|
||||||
} else {
|
|
||||||
_ui->infoLabel->setVisible(true);
|
|
||||||
_ui->errorLabel->setVisible(false);
|
|
||||||
|
|
||||||
_ui->loginArea->setDisabled(true);
|
|
||||||
AccountManager::getInstance().requestAccessToken(_ui->emailLineEdit->text(), _ui->passwordLineEdit->text());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void LoginDialog::moveEvent(QMoveEvent* event) {
|
|
||||||
// Modal dialogs seemed to get repositioned automatically. Combat this by moving the window if needed.
|
|
||||||
resizeAndPosition();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void LoginDialog::toggleQAction() {
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
QAction* loginAction = Menu::getInstance()->getActionForOption(MenuOption::Login);
|
QAction* loginAction = Menu::getInstance()->getActionForOption(MenuOption::Login);
|
||||||
Q_CHECK_PTR(loginAction);
|
Q_CHECK_PTR(loginAction);
|
||||||
|
|
||||||
disconnect(loginAction, 0, 0, 0);
|
disconnect(loginAction, 0, 0, 0);
|
||||||
|
|
||||||
if (accountManager.isLoggedIn()) {
|
if (accountManager.isLoggedIn()) {
|
||||||
|
@ -122,11 +37,40 @@ void LoginDialog::toggleQAction() {
|
||||||
} else {
|
} else {
|
||||||
// change the menu item to login
|
// change the menu item to login
|
||||||
loginAction->setText("Login");
|
loginAction->setText("Login");
|
||||||
connect(loginAction, &QAction::triggered, this, &LoginDialog::showLoginForCurrentDomain);
|
connect(loginAction, &QAction::triggered, &LoginDialog::show);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoginDialog::showLoginForCurrentDomain() {
|
void LoginDialog::handleLoginCompleted(const QUrl& authURL) {
|
||||||
show();
|
setEnabled(false);
|
||||||
resizeAndPosition(false);
|
setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginDialog::handleLoginFailed() {
|
||||||
|
setStatusText("<font color = \"#267077\">Invalid username or password.< / font>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginDialog::setStatusText(const QString &a) {
|
||||||
|
if (a != _statusText) {
|
||||||
|
_statusText = a;
|
||||||
|
emit statusTextChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LoginDialog::statusText() const {
|
||||||
|
return _statusText;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LoginDialog::rootUrl() const {
|
||||||
|
return _rootUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginDialog::login(const QString & username, const QString & password) {
|
||||||
|
qDebug() << "Attempting to login " << username;
|
||||||
|
setStatusText("Authenticating...");
|
||||||
|
AccountManager::getInstance().requestAccessToken(username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginDialog::openUrl(const QString & url) {
|
||||||
|
qDebug() << url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
//
|
//
|
||||||
// LoginDialog.h
|
// LoginDialog.h
|
||||||
// interface/src/ui
|
|
||||||
//
|
//
|
||||||
// Created by Ryan Huffman on 4/23/14.
|
// Created by Bradley Austin Davis on 2015/04/14
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
@ -12,35 +11,41 @@
|
||||||
#ifndef hifi_LoginDialog_h
|
#ifndef hifi_LoginDialog_h
|
||||||
#define hifi_LoginDialog_h
|
#define hifi_LoginDialog_h
|
||||||
|
|
||||||
#include <QObject>
|
#pragma once
|
||||||
#include "FramelessDialog.h"
|
#include <QQuickItem>
|
||||||
|
|
||||||
namespace Ui {
|
#include "OffscreenUi.h"
|
||||||
class LoginDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoginDialog : public FramelessDialog {
|
class LoginDialog : public QQuickItem
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
QML_DIALOG_DECL
|
||||||
|
|
||||||
|
Q_PROPERTY(QString statusText READ statusText WRITE setStatusText NOTIFY statusTextChanged)
|
||||||
|
Q_PROPERTY(QString rootUrl READ rootUrl)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LoginDialog(QWidget* parent);
|
static void toggleAction();
|
||||||
~LoginDialog();
|
|
||||||
|
|
||||||
public slots:
|
LoginDialog(QQuickItem *parent = 0);
|
||||||
void toggleQAction();
|
|
||||||
void showLoginForCurrentDomain();
|
|
||||||
|
|
||||||
protected slots:
|
void setStatusText(const QString & a);
|
||||||
void reset();
|
QString statusText() const;
|
||||||
void handleLoginClicked();
|
|
||||||
|
QString rootUrl() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void statusTextChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
void handleLoginCompleted(const QUrl& authURL);
|
void handleLoginCompleted(const QUrl& authURL);
|
||||||
void handleLoginFailed();
|
void handleLoginFailed();
|
||||||
|
|
||||||
protected:
|
Q_INVOKABLE void login(const QString & username, const QString & password);
|
||||||
void moveEvent(QMoveEvent* event);
|
Q_INVOKABLE void openUrl(const QString & url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::LoginDialog* _ui = nullptr;
|
QString _statusText;
|
||||||
|
const QString _rootUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_LoginDialog_h
|
#endif // hifi_LoginDialog_h
|
||||||
|
|
|
@ -6,7 +6,7 @@ AUTOSCRIBE_SHADER_LIB(gpu model)
|
||||||
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
||||||
|
|
||||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||||
setup_hifi_library(Widgets OpenGL Network Script)
|
setup_hifi_library(Widgets OpenGL Network Qml Quick Script)
|
||||||
|
|
||||||
add_dependency_external_projects(glm)
|
add_dependency_external_projects(glm)
|
||||||
find_package(GLM REQUIRED)
|
find_package(GLM REQUIRED)
|
||||||
|
|
98
libraries/render-utils/src/FboCache.cpp
Normal file
98
libraries/render-utils/src/FboCache.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
//
|
||||||
|
// OffscreenGlCanvas.cpp
|
||||||
|
// interface/src/renderer
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2014/04/09.
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "FboCache.h"
|
||||||
|
|
||||||
|
#include <QOpenGLFramebufferObject>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "ThreadHelpers.h"
|
||||||
|
|
||||||
|
FboCache::FboCache() {
|
||||||
|
// Why do we even HAVE that lever?
|
||||||
|
}
|
||||||
|
|
||||||
|
void FboCache::lockTexture(int texture) {
|
||||||
|
withLock(_lock, [&] {
|
||||||
|
Q_ASSERT(_fboMap.count(texture));
|
||||||
|
if (!_fboLocks.count(texture)) {
|
||||||
|
Q_ASSERT(_readyFboQueue.front()->texture() == texture);
|
||||||
|
_readyFboQueue.pop_front();
|
||||||
|
_fboLocks[texture] = 1;
|
||||||
|
} else {
|
||||||
|
_fboLocks[texture]++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FboCache::releaseTexture(int texture) {
|
||||||
|
withLock(_lock, [&] {
|
||||||
|
Q_ASSERT(_fboMap.count(texture));
|
||||||
|
Q_ASSERT(_fboLocks.count(texture));
|
||||||
|
int newLockCount = --_fboLocks[texture];
|
||||||
|
if (!newLockCount) {
|
||||||
|
auto fbo = _fboMap[texture].data();
|
||||||
|
if (fbo->size() != _size) {
|
||||||
|
// Move the old FBO to the destruction queue.
|
||||||
|
// We can't destroy the FBO here because we might
|
||||||
|
// not be on the right thread or have the context active
|
||||||
|
_destroyFboQueue.push_back(_fboMap[texture]);
|
||||||
|
_fboMap.remove(texture);
|
||||||
|
} else {
|
||||||
|
_readyFboQueue.push_back(fbo);
|
||||||
|
}
|
||||||
|
_fboLocks.remove(texture);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QOpenGLFramebufferObject* FboCache::getReadyFbo() {
|
||||||
|
QOpenGLFramebufferObject* result = nullptr;
|
||||||
|
withLock(_lock, [&] {
|
||||||
|
// Delete any FBOs queued for deletion
|
||||||
|
_destroyFboQueue.clear();
|
||||||
|
|
||||||
|
if (_readyFboQueue.empty()) {
|
||||||
|
qDebug() << "Building new offscreen FBO number " << _fboMap.size() + 1;
|
||||||
|
result = new QOpenGLFramebufferObject(_size, QOpenGLFramebufferObject::CombinedDepthStencil);
|
||||||
|
_fboMap[result->texture()] = QSharedPointer<QOpenGLFramebufferObject>(result);
|
||||||
|
_readyFboQueue.push_back(result);
|
||||||
|
} else {
|
||||||
|
result = _readyFboQueue.front();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FboCache::setSize(const QSize & newSize) {
|
||||||
|
if (_size == newSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_size = newSize;
|
||||||
|
withLock(_lock, [&] {
|
||||||
|
// Clear out any fbos with the old id
|
||||||
|
_readyFboQueue.clear();
|
||||||
|
|
||||||
|
QSet<int> outdatedFbos;
|
||||||
|
// FBOs that are locked will be removed as they are unlocked
|
||||||
|
foreach(int texture, _fboMap.keys()) {
|
||||||
|
if (!_fboLocks.count(texture)) {
|
||||||
|
outdatedFbos.insert(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Implicitly deletes the FBO via the shared pointer destruction mechanism
|
||||||
|
foreach(int texture, outdatedFbos) {
|
||||||
|
_fboMap.remove(texture);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
50
libraries/render-utils/src/FboCache.h
Normal file
50
libraries/render-utils/src/FboCache.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
//
|
||||||
|
// OffscreenGlCanvas.h
|
||||||
|
// interface/src/renderer
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2014/04/09.
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#ifndef hifi_FboCache_h
|
||||||
|
#define hifi_FboCache_h
|
||||||
|
|
||||||
|
#include <QOpenGLContext>
|
||||||
|
#include <QOffscreenSurface>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
|
class QOpenGLFramebufferObject;
|
||||||
|
|
||||||
|
class FboCache : public QObject {
|
||||||
|
public:
|
||||||
|
FboCache();
|
||||||
|
|
||||||
|
// setSize() and getReadyFbo() must consitently be called from only a single
|
||||||
|
// thread. Additionally, it is the caller's responsibility to ensure that
|
||||||
|
// the appropriate OpenGL context is active when doing so.
|
||||||
|
|
||||||
|
// Important.... textures are sharable resources, but FBOs ARE NOT.
|
||||||
|
void setSize(const QSize & newSize);
|
||||||
|
QOpenGLFramebufferObject* getReadyFbo();
|
||||||
|
|
||||||
|
// These operations are thread safe and require no OpenGL context. They manipulate the
|
||||||
|
// internal locks and pointers but execute no OpenGL opreations.
|
||||||
|
void lockTexture(int texture);
|
||||||
|
void releaseTexture(int texture);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QMap<int, QSharedPointer<QOpenGLFramebufferObject>> _fboMap;
|
||||||
|
QMap<int, int> _fboLocks;
|
||||||
|
QQueue<QOpenGLFramebufferObject*> _readyFboQueue;
|
||||||
|
QQueue<QSharedPointer<QOpenGLFramebufferObject>> _destroyFboQueue;
|
||||||
|
QMutex _lock;
|
||||||
|
QSize _size;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_FboCache_h
|
43
libraries/render-utils/src/OffscreenGlCanvas.cpp
Normal file
43
libraries/render-utils/src/OffscreenGlCanvas.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// OffscreenGlCanvas.cpp
|
||||||
|
// interface/src/renderer
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2014/04/09.
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "OffscreenGlCanvas.h"
|
||||||
|
|
||||||
|
OffscreenGlCanvas::OffscreenGlCanvas() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenGlCanvas::create(QOpenGLContext * sharedContext) {
|
||||||
|
QSurfaceFormat format;
|
||||||
|
format.setDepthBufferSize(16);
|
||||||
|
format.setStencilBufferSize(8);
|
||||||
|
format.setMajorVersion(4);
|
||||||
|
format.setMinorVersion(1);
|
||||||
|
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
|
||||||
|
|
||||||
|
_context.setFormat(format);
|
||||||
|
if (nullptr != sharedContext) {
|
||||||
|
_context.setShareContext(sharedContext);
|
||||||
|
}
|
||||||
|
_context.create();
|
||||||
|
|
||||||
|
_offscreenSurface.setFormat(_context.format());
|
||||||
|
_offscreenSurface.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OffscreenGlCanvas::makeCurrent() {
|
||||||
|
return _context.makeCurrent(&_offscreenSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenGlCanvas::doneCurrent() {
|
||||||
|
_context.doneCurrent();
|
||||||
|
}
|
||||||
|
|
31
libraries/render-utils/src/OffscreenGlCanvas.h
Normal file
31
libraries/render-utils/src/OffscreenGlCanvas.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// OffscreenGlCanvas.h
|
||||||
|
// interface/src/renderer
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2014/04/09.
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#ifndef hifi_OffscreenGlCanvas_h
|
||||||
|
#define hifi_OffscreenGlCanvas_h
|
||||||
|
|
||||||
|
#include <QOpenGLContext>
|
||||||
|
#include <QOffscreenSurface>
|
||||||
|
|
||||||
|
class OffscreenGlCanvas : public QObject {
|
||||||
|
public:
|
||||||
|
OffscreenGlCanvas();
|
||||||
|
void create(QOpenGLContext * sharedContext = nullptr);
|
||||||
|
bool makeCurrent();
|
||||||
|
void doneCurrent();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QOpenGLContext _context;
|
||||||
|
QOffscreenSurface _offscreenSurface;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_OffscreenGlCanvas_h
|
325
libraries/render-utils/src/OffscreenUi.cpp
Normal file
325
libraries/render-utils/src/OffscreenUi.cpp
Normal file
|
@ -0,0 +1,325 @@
|
||||||
|
#include "OffscreenUi.h"
|
||||||
|
#include <QOpenGLFramebufferObject>
|
||||||
|
#include <QOpenGLDebugLogger>
|
||||||
|
#include <QGLWidget>
|
||||||
|
|
||||||
|
OffscreenUi::OffscreenUi() {
|
||||||
|
}
|
||||||
|
|
||||||
|
OffscreenUi::~OffscreenUi() {
|
||||||
|
// Make sure the context is current while doing cleanup. Note that we use the
|
||||||
|
// offscreen surface here because passing 'this' at this point is not safe: the
|
||||||
|
// underlying platform window may already be destroyed. To avoid all the trouble, use
|
||||||
|
// another surface that is valid for sure.
|
||||||
|
makeCurrent();
|
||||||
|
|
||||||
|
// Delete the render control first since it will free the scenegraph resources.
|
||||||
|
// Destroy the QQuickWindow only afterwards.
|
||||||
|
delete _renderControl;
|
||||||
|
|
||||||
|
delete _qmlComponent;
|
||||||
|
delete _quickWindow;
|
||||||
|
delete _qmlEngine;
|
||||||
|
|
||||||
|
doneCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::create(QOpenGLContext * shareContext) {
|
||||||
|
OffscreenGlCanvas::create(shareContext);
|
||||||
|
|
||||||
|
makeCurrent();
|
||||||
|
|
||||||
|
// Create a QQuickWindow that is associated with out render control. Note that this
|
||||||
|
// window never gets created or shown, meaning that it will never get an underlying
|
||||||
|
// native (platform) window.
|
||||||
|
QQuickWindow::setDefaultAlphaBuffer(true);
|
||||||
|
_quickWindow = new QQuickWindow(_renderControl);
|
||||||
|
_quickWindow->setColor(QColor(255, 255, 255, 0));
|
||||||
|
_quickWindow->setFlags(_quickWindow->flags() | static_cast<Qt::WindowFlags>(Qt::WA_TranslucentBackground));
|
||||||
|
// Create a QML engine.
|
||||||
|
_qmlEngine = new QQmlEngine;
|
||||||
|
if (!_qmlEngine->incubationController())
|
||||||
|
_qmlEngine->setIncubationController(_quickWindow->incubationController());
|
||||||
|
|
||||||
|
// When Quick says there is a need to render, we will not render immediately. Instead,
|
||||||
|
// a timer with a small interval is used to get better performance.
|
||||||
|
_updateTimer.setSingleShot(true);
|
||||||
|
_updateTimer.setInterval(5);
|
||||||
|
connect(&_updateTimer, &QTimer::timeout, this, &OffscreenUi::updateQuick);
|
||||||
|
|
||||||
|
// Now hook up the signals. For simplicy we don't differentiate between
|
||||||
|
// renderRequested (only render is needed, no sync) and sceneChanged (polish and sync
|
||||||
|
// is needed too).
|
||||||
|
connect(_renderControl, &QQuickRenderControl::renderRequested, this, &OffscreenUi::requestRender);
|
||||||
|
connect(_renderControl, &QQuickRenderControl::sceneChanged, this, &OffscreenUi::requestUpdate);
|
||||||
|
connect(_quickWindow, &QQuickWindow::focusObjectChanged, this, [this](QObject *object){
|
||||||
|
OffscreenUi * p = this;
|
||||||
|
qDebug() << "Focus changed to " << object;
|
||||||
|
});
|
||||||
|
_quickWindow->focusObject();
|
||||||
|
|
||||||
|
_qmlComponent = new QQmlComponent(_qmlEngine);
|
||||||
|
|
||||||
|
// Initialize the render control and our OpenGL resources.
|
||||||
|
makeCurrent();
|
||||||
|
_renderControl->initialize(&_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::resize(const QSize & newSize) {
|
||||||
|
makeCurrent();
|
||||||
|
|
||||||
|
// Clear out any fbos with the old size
|
||||||
|
_fboCache.setSize(newSize);
|
||||||
|
|
||||||
|
// Update our members
|
||||||
|
if (_rootItem) {
|
||||||
|
_rootItem->setSize(newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_quickWindow) {
|
||||||
|
_quickWindow->setGeometry(QRect(QPoint(), newSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
doneCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlContext * OffscreenUi::qmlContext() {
|
||||||
|
if (nullptr == _rootItem) {
|
||||||
|
return _qmlComponent->creationContext();
|
||||||
|
}
|
||||||
|
return QQmlEngine::contextForObject(_rootItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::loadQml(const QUrl & qmlSource, std::function<void(QQmlContext*)> f) {
|
||||||
|
_qmlComponent->loadUrl(qmlSource);
|
||||||
|
if (_qmlComponent->isLoading())
|
||||||
|
connect(_qmlComponent, &QQmlComponent::statusChanged, this, &OffscreenUi::finishQmlLoad);
|
||||||
|
else
|
||||||
|
finishQmlLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::requestUpdate() {
|
||||||
|
_polish = true;
|
||||||
|
if (!_updateTimer.isActive())
|
||||||
|
_updateTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::requestRender() {
|
||||||
|
if (!_updateTimer.isActive())
|
||||||
|
_updateTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::finishQmlLoad() {
|
||||||
|
disconnect(_qmlComponent, &QQmlComponent::statusChanged, this, &OffscreenUi::finishQmlLoad);
|
||||||
|
if (_qmlComponent->isError()) {
|
||||||
|
QList<QQmlError> errorList = _qmlComponent->errors();
|
||||||
|
foreach(const QQmlError &error, errorList) {
|
||||||
|
qWarning() << error.url() << error.line() << error;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *rootObject = _qmlComponent->create();
|
||||||
|
if (_qmlComponent->isError()) {
|
||||||
|
QList<QQmlError> errorList = _qmlComponent->errors();
|
||||||
|
foreach(const QQmlError &error, errorList)
|
||||||
|
qWarning() << error.url() << error.line() << error;
|
||||||
|
qFatal("Unable to finish loading QML");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_rootItem = qobject_cast<QQuickItem *>(rootObject);
|
||||||
|
if (!_rootItem) {
|
||||||
|
qWarning("run: Not a QQuickItem");
|
||||||
|
delete rootObject;
|
||||||
|
qFatal("Unable to find root QQuickItem");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we can assign focus to the root item (critical for
|
||||||
|
// supporting keyboard shortcuts)
|
||||||
|
_rootItem->setFlag(QQuickItem::ItemIsFocusScope, true);
|
||||||
|
// The root item is ready. Associate it with the window.
|
||||||
|
_rootItem->setParentItem(_quickWindow->contentItem());
|
||||||
|
_rootItem->setSize(_quickWindow->renderTargetSize());
|
||||||
|
qDebug() << "Finished setting up QML provider";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OffscreenUi::updateQuick() {
|
||||||
|
if (_paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!makeCurrent())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Polish, synchronize and render the next frame (into our fbo). In this example
|
||||||
|
// everything happens on the same thread and therefore all three steps are performed
|
||||||
|
// in succession from here. In a threaded setup the render() call would happen on a
|
||||||
|
// separate thread.
|
||||||
|
if (_polish) {
|
||||||
|
_renderControl->polishItems();
|
||||||
|
_renderControl->sync();
|
||||||
|
_polish = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QOpenGLFramebufferObject* fbo = _fboCache.getReadyFbo();
|
||||||
|
|
||||||
|
_quickWindow->setRenderTarget(fbo);
|
||||||
|
fbo->bind();
|
||||||
|
|
||||||
|
glClearColor(0, 0, 0, 1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
_renderControl->render();
|
||||||
|
|
||||||
|
Q_ASSERT(!glGetError());
|
||||||
|
|
||||||
|
_quickWindow->resetOpenGLState();
|
||||||
|
|
||||||
|
QOpenGLFramebufferObject::bindDefault();
|
||||||
|
// Force completion of all the operations before we emit the texture as being ready for use
|
||||||
|
glFinish();
|
||||||
|
|
||||||
|
emit textureUpdated(fbo->texture());
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF OffscreenUi::mapWindowToUi(const QPointF & p, QObject * dest) {
|
||||||
|
vec2 sourceSize;
|
||||||
|
if (dynamic_cast<QWidget*>(dest)) {
|
||||||
|
sourceSize = toGlm(((QWidget*)dest)->size());
|
||||||
|
} else if (dynamic_cast<QWindow*>(dest)) {
|
||||||
|
sourceSize = toGlm(((QWindow*)dest)->size());
|
||||||
|
}
|
||||||
|
vec2 pos = toGlm(p);
|
||||||
|
pos /= sourceSize;
|
||||||
|
pos *= vec2(toGlm(_quickWindow->renderTargetSize()));
|
||||||
|
return QPointF(pos.x, pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Event handling customization
|
||||||
|
//
|
||||||
|
|
||||||
|
bool OffscreenUi::eventFilter(QObject * dest, QEvent * e) {
|
||||||
|
// Only intercept events while we're in an active state
|
||||||
|
if (_paused) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't intercept our own events, or we enter an infinite recursion
|
||||||
|
if (dest == _quickWindow) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (e->type()) {
|
||||||
|
case QEvent::Resize:
|
||||||
|
{
|
||||||
|
QResizeEvent * re = (QResizeEvent *)e;
|
||||||
|
QGLWidget * widget = dynamic_cast<QGLWidget*>(dest);
|
||||||
|
if (widget) {
|
||||||
|
this->resize(re->size());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QEvent::KeyPress:
|
||||||
|
case QEvent::KeyRelease:
|
||||||
|
{
|
||||||
|
e->ignore();
|
||||||
|
if (QApplication::sendEvent(_quickWindow, e)) {
|
||||||
|
return e->isAccepted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QEvent::Wheel:
|
||||||
|
{
|
||||||
|
QWheelEvent * we = (QWheelEvent*)e;
|
||||||
|
QWheelEvent mappedEvent(mapWindowToUi(we->pos(), dest), we->delta(), we->buttons(), we->modifiers(), we->orientation());
|
||||||
|
QCoreApplication::sendEvent(_quickWindow, &mappedEvent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Fall through
|
||||||
|
case QEvent::MouseButtonDblClick:
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
case QEvent::MouseMove:
|
||||||
|
{
|
||||||
|
QMouseEvent * me = (QMouseEvent *)e;
|
||||||
|
QPointF originalPos = me->localPos();
|
||||||
|
QPointF transformedPos = _mouseTranslator(originalPos);
|
||||||
|
QMouseEvent mappedEvent(e->type(), mapWindowToUi(transformedPos, dest), me->screenPos(), me->button(), me->buttons(), me->modifiers());
|
||||||
|
QCoreApplication::sendEvent(_quickWindow, &mappedEvent);
|
||||||
|
return QObject::event(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::lockTexture(int texture) {
|
||||||
|
_fboCache.lockTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::releaseTexture(int texture) {
|
||||||
|
_fboCache.releaseTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::pause() {
|
||||||
|
_paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::resume() {
|
||||||
|
_paused = false;
|
||||||
|
requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OffscreenUi::isPaused() const {
|
||||||
|
return _paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::setProxyWindow(QWindow * window) {
|
||||||
|
_renderControl->_renderWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::show(const QUrl & url, const QString & name) {
|
||||||
|
QQuickItem * item = _rootItem->findChild<QQuickItem*>(name);
|
||||||
|
if (nullptr != item) {
|
||||||
|
item->setEnabled(true);
|
||||||
|
item->setVisible(true);
|
||||||
|
} else {
|
||||||
|
load(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenUi::toggle(const QUrl & url, const QString & name) {
|
||||||
|
QQuickItem * item = _rootItem->findChild<QQuickItem*>(name);
|
||||||
|
// First load?
|
||||||
|
if (nullptr == item) {
|
||||||
|
load(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the visibity AND the enabled flag (otherwise invisible
|
||||||
|
// dialogs can still swallow keyboard input)
|
||||||
|
bool newFlag = !item->isVisible();
|
||||||
|
item->setVisible(newFlag);
|
||||||
|
item->setEnabled(newFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OffscreenUi::load(const QUrl & url) {
|
||||||
|
QVariant returnedValue;
|
||||||
|
QVariant msg = url;
|
||||||
|
QMetaObject::invokeMethod(_rootItem, "loadChild",
|
||||||
|
Q_RETURN_ARG(QVariant, returnedValue),
|
||||||
|
Q_ARG(QVariant, msg));
|
||||||
|
qDebug() << "QML function returned:" << returnedValue.toString();
|
||||||
|
}
|
||||||
|
|
136
libraries/render-utils/src/OffscreenUi.h
Normal file
136
libraries/render-utils/src/OffscreenUi.h
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
//
|
||||||
|
// OffscreenUi.h
|
||||||
|
// interface/src/entities
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015-04-04
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#ifndef hifi_OffscreenUi_h
|
||||||
|
#define hifi_OffscreenUi_h
|
||||||
|
|
||||||
|
|
||||||
|
#include <QOpenGLContext>
|
||||||
|
#include <QOffscreenSurface>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QQuickWindow>
|
||||||
|
#include <QQuickRenderControl>
|
||||||
|
#include <QQuickImageProvider>
|
||||||
|
#include <GLMHelpers.h>
|
||||||
|
#include <ThreadHelpers.h>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <atomic>
|
||||||
|
#include <functional>
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
#include "FboCache.h"
|
||||||
|
#include "OffscreenGlCanvas.h"
|
||||||
|
|
||||||
|
#define QML_DIALOG_DECL \
|
||||||
|
private: \
|
||||||
|
static const QString NAME; \
|
||||||
|
static const QUrl QML; \
|
||||||
|
public: \
|
||||||
|
static void registerType(); \
|
||||||
|
static void show(); \
|
||||||
|
static void toggle(); \
|
||||||
|
private:
|
||||||
|
|
||||||
|
#define QML_DIALOG_DEF(x) \
|
||||||
|
const QUrl x::QML = #x ".qml"; \
|
||||||
|
const QString x::NAME = #x; \
|
||||||
|
\
|
||||||
|
void x::registerType() { \
|
||||||
|
qmlRegisterType<x>("Hifi", 1, 0, NAME.toLocal8Bit().constData()); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void x::show() { \
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>(); \
|
||||||
|
offscreenUi->show(QML, NAME); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void x::toggle() { \
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>(); \
|
||||||
|
offscreenUi->toggle(QML, NAME); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class OffscreenUi : public OffscreenGlCanvas, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
class QMyQuickRenderControl : public QQuickRenderControl {
|
||||||
|
protected:
|
||||||
|
QWindow * renderWindow(QPoint * offset) Q_DECL_OVERRIDE{
|
||||||
|
if (nullptr == _renderWindow) {
|
||||||
|
return QQuickRenderControl::renderWindow(offset);
|
||||||
|
}
|
||||||
|
if (nullptr != offset) {
|
||||||
|
offset->rx() = offset->ry() = 0;
|
||||||
|
}
|
||||||
|
return _renderWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWindow * _renderWindow{ nullptr };
|
||||||
|
friend class OffscreenUi;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
using MouseTranslator = std::function < QPointF(const QPointF &) > ;
|
||||||
|
OffscreenUi();
|
||||||
|
virtual ~OffscreenUi();
|
||||||
|
void create(QOpenGLContext * context);
|
||||||
|
void resize(const QSize & size);
|
||||||
|
void loadQml(const QUrl & qmlSource, std::function<void(QQmlContext*)> f = [](QQmlContext*) {});
|
||||||
|
void load(const QUrl & url);
|
||||||
|
void show(const QUrl & url, const QString & name);
|
||||||
|
void toggle(const QUrl & url, const QString & name);
|
||||||
|
|
||||||
|
QQmlContext * qmlContext();
|
||||||
|
|
||||||
|
void pause();
|
||||||
|
void resume();
|
||||||
|
bool isPaused() const;
|
||||||
|
void setProxyWindow(QWindow * window);
|
||||||
|
QPointF mapWindowToUi(const QPointF & p, QObject * dest);
|
||||||
|
virtual bool eventFilter(QObject * dest, QEvent * e);
|
||||||
|
void setMouseTranslator(MouseTranslator mt) {
|
||||||
|
_mouseTranslator = mt;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateQuick();
|
||||||
|
void finishQmlLoad();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void requestUpdate();
|
||||||
|
void requestRender();
|
||||||
|
void lockTexture(int texture);
|
||||||
|
void releaseTexture(int texture);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void textureUpdated(GLuint texture);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMyQuickRenderControl *_renderControl{ new QMyQuickRenderControl };
|
||||||
|
QQuickWindow *_quickWindow{ nullptr };
|
||||||
|
QQmlEngine *_qmlEngine{ nullptr };
|
||||||
|
QQmlComponent *_qmlComponent{ nullptr };
|
||||||
|
QQuickItem * _rootItem{ nullptr };
|
||||||
|
QTimer _updateTimer;
|
||||||
|
FboCache _fboCache;
|
||||||
|
bool _polish{ true };
|
||||||
|
bool _paused{ true };
|
||||||
|
MouseTranslator _mouseTranslator{ [](const QPointF & p) { return p; } };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,4 +15,54 @@
|
||||||
/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax).
|
/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax).
|
||||||
void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f);
|
void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f);
|
||||||
|
|
||||||
|
template <typename F, GLenum matrix>
|
||||||
|
void withMatrixPush(F f) {
|
||||||
|
glMatrixMode(matrix);
|
||||||
|
glPushMatrix();
|
||||||
|
f();
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void withProjectionPush(F f) {
|
||||||
|
withMatrixPush<GL_PROJECTION>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void withProjectionIdentity(F f) {
|
||||||
|
withProjectionPush([&] {
|
||||||
|
glLoadIdentity();
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void withProjectionMatrix(GLfloat * matrix, F f) {
|
||||||
|
withProjectionPush([&] {
|
||||||
|
glLoadMatrixf(matrix);
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void withModelviewPush(F f) {
|
||||||
|
withMatrixPush<GL_MODELVIEW>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void withModelviewIdentity(F f) {
|
||||||
|
withModelviewPush([&] {
|
||||||
|
glLoadIdentity();
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void withModelviewMatrix(GLfloat * matrix, F f) {
|
||||||
|
withModelviewPush([&] {
|
||||||
|
glLoadMatrixf(matrix);
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#endif // hifi_RenderUtil_h
|
#endif // hifi_RenderUtil_h
|
||||||
|
|
|
@ -17,6 +17,17 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
// Bring the most commonly used GLM types into the default namespace
|
||||||
|
using glm::ivec3;
|
||||||
|
using glm::ivec2;
|
||||||
|
using glm::uvec2;
|
||||||
|
using glm::mat3;
|
||||||
|
using glm::mat4;
|
||||||
|
using glm::vec2;
|
||||||
|
using glm::vec3;
|
||||||
|
using glm::vec4;
|
||||||
|
using glm::quat;
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
#include <QtCore/QByteArray>
|
||||||
#include <QtGui/QMatrix4x4>
|
#include <QtGui/QMatrix4x4>
|
||||||
#include <QtGui/QColor>
|
#include <QtGui/QColor>
|
||||||
|
|
13
libraries/shared/src/ThreadHelpers.h
Normal file
13
libraries/shared/src/ThreadHelpers.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
template <typename L, typename F>
|
||||||
|
void withLock(L lock, F function) {
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void withLock(QMutex & lock, F function) {
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
function();
|
||||||
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "TextRenderer.h"
|
#include "TextRenderer.h"
|
||||||
#include "MatrixStack.h"
|
#include "MatrixStack.h"
|
||||||
|
#include "OffscreenUi.h"
|
||||||
|
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
@ -21,9 +22,11 @@
|
||||||
#include <QOpenGLBuffer>
|
#include <QOpenGLBuffer>
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
|
#include <QLoggingCategory>
|
||||||
#include <QOpenGLTexture>
|
#include <QOpenGLTexture>
|
||||||
#include <QOpenGLVertexArrayObject>
|
#include <QOpenGLVertexArrayObject>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QOpenGLDebugLogger>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
@ -68,52 +71,39 @@ public:
|
||||||
// Create a simple OpenGL window that renders text in various ways
|
// Create a simple OpenGL window that renders text in various ways
|
||||||
class QTestWindow : public QWindow {
|
class QTestWindow : public QWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QOpenGLContext * _context;
|
|
||||||
|
QOpenGLContext * _context{ nullptr };
|
||||||
QSize _size;
|
QSize _size;
|
||||||
TextRenderer* _textRenderer[4];
|
TextRenderer* _textRenderer[4];
|
||||||
RateCounter fps;
|
RateCounter fps;
|
||||||
|
OffscreenUi _offscreenUi;
|
||||||
|
int testQmlTexture{ 0 };
|
||||||
|
//ProgramPtr _planeProgam;
|
||||||
|
//ShapeWrapperPtr _planeShape;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent * ev) override {
|
|
||||||
QWindow::resizeEvent(ev);
|
|
||||||
_size = ev->size();
|
|
||||||
resizeGl();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resizeGl() {
|
void renderText();
|
||||||
glMatrixMode(GL_PROJECTION);
|
void renderQml();
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(0, _size.width(), _size.height(), 0, 1, -1);
|
private:
|
||||||
glMatrixMode(GL_MODELVIEW);
|
void resizeWindow(const QSize & size) {
|
||||||
glViewport(0, 0, _size.width(), _size.height());
|
_size = size;
|
||||||
|
_offscreenUi.resize(_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QTestWindow();
|
QTestWindow() {
|
||||||
virtual ~QTestWindow() {
|
|
||||||
|
|
||||||
}
|
|
||||||
void makeCurrent() {
|
|
||||||
_context->makeCurrent(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw();
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef SERIF_FONT_FAMILY
|
|
||||||
#define SERIF_FONT_FAMILY "Times New Roman"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QTestWindow::QTestWindow() {
|
|
||||||
setSurfaceType(QSurface::OpenGLSurface);
|
setSurfaceType(QSurface::OpenGLSurface);
|
||||||
|
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
|
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
|
||||||
format.setDepthBufferSize(16);
|
format.setDepthBufferSize(16);
|
||||||
format.setStencilBufferSize(8);
|
format.setStencilBufferSize(8);
|
||||||
format.setVersion(3, 2);
|
format.setVersion(4, 5);
|
||||||
format.setProfile(
|
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
|
||||||
QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
|
format.setOption(QSurfaceFormat::DebugContext);
|
||||||
|
|
||||||
setFormat(format);
|
setFormat(format);
|
||||||
|
|
||||||
_context = new QOpenGLContext;
|
_context = new QOpenGLContext;
|
||||||
|
@ -122,6 +112,16 @@ QTestWindow::QTestWindow() {
|
||||||
|
|
||||||
show();
|
show();
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
|
|
||||||
|
{
|
||||||
|
QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this);
|
||||||
|
logger->initialize(); // initializes in the current context, i.e. ctx
|
||||||
|
logger->enableMessages();
|
||||||
|
connect(logger, &QOpenGLDebugLogger::messageLogged, this, [&](const QOpenGLDebugMessage & debugMessage) {
|
||||||
|
qDebug() << debugMessage;
|
||||||
|
});
|
||||||
|
// logger->startLogging(QOpenGLDebugLogger::SynchronousLogging);
|
||||||
|
}
|
||||||
qDebug() << (const char*)glGetString(GL_VERSION);
|
qDebug() << (const char*)glGetString(GL_VERSION);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -141,10 +141,6 @@ QTestWindow::QTestWindow() {
|
||||||
glGetError();
|
glGetError();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setFramePosition(QPoint(100, -900));
|
|
||||||
resize(QSize(800, 600));
|
|
||||||
_size = QSize(800, 600);
|
|
||||||
|
|
||||||
_textRenderer[0] = TextRenderer::getInstance(SANS_FONT_FAMILY, 12, false);
|
_textRenderer[0] = TextRenderer::getInstance(SANS_FONT_FAMILY, 12, false);
|
||||||
_textRenderer[1] = TextRenderer::getInstance(SERIF_FONT_FAMILY, 12, false,
|
_textRenderer[1] = TextRenderer::getInstance(SERIF_FONT_FAMILY, 12, false,
|
||||||
TextRenderer::SHADOW_EFFECT);
|
TextRenderer::SHADOW_EFFECT);
|
||||||
|
@ -156,8 +152,59 @@ QTestWindow::QTestWindow() {
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glClearColor(0.2f, 0.2f, 0.2f, 1);
|
glClearColor(0.2f, 0.2f, 0.2f, 1);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
resizeGl();
|
|
||||||
|
_offscreenUi.create(_context);
|
||||||
|
// FIXME, need to switch to a QWindow for mouse and keyboard input to work
|
||||||
|
_offscreenUi.setProxyWindow(this);
|
||||||
|
// "#0e7077"
|
||||||
|
setFramePosition(QPoint(-1000, 0));
|
||||||
|
resize(QSize(800, 600));
|
||||||
|
|
||||||
|
static const QString f("/Users/bdavis/Git/hifi/interface/resources/qml/Root.qml");
|
||||||
|
_offscreenUi.loadQml(QUrl::fromLocalFile(f));
|
||||||
|
connect(&_offscreenUi, &OffscreenUi::textureUpdated, this, [&](int textureId) {
|
||||||
|
_offscreenUi.lockTexture(textureId);
|
||||||
|
assert(!glGetError());
|
||||||
|
GLuint oldTexture = testQmlTexture;
|
||||||
|
testQmlTexture = textureId;
|
||||||
|
if (oldTexture) {
|
||||||
|
_offscreenUi.releaseTexture(oldTexture);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
installEventFilter(&_offscreenUi);
|
||||||
|
_offscreenUi.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~QTestWindow() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
void makeCurrent() {
|
||||||
|
_context->makeCurrent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent * ev) override {
|
||||||
|
resizeWindow(ev->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void keyPressEvent(QKeyEvent *event) {
|
||||||
|
switch (event->key()) {
|
||||||
|
case Qt::Key_Slash:
|
||||||
|
qDebug() << "Foo";
|
||||||
|
_offscreenUi.load(QString("Login.qml"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QWindow::keyPressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef SERIF_FONT_FAMILY
|
||||||
|
#define SERIF_FONT_FAMILY "Times New Roman"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const wchar_t * EXAMPLE_TEXT = L"Hello";
|
static const wchar_t * EXAMPLE_TEXT = L"Hello";
|
||||||
//static const wchar_t * EXAMPLE_TEXT = L"\xC1y Hello 1.0\ny\xC1 line 2\n\xC1y";
|
//static const wchar_t * EXAMPLE_TEXT = L"\xC1y Hello 1.0\ny\xC1 line 2\n\xC1y";
|
||||||
|
@ -166,14 +213,21 @@ static const glm::uvec2 QUAD_OFFSET(10, 10);
|
||||||
static const glm::vec3 COLORS[4] = { { 1.0, 1.0, 1.0 }, { 0.5, 1.0, 0.5 }, {
|
static const glm::vec3 COLORS[4] = { { 1.0, 1.0, 1.0 }, { 0.5, 1.0, 0.5 }, {
|
||||||
1.0, 0.5, 0.5 }, { 0.5, 0.5, 1.0 } };
|
1.0, 0.5, 0.5 }, { 0.5, 0.5, 1.0 } };
|
||||||
|
|
||||||
void QTestWindow::draw() {
|
void QTestWindow::renderText() {
|
||||||
makeCurrent();
|
glMatrixMode(GL_PROJECTION);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glLoadIdentity();
|
||||||
|
glOrtho(0, _size.width(), _size.height(), 0, 1, -1);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
const glm::uvec2 size = glm::uvec2(_size.width() / 2, _size.height() / 2);
|
const glm::uvec2 size = glm::uvec2(_size.width() / 2, _size.height() / 2);
|
||||||
const glm::uvec2 offsets[4] = { { QUAD_OFFSET.x, QUAD_OFFSET.y }, { size.x
|
|
||||||
+ QUAD_OFFSET.x, QUAD_OFFSET.y }, { size.x + QUAD_OFFSET.x, size.y
|
const glm::uvec2 offsets[4] = {
|
||||||
+ QUAD_OFFSET.y }, { QUAD_OFFSET.x, size.y + QUAD_OFFSET.y }, };
|
{ QUAD_OFFSET.x, QUAD_OFFSET.y },
|
||||||
|
{ size.x + QUAD_OFFSET.x, QUAD_OFFSET.y },
|
||||||
|
{ size.x + QUAD_OFFSET.x, size.y + QUAD_OFFSET.y },
|
||||||
|
{ QUAD_OFFSET.x, size.y + QUAD_OFFSET.y },
|
||||||
|
};
|
||||||
|
|
||||||
QString str = QString::fromWCharArray(EXAMPLE_TEXT);
|
QString str = QString::fromWCharArray(EXAMPLE_TEXT);
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
@ -200,17 +254,57 @@ void QTestWindow::draw() {
|
||||||
glm::vec4(COLORS[i], 1.0f));
|
glm::vec4(COLORS[i], 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QTestWindow::renderQml() {
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
if (testQmlTexture > 0) {
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, testQmlTexture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
{
|
||||||
|
|
||||||
|
glTexCoord2f(0, 0);
|
||||||
|
glVertex2f(-1, -1);
|
||||||
|
glTexCoord2f(0, 1);
|
||||||
|
glVertex2f(-1, 1);
|
||||||
|
glTexCoord2f(1, 1);
|
||||||
|
glVertex2f(1, 1);
|
||||||
|
glTexCoord2f(1, 0);
|
||||||
|
glVertex2f(1, -1);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QTestWindow::draw() {
|
||||||
|
makeCurrent();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glViewport(0, 0, _size.width(), _size.height());
|
||||||
|
|
||||||
|
renderText();
|
||||||
|
//renderQml();
|
||||||
|
|
||||||
_context->swapBuffers(this);
|
_context->swapBuffers(this);
|
||||||
glFinish();
|
glFinish();
|
||||||
|
|
||||||
fps.increment();
|
fps.increment();
|
||||||
if (fps.elapsed() >= 2.0f) {
|
if (fps.elapsed() >= 2.0f) {
|
||||||
qDebug() << "FPS: " << fps.rate();
|
//qDebug() << "FPS: " << fps.rate();
|
||||||
fps.reset();
|
fps.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
//QLoggingCategory::setFilterRules("qt.quick.mouse.debug = true");
|
||||||
QTestWindow window;
|
QTestWindow window;
|
||||||
QTimer timer;
|
QTimer timer;
|
||||||
timer.setInterval(1);
|
timer.setInterval(1);
|
||||||
|
|
Loading…
Reference in a new issue