overhauled navigation, it doesn't suck now
This commit is contained in:
@@ -19,6 +19,7 @@ qt_add_qml_module(nomad-shell
|
|||||||
VERSION 1.0
|
VERSION 1.0
|
||||||
QML_FILES
|
QML_FILES
|
||||||
qml/Main.qml
|
qml/Main.qml
|
||||||
|
qml/NavigationManager.qml
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(nomad-shell
|
target_link_libraries(nomad-shell
|
||||||
|
|||||||
+59
-40
@@ -59,50 +59,27 @@ QtObject {
|
|||||||
property int focusRegion: bottomWindow.mainMenuNavRegions.GamesList
|
property int focusRegion: bottomWindow.mainMenuNavRegions.GamesList
|
||||||
property int dockMenuIndex: 0
|
property int dockMenuIndex: 0
|
||||||
|
|
||||||
|
NavigationManager {
|
||||||
|
id: navigationManager
|
||||||
|
rootItem: bottomRoot
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: inputManager
|
target: inputManager
|
||||||
|
|
||||||
function onActionPressed(action) {
|
function onActionPressed(action) {
|
||||||
if (action === InputManager.Up) {
|
switch (action) {
|
||||||
if (bottomWindow.focusRegion < bottomWindow.mainMenuNavRegions.Count - 1) {
|
case InputManager.Up:
|
||||||
bottomWindow.focusRegion += 1
|
case InputManager.Down:
|
||||||
}
|
case InputManager.Left:
|
||||||
}
|
case InputManager.Right:
|
||||||
if (action === InputManager.Down) {
|
navigationManager.move(action)
|
||||||
if (bottomWindow.focusRegion > 0) {
|
break
|
||||||
bottomWindow.focusRegion -= 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (action === InputManager.Left || action === InputManager.Right) {
|
|
||||||
switch (bottomWindow.focusRegion) {
|
|
||||||
case bottomWindow.mainMenuNavRegions.GamesList:
|
|
||||||
if (action === InputManager.Left) {
|
|
||||||
if (gamesList.currentIndex > 0) {
|
|
||||||
gamesList.currentIndex -= 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (gamesList.currentIndex < gamesList.count - 1) {
|
|
||||||
gamesList.currentIndex += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
|
|
||||||
case bottomWindow.mainMenuNavRegions.DockMenu:
|
|
||||||
if (action === InputManager.Left) {
|
|
||||||
if (bottomWindow.dockMenuIndex > 0) {
|
|
||||||
bottomWindow.dockMenuIndex -= 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (bottomWindow.dockMenuIndex < dockRepeater.count - 1) {
|
|
||||||
bottomWindow.dockMenuIndex += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: bottomRoot
|
id: bottomRoot
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -135,17 +112,36 @@ QtObject {
|
|||||||
|
|
||||||
model: 20
|
model: 20
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (currentItem) {
|
||||||
|
navigationManager.focusItem(currentItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
|
id: gameTile
|
||||||
|
|
||||||
width: 110
|
width: 110
|
||||||
height: 110
|
height: 110
|
||||||
|
|
||||||
color: bottomWindow.focusRegion === bottomWindow.mainMenuNavRegions.GamesList && index === gamesList.currentIndex ? "blue" : "white"
|
color: navigationManager.currentItem === gameTile ? "blue" : "white"
|
||||||
|
|
||||||
|
function navFocus() {
|
||||||
|
gamesList.currentIndex = index
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
navigationManager.registerItem(gameTile)
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
navigationManager.unregisterItem(gameTile)
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
bottomWindow.focusRegion = bottomWindow.mainMenuNavRegions.GamesList
|
navigationManager.focusItem(gameTile)
|
||||||
gamesList.currentIndex = index
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,9 +161,32 @@ QtObject {
|
|||||||
model: 5
|
model: 5
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: dockButton
|
||||||
|
|
||||||
width: 60
|
width: 60
|
||||||
height: 60
|
height: 60
|
||||||
color: bottomWindow.focusRegion === bottomWindow.mainMenuNavRegions.DockMenu && index === bottomWindow.dockMenuIndex ? "blue" : "white"
|
|
||||||
|
color: navigationManager.currentItem === dockButton ? "blue" : "white"
|
||||||
|
|
||||||
|
function navFocus() {
|
||||||
|
bottomWindow.dockMenuIndex = index
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
navigationManager.registerItem(dockButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
navigationManager.unregisterItem(dockButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
navigationManager.focusItem(dockButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
import QtQuick
|
||||||
|
import NomadInput 1.0
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: manager
|
||||||
|
|
||||||
|
property Item rootItem: null
|
||||||
|
property list<QtObject> items
|
||||||
|
property var currentItem: null
|
||||||
|
|
||||||
|
function focusItem(item) {
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
currentItem = item
|
||||||
|
|
||||||
|
if (typeof item.navFocus === "function") {
|
||||||
|
item.navFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerItem(item) {
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
if (items[i] === item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
items.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
function unregisterItem(item) {
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
if (items[i] === item) {
|
||||||
|
items.splice(i, 1)
|
||||||
|
|
||||||
|
if (currentItem === item) {
|
||||||
|
currentItem = null
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function move(action) {
|
||||||
|
if (!currentItem || !rootItem) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let dx = 0
|
||||||
|
let dy = 0
|
||||||
|
|
||||||
|
switch(action) {
|
||||||
|
case InputManager.Left:
|
||||||
|
dx = -1
|
||||||
|
break
|
||||||
|
|
||||||
|
case InputManager.Right:
|
||||||
|
dx = 1
|
||||||
|
break
|
||||||
|
|
||||||
|
case InputManager.Up:
|
||||||
|
dy = -1
|
||||||
|
break
|
||||||
|
|
||||||
|
case InputManager.Down:
|
||||||
|
dy = 1
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentCenter = currentItem.mapToItem(rootItem, currentItem.width / 2, currentItem.height / 2)
|
||||||
|
|
||||||
|
let bestItem = null
|
||||||
|
let bestScore = Infinity
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
let candidate = items[i]
|
||||||
|
|
||||||
|
if (!candidate) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (candidate === currentItem) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!candidate.visible || !candidate.enabled) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let candidateCenter = candidate.mapToItem(rootItem, candidate.width / 2, candidate.height / 2)
|
||||||
|
|
||||||
|
let differenceX = candidateCenter.x - currentCenter.x
|
||||||
|
let differenceY = candidateCenter.y - currentCenter.y
|
||||||
|
|
||||||
|
let forwardDistance
|
||||||
|
let sidewaysDistance
|
||||||
|
|
||||||
|
if (dx !== 0) {
|
||||||
|
forwardDistance = differenceX * dx
|
||||||
|
sidewaysDistance = Math.abs(differenceY)
|
||||||
|
} else {
|
||||||
|
forwardDistance = differenceY * dy
|
||||||
|
sidewaysDistance = Math.abs(differenceX)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forwardDistance <= 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let score = forwardDistance + sidewaysDistance * 2
|
||||||
|
|
||||||
|
if (score < bestScore) {
|
||||||
|
bestScore = score
|
||||||
|
bestItem = candidate
|
||||||
|
}
|
||||||
|
console.log("candidate:", candidate, "center:", candidateCenter.x, candidateCenter.y, "difference:", differenceX, differenceY)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestItem) {
|
||||||
|
focusItem(bestItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("MOVE", inputManager.actionName(action), "current:", currentItem, "center:", currentCenter.x, currentCenter.y)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user