From 5e162a64470da527e89bd9371a8fad240b45afc9 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Sat, 18 Mar 2017 14:38:49 +0100 Subject: [PATCH] Implemented login facility for tablet UI --- .../TabletLoginDialog/CompleteProfileBody.qml | 124 ++++++++ .../qml/TabletLoginDialog/LinkAccountBody.qml | 296 ++++++++++++++++++ .../qml/TabletLoginDialog/SignInBody.qml | 109 +++++++ .../qml/TabletLoginDialog/SignUpBody.qml | 276 ++++++++++++++++ .../UsernameCollisionBody.qml | 157 ++++++++++ .../qml/TabletLoginDialog/WelcomeBody.qml | 79 +++++ .../qml/dialogs/TabletLoginDialog.qml | 113 +++++++ interface/src/ui/DialogsManager.cpp | 5 +- interface/src/ui/LoginDialog.cpp | 44 ++- interface/src/ui/LoginDialog.h | 1 + 10 files changed, 1199 insertions(+), 5 deletions(-) create mode 100644 interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml create mode 100644 interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml create mode 100644 interface/resources/qml/TabletLoginDialog/SignInBody.qml create mode 100644 interface/resources/qml/TabletLoginDialog/SignUpBody.qml create mode 100644 interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml create mode 100644 interface/resources/qml/TabletLoginDialog/WelcomeBody.qml create mode 100644 interface/resources/qml/dialogs/TabletLoginDialog.qml 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();