Every so often a mug appears at the cat's nose, it sits down, dips its head in and takes a few slow sips while steam rises. M01, optional stop. The mug lives in its own click-through window like the chip, or inside the overlay on Wayland. It goes away as soon as the cat is petted, dragged, sent to sleep or moves on to something else, so no mug is ever left standing. Also renames OverlayWindow's mode flag, which shadowed QWindow::active. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
213 lines
7.3 KiB
QML
213 lines
7.3 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("Coffee") }
|
|
Switch {
|
|
text: qsTr("Take a coffee break now and then")
|
|
checked: win.settings.coffeeEnabled
|
|
onToggled: win.settings.coffeeEnabled = 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() }
|
|
Button { text: qsTr("Coffee"); onClicked: win.cat.coffeeBreak() }
|
|
}
|
|
}
|
|
|
|
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()
|
|
}
|
|
}
|
|
}
|
|
}
|