diff --git a/interface/resources/qml/VrMenu.qml b/interface/resources/qml/VrMenu.qml index 14a4a449fd..eef87ed943 100644 --- a/interface/resources/qml/VrMenu.qml +++ b/interface/resources/qml/VrMenu.qml @@ -1,7 +1,9 @@ import Hifi 1.0 as Hifi + import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Controls.Styles 1.3 + import "controls" import "styles" @@ -21,15 +23,18 @@ Hifi.VrMenu { property var models: [] property var columns: [] - onEnabledChanged: { + console.log("Activating menu " + enabled); if (enabled && columns.length == 0) { + console.log(rootMenu) + console.log(rootMenu.items) pushColumn(rootMenu.items); } opacity = enabled ? 1.0 : 0.0 - if (enabled) { - forceActiveFocus() - } + offscreenFlags.navigationFocused = enabled; +// if (enabled) { + //forceActiveFocus() +// } } // The actual animator @@ -49,13 +54,12 @@ Hifi.VrMenu { } property var menuBuilder: Component { - Border { - HifiConstants { id: hifi } - property int menuDepth + VrMenuView { + property int menuDepth: root.models.length - 1 + model: root.models[menuDepth] Component.onCompleted: { - menuDepth = root.models.length - 1 - if (menuDepth == 0) { + if (menuDepth === 0) { x = lastMousePosition.x - 20 y = lastMousePosition.y - 20 } else { @@ -63,50 +67,11 @@ Hifi.VrMenu { x = lastColumn.x + 64; y = lastMousePosition.y - height / 2; } + //recalcSize(); } - border.color: hifi.colors.hifiBlue - color: hifi.colors.window - implicitHeight: listView.implicitHeight + 16 - implicitWidth: listView.implicitWidth + 16 - - Column { - id: listView - property real minWidth: 0 - anchors { - top: parent.top - topMargin: 8 - left: parent.left - leftMargin: 8 - right: parent.right - rightMargin: 8 - } - - Repeater { - model: root.models[menuDepth] - delegate: Loader { - id: loader - source: "VrMenuItem.qml" - Binding { - target: loader.item - property: "menuContainer" - value: root - when: loader.status == Loader.Ready - } - Binding { - target: loader.item - property: "source" - value: modelData - when: loader.status == Loader.Ready - } - Binding { - target: loader.item - property: "listView" - value: listView - when: loader.status == Loader.Ready - } - } - } + onSelected: { + root.selectItem(menuDepth, item) } } } @@ -116,14 +81,14 @@ Hifi.VrMenu { } function pushColumn(items) { - models.push(items) + models.push(itemsToModel(items)) if (columns.length) { var oldColumn = lastColumn(); //oldColumn.enabled = false } var newColumn = menuBuilder.createObject(root); columns.push(newColumn); - newColumn.forceActiveFocus(); + forceActiveFocus(); } function popColumn() { @@ -145,13 +110,41 @@ Hifi.VrMenu { curColumn.forceActiveFocus(); } - function selectItem(source) { + function itemsToModel(items) { + var newListModel = Qt.createQmlObject('import QtQuick 2.2; ListModel {}', root); + console.log(items) + console.log(items.length) + for (var i = 0; i < items.length; ++i) { + var item = items[i]; + switch (item.type) { + case 2: + newListModel.append({"type":item.type, "name": item.title, "item": item}) + break; + case 1: + newListModel.append({"type":item.type, "name": item.text, "item": item}) + break; + case 0: + newListModel.append({"type":item.type, "name": "-----", "item": item}) + break; + } + } + return newListModel; + } + + function selectItem(depth, source) { + var popped = false; + while (depth + 1 < columns.length) { + popColumn() + popped = true + } + switch (source.type) { case 2: + lastColumn().enabled = false pushColumn(source.items) break; case 1: - source.trigger() + if (!popped) source.trigger() enabled = false break; case 0: @@ -165,14 +158,6 @@ Hifi.VrMenu { } } - Keys.onPressed: { - switch (event.key) { - case Qt.Key_Escape: - root.popColumn() - event.accepted = true; - } - } - MouseArea { anchors.fill: parent id: mouseArea @@ -206,4 +191,36 @@ Hifi.VrMenu { function removeItem(menu, menuItem) { menu.removeItem(menuItem); } + + function previousItem() { + if (columns.length) { + lastColumn().incrementCurrentIndex() + } + } + + function nextItem() { + if (columns.length) { + lastColumn().decrementCurrentIndex() + } + } + + function selectCurrentItem() { + if (columns.length) { + var depth = columns.length - 1; + var index = lastColumn().currentIndex; + if (index >= 0) { + var model = models[depth]; + var item = model.get(index).item; + selectItem(depth, item); + } + } + } + + Keys.onDownPressed: previousItem(); + Keys.onUpPressed: nextItem(); + Keys.onSpacePressed: selectCurrentItem(); + Keys.onReturnPressed: selectCurrentItem(); + Keys.onRightPressed: selectCurrentItem(); + Keys.onLeftPressed: popColumn(); + Keys.onEscapePressed: popColumn(); } diff --git a/interface/resources/qml/VrMenuItem.qml b/interface/resources/qml/VrMenuItem.qml index fbde35059d..4dcde0e2ae 100644 --- a/interface/resources/qml/VrMenuItem.qml +++ b/interface/resources/qml/VrMenuItem.qml @@ -1,62 +1,23 @@ import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Controls.Styles 1.3 -import "controls" + import "styles" +import "controls" Item { id: root - HifiConstants { - id: hifi - } + HifiConstants { id: hifi } + // The model object + property alias text: label.text property var source - property var menuContainer - property var listView - MouseArea { - anchors.left: parent.left - anchors.right: tag.right - anchors.rightMargin: -4 - anchors.top: parent.top - anchors.bottom: parent.bottom - acceptedButtons: Qt.LeftButton - hoverEnabled: true - - Rectangle { - id: highlight - visible: false - anchors.fill: parent - color: "#7f0e7077" - } - - onEntered: { - //if (source.type == 2 && enabled) { - // timer.start() - //} - highlight.visible = source.enabled - } - - onExited: { - timer.stop() - highlight.visible = false - } - - onClicked: { - select() - } - } implicitHeight: source.visible ? label.implicitHeight * 1.5 : 0 - implicitWidth: label.implicitWidth + label.height * 2.5 + implicitWidth: label.width + label.height * 2.5 visible: source.visible - - Timer { - id: timer - interval: 1000 - onTriggered: parent.select() - } - + width: parent.width FontAwesome { clip: true @@ -84,32 +45,18 @@ Item { Text { id: label - text: typedText() anchors.left: check.right anchors.leftMargin: 4 anchors.verticalCenter: parent.verticalCenter verticalAlignment: Text.AlignVCenter color: source.enabled ? hifi.colors.text : hifi.colors.disabledText - enabled: source.enabled && source.visible + enabled: source.visible && (source.type !== 0 ? source.enabled : false) visible: source.visible - function typedText() { - if (source) { - switch (source.type) { - case 2: - return source.title - case 1: - return source.text - case 0: - return "-----" - } - } - return "" - } } FontAwesome { id: tag - x: listView.width - width - 4 + x: root.parent.width - width size: label.height width: implicitWidth visible: source.visible && (source.type == 2) @@ -117,17 +64,4 @@ Item { anchors.verticalCenter: parent.verticalCenter color: label.color } - - function select() { - //timer.stop(); - var popped = false - while (columns.length - 1 > listView.parent.menuDepth) { - popColumn() - popped = true - } - - if (!popped || source.type != 1) { - root.menuContainer.selectItem(source) - } - } } diff --git a/interface/resources/qml/VrMenuView.qml b/interface/resources/qml/VrMenuView.qml new file mode 100644 index 0000000000..6758031491 --- /dev/null +++ b/interface/resources/qml/VrMenuView.qml @@ -0,0 +1,78 @@ +import QtQuick 2.4 +import QtQuick.Controls 1.3 +import QtQuick.Controls.Styles 1.3 + +import "styles" + +ListView { + id: root + HifiConstants { id: hifi } + width: 128 + height: count * 32 + onEnabledChanged: root.recalcSize(); + onVisibleChanged: root.recalcSize(); + signal selected(var item) + + highlight: Rectangle { + width: root.currentItem ? root.currentItem.width : 0 + height: root.currentItem ? root.currentItem.height : 0 + color: "lightsteelblue"; radius: 3 +// y: root.currentItem ? root.currentItem.y : 0 + } + + delegate: VrMenuItem { + text: name + source: item + onImplicitHeightChanged: root.recalcSize() + onImplicitWidthChanged: root.recalcSize() + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onEntered: root.currentIndex = index + onClicked: root.selected(item) + } + } + + onCountChanged: recalcSize(); + + function recalcSize() { + if (model.count !== count || !visible) { + return; + } + + var originalIndex = currentIndex; + var maxWidth = width; + var newHeight = 0; + for (var i = 0; i < count; ++i) { + currentIndex = i; + if (!currentItem) { + continue; + } + if (currentItem && currentItem.implicitWidth > maxWidth) { + maxWidth = currentItem.implicitWidth + } + if (currentItem.visible) { + newHeight += currentItem.implicitHeight + } + } + if (maxWidth > width) { + width = maxWidth; + } + if (newHeight > height) { + height = newHeight + } + currentIndex = originalIndex; + } + + Border { + id: border + anchors.fill: parent + anchors.margins: -8 + z: parent.z - 1 + border.color: hifi.colors.hifiBlue + color: hifi.colors.window + } +} + +