viewer: shift/ctrl-drag creates list ROIs; remove the old scratch panel
The interactive shift-drag (box) / shift+ctrl-drag (circle) now creates a new persistent ROI in the list instead of feeding the old single-ROI scratch panel. The base emits a roiScratchDrawn hook on release; the diffraction image turns the drawn shape into a named ROI committed via SetROIDefinition. The old JFJochViewerImageROIStatistics scratch panel and all its wiring (box/circle configuration, single-ROI result, add/subtract user mask) are removed from the side panel and window; the ROI list is now the single source. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -132,20 +132,6 @@ JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent)
|
||||
connect(roi_list, &JFJochViewerROIList::roisChanged, this, &JFJochViewerSidePanel::roisChanged);
|
||||
connect(roi_list, &JFJochViewerROIList::selectedROIChanged, this, &JFJochViewerSidePanel::selectedROIChanged);
|
||||
|
||||
roi = new JFJochViewerImageROIStatistics(this);
|
||||
layout->addWidget(roi);
|
||||
|
||||
connect(roi, &JFJochViewerImageROIStatistics::ROIBoxConfigured, [this] (QRect box) {
|
||||
emit ROIBoxConfigured(box);
|
||||
});
|
||||
|
||||
connect(roi, &JFJochViewerImageROIStatistics::ROICircleConfigured, [this] (double x, double y, double radius) {
|
||||
emit ROICircleConfigured(x, y, radius);
|
||||
});
|
||||
|
||||
connect(roi, &JFJochViewerImageROIStatistics::AddROIToUserMask, [this]() { emit AddROIToUserMask(); });
|
||||
connect(roi, &JFJochViewerImageROIStatistics::SubtractROIFromUserMask, [this]() { emit SubtractROIFromUserMask(); });
|
||||
|
||||
layout->addWidget(new TitleLabel("Data analysis", this));
|
||||
|
||||
auto analyzeButton = new QPushButton("Full analysis", this);
|
||||
@@ -193,18 +179,6 @@ void JFJochViewerSidePanel::selectROIInList(QString name) {
|
||||
roi_list->setSelected(name);
|
||||
}
|
||||
|
||||
void JFJochViewerSidePanel::SetROIBox(QRect box) {
|
||||
roi->SetROIBox(box);
|
||||
}
|
||||
|
||||
void JFJochViewerSidePanel::SetROICircle(double x, double y, double radius) {
|
||||
roi->SetROICircle(x, y, radius);
|
||||
}
|
||||
|
||||
void JFJochViewerSidePanel::SetROIResult(ROIMessage msg) {
|
||||
roi->SetROIResult(msg);
|
||||
}
|
||||
|
||||
void JFJochViewerSidePanel::SetRings(QVector<float> v) {
|
||||
res_rings->setRings(v);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <QLineEdit>
|
||||
#include <QCheckBox>
|
||||
|
||||
#include "widgets/JFJochViewerImageROIStatistics.h"
|
||||
#include "widgets/JFJochViewerROIList.h"
|
||||
#include "../reader/JFJochReader.h"
|
||||
#include "charts/JFJochSimpleChartView.h"
|
||||
@@ -19,7 +18,6 @@ class JFJochViewerSidePanel : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
JFJochViewerSidePanelChart *chart = nullptr;
|
||||
JFJochViewerImageROIStatistics *roi = nullptr;
|
||||
JFJochViewerROIList *roi_list = nullptr;
|
||||
ResolutionRingWidget *res_rings = nullptr;
|
||||
|
||||
@@ -40,10 +38,6 @@ signals:
|
||||
|
||||
void imageLoaded(std::shared_ptr<const JFJochReaderImage> image);
|
||||
|
||||
void ROIBoxConfigured(QRect box);
|
||||
void ROICircleConfigured(double center_x, double center_y, double radius);
|
||||
void AddROIToUserMask();
|
||||
void SubtractROIFromUserMask();
|
||||
void writeStatusBar(QString string, int timeout_ms = 0);
|
||||
|
||||
void ringModeSet(JFJochDiffractionImage::RingMode mode);
|
||||
@@ -52,9 +46,6 @@ public:
|
||||
JFJochViewerSidePanel(QWidget *parent);
|
||||
public slots:
|
||||
void loadImage(std::shared_ptr<const JFJochReaderImage> image);
|
||||
void SetROIBox(QRect box);
|
||||
void SetROICircle(double x, double y, double radius);
|
||||
void SetROIResult(ROIMessage msg);
|
||||
void SetRings(QVector<float> v);
|
||||
void selectROIInList(QString name);
|
||||
|
||||
|
||||
@@ -189,21 +189,6 @@ JFJochViewerWindow::JFJochViewerWindow(QWidget *parent, bool dbus, const QString
|
||||
connect(viewer, &JFJochDiffractionImage::foregroundChanged,
|
||||
toolBarDisplay, &JFJochViewerToolbarDisplay::updateForeground);
|
||||
|
||||
connect(viewer, &JFJochDiffractionImage::roiBoxUpdated,
|
||||
reading_worker, &JFJochImageReadingWorker::SetROIBox);
|
||||
|
||||
connect(viewer, &JFJochDiffractionImage::roiCircleUpdated,
|
||||
reading_worker, &JFJochImageReadingWorker::SetROICircle);
|
||||
|
||||
connect(viewer, &JFJochDiffractionImage::roiBoxUpdated,
|
||||
side_panel, &JFJochViewerSidePanel::SetROIBox);
|
||||
|
||||
connect(viewer, &JFJochDiffractionImage::roiCircleUpdated,
|
||||
side_panel, &JFJochViewerSidePanel::SetROICircle);
|
||||
|
||||
connect(viewer, &JFJochDiffractionImage::roiCalculated,
|
||||
side_panel, &JFJochViewerSidePanel::SetROIResult);
|
||||
|
||||
connect(side_panel, &JFJochViewerSidePanel::roisChanged,
|
||||
reading_worker, &JFJochImageReadingWorker::SetROIDefinition);
|
||||
connect(side_panel, &JFJochViewerSidePanel::selectedROIChanged,
|
||||
@@ -213,24 +198,6 @@ JFJochViewerWindow::JFJochViewerWindow(QWidget *parent, bool dbus, const QString
|
||||
connect(viewer, &JFJochDiffractionImage::roiSelected,
|
||||
side_panel, &JFJochViewerSidePanel::selectROIInList);
|
||||
|
||||
connect(side_panel, &JFJochViewerSidePanel::ROIBoxConfigured,
|
||||
reading_worker, &JFJochImageReadingWorker::SetROIBox);
|
||||
|
||||
connect(side_panel, &JFJochViewerSidePanel::ROICircleConfigured,
|
||||
reading_worker, &JFJochImageReadingWorker::SetROICircle);
|
||||
|
||||
connect(side_panel, &JFJochViewerSidePanel::ROIBoxConfigured,
|
||||
viewer, &JFJochDiffractionImage::SetROIBox);
|
||||
|
||||
connect(side_panel, &JFJochViewerSidePanel::ROICircleConfigured,
|
||||
viewer, &JFJochDiffractionImage::SetROICircle);
|
||||
|
||||
connect(side_panel, &JFJochViewerSidePanel::AddROIToUserMask,
|
||||
reading_worker, &JFJochImageReadingWorker::AddROIToUserMask);
|
||||
|
||||
connect(side_panel, &JFJochViewerSidePanel::SubtractROIFromUserMask,
|
||||
reading_worker, &JFJochImageReadingWorker::SubtractROIFromUserMask);
|
||||
|
||||
connect(menuBar, &JFJochViewerMenu::clearUserMaskSelected,
|
||||
reading_worker, &JFJochImageReadingWorker::ClearUserMask);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "JFJochDiffractionImage.h"
|
||||
#include "../../common/DiffractionGeometry.h"
|
||||
#include "../../common/JFJochMath.h"
|
||||
@@ -755,6 +757,42 @@ ROIDefinition JFJochDiffractionImage::BuildEditedROIDefinition() const {
|
||||
return rois;
|
||||
}
|
||||
|
||||
void JFJochDiffractionImage::roiScratchDrawn() {
|
||||
// The base just drew a scratch box/circle (roiBox/roi_type, in pixel coords);
|
||||
// turn it into a new persistent ROI in the list.
|
||||
if (!image || roiBox.isNull() || roiBox.width() <= 0 || roiBox.height() <= 0)
|
||||
return;
|
||||
|
||||
ROIDefinition rois = image->Dataset().experiment.ROI().GetROIDefinition();
|
||||
if (rois.boxes.size() + rois.circles.size() + rois.azimuthal.size() >= 16)
|
||||
return;
|
||||
|
||||
std::set<std::string> used;
|
||||
for (const auto &b : rois.boxes) used.insert(b.GetName());
|
||||
for (const auto &c : rois.circles) used.insert(c.GetName());
|
||||
for (const auto &a : rois.azimuthal) used.insert(a.GetName());
|
||||
std::string name;
|
||||
for (int i = 1; ; i++) {
|
||||
name = "roi" + std::to_string(i);
|
||||
if (!used.count(name)) break;
|
||||
}
|
||||
|
||||
if (roi_type == RoiType::RoiBox) {
|
||||
const QRectF r = roiBox.normalized();
|
||||
rois.boxes.emplace_back(name, std::lround(r.left()), std::lround(r.right()),
|
||||
std::lround(r.top()), std::lround(r.bottom()));
|
||||
} else {
|
||||
const QPointF c = roiBox.center();
|
||||
const double rad = 0.5 * std::min(roiBox.width(), roiBox.height());
|
||||
rois.circles.emplace_back(name, c.x(), c.y(), std::max(0.1, rad));
|
||||
}
|
||||
|
||||
roiBox = QRectF(); // clear the scratch overlay
|
||||
selected_roi_ = QString::fromStdString(name);
|
||||
emit roiSelected(selected_roi_);
|
||||
emit roiGeometryEdited(rois);
|
||||
}
|
||||
|
||||
void JFJochDiffractionImage::keyPressEvent(QKeyEvent *event) {
|
||||
if (event->key() == Qt::Key_Delete && image && !selected_roi_.isEmpty()) {
|
||||
ROIDefinition rois = image->Dataset().experiment.ROI().GetROIDefinition();
|
||||
|
||||
@@ -37,6 +37,7 @@ private:
|
||||
bool roiEditPress(const QPointF &scenePos) override;
|
||||
void roiEditMove(const QPointF &scenePos) override;
|
||||
void roiEditRelease() override;
|
||||
void roiScratchDrawn() override;
|
||||
void keyPressEvent(QKeyEvent *event) override; // Delete removes the selected ROI
|
||||
[[nodiscard]] ROIDefinition BuildEditedROIDefinition() const; // current ROIs with the edit applied
|
||||
[[nodiscard]] ResizeHandle hitTestBoxHandle(const QRectF &r, const QPointF &p, qreal tol) const;
|
||||
|
||||
@@ -297,9 +297,12 @@ void JFJochImage::mouseReleaseEvent(QMouseEvent *event) {
|
||||
if (mouse_event_type == MouseEventType::EditingExternalROI) {
|
||||
roiEditRelease();
|
||||
} else {
|
||||
if (mouse_event_type == MouseEventType::DrawingROI)
|
||||
const bool drawn = (mouse_event_type == MouseEventType::DrawingROI);
|
||||
if (drawn)
|
||||
roiEndPos = RoundPoint(mapToScene(event->pos()));
|
||||
updateROI();
|
||||
if (drawn)
|
||||
roiScratchDrawn(); // turn the drawn scratch box/circle into a persistent ROI
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ protected:
|
||||
virtual bool roiEditPress(const QPointF &scenePos) { return false; }
|
||||
virtual void roiEditMove(const QPointF &scenePos) {}
|
||||
virtual void roiEditRelease() {}
|
||||
virtual void roiScratchDrawn() {} // a shift/ctrl-drag finished drawing a new box/circle
|
||||
QPoint lastMousePos; // To track panning movement
|
||||
|
||||
// Resizing which edge/corner
|
||||
|
||||
Reference in New Issue
Block a user