widgets/matrixeditor.cpp

Sun, 09 Apr 2023 15:59:08 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Sun, 09 Apr 2023 15:59:08 +0300
changeset 362
e1d646a4cbd8
parent 264
76a025db4948
permissions
-rw-r--r--

Extracted the state of the program into a MainState structure, and extracted local functions of main() into static functions.
I was planning to make the core logic and state of the program into a Main class, which would be a QObject that would
have lots of signals and slots, but it looks like this works even without it

#include <ui_matrixeditor.h>
#include "widgets/matrixeditor.h"
#include "widgets/multiplyfactordialog.h"

constexpr char BUTTON_COLUMN_PROPERTY[] = "_ldforge_column";

MatrixEditor::MatrixEditor(const glm::mat4 value, QWidget* parent) :
	QWidget(parent),
	ui(new Ui::MatrixEditor)
{
	ui->setupUi(this);
	for (int column = 0; column < (int)glm::countof(this->spinboxes); column += 1)
	{
		for (int row = 0; row < (int)glm::countof(this->spinboxes[0]); row += 1)
		{
			const QString name = QStringLiteral("cell%1%2").arg(column).arg(row);
			QDoubleSpinBox** spinbox = &this->spinboxes[column][row];
			*spinbox = this->findChild<QDoubleSpinBox*>(name);
			connect(*spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), [&]()
			{
				Q_EMIT this->valueChanged(this->value());
			});
			Q_ASSERT(*spinbox != nullptr);
		}
		const QString multiplyButtonName = QStringLiteral("multiply%1").arg(column);
		QAbstractButton* button = this->findChild<QAbstractButton*>(multiplyButtonName);
		button->setProperty(BUTTON_COLUMN_PROPERTY, column);
		connect(button, &QAbstractButton::clicked, this, &MatrixEditor::multiplyButtonPressed);
	}
	this->setValue(value);
}

MatrixEditor::MatrixEditor(QWidget *parent) :
	MatrixEditor{glm::mat4{1}, parent}
{
}

MatrixEditor::~MatrixEditor()
{
	delete ui;
}

glm::mat4 MatrixEditor::value() const
{
	glm::mat4 result{1};
	for (int column = 0; column < (int)glm::countof(this->spinboxes); column += 1)
	{
		for (int row = 0; row < (int)glm::countof(this->spinboxes[0]); row += 1)
		{
			result[column][row] = static_cast<float>(this->spinboxes[column][row]->value());
		}
	}
	return result;
}

void MatrixEditor::setValue(const glm::mat4& value)
{
	for (int column = 0; column < (int)glm::countof(this->spinboxes); column += 1)
	{
		for (int row = 0; row < (int)glm::countof(this->spinboxes[0]); row += 1)
		{
			QDoubleSpinBox* spinbox = this->spinboxes[column][row];
			QSignalBlocker blocker{spinbox};
			spinbox->setValue(value[column][row]);
		}
	}
}

void MatrixEditor::multiplyButtonPressed()
{
	QAbstractButton* button = qobject_cast<QAbstractButton*>(this->sender());
	if (button != nullptr)
	{
		bool ok;
		const int column = button->property(BUTTON_COLUMN_PROPERTY).toInt(&ok);
		if (ok and column >= 0 and column < this->matrixSize())
		{
			glm::mat4 newValue = this->value();
			MultiplyFactorDialog dialog{newValue[column], this};
			const int result = dialog.exec();
			if (result == QDialog::Accepted)
			{
				newValue[column] = glm::vec4{dialog.value(), (column == 3) ? 1 : 0};
				this->setValue(newValue);
				Q_EMIT valueChanged(newValue);
			}
		}
	}
}

mercurial