Sun, 13 Mar 2022 18:46:10 +0200
Handle properties in a generic manner in the object editor
#include <QColorDialog> #include <QTableView> #include <QStyleFactory> #include "colorselectdialog.h" #include "ui_colorselectdialog.h" #include "uiutilities.h" ColorSelectDialog::ColorSelectDialog(const ldraw::ColorTable& colorTable, QWidget *parent) : QDialog{parent}, ui{*new Ui_ColorSelectDialog}, colorTable{colorTable} { this->ui.setupUi(this); this->makeColorButtons(); connect(this->ui.filter, &QLineEdit::textEdited, this, &ColorSelectDialog::populateColors); this->updateSelectedColorTexts(); connect(this->ui.colorIndex, qOverload<int>(&QSpinBox::valueChanged), this, &ColorSelectDialog::spinboxEdited); connect(this->ui.directColorButton, &QPushButton::clicked, this, &ColorSelectDialog::chooseDirectColor); connect(this->ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(this->ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); this->populateColors(); } ColorSelectDialog::~ColorSelectDialog() { delete &this->ui; } ldraw::Color colorFromButton(QAbstractButton* button) { return {button->property("_colorIndex").value<qint32>()}; } void ColorSelectDialog::makeColorButtons() { this->buttons.reserve(this->colorTable.size()); for ( auto iterator = std::begin(this->colorTable); iterator != std::end(this->colorTable); ++iterator ) { const qint32 index = iterator->first; const ldraw::ColorDefinition& colordef = iterator->second; QPushButton* const button = new QPushButton{QString::number(index), this}; button->setMinimumSize({40, 40}); button->setToolTip(colordef.displayName); uiutilities::colorizeWidget(button, ldraw::colorFace({index}, colorTable)); button->setProperty("_colorIndex", index); button->setCheckable(true); connect(button, &QAbstractButton::clicked, this, &ColorSelectDialog::handleButtonClick); this->buttons.push_back(button); } std::sort( std::begin(this->buttons), std::end(this->buttons), [](QAbstractButton* button_1, QAbstractButton* button_2) { return colorFromButton(button_1) < colorFromButton(button_2); } ); } void ColorSelectDialog::populateColors() { delete this->ui.colorFrame->layout(); if (this->buttons.size() > 0) { QGridLayout* gridLayout = new QGridLayout{}; this->ui.colorFrame->setLayout(gridLayout); const int columnsPerRow = 8; int i = 0; for ( auto iterator = std::begin(this->buttons); iterator != std::end(this->buttons); ++iterator ) { QPushButton* const button = *iterator; const bool filtered = this->filterColor(colorFromButton(button)); button->setVisible(filtered); if (filtered) { const int row = i / columnsPerRow; const int column = i % columnsPerRow; gridLayout->addWidget(button, row, column); i += 1; } } } } void ColorSelectDialog::updateSelectedColorTexts() { this->ui.selectedColorName->setText(ldraw::colorDisplayName(this->selectedColor, this->colorTable)); uiutilities::colorizeWidget(this->ui.selectedColorName, ldraw::colorFace(this->selectedColor, colorTable)); this->ui.colorIndex->setValue(this->selectedColor.index); for (QPushButton* button : this->buttons) { ldraw::Color buttonColor = colorFromButton(button); button->setChecked(buttonColor == this->selectedColor); } } void ColorSelectDialog::handleButtonClick() { QAbstractButton* button = qobject_cast<QAbstractButton*>(this->sender()); if (button != nullptr) { this->setCurrentColor(colorFromButton(button)); } } void ColorSelectDialog::spinboxEdited() { this->setCurrentColor(ldraw::Color{this->ui.colorIndex->value()}); } void ColorSelectDialog::chooseDirectColor() { QColorDialog dialog; dialog.setCurrentColor(ldraw::colorFace(this->selectedColor, this->colorTable)); if (dialog.exec()) { this->setCurrentColor(ldraw::directColor(dialog.selectedColor())); } } bool ColorSelectDialog::filterColor(ldraw::Color color) const { const QString& filterText = this->ui.filter->text(); if (filterText.isEmpty()) { return true; } else { const ldraw::ColorDefinition& colordef = this->colorTable[color]; return colordef.displayName.contains(filterText, Qt::CaseInsensitive); } } void ColorSelectDialog::setCurrentColor(ldraw::Color color) { this->selectedColor = color; this->updateSelectedColorTexts(); } ldraw::Color ColorSelectDialog::currentColor() const { return this->selectedColor; }