mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
Add theme system with Reclass Dark and Warm built-in themes
Replaces ~40 hardcoded color values with 27 semantic color roles. Adds ThemeManager singleton, theme editor dialog, View > Theme menu, JSON persistence for user themes, and fixes inline edit selection color from blue #264f78 to #2b2b2b.
This commit is contained in:
95
src/themes/themeeditor.cpp
Normal file
95
src/themes/themeeditor.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "themeeditor.h"
|
||||
#include <QFormLayout>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QColorDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
|
||||
namespace rcx {
|
||||
|
||||
ThemeEditor::ThemeEditor(const Theme& theme, QWidget* parent)
|
||||
: QDialog(parent), m_theme(theme)
|
||||
{
|
||||
setWindowTitle("Edit Theme");
|
||||
setMinimumWidth(320);
|
||||
|
||||
auto* form = new QFormLayout;
|
||||
|
||||
// Name field
|
||||
auto* nameEdit = new QLineEdit(m_theme.name);
|
||||
connect(nameEdit, &QLineEdit::textChanged, this, [this](const QString& t) {
|
||||
m_theme.name = t;
|
||||
});
|
||||
form->addRow("Name", nameEdit);
|
||||
|
||||
// Color swatches
|
||||
struct FieldDef { const char* label; QColor Theme::*ptr; };
|
||||
const FieldDef fields[] = {
|
||||
{"Background", &Theme::background},
|
||||
{"Background Alt", &Theme::backgroundAlt},
|
||||
{"Surface", &Theme::surface},
|
||||
{"Border", &Theme::border},
|
||||
{"Button", &Theme::button},
|
||||
{"Text", &Theme::text},
|
||||
{"Text Dim", &Theme::textDim},
|
||||
{"Text Muted", &Theme::textMuted},
|
||||
{"Text Faint", &Theme::textFaint},
|
||||
{"Hover", &Theme::hover},
|
||||
{"Selected", &Theme::selected},
|
||||
{"Selection", &Theme::selection},
|
||||
{"Keyword", &Theme::syntaxKeyword},
|
||||
{"Number", &Theme::syntaxNumber},
|
||||
{"String", &Theme::syntaxString},
|
||||
{"Comment", &Theme::syntaxComment},
|
||||
{"Preprocessor", &Theme::syntaxPreproc},
|
||||
{"Type", &Theme::syntaxType},
|
||||
{"Hover Span", &Theme::indHoverSpan},
|
||||
{"Cmd Pill", &Theme::indCmdPill},
|
||||
{"Data Changed", &Theme::indDataChanged},
|
||||
{"Hint Green", &Theme::indHintGreen},
|
||||
{"Pointer Marker", &Theme::markerPtr},
|
||||
{"Cycle Marker", &Theme::markerCycle},
|
||||
{"Error Marker", &Theme::markerError},
|
||||
};
|
||||
|
||||
for (const auto& f : fields) {
|
||||
auto* btn = new QPushButton;
|
||||
btn->setFixedSize(60, 24);
|
||||
btn->setCursor(Qt::PointingHandCursor);
|
||||
SwatchEntry entry{f.label, f.ptr, btn};
|
||||
m_swatches.append(entry);
|
||||
updateSwatch(m_swatches.last());
|
||||
|
||||
int idx = m_swatches.size() - 1;
|
||||
connect(btn, &QPushButton::clicked, this, [this, idx]() {
|
||||
pickColor(m_swatches[idx]);
|
||||
});
|
||||
form->addRow(f.label, btn);
|
||||
}
|
||||
|
||||
auto* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
layout->addLayout(form);
|
||||
layout->addWidget(buttons);
|
||||
}
|
||||
|
||||
void ThemeEditor::updateSwatch(SwatchEntry& entry) {
|
||||
QColor c = m_theme.*entry.field;
|
||||
entry.button->setStyleSheet(QStringLiteral(
|
||||
"QPushButton { background: %1; border: 1px solid #555; border-radius: 3px; }")
|
||||
.arg(c.name()));
|
||||
entry.button->setToolTip(c.name());
|
||||
}
|
||||
|
||||
void ThemeEditor::pickColor(SwatchEntry& entry) {
|
||||
QColor c = QColorDialog::getColor(m_theme.*entry.field, this, entry.label);
|
||||
if (c.isValid()) {
|
||||
m_theme.*entry.field = c;
|
||||
updateSwatch(entry);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rcx
|
||||
Reference in New Issue
Block a user