diff options
Diffstat (limited to 'src/mainwindow.cpp')
| -rw-r--r-- | src/mainwindow.cpp | 303 |
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}; +} |
