Files
nomad-shell/shell/qml/NavigationManager.qml
T

139 lines
3.1 KiB
QML

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)
}
}