diff --git a/GUI/Model/Item/RectangularDetectorItem.cpp b/GUI/Model/Item/RectangularDetectorItem.cpp
index d1c458c9b41f0eee5db7686c8e0102bef2adcbab..42f7cb9e4845508ac6405cbd464e9f964bf0370c 100644
--- a/GUI/Model/Item/RectangularDetectorItem.cpp
+++ b/GUI/Model/Item/RectangularDetectorItem.cpp
@@ -63,7 +63,7 @@ QString alignmentTitle(RectangularDetector::EDetectorArrangement a)
     case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM:
         return "Perpendicular to reflected beam";
     case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM_DPOS:
-        return "Perpendicular to reflected beam (dpos)";
+        return "Perpendicular to reflected beam (intersection unknown)";
     default:
         ASSERT(false);
     }
diff --git a/GUI/View/Instrument/DetectorAlignmentEditor.cpp b/GUI/View/Instrument/DetectorAlignmentEditor.cpp
index 8cf2ee19fd503a3f2249cd3b536d18db43dbccd2..86f0d9e403a5bf05f8e9bbcfdb44a4177aaa1840 100644
--- a/GUI/View/Instrument/DetectorAlignmentEditor.cpp
+++ b/GUI/View/Instrument/DetectorAlignmentEditor.cpp
@@ -15,6 +15,7 @@
 #include "GUI/View/Instrument/DetectorAlignmentEditor.h"
 #include "GUI/Model/Item/RectangularDetectorItem.h"
 #include "GUI/Util/ComboProperty.h"
+#include "GUI/View/Edit/DoubleSpinBox.h"
 #include "GUI/View/Instrument/VectorEditor.h"
 #include "GUI/View/Tool/WidgetUtils.h"
 #include <QComboBox>
@@ -23,356 +24,26 @@
 #include <QGroupBox>
 #include <QStackedLayout>
 
