fix saving

Sun, 13 Mar 2022 14:51:39 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 13 Mar 2022 14:51:39 +0200
changeset 178
a23024fc98e0
parent 177
f69d53c053df
child 179
7b9b85b459de

fix saving
add color editing to object editor

CMakeLists.txt file | annotate | diff | comparison | revisions
src/colors.cpp file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/document.cpp file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/ui/objecteditor.cpp file | annotate | diff | comparison | revisions
src/ui/objecteditor.h file | annotate | diff | comparison | revisions
src/ui/polygonobjecteditor.cpp file | annotate | diff | comparison | revisions
src/ui/polygonobjecteditor.h file | annotate | diff | comparison | revisions
src/uiutilities.cpp file | annotate | diff | comparison | revisions
src/uiutilities.h file | annotate | diff | comparison | revisions
src/widgets/colorindexinput.cpp file | annotate | diff | comparison | revisions
src/widgets/colorindexinput.h file | annotate | diff | comparison | revisions
src/widgets/colorindexinput.ui file | annotate | diff | comparison | revisions
src/widgets/colorselectdialog.cpp file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Wed Mar 09 14:22:22 2022 +0200
+++ b/CMakeLists.txt	Sun Mar 13 14:51:39 2022 +0200
@@ -71,6 +71,7 @@
 	src/ui/objecteditor.cpp
 	src/ui/polygonobjecteditor.cpp
 	src/widgets/colorbutton.cpp
+	src/widgets/colorindexinput.cpp
 	src/widgets/colorselectdialog.cpp
 	src/widgets/doublespinbox.cpp
 	src/widgets/matrixeditor.cpp
@@ -130,6 +131,7 @@
 	src/ui/objecteditor.h
 	src/ui/polygonobjecteditor.h
 	src/widgets/colorbutton.h
+	src/widgets/colorindexinput.h
 	src/widgets/colorselectdialog.h
 	src/widgets/doublespinbox.h
 	src/widgets/matrixeditor.h
@@ -146,6 +148,7 @@
 	src/settingseditor/settingseditor.ui
 	src/ui/multiplyfactordialog.ui
 	src/widgets/colorselectdialog.ui
+	src/widgets/colorindexinput.ui
 	src/widgets/matrixeditor.ui
 	src/widgets/vec3editor.ui
 )
--- a/src/colors.cpp	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/colors.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -178,6 +178,19 @@
 	}
 }
 
