Add Qt Bigscreen (QML/CMake), remove Tauri
Add a native Qt "Bigscreen" shell: CMakeLists, C++ entry (main.cpp, InputRouter), QML module (Theme, ShellWindow, views and components) and a Bigscreen/.gitignore; update top-level .gitignore and README with Qt build/run instructions. Remove the legacy Tauri/web prototype files (package.json, package-lock.json, src-tauri and many web assets) as part of the migration to the Qt/CMake-based shell.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Nebula.Bigscreen
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var homeTiles: [
|
||||
{ label: "Library", meta: "Games and apps", icon: "📚", route: "library" },
|
||||
{ label: "Settings", meta: "System controls", icon: "⚙", route: "settings" },
|
||||
{ label: "Power", meta: "Sleep and sessions", icon: "⏻", route: "power" }
|
||||
]
|
||||
|
||||
signal navigate(string route)
|
||||
|
||||
spacing: 28
|
||||
|
||||
Text {
|
||||
text: "Home"
|
||||
font: Theme.brandFont
|
||||
color: Theme.textPrimary
|
||||
Layout.leftMargin: 40
|
||||
}
|
||||
|
||||
TileRail {
|
||||
id: rail
|
||||
Layout.fillWidth: true
|
||||
tiles: root.homeTiles
|
||||
|
||||
onTileActivated: function(index) {
|
||||
const route = root.homeTiles[index].route
|
||||
if (route === "power") {
|
||||
root.navigate("power")
|
||||
} else {
|
||||
root.navigate(route)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleInput(action) {
|
||||
switch (action) {
|
||||
case InputRouter.Left:
|
||||
rail.moveFocus(-1)
|
||||
break
|
||||
case InputRouter.Right:
|
||||
rail.moveFocus(1)
|
||||
break
|
||||
case InputRouter.Accept:
|
||||
rail.activateFocused()
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function accentFocus() {
|
||||
return rail.accentFocus
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Nebula.Bigscreen
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
signal goBack()
|
||||
|
||||
readonly property var entries: [
|
||||
{ title: "Nebula Demo", meta: "Local • Ready", icon: "🎮" },
|
||||
{ title: "Retro Runner", meta: "Wine • Installed", icon: "👾" },
|
||||
{ title: "Media Hub", meta: "App • Installed", icon: "🎬" }
|
||||
]
|
||||
|
||||
property int focusIndex: 0
|
||||
|
||||
spacing: 20
|
||||
|
||||
Text {
|
||||
text: "Library"
|
||||
font: Theme.brandFont
|
||||
color: Theme.textPrimary
|
||||
Layout.leftMargin: 40
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Mock entries for v0 — scanners and launchers come later."
|
||||
font: Theme.metaFont
|
||||
color: Theme.textMuted
|
||||
Layout.leftMargin: 40
|
||||
Layout.bottomMargin: 8
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 40
|
||||
Layout.rightMargin: 40
|
||||
clip: true
|
||||
spacing: 12
|
||||
model: root.entries
|
||||
|
||||
delegate: Rectangle {
|
||||
width: list.width
|
||||
height: 72
|
||||
radius: 12
|
||||
color: index === root.focusIndex ? "#22304A66" : Theme.backgroundPanel
|
||||
border.color: index === root.focusIndex ? Theme.accentCyan : Theme.accentLine
|
||||
border.width: index === root.focusIndex ? 2 : 1
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16
|
||||
spacing: 16
|
||||
|
||||
Text {
|
||||
text: modelData.icon
|
||||
font.pixelSize: 28
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 2
|
||||
Text {
|
||||
text: modelData.title
|
||||
font: Theme.titleFont
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
Text {
|
||||
text: modelData.meta
|
||||
font: Theme.metaFont
|
||||
color: Theme.textMuted
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleInput(action) {
|
||||
switch (action) {
|
||||
case InputRouter.Up:
|
||||
focusIndex = Math.max(0, focusIndex - 1)
|
||||
list.currentIndex = focusIndex
|
||||
break
|
||||
case InputRouter.Down:
|
||||
focusIndex = Math.min(entries.length - 1, focusIndex + 1)
|
||||
list.currentIndex = focusIndex
|
||||
break
|
||||
case InputRouter.Back:
|
||||
root.goBack()
|
||||
break
|
||||
case InputRouter.Accept:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Nebula.Bigscreen
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
signal goBack()
|
||||
|
||||
readonly property var categories: [
|
||||
"Network",
|
||||
"Audio",
|
||||
"Display",
|
||||
"Controller",
|
||||
"System"
|
||||
]
|
||||
|
||||
property int categoryIndex: 0
|
||||
property int itemIndex: 0
|
||||
|
||||
spacing: 20
|
||||
|
||||
Text {
|
||||
text: "Settings"
|
||||
font: Theme.brandFont
|
||||
color: Theme.textPrimary
|
||||
Layout.leftMargin: 40
|
||||
}
|
||||
|
||||
Row {
|
||||
Layout.leftMargin: 40
|
||||
spacing: 16
|
||||
|
||||
Repeater {
|
||||
model: root.categories
|
||||
|
||||
Rectangle {
|
||||
height: 40
|
||||
width: categoryLabel.implicitWidth + 24
|
||||
radius: 8
|
||||
color: index === root.categoryIndex ? "#22304A66" : "transparent"
|
||||
border.color: index === root.categoryIndex ? Theme.accentCyan : "transparent"
|
||||
border.width: index === root.categoryIndex ? 2 : 0
|
||||
|
||||
Text {
|
||||
id: categoryLabel
|
||||
anchors.centerIn: parent
|
||||
text: modelData
|
||||
font: Theme.bodyFont
|
||||
color: index === root.categoryIndex ? Theme.accentCyan : Theme.textMuted
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.margins: 40
|
||||
radius: 16
|
||||
color: Theme.backgroundPanel
|
||||
border.color: Theme.accentLine
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 24
|
||||
spacing: 12
|
||||
|
||||
Text {
|
||||
text: root.categories[root.categoryIndex]
|
||||
font: Theme.titleFont
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: 3
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 52
|
||||
radius: 10
|
||||
color: index === root.itemIndex ? "#22304A66" : Theme.backgroundMid
|
||||
border.color: index === root.itemIndex ? Theme.accentCyan : Theme.accentLine
|
||||
border.width: index === root.itemIndex ? 2 : 1
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
text: "Placeholder setting " + (index + 1)
|
||||
font: Theme.bodyFont
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleInput(action) {
|
||||
switch (action) {
|
||||
case InputRouter.Left:
|
||||
categoryIndex = Math.max(0, categoryIndex - 1)
|
||||
break
|
||||
case InputRouter.Right:
|
||||
categoryIndex = Math.min(categories.length - 1, categoryIndex + 1)
|
||||
break
|
||||
case InputRouter.Up:
|
||||
itemIndex = Math.max(0, itemIndex - 1)
|
||||
break
|
||||
case InputRouter.Down:
|
||||
itemIndex = Math.min(2, itemIndex + 1)
|
||||
break
|
||||
case InputRouter.Back:
|
||||
root.goBack()
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user