-//==================================================================================================
-// DetectorAlignmentForm
-//==================================================================================================
-
-/// abstract interface of all detector alignment forms
-class DetectorAlignmentForm : public QWidget {
-public:
-    /// Set type if not already the matching one and display parameters of distribution
-    virtual void setItem(RectangularDetectorItem* item) = 0;
-
-protected:
-    DetectorAlignmentForm(QWidget* parent, std::function<void()> dataChangedSlot)
-        : QWidget(parent)
-        , dataChanged(dataChangedSlot)
-    {
-    }
-
-    std::function<void()> dataChanged;
-};
-
-//==================================================================================================
-// GenericDetectorAlignmentForm
-//==================================================================================================
-
-/// Alignment form for the generic case
-class GenericDetectorAlignmentForm : public DetectorAlignmentForm {
-public:
-    GenericDetectorAlignmentForm(QWidget* parent, std::function<void()> dataChangedSlot);
-    void setItem(RectangularDetectorItem* item) override;
-
-private slots:
-    void onU0ValueChanged(double u0);
-    void onV0ValueChanged(double v0);
-
-private:
-    QDoubleSpinBox* m_u0SpinBox;
-    QDoubleSpinBox* m_v0SpinBox;
-    VectorEditor* m_normalEditor;
-    VectorEditor* m_directionEditor;
-    RectangularDetectorItem* m_item;
-};
-
-GenericDetectorAlignmentForm::GenericDetectorAlignmentForm(QWidget* parent,
-                                                           std::function<void()> dataChangedSlot)
-    : DetectorAlignmentForm(parent, dataChangedSlot)
-    , m_item(nullptr)
-{
-    auto* layout = new QHBoxLayout(this);
-
-    auto* gbox = new QGroupBox("Intersection of normal and detector", this);
-    auto* form = new QFormLayout(gbox);
-    layout->addWidget(gbox);
-
-    m_u0SpinBox = new QDoubleSpinBox(gbox);
-    m_u0SpinBox->setDecimals(3);
-    m_u0SpinBox->setRange(std::numeric_limits<double>::lowest(),
-                          std::numeric_limits<double>::max());
-    m_u0SpinBox->setSingleStep(0.01);
-    m_u0SpinBox->setToolTip("u-coordinate of intersection of normal vector "
-                            "and detector plane, \n in local detector coordinates");
-    connect(m_u0SpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
-            &GenericDetectorAlignmentForm::onU0ValueChanged);
-    form->addRow("u0 [mm]:", m_u0SpinBox);
-
-    m_v0SpinBox = new QDoubleSpinBox(gbox);
-    m_v0SpinBox->setDecimals(3);
-    m_v0SpinBox->setRange(std::numeric_limits<double>::lowest(),
-                          std::numeric_limits<double>::max());
-    m_v0SpinBox->setSingleStep(0.01);
-    m_v0SpinBox->setToolTip("v-coordinate of intersection of normal vector "
-                            "and detector plane, \n in local detector coordinates");
-    connect(m_v0SpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
-            &GenericDetectorAlignmentForm::onV0ValueChanged);
-    form->addRow("v0 [mm]:", m_v0SpinBox);
-
-    m_normalEditor = new VectorEditor(
-        "Normal vector",
-        "Normal of the detector plane with length equal to the sample detector distance (%1)",
-        this);
-    layout->addWidget(m_normalEditor);
-    connect(m_normalEditor, &VectorEditor::vectorChanged, [=]() { dataChanged(); });
-
-    m_directionEditor = new VectorEditor(
-        "Detector axis direction vector",
-        "Detector axis direction vector w.r.t. the sample coordinate system (%1)", this);
-    layout->addWidget(m_directionEditor);
-    connect(m_directionEditor, &VectorEditor::vectorChanged, [=]() { dataChanged(); });
-}
-
-void GenericDetectorAlignmentForm::setItem(RectangularDetectorItem* item)
-{
-    m_item = item;
-    m_u0SpinBox->setValue(m_item->u0());
-    m_v0SpinBox->setValue(m_item->v0());
-    m_normalEditor->setVector(m_item->normalVector());
-    m_directionEditor->setVector(m_item->directionVector());
-}
-
-void GenericDetectorAlignmentForm::onU0ValueChanged(double u0)
-{
-    if (m_item && m_item->u0() != u0) {
-        m_item->setU0(u0);
-        dataChanged();
-    }
-}
-
-void GenericDetectorAlignmentForm::onV0ValueChanged(double v0)
-{
-    if (m_item && m_item->v0() != v0) {
-
-        m_item->setV0(v0);
-        dataChanged();
-    }
-}
-
-//==================================================================================================
-// PerpendicularDetectorAlignmentForm
-//==================================================================================================
-
-/// Abstract alignment form for the perpendicular case
-class PerpendicularDetectorAlignmentForm : public DetectorAlignmentForm {
-public:
-    void setItem(RectangularDetectorItem* item) override;
-
-protected:
-    PerpendicularDetectorAlignmentForm(const QString& title, const QString& tooltip,
-                                       QWidget* parent, std::function<void()> dataChangedSlot);
-    RectangularDetectorItem* item() const;
-
-private slots:
-    void onU0ValueChanged(double u0);
-    void onV0ValueChanged(double v0);
-    void onDistanceValueChanged(double distance);
-
-private:
-    virtual double getU0() const = 0;
-    virtual double getV0() const = 0;
-    virtual void setU0(double u0) = 0;
-    virtual void setV0(double v0) = 0;
-
-    QDoubleSpinBox* m_u0SpinBox;
-    QDoubleSpinBox* m_v0SpinBox;
-    QDoubleSpinBox* m_distanceSpinBox;
-    RectangularDetectorItem* m_item;
-};
-
-//--------------------------------------------------------------------------------------------------
-// public member functions
-//--------------------------------------------------------------------------------------------------
-
-void PerpendicularDetectorAlignmentForm::setItem(RectangularDetectorItem* item)
-{
-    m_item = item;
-    m_u0SpinBox->setValue(getU0());
-    m_v0SpinBox->setValue(getV0());
-    m_distanceSpinBox->setValue(m_item->distance());
-}
-
-//--------------------------------------------------------------------------------------------------
-// protected member functions
-//--------------------------------------------------------------------------------------------------
-
-PerpendicularDetectorAlignmentForm::PerpendicularDetectorAlignmentForm(
-    const QString& title, const QString& tooltip, QWidget* parent,
-    std::function<void()> dataChangedSlot)
-    : DetectorAlignmentForm(parent, dataChangedSlot)
-    , m_item(nullptr)
-{
-    auto* layout = new QHBoxLayout(this);
-
-    auto* gbox = new QGroupBox(title, this);
-    auto* form = new QFormLayout(gbox);
-    layout->addWidget(gbox);
-
-    m_u0SpinBox = new QDoubleSpinBox(gbox);
-    m_u0SpinBox->setDecimals(3);
-    m_u0SpinBox->setRange(std::numeric_limits<double>::lowest(),
-                          std::numeric_limits<double>::max());
-    m_u0SpinBox->setSingleStep(0.01);
-    m_u0SpinBox->setToolTip(tooltip.arg("u-coordinate"));
-    connect(m_u0SpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
-            &PerpendicularDetectorAlignmentForm::onU0ValueChanged);
-    form->addRow("u0 [mm]:", m_u0SpinBox);
-
-    m_v0SpinBox = new QDoubleSpinBox(gbox);
-    m_v0SpinBox->setDecimals(3);
-    m_v0SpinBox->setRange(std::numeric_limits<double>::lowest(),
-                          std::numeric_limits<double>::max());
-    m_v0SpinBox->setSingleStep(0.01);
-    m_v0SpinBox->setToolTip(tooltip.arg("v-coordinate"));
-    connect(m_v0SpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
-            &PerpendicularDetectorAlignmentForm::onV0ValueChanged);
-    form->addRow("v0 [mm]:", m_v0SpinBox);
-
-    m_distanceSpinBox = new QDoubleSpinBox(gbox);
-    m_distanceSpinBox->setDecimals(3);
-    m_distanceSpinBox->setRange(0, std::numeric_limits<double>::max());
-    m_distanceSpinBox->setSingleStep(0.01);
-    m_distanceSpinBox->setToolTip("Distance in [mm] from the sample origin to the detector plane");
-    connect(m_distanceSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this,
-            &PerpendicularDetectorAlignmentForm::onDistanceValueChanged);
-    form->addRow("Distance [mm]:", m_distanceSpinBox);
-}
-
-RectangularDetectorItem* PerpendicularDetectorAlignmentForm::item() const
-{
-    return m_item;
-}
-
-//--------------------------------------------------------------------------------------------------
-// private slots
-//--------------------------------------------------------------------------------------------------
-
-void PerpendicularDetectorAlignmentForm::onU0ValueChanged(double u0)
-{
-    setU0(u0);
-}
-
-void PerpendicularDetectorAlignmentForm::onV0ValueChanged(double v0)
-{
-    setV0(v0);
-}
-
-void PerpendicularDetectorAlignmentForm::onDistanceValueChanged(double distance)
-{
-    if (m_item && m_item->distance() != distance) {
-        m_item->setDistance(distance);
-        dataChanged();
-    }
-}
-
-//==================================================================================================
-// ReflectedBeamDetectorAlignmentForm
-//==================================================================================================
-
-/// detector alignment form for the perpendicular case where the reflected beam is used
-class ReflectedBeamDetectorAlignmentForm : public PerpendicularDetectorAlignmentForm {
-public:
-    ReflectedBeamDetectorAlignmentForm(const QString& title, const QString& tooltip,
-                                       QWidget* parent, std::function<void()> dataChangedSlot);
-
-private:
-    double getU0() const override;
-    double getV0() const override;
-    void setU0(double u0) override;
-    void setV0(double v0) override;
-};
-
-//--------------------------------------------------------------------------------------------------
-// public member functions
-//--------------------------------------------------------------------------------------------------
-
-ReflectedBeamDetectorAlignmentForm::ReflectedBeamDetectorAlignmentForm(
-    const QString& title, const QString& tooltip, QWidget* parent,
-    std::function<void()> dataChangedSlot)
-    : PerpendicularDetectorAlignmentForm(title, tooltip, parent, dataChangedSlot)
-{
-}
-
-//--------------------------------------------------------------------------------------------------
-// private slots
-//--------------------------------------------------------------------------------------------------
-
-double ReflectedBeamDetectorAlignmentForm::getU0() const
-{
-    return item()->u0();
-}
-
-double ReflectedBeamDetectorAlignmentForm::getV0() const
-{
-    return item()->v0();
-}
-
-void ReflectedBeamDetectorAlignmentForm::setU0(double u0)
-{
-    if (item() && item()->u0() != u0) {
-        item()->setU0(u0);
-        dataChanged();
-    }
-}
-
-void ReflectedBeamDetectorAlignmentForm::setV0(double v0)
-{
-    if (item() && item()->v0() != v0) {
-        item()->setV0(v0);
-        dataChanged();
-    }
-}
-
-//==================================================================================================
-// DirectBeamDetectorAlignmentForm
-//==================================================================================================
-
-/// detector alignment form for the perpendicular case where the direct beam is used
-class DirectBeamDetectorAlignmentForm : public PerpendicularDetectorAlignmentForm {
-public:
-    DirectBeamDetectorAlignmentForm(const QString& title, const QString& tooltip, QWidget* parent,
-                                    std::function<void()> dataChangedSlot);
-
-private:
-    double getU0() const override;
-    double getV0() const override;
-    void setU0(double u0) override;
-    void setV0(double v0) override;
-};
-
-//--------------------------------------------------------------------------------------------------
-// public member functions
-//--------------------------------------------------------------------------------------------------
-
-DirectBeamDetectorAlignmentForm::DirectBeamDetectorAlignmentForm(
-    const QString& title, const QString& tooltip, QWidget* parent,
-    std::function<void()> dataChangedSlot)
-    : PerpendicularDetectorAlignmentForm(title, tooltip, parent, dataChangedSlot)
+namespace {
+QString alignmentDescription(RectangularDetector::EDetectorArrangement a)
 {
-}
-
-//--------------------------------------------------------------------------------------------------
-// private slots
-//--------------------------------------------------------------------------------------------------
-
-double DirectBeamDetectorAlignmentForm::getU0() const
-{
-    return item()->directBeamU0();
-}
-
-double DirectBeamDetectorAlignmentForm::getV0() const
-{
-    return item()->directBeamV0();
-}
-
-void DirectBeamDetectorAlignmentForm::setU0(double u0)
-{
-    if (item() && item()->directBeamU0() != u0) {
-        item()->setDirectBeamU0(u0);
-        dataChanged();
-    }
-}
-
-void DirectBeamDetectorAlignmentForm::setV0(double v0)
-{
-    if (item() && item()->directBeamV0() != v0) {
-        item()->setDirectBeamV0(v0);
-        dataChanged();
+    switch (a) {
+    case RectangularDetector::GENERIC:
+        return "Intersection of normal and detector";
+    case RectangularDetector::PERPENDICULAR_TO_SAMPLE:
+        return "Intersection of sample x-axis and detector";
+    case RectangularDetector::PERPENDICULAR_TO_DIRECT_BEAM:
+        return "Intersection of direct beam and detector";
+    case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM:
+        return "Intersection of reflected beam and detector";
+    case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM_DPOS:
+        return "Intersection of direct beam and detector";
+    default:
+        ASSERT(false);
     }
 }
 
-//==================================================================================================
-// DetectorAlignmentEditor
-//==================================================================================================
+} // namespace
 
 DetectorAlignmentEditor::DetectorAlignmentEditor(QWidget* parent, RectangularDetectorItem* item)
     : QWidget(parent)
@@ -380,48 +51,85 @@ DetectorAlignmentEditor::DetectorAlignmentEditor(QWidget* parent, RectangularDet
 {
     ASSERT(m_item);
     m_formLayout = new QFormLayout(this);
-
-    auto* m_combo = GUI::Util::createSelectionCombo(this, item->detectorAlignmentSelection(),
-                                                    [=](int) { createAligmentWidgets(); });
+    m_formLayout->setContentsMargins(0, 15, 0, 0);
+    m_formLayout->setSpacing(8);
+
+    auto* m_combo =
+        GUI::Util::createSelectionCombo(this, item->detectorAlignmentSelection(), [=](int) {
+            createAligmentWidgets();
+            emit dataChanged();
+        });
     m_formLayout->addRow("Alignment:", m_combo);
 
     createAligmentWidgets();
 }
 
+DoubleSpinBox* DetectorAlignmentEditor::createSpinBox(QFormLayout* parentFormLayout,
+                                                      const DoubleDescriptor& d)
+{
+    auto* sb = GUI::Util::createSpinBox(parentFormLayout, d);
+    connect(sb, qOverload<double>(&DoubleSpinBox::baseValueChanged), [=](double v) {
+        if (d.get() != v) {
+            d.set(v);
+            emit dataChanged();
+        }
+    });
+    return sb;
+}
+
 void DetectorAlignmentEditor::createAligmentWidgets()
 {
     while (m_formLayout->rowCount() > 1)
         m_formLayout->removeRow(1);
 
+    const QString descr = alignmentDescription(m_item->detectorAlignment());
     switch (m_item->detectorAlignment()) {
-    case RectangularDetector::GENERIC:
-        m_formLayout->addRow(new GenericDetectorAlignmentForm(this, [=]() { dataChanged(); }));
-        break;
-    case RectangularDetector::PERPENDICULAR_TO_SAMPLE:
-        m_formLayout->addRow(new ReflectedBeamDetectorAlignmentForm(
-            "Intersection of sample x-axis and detector",
-            "Point where the sample x-axis intersects with the detector plane (%1)", this,
-            [=]() { dataChanged(); }));
-        break;
-    case RectangularDetector::PERPENDICULAR_TO_DIRECT_BEAM:
-        m_formLayout->addRow(new DirectBeamDetectorAlignmentForm(
-            "Intersection of direct beam and detector",
-            "Point where the direct beam hits the detector plane (%1)", this,
-            [=]() { dataChanged(); }));
-        break;
-    case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM:
-        m_formLayout->addRow(new ReflectedBeamDetectorAlignmentForm(
-            "Intersection of reflected beam and detector",
-            "Point where the reflected beam hits the detector plane (%1)", this,
-            [=]() { dataChanged(); }));
-        break;
-    case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM_DPOS:
-        m_formLayout->addRow(new DirectBeamDetectorAlignmentForm(
-            "Intersection of direct beam and detector",
-            "Point where the direct beam hits the detector plane (%1)", this,
-            [=]() { dataChanged(); }));
-        break;
+    case RectangularDetector::GENERIC: {
+        auto* layout = new QHBoxLayout(this);
+        auto* gbox = new QGroupBox(descr, this);
+        auto* form = new QFormLayout(gbox);
+
+        createSpinBox(form, m_item->u0());
+        createSpinBox(form, m_item->v0());
+
+        auto* normalEditor = new VectorEditor(
+            "Normal vector",
+            "Normal of the detector plane with length equal to the sample detector distance (%1)",
+            this);
+        normalEditor->setVector(m_item->normalVector());
+        connect(normalEditor, &VectorEditor::vectorChanged, [=]() { dataChanged(); });
+
+        auto* directionEditor = new VectorEditor(
+            "Detector axis direction vector",
+            "Detector axis direction vector w.r.t. the sample coordinate system (%1)", this);
+        directionEditor->setVector(m_item->directionVector());
+        connect(directionEditor, &VectorEditor::vectorChanged, [=]() { dataChanged(); });
+
+        layout->addWidget(gbox);
+        layout->addWidget(normalEditor);
+        layout->addWidget(directionEditor);
+
+        m_formLayout->addRow(layout);
+    } break;
+    case RectangularDetector::PERPENDICULAR_TO_SAMPLE: // fall-through!
+    case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM: {
+        auto* gbox = new QGroupBox(descr, this);
+        auto* form = new QFormLayout(gbox);
+        createSpinBox(form, m_item->u0());
+        createSpinBox(form, m_item->v0());
+        createSpinBox(form, m_item->distance());
+        m_formLayout->addRow(gbox);
+    } break;
+    case RectangularDetector::PERPENDICULAR_TO_DIRECT_BEAM: // fall-through!
+    case RectangularDetector::PERPENDICULAR_TO_REFLECTED_BEAM_DPOS: {
+        auto* gbox = new QGroupBox(descr, this);
+        auto* form = new QFormLayout(gbox);
+        createSpinBox(form, m_item->directBeamU0());
+        createSpinBox(form, m_item->directBeamV0());
+        createSpinBox(form, m_item->distance());
+        m_formLayout->addRow(gbox);
+    } break;
     default:
-        break;
+        ASSERT(false);
     }
 }
diff --git a/GUI/View/Instrument/DetectorAlignmentEditor.h b/GUI/View/Instrument/DetectorAlignmentEditor.h
index 7285424b3df40de8ff93da663b2a762b23b0f63a..dd138d0e36503c0a3937c862a54727fc6f31711b 100644
--- a/GUI/View/Instrument/DetectorAlignmentEditor.h
+++ b/GUI/View/Instrument/DetectorAlignmentEditor.h
@@ -23,6 +23,8 @@ class QStackedLayout;
 class DetectorAlignmentForm;
 class RectangularDetectorItem;
 class QFormLayout;
+class DoubleSpinBox;
+class DoubleDescriptor;
 
 /// Widget for selecting the alignment of a detector (combo box) and input of the corresponding
 /// values
@@ -37,6 +39,7 @@ signals:
 
 private:
     void createAligmentWidgets();
+    DoubleSpinBox* createSpinBox(QFormLayout* parentFormLayout, const DoubleDescriptor& d);
 
 private:
     RectangularDetectorItem* m_item;