//// Wizard.qml//// Created by keeshii on 26 Sep 2023// Copyright 2023 Overte, Org.//// 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 as Hifiimport QtQuick 2.7import QtQuick.Controls 2.2import QtQuick.Layouts 1.12 import stylesUit 1.0 as HifiStylesUitimport controlsUit 1.0 as HifiControlsimport "qrc:////qml//styles" as HifiStylesimport "qrc:////qml//hifi" as Hifi Rectangle { id: wizard color: "#433952" property int performancePreset: 0 property int refreshRateProfile: 0 property string displayName: "" property bool keyboardEnabled: false property bool punctuationMode: false property bool keyboardRaised: false function setStep(stepNum) { stepList.completed = stepNum switch (stepNum) { case 0: loader.sourceComponent = step1; break; case 1: loader.sourceComponent = step2; break; case 2: loader.sourceComponent = step3; break; case 3: loader.sourceComponent = step4; break; case 4: loader.sourceComponent = step5; break; default: loader.setSource(undefined); } } function completeWizard() { var completionMessage = { command: "complete-wizard", data: { performancePreset: wizard.performancePreset, refreshRateProfile: wizard.refreshRateProfile, displayName: wizard.displayName } }; eventBridge.emitWebEvent(JSON.stringify(completionMessage)); } function handleWebEvent(message) { var messageJSON = JSON.parse(message); if (messageJSON.command === "script-to-web-initialize") { wizard.performancePreset = messageJSON.data.performancePreset; wizard.refreshRateProfile = messageJSON.data.refreshRateProfile; wizard.displayName = messageJSON.data.displayName; } } function initializeWizard() { var initializeCommand = {"command": "first-run-wizard-ready"}; eventBridge.emitWebEvent(JSON.stringify(initializeCommand)); } function stop() { wizard.keyboardEnabled = false; } // Layout constants constants HifiStyles.HifiConstants { id: hifi } Rectangle { id: steps color: "#26202e" width: parent.width - 8 * hifi.layout.spacing height: hifi.layout.rowHeight + 6 * hifi.layout.spacing anchors.top: wizard.top anchors.topMargin: 4 * hifi.layout.spacing anchors.horizontalCenter: wizard.horizontalCenter radius: hifi.layout.spacing ListView { id: stepList anchors.fill: parent orientation: ListView.Horizontal property int completed: 0 delegate: Item { id: stepItem width: stepList.width / 5 height: stepList.height property int num: index Rectangle { width: parent.width height: 1 anchors.left: stepCircle.horizontalCenter anchors.top: stepCircle.verticalCenter visible: stepItem.num + 1 < stepList.model.count color: stepList.completed > stepItem.num ? "#4bb543" : "gray" } Rectangle { id: stepCircle color: stepList.completed > stepItem.num ? "#4bb543" : (stepList.completed === stepItem.num ? "white" : "gray") width: hifi.layout.rowHeight height: hifi.layout.rowHeight radius: hifi.layout.rowHeight / 2 anchors.top: stepItem.top anchors.topMargin: hifi.layout.spacing anchors.horizontalCenter: stepItem.horizontalCenter Text { id: stepNum text: String(stepItem.num + 1) color: stepList.completed === stepItem.num ? hifi.colors.text : "white" anchors.centerIn: stepCircle } } Text { id: stepName text: name color: "white" anchors.top: stepCircle.bottom anchors.topMargin: hifi.layout.spacing anchors.horizontalCenter: stepItem.horizontalCenter font.bold: true } } model: ListModel { ListElement { name: "Welcome" } ListElement { name: "Quality" } ListElement { name: "Performance" } ListElement { name: "Display Name" } ListElement { name: "Completion" } } } } Loader { id: loader width: parent.width - 8 * hifi.layout.spacing height: parent.height - steps.height - backButton.height - 12 * hifi.layout.spacing anchors.top: steps.bottom anchors.topMargin: 2 * hifi.layout.spacing anchors.horizontalCenter: wizard.horizontalCenter sourceComponent: step1 } Component { id: step1 Item { id: step1Body anchors.fill: loader Text { id: step1Header width: parent.width text: "Welcome to Overte!" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step1Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step1Text1 width: parent.width text: "Let's get you setup to experience the virtual world.<br />" + "First, we need to select some performance and graphics quality options.<br />" + "<br />" + "Press <b><font color=\"#2e89ff\">Continue</font></b> when you are ready." color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step1Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } } } Component { id: step2 Item { id: step2Body anchors.fill: loader Text { id: step2Header width: parent.width text: "Quality" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step2Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step2Text1 width: parent.width text: "What level of visual quality would you like?<br />" + "<b>Remember! If you do not have a powerful computer,<br />" + "you may want to set this to low or medium at most.</b>" color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step2Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } ColumnLayout { anchors.top: step2Text1.bottom anchors.topMargin: 2 * hifi.layout.spacing RadioButton { text: "<font size=\"4\" color=\"#ff9900\"><b>Very Low Quality</b></font>\n" + "<font color=\"white\">Slow Laptop / Very Slow Computer</font>" onClicked: wizard.performancePreset = 1 checked: wizard.performancePreset === 1 } RadioButton { text: "<font size=\"4\" color=\"#ffff00\"><b>Low Quality</b></font>\n" + "<font color=\"white\">Average Laptop / Slow Computer</font>" onClicked: wizard.performancePreset = 2 checked: wizard.performancePreset === 2 } RadioButton { text: "<font size=\"4\" color=\"#00ba1c\"><b>Medium Quality</b></font>\n" + "<font color=\"white\">Average Computer - </font><font color=\"#00ba1c\"><i>Recommended</i></font>" onClicked: wizard.performancePreset = 3 checked: wizard.performancePreset === 3 } RadioButton { text: "<font size=\"4\" color=\"#0096db\"><b>High Quality</b></font>\n" + "<font color=\"white\">Gaming Computer</font>" onClicked: wizard.performancePreset = 4 checked: wizard.performancePreset === 4 } } } } Component { id: step3 Item { id: step3Body anchors.fill: loader Text { id: step3Header width: parent.width text: "Performance" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step3Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step3Text1 width: parent.width text: "Do you want a smooth experience <i>(high refresh rate)</i><br />" + "or do you want to conserve power and resources <i>(low refresh rate)</i> on your computer?<br />" + "<b><i>Note: This does not apply to virtual reality headsets.</i><b>" color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step3Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } ColumnLayout { anchors.top: step3Text1.bottom anchors.topMargin: 2 * hifi.layout.spacing RadioButton { text: "<font size=\"4\" color=\"#ff9900\"><b>Not Smooth (20 Hz)</b></font>\n" + "<font color=\"white\">Conserve Power</font>" onClicked: wizard.refreshRateProfile = 0 checked: wizard.refreshRateProfile === 0 } RadioButton { text: "<font size=\"4\" color=\"#ffff00\"><b>Smooth (30 Hz)</b></font>\n" + "<font color=\"white\">Use Average Resources</font>" onClicked: wizard.refreshRateProfile = 1 checked: wizard.refreshRateProfile === 1 } RadioButton { text: "<font size=\"4\" color=\"#00ba1c\"><b>Very Smooth (60 Hz)</b></font>\n" + "<font color=\"white\">Use Maximum Resources - </font><font color=\"#00ba1c\"><i>Recommended</i></font>" onClicked: wizard.refreshRateProfile = 2 checked: wizard.refreshRateProfile === 2 } } } } Component { id: step4 Item { id: step4Body anchors.fill: loader Text { id: step4Header width: parent.width text: "Display Name" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step4Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step4Text1 width: parent.width text: "What should people call you?<br />" + "This is simply a nickname, it will be shown in place of your username (if you have one)." color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step4Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } Rectangle { id: inputBar width: parent.width height: 40 color: 'white' anchors.top: step4Text1.bottom anchors.topMargin: 2 * hifi.layout.spacing TextField { id: displayName text: wizard.displayName focus: true width: inputBar.width - inputBar.anchors.leftMargin - inputBar.anchors.rightMargin; anchors { left: inputBar.left; leftMargin: 8; verticalCenter: inputBar.verticalCenter; } onTextChanged: wizard.displayName = text placeholderText: "Enter display name" verticalAlignment: TextInput.AlignBottom onAccepted: { if (HMD.active) { wizard.keyboardEnabled = false; } } font { family: hifi.fonts.fontFamily pixelSize: hifi.fonts.pixelSize * 0.75 } color: hifi.colors.text background: Item {} } MouseArea { anchors.fill: parent; onClicked: { displayName.focus = true; displayName.forceActiveFocus(); if (HMD.active) { wizard.keyboardEnabled = true; } } } } } } Component { id: step5 Item { id: step5Body anchors.fill: loader Text { id: step5Header width: parent.width text: "All done!" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step5Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step5Text1 width: parent.width text: "Now you're almost ready to go!<br />" + "Press <font color=\"#1ee62e\">Complete</font> to save your setup.<br />" + "Then take a look at the other information kiosks after completing this wizard." color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step5Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } } } Button { id: backButton text: "< Back" width: nextButton.width anchors.bottom: wizard.bottom anchors.left: wizard.left anchors.bottomMargin: 4 * hifi.layout.spacing anchors.leftMargin: 4 * hifi.layout.spacing visible: stepList.completed > 0 onClicked: setStep(stepList.completed - 1) contentItem: Text { text: backButton.text font.bold: true color: "white" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 gradient: Gradient { GradientStop { position: 0 ; color: backButton.hovered ? "#0599fc" : "#0599fc" } GradientStop { position: 1 ; color: backButton.hovered ? "#003670" : "#002259" } } border.color: "#26282a" border.width: 1 radius: 4 } } Button { id: nextButton text: "Continue >" anchors.bottom: wizard.bottom anchors.right: wizard.right anchors.bottomMargin: 4 * hifi.layout.spacingLines 1–500 of 599. Load more
// // Wizard.qml // // Created by keeshii on 26 Sep 2023 // Copyright 2023 Overte, Org. // // 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 as Hifi import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.12 import stylesUit 1.0 as HifiStylesUit import controlsUit 1.0 as HifiControls import "qrc:////qml//styles" as HifiStyles import "qrc:////qml//hifi" as Hifi Rectangle { id: wizard color: "#433952" property int performancePreset: 0 property int refreshRateProfile: 0 property string displayName: "" property bool keyboardEnabled: false property bool punctuationMode: false property bool keyboardRaised: false function setStep(stepNum) { stepList.completed = stepNum switch (stepNum) { case 0: loader.sourceComponent = step1; break; case 1: loader.sourceComponent = step2; break; case 2: loader.sourceComponent = step3; break; case 3: loader.sourceComponent = step4; break; case 4: loader.sourceComponent = step5; break; default: loader.setSource(undefined); } } function completeWizard() { var completionMessage = { command: "complete-wizard", data: { performancePreset: wizard.performancePreset, refreshRateProfile: wizard.refreshRateProfile, displayName: wizard.displayName } }; eventBridge.emitWebEvent(JSON.stringify(completionMessage)); } function handleWebEvent(message) { var messageJSON = JSON.parse(message); if (messageJSON.command === "script-to-web-initialize") { wizard.performancePreset = messageJSON.data.performancePreset; wizard.refreshRateProfile = messageJSON.data.refreshRateProfile; wizard.displayName = messageJSON.data.displayName; } } function initializeWizard() { var initializeCommand = {"command": "first-run-wizard-ready"}; eventBridge.emitWebEvent(JSON.stringify(initializeCommand)); } function stop() { wizard.keyboardEnabled = false; } // Layout constants constants HifiStyles.HifiConstants { id: hifi } Rectangle { id: steps color: "#26202e" width: parent.width - 8 * hifi.layout.spacing height: hifi.layout.rowHeight + 6 * hifi.layout.spacing anchors.top: wizard.top anchors.topMargin: 4 * hifi.layout.spacing anchors.horizontalCenter: wizard.horizontalCenter radius: hifi.layout.spacing ListView { id: stepList anchors.fill: parent orientation: ListView.Horizontal property int completed: 0 delegate: Item { id: stepItem width: stepList.width / 5 height: stepList.height property int num: index Rectangle { width: parent.width height: 1 anchors.left: stepCircle.horizontalCenter anchors.top: stepCircle.verticalCenter visible: stepItem.num + 1 < stepList.model.count color: stepList.completed > stepItem.num ? "#4bb543" : "gray" } Rectangle { id: stepCircle color: stepList.completed > stepItem.num ? "#4bb543" : (stepList.completed === stepItem.num ? "white" : "gray") width: hifi.layout.rowHeight height: hifi.layout.rowHeight radius: hifi.layout.rowHeight / 2 anchors.top: stepItem.top anchors.topMargin: hifi.layout.spacing anchors.horizontalCenter: stepItem.horizontalCenter Text { id: stepNum text: String(stepItem.num + 1) color: stepList.completed === stepItem.num ? hifi.colors.text : "white" anchors.centerIn: stepCircle } } Text { id: stepName text: name color: "white" anchors.top: stepCircle.bottom anchors.topMargin: hifi.layout.spacing anchors.horizontalCenter: stepItem.horizontalCenter font.bold: true } } model: ListModel { ListElement { name: "Welcome" } ListElement { name: "Quality" } ListElement { name: "Performance" } ListElement { name: "Display Name" } ListElement { name: "Completion" } } } } Loader { id: loader width: parent.width - 8 * hifi.layout.spacing height: parent.height - steps.height - backButton.height - 12 * hifi.layout.spacing anchors.top: steps.bottom anchors.topMargin: 2 * hifi.layout.spacing anchors.horizontalCenter: wizard.horizontalCenter sourceComponent: step1 } Component { id: step1 Item { id: step1Body anchors.fill: loader Text { id: step1Header width: parent.width text: "Welcome to Overte!" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step1Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step1Text1 width: parent.width text: "Let's get you setup to experience the virtual world.<br />" + "First, we need to select some performance and graphics quality options.<br />" + "<br />" + "Press <b><font color=\"#2e89ff\">Continue</font></b> when you are ready." color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step1Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } } } Component { id: step2 Item { id: step2Body anchors.fill: loader Text { id: step2Header width: parent.width text: "Quality" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step2Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step2Text1 width: parent.width text: "What level of visual quality would you like?<br />" + "<b>Remember! If you do not have a powerful computer,<br />" + "you may want to set this to low or medium at most.</b>" color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step2Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } ColumnLayout { anchors.top: step2Text1.bottom anchors.topMargin: 2 * hifi.layout.spacing RadioButton { text: "<font size=\"4\" color=\"#ff9900\"><b>Very Low Quality</b></font>\n" + "<font color=\"white\">Slow Laptop / Very Slow Computer</font>" onClicked: wizard.performancePreset = 1 checked: wizard.performancePreset === 1 } RadioButton { text: "<font size=\"4\" color=\"#ffff00\"><b>Low Quality</b></font>\n" + "<font color=\"white\">Average Laptop / Slow Computer</font>" onClicked: wizard.performancePreset = 2 checked: wizard.performancePreset === 2 } RadioButton { text: "<font size=\"4\" color=\"#00ba1c\"><b>Medium Quality</b></font>\n" + "<font color=\"white\">Average Computer - </font><font color=\"#00ba1c\"><i>Recommended</i></font>" onClicked: wizard.performancePreset = 3 checked: wizard.performancePreset === 3 } RadioButton { text: "<font size=\"4\" color=\"#0096db\"><b>High Quality</b></font>\n" + "<font color=\"white\">Gaming Computer</font>" onClicked: wizard.performancePreset = 4 checked: wizard.performancePreset === 4 } } } } Component { id: step3 Item { id: step3Body anchors.fill: loader Text { id: step3Header width: parent.width text: "Performance" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step3Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step3Text1 width: parent.width text: "Do you want a smooth experience <i>(high refresh rate)</i><br />" + "or do you want to conserve power and resources <i>(low refresh rate)</i> on your computer?<br />" + "<b><i>Note: This does not apply to virtual reality headsets.</i><b>" color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step3Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } ColumnLayout { anchors.top: step3Text1.bottom anchors.topMargin: 2 * hifi.layout.spacing RadioButton { text: "<font size=\"4\" color=\"#ff9900\"><b>Not Smooth (20 Hz)</b></font>\n" + "<font color=\"white\">Conserve Power</font>" onClicked: wizard.refreshRateProfile = 0 checked: wizard.refreshRateProfile === 0 } RadioButton { text: "<font size=\"4\" color=\"#ffff00\"><b>Smooth (30 Hz)</b></font>\n" + "<font color=\"white\">Use Average Resources</font>" onClicked: wizard.refreshRateProfile = 1 checked: wizard.refreshRateProfile === 1 } RadioButton { text: "<font size=\"4\" color=\"#00ba1c\"><b>Very Smooth (60 Hz)</b></font>\n" + "<font color=\"white\">Use Maximum Resources - </font><font color=\"#00ba1c\"><i>Recommended</i></font>" onClicked: wizard.refreshRateProfile = 2 checked: wizard.refreshRateProfile === 2 } } } } Component { id: step4 Item { id: step4Body anchors.fill: loader Text { id: step4Header width: parent.width text: "Display Name" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step4Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step4Text1 width: parent.width text: "What should people call you?<br />" + "This is simply a nickname, it will be shown in place of your username (if you have one)." color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step4Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } Rectangle { id: inputBar width: parent.width height: 40 color: 'white' anchors.top: step4Text1.bottom anchors.topMargin: 2 * hifi.layout.spacing TextField { id: displayName text: wizard.displayName focus: true width: inputBar.width - inputBar.anchors.leftMargin - inputBar.anchors.rightMargin; anchors { left: inputBar.left; leftMargin: 8; verticalCenter: inputBar.verticalCenter; } onTextChanged: wizard.displayName = text placeholderText: "Enter display name" verticalAlignment: TextInput.AlignBottom onAccepted: { if (HMD.active) { wizard.keyboardEnabled = false; } } font { family: hifi.fonts.fontFamily pixelSize: hifi.fonts.pixelSize * 0.75 } color: hifi.colors.text background: Item {} } MouseArea { anchors.fill: parent; onClicked: { displayName.focus = true; displayName.forceActiveFocus(); if (HMD.active) { wizard.keyboardEnabled = true; } } } } } } Component { id: step5 Item { id: step5Body anchors.fill: loader Text { id: step5Header width: parent.width text: "All done!" color: "white" font.pixelSize: hifi.fonts.headerPixelSize font.bold: true anchors.top: step5Body.top anchors.topMargin: 2 * hifi.layout.spacing } Text { id: step5Text1 width: parent.width text: "Now you're almost ready to go!<br />" + "Press <font color=\"#1ee62e\">Complete</font> to save your setup.<br />" + "Then take a look at the other information kiosks after completing this wizard." color: "white" wrapMode: Text.Wrap textFormat: TextEdit.RichText anchors.top: step5Header.bottom anchors.topMargin: 2 * hifi.layout.spacing } } } Button { id: backButton text: "< Back" width: nextButton.width anchors.bottom: wizard.bottom anchors.left: wizard.left anchors.bottomMargin: 4 * hifi.layout.spacing anchors.leftMargin: 4 * hifi.layout.spacing visible: stepList.completed > 0 onClicked: setStep(stepList.completed - 1) contentItem: Text { text: backButton.text font.bold: true color: "white" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 gradient: Gradient { GradientStop { position: 0 ; color: backButton.hovered ? "#0599fc" : "#0599fc" } GradientStop { position: 1 ; color: backButton.hovered ? "#003670" : "#002259" } } border.color: "#26282a" border.width: 1 radius: 4 } } Button { id: nextButton text: "Continue >" anchors.bottom: wizard.bottom anchors.right: wizard.right anchors.bottomMargin: 4 * hifi.layout.spacing