The project is now TNCat, after HEIDENHAIN's TNC controls. Binary, QML module URI, settings path, bundle id and .desktop entry follow; the environment switches are TNCAT_*. Entertainment: a curled steel chip skitters in every minute or two, the cat runs it down and bats it away a few times before sitting back looking pleased. Mood changes flash the matching machine code above its head, G00 for a sprint, G01 for a stroll, M08 while it washes, G28 for a stretch, M30 for a nap. Window handling was split into two layouts. X11 and macOS keep one small window per object, positioned by the app. Wayland gets a screen-filling overlay whose input region is masked down to the cat, since a Wayland client cannot place its own window. Overlay mode is automatic there and available elsewhere via TNCAT_OVERLAY=1. Also adds a ground-line setting so the cat can walk above a softkey row. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
205 lines
7.0 KiB
QML
205 lines
7.0 KiB
QML
pragma ComponentBehavior: Bound
|
|
import QtQuick
|
|
import QtQuick.Controls.Basic
|
|
import QtQuick.Layouts
|
|
import TNCat
|
|
|
|
Window {
|
|
id: win
|
|
|
|
required property CatController cat
|
|
required property AppSettings settings
|
|
|
|
readonly property var coats: [
|
|
{ name: qsTr("Apricot"), color: "#f4b183" },
|
|
{ name: qsTr("Ivory"), color: "#f3ede2" },
|
|
{ name: qsTr("Grey"), color: "#a4a6b3" },
|
|
{ name: qsTr("Charcoal"), color: "#3c3b46" },
|
|
{ name: qsTr("Sage"), color: "#a9bfa0" },
|
|
{ name: qsTr("Plum"), color: "#9a7bb0" }
|
|
]
|
|
|
|
width: 440
|
|
height: 700
|
|
minimumWidth: 380
|
|
minimumHeight: 600
|
|
title: qsTr("TNCat")
|
|
color: "#faf7f2"
|
|
flags: Qt.Dialog | Qt.WindowStaysOnTopHint
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: 24
|
|
spacing: 18
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 16
|
|
Loader {
|
|
Layout.preferredWidth: 110
|
|
Layout.preferredHeight: 99
|
|
active: win.visible
|
|
sourceComponent: Cat {
|
|
coat: win.settings.coat
|
|
mood: "sitting"
|
|
showCodes: false
|
|
petted: previewHover.hovered
|
|
HoverHandler { id: previewHover }
|
|
}
|
|
}
|
|
ColumnLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 4
|
|
Label {
|
|
Layout.fillWidth: true
|
|
text: qsTr("TNCat")
|
|
font.pixelSize: 26
|
|
font.bold: true
|
|
color: "#2f2a36"
|
|
}
|
|
Label {
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.WordWrap
|
|
text: qsTr("A little cat that wanders along the bottom of your screen. Drag it around, pet it with a click, and it will purr.")
|
|
color: "#7a7484"
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: qsTr("Coat")
|
|
Flow {
|
|
anchors.fill: parent
|
|
spacing: 10
|
|
Repeater {
|
|
model: win.coats
|
|
Column {
|
|
id: swatch
|
|
required property var modelData
|
|
readonly property bool selected: Qt.colorEqual(win.settings.coat, modelData.color)
|
|
spacing: 4
|
|
Rectangle {
|
|
width: 40; height: 40
|
|
radius: 20
|
|
color: swatch.modelData.color
|
|
border.width: swatch.selected ? 3 : 1
|
|
border.color: swatch.selected ? "#f25f7a" : "#d8d2ca"
|
|
antialiasing: true
|
|
Accessible.role: Accessible.RadioButton
|
|
Accessible.name: swatch.modelData.name
|
|
Accessible.checked: swatch.selected
|
|
activeFocusOnTab: true
|
|
Keys.onSpacePressed: win.settings.coat = swatch.modelData.color
|
|
TapHandler { onTapped: win.settings.coat = swatch.modelData.color }
|
|
}
|
|
Label {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: swatch.modelData.name
|
|
font.pixelSize: 11
|
|
color: "#7a7484"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GridLayout {
|
|
Layout.fillWidth: true
|
|
columns: 2
|
|
columnSpacing: 14
|
|
rowSpacing: 12
|
|
|
|
Label { text: qsTr("Size") }
|
|
Slider {
|
|
Layout.fillWidth: true
|
|
from: 72; to: 260; stepSize: 4
|
|
value: win.settings.catSize
|
|
onMoved: win.settings.catSize = value
|
|
}
|
|
|
|
Label { text: qsTr("Pace") }
|
|
Slider {
|
|
Layout.fillWidth: true
|
|
from: 10; to: 200; stepSize: 5
|
|
value: win.settings.walkSpeed
|
|
onMoved: win.settings.walkSpeed = value
|
|
}
|
|
|
|
Label { text: qsTr("Ground line") }
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Slider {
|
|
id: marginSlider
|
|
Layout.fillWidth: true
|
|
from: 0; to: 600; stepSize: 10
|
|
value: win.settings.bottomMargin
|
|
onMoved: win.settings.bottomMargin = value
|
|
}
|
|
Label {
|
|
Layout.preferredWidth: 54
|
|
text: qsTr("%1 px").arg(Math.round(marginSlider.value))
|
|
}
|
|
}
|
|
|
|
Label { text: qsTr("Eyes") }
|
|
Switch {
|
|
text: qsTr("Follow the mouse")
|
|
checked: win.settings.followCursor
|
|
onToggled: win.settings.followCursor = checked
|
|
}
|
|
|
|
Label { text: qsTr("Codes") }
|
|
Switch {
|
|
text: qsTr("Show G-code above the cat")
|
|
checked: win.settings.showCodes
|
|
onToggled: win.settings.showCodes = checked
|
|
}
|
|
|
|
Label { text: qsTr("Chips") }
|
|
Switch {
|
|
text: qsTr("Let a chip skitter past now and then")
|
|
checked: win.settings.chipsEnabled
|
|
onToggled: win.settings.chipsEnabled = checked
|
|
}
|
|
|
|
Label { text: qsTr("Cat") }
|
|
Switch {
|
|
text: checked ? qsTr("Napping") : qsTr("Awake")
|
|
checked: win.cat.paused
|
|
onToggled: win.cat.paused = checked
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: qsTr("Tricks")
|
|
Flow {
|
|
anchors.fill: parent
|
|
spacing: 8
|
|
Button { text: qsTr("Sit"); onClicked: win.cat.doTrick(CatController.Sitting) }
|
|
Button { text: qsTr("Groom"); onClicked: win.cat.doTrick(CatController.Grooming) }
|
|
Button { text: qsTr("Stretch"); onClicked: win.cat.doTrick(CatController.Stretching) }
|
|
Button { text: qsTr("Dash"); onClicked: win.cat.doTrick(CatController.Running) }
|
|
Button { text: qsTr("Nap"); onClicked: win.cat.doTrick(CatController.Sleeping) }
|
|
Button { text: qsTr("Toss a chip"); onClicked: win.cat.tossChip() }
|
|
}
|
|
}
|
|
|
|
Item { Layout.fillHeight: true }
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Label {
|
|
Layout.fillWidth: true
|
|
text: qsTr("%n pet(s) so far.", "", win.settings.petCount)
|
|
color: "#7a7484"
|
|
}
|
|
Button {
|
|
text: qsTr("Quit")
|
|
onClicked: Qt.quit()
|
|
}
|
|
}
|
|
}
|
|
}
|