summaryrefslogtreecommitdiff
path: root/src/mainwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainwindow.cpp')
-rw-r--r--src/mainwindow.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
new file mode 100644
index 0000000..66274c1
--- /dev/null
+++ b/src/mainwindow.cpp
@@ -0,0 +1,303 @@
+#include "mainwindow.h"
+
+// qt
+#include <QComboBox>
+#include <QDoubleSpinBox>
+#include <QFormLayout>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QOpenGLWidget>
+#include <QShortcut>
+#include <QStyle>
+
+// optical design
+#include "graphicsscene.h"
+#include "graphicsview.h"
+#include "opticaldesign.h"
+
+MainWindow::MainWindow(QWidget* parent)
+ : QMainWindow{parent}
+ , m_scene{new GraphicsScene{this}}
+ , m_view{new GraphicsView{m_scene, this}}
+ , m_design{new OpticalDesign{this}}
+{
+ initUi();
+ initShortcuts();
+}
+
+MainWindow::~MainWindow() {}
+
+void MainWindow::initUi()
+{
+ setMinimumSize({640, 480});
+
+ qDebug() << "global settings path:"
+ << GlobalSettings::instance()->fileName();
+
+ const auto mainWidget = new QWidget{this};
+
+ const auto mainLayout = new QHBoxLayout{mainWidget};
+ mainWidget->setLayout(mainLayout);
+ // addLayout sets parent below
+ const auto leftLayout = new QFormLayout{};
+ leftLayout->setLabelAlignment(Qt::AlignVCenter | Qt::AlignRight);
+ mainLayout->addLayout(leftLayout);
+
+ // left panel
+ const auto connectWidgetToProperty = [this](
+ const auto widget,
+ const auto widgetSignal,
+ const auto widgetSetter,
+ const auto propertyObject,
+ const auto propertySignal,
+ const auto propertySetter
+ ) {
+ connect(widget, widgetSignal, propertyObject, propertySetter);
+ connect(propertyObject, propertySignal, widget, widgetSetter);
+ };
+
+ using MinValue = double;
+ using MaxValue = double;
+ using SingleStep = double;
+ auto addFormPair = [this, leftLayout, connectWidgetToProperty](
+ const QString text,
+ const auto propertySignal,
+ const auto propertyGetter,
+ const auto propertySetter,
+ const MinValue minValue,
+ const MaxValue maxValue,
+ const SingleStep singleStep = 0.1
+ ) {
+ const auto spinBox = new QDoubleSpinBox{centralWidget()};
+ spinBox->setRange(minValue, maxValue);
+ spinBox->setSingleStep(singleStep);
+ spinBox->setValue(std::bind(propertyGetter, m_design)());
+
+ connect(
+ spinBox,
+ &QDoubleSpinBox::valueChanged,
+ m_design,
+ propertySetter
+ );
+ connect(m_design, propertySignal, spinBox, &QDoubleSpinBox::setValue);
+ connect(
+ m_design,
+ propertySignal,
+ m_scene,
+ std::bind(&GraphicsScene::update, m_scene, m_design)
+ );
+
+ leftLayout->addRow(text, spinBox);
+ };
+
+ using Decimals = int;
+ auto addFormLabel = [this, leftLayout](
+ const QString text,
+ const auto propertySignal,
+ const Decimals decimals = 2
+ ) {
+ const auto label = new QLabel{centralWidget()};
+
+ connect(
+ m_design,
+ propertySignal,
+ label,
+ [label, decimals](const auto value) {
+ label->setText(QString::number(value, 'F', decimals));
+ }
+ );
+
+ leftLayout->addRow(text, label);
+ };
+
+ const auto createLenseApertureComboBox = [this, leftLayout]() {
+ const auto comboBox = new QComboBox{centralWidget()};
+
+ using namespace orphex;
+ const auto metaEnum = QMetaEnum::fromType<LenseAperture>();
+
+ for (int i{0}; i < metaEnum.keyCount(); ++i)
+ {
+ const auto key = metaEnum.key(i);
+ const auto value = metaEnum.value(i);
+ const auto text =
+ QString{key}
+ .replace(QStringLiteral("F"), QStringLiteral("1/"))
+ .replace(QChar{'_'}, QChar{'.'});
+
+ comboBox->addItem(text, value);
+ }
+
+ // update property on combobox change
+ connect(
+ comboBox,
+ &QComboBox::currentIndexChanged,
+ m_design,
+ [this, metaEnum, comboBox](const auto index) {
+ m_design->set_lenseAperture(
+ comboBox->currentData().value<LenseAperture>()
+ );
+
+ qDebug() << m_design->get_lenseAperture();
+ }
+ );
+
+ // update combobox on property change
+ connect(
+ m_design,
+ qOverload<LenseAperture>(&OpticalDesign::lenseApertureChanged),
+ comboBox,
+ [comboBox](const auto value) {
+ comboBox->setCurrentIndex(
+ comboBox->findData(QVariant::fromValue(value))
+ );
+ }
+ );
+
+ leftLayout->addRow(tr("Lense A&perture:"), comboBox);
+ };
+
+ addFormPair(
+ tr("&Axis Angle (°):"),
+ qOverload<double>(&OpticalDesign::opticalAxisAngleDegreesChanged),
+ &OpticalDesign::get_opticalAxisAngleDegrees,
+ &OpticalDesign::set_opticalAxisAngleDegrees,
+ MinValue{10.},
+ MaxValue{85.}
+ );
+
+ addFormPair(
+ tr("Lense &Y pos (mm):"),
+ qOverload<double>(&OpticalDesign::lenseYPosMmChanged),
+ &OpticalDesign::get_lenseYPosMm,
+ &OpticalDesign::set_lenseYPosMm,
+ MinValue{10.},
+ MaxValue{500.},
+ SingleStep{1.}
+ );
+
+ addFormPair(
+ tr("&Focal Distance (mm):"),
+ qOverload<double>(&OpticalDesign::focalDistanceMmChanged),
+ &OpticalDesign::get_focalDistanceMm,
+ &OpticalDesign::set_focalDistanceMm,
+ MinValue{1.},
+ MaxValue{45.}
+ );
+
+ createLenseApertureComboBox();
+
+ addFormPair(
+ tr("Sensor &Width (mm):"),
+ qOverload<double>(&OpticalDesign::sensorWidthMmChanged),
+ &OpticalDesign::get_sensorWidthMm,
+ &OpticalDesign::set_sensorWidthMm,
+ MinValue{1.},
+ MaxValue{30.}
+ );
+
+ addFormPair(
+ tr("Sensor &Height (mm):"),
+ qOverload<double>(&OpticalDesign::sensorHeightMmChanged),
+ &OpticalDesign::get_sensorHeightMm,
+ &OpticalDesign::set_sensorHeightMm,
+ MinValue{1.},
+ MaxValue{30.}
+ );
+
+ addFormPair(
+ tr("Sensor Cell W&idth (mm):"),
+ qOverload<double>(&OpticalDesign::sensorCellWidthUmChanged),
+ &OpticalDesign::get_sensorCellWidthUm,
+ &OpticalDesign::set_sensorCellWidthUm,
+ MinValue{1.},
+ MaxValue{30.}
+ );
+
+ addFormPair(
+ tr("Sensor Cell H&eight (mm):"),
+ qOverload<double>(&OpticalDesign::sensorCellHeightUmChanged),
+ &OpticalDesign::get_sensorCellHeightUm,
+ &OpticalDesign::set_sensorCellHeightUm,
+ MinValue{1.},
+ MaxValue{30.}
+ );
+
+ addFormPair(
+ tr("Sensor Vertical &Offset (mm):"),
+ qOverload<double>(&OpticalDesign::sensorVerticalOffsetMmChanged),
+ &OpticalDesign::get_sensorVerticalOffsetMm,
+ &OpticalDesign::set_sensorVerticalOffsetMm,
+ MinValue{-50.},
+ MaxValue{50.},
+ SingleStep{0.1}
+ );
+
+ addFormPair(
+ tr("Z &Base (mm):"),
+ qOverload<double>(&OpticalDesign::zBaseMmChanged),
+ &OpticalDesign::get_zBaseMm,
+ &OpticalDesign::set_zBaseMm,
+ MinValue{1.},
+ MaxValue{10000.},
+ SingleStep{1.}
+ );
+
+ addFormPair(
+ tr("Z &Range (mm):"),
+ qOverload<double>(&OpticalDesign::zRangeMmChanged),
+ &OpticalDesign::get_zRangeMm,
+ &OpticalDesign::set_zRangeMm,
+ MinValue{1.},
+ MaxValue{10000.},
+ SingleStep{1.}
+ );
+
+ addFormLabel(
+ tr("Sensor/Lense Angle (°):"),
+ qOverload<double>(&OpticalDesign::sensorLenseAngleDegreesChanged),
+ Decimals{3}
+ );
+
+ addFormLabel(
+ tr("Actual Z Base (mm):"),
+ qOverload<double>(&OpticalDesign::actualZBaseMmChanged),
+ Decimals{2}
+ );
+
+ addFormLabel(
+ tr("Actual Z Range (mm):"),
+ qOverload<double>(&OpticalDesign::actualZRangeMmChanged),
+ Decimals{2}
+ );
+
+ // graphics view
+ const auto openGlWidget = new QOpenGLWidget{centralWidget()};
+ QSurfaceFormat surfaceFormat{};
+ surfaceFormat.setSamples(4);
+ openGlWidget->setFormat(surfaceFormat);
+ m_view->setViewport(openGlWidget);
+ // m_view->centerOn({0, 0});
+ // m_view->ensureVisible(QRectF{m_scene->sceneRect()});
+
+ mainLayout->addWidget(m_view);
+ setCentralWidget(mainWidget);
+
+ connect(
+ m_design,
+ qOverload<double>(&OpticalDesign::opticalAxisAngleDegreesChanged),
+ this,
+ [](const auto value) { qDebug() << "angle changed:" << value; }
+ );
+
+ m_view->setTransformationAnchor(GraphicsView::AnchorViewCenter);
+ m_view->scale(15, 15);
+ m_view->centerOn({0, -m_design->get_lenseYPosMm()});
+
+ m_scene->update(m_design);
+}
+
+void MainWindow::initShortcuts()
+{
+ new QShortcut{Qt::CTRL | Qt::Key_Q, this, this, &MainWindow::close};
+}