Files
TNCcat/qml/SettingsWindow.qml
T
JulianandClaude Opus 5 6b9553f6d4 Stop clipping the cat at the window edge
The cat was drawn in a 100 x 90 box that was exactly the window, so anything
reaching past it was cut off: the right whiskers always, and more of them in
poses that push the head forward, up to art x 109 while stretching.

The window box is now 120 x 106 with the drawing inset at (7, 14). The slack is
symmetric on purpose, because facing left mirrors the art about the box centre,
so asymmetric slack would clip the other side instead.

The mood-name mapper grew the shared aspect ratio and became CatDefs, so every
window sizes the cat the same way. Nose and mug offsets follow the new inset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 03:10:04 +02:00

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: Math.round(110 * CatDefs.aspect)
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()
}
}
}
}