GUI Milestone 6

This commit is contained in:
Joey Yakimowich-Payne 2026-01-30 06:38:58 -07:00
commit 0e67c19902
4 changed files with 211 additions and 26 deletions

View file

@ -4,19 +4,83 @@
#include <QAction>
#include <QApplication>
#include <QCommandLineParser>
#include <QDateTime>
#include <QDir>
#include <QKeySequence>
#include <QLabel>
#include <QMainWindow>
#include <QPixmap>
#include <QScreen>
#include <QStandardPaths>
#include <QStatusBar>
#include <QTimer>
#include <cstring>
#include <iostream>
static int captureWindow(QMainWindow *window, const QString &path) {
QPixmap pixmap = window->grab();
if (pixmap.isNull()) {
QScreen *screen = window->screen();
if (screen) {
pixmap = screen->grabWindow(window->winId());
}
}
if (pixmap.isNull()) {
std::cerr << "warppipe: screenshot capture failed\n";
return 3;
}
QFileInfo fi(path);
QDir dir = fi.absoluteDir();
if (!dir.exists()) {
dir.mkpath(".");
}
if (!pixmap.save(path)) {
std::cerr << "warppipe: failed to write screenshot to "
<< path.toStdString() << "\n";
return 3;
}
return 0;
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) {
if (std::strcmp(argv[i], "--offscreen") == 0) {
qputenv("QT_QPA_PLATFORM", "offscreen");
}
}
QApplication app(argc, argv);
QCoreApplication::setApplicationName("Warppipe");
QCoreApplication::setApplicationVersion("0.1.0");
QCommandLineParser parser;
parser.setApplicationDescription("Warppipe — PipeWire Audio Router GUI");
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption screenshotOpt(
QStringList() << "s" << "screenshot",
"Capture window to PNG and exit.", "path");
QCommandLineOption delayOpt(
"screenshot-delay",
"Delay in ms before capture (default 800).", "ms", "800");
QCommandLineOption debugDirOpt(
"debug-screenshot-dir",
"Save timestamped screenshot on every graph state change.", "dir");
QCommandLineOption offscreenOpt(
"offscreen",
"Run with QT_QPA_PLATFORM=offscreen (headless).");
parser.addOption(screenshotOpt);
parser.addOption(delayOpt);
parser.addOption(debugDirOpt);
parser.addOption(offscreenOpt);
parser.process(app);
warppipe::ConnectionOptions opts;
opts.application_name = "warppipe-gui";
@ -50,6 +114,56 @@ int main(int argc, char *argv[]) {
});
statusTimer->start(500);
if (parser.isSet(debugDirOpt)) {
editor->setDebugScreenshotDir(parser.value(debugDirOpt));
}
if (parser.isSet(screenshotOpt)) {
QString screenshotPath = parser.value(screenshotOpt);
int delay = parser.value(delayOpt).toInt();
if (delay <= 0) {
delay = 800;
}
bool captured = false;
auto doCapture = [&]() {
if (captured) return;
captured = true;
QTimer::singleShot(100, [&]() {
int code = captureWindow(&window, screenshotPath);
app.exit(code);
});
};
auto *fallbackTimer = new QTimer(&window);
fallbackTimer->setSingleShot(true);
QObject::connect(fallbackTimer, &QTimer::timeout, doCapture);
QObject::connect(editor, &GraphEditorWidget::graphReady, [&]() {
fallbackTimer->stop();
doCapture();
});
fallbackTimer->start(delay);
}
auto *f12Action = new QAction(&window);
f12Action->setShortcut(Qt::Key_F12);
QObject::connect(f12Action, &QAction::triggered, [&]() {
QString picDir =
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) +
"/warppipe";
QDir().mkpath(picDir);
QString timestamp =
QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
QString path = picDir + "/warppipe_" + timestamp + ".png";
int code = captureWindow(&window, path);
if (code == 0) {
window.statusBar()->showMessage("Screenshot saved: " + path, 3000);
}
});
window.addAction(f12Action);
auto *closeAction = new QAction(&window);
closeAction->setShortcut(QKeySequence::Quit);
QObject::connect(closeAction, &QAction::triggered, &window,