--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/colorselectdialog.cpp Mon Sep 21 19:48:18 2020 +0300 @@ -0,0 +1,158 @@ +#include <QColorDialog> +#include <QTableView> +#include "colorselectdialog.h" +#include "ui_colorselectdialog.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>()}; +} + +QString styleSheetForColor(const QColor& color) +{ + QColor const textColor = (luma(color) < 0.4) ? Qt::white : Qt::black; + return QString{"background-color: %1; color: %2;"} + .arg(color.name()) + .arg(textColor.name()); +} + +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::ColorTable::ColorDefinition& colordef = iterator->second; + QPushButton* const button = new QPushButton{QString::number(index), this}; + button->setToolTip(colordef.displayName); + button->setStyleSheet(styleSheetForColor(colordef.faceColor)); + 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() +{ + if (ldraw::isDirectColor(this->selectedColor)) + { + this->ui.selectedColorName->setText(ldraw::directColorFace(this->selectedColor).name()); + } + else + { + const ldraw::ColorTable::ColorDefinition& colordef = this->colorTable[this->selectedColor]; + this->ui.selectedColorName->setText(colordef.displayName); + } + this->ui.selectedColorName->setStyleSheet(styleSheetForColor(ldraw::colorFace(this->selectedColor, this->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::ColorTable::ColorDefinition& colordef = this->colorTable[color]; + return colordef.displayName.contains(filterText, Qt::CaseInsensitive); + } +} + +void ColorSelectDialog::setCurrentColor(ldraw::Color color) +{ + this->selectedColor = color; + this->updateSelectedColorTexts(); +}