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>
72 lines
2.4 KiB
C++
72 lines
2.4 KiB
C++
#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;
|
|
}
|