+QColor ldraw::colorEdge(ldraw::Color color, const ldraw::ColorTable& colorTable)
+{
+	if (isDirectColor(color))
+	{
+		QColor const faceColor = directColorFace(color);
+		return (luma(faceColor) < 0.4) ? Qt::white : Qt::black;
+	}
+	else
+	{
+		return colorTable[color].faceColor;
+	}
+}
+
 /**
  * @brief Writes a color index into a @c QDataStream
  * @param stream
@@ -199,3 +212,15 @@
 {
 	return stream >> color.index;
 }
+
+QString ldraw::colorDisplayName(ldraw::Color color, const ldraw::ColorTable &colorTable)
+{
+	if (isDirectColor(color))
+	{
+		return directColorFace(color).name();
+	}
+	else
+	{
+		return colorTable[color].displayName;
+	}
+}
--- a/src/colors.h	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/colors.h	Sun Mar 13 14:51:39 2022 +0200
@@ -29,6 +29,8 @@
 	bool isDirectColor(Color color);
 	QColor directColorFace(Color color);
 	QColor colorFace(Color color, const ColorTable& colorTable);
+	QColor colorEdge(Color color, const ColorTable& colorTable);
+	QString colorDisplayName(Color color, const ColorTable& colorTable);
 }
 
 /**
--- a/src/document.cpp	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/document.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -33,9 +33,9 @@
 	const ldraw::ColorTable& colorTable,
 	QWidget* parent) :
 	QWidget{parent},
+	colorTable{colorTable},
 	model{model},
 	documents{documents},
-	colorTable{colorTable},
 	vertexMap{model},
 	renderer{new Canvas{model, documents, colorTable, this}},
 	ui{*new Ui::Document},
@@ -234,7 +234,7 @@
 	this->renderer->adjustGridToView();
 }
 
-const Model &Document::getModel()
+const Model &Document::getModel() const
 {
 	return *this->model;
 }
--- a/src/document.h	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/document.h	Sun Mar 13 14:51:39 2022 +0200
@@ -48,8 +48,9 @@
 	void applyToVertices(VertexMap::ApplyFunction fn) const;
 	void handleKeyPress(QKeyEvent* event);
 	void adjustGridToView();
-	const Model& getModel();
+	const Model& getModel() const;
 	const QSet<ldraw::id_t> selectedObjects() const;
+	const ldraw::ColorTable& colorTable;
 Q_SIGNALS:
 	void newStatusText(const QString& newStatusText);
 	void splitterChanged();
@@ -62,7 +63,6 @@
 	void selectTool(class BaseTool* tool);
 	Model* model;
 	DocumentManager* const documents;
-	const ldraw::ColorTable& colorTable;
 	VertexMap vertexMap;
 	Canvas* renderer;
 	Ui::Document& ui;
--- a/src/mainwindow.cpp	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/mainwindow.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -224,6 +224,11 @@
 	return qobject_cast<Document*>(this->ui->tabs->currentWidget());
 }
 
+const Document* MainWindow::currentDocument() const
+{
+	return qobject_cast<const Document*>(this->ui->tabs->currentWidget());
+}
+
 void MainWindow::handleDocumentSplitterChange()
 {
 	Document* currentDocument = this->currentDocument();
@@ -285,24 +290,27 @@
 {
 	if (this->currentDocument() != nullptr)
 	{
-		const ModelId modelId = {0};
-		const QString* path = this->documents.modelPath(modelId);
-		if (path == nullptr or path->isEmpty())
+		const std::optional<ModelId> modelId = this->findCurrentModelId();
+		if (modelId.has_value())
 		{
-			this->actionSaveAs();
-		}
-		else
-		{
-			QString error;
-			QTextStream errorStream{&error};
-			const bool succeeded = this->documents.saveModel(modelId, errorStream);
-			if (not succeeded)
+			const QString* path = this->documents.modelPath(*modelId);
+			if (path == nullptr or path->isEmpty())
 			{
-				QMessageBox::critical(this, tr("Save error"), error);
+				this->actionSaveAs();
 			}
 			else
 			{
-				this->addRecentlyOpenedFile(*path);
+				QString error;
+				QTextStream errorStream{&error};
+				const bool succeeded = this->documents.saveModel(*modelId, errorStream);
+				if (not succeeded)
+				{
+					QMessageBox::critical(this, tr("Save error"), error);
+				}
+				else
+				{
+					this->addRecentlyOpenedFile(*path);
+				}
 			}
 		}
 	}
@@ -315,22 +323,25 @@
 {
 	if (this->currentDocument() != nullptr)
 	{
-		const ModelId modelId = {0};
-		const QString* pathPtr = this->documents.modelPath(modelId);
-		QString defaultPath = (pathPtr != nullptr) ? *pathPtr : "";
-		const QString newPath = QFileDialog::getSaveFileName(
-			this,
-			tr("Save as…"),
-			QFileInfo{defaultPath}.absoluteDir().path(), 
-			tr("LDraw files (*.ldr *dat);;All files (*)")
-		);
-		if (not newPath.isEmpty())
+		const std::optional<ModelId> modelId = this->findCurrentModelId();
+		if (modelId.has_value())
 		{
-			QString error;
-			QTextStream errorStream{&error};
-			this->documents.setModelPath(modelId, newPath, this->libraries, errorStream);
-			this->ui->tabs->setTabText(this->ui->tabs->currentIndex(), QFileInfo{newPath}.fileName());
-			this->actionSave();
+			const QString* pathPtr = this->documents.modelPath(*modelId);
+			QString defaultPath = (pathPtr != nullptr) ? *pathPtr : "";
+			const QString newPath = QFileDialog::getSaveFileName(
+				this,
+				tr("Save as…"),
+				QFileInfo{defaultPath}.absoluteDir().path(), 
+				tr("LDraw files (*.ldr *dat);;All files (*)")
+			);
+			if (not newPath.isEmpty())
+			{
+				QString error;
+				QTextStream errorStream{&error};
+				this->documents.setModelPath(*modelId, newPath, this->libraries, errorStream);
+				this->ui->tabs->setTabText(this->ui->tabs->currentIndex(), QFileInfo{newPath}.fileName());
+				this->actionSave();
+			}
 		}
 	}
 }
@@ -397,6 +408,19 @@
 	}
 }
 
+std::optional<ModelId> MainWindow::findCurrentModelId() const
+{
+	const Document* document = this->currentDocument();
+	if (document != nullptr)
+	{
+		return this->documents.findIdForModel(&document->getModel());
+	}
+	else
+	{
+		return {};
+	}
+}
+
 void MainWindow::changeEvent(QEvent* event)
 {
 	if (event != nullptr)
--- a/src/mainwindow.h	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/mainwindow.h	Sun Mar 13 14:51:39 2022 +0200
@@ -78,5 +78,7 @@
 	static QString pathToTranslation(const QString& localeCode);
 	void loadColors();
 	Document *currentDocument();
+	const Document *currentDocument() const;
 	void closeDocument(Document* document);
+	std::optional<ModelId> findCurrentModelId() const;
 };
--- a/src/ui/objecteditor.cpp	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/ui/objecteditor.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -1,15 +1,28 @@
 #include <QVBoxLayout>
+#include <QFormLayout>
+#include <QPushButton>
 #include <QLabel>
+#include <QSpinBox>
 #include "objecteditor.h"
 #include "document.h"
+#include "modeleditor.h"
+#include "widgets/colorbutton.h"
+#include "widgets/colorindexinput.h"
+
+template<ldraw::Property property>
+static void makeColorEditor()
+{
+	QString propertyName = ldraw::PropertyTraits<property>::name;
+}
 
 ObjectEditor::ObjectEditor(Document* document, const ldraw::id_t id) :
 	QWidget{document},
 	document{document},
+	formContainer{new QWidget{this}},
 	objectTypeNameLabel{new QLabel{this}},
 	objectTypeIconLabel{new QLabel{this}}
 {
-	this->setObjectId(id);
+	this->polygonEditor.emplace(this->document, id);
 	this->setLayout(new QVBoxLayout{this});
 	QWidget* objectTitleLayoutContainer = new QWidget{this};
 	QLayout* objectTitleLayout = new QHBoxLayout{objectTitleLayoutContainer};
@@ -18,6 +31,31 @@
 	objectTitleLayout->addWidget(this->objectTypeNameLabel);
 	objectTitleLayout->addWidget(new QSplitter{Qt::Horizontal, this});
 	this->layout()->addWidget(objectTitleLayoutContainer);
+	this->layout()->addWidget(&*this->polygonEditor);
+	this->layout()->addWidget(formContainer);
+	this->setObjectId(id);
+	
+	QWidget* const parent = this->formContainer;
+	QFormLayout* formLayout = new QFormLayout{parent};
+	this->formContainer->setLayout(formLayout);
+	QLabel* colorLabel = new QLabel{"Color", parent};
+	ColorIndexInput* colorWidget = new ColorIndexInput{document, {0}, parent};
+	formLayout->addRow(colorLabel, colorWidget);
+	connect(colorWidget, &ColorIndexInput::colorChanged, [this](ldraw::Color color)
+	{
+		const QModelIndex index = this->document->getModel().find(this->objectId);
+		if (index.isValid())
+		{
+			this->document->editModel()->modifyObjectAt<ldraw::ColoredObject>(
+				index.row(),
+				[color](ldraw::ColoredObject* object)
+				{
+					object->colorIndex = color;
+				}
+			);
+		}
+	});
+	this->propertyWidgets[ldraw::Property::Color] = {colorLabel, colorWidget};
 }
 
 QString titleCase(const QString& string)
@@ -29,24 +67,42 @@
 {
 	this->objectId = id;
 	const ldraw::Object* object = this->document->getModel().get(id);
-	if (object != nullptr and object->numPoints() > 0)
+	this->clear();
+	if (object != nullptr)
 	{
 		this->objectTypeNameLabel->setText("<b>" + titleCase(object->typeName()) + "</b>");
 		this->objectTypeIconLabel->setPixmap(QPixmap{object->iconName()}.scaledToWidth(24));
-		if (not this->polygonEditor.has_value())
+		if (object->numPoints() > 0)
 		{
-			this->polygonEditor.emplace(this->document, id);
-			this->layout()->addWidget(&*this->polygonEditor);
+			this->polygonEditor->setObjectId(id);
 		}
 		else
 		{
-			this->polygonEditor->setObjectId(id);
+			this->polygonEditor->clear();
+		}
+		constexpr ldraw::Property prop = ldraw::Property::Color;
+		QVariant color = object->getProperty(prop);
+		this->propertyWidgets[prop].first->setVisible(not color.isNull());
+		this->propertyWidgets[prop].second->setVisible(not color.isNull());
+		if (not color.isNull())
+		{
+			static_cast<ColorIndexInput*>(this->propertyWidgets[prop].second)->setSelectedColor(color.value<ldraw::Color>());
 		}
 	}
 	else
 	{
-		this->objectTypeNameLabel->clear();
-		this->objectTypeIconLabel->clear();
-		this->polygonEditor.reset();
+		for (auto& pair : this->propertyWidgets)
+		{
+			pair.first->setVisible(false);
+			pair.second->setVisible(false);
+		}
 	}
 }
+
+void ObjectEditor::clear()
+{
+	this->objectTypeNameLabel->clear();
+	this->objectTypeIconLabel->clear();
+	this->polygonEditor->clear();
+	delete this->formContainer->layout();
+}
--- a/src/ui/objecteditor.h	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/ui/objecteditor.h	Sun Mar 13 14:51:39 2022 +0200
@@ -12,10 +12,13 @@
 public:
 	explicit ObjectEditor(Document* document, ldraw::id_t id = ldraw::NULL_ID);
 	void setObjectId(ldraw::id_t id);
+	void clear();
 private:
 	Document* const document;
 	ldraw::id_t objectId = ldraw::NULL_ID;
 	std::optional<PolygonObjectEditor> polygonEditor;
+	QWidget* formContainer;
 	class QLabel* objectTypeNameLabel;
 	class QLabel* objectTypeIconLabel;
+	QMap<ldraw::Property, QPair<QWidget*, QWidget*>> propertyWidgets;
 };
--- a/src/ui/polygonobjecteditor.cpp	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/ui/polygonobjecteditor.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -14,6 +14,7 @@
 	storedObjectId{ldraw::NULL_ID.value}
 {
 	this->splitter.emplace(Qt::Vertical, this);
+	this->buildWidgets();
 	this->setObjectId(id);
 }
 
@@ -30,44 +31,60 @@
 void PolygonObjectEditor::setObjectId(ldraw::id_t id)
 {
 	this->storedObjectId = id;
-	this->buildWidgets();
+	const QModelIndex index = this->document->getModel().find(this->objectId());
+	if (index.isValid())
+	{
+		for (int n : {0, 1, 2, 3})
+		{
+			const ldraw::Object* const object = this->document->getModel()[index.row()];
+			const ldraw::Property property = ldraw::pointProperty(n);
+			const QVariant value = object->getProperty(property);
+			this->widgets[n]->setVisible(value.isValid());
+			this->formLayout->itemAt(n, QFormLayout::LabelRole)->widget()->setVisible(value.isValid());
+			if (value.isValid())
+			{
+				this->widgets[n]->setValue(value.value<glm::vec3>());
+			}
+		}
+	}
+	else
+	{
+		for (int n : {0, 1, 2, 3})
+		{
+			this->widgets[n]->setVisible(false);
+			this->formLayout->itemAt(n, QFormLayout::LabelRole)->widget()->setVisible(false);
+		}
+	}
+}
+
+void PolygonObjectEditor::clear()
+{
+	this->setObjectId(ldraw::NULL_ID);
 }
 
 void PolygonObjectEditor::buildWidgets()
 {
-	this->widgets.clear();
-	delete this->layout();
-	QFormLayout* layout = new QFormLayout{this};
-	this->setLayout(layout);
+	this->formLayout = new QFormLayout{this};
+	this->setLayout(this->formLayout);
 	for (int n : {0, 1, 2, 3})
 	{
 		this->setupPointWidget(n);
 	}
-	for (std::unique_ptr<QWidget>& widget : this->widgets)
+	for (std::unique_ptr<Vec3Editor>& widget : this->widgets)
 	{
 		const QString label = widget->property(LABEL_NAME).toString();
-		layout->addRow(label, widget.get());
+		this->formLayout->addRow(label, widget.get());
 	}
-	layout->addRow("", &*this->splitter);
+	this->formLayout->addRow("", &*this->splitter);
 }
 
 void PolygonObjectEditor::setupPointWidget(int n)
 {
-	const QModelIndex index = this->document->getModel().find(this->objectId());
-	if (index.isValid())
-	{
-		const ldraw::Object* const object = this->document->getModel()[index.row()];
-		const ldraw::Property property = ldraw::pointProperty(n);
-		const QVariant value = object->getProperty(property);
-		if (value.isValid())
-		{
-			std::unique_ptr<Vec3Editor> editor = std::make_unique<Vec3Editor>(value.value<glm::vec3>(), this);
-			QObject::connect(editor.get(), &Vec3Editor::valueChanged, this, &PolygonObjectEditor::pointChanged);
-			editor->setProperty(INDEX_NAME, QVariant::fromValue(n));
-			editor->setProperty(LABEL_NAME, &ldraw::traits(property).name[0]);
-			this->widgets.push_back(std::move(editor));
-		}
-	}
+	std::unique_ptr<Vec3Editor> editor = std::make_unique<Vec3Editor>(glm::vec3{}, this);
+	QObject::connect(editor.get(), &Vec3Editor::valueChanged, this, &PolygonObjectEditor::pointChanged);
+	editor->setProperty(INDEX_NAME, QVariant::fromValue(n));
+	editor->setProperty(LABEL_NAME, &ldraw::traits(ldraw::pointProperty(n)).name[0]);
+	this->widgets.push_back(std::move(editor));
 }
 
 void PolygonObjectEditor::pointChanged(const glm::vec3& value)
--- a/src/ui/polygonobjecteditor.h	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/ui/polygonobjecteditor.h	Sun Mar 13 14:51:39 2022 +0200
@@ -13,12 +13,14 @@
 	~PolygonObjectEditor();
 	ldraw::id_t objectId() const;
 	void setObjectId(ldraw::id_t id);
+	void clear();
 private:
 	void buildWidgets();
 	void setupPointWidget(int n);
 	Q_SLOT void pointChanged(const glm::vec3& value);
 	Document* document;
 	ldraw::id_t storedObjectId;
-	std::vector<std::unique_ptr<QWidget>> widgets;
+	std::vector<std::unique_ptr<Vec3Editor>> widgets;
 	std::optional<QSplitter> splitter;
+	class QFormLayout* formLayout = nullptr;
 };
--- a/src/uiutilities.cpp	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/uiutilities.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -16,6 +16,7 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QStyleFactory>
 #include "uiutilities.h"
 
 QVector<QAction*> uiutilities::collectActions(QObject* subject)
@@ -42,3 +43,12 @@
 	}
 	return result;
 }
+
+void uiutilities::colorizeWidget(QWidget* widget, const QColor& color)
+{
+	QPalette pal{color};
+	widget->setPalette(pal);
+	widget->setAutoFillBackground(true);
+	widget->setStyle(QStyleFactory::create("Fusion"));
+	widget->update();
+}
\ No newline at end of file
--- a/src/uiutilities.h	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/uiutilities.h	Sun Mar 13 14:51:39 2022 +0200
@@ -24,4 +24,5 @@
 	using KeySequenceMap = QMap<QString, QKeySequence>;
 	QVector<QAction*> collectActions(QObject* subject);
 	KeySequenceMap makeKeySequenceMap(const QVector<QAction*>& actions);
+	void colorizeWidget(QWidget* widget, const QColor& color);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/colorindexinput.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -0,0 +1,43 @@
+#include "colorindexinput.h"
+#include "ui_colorindexinput.h"
+#include "colorselectdialog.h"
+#include "uiutilities.h"
+
+ColorIndexInput::ColorIndexInput(Document *document, ldraw::Color color, QWidget *parent) :
+	QWidget{parent},
+	document{document},
+	ui{*new Ui_ColorIndexInput}
+{
+	this->ui.setupUi(this);
+	connect(this->ui.button, &QPushButton::clicked, [this]()
+	{
+		ColorSelectDialog dialog{this->document->colorTable, this->document};
+		const int result = dialog.exec();
+		if (result == QDialog::Accepted)
+		{
+			this->ui.index->setValue(dialog.currentColor().index);
+		}
+	});
+	connect(this->ui.index, qOverload<int>(&QSpinBox::valueChanged), [this](int value)
+	{
+		this->ui.button->setText(ldraw::colorDisplayName({value}, this->document->colorTable));
+		uiutilities::colorizeWidget(this->ui.button, ldraw::colorFace({value}, this->document->colorTable));
+		Q_EMIT this->colorChanged({value});
+	});
+	this->ui.index->setValue(color.index);
+}
+
+ColorIndexInput::~ColorIndexInput()
+{
+	delete &this->ui;
+}
+
+ldraw::Color ColorIndexInput::selectedColor() const
+{
+	return {this->ui.index->value()};
+}
+
+void ColorIndexInput::setSelectedColor(ldraw::Color color)
+{
+	this->ui.index->setValue(color.index);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/colorindexinput.h	Sun Mar 13 14:51:39 2022 +0200
@@ -0,0 +1,17 @@
+#pragma once
+#include "document.h"
+
+class ColorIndexInput : public QWidget
+{
+	Q_OBJECT
+public:
+	ColorIndexInput(Document *document, ldraw::Color color = ldraw::MAIN_COLOR, QWidget *parent = nullptr);
+	~ColorIndexInput();
+	ldraw::Color selectedColor() const;
+	void setSelectedColor(ldraw::Color color);
+Q_SIGNALS:
+	void colorChanged(ldraw::Color color);
+private:
+	Document* const document;
+	class Ui_ColorIndexInput& ui;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/colorindexinput.ui	Sun Mar 13 14:51:39 2022 +0200
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ColorIndexInput</class>
+ <widget class="QWidget" name="ColorIndexInput">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>370</width>
+    <height>47</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout_2">
+   <item>
+    <widget class="QSpinBox" name="index">
+     <property name="suffix">
+      <string/>
+     </property>
+     <property name="maximum">
+      <number>2147483647</number>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QPushButton" name="button">
+     <property name="text">
+      <string>…</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <spacer name="horizontalSpacer">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>40</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- a/src/widgets/colorselectdialog.cpp	Wed Mar 09 14:22:22 2022 +0200
+++ b/src/widgets/colorselectdialog.cpp	Sun Mar 13 14:51:39 2022 +0200
@@ -1,7 +1,9 @@
 #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},
@@ -29,14 +31,6 @@
 	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());
@@ -48,8 +42,9 @@
 		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);
-		button->setStyleSheet(styleSheetForColor(colordef.faceColor));
+		uiutilities::colorizeWidget(button, ldraw::colorFace({index}, colorTable));
 		button->setProperty("_colorIndex", index);
 		button->setCheckable(true);
 		connect(button, &QAbstractButton::clicked, this, &ColorSelectDialog::handleButtonClick);
@@ -95,17 +90,8 @@
 
 void ColorSelectDialog::updateSelectedColorTexts()
 {
-	if (ldraw::isDirectColor(this->selectedColor))
-	{
-		this->ui.selectedColorName->setText(ldraw::directColorFace(this->selectedColor).name());
-	}
-	else
-	{
-		const ldraw::ColorDefinition& colordef = this->colorTable[this->selectedColor];
-		this->ui.selectedColorName->setText(colordef.displayName);
-	}
-	const QColor colorFace = ldraw::colorFace(this->selectedColor, this->colorTable);
-	this->ui.selectedColorName->setStyleSheet(styleSheetForColor(colorFace));
+	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)
 	{
@@ -157,3 +143,8 @@
 	this->selectedColor = color;
 	this->updateSelectedColorTexts();
 }
+
+ldraw::Color ColorSelectDialog::currentColor() const
+{
+	return this->selectedColor;
+}

mercurial