From 4ba0ecd416a4bacf62cf8288695cb5decad467e7 Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols <federico.montesino-pouzols@stfc.ac.uk> Date: Tue, 6 Oct 2015 16:57:40 +0100 Subject: [PATCH] process events in the image stack event filter, re #13140 --- .../Tomography/IImageCoRView.h | 14 +- .../Tomography/ImageCoRViewQtWidget.h | 26 ++- .../src/Tomography/ImageCoRPresenter.cpp | 14 +- .../src/Tomography/ImageCoRViewQtWidget.cpp | 204 +++++++++++++++--- .../Tomography/TomographyIfaceViewQtGUI.cpp | 2 +- 5 files changed, 222 insertions(+), 38 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/IImageCoRView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/IImageCoRView.h index d0094440c0b..81f64bdb6b8 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/IImageCoRView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/IImageCoRView.h @@ -72,12 +72,21 @@ public: */ virtual ImageStackPreParams userSelection() const = 0; + /** + * The current selection state. For example: nothin/initialized, + * selecting CoR, selecting second corner of the normalization area, + * selecting first corner of the ROI. + * + * @return current state + */ + virtual SelectionState selectionState() const = 0; + /** * Update to a new state (for example select CoR). * * @param new state we're transitioning into. */ - virtual void changeSelectionState(const SelectionState state) = 0; + virtual void changeSelectionState(const SelectionState& state) = 0; /** * Display a special case of stack of images: individual image, from @@ -106,8 +115,7 @@ public: * workspace group was loaded, in whatever directory layout is being * used (unknown to this view). */ - virtual void showStack(Mantid::API::WorkspaceGroup_sptr &ws, - const std::string &m_stackPath) = 0; + virtual void showStack(Mantid::API::WorkspaceGroup_sptr &ws) = 0; /** * Get the stack of images currently being displayed (it has been diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageCoRViewQtWidget.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageCoRViewQtWidget.h index 501924775b0..037de649329 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageCoRViewQtWidget.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageCoRViewQtWidget.h @@ -59,13 +59,15 @@ public: ImageStackPreParams userSelection() const; - void changeSelectionState(const SelectionState state); + SelectionState selectionState() const { return m_selectionState; } + + void changeSelectionState(const SelectionState& state); /// show a stack of images given the path to the files void showStack(const std::string &path); /// show a stack of images that have been loaded into a group of workspaces - void showStack(Mantid::API::WorkspaceGroup_sptr &ws, const std::string &path); + void showStack(Mantid::API::WorkspaceGroup_sptr &ws); const Mantid::API::WorkspaceGroup_sptr stack() const { return m_stack; } @@ -95,6 +97,20 @@ protected: void grabROIFromWidgets(); void grabNormAreaFromWidgets(); + void grabCoRFromMousePoint(int x, int y); + void grabROICorner1FromMousePoint(int x, int y); + void grabROICorner2FromMousePoint(int x, int y); + void grabNormAreaCorner1FromMousePoint(int x, int y); + void grabNormAreaCorner2FromMousePoint(int x, int y); + + void mouseUpdateCoR(int x, int y); + void mouseUpdateROICorners12(int x, int y); + void mouseUpdateROICorner2(int x, int y); + void mouseFinishROI(int x, int y); + void mouseUpdateNormAreaCorners12(int x, int y); + void mouseUpdateNormAreaCorner2(int x, int y); + void mouseFinishNormArea(int x, int y); + private slots: void browseImgClicked(); @@ -119,6 +135,9 @@ private: // widget closing virtual void closeEvent(QCloseEvent *ev); + /// enable/disable the groups with spin boxes for the center and corners + void enableParamWidgets(bool enable); + /// initialize values to defaults and set max/min for the spin boxes void initParamWidgets(size_t maxWidth, size_t maxHeight); void setParamWidgets(ImageStackPreParams ¶ms); @@ -148,6 +167,9 @@ private: /// parameters currently set by the user ImageStackPreParams m_params; + /// max image size for the current stack + int m_imgWidth, m_imgHeight; + /// are we picking the CoR, or the first point of the ROI, etc. SelectionState m_selectionState; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRPresenter.cpp index e65df38784c..e37b4f4c497 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRPresenter.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRPresenter.cpp @@ -157,7 +157,7 @@ void ImageCoRPresenter::processNewStack() { return; } - m_view->showStack(wsg, m_stackPath); + m_view->showStack(wsg); // clean-up container group workspace? Not for now if (false && wsg) @@ -180,11 +180,17 @@ void ImageCoRPresenter::processSelectNormalization() { m_view->changeSelectionState(IImageCoRView::SelectNormAreaFirst); } -void ImageCoRPresenter::processFinishedCoR() {} +void ImageCoRPresenter::processFinishedCoR() { + m_view->changeSelectionState(IImageCoRView::SelectNone); +} -void ImageCoRPresenter::processFinishedROI() {} +void ImageCoRPresenter::processFinishedROI() { + m_view->changeSelectionState(IImageCoRView::SelectNone); +} -void ImageCoRPresenter::processFinishedNormalization() {} +void ImageCoRPresenter::processFinishedNormalization() { + m_view->changeSelectionState(IImageCoRView::SelectNone); +} void ImageCoRPresenter::processResetCoR() { m_view->resetCoR(); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRViewQtWidget.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRViewQtWidget.cpp index 109349cbfeb..3321938acd3 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRViewQtWidget.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/ImageCoRViewQtWidget.cpp @@ -23,8 +23,8 @@ const std::string ImageCoRViewQtWidget::m_settingsGroup = "CustomInterfaces/ImageCoRView"; ImageCoRViewQtWidget::ImageCoRViewQtWidget(QWidget *parent) - : QWidget(parent), IImageCoRView(), m_selectionState(SelectNone), - m_presenter(NULL) { + : QWidget(parent), IImageCoRView(), m_imgWidth(0), m_imgHeight(0), + m_selectionState(SelectNone), m_presenter(NULL) { initLayout(); // using an event filter. might be worth refactoring into a specific @@ -49,6 +49,8 @@ void ImageCoRViewQtWidget::initLayout() { m_ui.horizontalScrollBar_img_stack->setEnabled(false); m_ui.lineEdit_img_seq->setText("---"); + enableParamWidgets(false); + setupConnections(); initParamWidgets(1, 1); @@ -114,10 +116,43 @@ void ImageCoRViewQtWidget::setupConnections() { } bool ImageCoRViewQtWidget::eventFilter(QObject *obj, QEvent *event) { + // quick ignore + if (IImageCoRView::SelectNone == m_selectionState) + return false; + if (m_ui.label_img == obj) { - if (event->type() == QEvent::MouseButtonPress) { - } else if (event->type() == QEvent::MouseButtonRelease) { - } else if (event->type() == QEvent::MouseMove) { + + QPoint p = m_ui.label_img->mapFromGlobal(QCursor::pos()); + int x = p.x(); + int y = p.y(); + // ignore potential clicks outside of the image + if (x >= m_imgWidth || y >= m_imgHeight || x < 0 || y < 0) + return false; + + auto type = event->type(); + if (type == QEvent::MouseButtonPress) { + + if (IImageCoRView::SelectCoR == m_selectionState) { + mouseUpdateCoR(x, y); + } else if (IImageCoRView::SelectROIFirst == m_selectionState) { + mouseUpdateROICorners12(x, y); + } else if (IImageCoRView::SelectNormAreaFirst == m_selectionState) { + mouseUpdateNormAreaCorners12(x, y); + } + } else if (type == QEvent::MouseMove) { + + if (IImageCoRView::SelectROISecond == m_selectionState) { + mouseUpdateROICorner2(x, y); + } else if (IImageCoRView::SelectNormAreaSecond == m_selectionState) { + mouseUpdateNormAreaCorner2(x, y); + } + } else if (type == QEvent::MouseButtonRelease) { + + if (IImageCoRView::SelectROISecond == m_selectionState) { + mouseFinishROI(x, y); + } else if (IImageCoRView::SelectNormAreaSecond == m_selectionState) { + mouseFinishNormArea(x, y); + } } } // pass on the event up to the parent class @@ -130,7 +165,7 @@ void ImageCoRViewQtWidget::valueUpdatedCoR(int) { } void ImageCoRViewQtWidget::valueUpdatedROI(int) { - grabCoRFromWidgets(); + grabROIFromWidgets(); refreshROIetAl(); } @@ -160,6 +195,111 @@ void ImageCoRViewQtWidget::grabNormAreaFromWidgets() { m_ui.spinBox_norm_bottom_y->value())); } +void ImageCoRViewQtWidget::grabCoRFromMousePoint(int x, int y) { + m_params.cor = Mantid::Kernel::V2D(x, y); + m_ui.spinBox_cor_x->setValue(x); + m_ui.spinBox_cor_y->setValue(y); +} + +void ImageCoRViewQtWidget::grabROICorner1FromMousePoint(int x, int y) { + m_params.roi.first = Mantid::Kernel::V2D(x, y); + m_ui.spinBox_roi_top_x->setValue(x); + m_ui.spinBox_roi_top_y->setValue(y); +} + +void ImageCoRViewQtWidget::grabROICorner2FromMousePoint(int x, int y) { + m_params.roi.second = Mantid::Kernel::V2D(x, y); + m_ui.spinBox_roi_bottom_x->setValue(x); + m_ui.spinBox_roi_bottom_y->setValue(y); +} + +void ImageCoRViewQtWidget::grabNormAreaCorner1FromMousePoint(int x, int y) { + m_params.normalizationRegion.first = Mantid::Kernel::V2D(x, y); + m_ui.spinBox_norm_top_x->setValue(x); + m_ui.spinBox_norm_top_y->setValue(y); +} + +void ImageCoRViewQtWidget::grabNormAreaCorner2FromMousePoint(int x, int y) { + m_params.normalizationRegion.second = Mantid::Kernel::V2D(x, y); + m_ui.spinBox_norm_bottom_x->setValue(x); + m_ui.spinBox_norm_bottom_y->setValue(y); +} + +/** + * This is an update and implicity a finish, as there's only one + * update for the CoR (single point-click). The coordinates count as + * usual in Qt widgets. Top-left is (0,0). + * + * @param x position on x axis (local to the image) + * @param x position on y axis (local to the image) + */ +void ImageCoRViewQtWidget::mouseUpdateCoR(int x, int y) { + grabCoRFromMousePoint(x, y); + refreshROIetAl(); + + m_presenter->notify(IImageCoRPresenter::FinishedCoR); +} + +/** + * Start of ROI selection (or first click after pushing "select + * ROI". The rectangle starts as a point from the mouse click. + * + * @param x position on x axis (local to the image) + * @param y position on y axis (local to the image) + */ +void ImageCoRViewQtWidget::mouseUpdateROICorners12(int x, int y) { + grabROICorner1FromMousePoint(x, y); + grabROICorner2FromMousePoint(x, y); + refreshROIetAl(); + m_selectionState = IImageCoRView::SelectROISecond; +} + +/** + * Change the rectangle while pressing the mouse button. The first + * corner stays at the first click, now only the second corner changes + * to the new mouse position. On release of the mouse button we'll get + * to mouseFinishROICorner2() and end the selection of the ROI. + * + * @param x position on x axis (local to the image) + * @param y position on y axis (local to the image) + */ +void ImageCoRViewQtWidget::mouseUpdateROICorner2(int x, int y) { + grabROICorner2FromMousePoint(x, y); + refreshROIetAl(); +} + +/** + * End of ROI selection (or mouse button release after clicking once + * and move, all after pushing "select ROI". The second corner of the + * rectangle is set at the current position. + * + * @param x position on x axis (local to the image) + * @param y position on y axis (local to the image) + */ +void ImageCoRViewQtWidget::mouseFinishROI(int x, int y) { + grabROICorner2FromMousePoint(x, y); + refreshROIetAl(); + m_presenter->notify(IImageCoRPresenter::FinishedROI); +} + +void ImageCoRViewQtWidget::mouseUpdateNormAreaCorners12(int x, int y) { + grabNormAreaCorner1FromMousePoint(x, y); + grabNormAreaCorner2FromMousePoint(x, y); + refreshROIetAl(); + m_selectionState = IImageCoRView::SelectNormAreaSecond; +} + +void ImageCoRViewQtWidget::mouseUpdateNormAreaCorner2(int x, int y) { + grabNormAreaCorner2FromMousePoint(x, y); + refreshROIetAl(); +} + +void ImageCoRViewQtWidget::mouseFinishNormArea(int x, int y) { + grabNormAreaCorner2FromMousePoint(x, y); + refreshROIetAl(); + m_presenter->notify(IImageCoRPresenter::FinishedNormalization); +} + void ImageCoRViewQtWidget::refreshCoR() { const QPixmap *pp = m_ui.label_img->pixmap(); if (!pp) @@ -189,10 +329,6 @@ void ImageCoRViewQtWidget::refreshROIetAl() { if (!pp) return; - grabCoRFromWidgets(); - grabROIFromWidgets(); - grabNormAreaFromWidgets(); - QPixmap toDisplay(*m_basePixmap.get()); QPainter painter(&toDisplay); @@ -275,37 +411,43 @@ void ImageCoRViewQtWidget::setParams(ImageStackPreParams ¶ms) { setParamWidgets(m_params); } +void ImageCoRViewQtWidget::enableParamWidgets(bool enable) { + m_ui.groupBox_cor->setEnabled(enable); + m_ui.groupBox_roi->setEnabled(enable); + m_ui.groupBox_norm->setEnabled(enable); +} + void ImageCoRViewQtWidget::initParamWidgets(size_t maxWidth, size_t maxHeight) { - int width = static_cast<int>(maxWidth); - int height = static_cast<int>(maxHeight); + m_imgWidth = static_cast<int>(maxWidth); + m_imgHeight = static_cast<int>(maxHeight); m_ui.spinBox_cor_x->setMinimum(0); - m_ui.spinBox_cor_x->setMaximum(width - 1); + m_ui.spinBox_cor_x->setMaximum(m_imgWidth - 1); m_ui.spinBox_cor_y->setMinimum(0); - m_ui.spinBox_cor_y->setMaximum(height - 1); + m_ui.spinBox_cor_y->setMaximum(m_imgHeight - 1); resetCoR(); m_ui.spinBox_roi_top_x->setMinimum(0); - m_ui.spinBox_roi_top_x->setMaximum(width - 1); + m_ui.spinBox_roi_top_x->setMaximum(m_imgWidth - 1); m_ui.spinBox_roi_top_y->setMinimum(0); - m_ui.spinBox_roi_top_y->setMaximum(height - 1); + m_ui.spinBox_roi_top_y->setMaximum(m_imgHeight - 1); m_ui.spinBox_roi_bottom_x->setMinimum(0); - m_ui.spinBox_roi_bottom_x->setMaximum(width - 1); + m_ui.spinBox_roi_bottom_x->setMaximum(m_imgWidth - 1); m_ui.spinBox_roi_bottom_y->setMinimum(0); - m_ui.spinBox_roi_bottom_y->setMaximum(height - 1); + m_ui.spinBox_roi_bottom_y->setMaximum(m_imgHeight - 1); resetROI(); m_ui.spinBox_norm_top_x->setMinimum(0); - m_ui.spinBox_norm_top_x->setMaximum(width - 1); + m_ui.spinBox_norm_top_x->setMaximum(m_imgWidth - 1); m_ui.spinBox_norm_top_y->setMinimum(0); - m_ui.spinBox_norm_top_y->setMaximum(height - 1); + m_ui.spinBox_norm_top_y->setMaximum(m_imgHeight - 1); m_ui.spinBox_norm_bottom_x->setMinimum(0); - m_ui.spinBox_norm_bottom_x->setMaximum(width - 1); + m_ui.spinBox_norm_bottom_x->setMaximum(m_imgWidth - 1); m_ui.spinBox_norm_bottom_y->setMinimum(0); - m_ui.spinBox_norm_bottom_y->setMaximum(height - 1); + m_ui.spinBox_norm_bottom_y->setMaximum(m_imgHeight - 1); resetNormArea(); } @@ -336,7 +478,7 @@ ImageStackPreParams ImageCoRViewQtWidget::userSelection() const { } void ImageCoRViewQtWidget::changeSelectionState( - const IImageCoRView::SelectionState state) { + const IImageCoRView::SelectionState &state) { m_selectionState = state; } @@ -345,6 +487,7 @@ void ImageCoRViewQtWidget::corClicked() { } void ImageCoRViewQtWidget::corResetClicked() { m_presenter->notify(IImageCoRPresenter::ResetCoR); + refreshROIetAl(); } void ImageCoRViewQtWidget::roiClicked() { @@ -352,13 +495,15 @@ void ImageCoRViewQtWidget::roiClicked() { } void ImageCoRViewQtWidget::roiResetClicked() { m_presenter->notify(IImageCoRPresenter::ResetROI); + refreshROIetAl(); } void ImageCoRViewQtWidget::normAreaClicked() { - m_presenter->notify(IImageCoRPresenter::SelectROI); + m_presenter->notify(IImageCoRPresenter::SelectNormalization); } void ImageCoRViewQtWidget::normAreaResetClicked() { m_presenter->notify(IImageCoRPresenter::ResetNormalization); + refreshROIetAl(); } void ImageCoRViewQtWidget::browseImgClicked() { @@ -434,10 +579,11 @@ void ImageCoRViewQtWidget::showStack(const std::string & /*path*/) { // we have a firt working version of the "lean MD workspace". This method // would then load into one workspace of such type. // b) load as workspace group - this is done in the overloaded method below + + // enableParamWidgets(true); } -void ImageCoRViewQtWidget::showStack(Mantid::API::WorkspaceGroup_sptr &wsg, - const std::string &stackPath) { +void ImageCoRViewQtWidget::showStack(Mantid::API::WorkspaceGroup_sptr &wsg) { if (0 == wsg->size()) return; @@ -448,8 +594,6 @@ void ImageCoRViewQtWidget::showStack(Mantid::API::WorkspaceGroup_sptr &wsg, m_ui.horizontalScrollBar_img_stack->setMaximum( static_cast<int>(m_stack->size() - 1)); - showProjection(m_stack, 0); - size_t width = 0, height = 0; try { MatrixWorkspace_sptr ws = @@ -465,13 +609,17 @@ void ImageCoRViewQtWidget::showStack(Mantid::API::WorkspaceGroup_sptr &wsg, QString::fromStdString(e.what())); } + showProjection(m_stack, 0); initParamWidgets(width, height); + refreshROIetAl(); + enableParamWidgets(true); } void ImageCoRViewQtWidget::showProjection( const Mantid::API::WorkspaceGroup_sptr &wsg, size_t idx) { showProjectionImage(wsg, idx); + refreshROIetAl(); // give name, set up scroll/slider std::string name; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp index df5a9052eb3..5af8380adb7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp @@ -74,7 +74,7 @@ void TomographyIfaceViewQtGUI::initLayout() { m_ui.tabMain->addTab(tabSetupW, QString("Setup")); ImageCoRViewQtWidget *tabCoRW = new ImageCoRViewQtWidget(m_ui.tabMain); - m_ui.tabMain->addTab(tabCoRW, QString("Center && ROI")); + m_ui.tabMain->addTab(tabCoRW, QString("ROI etc.")); QWidget *tabFiltersW = new QWidget(); m_ui.tabMain->addTab(tabFiltersW, QString("Filters")); -- GitLab