fix: Options dialog - remove CSS overrides, fix title case, add show icon checkbox, add Generator page

This commit is contained in:
IChooseYou
2026-02-15 13:17:00 -07:00
parent 193ab81ecf
commit 9d22a5ed69
6 changed files with 292 additions and 130 deletions

View File

@@ -8,8 +8,6 @@
#include <QGroupBox>
#include <QLabel>
#include <QTreeWidgetItem>
#include <QGraphicsDropShadowEffect>
#include <QEvent>
#include <functional>
namespace rcx {
@@ -20,8 +18,6 @@ OptionsDialog::OptionsDialog(const OptionsResult& current, QWidget* parent)
setWindowTitle("Options");
setFixedSize(700, 450);
const auto& t = ThemeManager::instance().current();
auto* mainLayout = new QVBoxLayout(this);
mainLayout->setSpacing(8);
mainLayout->setContentsMargins(10, 10, 10, 10);
@@ -87,6 +83,10 @@ OptionsDialog::OptionsDialog(const OptionsResult& current, QWidget* parent)
m_titleCaseCheck->setChecked(current.menuBarTitleCase);
visualLayout->addRow(m_titleCaseCheck);
m_showIconCheck = new QCheckBox("Show icon in title bar");
m_showIconCheck->setChecked(current.showIcon);
visualLayout->addRow(m_showIconCheck);
generalLayout->addWidget(visualGroup);
// Safe Mode group box
@@ -96,8 +96,6 @@ OptionsDialog::OptionsDialog(const OptionsResult& current, QWidget* parent)
m_safeModeCheck = new QCheckBox("Safe Mode");
m_safeModeCheck->setChecked(current.safeMode);
m_safeModeCheck->setStyleSheet(QStringLiteral(
"QCheckBox { font-weight: bold; }"));
safeModeLayout->addWidget(m_safeModeCheck);
auto* safeModeDesc = new QLabel(
@@ -127,8 +125,6 @@ OptionsDialog::OptionsDialog(const OptionsResult& current, QWidget* parent)
m_autoMcpCheck = new QCheckBox("Auto-start MCP server");
m_autoMcpCheck->setChecked(current.autoStartMcp);
m_autoMcpCheck->setStyleSheet(QStringLiteral(
"QCheckBox { font-weight: bold; }"));
mcpLayout->addWidget(m_autoMcpCheck);
auto* mcpDesc = new QLabel(
@@ -144,6 +140,18 @@ OptionsDialog::OptionsDialog(const OptionsResult& current, QWidget* parent)
m_pages->addWidget(aiPage); // index 1
m_pageKeywords[aiItem] = collectPageKeywords(aiPage);
// -- Generator page --
auto* generatorItem = new QTreeWidgetItem(envItem, {"Generator"});
auto* generatorPage = new QWidget;
auto* generatorLayout = new QVBoxLayout(generatorPage);
generatorLayout->setContentsMargins(0, 0, 0, 0);
generatorLayout->setSpacing(8);
generatorLayout->addStretch();
m_pages->addWidget(generatorPage); // index 2
m_pageKeywords[generatorItem] = collectPageKeywords(generatorPage);
middleLayout->addWidget(m_pages, 1);
mainLayout->addLayout(middleLayout, 1);
@@ -151,6 +159,7 @@ OptionsDialog::OptionsDialog(const OptionsResult& current, QWidget* parent)
// Tree <-> page connection
m_itemPageIndex[generalItem] = 0;
m_itemPageIndex[aiItem] = 1;
m_itemPageIndex[generatorItem] = 2;
connect(m_tree, &QTreeWidget::currentItemChanged, this,
[this](QTreeWidgetItem* item, QTreeWidgetItem*) {
if (!item) return;
@@ -165,106 +174,6 @@ OptionsDialog::OptionsDialog(const OptionsResult& current, QWidget* parent)
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
mainLayout->addWidget(buttons);
// -- Styling --
// Combo boxes: set directly so the popup (top-level widget) inherits it
QString comboStyle = QStringLiteral(
"QComboBox {"
" background: %1; color: %2; border: 1px solid %3;"
" padding: 3px 8px; font-size: 12px;"
"}"
"QComboBox::drop-down {"
" border: none; border-left: 1px solid %3;"
" width: 20px;"
"}"
"QComboBox::down-arrow {"
" image: url(:/vsicons/chevron-down.svg);"
" width: 12px; height: 12px;"
"}"
"QComboBox QAbstractItemView {"
" background: %1; color: %2; border: 1px solid %3;"
" selection-background-color: %4;"
"}")
.arg(t.backgroundAlt.name(), t.text.name(),
t.border.name(), t.hover.name());
m_themeCombo->setStyleSheet(comboStyle);
m_fontCombo->setStyleSheet(comboStyle);
// Dialog-wide stylesheet for everything else
setStyleSheet(QStringLiteral(
"QDialog { background: %1; }"
"QLineEdit {"
" background: %2; color: %3; border: 1px solid %4;"
" padding: 4px 8px; font-size: 12px;"
"}"
"QTreeWidget {"
" background: %2; color: %3; border: 1px solid %4;"
" font-size: 12px; outline: none;"
"}"
"QTreeWidget::item { padding: 3px 0; outline: none; }"
"QTreeWidget::item:selected { background: %5; color: %3; }"
"QTreeWidget::item:hover { background: %6; }"
"QGroupBox {"
" color: %3; border: 1px solid %4;"
" margin-top: 8px; padding: 12px 8px 8px 8px;"
" font-size: 12px; font-weight: bold;"
"}"
"QGroupBox::title {"
" subcontrol-origin: margin;"
" left: 8px; padding: 0 4px;"
"}"
"QLabel { color: %3; font-size: 12px; }"
"QCheckBox { color: %3; font-size: 12px; spacing: 6px; }"
"QPushButton {"
" background: %2; color: %3; border: 1px solid %4;"
" padding: 5px 16px; min-width: 70px; font-size: 12px;"
" outline: none;"
"}"
"QPushButton:hover { background: %6; }"
"QPushButton:pressed { background: %1; }"
"QPushButton:focus { outline: none; }")
.arg(t.background.name(), // %1
t.backgroundAlt.name(), // %2
t.text.name(), // %3
t.border.name(), // %4
t.selection.name(), // %5
t.hover.name())); // %6
// Install hover shadow on interactive widgets (not buttons — they use stylesheet hover)
for (auto* w : {static_cast<QWidget*>(m_search),
static_cast<QWidget*>(m_themeCombo),
static_cast<QWidget*>(m_fontCombo),
static_cast<QWidget*>(m_titleCaseCheck),
static_cast<QWidget*>(m_safeModeCheck),
static_cast<QWidget*>(m_autoMcpCheck)})
w->installEventFilter(this);
m_shadowColor = t.text;
m_shadowColor.setAlpha(80);
}
bool OptionsDialog::eventFilter(QObject* obj, QEvent* event) {
if (event->type() == QEvent::Enter) {
auto* w = qobject_cast<QWidget*>(obj);
if (w && !w->graphicsEffect()) {
auto* shadow = new QGraphicsDropShadowEffect(w);
shadow->setBlurRadius(12);
shadow->setOffset(0, 0);
shadow->setColor(m_shadowColor);
w->setGraphicsEffect(shadow);
}
} else if (event->type() == QEvent::Leave) {
auto* w = qobject_cast<QWidget*>(obj);
if (w)
w->setGraphicsEffect(nullptr);
}
return QDialog::eventFilter(obj, event);
}
OptionsResult OptionsDialog::result() const {
@@ -272,6 +181,7 @@ OptionsResult OptionsDialog::result() const {
r.themeIndex = m_themeCombo->currentIndex();
r.fontName = m_fontCombo->currentText();
r.menuBarTitleCase = m_titleCaseCheck->isChecked();
r.showIcon = m_showIconCheck->isChecked();
r.safeMode = m_safeModeCheck->isChecked();
r.autoStartMcp = m_autoMcpCheck->isChecked();
return r;