src/ui/objecteditor.cpp

Tue, 15 Mar 2022 18:52:48 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Tue, 15 Mar 2022 18:52:48 +0200
changeset 183
97b591813c8b
parent 182
27fb1c3c9fbb
child 200
ca23936b455b
permissions
-rw-r--r--

- Add editors for string and bool properties
- Add invert action

#include <QCheckBox>
#include <QLineEdit>
#include <QFormLayout>
#include "objecteditor.h"
#include "document.h"
#include "modeleditor.h"
#include "widgets/colorbutton.h"
#include "widgets/colorindexinput.h"
#include "widgets/vec3editor.h"
#include "ui_objecteditor.h"

ObjectEditor::ObjectEditor(Document* document, const ldraw::id_t id) :
	QWidget{document},
	ui{*new Ui_ObjectEditor}, 
	document{document}
{
	this->ui.setupUi(this);
	this->setObjectId(id);
	QFormLayout* formLayout = new QFormLayout{ui.properties};
	this->ui.properties->setLayout(formLayout);
	for (const ldraw::Property property : ldraw::ALL_PROPERTIES)
	{
		QWidget* editorWidget = this->makeEditorWidgetForProperty(property);
		if (editorWidget != nullptr)
		{
			editorWidget->setProperty("_property_id", static_cast<int>(property));
			QLabel* propertyLabel = new QLabel{ldraw::traits(property).name.data()};
			formLayout->addRow(propertyLabel, editorWidget);
			this->propertyWidgets[property] = {propertyLabel, editorWidget};
		}
	}
	this->setObjectId(ldraw::NULL_ID);
}

ObjectEditor::~ObjectEditor()
{
	delete &this->ui;
}

QString titleCase(const QString& string)
{
	return string.left(1).toUpper() + string.mid(1);
}

void setValueToWidget(QWidget* widget, const QVariant& value)
{
	ColorIndexInput* colorIndexInput = qobject_cast<ColorIndexInput*>(widget);
	if (colorIndexInput != nullptr)
	{
		colorIndexInput->setSelectedColor(value.value<ldraw::Color>());
	}
	else
	{
		Vec3Editor* vec3Editor = qobject_cast<Vec3Editor*>(widget);
		if (vec3Editor != nullptr)
		{
			vec3Editor->setValue(value.value<glm::vec3>());
		}
		else
		{
			QCheckBox* checkBox = qobject_cast<QCheckBox*>(widget);
			if (checkBox != nullptr)
			{
				checkBox->setChecked(value.toBool());
			}
			else
			{
				QLineEdit* lineEdit = qobject_cast<QLineEdit*>(widget);
				if (lineEdit != nullptr)
				{
					lineEdit->setText(value.toString());
				}
			}
		}
	}
}

void ObjectEditor::setObjectId(const ldraw::id_t id)
{
	this->objectId = id;
	const ldraw::Object* object = this->document->getModel().get(id);
	this->ui.properties->setEnabled(object != nullptr);
	if (object != nullptr)
	{
		this->ui.typeNameLabel->setText("<b>" + titleCase(object->typeName()) + "</b>");
		this->ui.typeIconLabel->setPixmap(QPixmap{object->iconName()}.scaledToWidth(24));
		for (const ldraw::Property property : ldraw::ALL_PROPERTIES)
		{
			const QVariant value = object->getProperty(property);
			const auto it = this->propertyWidgets.find(property);
			if (it != this->propertyWidgets.end())
			{
				it->first->setEnabled(not value.isNull());
				it->second->setEnabled(not value.isNull());
				if (not value.isNull())
				{
					setValueToWidget(it->second, value);
				}
			}
		}
	}
	else
	{
		this->ui.typeNameLabel->setText(tr("No object selected"));
		this->ui.typeIconLabel->clear();
	}
}

void ObjectEditor::handleColorChange(ldraw::Color value)
{
	this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
}

void ObjectEditor::handleVec3Change(const glm::vec3 &value)
{
	this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
}

void ObjectEditor::handleBoolChange(bool value)
{
	this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
}

void ObjectEditor::handleStringChange(const QString &value)
{
	this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
}

QWidget* ObjectEditor::makeEditorWidgetForProperty(ldraw::Property property)
{
	QWidget* const parent = qobject_cast<QWidget*>(this->parent());
	if (ldraw::traits(property).type == qMetaTypeId<ldraw::Color>())
	{
		ColorIndexInput* colorWidget = new ColorIndexInput{this->document, {0}, parent};
		connect(colorWidget, &ColorIndexInput::colorChanged, this, &ObjectEditor::handleColorChange);
		return colorWidget;
	}
	else if (ldraw::traits(property).type == qMetaTypeId<glm::vec3>())
	{
		Vec3Editor* editor = new Vec3Editor{{}, parent};
		connect(editor, &Vec3Editor::valueChanged, this, &ObjectEditor::handleVec3Change);
		return editor;
	}
	else if (ldraw::traits(property).type == qMetaTypeId<bool>())
	{
		QCheckBox* editor = new QCheckBox{{}, parent};
		connect(editor, &QCheckBox::clicked, this, &ObjectEditor::handleBoolChange);
		return editor;
	}
	else if (ldraw::traits(property).type == qMetaTypeId<QString>())
	{
		QLineEdit* editor = new QLineEdit{{}, parent};
		connect(editor, &QLineEdit::textChanged, this, &ObjectEditor::handleStringChange);
		return editor;
	}
	else
	{
		return nullptr;
	}
}

void ObjectEditor::handlePropertyChange(QObject *caller, const QVariant &value)
{
	QVariant propertyVariant = caller->property("_property_id");
	if (not propertyVariant.isNull())
	{
		ldraw::Property const property = static_cast<ldraw::Property>(propertyVariant.toInt());
		this->document->editModel()->setObjectProperty(this->objectId, property, value);
	}
}

mercurial