mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
fix: type chooser SVG icons and gutter scale with editor zoom level
Derive icon size, gutter width, and icon column width from font metrics instead of hardcoded 16/10/20 pixel values. Popup width calculation also scales with font.
This commit is contained in:
@@ -97,6 +97,12 @@ public:
|
||||
int h = option.rect.height();
|
||||
int w = option.rect.width();
|
||||
|
||||
// Scale metrics from font height
|
||||
QFontMetrics fmMain(m_font);
|
||||
int iconSz = fmMain.height(); // icon matches text height
|
||||
int gutterW = fmMain.horizontalAdvance(QChar(0x25B8)) + 4;
|
||||
int iconColW = iconSz + 4;
|
||||
|
||||
// Section: centered dim text with horizontal rules
|
||||
if (isSection) {
|
||||
painter->setPen(t.textDim);
|
||||
@@ -133,18 +139,18 @@ public:
|
||||
if (isCurrent) {
|
||||
painter->setPen(t.text);
|
||||
painter->setFont(m_font);
|
||||
painter->drawText(QRect(x, y, 10, h), Qt::AlignCenter,
|
||||
painter->drawText(QRect(x, y, gutterW, h), Qt::AlignCenter,
|
||||
QString(QChar(0x25B8)));
|
||||
}
|
||||
}
|
||||
x += 10;
|
||||
x += gutterW;
|
||||
|
||||
// Icon 16x16 — only for composite entries
|
||||
// Icon (scaled to font height) — only for composite entries
|
||||
bool hasIcon = (m_filtered && row >= 0 && row < m_filtered->size()
|
||||
&& (*m_filtered)[row].entryKind == TypeEntry::Composite);
|
||||
if (hasIcon) {
|
||||
static QIcon structIcon(QStringLiteral(":/vsicons/symbol-structure.svg"));
|
||||
QPixmap pm = structIcon.pixmap(16, 16);
|
||||
QPixmap pm = structIcon.pixmap(iconSz, iconSz);
|
||||
if (isDisabled) {
|
||||
// Paint dimmed
|
||||
QPixmap dimmed(pm.size());
|
||||
@@ -153,12 +159,12 @@ public:
|
||||
p.setOpacity(0.35);
|
||||
p.drawPixmap(0, 0, pm);
|
||||
p.end();
|
||||
painter->drawPixmap(x, y + (h - 16) / 2, dimmed);
|
||||
painter->drawPixmap(x, y + (h - iconSz) / 2, dimmed);
|
||||
} else {
|
||||
structIcon.paint(painter, x, y + (h - 16) / 2, 16, 16);
|
||||
structIcon.paint(painter, x, y + (h - iconSz) / 2, iconSz, iconSz);
|
||||
}
|
||||
}
|
||||
x += 20;
|
||||
x += iconColW;
|
||||
|
||||
// Text
|
||||
QColor textColor;
|
||||
@@ -498,7 +504,9 @@ void TypeSelectorPopup::popup(const QPoint& globalPos) {
|
||||
QString text = t.classKeyword.isEmpty()
|
||||
? t.displayName
|
||||
: (t.classKeyword + QStringLiteral(" ") + t.displayName);
|
||||
int w = 10 + 20 + fm.horizontalAdvance(text) + 16;
|
||||
int gutterW = fm.horizontalAdvance(QChar(0x25B8)) + 4;
|
||||
int iconColW = fm.height() + 4;
|
||||
int w = gutterW + iconColW + fm.horizontalAdvance(text) + 16;
|
||||
if (w > maxTextW) maxTextW = w;
|
||||
}
|
||||
int popupW = qBound(280, maxTextW + 24, 500);
|
||||
|
||||
@@ -793,6 +793,100 @@ private slots:
|
||||
delete splitter;
|
||||
delete doc;
|
||||
}
|
||||
// ── Test: SVG icon and gutter scale with font size ──
|
||||
|
||||
void testDelegateIconScalesWithFont() {
|
||||
// Create a popup and set two different font sizes.
|
||||
// The delegate sizeHint row height should scale with font.
|
||||
TypeSelectorPopup popup;
|
||||
|
||||
TypeEntry prim;
|
||||
prim.entryKind = TypeEntry::Primitive;
|
||||
prim.primitiveKind = NodeKind::Int32;
|
||||
prim.displayName = QStringLiteral("int32_t");
|
||||
|
||||
TypeEntry comp;
|
||||
comp.entryKind = TypeEntry::Composite;
|
||||
comp.structId = 100;
|
||||
comp.displayName = QStringLiteral("TestStruct");
|
||||
comp.classKeyword = QStringLiteral("struct");
|
||||
|
||||
// Small font
|
||||
QFont small(QStringLiteral("Consolas"), 9);
|
||||
popup.setFont(small);
|
||||
popup.setTypes({prim, comp});
|
||||
popup.popup(QPoint(-9999, -9999)); // offscreen
|
||||
QApplication::processEvents();
|
||||
|
||||
auto* listView = popup.findChild<QListView*>();
|
||||
QVERIFY(listView);
|
||||
auto* delegate = listView->itemDelegate();
|
||||
QVERIFY(delegate);
|
||||
|
||||
// Find first non-section row for consistent measurement
|
||||
int dataRow = -1;
|
||||
for (int i = 0; i < listView->model()->rowCount(); i++) {
|
||||
QSize h = delegate->sizeHint(QStyleOptionViewItem(), listView->model()->index(i, 0));
|
||||
// Non-section rows are taller (font.height + 8 vs + 2)
|
||||
if (h.height() > QFontMetrics(small).height() + 4) { dataRow = i; break; }
|
||||
}
|
||||
QVERIFY2(dataRow >= 0, "Should find a non-section row");
|
||||
|
||||
QSize smallHint = delegate->sizeHint(QStyleOptionViewItem(), listView->model()->index(dataRow, 0));
|
||||
popup.hide();
|
||||
|
||||
// Large font (simulates zoomed editor)
|
||||
QFont large(QStringLiteral("Consolas"), 18);
|
||||
popup.setFont(large);
|
||||
popup.setTypes({prim, comp});
|
||||
popup.popup(QPoint(-9999, -9999));
|
||||
QApplication::processEvents();
|
||||
|
||||
QSize largeHint = delegate->sizeHint(QStyleOptionViewItem(), listView->model()->index(dataRow, 0));
|
||||
popup.hide();
|
||||
|
||||
// Large font should produce taller rows than small font
|
||||
QVERIFY2(largeHint.height() > smallHint.height(),
|
||||
qPrintable(QString("Large hint %1 should be > small hint %2")
|
||||
.arg(largeHint.height()).arg(smallHint.height())));
|
||||
|
||||
// The ratio should roughly match the font size ratio (18/9 = 2x)
|
||||
double ratio = double(largeHint.height()) / double(smallHint.height());
|
||||
QVERIFY2(ratio > 1.4, qPrintable(QString("Row height ratio %1 should be > 1.4").arg(ratio)));
|
||||
}
|
||||
|
||||
void testPopupWidthScalesWithFont() {
|
||||
TypeSelectorPopup popup;
|
||||
|
||||
TypeEntry comp;
|
||||
comp.entryKind = TypeEntry::Composite;
|
||||
comp.structId = 100;
|
||||
comp.displayName = QStringLiteral("MyLongStructName");
|
||||
comp.classKeyword = QStringLiteral("struct");
|
||||
popup.setTypes({comp});
|
||||
|
||||
// Small font
|
||||
QFont small(QStringLiteral("Consolas"), 9);
|
||||
popup.setFont(small);
|
||||
popup.popup(QPoint(-9999, -9999));
|
||||
QApplication::processEvents();
|
||||
int smallW = popup.width();
|
||||
popup.hide();
|
||||
|
||||
// Large font
|
||||
QFont large(QStringLiteral("Consolas"), 18);
|
||||
popup.setFont(large);
|
||||
popup.setTypes({comp});
|
||||
popup.popup(QPoint(-9999, -9999));
|
||||
QApplication::processEvents();
|
||||
int largeW = popup.width();
|
||||
popup.hide();
|
||||
|
||||
// Popup with larger font should be wider
|
||||
QVERIFY2(largeW > smallW,
|
||||
qPrintable(QString("Large popup width %1 should be > small %2")
|
||||
.arg(largeW).arg(smallW)));
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(TestTypeSelector)
|
||||
|
||||
Reference in New Issue
Block a user