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
154 lines
6.2 KiB
C++
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();
|
|
}
|