diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 1996834378..b597016b5a 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -18,13 +18,13 @@ FocusScope { // The VR version of the primary menu property var rootMenu: Menu { objectName: "rootMenu" } + Component { id: messageDialogBuilder; MessageDialog { } } + QtObject { id: d readonly property int zBasisNormal: 0 readonly property int zBasisAlwaysOnTop: 4096 readonly property int zBasisModal: 8192 - readonly property var messageDialogBuilder: Component { MessageDialog { } } - readonly property var nativeMessageDialogBuilder: Component { OriginalDialogs.MessageDialog { } } function findChild(item, name) { for (var i = 0; i < item.children.length; ++i) { @@ -165,9 +165,7 @@ FocusScope { } function messageBox(properties) { - // Debugging: native message dialog for comparison - // d.nativeMessageDialogBuilder.createObject(desktop, properties); - return d.messageDialogBuilder.createObject(desktop, properties); + return messageDialogBuilder.createObject(desktop, properties); } function popupMenu(point) { @@ -216,7 +214,7 @@ FocusScope { console.log("Focus item is " + offscreenWindow.activeFocusItem); var focusedItem = offscreenWindow.activeFocusItem ; if (DebugQML && focusedItem) { - var rect = desktop.mapToItem(null, focusedItem.x, focusedItem.y, focusedItem.width, focusedItem.height); + var rect = desktop.mapFromItem(focusedItem, 0, 0, focusedItem.width, focusedItem.height); focusDebugger.visible = true focusDebugger.x = rect.x; focusDebugger.y = rect.y; diff --git a/interface/resources/qml/hifi/dialogs/PreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/PreferencesDialog.qml index 2851dd7ff0..8dc057d585 100644 --- a/interface/resources/qml/hifi/dialogs/PreferencesDialog.qml +++ b/interface/resources/qml/hifi/dialogs/PreferencesDialog.qml @@ -25,6 +25,14 @@ Window { destroy(); } + function restoreAll() { + for (var i = 0; i < sections.length; ++i) { + var section = sections[i]; + section.restoreAll(); + } + destroy(); + } + Rectangle { anchors.fill: parent clip: true @@ -70,7 +78,12 @@ Window { Row { id: dialogButtons anchors { bottom: parent.bottom; right: parent.right; margins: 8 } - Button { text: "Cancel"; onClicked: root.destroy(); } + + Button { + text: "Cancel"; + onClicked: root.restoreAll(); + } + Button { text: "Save all changes" onClicked: root.saveAll(); diff --git a/interface/resources/qml/hifi/dialogs/preferences/Avatar.qml b/interface/resources/qml/hifi/dialogs/preferences/Avatar.qml index 9c19b80357..c5f115e284 100644 --- a/interface/resources/qml/hifi/dialogs/preferences/Avatar.qml +++ b/interface/resources/qml/hifi/dialogs/preferences/Avatar.qml @@ -1,33 +1,80 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original +import QtQuick.Controls 1.4 + import "." +import "../../../dialogs" Preference { id: root - property alias spinner: spinner - height: spinner.height - + property alias buttonText: button.text + property alias text: dataTextField.text + property alias placeholderText: dataTextField.placeholderText + property real spacing: 8 + property var browser; + height: labelText.height + Math.max(dataTextField.height, button.height) + spacing Component.onCompleted: { - spinner.value = preference.value; + dataTextField.text = preference.value; + console.log("MyAvatar modelName " + MyAvatar.getFullAvatarModelName()) + console.log("Application : " + ApplicationInterface) + ApplicationInterface.fullAvatarURLChanged.connect(processNewAvatar); + } + + Component.onDestruction: { + ApplicationInterface.fullAvatarURLChanged.disconnect(processNewAvatar); + } + + function processNewAvatar(url, modelName) { + if (browser) { + browser.destroy(); + browser = null + } + + dataTextField.text = url; } function save() { - preference.value = spinner.value; + preference.value = dataTextField.text; + preference.save(); + } + + // Restores the original avatar URL + function restore() { preference.save(); } Text { - text: root.label - anchors.verticalCenter: spinner.verticalCenter + id: labelText + text: root.label } - Original.SpinBox { - id: spinner - decimals: preference.decimals - minimumValue: preference.min - maximumValue: preference.max - width: 100 - anchors { right: parent.right } + TextField { + id: dataTextField + placeholderText: root.placeholderText + text: preference.value + anchors { + top: labelText.bottom + left: parent.left + right: button.left + topMargin: root.spacing + rightMargin: root.spacing + } + } + + Component { + id: avatarBrowserBuilder; + AvatarBrowser { } + } + + Button { + id: button + anchors { right: parent.right; verticalCenter: dataTextField.verticalCenter } + text: "Browse" + onClicked: { + root.browser = avatarBrowserBuilder.createObject(desktop); + root.browser.windowDestroyed.connect(function(){ + root.browser = null; + }) + } } } diff --git a/interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml b/interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml index e69de29bb2..e71ae9312a 100644 --- a/interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml +++ b/interface/resources/qml/hifi/dialogs/preferences/AvatarBrowser.qml @@ -0,0 +1,35 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtWebEngine 1.1 + +import "../../../windows" as Windows +import "../../../controls" as Controls +import "../../../styles" + +Windows.Window { + id: root + HifiConstants { id: hifi } + width: 900; height: 700 + resizable: true + anchors.centerIn: parent + modality: Qt.ApplicationModal + frame: Windows.ModalFrame {} + + Item { + anchors.fill: parent + + Controls.WebView { + id: webview + anchors { top: parent.top; left: parent.left; right: parent.right; bottom: closeButton.top; margins: 8 } + url: "https://metaverse.highfidelity.com/marketplace?category=avatars" + focus: true + } + + Button { + id: closeButton + anchors { bottom: parent.bottom; right: parent.right; margins: 8 } + text: "Close" + onClicked: root.destroy(); + } + } +} diff --git a/interface/resources/qml/hifi/dialogs/preferences/Browsable.qml b/interface/resources/qml/hifi/dialogs/preferences/Browsable.qml index 5d2c0ccd58..811d61b714 100644 --- a/interface/resources/qml/hifi/dialogs/preferences/Browsable.qml +++ b/interface/resources/qml/hifi/dialogs/preferences/Browsable.qml @@ -2,6 +2,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import "." +import "../../../dialogs" Preference { id: root @@ -38,12 +39,22 @@ Preference { } } + Component { + id: fileBrowserBuilder; + FileDialog { selectDirectory: true } + } + Button { id: button - anchors { - right: parent.right; - verticalCenter: dataTextField.verticalCenter - } + anchors { right: parent.right; verticalCenter: dataTextField.verticalCenter } text: "Browse" + onClicked: { + var browser = fileBrowserBuilder.createObject(desktop, { selectDirectory: true, folder: fileDialogHelper.pathToUrl(preference.value) }); + browser.selectedFile.connect(function(fileUrl){ + console.log(fileUrl); + dataTextField.text = fileDialogHelper.urlToPath(fileUrl); + }); + } + } } diff --git a/interface/resources/qml/hifi/dialogs/preferences/Preference.qml b/interface/resources/qml/hifi/dialogs/preferences/Preference.qml index 0099df6869..d388f580b3 100644 --- a/interface/resources/qml/hifi/dialogs/preferences/Preference.qml +++ b/interface/resources/qml/hifi/dialogs/preferences/Preference.qml @@ -6,5 +6,7 @@ Item { anchors { left: parent.left; right: parent.right } property var preference; property string label: preference ? preference.name : ""; - Component.onCompleted: preference.load(); + Component.onCompleted: if (preference) { preference.load(); } + + function restore() { } } diff --git a/interface/resources/qml/hifi/dialogs/preferences/Section.qml b/interface/resources/qml/hifi/dialogs/preferences/Section.qml index 66ec83a641..49eb2d5c89 100644 --- a/interface/resources/qml/hifi/dialogs/preferences/Section.qml +++ b/interface/resources/qml/hifi/dialogs/preferences/Section.qml @@ -21,6 +21,13 @@ Preference { } } + function restoreAll() { + for (var i = 0; i < d.preferences.length; ++i) { + var preference = d.preferences[i]; + preference.restore(); + } + } + clip: true children: [ toggle, header, contentContainer ] height: expanded ? header.height + contentContainer.height + root.spacing * 3 @@ -68,6 +75,7 @@ Preference { property var spinnerBuilder: Component { SpinBox { } } property var checkboxBuilder: Component { CheckBox { } } property var sliderBuilder: Component { Slider { } } + property var avatarBuilder: Component { Avatar { } } property var preferences: [] function buildPreferences() { @@ -104,6 +112,9 @@ Preference { builder = checkboxBuilder; break; + case Preference.Avatar: + builder = avatarBuilder; + break; }; if (builder) { diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 6031994415..4a877a719c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -58,8 +58,8 @@ void setupPreferences() { { auto getter = [=]()->QString { return myAvatar->getFullAvatarURLFromPreferences().toString(); }; - auto setter = [=](const QString& value) { /* FIXME */ }; - auto preference = new BrowsePreference(AVATAR_BASICS, "Appearance: ", getter, setter); + auto setter = [=](const QString& value) { myAvatar->useFullAvatarURL(value, ""); }; + auto preference = new AvatarPreference(AVATAR_BASICS, "Appearance: ", getter, setter); preferences->addPreference(preference); } diff --git a/libraries/shared/src/Preferences.h b/libraries/shared/src/Preferences.h index 3316086c3d..84dd4995ea 100644 --- a/libraries/shared/src/Preferences.h +++ b/libraries/shared/src/Preferences.h @@ -52,6 +52,8 @@ public: Spinner, Checkbox, Button, + // Special casing for an unusual preference + Avatar }; explicit Preference(QObject* parent = nullptr) : QObject(parent) {} @@ -237,6 +239,17 @@ protected: QString _browseLabel { "Browse" }; }; +class AvatarPreference : public BrowsePreference { + Q_OBJECT +public: + AvatarPreference(const QString& category, const QString& name, Getter getter, Setter setter) + : BrowsePreference(category, name, getter, setter) { + _browseLabel = "Change"; + } + Type getType() { return Avatar; } +}; + + class CheckPreference : public BoolPreference { Q_OBJECT public: