Rename to TNCat, add chip chase, G-codes and a Wayland layout
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>
This commit is contained in:
1 parent
acef398f49
commit
0f1df75a1d
19 files changed
+817
-185
No files matched your search
@@ -0,0 +1,119 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import TNCat
|
||||
|
||||
// One screen-filling, click-through window that holds the cat and the chip.
|
||||
// Wayland does not let a client place its own window, so there the cat moves
|
||||
// inside this overlay instead of the window moving across the desktop.
|
||||
Window {
|
||||
id: win
|
||||
|
||||
required property CatController cat
|
||||
required property AppSettings settings
|
||||
|
||||
signal settingsRequested()
|
||||
|
||||
// Fullscreen is a visibility, not a visible flag, so the mode switch has to
|
||||
// go through visibility or the two fight each other.
|
||||
property bool active: false
|
||||
|
||||
readonly property int catW: settings.catSize
|
||||
readonly property int catH: Math.round(settings.catSize * 0.9)
|
||||
readonly property real groundY: height - catH - settings.bottomMargin
|
||||
|
||||
// Only the cat itself should swallow clicks; everything else falls through.
|
||||
function refreshInputRegion() {
|
||||
Platform.setInputRegion(win, Qt.rect(Math.round(cat.x), Math.round(groundY), catW, catH))
|
||||
}
|
||||
|
||||
visibility: active ? Window.FullScreen : Window.Hidden
|
||||
color: "transparent"
|
||||
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool
|
||||
| Qt.NoDropShadowWindowHint | Qt.WindowDoesNotAcceptFocus
|
||||
title: qsTr("TNCat")
|
||||
|
||||
onActiveChanged: {
|
||||
if (!active)
|
||||
return
|
||||
cat.stageWidth = width
|
||||
cat.catWidth = catW
|
||||
refreshInputRegion()
|
||||
}
|
||||
onWidthChanged: cat.stageWidth = width
|
||||
onCatWChanged: cat.catWidth = catW
|
||||
|
||||
Binding {
|
||||
target: win.cat
|
||||
property: "catCenter"
|
||||
value: Qt.point(win.x + win.cat.x + win.catW / 2, win.y + win.groundY + win.catH / 2)
|
||||
}
|
||||
|
||||
// Coalesce mask updates: one X11 round trip per frame of walking is plenty.
|
||||
Timer {
|
||||
interval: 33
|
||||
running: win.active
|
||||
repeat: true
|
||||
onTriggered: win.refreshInputRegion()
|
||||
}
|
||||
|
||||
Chip {
|
||||
x: win.cat.chipX - width / 2
|
||||
y: win.height - height - win.settings.bottomMargin
|
||||
width: Math.round(win.settings.catSize * 0.45)
|
||||
height: Math.round(width * 0.73)
|
||||
visible: win.cat.chipVisible
|
||||
kick: win.cat.chipKick
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation { duration: 320; easing.type: Easing.OutQuad }
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: catItem
|
||||
x: win.cat.x
|
||||
y: win.groundY
|
||||
width: win.catW
|
||||
height: win.catH
|
||||
|
||||
Cat {
|
||||
anchors.fill: parent
|
||||
coat: win.settings.coat
|
||||
facingRight: win.cat.facingRight
|
||||
mood: CatMoods.name(win.cat.mood)
|
||||
lifted: win.cat.dragging
|
||||
petted: win.cat.hovered && !win.cat.dragging
|
||||
look: win.cat.look
|
||||
showCodes: win.settings.showCodes
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: qsTr("TNCat")
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
onHoveredChanged: win.cat.hovered = hovered
|
||||
}
|
||||
|
||||
DragHandler {
|
||||
target: null
|
||||
onActiveChanged: win.cat.dragging = active
|
||||
onCentroidChanged: {
|
||||
if (active)
|
||||
win.cat.x = Math.max(0, Math.min(win.cat.stageWidth - win.catW,
|
||||
catItem.x + centroid.position.x - centroid.pressPosition.x))
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onTapped: win.cat.pet()
|
||||
onDoubleTapped: win.settingsRequested()
|
||||
onLongPressed: win.settingsRequested()
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: win.settingsRequested()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user