mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
fix: type chooser updates colors when theme changes
Add applyTheme() to TypeSelectorPopup that refreshes palette and stylesheets for all child widgets. Controller connects it to ThemeManager::themeChanged on popup creation.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "typeselectorpopup.h"
|
#include "typeselectorpopup.h"
|
||||||
#include "providerregistry.h"
|
#include "providerregistry.h"
|
||||||
|
#include "themes/thememanager.h"
|
||||||
#include <Qsci/qsciscintilla.h>
|
#include <Qsci/qsciscintilla.h>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@@ -1726,6 +1727,9 @@ void RcxController::updateCommandRow() {
|
|||||||
TypeSelectorPopup* RcxController::ensurePopup(RcxEditor* editor) {
|
TypeSelectorPopup* RcxController::ensurePopup(RcxEditor* editor) {
|
||||||
if (!m_cachedPopup) {
|
if (!m_cachedPopup) {
|
||||||
m_cachedPopup = new TypeSelectorPopup(editor);
|
m_cachedPopup = new TypeSelectorPopup(editor);
|
||||||
|
// Keep popup colors in sync when theme changes
|
||||||
|
connect(&ThemeManager::instance(), &ThemeManager::themeChanged,
|
||||||
|
m_cachedPopup, &TypeSelectorPopup::applyTheme);
|
||||||
// Pre-warm: force native window creation so first visible show is fast
|
// Pre-warm: force native window creation so first visible show is fast
|
||||||
m_cachedPopup->warmUp();
|
m_cachedPopup->warmUp();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -279,14 +279,14 @@ TypeSelectorPopup::TypeSelectorPopup(QWidget* parent)
|
|||||||
|
|
||||||
// Separator
|
// Separator
|
||||||
{
|
{
|
||||||
auto* sep = new QFrame;
|
m_separator = new QFrame;
|
||||||
sep->setFrameShape(QFrame::HLine);
|
m_separator->setFrameShape(QFrame::HLine);
|
||||||
sep->setFrameShadow(QFrame::Plain);
|
m_separator->setFrameShadow(QFrame::Plain);
|
||||||
QPalette sepPal = pal;
|
QPalette sepPal = pal;
|
||||||
sepPal.setColor(QPalette::WindowText, theme.border);
|
sepPal.setColor(QPalette::WindowText, theme.border);
|
||||||
sep->setPalette(sepPal);
|
m_separator->setPalette(sepPal);
|
||||||
sep->setFixedHeight(1);
|
m_separator->setFixedHeight(1);
|
||||||
layout->addWidget(sep);
|
layout->addWidget(m_separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Row 3: Modifier toggles [ plain ] [ * ] [ ** ] [ [n] ]
|
// Row 3: Modifier toggles [ plain ] [ * ] [ ** ] [ [n] ]
|
||||||
@@ -456,6 +456,60 @@ void TypeSelectorPopup::setFont(const QFont& font) {
|
|||||||
delegate->setFont(font);
|
delegate->setFont(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TypeSelectorPopup::applyTheme(const Theme& theme) {
|
||||||
|
QPalette pal;
|
||||||
|
pal.setColor(QPalette::Window, theme.backgroundAlt);
|
||||||
|
pal.setColor(QPalette::WindowText, theme.text);
|
||||||
|
pal.setColor(QPalette::Base, theme.background);
|
||||||
|
pal.setColor(QPalette::AlternateBase, theme.surface);
|
||||||
|
pal.setColor(QPalette::Text, theme.text);
|
||||||
|
pal.setColor(QPalette::Button, theme.button);
|
||||||
|
pal.setColor(QPalette::ButtonText, theme.text);
|
||||||
|
pal.setColor(QPalette::Highlight, theme.hover);
|
||||||
|
pal.setColor(QPalette::HighlightedText, theme.text);
|
||||||
|
setPalette(pal);
|
||||||
|
|
||||||
|
m_titleLabel->setPalette(pal);
|
||||||
|
m_filterEdit->setPalette(pal);
|
||||||
|
m_listView->setPalette(pal);
|
||||||
|
m_previewLabel->setPalette(pal);
|
||||||
|
m_arrayCountEdit->setPalette(pal);
|
||||||
|
|
||||||
|
// Separator
|
||||||
|
QPalette sepPal = pal;
|
||||||
|
sepPal.setColor(QPalette::WindowText, theme.border);
|
||||||
|
m_separator->setPalette(sepPal);
|
||||||
|
|
||||||
|
// Esc button
|
||||||
|
m_escLabel->setStyleSheet(QStringLiteral(
|
||||||
|
"QToolButton { color: %1; border: none; padding: 2px 6px; }"
|
||||||
|
"QToolButton:hover { color: %2; }")
|
||||||
|
.arg(theme.textDim.name(), theme.indHoverSpan.name()));
|
||||||
|
|
||||||
|
// Create button
|
||||||
|
m_createBtn->setStyleSheet(QStringLiteral(
|
||||||
|
"QToolButton { color: %1; border: none; padding: 3px 6px; }"
|
||||||
|
"QToolButton:hover { color: %2; background: %3; }")
|
||||||
|
.arg(theme.textMuted.name(), theme.text.name(), theme.hover.name()));
|
||||||
|
|
||||||
|
// Modifier toggle buttons
|
||||||
|
QString btnStyle = QStringLiteral(
|
||||||
|
"QToolButton { color: %1; background: %2; border: 1px solid %3;"
|
||||||
|
" padding: 2px 8px; border-radius: 3px; }"
|
||||||
|
"QToolButton:checked { color: %4; background: %5; border-color: %5; }"
|
||||||
|
"QToolButton:hover:!checked { background: %6; }")
|
||||||
|
.arg(theme.textDim.name(), theme.background.name(), theme.border.name(),
|
||||||
|
theme.text.name(), theme.selected.name(), theme.hover.name());
|
||||||
|
m_btnPlain->setStyleSheet(btnStyle);
|
||||||
|
m_btnPtr->setStyleSheet(btnStyle);
|
||||||
|
m_btnDblPtr->setStyleSheet(btnStyle);
|
||||||
|
m_btnArray->setStyleSheet(btnStyle);
|
||||||
|
|
||||||
|
// Preview label
|
||||||
|
m_previewLabel->setStyleSheet(QStringLiteral(
|
||||||
|
"QLabel { color: %1; padding: 1px 6px; }").arg(theme.syntaxType.name()));
|
||||||
|
}
|
||||||
|
|
||||||
void TypeSelectorPopup::setTitle(const QString& title) {
|
void TypeSelectorPopup::setTitle(const QString& title) {
|
||||||
m_titleLabel->setText(title);
|
m_titleLabel->setText(title);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ class QWidget;
|
|||||||
|
|
||||||
namespace rcx {
|
namespace rcx {
|
||||||
|
|
||||||
|
struct Theme;
|
||||||
|
|
||||||
// ── Popup mode ──
|
// ── Popup mode ──
|
||||||
|
|
||||||
enum class TypePopupMode { Root, FieldType, ArrayElement, PointerTarget };
|
enum class TypePopupMode { Root, FieldType, ArrayElement, PointerTarget };
|
||||||
@@ -53,6 +55,7 @@ public:
|
|||||||
void setFont(const QFont& font);
|
void setFont(const QFont& font);
|
||||||
void setTitle(const QString& title);
|
void setTitle(const QString& title);
|
||||||
void setMode(TypePopupMode mode);
|
void setMode(TypePopupMode mode);
|
||||||
|
void applyTheme(const Theme& theme);
|
||||||
void setCurrentNodeSize(int bytes);
|
void setCurrentNodeSize(int bytes);
|
||||||
void setTypes(const QVector<TypeEntry>& types, const TypeEntry* current = nullptr);
|
void setTypes(const QVector<TypeEntry>& types, const TypeEntry* current = nullptr);
|
||||||
void popup(const QPoint& globalPos);
|
void popup(const QPoint& globalPos);
|
||||||
@@ -77,6 +80,7 @@ private:
|
|||||||
QLabel* m_previewLabel = nullptr;
|
QLabel* m_previewLabel = nullptr;
|
||||||
QListView* m_listView = nullptr;
|
QListView* m_listView = nullptr;
|
||||||
QStringListModel* m_model = nullptr;
|
QStringListModel* m_model = nullptr;
|
||||||
|
QFrame* m_separator = nullptr;
|
||||||
|
|
||||||
// Modifier toggles
|
// Modifier toggles
|
||||||
QWidget* m_modRow = nullptr;
|
QWidget* m_modRow = nullptr;
|
||||||
|
|||||||
@@ -887,6 +887,79 @@ private slots:
|
|||||||
qPrintable(QString("Large popup width %1 should be > small %2")
|
qPrintable(QString("Large popup width %1 should be > small %2")
|
||||||
.arg(largeW).arg(smallW)));
|
.arg(largeW).arg(smallW)));
|
||||||
}
|
}
|
||||||
|
// ── Test: popup updates colors when theme changes ──
|
||||||
|
|
||||||
|
void testPopupUpdatesOnThemeChange() {
|
||||||
|
auto& tm = ThemeManager::instance();
|
||||||
|
int origIdx = tm.currentIndex();
|
||||||
|
|
||||||
|
// Ensure at least two themes exist
|
||||||
|
QVERIFY2(tm.themes().size() >= 2,
|
||||||
|
"Need at least 2 themes to test theme switching");
|
||||||
|
|
||||||
|
// Create popup with current theme
|
||||||
|
TypeSelectorPopup popup;
|
||||||
|
TypeEntry prim;
|
||||||
|
prim.entryKind = TypeEntry::Primitive;
|
||||||
|
prim.primitiveKind = NodeKind::Int32;
|
||||||
|
prim.displayName = QStringLiteral("int32_t");
|
||||||
|
popup.setTypes({prim});
|
||||||
|
|
||||||
|
QColor bgBefore = popup.palette().color(QPalette::Window);
|
||||||
|
|
||||||
|
// Switch to a different theme
|
||||||
|
int otherIdx = (origIdx == 0) ? 1 : 0;
|
||||||
|
tm.setCurrent(otherIdx);
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// The popup should have applyTheme connected to themeChanged
|
||||||
|
popup.applyTheme(tm.current());
|
||||||
|
QColor bgAfter = popup.palette().color(QPalette::Window);
|
||||||
|
|
||||||
|
// If the two themes have different background colors, verify the change
|
||||||
|
// (some themes may coincidentally share colors, so we just verify the
|
||||||
|
// method doesn't crash and the palette is set to the new theme's color)
|
||||||
|
QCOMPARE(bgAfter, tm.current().backgroundAlt);
|
||||||
|
|
||||||
|
// Also verify child widgets got updated
|
||||||
|
auto* filterEdit = popup.findChild<QLineEdit*>();
|
||||||
|
QVERIFY(filterEdit);
|
||||||
|
QCOMPARE(filterEdit->palette().color(QPalette::Base),
|
||||||
|
tm.current().background);
|
||||||
|
|
||||||
|
auto* listView = popup.findChild<QListView*>();
|
||||||
|
QVERIFY(listView);
|
||||||
|
QCOMPARE(listView->palette().color(QPalette::Base),
|
||||||
|
tm.current().background);
|
||||||
|
|
||||||
|
// Restore original theme
|
||||||
|
tm.setCurrent(origIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPopupAutoConnectsThemeChange() {
|
||||||
|
auto& tm = ThemeManager::instance();
|
||||||
|
int origIdx = tm.currentIndex();
|
||||||
|
QVERIFY2(tm.themes().size() >= 2, "Need >= 2 themes");
|
||||||
|
|
||||||
|
TypeSelectorPopup popup;
|
||||||
|
|
||||||
|
// applyTheme is a public slot — verify it can be connected
|
||||||
|
connect(&tm, &ThemeManager::themeChanged,
|
||||||
|
&popup, &TypeSelectorPopup::applyTheme);
|
||||||
|
|
||||||
|
QColor bgBefore = popup.palette().color(QPalette::Window);
|
||||||
|
|
||||||
|
int otherIdx = (origIdx == 0) ? 1 : 0;
|
||||||
|
tm.setCurrent(otherIdx);
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// After theme change + signal, popup palette should match new theme
|
||||||
|
QCOMPARE(popup.palette().color(QPalette::Window),
|
||||||
|
tm.current().backgroundAlt);
|
||||||
|
|
||||||
|
// Restore
|
||||||
|
tm.setCurrent(origIdx);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QTEST_MAIN(TestTypeSelector)
|
QTEST_MAIN(TestTypeSelector)
|
||||||
|
|||||||
Reference in New Issue
Block a user