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>
139 lines
4.2 KiB
C++
139 lines
4.2 KiB
C++
#pragma once
|
|
|
|
#include <QObject>
|
|
#include <QQmlEngine>
|
|
#include <QTimer>
|
|
#include <QElapsedTimer>
|
|
#include <QPointF>
|
|
|
|
class AppSettings;
|
|
|
|
// Drives the cat: wanders along its ground line, sits, grooms, stretches and
|
|
// naps, chases the odd metal chip, and reacts to petting and dragging.
|
|
class CatController : public QObject
|
|
{
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
QML_UNCREATABLE("Provided by C++")
|
|
|
|
Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
|
|
Q_PROPERTY(qreal stageWidth READ stageWidth WRITE setStageWidth NOTIFY stageWidthChanged)
|
|
Q_PROPERTY(qreal catWidth READ catWidth WRITE setCatWidth NOTIFY catWidthChanged)
|
|
Q_PROPERTY(QPointF catCenter READ catCenter WRITE setCatCenter NOTIFY catCenterChanged)
|
|
Q_PROPERTY(bool facingRight READ facingRight NOTIFY facingRightChanged)
|
|
Q_PROPERTY(Mood mood READ mood NOTIFY moodChanged)
|
|
Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged)
|
|
Q_PROPERTY(bool dragging READ dragging WRITE setDragging NOTIFY draggingChanged)
|
|
Q_PROPERTY(bool hovered READ hovered WRITE setHovered NOTIFY hoveredChanged)
|
|
Q_PROPERTY(QPointF look READ look NOTIFY lookChanged)
|
|
|
|
Q_PROPERTY(bool chipVisible READ chipVisible NOTIFY chipVisibleChanged)
|
|
Q_PROPERTY(qreal chipX READ chipX NOTIFY chipXChanged)
|
|
Q_PROPERTY(int chipKick READ chipKick NOTIFY chipKickChanged)
|
|
Q_PROPERTY(bool cupVisible READ cupVisible NOTIFY cupVisibleChanged)
|
|
Q_PROPERTY(qreal cupX READ cupX NOTIFY cupXChanged)
|
|
|
|
public:
|
|
enum class Mood { Walking, Running, Sitting, Grooming, Stretching, Sleeping, Loving, Alert, Chasing, Batting, Drinking };
|
|
Q_ENUM(Mood)
|
|
|
|
explicit CatController(AppSettings *settings, QObject *parent = nullptr);
|
|
|
|
qreal x() const { return m_x; }
|
|
void setX(qreal x);
|
|
|
|
qreal stageWidth() const { return m_stageWidth; }
|
|
void setStageWidth(qreal width);
|
|
|
|
qreal catWidth() const { return m_catWidth; }
|
|
void setCatWidth(qreal width);
|
|
|
|
// Where the cat's face is on the desktop, so the eyes can find the cursor.
|
|
QPointF catCenter() const { return m_catCenter; }
|
|
void setCatCenter(const QPointF ¢er);
|
|
|
|
bool facingRight() const { return m_facingRight; }
|
|
Mood mood() const { return m_mood; }
|
|
|
|
bool paused() const { return m_paused; }
|
|
void setPaused(bool paused);
|
|
|
|
bool dragging() const { return m_dragging; }
|
|
void setDragging(bool dragging);
|
|
|
|
bool hovered() const { return m_hovered; }
|
|
void setHovered(bool hovered);
|
|
|
|
QPointF look() const { return m_look; }
|
|
|
|
bool chipVisible() const { return m_chipVisible; }
|
|
qreal chipX() const { return m_chipX; }
|
|
int chipKick() const { return m_chipKick; }
|
|
bool cupVisible() const { return m_cupVisible; }
|
|
qreal cupX() const { return m_cupX; }
|
|
|
|
Q_INVOKABLE void pet();
|
|
Q_INVOKABLE void doTrick(Mood mood);
|
|
Q_INVOKABLE void tossChip();
|
|
Q_INVOKABLE void coffeeBreak();
|
|
|
|
signals:
|
|
void xChanged();
|
|
void stageWidthChanged();
|
|
void catWidthChanged();
|
|
void catCenterChanged();
|
|
void facingRightChanged();
|
|
void moodChanged();
|
|
void pausedChanged();
|
|
void draggingChanged();
|
|
void hoveredChanged();
|
|
void lookChanged();
|
|
void chipVisibleChanged();
|
|
void chipXChanged();
|
|
void chipKickChanged();
|
|
void cupVisibleChanged();
|
|
void cupXChanged();
|
|
|
|
private:
|
|
void tick();
|
|
void trackCursor();
|
|
void setMood(Mood mood);
|
|
void setFacingRight(bool right);
|
|
void setChipX(qreal x);
|
|
void pickNextMood();
|
|
void holdMood(Mood mood, int ms);
|
|
void batChip();
|
|
void endChase();
|
|
void endCoffee();
|
|
void scheduleChip();
|
|
qreal catNose() const;
|
|
|
|
AppSettings *m_settings;
|
|
QTimer m_tickTimer;
|
|
QTimer m_moodTimer;
|
|
QTimer m_cursorTimer;
|
|
QTimer m_chipTimer;
|
|
QElapsedTimer m_clock;
|
|
qint64 m_lastTickMs = 0;
|
|
|
|
qreal m_x = 120;
|
|
qreal m_stageWidth = 1440;
|
|
qreal m_catWidth = 120;
|
|
QPointF m_catCenter;
|
|
bool m_facingRight = true;
|
|
Mood m_mood = Mood::Walking;
|
|
bool m_paused = false;
|
|
bool m_dragging = false;
|
|
bool m_hovered = false;
|
|
bool m_frozen = false;
|
|
QPointF m_look;
|
|
|
|
bool m_chipVisible = false;
|
|
qreal m_chipX = 0;
|
|
int m_chipKick = 0;
|
|
int m_batsLeft = 0;
|
|
|
|
bool m_cupVisible = false;
|
|
qreal m_cupX = 0;
|
|
};
|