Files
Jungfraujoch/viewer/jfjoch_viewer.cpp
T
leonarski_fandClaude Fable 5 89272850fb viewer: the splitter is a cased centre grip, not a full coral line
The 10 px coral band gave the resize handles the 3:1 contrast that made
them findable, but three of them frame the image panel and dominated the
view. The separator keeps its 10 px grab area and is painted in the
window colour; what marks it is a short dark-amber pill (4.4:1 on
salmon) at its midpoint, cased in a near-white rim like the spot markers
so the amber does not bleed into the salmon, and taking the brand coral
under the cursor. Drawn by a QProxyStyle over Fusion, since a stylesheet
can only fill the whole band.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015vRwzF8PLaaa2novAKYorq
2026-09-13 19:27:39 +02:00

154 lines
6.2 KiB
C++

#include <QApplication>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QSplashScreen>
#include <QTimer>
#include <QPalette>
#include <QProxyStyle>
#include <QStyleOption>
#include <QPainter>
#include "JFJochViewerWindow.h"
#include "RemoteDisplayMode.h"
#include "../writer/HDF5Objects.h"
#include "../common/GitInfo.h"
namespace {
// Fusion paints the dock resize handles in the window colour, which leaves them invisible against
// the salmon background (1.00:1) and impossible to find; a full-length coral band fixed that but
// dominated the view. So the separator keeps its 10 px grab area, is painted in the window colour,
// and is marked only by a short dark-amber pill (4.4:1 on salmon) at its midpoint, which takes the
// brand coral under the cursor.
class SeparatorHandleStyle final : public QProxyStyle {
public:
explicit SeparatorHandleStyle(const QString &base) : QProxyStyle(base) {}
int pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *w) const override {
if (m == PM_DockWidgetSeparatorExtent)
return 10;
return QProxyStyle::pixelMetric(m, opt, w);
}
void drawPrimitive(PrimitiveElement el, const QStyleOption *opt, QPainter *p,
const QWidget *w) const override {
if (el != PE_IndicatorDockWidgetResizeHandle) {
QProxyStyle::drawPrimitive(el, opt, p, w);
return;
}
p->fillRect(opt->rect, opt->palette.window());
const bool vertical = opt->rect.width() < opt->rect.height();
const QColor pill_color = (opt->state & State_MouseOver) ? QColor(0xFA, 0x72, 0x68)
: QColor(0xB4, 0x53, 0x09);
constexpr qreal kLen = 56.0, kThick = 5.0;
const QPointF c = QRectF(opt->rect).center();
const QRectF pill = vertical ? QRectF(c.x() - kThick / 2, c.y() - kLen / 2, kThick, kLen)
: QRectF(c.x() - kLen / 2, c.y() - kThick / 2, kLen, kThick);
p->save();
p->setRenderHint(QPainter::Antialiasing);
// Cased in a near-white rim, like the spot markers: the bright seam lifts the grip off
// the salmon band instead of letting the amber bleed into it.
p->setPen(QPen(QColor(0xFF, 0xFC, 0xFA), 1));
p->setBrush(pill_color);
p->drawRoundedRect(pill, kThick / 2, kThick / 2);
p->restore();
}
};
} // namespace
int main(int argc, char *argv[]) {
qRegisterMetaType<std::shared_ptr<const JFJochReaderDataset>>("std::shared_ptr<const JFJochReaderDataset>");
qRegisterMetaType<std::shared_ptr<const JFJochReaderImage>>("std::shared_ptr<const JFJochReaderImage>");
RegisterHDF5Filter();
QApplication app(argc, argv);
// Theme via the palette (robust across widgets): salmon panels, white entry fields that fall back
// to salmon when disabled, and a navy accent for selections and progress-bar chunks.
app.setStyle(new SeparatorHandleStyle("Fusion"));
QPalette pal = app.palette();
pal.setColor(QPalette::Window, QColor(255, 235, 230));
pal.setColor(QPalette::Base, Qt::white);
pal.setColor(QPalette::AlternateBase, QColor(255, 245, 242));
pal.setColor(QPalette::Button, QColor(255, 235, 230));
pal.setColor(QPalette::Disabled, QPalette::Base, QColor(255, 235, 230));
pal.setColor(QPalette::Highlight, QColor(0x1f, 0x3a, 0x5f));
pal.setColor(QPalette::HighlightedText, Qt::white);
app.setPalette(pal);
// Fusion fills QGroupBox interiors with a flat light colour; make them transparent so they show
// the salmon window background like the rest of the UI (entry widgets stay white via the palette).
// The dock resize handles are drawn by SeparatorHandleStyle above, not the stylesheet.
app.setStyleSheet("QGroupBox { background-color: transparent; }");
QIcon appIcon(":/jfjoch.png");
app.setWindowIcon(appIcon);
app.setApplicationName("JFJoch Viewer");
app.setApplicationVersion(QString::fromStdString(jfjoch_version()));
// Parse command line arguments
QCommandLineParser parser;
parser.setApplicationDescription("JFJoch Image Viewer");
parser.addHelpOption();
parser.addVersionOption();
// Add --dbus option with a value option that defaults to true
QCommandLineOption dbusOption(QStringList() << "d" << "dbus",
"Enable or disable D-Bus interface (default: enabled)",
"enable", "true");
parser.addOption(dbusOption);
// Process the actual command line arguments
parser.process(app);
if (RemoteDisplayMode())
qInfo() << "Remote display session detected - repaints are throttled"
" (JFJOCH_VIEWER_REMOTE=0 or the View menu to override)";
// Get any positional arguments (files to open)
QString fileToOpen;
QStringList positionalArgs = parser.positionalArguments();
if (!positionalArgs.isEmpty()) {
// Use the last argument as the file to open
fileToOpen = positionalArgs.last();
}
// Check if D-Bus should be enabled or disabled
bool enableDBus = true; // Default is enabled
QString dbusValue = parser.value(dbusOption).toLower();
if (dbusValue == "false" || dbusValue == "0" || dbusValue == "no" || dbusValue == "off") {
enableDBus = false;
qDebug() << "D-Bus interface disabled";
} else {
qDebug() << "D-Bus interface enabled";
}
// Create and show the main window with the appropriate settings
JFJochViewerWindow mainWindow(nullptr, enableDBus, fileToOpen);
mainWindow.show();
QPixmap pixmap(":/jfjoch.png");
QPixmap splash_pixmap(256+2*50, 256+50+50+30);
splash_pixmap.fill(Qt::white);
QPainter painter(&splash_pixmap);
painter.drawPixmap(50, 50, pixmap);
QSplashScreen *splash = new QSplashScreen(splash_pixmap);
splash->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::SplashScreen);
QString version(QString::fromStdString(jfjoch_version()));
splash->showMessage(
"<b>Jungfrujoch image viewer</b><br/> Version " + version + "<br/>Paul Scherrer Institut",
Qt::AlignBottom | Qt::AlignHCenter,
Qt::black
);
splash->show();
QTimer::singleShot(5000, splash, &QSplashScreen::close);
return QApplication::exec();
}