diff --git a/interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml b/interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml
new file mode 100644
index 0000000000..6024563bcf
--- /dev/null
+++ b/interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml
@@ -0,0 +1,124 @@
+//
+// CompleteProfileBody.qml
+//
+// Created by Clement on 7/18/16
+// Copyright 2015 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0
+import QtQuick 2.4
+import QtQuick.Controls.Styles 1.4 as OriginalStyles
+
+import "../controls-uit"
+import "../styles-uit"
+
+Item {
+ id: completeProfileBody
+ clip: true
+
+ QtObject {
+ id: d
+ function resize() {}
+ }
+
+ Row {
+ id: buttons
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ margins: 0
+ topMargin: 2 * hifi.dimensions.contentSpacing.y
+ }
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+ width: 200
+
+ text: qsTr("Create your profile")
+ color: hifi.buttons.blue
+
+ onClicked: loginDialog.createAccountFromStream()
+ }
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: qsTr("Cancel")
+
+ onClicked: bodyLoader.popup()
+ }
+ }
+
+ ShortcutText {
+ id: additionalTextContainer
+ anchors {
+ top: buttons.bottom
+ horizontalCenter: parent.horizontalCenter
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ text: "Already have a High Fidelity profile? Link to an existing profile here."
+
+ wrapMode: Text.WordWrap
+ lineHeight: 2
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+
+ onLinkActivated: {
+ bodyLoader.setSource("LinkAccountBody.qml")
+ }
+ }
+
+ InfoItem {
+ id: termsContainer
+ anchors {
+ top: additionalTextContainer.bottom
+ left: parent.left
+ margins: 0
+ topMargin: 2 * hifi.dimensions.contentSpacing.y
+ }
+
+ text: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service")
+ wrapMode: Text.WordWrap
+ color: hifi.colors.baseGrayHighlight
+ lineHeight: 1
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+
+ onLinkActivated: loginDialog.openUrl(link)
+ }
+
+ Component.onCompleted: {
+ loginDialogRoot.title = qsTr("Complete Your Profile")
+ loginDialogRoot.iconText = "<"
+ d.resize();
+ }
+
+ Connections {
+ target: loginDialog
+ onHandleCreateCompleted: {
+ console.log("Create Succeeded")
+
+ loginDialog.loginThroughSteam()
+ }
+ onHandleCreateFailed: {
+ console.log("Create Failed: " + error)
+
+ bodyLoadersetSource("UsernameCollisionBody.qml")
+ }
+ onHandleLoginCompleted: {
+ console.log("Login Succeeded")
+
+ bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false })
+ }
+ onHandleLoginFailed: {
+ console.log("Login Failed")
+ }
+ }
+}
diff --git a/interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml b/interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml
new file mode 100644
index 0000000000..8010a34250
--- /dev/null
+++ b/interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml
@@ -0,0 +1,296 @@
+//
+// LinkAccountBody.qml
+//
+// Created by Clement on 7/18/16
+// Copyright 2015 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0
+import QtQuick 2.4
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4 as OriginalStyles
+
+import "../controls-uit"
+import "../styles-uit"
+
+Item {
+ id: linkAccountBody
+ clip: true
+ height: parent.height
+ width: parent.width
+ property bool failAfterSignUp: false
+
+ function login() {
+ mainTextContainer.visible = false
+ toggleLoading(true)
+ loginDialog.login(usernameField.text, passwordField.text)
+ }
+
+ property bool keyboardEnabled: false
+ property bool keyboardRaised: false
+ property bool punctuationMode: false
+
+ onKeyboardRaisedChanged: d.resize();
+
+ QtObject {
+ id: d
+ function resize() {}
+ }
+
+ function toggleLoading(isLoading) {
+ linkAccountSpinner.visible = isLoading
+ form.visible = !isLoading
+
+ if (loginDialog.isSteamRunning()) {
+ additionalInformation.visible = !isLoading
+ }
+
+ leftButton.visible = !isLoading
+ buttons.visible = !isLoading
+ }
+
+ BusyIndicator {
+ id: linkAccountSpinner
+
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ visible: false
+ running: true
+
+ width: 48
+ height: 48
+ }
+
+ ShortcutText {
+ id: mainTextContainer
+ anchors {
+ top: parent.top
+ left: parent.left
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ visible: false
+
+ text: qsTr("Username or password incorrect.")
+ wrapMode: Text.WordWrap
+ color: hifi.colors.redAccent
+ lineHeight: 1
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Column {
+ id: form
+ anchors {
+ top: mainTextContainer.bottom
+ left: parent.left
+ margins: 0
+ topMargin: 2 * hifi.dimensions.contentSpacing.y
+ }
+ spacing: 2 * hifi.dimensions.contentSpacing.y
+
+ Row {
+ spacing: hifi.dimensions.contentSpacing.x
+
+ TextField {
+ id: usernameField
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+ width: 350
+
+ label: "Username or Email"
+ }
+
+ ShortcutText {
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+
+ text: "Forgot Username?"
+
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ linkColor: hifi.colors.blueAccent
+
+ onLinkActivated: loginDialog.openUrl(link)
+ }
+ }
+ Row {
+ spacing: hifi.dimensions.contentSpacing.x
+
+ TextField {
+ id: passwordField
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+ width: 350
+
+ label: "Password"
+ echoMode: TextInput.Password
+ }
+
+ ShortcutText {
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+
+ text: "Forgot Password?"
+
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ linkColor: hifi.colors.blueAccent
+
+ onLinkActivated: loginDialog.openUrl(link)
+ }
+ }
+
+ }
+
+ InfoItem {
+ id: additionalInformation
+ anchors {
+ top: form.bottom
+ left: parent.left
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ visible: loginDialog.isSteamRunning()
+
+ text: qsTr("Your steam account informations will not be exposed to other users.")
+ wrapMode: Text.WordWrap
+ color: hifi.colors.baseGrayHighlight
+ lineHeight: 1
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ // Override ScrollingWindow's keyboard that would be at very bottom of dialog.
+ Keyboard {
+ raised: keyboardEnabled && keyboardRaised
+ numeric: punctuationMode
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: buttons.top
+ bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
+ }
+ }
+
+ Row {
+ id: leftButton
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ bottomMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: qsTr("Sign Up")
+ visible: !loginDialog.isSteamRunning()
+
+ onClicked: {
+ bodyLoader.setSource("SignUpBody.qml")
+ }
+ }
+ }
+
+ Row {
+ id: buttons
+ anchors {
+ right: parent.right
+ bottom: parent.bottom
+ bottomMargin: hifi.dimensions.contentSpacing.y
+ }
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ id: linkAccountButton
+ anchors.verticalCenter: parent.verticalCenter
+ width: 200
+
+ text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login")
+ color: hifi.buttons.blue
+
+ onClicked: linkAccountBody.login()
+ }
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+ text: qsTr("Cancel")
+ onClicked: {
+ bodyLoader.popup()
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ loginDialogRoot.title = qsTr("Sign Into High Fidelity")
+ loginDialogRoot.iconText = "<"
+ keyboardEnabled = HMD.active;
+ d.resize();
+
+ if (failAfterSignUp) {
+ mainTextContainer.text = "Account created successfully."
+ mainTextContainer.visible = true
+ }
+
+ usernameField.forceActiveFocus();
+ }
+
+ Connections {
+ target: loginDialog
+ onHandleLoginCompleted: {
+ console.log("Login Succeeded, linking steam account")
+
+ if (loginDialog.isSteamRunning()) {
+ loginDialog.linkSteam()
+ } else {
+ bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true })
+ }
+ }
+ onHandleLoginFailed: {
+ console.log("Login Failed")
+ mainTextContainer.visible = true
+ toggleLoading(false)
+ }
+ onHandleLinkCompleted: {
+ console.log("Link Succeeded")
+
+ bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true })
+ }
+ onHandleLinkFailed: {
+ console.log("Link Failed")
+ toggleLoading(false)
+ }
+ }
+
+ Keys.onPressed: {
+ if (!visible) {
+ return
+ }
+
+ switch (event.key) {
+ case Qt.Key_Enter:
+ case Qt.Key_Return:
+ event.accepted = true
+ linkAccountBody.login()
+ break
+ }
+ }
+}
diff --git a/interface/resources/qml/TabletLoginDialog/SignInBody.qml b/interface/resources/qml/TabletLoginDialog/SignInBody.qml
new file mode 100644
index 0000000000..9cdf69c7bc
--- /dev/null
+++ b/interface/resources/qml/TabletLoginDialog/SignInBody.qml
@@ -0,0 +1,109 @@
+//
+// SignInBody.qml
+//
+// Created by Clement on 7/18/16
+// Copyright 2015 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0
+import QtQuick 2.4
+import QtQuick.Controls.Styles 1.4 as OriginalStyles
+
+import "../controls-uit"
+import "../styles-uit"
+
+Item {
+ id: signInBody
+ clip: true
+
+ property bool required: false
+
+ function login() {
+ console.log("Trying to log in")
+ loginDialog.loginThroughSteam()
+ }
+
+ function cancel() {
+ bodyLoader.popup()
+ }
+
+ QtObject {
+ id: d
+ function resize() {}
+ }
+
+ InfoItem {
+ id: mainTextContainer
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ text: required ? qsTr("This domain's owner requires that you sign in:")
+ : qsTr("Sign in to access your user account:")
+ wrapMode: Text.WordWrap
+ color: hifi.colors.baseGrayHighlight
+ lineHeight: 2
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Row {
+ id: buttons
+ anchors {
+ top: mainTextContainer.bottom
+ horizontalCenter: parent.horizontalCenter
+ margins: 0
+ topMargin: 2 * hifi.dimensions.contentSpacing.y
+ }
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ width: undefined // invalidate so that the image's size sets the width
+ height: undefined // invalidate so that the image's size sets the height
+ focus: true
+
+ style: OriginalStyles.ButtonStyle {
+ background: Image {
+ id: buttonImage
+ source: "../../images/steam-sign-in.png"
+ }
+ }
+ onClicked: signInBody.login()
+ }
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: qsTr("Cancel");
+
+ onClicked: signInBody.cancel()
+ }
+ }
+
+ Component.onCompleted: {
+ loginDialogRoot.title = required ? qsTr("Sign In Required")
+ : qsTr("Sign In")
+ loginDialogRoot.iconText = ""
+ d.resize();
+ }
+
+ Connections {
+ target: loginDialog
+ onHandleLoginCompleted: {
+ console.log("Login Succeeded")
+ bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true })
+ }
+ onHandleLoginFailed: {
+ console.log("Login Failed")
+ bodyLoader.setSource("CompleteProfileBody.qml")
+ }
+ }
+}
diff --git a/interface/resources/qml/TabletLoginDialog/SignUpBody.qml b/interface/resources/qml/TabletLoginDialog/SignUpBody.qml
new file mode 100644
index 0000000000..2cfc0e736a
--- /dev/null
+++ b/interface/resources/qml/TabletLoginDialog/SignUpBody.qml
@@ -0,0 +1,276 @@
+//
+// SignUpBody.qml
+//
+// Created by Stephen Birarda on 7 Dec 2016
+// Copyright 2016 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0
+import QtQuick 2.4
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4 as OriginalStyles
+
+import "../controls-uit"
+import "../styles-uit"
+
+Item {
+ id: signupBody
+ clip: true
+// height: parent.height
+// width: parent.width
+
+ function signup() {
+ mainTextContainer.visible = false
+ toggleLoading(true)
+ loginDialog.signup(emailField.text, usernameField.text, passwordField.text)
+ }
+
+ property bool keyboardEnabled: false
+ property bool keyboardRaised: false
+ property bool punctuationMode: false
+
+ onKeyboardRaisedChanged: d.resize();
+
+ QtObject {
+ id: d
+ function resize() {}
+ }
+
+ function toggleLoading(isLoading) {
+ linkAccountSpinner.visible = isLoading
+ form.visible = !isLoading
+
+ leftButton.visible = !isLoading
+ buttons.visible = !isLoading
+ }
+
+ BusyIndicator {
+ id: linkAccountSpinner
+
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ visible: false
+ running: true
+
+ width: 48
+ height: 48
+ }
+
+ ShortcutText {
+ id: mainTextContainer
+ anchors {
+ top: parent.top
+ left: parent.left
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ visible: false
+
+ text: qsTr("There was an unknown error while creating your account.")
+ wrapMode: Text.WordWrap
+ color: hifi.colors.redAccent
+ horizontalAlignment: Text.AlignLeft
+ }
+
+ Column {
+ id: form
+ anchors {
+ top: mainTextContainer.bottom
+ left: parent.left
+ margins: 0
+ topMargin: 2 * hifi.dimensions.contentSpacing.y
+ }
+ spacing: 2 * hifi.dimensions.contentSpacing.y
+
+ Row {
+ spacing: hifi.dimensions.contentSpacing.x
+
+ TextField {
+ id: emailField
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+ width: 300
+
+ label: "Email"
+ }
+ }
+
+ Row {
+ spacing: hifi.dimensions.contentSpacing.x
+
+ TextField {
+ id: usernameField
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+ width: 300
+
+ label: "Username"
+ }
+
+ ShortcutText {
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+
+ text: qsTr("No spaces / special chars.")
+
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+
+ color: hifi.colors.blueAccent
+ }
+ }
+
+ Row {
+ spacing: hifi.dimensions.contentSpacing.x
+
+ TextField {
+ id: passwordField
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+ width: 300
+
+ label: "Password"
+ echoMode: TextInput.Password
+ }
+
+ ShortcutText {
+ anchors {
+ verticalCenter: parent.verticalCenter
+ }
+
+ text: qsTr("At least 6 characters")
+
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+
+ color: hifi.colors.blueAccent
+ }
+ }
+
+ }
+
+ // Override ScrollingWindow's keyboard that would be at very bottom of dialog.
+ Keyboard {
+ raised: keyboardEnabled && keyboardRaised
+ numeric: punctuationMode
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: buttons.top
+ bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
+ }
+ }
+
+ Row {
+ id: leftButton
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ bottomMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: qsTr("Existing User")
+
+ onClicked: {
+ bodyLoader.setSource("LinkAccountBody.qml")
+ }
+ }
+ }
+
+ Row {
+ id: buttons
+ anchors {
+ right: parent.right
+ bottom: parent.bottom
+ bottomMargin: hifi.dimensions.contentSpacing.y
+ }
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ id: linkAccountButton
+ anchors.verticalCenter: parent.verticalCenter
+ width: 200
+
+ text: qsTr("Sign Up")
+ color: hifi.buttons.blue
+
+ onClicked: signupBody.signup()
+ }
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: qsTr("Cancel")
+
+ onClicked: bodyLoader.popup()
+ }
+ }
+
+ Component.onCompleted: {
+ loginDialogRoot.title = qsTr("Create an Account")
+ loginDialogRoot.iconText = "<"
+ keyboardEnabled = HMD.active;
+ d.resize();
+
+ emailField.forceActiveFocus();
+ }
+
+ Connections {
+ target: loginDialog
+ onHandleSignupCompleted: {
+ console.log("Sign Up Succeeded");
+
+ // now that we have an account, login with that username and password
+ loginDialog.login(usernameField.text, passwordField.text)
+ }
+ onHandleSignupFailed: {
+ console.log("Sign Up Failed")
+ toggleLoading(false)
+
+ mainTextContainer.text = errorString
+ mainTextContainer.visible = true
+
+ d.resize();
+ }
+ onHandleLoginCompleted: {
+ bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack": false })
+ }
+ onHandleLoginFailed: {
+ // we failed to login, show the LoginDialog so the user will try again
+ bodyLoader.setSource("LinkAccountBody.qml", { "failAfterSignUp": true })
+ }
+ }
+
+ Keys.onPressed: {
+ if (!visible) {
+ return
+ }
+
+ switch (event.key) {
+ case Qt.Key_Enter:
+ case Qt.Key_Return:
+ event.accepted = true
+ signupBody.signup()
+ break
+ }
+ }
+}
diff --git a/interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml
new file mode 100644
index 0000000000..9e5b01d339
--- /dev/null
+++ b/interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml
@@ -0,0 +1,157 @@
+//
+// UsernameCollisionBody.qml
+//
+// Created by Clement on 7/18/16
+// Copyright 2015 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0
+import QtQuick 2.4
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4 as OriginalStyles
+
+import "../controls-uit"
+import "../styles-uit"
+
+Item {
+ id: usernameCollisionBody
+ clip: true
+ width: parent.width
+ height: parent.height
+
+ function create() {
+ mainTextContainer.visible = false
+ loginDialog.createAccountFromStream(textField.text)
+ }
+
+
+ property bool keyboardEnabled: false
+ property bool keyboardRaised: false
+ property bool punctuationMode: false
+
+ onKeyboardRaisedChanged: d.resize();
+
+ QtObject {
+ id: d
+ function resize() {}
+ }
+
+ ShortcutText {
+ id: mainTextContainer
+ anchors {
+ top: parent.top
+ left: parent.left
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ text: qsTr("Your Steam username is not available.")
+ wrapMode: Text.WordWrap
+ color: hifi.colors.redAccent
+ lineHeight: 1
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+
+ TextField {
+ id: textField
+ anchors {
+ top: mainTextContainer.bottom
+ left: parent.left
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+ width: 250
+
+ placeholderText: "Choose your own"
+ }
+
+ // Override ScrollingWindow's keyboard that would be at very bottom of dialog.
+ Keyboard {
+ raised: keyboardEnabled && keyboardRaised
+ numeric: punctuationMode
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: buttons.top
+ bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
+ }
+ }
+
+ Row {
+ id: buttons
+ anchors {
+ bottom: parent.bottom
+ right: parent.right
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+ width: 200
+
+ text: qsTr("Create your profile")
+ color: hifi.buttons.blue
+
+ onClicked: usernameCollisionBody.create()
+ }
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: qsTr("Cancel")
+ onClicked: bodyLoader.popup()
+ }
+ }
+
+ Component.onCompleted: {
+ loginDialogRoot.title = qsTr("Complete Your Profile")
+ loginDialogRoot.iconText = "<"
+ keyboardEnabled = HMD.active;
+ d.resize();
+ }
+
+ Connections {
+ target: loginDialog
+ onHandleCreateCompleted: {
+ console.log("Create Succeeded")
+
+ loginDialog.loginThroughSteam()
+ }
+ onHandleCreateFailed: {
+ console.log("Create Failed: " + error)
+
+ mainTextContainer.visible = true
+ mainTextContainer.text = "\"" + textField.text + qsTr("\" is invalid or already taken.")
+ }
+ onHandleLoginCompleted: {
+ console.log("Login Succeeded")
+
+ bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false })
+ }
+ onHandleLoginFailed: {
+ console.log("Login Failed")
+ }
+ }
+
+ Keys.onPressed: {
+ if (!visible) {
+ return
+ }
+
+ switch (event.key) {
+ case Qt.Key_Enter:
+ case Qt.Key_Return:
+ event.accepted = true
+ usernameCollisionBody.create()
+ break
+ }
+ }
+}
diff --git a/interface/resources/qml/TabletLoginDialog/WelcomeBody.qml b/interface/resources/qml/TabletLoginDialog/WelcomeBody.qml
new file mode 100644
index 0000000000..5ec259ca96
--- /dev/null
+++ b/interface/resources/qml/TabletLoginDialog/WelcomeBody.qml
@@ -0,0 +1,79 @@
+//
+// WelcomeBody.qml
+//
+// Created by Clement on 7/18/16
+// Copyright 2015 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0
+import QtQuick 2.4
+
+import "../controls-uit"
+import "../styles-uit"
+
+Item {
+ id: welcomeBody
+ clip: true
+
+ property bool welcomeBack: false
+
+ function setTitle() {
+ loginDialogRoot.title = (welcomeBack ? qsTr("Welcome back ") : qsTr("Welcome ")) + Account.username + qsTr("!")
+ loginDialogRoot.iconText = ""
+ d.resize();
+ }
+
+ QtObject {
+ id: d
+ function resize() {}
+ }
+
+ InfoItem {
+ id: mainTextContainer
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ margins: 0
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+
+ text: qsTr("You are now signed into High Fidelity")
+ wrapMode: Text.WordWrap
+ color: hifi.colors.baseGrayHighlight
+ lineHeight: 2
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Row {
+ id: buttons
+ anchors {
+ top: mainTextContainer.bottom
+ horizontalCenter: parent.horizontalCenter
+ margins: 0
+ topMargin: 2 * hifi.dimensions.contentSpacing.y
+ }
+ spacing: hifi.dimensions.contentSpacing.x
+ onHeightChanged: d.resize(); onWidthChanged: d.resize();
+
+ Button {
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: qsTr("Close");
+
+ onClicked: bodyLoader.popup()
+ }
+ }
+
+ Component.onCompleted: {
+ welcomeBody.setTitle()
+ }
+
+ Connections {
+ target: Account
+ onUsernameChanged: welcomeBody.setTitle()
+ }
+}
diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml
new file mode 100644
index 0000000000..78e5edebb5
--- /dev/null
+++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml
@@ -0,0 +1,113 @@
+//
+// TabletLoginDialog.qml
+//
+// Created by Vlad Stelmahovsky on 15 Mar 2017
+// Copyright 2017 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+
+import "../controls-uit"
+import "../styles-uit"
+import "../windows"
+
+TabletModalWindow {
+ id: loginDialogRoot
+ objectName: "LoginDialog"
+
+ property var eventBridge;
+ signal sendToScript(var message);
+ property bool isHMD: false
+
+ color: hifi.colors.baseGray
+
+ property int colorScheme: hifi.colorSchemes.dark
+ property int titleWidth: 0
+ property string iconText: ""
+ property int icon: hifi.icons.none
+ property int iconSize: 35
+ MouseArea {
+ width: parent.width
+ height: parent.height
+ }
+
+ property bool keyboardOverride: true
+ onIconChanged: updateIcon();
+
+ property var items;
+ property string label: ""
+
+ onTitleWidthChanged: d.resize();
+
+ property bool keyboardEnabled: false
+ property bool keyboardRaised: false
+ property bool punctuationMode: false
+
+ onKeyboardRaisedChanged: d.resize();
+
+ signal canceled();
+
+ function updateIcon() {
+ if (!root) {
+ return;
+ }
+ iconText = hifi.glyphForIcon(root.icon);
+ }
+
+ property alias bodyLoader: bodyLoader
+ property alias loginDialog: loginDialog
+ property alias hifi: hifi
+
+ HifiConstants { id: hifi }
+
+ onCanceled: {
+ loginDialogRoot.Stack.view.pop()
+ }
+
+ LoginDialog {
+ id: loginDialog
+ width: parent.width
+ height: parent.height
+ StackView {
+ id: bodyLoader
+ property var item: currentItem
+ property var props
+ property string source: ""
+
+ onCurrentItemChanged: {
+ //cleanup source for future usage
+ source = ""
+ }
+
+ function setSource(src, props) {
+ source = "../TabletLoginDialog/" + src
+ bodyLoader.props = props
+ }
+ function popup() {
+ bodyLoader.pop()
+
+ //check if last screen, if yes, dialog is popped out
+ if (depth === 1)
+ loginDialogRoot.canceled()
+ }
+
+ anchors.fill: parent
+ anchors.margins: 10
+ onSourceChanged: {
+ if (source !== "") {
+ bodyLoader.push(Qt.resolvedUrl(source), props)
+ }
+ }
+ Component.onCompleted: {
+ setSource(loginDialog.isSteamRunning() ?
+ "SignInBody.qml" :
+ "LinkAccountBody.qml")
+ }
+ }
+ }
+}
diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp
index 3252fef4f0..e52b1b6d9e 100644
--- a/interface/src/ui/DialogsManager.cpp
+++ b/interface/src/ui/DialogsManager.cpp
@@ -31,6 +31,9 @@
#include "ScriptEditorWindow.h"
#include "UpdateDialog.h"
+#include "TabletScriptingInterface.h"
+#include "scripting/HMDScriptingInterface.h"
+
template
void DialogsManager::maybeCreateDialog(QPointer& member) {
if (!member) {
@@ -77,7 +80,7 @@ void DialogsManager::toggleLoginDialog() {
}
void DialogsManager::showLoginDialog() {
- LoginDialog::show();
+ LoginDialog::showWithSelection();
}
void DialogsManager::showUpdateDialog() {
diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp
index e333bb1b88..dce76eb661 100644
--- a/interface/src/ui/LoginDialog.cpp
+++ b/interface/src/ui/LoginDialog.cpp
@@ -24,6 +24,10 @@
#include "DependencyManager.h"
#include "Menu.h"
+#include "Application.h"
+#include "TabletScriptingInterface.h"
+#include "scripting/HMDScriptingInterface.h"
+
HIFI_QML_DEF(LoginDialog)
LoginDialog::LoginDialog(QQuickItem *parent) : OffscreenQmlDialog(parent) {
@@ -31,7 +35,25 @@ LoginDialog::LoginDialog(QQuickItem *parent) : OffscreenQmlDialog(parent) {
connect(accountManager.data(), &AccountManager::loginComplete,
this, &LoginDialog::handleLoginCompleted);
connect(accountManager.data(), &AccountManager::loginFailed,
- this, &LoginDialog::handleLoginFailed);
+ this, &LoginDialog::handleLoginFailed);
+}
+
+void LoginDialog::showWithSelection()
+{
+ auto tabletScriptingInterface = DependencyManager::get();
+ auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
+ auto hmd = DependencyManager::get();
+
+ if (tablet->getToolbarMode()) {
+ LoginDialog::show();
+ } else {
+ if (!hmd->getShouldShowTablet() && !qApp->isHMDMode()) {
+ LoginDialog::show();
+ } else {
+ static const QUrl url("../../dialogs/TabletLoginDialog.qml");
+ tablet->pushOntoStack(url);
+ }
+ }
}
void LoginDialog::toggleAction() {
@@ -51,7 +73,7 @@ void LoginDialog::toggleAction() {
// change the menu item to login
loginAction->setText("Login / Sign Up");
connection = connect(loginAction, &QAction::triggered, [] {
- LoginDialog::show();
+ LoginDialog::showWithSelection();
});
}
}
@@ -141,9 +163,23 @@ void LoginDialog::createAccountFromStream(QString username) {
}
void LoginDialog::openUrl(const QString& url) const {
+
+ auto tabletScriptingInterface = DependencyManager::get();
+ auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
+ auto hmd = DependencyManager::get();
auto offscreenUi = DependencyManager::get();
- auto browser = offscreenUi->load("Browser.qml");
- browser->setProperty("url", url);
+
+ if (tablet->getToolbarMode()) {
+ auto browser = offscreenUi->load("Browser.qml");
+ browser->setProperty("url", url);
+ } else {
+ if (!hmd->getShouldShowTablet() && !qApp->isHMDMode()) {
+ auto browser = offscreenUi->load("Browser.qml");
+ browser->setProperty("url", url);
+ } else {
+ tablet->gotoWebScreen(url);
+ }
+ }
}
void LoginDialog::linkCompleted(QNetworkReply& reply) {
diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h
index ce6075793b..5ebf866fbd 100644
--- a/interface/src/ui/LoginDialog.h
+++ b/interface/src/ui/LoginDialog.h
@@ -27,6 +27,7 @@ public:
LoginDialog(QQuickItem* parent = nullptr);
+ static void showWithSelection();
signals:
void handleLoginCompleted();
void handleLoginFailed();