Workcat: cute desktop cat, no window closing
Reworks the example into a pure desktop-pet: the cat wanders, sits, grooms, stretches, dashes and naps, reacts to petting and dragging, and follows the cursor with its eyes. The window-scanning and Accessibility code is gone. The cat is drawn from rounded primitives plus Shape paths in a fixed 100x90 design space, so it scales cleanly to any size. Linux/X11 is the primary target: the tray is optional, Wayland gets a warning, and WORKCAT_X11_BYPASS / WORKCAT_OPAQUE cover uncooperative window managers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
commit
acef398f49
17 files changed
+1584
No files matched your search
@@ -0,0 +1,71 @@
|
||||
#include "traycontroller.h"
|
||||
#include "catcontroller.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
TrayController::TrayController(CatController *cat, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_cat(cat)
|
||||
{
|
||||
QMenu *tricks = m_menu.addMenu(tr("Tricks"));
|
||||
const struct { const char *label; CatController::Mood mood; } entries[] = {
|
||||
{ QT_TR_NOOP("Sit"), CatController::Mood::Sitting },
|
||||
{ QT_TR_NOOP("Groom"), CatController::Mood::Grooming },
|
||||
{ QT_TR_NOOP("Stretch"), CatController::Mood::Stretching },
|
||||
{ QT_TR_NOOP("Dash"), CatController::Mood::Running },
|
||||
{ QT_TR_NOOP("Nap"), CatController::Mood::Sleeping },
|
||||
};
|
||||
for (const auto &e : entries) {
|
||||
const auto mood = e.mood;
|
||||
tricks->addAction(tr(e.label), this, [this, mood] { m_cat->doTrick(mood); });
|
||||
}
|
||||
|
||||
m_pauseAction = m_menu.addAction(tr("Let the cat sleep"));
|
||||
m_pauseAction->setCheckable(true);
|
||||
connect(m_pauseAction, &QAction::toggled, m_cat, &CatController::setPaused);
|
||||
connect(m_cat, &CatController::pausedChanged, this, [this] {
|
||||
m_pauseAction->setChecked(m_cat->paused());
|
||||
});
|
||||
|
||||
m_menu.addAction(tr("Settings…"), this, &TrayController::settingsRequested);
|
||||
m_menu.addSeparator();
|
||||
m_menu.addAction(tr("Quit Workcat"), qApp, &QCoreApplication::quit);
|
||||
|
||||
m_tray.setIcon(makeIcon());
|
||||
m_tray.setToolTip(tr("Workcat"));
|
||||
m_tray.setContextMenu(&m_menu);
|
||||
|
||||
// Not every X11 desktop runs a status-notifier host. Without a tray the
|
||||
// cat itself is the only entry point, so say so instead of failing mutely.
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable())
|
||||
m_tray.show();
|
||||
else
|
||||
qWarning("Workcat: no system tray on this desktop. Right-click the cat for settings.");
|
||||
}
|
||||
|
||||
QIcon TrayController::makeIcon()
|
||||
{
|
||||
QPixmap pm(44, 44);
|
||||
pm.fill(Qt::transparent);
|
||||
QPainter p(&pm);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(Qt::black);
|
||||
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(QRectF(5, 12, 34, 28), 14, 14);
|
||||
path.moveTo(8, 22); path.lineTo(9, 5); path.lineTo(21, 14); path.closeSubpath();
|
||||
path.moveTo(36, 22); path.lineTo(35, 5); path.lineTo(23, 14); path.closeSubpath();
|
||||
p.drawPath(path);
|
||||
|
||||
p.setBrush(Qt::white);
|
||||
p.drawEllipse(QRectF(13, 22, 6, 7));
|
||||
p.drawEllipse(QRectF(25, 22, 6, 7));
|
||||
|
||||
QIcon icon(pm);
|
||||
icon.setIsMask(true);
|
||||
return icon;
|
||||
}
|
||||
Reference in new issue
Block a user