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>
110 lines
3.2 KiB
QML
110 lines
3.2 KiB
QML
pragma ComponentBehavior: Bound
|
|
import QtQuick
|
|
import QtQuick.Shapes
|
|
|
|
// A mug of coffee with steam. Design space is 44 x 52 units, mug on the ground.
|
|
Item {
|
|
id: cup
|
|
|
|
readonly property real unit: width / 44
|
|
|
|
implicitWidth: 44
|
|
implicitHeight: 52
|
|
|
|
Item {
|
|
width: 44
|
|
height: 52
|
|
transformOrigin: Item.TopLeft
|
|
scale: cup.unit
|
|
|
|
Rectangle { // ground shadow
|
|
x: 8; y: 46
|
|
width: 26; height: 5
|
|
radius: 2.5
|
|
color: "#000000"
|
|
opacity: 0.18
|
|
antialiasing: true
|
|
}
|
|
|
|
// steam
|
|
Repeater {
|
|
model: 3
|
|
Shape {
|
|
id: wisp
|
|
required property int index
|
|
x: 10 + index * 7
|
|
y: 2
|
|
width: 8
|
|
height: 16
|
|
opacity: 0
|
|
preferredRendererType: Shape.CurveRenderer
|
|
|
|
ShapePath {
|
|
strokeColor: "#ffffff"
|
|
strokeWidth: 1.8
|
|
capStyle: ShapePath.RoundCap
|
|
fillColor: "transparent"
|
|
startX: 4; startY: 15
|
|
PathQuad { controlX: 0; controlY: 10; x: 4; y: 7 }
|
|
PathQuad { controlX: 8; controlY: 4; x: 4; y: 0 }
|
|
}
|
|
|
|
SequentialAnimation {
|
|
running: true
|
|
loops: Animation.Infinite
|
|
PauseAnimation { duration: wisp.index * 600 }
|
|
ParallelAnimation {
|
|
NumberAnimation { target: wisp; property: "opacity"; from: 0; to: 0.55; duration: 700 }
|
|
NumberAnimation { target: wisp; property: "y"; from: 8; to: 2; duration: 700 }
|
|
}
|
|
ParallelAnimation {
|
|
NumberAnimation { target: wisp; property: "opacity"; to: 0; duration: 1000 }
|
|
NumberAnimation { target: wisp; property: "y"; to: -6; duration: 1000 }
|
|
}
|
|
PauseAnimation { duration: 1800 - wisp.index * 600 }
|
|
}
|
|
}
|
|
}
|
|
|
|
// handle
|
|
Shape {
|
|
x: 28; y: 24
|
|
width: 14; height: 18
|
|
preferredRendererType: Shape.CurveRenderer
|
|
ShapePath {
|
|
strokeColor: "#e8e3da"
|
|
strokeWidth: 3.5
|
|
capStyle: ShapePath.RoundCap
|
|
fillColor: "transparent"
|
|
startX: 1; startY: 2
|
|
PathCubic { control1X: 12; control1Y: 0; control2X: 12; control2Y: 14; x: 1; y: 13 }
|
|
}
|
|
}
|
|
|
|
// mug
|
|
Rectangle {
|
|
x: 9; y: 20
|
|
width: 22; height: 27
|
|
radius: 4
|
|
color: "#f7f4ee"
|
|
antialiasing: true
|
|
|
|
Rectangle { // band
|
|
x: 0; y: 13
|
|
width: parent.width
|
|
height: 5
|
|
color: "#4d7ea8"
|
|
}
|
|
}
|
|
|
|
// coffee surface
|
|
Rectangle {
|
|
x: 10.5; y: 19
|
|
width: 19; height: 5
|
|
radius: 2.5
|
|
color: "#4a2c17"
|
|
antialiasing: true
|
|
}
|
|
}
|
|
}
|