src/widgets/colorselectdialog.cpp

changeset 94
164f53fb5921
child 115
ed884a2fb009
--- /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();
+}

mercurial