The inspector's width bounds were 75-100 average character widths, which on macOS (8 px) came to 600 px for content that needs 397. They are now measured: at least the panel's minimum size hint plus the scroll bar, at most a third more. CollapsibleSection reports its folded content's width in minimumSizeHint, so the panel keeps its width when a section opens. On a font change the measurement waits a turn, until the children have the new font. When shrinking the window would leave the image narrower than the inspector, the inspector folds away, with the magnifier if it shares the inspector's column; they come back once the image would still be at least as wide as the inspector (plus 40 px of hysteresis). Only a shrink folds, a dock shown by anyone else is no longer the window's to restore, and folded docks are saved as open. Measured on a 1920 px screen: folds at 1140 px, returns at 1260 px; at 960 px the image gets 620 px instead of ~145. Dark theme: disabled text is set explicitly (#858AAE, ~4.8:1 on the panels) instead of the derived colour, which was nearly the panel colour and made greyed-out fields look empty. The splash text is black in either theme: its message is rich text, which takes the palette's text colour rather than showMessage's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
144 lines
5.6 KiB
C++
144 lines
5.6 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 "ViewerTheme.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);
|
|
|
|
app.setStyle(new SeparatorHandleStyle("Fusion"));
|
|
InitTheme(); // light or dark palette and the application stylesheet, per the View menu's choice
|
|
|
|
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()));
|
|
// The splash is white in either theme, so its text is black in either theme too. The message is
|
|
// rich text, and rich text takes its colour from the palette, not from showMessage's colour.
|
|
splash->showMessage(
|
|
"<span style=\"color: black;\"><b>Jungfrujoch image viewer</b><br/> Version " + version
|
|
+ "<br/>Paul Scherrer Institut</span>",
|
|
Qt::AlignBottom | Qt::AlignHCenter,
|
|
Qt::black
|
|
);
|
|
|
|
splash->show();
|
|
|
|
QTimer::singleShot(5000, splash, &QSplashScreen::close);
|
|
return QApplication::exec();
|
|
}
|