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