Sun, 09 Apr 2023 15:59:08 +0300
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); } } } }