diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeBase.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeBase.h index 74a52048775960e1069155e52a3b2e8f4593ed8c..4ca2a6d79f837a2566b7daa5e1ffaeb6bb9dcf92 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeBase.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeBase.h @@ -52,6 +52,8 @@ public: std::string algorithmName() const; /// Get the version of the algorithm used to make this shape int algorithmVersion() const; + /// Radius + virtual double radius() const = 0; protected: /// Copy constructor diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h index 67c05c5c1ab64e1a02b121ead5e3e2c5edf65b09..1b097d46fcc19d728d1ca92dbaf6b0d281c9d64d 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h @@ -67,6 +67,9 @@ namespace DataObjects /// Get the peak shape std::string shapeName() const; + /// PeakBase interface + double radius() const; + static const std::string ellipsoidShapeName(); private: diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp index c3e0a131080c6fc17678ceddc1ad63deb7738ae3..dab828a13b89acc491ce0f24c802a0c95edd963e 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp @@ -117,6 +117,15 @@ PeakShapeEllipsoid* PeakShapeEllipsoid::clone() const { std::string PeakShapeEllipsoid::shapeName() const { return PeakShapeEllipsoid::ellipsoidShapeName(); } +double PeakShapeEllipsoid::radius() const +{ + double radius = m_abc_radii[0]; + for(int8_t i = 1; i < 3; ++i) { + radius = std::max(radius, m_abc_radii[i]); + } + return radius; +} + const std::string PeakShapeEllipsoid::ellipsoidShapeName() { return "ellipsoid"; diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h index 74438548220d15fc4571f497ea4e1ab05565d6ff..c67bc7c1b049c7daf86372aabe4a224c8e3aca78 100644 --- a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h +++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h @@ -127,6 +127,19 @@ public: TS_ASSERT_EQUALS(a.algorithmVersion(), b.algorithmVersion()); } + void test_radius() { + + std::vector<double> radius = list_of(1)(2)(3); + + + PeakShapeEllipsoid shape(list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1)) + .convert_to_container<std::vector<V3D>>(), + radius, radius, radius, Mantid::Kernel::HKL); + + TSM_ASSERT_EQUALS("Radius should be taken to be the max of the ABC radii", 3.0, shape.radius()); + + } + void test_shape_name() { // Construct it. diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 49dc06327bb29679eaa50ce8827e38e06deac3a9..53f8d9c3b159491693788745e37616ad0271edf8 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -201,7 +201,6 @@ set ( MANTID_SRCS src/Mantid/AlgorithmMonitor.cpp src/Mantid/InstrumentWidget/GLColor.cpp src/Mantid/InstrumentWidget/GLObject.cpp src/Mantid/InstrumentWidget/ICompAssemblyActor.cpp - src/Mantid/InstrumentWidget/InputController.cpp src/Mantid/InstrumentWidget/InstrumentActor.cpp src/Mantid/InstrumentWidget/InstrumentTreeModel.cpp src/Mantid/InstrumentWidget/InstrumentTreeWidget.cpp @@ -438,7 +437,6 @@ set ( MANTID_HDRS src/Mantid/AlgorithmMonitor.h src/Mantid/InstrumentWidget/GLColor.h src/Mantid/InstrumentWidget/GLObject.h src/Mantid/InstrumentWidget/ICompAssemblyActor.h - src/Mantid/InstrumentWidget/InputController.h src/Mantid/InstrumentWidget/InstrumentActor.h src/Mantid/InstrumentWidget/InstrumentTreeModel.h src/Mantid/InstrumentWidget/InstrumentTreeWidget.h @@ -701,7 +699,6 @@ set ( MANTID_MOC_FILES src/Mantid/AlgorithmMonitor.h src/Mantid/UserFitFunctionDialog.h src/Mantid/InstrumentWidget/XIntegrationControl.h src/Mantid/InstrumentWidget/BinDialog.h - src/Mantid/InstrumentWidget/InputController.h src/Mantid/InstrumentWidget/InstrumentTreeModel.h src/Mantid/InstrumentWidget/InstrumentTreeWidget.h src/Mantid/InstrumentWidget/InstrumentWindow.h diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InputController.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InputController.h deleted file mode 100644 index b6e091a52d633c9c18183249de612a3bcb587f29..0000000000000000000000000000000000000000 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InputController.h +++ /dev/null @@ -1,228 +0,0 @@ -#ifndef INPUTCONTROLLER_H -#define INPUTCONTROLLER_H - -#include <QObject> -#include <QRect> -#include <QColor> - -class QMouseEvent; -class QWheelEvent; -class QKeyEvent; -class QPainter; -class QPixmap; - -/** - The base class for the mouse and keyboard controllers to work - with ProjectionSurfaces. Surfaces can be in different interaction - modes and the same mode on different surfaces can involve - different inputs. - - A projection surface keeps a list of controllers: one per interaction mode. - The current controller emits signals which are connected to the relevant slots - on the surface. - - */ -class InputController : public QObject -{ - Q_OBJECT -public: - explicit InputController(QObject *parent, bool contextAllowed = true); - - virtual void mousePressEvent(QMouseEvent*){} - virtual void mouseMoveEvent(QMouseEvent*){} - virtual void mouseReleaseEvent(QMouseEvent*){} - virtual void wheelEvent(QWheelEvent *){} - virtual void keyPressEvent(QKeyEvent*){} - virtual void enterEvent(QEvent*) {} - virtual void leaveEvent(QEvent*) {} - /// To be called after the owner widget has drawn its content - virtual void onPaint(QPainter&){} - /// To be called when this controller takes control of the input. By default emits enabled() signal. - virtual void onEnabled() {emit enabled();} - /// To be called when this controller looses control. By default emits disabled() signal. - virtual void onDisabled() {emit disabled();} - - /// Returns true if a surface using this controller can show - /// a context menu on right-click - bool canShowContextMenu() const {return m_canShowContextMenu;} - -signals: - void enabled(); - void disabled(); - -private: - bool m_canShowContextMenu; -}; - -/** - Controller for moving the instrument on Projection3D surface: - translation, rotation and zooming. - - */ -class InputController3DMove: public InputController -{ - Q_OBJECT - -public: - InputController3DMove(QObject *parent); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - virtual void wheelEvent(QWheelEvent *); - -signals: - /// Init zooming. x and y is the zoom starting point on the screen. - void initZoom(int x, int y); - /// Init rotation. x and y is the starting point on the screen. - void initRotation(int x, int y); - /// Init translation. x and y is the starting point on the screen. - void initTranslation(int x, int y); - /// Zoom - void zoom(int x, int y); - /// Wheel zoom - void wheelZoom(int x, int y, int d); - /// Rotate - void rotate(int x, int y); - /// Translate - void translate(int x, int y); - /// Finish movement - void finish(); - -private: - bool m_isButtonPressed; -}; - -/** - Controller for picking detectors. - */ -class InputControllerPick: public InputController -{ - Q_OBJECT - -public: - InputControllerPick(QObject *parent); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - -signals: - void pickPointAt(int,int); - void touchPointAt(int,int); - void setSelection(const QRect&); - void finishSelection(); - -private: - bool m_isButtonPressed; - QRect m_rect; -}; - -/** - Controller for drawing mask shapes. - */ -class InputControllerDrawShape: public InputController -{ - Q_OBJECT - -public: - InputControllerDrawShape(QObject *parent); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - virtual void keyPressEvent(QKeyEvent*); - virtual void leaveEvent(QEvent*); - -signals: - /// Deselect all selected shapes - void deselectAll(); - /// Add a new shape - void addShape(const QString& type,int x,int y,const QColor& borderColor,const QColor& fillColor); - /// Resize the current shape by moving the right-bottom control point to a location on the screen - void moveRightBottomTo(int,int); - /// Select a shape or a conrol point at a location on the screen. - void selectAt(int,int); - /// Select a shape with ctrl key pressed at a location on the screen. - void selectCtrlAt(int,int); - /// Move selected shape or a control point by a displacement vector. - void moveBy(int,int); - /// Sent when the mouse is moved to a new position with the buttons up - void touchPointAt(int,int); - /// Remove the selected shapes - void removeSelectedShapes(); - /// Restore the cursor to its default image - void restoreOverrideCursor(); - /// Update the rubber band selection - void setSelection(const QRect&); - /// Rubber band selection is done - void finishSelection(const QRect&); - -public slots: - void startCreatingShape2D(const QString& type,const QColor& borderColor,const QColor& fillColor); - void onDisabled(); - -private: - bool m_creating; ///< a shape is being created with a mouse - int m_x,m_y; - QString m_shapeType; - QColor m_borderColor, m_fillColor; - bool m_isButtonPressed; - QRect m_rect; -}; - -/** - Controller for moving the instrument on an unwrapped surface. - */ -class InputControllerMoveUnwrapped: public InputController -{ - Q_OBJECT - -public: - InputControllerMoveUnwrapped(QObject *parent); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - -signals: - void setSelectionRect(const QRect&); - void zoom(); - void unzoom(); - -private: - bool m_isButtonPressed; - QRect m_rect; -}; - -/** - Controller for moving the instrument on an unwrapped surface. - */ -class InputControllerErase: public InputController -{ - Q_OBJECT - -public: - InputControllerErase(QObject *parent); - ~InputControllerErase(); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - virtual void wheelEvent(QWheelEvent *); - - virtual void onPaint(QPainter&); - virtual void enterEvent(QEvent*); - virtual void leaveEvent(QEvent*); - -signals: - void erase(const QRect&); - -private: - void drawCursor(); - - const int m_max_size; - int m_size; ///< Size of the eraser - bool m_isButtonPressed; - bool m_isActive; - QRect m_rect; - QPixmap *m_cursor; - QPixmap *m_image; -}; - -#endif // INPUTCONTROLLER_H diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Projection3D.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Projection3D.cpp index b964aa6d0999d82cac1ff8b419b3f448d8ab8547..d02948d9a19c79fe9251eef460285871c14a0e53 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Projection3D.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Projection3D.cpp @@ -7,11 +7,11 @@ #include "UnwrappedCylinder.h" #include "UnwrappedSphere.h" #include "OpenGLError.h" -#include "InputController.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Objects/Object.h" #include "MantidAPI/MatrixWorkspace.h" +#include "MantidQtMantidWidgets/InputController.h" #include <boost/shared_ptr.hpp> #include <boost/scoped_ptr.hpp> @@ -35,6 +35,7 @@ using namespace Mantid; using namespace Mantid::API; using namespace Mantid::Kernel; using namespace Mantid::Geometry; +using namespace MantidQt::MantidWidgets; Projection3D::Projection3D(const InstrumentActor* rootActor,int winWidth,int winHeight) :ProjectionSurface(rootActor), diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp index 7a33472f9183a66a1fa085eb63db0f6758b070c3..cd8e0151e575838b1d05707d676ee92dc73ba563 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp @@ -2,11 +2,12 @@ #include "GLColor.h" #include "MantidGLWidget.h" #include "OpenGLError.h" -#include "InputController.h" + #include "MantidGeometry/IDetector.h" #include "MantidGeometry/Objects/Object.h" #include "MantidAPI/IPeaksWorkspace.h" +#include "MantidQtMantidWidgets/InputController.h" #include <QRgb> #include <QSet> @@ -22,6 +23,7 @@ #include "MantidKernel/V3D.h" using Mantid::Kernel::V3D; +using namespace MantidQt::MantidWidgets; /** * The constructor. diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h index e53dbacdf73b1589bf8c3235c76988d08c0a71ed..33b4a96a7badc9e2716a931a536476cbb9271d87 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h @@ -27,10 +27,14 @@ namespace Mantid{ class IPeaksWorkspace; } } +namespace MantidQt { + namespace MantidWidgets { + class InputController; + } +} class GLColor; class MantidGLWidget; -class InputController; class QMouseEvent; class QWheelEvent; @@ -245,7 +249,7 @@ protected: QRect selectionRect()const; RectF selectionRectUV()const; size_t getPickID(int x, int y)const; - void setInputController(int mode, InputController* controller); + void setInputController(int mode, MantidQt::MantidWidgets::InputController* controller); void setPeakVisibility() const; //----------------------------------- @@ -270,9 +274,9 @@ protected: private: /// Get the current input controller - InputController* getController() const; + MantidQt::MantidWidgets::InputController* getController() const; - QMap<int,InputController*> m_inputControllers; ///< controllers for mouse and keyboard input + QMap<int,MantidQt::MantidWidgets::InputController*> m_inputControllers; ///< controllers for mouse and keyboard input /// Set when the image must be redrawn mutable bool m_viewChanged; /// Set when the picking image must be redrawn regardless of the interaction mode diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp index 6014dcc2084a78d1abc960b485a0d7896d2b05bb..d83662b41b3b486ee0e4da6bce7f7fb13c2a5f1c 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp @@ -3,11 +3,11 @@ #include "MantidGLWidget.h" #include "OpenGLError.h" #include "PeakMarker2D.h" -#include "InputController.h" #include "MantidGeometry/IDetector.h" #include "MantidGeometry/Objects/Object.h" #include "MantidGeometry/Instrument.h" +#include "MantidQtMantidWidgets/InputController.h" #include <QRgb> #include <QSet> @@ -24,6 +24,7 @@ using namespace Mantid::Geometry; using Mantid::Kernel::Exception::NotFoundError; +using namespace MantidQt::MantidWidgets; UnwrappedDetector::UnwrappedDetector(): u(0), v(0), width(0), height(0), uscale(0), vscale(0), detector() diff --git a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt index d6622fb3eb80fb1b699e334d5e44ba2c59d743b1..bfa83bcd97ac789222829f5e9d80ea33db0866d4 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt +++ b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt @@ -16,6 +16,7 @@ set ( SRC_FILES src/HintingLineEdit.cpp src/InstrumentSelector.cpp src/IndirectInstrumentConfig.cpp + src/InputController.cpp src/MantidHelpWindow.cpp src/MWDiag.cpp src/MWRunFiles.cpp @@ -65,6 +66,7 @@ set ( MOC_FILES inc/MantidQtMantidWidgets/CatalogSelector.h inc/MantidQtMantidWidgets/InstrumentSelector.h inc/MantidQtMantidWidgets/IndirectInstrumentConfig.h + inc/MantidQtMantidWidgets/InputController.h inc/MantidQtMantidWidgets/MantidHelpWindow.h inc/MantidQtMantidWidgets/MessageDisplay.h inc/MantidQtMantidWidgets/MultifitSetupDialog.h diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InputController.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InputController.h new file mode 100644 index 0000000000000000000000000000000000000000..6c2b3ab4330b8d0449a41efd133838c1cdd18e17 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InputController.h @@ -0,0 +1,234 @@ +#ifndef MANTID_MANTIDWIDGETS_INPUTCONTROLLER_H +#define MANTID_MANTIDWIDGETS_INPUTCONTROLLER_H + +#include "WidgetDllOption.h" +#include <QObject> +#include <QRect> +#include <QColor> + +class QMouseEvent; +class QWheelEvent; +class QKeyEvent; +class QPainter; +class QPixmap; + +namespace MantidQt { +namespace MantidWidgets { + +/** + The base class for the mouse and keyboard controllers to work + with ProjectionSurfaces. Surfaces can be in different interaction + modes and the same mode on different surfaces can involve + different inputs. + + A projection surface keeps a list of controllers: one per interaction mode. + The current controller emits signals which are connected to the relevant + slots + on the surface. + + */ +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputController : public QObject { + Q_OBJECT +public: + explicit InputController(QObject *parent, bool contextAllowed = true); + + virtual void mousePressEvent(QMouseEvent *) {} + virtual void mouseMoveEvent(QMouseEvent *) {} + virtual void mouseReleaseEvent(QMouseEvent *) {} + virtual void wheelEvent(QWheelEvent *) {} + virtual void keyPressEvent(QKeyEvent *) {} + virtual void enterEvent(QEvent *) {} + virtual void leaveEvent(QEvent *) {} + /// To be called after the owner widget has drawn its content + virtual void onPaint(QPainter &) {} + /// To be called when this controller takes control of the input. By default + /// emits enabled() signal. + virtual void onEnabled() { emit enabled(); } + /// To be called when this controller looses control. By default emits + /// disabled() signal. + virtual void onDisabled() { emit disabled(); } + + /// Returns true if a surface using this controller can show + /// a context menu on right-click + bool canShowContextMenu() const { return m_canShowContextMenu; } + +signals: + void enabled(); + void disabled(); + +private: + bool m_canShowContextMenu; +}; + +/** + Controller for moving the instrument on Projection3D surface: + translation, rotation and zooming. + + */ +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputController3DMove : public InputController { + Q_OBJECT + +public: + InputController3DMove(QObject *parent); + virtual void mousePressEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void wheelEvent(QWheelEvent *); + +signals: + /// Init zooming. x and y is the zoom starting point on the screen. + void initZoom(int x, int y); + /// Init rotation. x and y is the starting point on the screen. + void initRotation(int x, int y); + /// Init translation. x and y is the starting point on the screen. + void initTranslation(int x, int y); + /// Zoom + void zoom(int x, int y); + /// Wheel zoom + void wheelZoom(int x, int y, int d); + /// Rotate + void rotate(int x, int y); + /// Translate + void translate(int x, int y); + /// Finish movement + void finish(); + +private: + bool m_isButtonPressed; +}; + +/** + Controller for picking detectors. + */ +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerPick : public InputController { + Q_OBJECT + +public: + InputControllerPick(QObject *parent); + virtual void mousePressEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *); + virtual void mouseReleaseEvent(QMouseEvent *); + +signals: + void pickPointAt(int, int); + void touchPointAt(int, int); + void setSelection(const QRect &); + void finishSelection(); + +private: + bool m_isButtonPressed; + QRect m_rect; +}; + +/** + Controller for drawing mask shapes. + */ +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerDrawShape : public InputController { + Q_OBJECT + +public: + InputControllerDrawShape(QObject *parent); + virtual void mousePressEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void keyPressEvent(QKeyEvent *); + virtual void leaveEvent(QEvent *); + +signals: + /// Deselect all selected shapes + void deselectAll(); + /// Add a new shape + void addShape(const QString &type, int x, int y, const QColor &borderColor, + const QColor &fillColor); + /// Resize the current shape by moving the right-bottom control point to a + /// location on the screen + void moveRightBottomTo(int, int); + /// Select a shape or a conrol point at a location on the screen. + void selectAt(int, int); + /// Select a shape with ctrl key pressed at a location on the screen. + void selectCtrlAt(int, int); + /// Move selected shape or a control point by a displacement vector. + void moveBy(int, int); + /// Sent when the mouse is moved to a new position with the buttons up + void touchPointAt(int, int); + /// Remove the selected shapes + void removeSelectedShapes(); + /// Restore the cursor to its default image + void restoreOverrideCursor(); + /// Update the rubber band selection + void setSelection(const QRect &); + /// Rubber band selection is done + void finishSelection(const QRect &); + +public slots: + void startCreatingShape2D(const QString &type, const QColor &borderColor, + const QColor &fillColor); + void onDisabled(); + +private: + bool m_creating; ///< a shape is being created with a mouse + int m_x, m_y; + QString m_shapeType; + QColor m_borderColor, m_fillColor; + bool m_isButtonPressed; + QRect m_rect; +}; + +/** + Controller for moving the instrument on an unwrapped surface. + */ +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerMoveUnwrapped : public InputController { + Q_OBJECT + +public: + InputControllerMoveUnwrapped(QObject *parent); + virtual void mousePressEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *); + virtual void mouseReleaseEvent(QMouseEvent *); + +signals: + void setSelectionRect(const QRect &); + void zoom(); + void unzoom(); + +private: + bool m_isButtonPressed; + QRect m_rect; +}; + +/** + Controller for moving the instrument on an unwrapped surface. + */ +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerErase : public InputController { + Q_OBJECT + +public: + InputControllerErase(QObject *parent); + ~InputControllerErase(); + virtual void mousePressEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void wheelEvent(QWheelEvent *); + + virtual void onPaint(QPainter &); + virtual void enterEvent(QEvent *); + virtual void leaveEvent(QEvent *); + +signals: + void erase(const QRect &); + +private: + void drawCursor(); + + const int m_max_size; + int m_size; ///< Size of the eraser + bool m_isButtonPressed; + bool m_isActive; + QRect m_rect; + QPixmap *m_cursor; + QPixmap *m_image; +}; +} +} + +#endif // MANTID_MANTIDWIDGETS_INPUTCONTROLLER_H diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InputController.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/InputController.cpp similarity index 98% rename from Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InputController.cpp rename to Code/Mantid/MantidQt/MantidWidgets/src/InputController.cpp index 975dbd2960d451567afd0838fcac84862af4301d..b707dea7b2dd8c6e402b5d0c3b5745f80c846bec 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InputController.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/InputController.cpp @@ -1,4 +1,4 @@ -#include "InputController.h" +#include "MantidQtMantidWidgets/InputController.h" #include <QMouseEvent> #include <QPainter> @@ -8,6 +8,9 @@ #include <iostream> +namespace MantidQt { +namespace MantidWidgets { + //-------------------------------------------------------------------------------- InputController::InputController(QObject *parent, bool contextAllowed) : @@ -418,4 +421,6 @@ void InputControllerErase::drawCursor() m_rect.setSize( QSize(m_size,m_size) ); } +} +} diff --git a/Code/Mantid/MantidQt/SliceViewer/CMakeLists.txt b/Code/Mantid/MantidQt/SliceViewer/CMakeLists.txt index fb6925ffa7d87a266411ebc5976b2a05c0e0e891..02ce58efc0b5be5474502527b99a510a1103edbe 100644 --- a/Code/Mantid/MantidQt/SliceViewer/CMakeLists.txt +++ b/Code/Mantid/MantidQt/SliceViewer/CMakeLists.txt @@ -8,6 +8,7 @@ set ( SRC_FILES src/LineViewer.cpp src/PeakBoundingBox.cpp src/PeaksViewerOverlayDialog.cpp + src/PeakOverlayInteractive.cpp src/PeakOverlayMultiCross.cpp src/PeakOverlayMultiCrossFactory.cpp src/PeakOverlayMultiSphere.cpp @@ -42,7 +43,9 @@ set ( INC_FILES inc/MantidQtSliceViewer/LinePlotOptions.h inc/MantidQtSliceViewer/LineViewer.h inc/MantidQtSliceViewer/NullPeaksPresenter.h - inc/MantidQtSliceViewer/PeakBoundingBox.h + inc/MantidQtSliceViewer/PeakEditMode.h + inc/MantidQtSliceViewer/PeakBoundingBox.h + inc/MantidQtSliceViewer/PeakOverlayInteractive.h inc/MantidQtSliceViewer/PeakOverlayMultiCross.h inc/MantidQtSliceViewer/PeakOverlayMultiCrossFactory.h inc/MantidQtSliceViewer/PeakOverlayMultiSphere.h @@ -77,6 +80,7 @@ set ( MOC_FILES inc/MantidQtSliceViewer/LineOverlay.h inc/MantidQtSliceViewer/LineViewer.h inc/MantidQtSliceViewer/LinePlotOptions.h + inc/MantidQtSliceViewer/PeakOverlayInteractive.h inc/MantidQtSliceViewer/PeakOverlayMultiCross.h inc/MantidQtSliceViewer/PeakOverlayMultiSphere.h inc/MantidQtSliceViewer/PeaksTableColumnsDialog.h @@ -136,7 +140,9 @@ set ( ALL_SRC ${SRC_FILES} ${MOCCED_FILES} ) qt4_wrap_ui ( UI_HDRS ${UI_FILES} ) -include_directories ( ${CMAKE_CURRENT_BINARY_DIR} ) +include_directories ( ${CMAKE_CURRENT_BINARY_DIR}) + +include_directories ( ../../Framework/DataObjects/inc ) # For Windows: add_definitions ( -DIN_MANTIDQT_SLICEVIEWER ) @@ -152,6 +158,7 @@ endif () target_link_libraries ( MantidQtSliceViewer LINK_PRIVATE MantidQtAPI MantidWidgets + DataObjects ${CORE_MANTIDLIBS} ${POCO_LIBRARIES} ${Boost_LIBRARIES} @@ -177,7 +184,7 @@ if ( CXXTEST_FOUND ) ) cxxtest_add_test ( SliceViewerTest ${TEST_FILES} ${GMOCK_TEST_FILES} ) - target_link_libraries( SliceViewerTest LINK_PRIVATE + target_link_libraries( SliceViewerTest LINK_PRIVATE MantidQtSliceViewer DataObjects Crystal diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/CompositePeaksPresenter.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/CompositePeaksPresenter.h index 5e0ddeca1c6fcac8582b6c2ec9075fd819671ce2..c4d185001028bf4f3e97b92779cdd66a48279910 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/CompositePeaksPresenter.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/CompositePeaksPresenter.h @@ -3,6 +3,7 @@ #include "MantidQtSliceViewer/PeaksPresenter.h" #include "MantidQtSliceViewer/NullPeaksPresenter.h" +#include "MantidQtSliceViewer/PeakBoundingBox.h" #include "MantidQtSliceViewer/PeakPalette.h" #include "MantidQtSliceViewer/ZoomablePeaksView.h" #include "MantidQtSliceViewer/UpdateableOnDemand.h" @@ -11,6 +12,7 @@ #include <stdexcept> #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> +#include <boost/weak_ptr.hpp> namespace Mantid { namespace API { @@ -62,6 +64,8 @@ public: virtual void reInitialize( boost::shared_ptr<Mantid::API::IPeaksWorkspace> ) { /*Do nothing*/ } + virtual bool deletePeaksIn(PeakBoundingBox box); + virtual bool addPeakAt(double plotCoordsPointX, double plotCoordsPointY); /// Constructor CompositePeaksPresenter(ZoomablePeaksView *const zoomablePlottingWidget, @@ -83,6 +87,8 @@ public: virtual double getPeakSizeOnProjection() const; /// Get the peaks size into the current projection virtual double getPeakSizeIntoProjection() const; + /// Enter peak edit mode. + void peakEditMode(EditMode mode); /// Change the foreground representation for the peaks of this workspace void setForegroundColour(boost::shared_ptr<const Mantid::API::IPeaksWorkspace> ws, @@ -141,6 +147,12 @@ public: boost::shared_ptr<Mantid::API::IPeaksWorkspace> &changedPeaksWS); /// Determine if the presenter contents are different. bool contentsDifferent(PeaksPresenter const * other) const; + /// Enter the requested edit mode for the peaks workspace. + void editCommand(EditMode editMode, boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target); + /// Can we add peaks to this peaks workspace. + bool hasPeakAddModeFor(boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target); + /// Can we add peaks + bool hasPeakAddMode() const; private: /// Updateable on demand method. void updatePeaksWorkspace( @@ -173,6 +185,7 @@ private: /// index of peak zoomed in on. int m_zoomedPeakIndex; }; + } } diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ConcretePeaksPresenter.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ConcretePeaksPresenter.h index 8abe438eaec156b485effdf37be1bdfabf617c3f..97866336a2d0af1660199dfa070c64d19b701996 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ConcretePeaksPresenter.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ConcretePeaksPresenter.h @@ -57,6 +57,10 @@ public: virtual void zoomToPeak(const int index); virtual bool isHidden() const; virtual bool contentsDifferent(PeaksPresenter const * other) const; + virtual void peakEditMode(EditMode mode); + virtual bool deletePeaksIn(PeakBoundingBox plotCoordsBox); + virtual bool addPeakAt(double plotCoordsPointX, double plotCoordsPointY); + virtual bool hasPeakAddMode() const; private: /// Peak overlay view. @@ -77,6 +81,11 @@ private: UpdateableOnDemand *m_owningPresenter; /// Flag to indicate that this is hidden. bool m_isHidden; + /// Flag to indicate the current edit mode. + EditMode m_editMode; + /// Can we add to this peaks workspace + bool m_hasAddPeaksMode; + /// Configure peak transformations bool configureMappingTransform(); /// Hide all views @@ -99,7 +108,13 @@ private: void informOwnerUpdate(); /// initialize the setup void initialize(); + /// Find visible peak indexes. Those inside the bounding box, or interacting with the edges of the box. + std::vector<size_t> findVisiblePeakIndexes(const PeakBoundingBox &box, const bool pointOnlyMode); + /// Set the visible peak list. + void setVisiblePeaks(const std::vector<size_t>& indexes); }; + + } } diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/NullPeaksPresenter.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/NullPeaksPresenter.h index cf9ca36a843acde027c7b5da476633fe3115d3c6..30acbb69a4cd362e90419561aa05fa9c97546b05 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/NullPeaksPresenter.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/NullPeaksPresenter.h @@ -2,6 +2,7 @@ #define MANTID_SLICEVIEWER_NULLPEAKSPRESENTER_H_ #include "MantidQtSliceViewer/PeaksPresenter.h" +#include "MantidQtSliceViewer/PeakBoundingBox.h" namespace MantidQt { namespace SliceViewer { @@ -50,7 +51,13 @@ public: boost::shared_ptr<Mantid::API::IPeaksWorkspace> ) { /*Do nothing*/ } virtual bool contentsDifferent(const PeaksPresenter * ) const { return true; } + + void peakEditMode(EditMode){/*Do nothing*/} + bool deletePeaksIn(PeakBoundingBox){return false;/*Do nothing. Delete nothing.*/} + bool addPeakAt(double, double){return false;/*Do nothing. Add nothing.*/} + bool hasPeakAddMode() const {return false; /*Do nothing.*/} }; + } } diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakEditMode.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakEditMode.h new file mode 100644 index 0000000000000000000000000000000000000000..2c6bbb5a2fb73d32a577730dffbfb3befcc95fe7 --- /dev/null +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakEditMode.h @@ -0,0 +1,11 @@ +#ifndef MANTID_SLICEVIEWER_EDITMODE_H_ +#define MANTID_SLICEVIEWER_EDITMODE_H_ + +namespace MantidQt { +namespace SliceViewer { + +// Possible edit modes. +enum EditMode { None = 0, AddPeaks = 1, DeletePeaks = 2 }; +} +} +#endif diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayInteractive.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayInteractive.h new file mode 100644 index 0000000000000000000000000000000000000000..83de6efeeeca828b7991429c84fbb9d7319f6841 --- /dev/null +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayInteractive.h @@ -0,0 +1,111 @@ +#ifndef MANTID_SLICEVIEWER_PEAKOVERLAYINTERACTIVE_H_ +#define MANTID_SLICEVIEWER_PEAKOVERLAYINTERACTIVE_H_ + +#include "DllOption.h" +#include "MantidQtSliceViewer/PeakOverlayView.h" +#include <QtGui/QWidget> +#include <QtGui/QCursor> + +// Forward dec +class QwtPlot; +class QRect; + +namespace MantidQt { + +namespace MantidWidgets { +// Forward dec +class InputController; +} + +namespace SliceViewer { +// Forward dec +class PeaksPresenter; + +/** Widget base class for representing peaks. Contains common code used by + Interactive/Editable peak overlay widgets. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakOverlayInteractive : public QWidget, public PeakOverlayView { + Q_OBJECT + +public: + /// Constructor + PeakOverlayInteractive(PeaksPresenter *const peaksPresenter, QwtPlot *plot, + const int plotXIndex, const int plotYIndex, QWidget *parent); + /// Destructor + virtual ~PeakOverlayInteractive(); + + /// Enter peak deletion mode. + void peakDeletionMode(); + /// Enter peak addition mode + void peakAdditionMode(); + /// Enter display mode + void peakDisplayMode(); + + QSize sizeHint() const; + QSize size() const; + int height() const; + int width() const; + +protected: + /// Owning presenter + PeaksPresenter *m_presenter; + /// QwtPlot containing this + QwtPlot *m_plot; + /// Plot x index + const int m_plotXIndex; + /// Plot y index + const int m_plotYIndex; + +private: + /// Input controller. + MantidQt::MantidWidgets::InputController *m_tool; + + void mousePressEvent(QMouseEvent* e); + void mouseMoveEvent(QMouseEvent* e); + void mouseReleaseEvent(QMouseEvent* e); + void wheelEvent(QWheelEvent* e); + void keyPressEvent(QKeyEvent* e); + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + + void paintEvent(QPaintEvent *event); + + // Call do paint on sub-classes + virtual void doPaintPeaks(QPaintEvent *event) = 0; + + void captureMouseEvents(bool capture); + +private slots: + + void erasePeaks(const QRect &rect); + void addPeakAt(int coordX, int coordY); + + +}; + + +} +} + +#endif //MANTID_SLICEVIEWER_PEAKOVERLAYINTERACTIVE_H_ diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCross.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCross.h index b04d06f859581246752baf754294464d0d791b84..532c28e1f42736629773f461355d17aab7f06e89 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCross.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCross.h @@ -1,24 +1,25 @@ #ifndef MANTID_SLICEVIEWER_PEAKOVERLAYMULTICROSS_H_ #define MANTID_SLICEVIEWER_PEAKOVERLAYMULTICROSS_H_ +#include "MantidQtSliceViewer/PeakOverlayInteractive.h" #include "DllOption.h" -#include "MantidKernel/System.h" -#include "MantidKernel/V3D.h" -#include <q3iconview.h> -#include <QtCore/QtCore> -#include <QtGui/qwidget.h> -#include <qwt_plot.h> -#include <qpainter.h> -#include <qcolor.h> -#include "MantidQtSliceViewer/PeakOverlayView.h" #include "MantidQtSliceViewer/PhysicalCrossPeak.h" +class QPaintEvent; +class QwtPlot; namespace MantidQt { + +namespace MantidWidgets { +// Forward declaration +class InputController; +} + namespace SliceViewer { + class PeaksPresenter; /** Widget representing visible peaks in the plot. @date 2013-06-10 @@ -43,13 +44,14 @@ namespace SliceViewer File change history is stored at: <https://github.com/mantidproject/mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ - class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakOverlayMultiCross : public QWidget, public PeakOverlayView + class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakOverlayMultiCross : public PeakOverlayInteractive { Q_OBJECT public: /// Constructor - PeakOverlayMultiCross(QwtPlot * plot, QWidget * parent, const VecPhysicalCrossPeak& vecPhysicalPeaks, const QColor& peakColour); + PeakOverlayMultiCross(PeaksPresenter* const peaksPresenter, QwtPlot * plot, QWidget * parent, const VecPhysicalCrossPeak& vecPhysicalPeaks, const int plotXIndex, const int plotYIndex, + const QColor& peakColour); /// Destructor virtual ~PeakOverlayMultiCross(); /// Set the slice point at position. @@ -87,24 +89,25 @@ namespace SliceViewer /// Get the background colour virtual QColor getBackgroundColour() const; - private: + /// Take settings from another view + virtual void takeSettingsFrom(const PeakOverlayView * const); - //QRect drawHandle(QPainter & painter, QPointF coords, QColor brush); - void paintEvent(QPaintEvent *event); + private: - QSize sizeHint() const; - QSize size() const; - int height() const; - int width() const; + /// Pure virtual on PeakOverlayInteractive + virtual void doPaintPeaks(QPaintEvent*); - /// QwtPlot containing this - QwtPlot * m_plot; /// Physical model of the spacial cross peaks VecPhysicalCrossPeak m_physicalPeaks; /// Peak colour QColor m_peakColour; /// Peaks in the workspace that are viewable in the present view. std::vector<bool> m_viewablePeaks; + /// Cached occupancy into the view + double m_cachedOccupancyIntoView; + /// Cached occupancy onto view + double m_cachedOccupancyInView; + }; diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCrossFactory.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCrossFactory.h index 6beade764bf16741399a549c21c6904faa6850f5..1d92011f20d40048cdf57dca29f72b03ea3908c6 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCrossFactory.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiCrossFactory.h @@ -11,6 +11,8 @@ namespace MantidQt namespace SliceViewer { + class PeaksPresenter; + /** Concrete view factory. For creating instances of PeakOverlayMultiCross widget. @date 2013-06-10 @@ -38,9 +40,9 @@ namespace MantidQt class DLLExport PeakOverlayMultiCrossFactory : public PeakOverlayViewFactoryBase { public: - PeakOverlayMultiCrossFactory(boost::shared_ptr<Mantid::API::MDGeometry> mdWS, Mantid::Geometry::PeakTransform_const_sptr transform, Mantid::API::IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const size_t colourNumber=0); + PeakOverlayMultiCrossFactory(boost::shared_ptr<Mantid::API::MDGeometry> mdWS, Mantid::Geometry::PeakTransform_const_sptr transform, Mantid::API::IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const int plotXIndex, const int plotYIndex, const size_t colourNumber=0); virtual ~PeakOverlayMultiCrossFactory(); - virtual boost::shared_ptr<PeakOverlayView> createView(Mantid::Geometry::PeakTransform_const_sptr transform) const; + virtual boost::shared_ptr<PeakOverlayView> createView(PeaksPresenter* const presenter, Mantid::Geometry::PeakTransform_const_sptr transform) const; virtual int FOM() const; virtual void swapPeaksWorkspace(boost::shared_ptr<Mantid::API::IPeaksWorkspace>& peaksWS); private: diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphere.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphere.h index 34d9a8175dbb58e721dd904c6476397a28c795bb..23d1629522919c221e7672815b3ccc4095759c7a 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphere.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphere.h @@ -1,23 +1,23 @@ #ifndef MANTID_SLICEVIEWER_PEAKOVERLAYMULTISPHERE_H_ #define MANTID_SLICEVIEWER_PEAKOVERLAYMULTISPHERE_H_ -#include "DllOption.h" -#include "MantidKernel/System.h" -#include "MantidKernel/V3D.h" -#include <q3iconview.h> -#include <QtCore/QtCore> -#include <QtGui/qwidget.h> -#include <qwt_plot.h> -#include <qpainter.h> -#include <qcolor.h> -#include "MantidQtSliceViewer/PeakOverlayView.h" +#include "MantidQtSliceViewer/PeakOverlayInteractive.h" #include "MantidQtSliceViewer/PhysicalSphericalPeak.h" +#include "DllOption.h" +class QwtPlot; +class QWidget; namespace MantidQt { + +namespace MantidWidgets { +class InputController; +} + namespace SliceViewer { + class PeaksPresenter; /** Widget representing a peak sphere on the plot. Used for representing spherically integrated peaks. @@ -43,13 +43,14 @@ namespace SliceViewer File change history is stored at: <https://github.com/mantidproject/mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ - class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakOverlayMultiSphere : public QWidget, public PeakOverlayView + class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakOverlayMultiSphere : public PeakOverlayInteractive { Q_OBJECT public: /// Constructor - PeakOverlayMultiSphere(QwtPlot * plot, QWidget * parent, const VecPhysicalSphericalPeak& vecPhysicalPeaks, const QColor& peakColour, const QColor& backColour); + PeakOverlayMultiSphere(PeaksPresenter* const presenter, QwtPlot * plot, QWidget * parent, const VecPhysicalSphericalPeak& vecPhysicalPeaks, const int plotXIndex, const int plotYIndex, + const QColor& peakColour, const QColor& backColour); /// Destructor virtual ~PeakOverlayMultiSphere(); /// Set the slice point at position. @@ -88,19 +89,13 @@ namespace SliceViewer virtual QColor getBackgroundColour() const; /// Get the current foreground colour virtual QColor getForegroundColour() const; + /// Take settings from another view + void takeSettingsFrom(const PeakOverlayView * const); private: - //QRect drawHandle(QPainter & painter, QPointF coords, QColor brush); - void paintEvent(QPaintEvent *event); - - QSize sizeHint() const; - QSize size() const; - int height() const; - int width() const; - - /// QwtPlot containing this - QwtPlot * m_plot; + /// Draw the peak representations. Pure virtual on base class. + virtual void doPaintPeaks(QPaintEvent *); /// Physical peak object VecPhysicalSphericalPeak m_physicalPeaks; /// Peak colour @@ -111,6 +106,7 @@ namespace SliceViewer std::vector<bool> m_viewablePeaks; /// Show the background radius. bool m_showBackground; + /// Input controller. }; diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphereFactory.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphereFactory.h index 38cb3c3c3a91f9a114b7a16eb7b63acb6b987980..ab9e89828b95ed110b1867defc516e89a2e6b164 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphereFactory.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayMultiSphereFactory.h @@ -9,6 +9,8 @@ namespace MantidQt { namespace SliceViewer { + class PeaksPresenter; + /** Concrete view factory. For creating instances of PeakOverlayMultiSphere widget. @date 2013-06-12 @@ -42,9 +44,9 @@ namespace MantidQt Mantid::API::IPeaksWorkspace_sptr m_peaksWS; int m_FOM; public: - PeakOverlayMultiSphereFactory(Mantid::API::IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const size_t colourNumber=0); + PeakOverlayMultiSphereFactory(Mantid::API::IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const int plotXIndex, const int plotYIndex, const size_t colourNumber=0); virtual ~PeakOverlayMultiSphereFactory(); - virtual boost::shared_ptr<PeakOverlayView> createView(Mantid::Geometry::PeakTransform_const_sptr transform) const; + virtual boost::shared_ptr<PeakOverlayView> createView(PeaksPresenter* const presenter, Mantid::Geometry::PeakTransform_const_sptr transform) const; virtual int FOM() const; virtual void swapPeaksWorkspace(boost::shared_ptr<Mantid::API::IPeaksWorkspace>& peaksWS); }; diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayView.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayView.h index 78170a4a40a6efa0db0729142adc7fff8e02221d..4ad5cdbeb9d4e37092739fb36d8bb38253419007 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayView.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayView.h @@ -76,6 +76,14 @@ namespace MantidQt virtual QColor getBackgroundColour() const = 0; /// Get the current foreground colour virtual QColor getForegroundColour() const = 0; + /// Enter deletion mode + virtual void peakDeletionMode() = 0; + /// Enter addition mode + virtual void peakAdditionMode() = 0; + /// Enter normal view mode + virtual void peakDisplayMode() = 0; + /// Take settings from. + virtual void takeSettingsFrom(PeakOverlayView const * const) = 0; /// Destructor virtual ~PeakOverlayView() { diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactory.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactory.h index aba79e76f54e3418489358bc99a8a02eadb574ff..23a925721a4c01783d33ee83d754d23c761b4945 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactory.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactory.h @@ -23,6 +23,8 @@ namespace MantidQt { namespace SliceViewer { + class PeaksPresenter; + /** Abstract view factory. For creating types of IPeakOverlay. @date 2012-08-24 @@ -51,7 +53,7 @@ namespace MantidQt { public: /// Create a peak view from the index of a peak in the peaks workspace - virtual boost::shared_ptr<PeakOverlayView> createView(Mantid::Geometry::PeakTransform_const_sptr transform) const = 0; + virtual boost::shared_ptr<PeakOverlayView> createView(PeaksPresenter* const presenter, Mantid::Geometry::PeakTransform_const_sptr transform) const = 0; /// Destructor virtual ~PeakOverlayViewFactory() { diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactoryBase.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactoryBase.h index a989d55b6099f36a44ccaee49dc3dac277c675ff..d97935981e852d208b2e8b12eef595358ac205eb 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactoryBase.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactoryBase.h @@ -43,8 +43,10 @@ namespace MantidQt QWidget * m_parent; QColor m_peakColour; QColor m_backColour; + const int m_plotXIndex; + const int m_plotYIndex; public: - PeakOverlayViewFactoryBase(QwtPlot * plot, QWidget * parent, const size_t colourNumber=0); + PeakOverlayViewFactoryBase(QwtPlot * plot, QWidget * parent, const int plotXIndex, const int plotYIndex, const size_t colourNumber=0); virtual ~PeakOverlayViewFactoryBase(); virtual std::string getPlotXLabel() const; virtual std::string getPlotYLabel() const; @@ -52,4 +54,4 @@ namespace MantidQt } } -#endif /*MANTID_SLICEVIEWER_PEAKOVERLAYVIEWFACTORYBASE_H_*/ \ No newline at end of file +#endif /*MANTID_SLICEVIEWER_PEAKOVERLAYVIEWFACTORYBASE_H_*/ diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksPresenter.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksPresenter.h index d312d812824fef1e460d5548f85e710abb12b4eb..b31d22617b8efa4cade71bb6b1b959519d09707d 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksPresenter.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksPresenter.h @@ -3,13 +3,20 @@ #include "DllOption.h" #include <boost/shared_ptr.hpp> +#include "MantidQtSliceViewer/PeakEditMode.h" #include "MantidQtSliceViewer/PeakPalette.h" #include "MantidQtSliceViewer/PeakBoundingBox.h" + #include <set> #include <QObject> namespace Mantid { + namespace Kernel{ + // Forward dec + class V3D; + } + namespace Geometry { // Forward dec. class PeakTransform; @@ -67,8 +74,12 @@ namespace SliceViewer virtual void zoomToPeak(const int peakIndex) = 0; virtual bool isHidden() const = 0; virtual bool contentsDifferent(PeaksPresenter const * other) const = 0; - virtual ~PeaksPresenter(){}; virtual void reInitialize(boost::shared_ptr<Mantid::API::IPeaksWorkspace> peaksWS) = 0; + virtual void peakEditMode(EditMode mode) = 0; + virtual bool deletePeaksIn(PeakBoundingBox plotCoordsBox) = 0; + virtual bool addPeakAt(double plotCoordsPointX, double plotCoordsPointY) =0; + virtual bool hasPeakAddMode() const = 0; + virtual ~PeaksPresenter(){}; }; diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksViewer.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksViewer.h index 36e5099f75c2ab3bea03a987e8b14b5f0ebed4a1..ef59eee619fc2c34b5638f78cb4542fcc856f759 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksViewer.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksViewer.h @@ -19,6 +19,7 @@ namespace MantidQt { namespace SliceViewer { /// Forward dec. class ProxyCompositePeaksPresenter; +class PeaksWorkspaceWidget; /** @@ -40,6 +41,8 @@ public: void hide(); ~PeaksViewer(); bool hasThingsToShow() const; + void clearPeaksModeRequest(PeaksWorkspaceWidget const * const originWidget, const bool on); + void addPeaksModeRequest(PeaksWorkspaceWidget const * const originWidget, const bool on); public slots: void onPeakColourChanged(Mantid::API::IPeaksWorkspace_const_sptr, QColor); diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.h index eb3e25bdd06feba9a131515887f73f8d623474fb..c1d2aedb2e9a3d08f9aa7e5414c09a6e5076cdf6 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.h @@ -5,66 +5,78 @@ #include "DllOption.h" #include "MantidAPI/IPeaksWorkspace.h" #include "ui_PeaksWorkspaceWidget.h" -namespace MantidQt -{ -namespace SliceViewer -{ - class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeaksWorkspaceWidget : public QWidget - { - Q_OBJECT - public: - PeaksWorkspaceWidget(Mantid::API::IPeaksWorkspace_const_sptr ws, const std::string& coordinateSystem, const QColor& defaultForegroundColour, const QColor& defaultBackgroundColour, QWidget *parent = 0); - std::set<QString> getShownColumns(); - void setShownColumns(std::set<QString> & cols); - virtual ~PeaksWorkspaceWidget(); - Mantid::API::IPeaksWorkspace_const_sptr getPeaksWorkspace() const; - void setBackgroundColor(const QColor& backgroundColor); - void setForegroundColor(const QColor& foregroundColor); - void setShowBackground(bool showBackground); - void setHidden(bool isHidden); - void setSelectedPeak(int index); - std::string getWSName() const; - void workspaceUpdate(Mantid::API::IPeaksWorkspace_const_sptr ws = Mantid::API::IPeaksWorkspace_const_sptr()); - signals: - void peakColourChanged(Mantid::API::IPeaksWorkspace_const_sptr, QColor); - void backgroundColourChanged(Mantid::API::IPeaksWorkspace_const_sptr, QColor); - void backgroundRadiusShown(Mantid::API::IPeaksWorkspace_const_sptr, bool); - void removeWorkspace(Mantid::API::IPeaksWorkspace_const_sptr); - void hideInPlot(Mantid::API::IPeaksWorkspace_const_sptr, bool); - void zoomToPeak(Mantid::API::IPeaksWorkspace_const_sptr, int); - void peaksSorted(const std::string&, const bool, Mantid::API::IPeaksWorkspace_const_sptr); - private: - /// Populate the widget with model data. - void populate(); - /// Create the MVC table for peaks display - void createTableMVC(); - /// Auto-generated UI controls. - Ui::PeaksWorkspaceWidget ui; - /// Peaks workspace to view. - Mantid::API::IPeaksWorkspace_const_sptr m_ws; - /// Coordinate system. - const std::string m_coordinateSystem; - /// Foreground colour - QColor m_foregroundColour; - /// Background colour - QColor m_backgroundColour; - /// Original table width - int m_originalTableWidth; - /// Workspace name. - QString m_nameText; - /// Current index changed - overrriden +namespace MantidQt { +namespace SliceViewer { +class PeaksViewer; +class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeaksWorkspaceWidget : public QWidget { + Q_OBJECT +public: + PeaksWorkspaceWidget(Mantid::API::IPeaksWorkspace_const_sptr ws, + const std::string &coordinateSystem, + const QColor &defaultForegroundColour, + const QColor &defaultBackgroundColour, + const bool canAddPeaks, + PeaksViewer *parent); - private slots: - void onBackgroundColourClicked(); - void onForegroundColourClicked(); - void onShowBackgroundChanged(bool); - void onRemoveWorkspaceClicked(); - void onToggleHideInPlot(); - void onPeaksSorted(const std::string&, const bool); - void onCurrentChanged(QModelIndex, QModelIndex); - }; + std::set<QString> getShownColumns(); + void setShownColumns(std::set<QString> &cols); + virtual ~PeaksWorkspaceWidget(); + Mantid::API::IPeaksWorkspace_const_sptr getPeaksWorkspace() const; + void setBackgroundColor(const QColor &backgroundColor); + void setForegroundColor(const QColor &foregroundColor); + void setShowBackground(bool showBackground); + void setHidden(bool isHidden); + void setSelectedPeak(int index); + std::string getWSName() const; + void workspaceUpdate(Mantid::API::IPeaksWorkspace_const_sptr ws = + Mantid::API::IPeaksWorkspace_const_sptr()); + void exitClearPeaksMode(); + void exitAddPeaksMode(); +signals: + void peakColourChanged(Mantid::API::IPeaksWorkspace_const_sptr, QColor); + void backgroundColourChanged(Mantid::API::IPeaksWorkspace_const_sptr, QColor); + void backgroundRadiusShown(Mantid::API::IPeaksWorkspace_const_sptr, bool); + void removeWorkspace(Mantid::API::IPeaksWorkspace_const_sptr); + void hideInPlot(Mantid::API::IPeaksWorkspace_const_sptr, bool); + void zoomToPeak(Mantid::API::IPeaksWorkspace_const_sptr, int); + void peaksSorted(const std::string &, const bool, + Mantid::API::IPeaksWorkspace_const_sptr); -} //namespace +private: + /// Populate the widget with model data. + void populate(); + /// Create the MVC table for peaks display + void createTableMVC(); + /// Auto-generated UI controls. + Ui::PeaksWorkspaceWidget ui; + /// Peaks workspace to view. + Mantid::API::IPeaksWorkspace_const_sptr m_ws; + /// Coordinate system. + const std::string m_coordinateSystem; + /// Foreground colour + QColor m_foregroundColour; + /// Background colour + QColor m_backgroundColour; + /// Original table width + int m_originalTableWidth; + /// Workspace name. + QString m_nameText; + /// Parent widget + PeaksViewer* const m_parent; + +private slots: + void onBackgroundColourClicked(); + void onForegroundColourClicked(); + void onShowBackgroundChanged(bool); + void onRemoveWorkspaceClicked(); + void onToggleHideInPlot(); + void onPeaksSorted(const std::string &, const bool); + void onCurrentChanged(QModelIndex, QModelIndex); + void onClearPeaksToggled(bool); + void onAddPeaksToggled(bool); +}; + +} // namespace } #endif // PEAKSWORKSPACEWIDGET_H diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.ui b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.ui index f6e2551044b09973be544cc338049cceb00626f1..4e96f3d638618b89b9fa4ea98aa132edfb06a3f0 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.ui +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeaksWorkspaceWidget.ui @@ -115,6 +115,9 @@ </item> <item> <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>1</number> + </property> <item> <widget class="QPushButton" name="btnRemove"> <property name="sizePolicy"> @@ -174,6 +177,40 @@ </property> </widget> </item> + <item> + <widget class="QPushButton" name="btnAddPeak"> + <property name="toolTip"> + <string>Add HKL peaks</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../../../../Images/images.qrc"> + <normaloff>:/PickTools/selection-peaks.png</normaloff>:/PickTools/selection-peaks.png</iconset> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnRemovePeak"> + <property name="toolTip"> + <string>Erase peaks</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../../../../Images/images.qrc"> + <normaloff>:/PickTools/eraser.png</normaloff>:/PickTools/eraser.png</iconset> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> </layout> </item> <item> @@ -187,6 +224,9 @@ <layout class="QVBoxLayout" name="verticalLayout_3"> <item> <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>1</number> + </property> <item> <widget class="QLabel" name="label_2"> <property name="sizePolicy"> @@ -313,6 +353,8 @@ </item> </layout> </widget> - <resources/> + <resources> + <include location="../../../../Images/images.qrc"/> + </resources> <connections/> </ui> diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ProxyCompositePeaksPresenter.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ProxyCompositePeaksPresenter.h index 2ade65b1f5d966dc6ed78624e447a32af4a5364c..d6a839578a8eace8b26c6ad2019e1856f4caa9c4 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ProxyCompositePeaksPresenter.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ProxyCompositePeaksPresenter.h @@ -79,6 +79,10 @@ public: boost::optional<PeaksPresenter_sptr> getZoomedPeakPresenter() const; /// Get optional zoomed peak index. int getZoomedPeakIndex() const; + /// Set the edit mode. + void editCommand(EditMode editMode, boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target); + /// Can we add HKL peaks to this workspace. + bool hasPeakAddModeFor(boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target); private: /// Wrapped composite to delegate to. diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h index ba72ee0a81f43c2f4c496481b874e6e4e9be30a7..9a0497b745ff6b9e58e559c39343ddd37fe924e7 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h @@ -362,6 +362,6 @@ private: }; } // namespace SliceViewer -} // namespace Mantid +} // namespace MantidQt #endif // SLICEVIEWER_H diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ZoomablePeaksView.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ZoomablePeaksView.h index e38112004f1c7203a9ed607d240238c498d5ec4c..32bc20422a668f2bfeb388b2b1e2a4bf8d947c5f 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ZoomablePeaksView.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ZoomablePeaksView.h @@ -3,6 +3,8 @@ #include "MantidKernel/System.h" #include "MantidKernel/V2D.h" +#include <boost/shared_ptr.hpp> + namespace MantidQt { diff --git a/Code/Mantid/MantidQt/SliceViewer/src/CompositePeaksPresenter.cpp b/Code/Mantid/MantidQt/SliceViewer/src/CompositePeaksPresenter.cpp index 81aac5895fa4082947feba5a3d6439974cb154e2..200ad1d8c22bd37e216019e82383aa33ec674f8a 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/CompositePeaksPresenter.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/CompositePeaksPresenter.cpp @@ -13,7 +13,7 @@ CompositePeaksPresenter::CompositePeaksPresenter( ZoomablePeaksView *const zoomablePlottingWidget, PeaksPresenter_sptr defaultPresenter) : m_zoomablePlottingWidget(zoomablePlottingWidget), - m_default(defaultPresenter), m_owner(NULL), m_zoomedPeakIndex(-1) { + m_default(defaultPresenter), m_owner(NULL), m_zoomedPeakIndex(-1){ if (m_zoomablePlottingWidget == NULL) { throw std::runtime_error("Zoomable Plotting Widget is NULL"); } @@ -383,6 +383,20 @@ void CompositePeaksPresenter::setPeakSizeOnProjection(const double fraction) { } } +/** + * Enter a peak edit mode + * @param mode : Mode to enter. + */ +void CompositePeaksPresenter::peakEditMode(EditMode mode) { + if (useDefault()) { + return m_default->peakEditMode(mode); + } + for (auto presenterIterator = m_subjects.begin(); + presenterIterator != m_subjects.end(); ++presenterIterator) { + (*presenterIterator)->peakEditMode(mode); + } +} + /** * Fraction of the z-range to use as the peak radius. * @param fraction to use as the peak radius @@ -605,7 +619,27 @@ CompositePeaksPresenter::getZoomedPeakPresenter() const { * @return a zoomed peak index. */ int CompositePeaksPresenter::getZoomedPeakIndex() const { - return m_zoomedPeakIndex; + return m_zoomedPeakIndex; +} + +void CompositePeaksPresenter::editCommand( + EditMode editMode, + boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target) { + if (auto ws = target.lock()) { + + // Change the right subject to the desired edit mode. + auto targetIterator = this->getPresenterIteratorFromWorkspace(ws); + if (targetIterator != m_subjects.end()) { + (*targetIterator)->peakEditMode(editMode); + } + // Reset everything else. + for (auto it = m_subjects.begin(); it != m_subjects.end(); ++it) { + if (it != targetIterator) { + // All other subjects must be in a neutral edit mode. + (*it)->peakEditMode(None); + } + } + } } void CompositePeaksPresenter::updatePeaksWorkspace( @@ -651,5 +685,55 @@ void CompositePeaksPresenter::notifyWorkspaceChanged( } } } + +bool CompositePeaksPresenter::deletePeaksIn(PeakBoundingBox box){ + if (useDefault()) { + return m_default->deletePeaksIn(box); + } + // Forward the request onwards + bool result = false; + for (auto it = m_subjects.begin(); it != m_subjects.end(); ++it) { + result |= (*it)->deletePeaksIn(box); + } + return result; } + +bool CompositePeaksPresenter::hasPeakAddModeFor(boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target){ + bool hasMode = false; + if(auto temp = target.lock()) { + auto it = this->getPresenterIteratorFromWorkspace(temp); + if(it != m_subjects.end()) { + hasMode = (*it)->hasPeakAddMode(); + } + } + return hasMode; +} + +bool CompositePeaksPresenter::hasPeakAddMode() const{ + if (useDefault()) { + return m_default->hasPeakAddMode(); + } + // Forward the request onwards + bool hasMode = false; + for (auto it = m_subjects.begin(); it != m_subjects.end(); ++it) { + hasMode |= (*it)->hasPeakAddMode(); + } + return hasMode; } + +bool CompositePeaksPresenter::addPeakAt(double plotCoordsPointX, double plotCoordsPointY) +{ + if (useDefault()) { + return m_default->addPeakAt(plotCoordsPointX, plotCoordsPointY); + } + // Forward the request onwards + bool result = false; + for (auto it = m_subjects.begin(); it != m_subjects.end(); ++it) { + result |= (*it)->addPeakAt(plotCoordsPointX, plotCoordsPointY); + } + return result; +} + +} +} + diff --git a/Code/Mantid/MantidQt/SliceViewer/src/ConcretePeaksPresenter.cpp b/Code/Mantid/MantidQt/SliceViewer/src/ConcretePeaksPresenter.cpp index 7077aa13bddfc29fd53b0f571adeaf820a3e3a62..b77a07265de1db62a4ac352681b4088c4f418937 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/ConcretePeaksPresenter.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/ConcretePeaksPresenter.cpp @@ -1,8 +1,13 @@ #include "MantidQtSliceViewer/ConcretePeaksPresenter.h" +#include "MantidQtSliceViewer/PeakEditMode.h" #include "MantidQtSliceViewer/UpdateableOnDemand.h" #include "MantidQtSliceViewer/ZoomableOnDemand.h" +#include "MantidKernel/V3D.h" +#include "MantidAPI/MultipleExperimentInfos.h" #include "MantidAPI/IPeaksWorkspace.h" #include "MantidGeometry/Crystal/IPeak.h" +#include "MantidGeometry/Crystal/PeakShape.h" +#include "MantidDataObjects/PeakShapeBase.h" #include "MantidAPI/IMDWorkspace.h" #include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/IAlgorithm.h" @@ -13,6 +18,7 @@ using namespace Mantid::API; using namespace Mantid::Kernel; +using namespace Mantid::Geometry; using Mantid::Geometry::IMDDimension_const_sptr; namespace MantidQt { @@ -20,6 +26,52 @@ namespace SliceViewer { namespace { /// static logger Mantid::Kernel::Logger g_log("PeaksPresenter"); + +/** + * makeVertexesFromBox. Convert a box into a form of vertexes that PeaksOnSurface understands. + * @param box : transformed PeakBoundingBox + * @return : vertex vector + */ +std::vector<std::vector<double> > makeVertexesFromBox(const PeakBoundingBox &box, Mantid::Geometry::PeakTransform const * const transform) { + + typedef std::vector<double> DoubleVec; + // Make vertexes in a counter clockwise ordering + std::vector<DoubleVec > vertexes(4); + + V3D plotVertex1(box.left(), box.bottom(), box.slicePoint()); + V3D vertex1 = transform->transformBack(plotVertex1); + + V3D plotVertex2(box.left(), box.top(), box.slicePoint()); + V3D vertex2 = transform->transformBack(plotVertex2); + + V3D plotVertex3(box.right(), box.top(), box.slicePoint()); + V3D vertex3 = transform->transformBack(plotVertex3); + + V3D plotVertex4(box.right(), box.bottom(), box.slicePoint()); + V3D vertex4 = transform->transformBack(plotVertex4); + + vertexes[0]=vertex1; + vertexes[1]=vertex2; + vertexes[2]=vertex3; + vertexes[3]=vertex4; + return vertexes; +} + +/** + * Determine if we can add peaks a peaks workspace. + * @param peaksWS : To possibly add to + * @param frame : Frame of base MDWorkspace + * @return True only if we can add to the peaks workspace. + */ +bool canAddPeaksTo(IPeaksWorkspace const * const peaksWS, Mantid::Kernel::SpecialCoordinateSystem frame){ + /* + - PeaksWS Must have an oriented lattice, otherwise we can't add a self-consistent peak. + - PeaksWS Must not be integrated, because we have no concept of radius until each individual peak is integrated. + - The MDWorkspace must be in the HKL frame otherwise we cannot interpret plot cursor coordinates. + */ + return peaksWS->sample().hasOrientedLattice() && !peaksWS->hasIntegratedPeaks() && frame == Mantid::Kernel::HKL; +} + } /** @@ -41,6 +93,7 @@ coordinateToString(Mantid::Kernel::SpecialCoordinateSystem coordSystem) { } } + /** * Produce the views for the internally held peaks workspace. * Indexes to peaks in the peaks workspace are used to reference the @@ -48,7 +101,16 @@ coordinateToString(Mantid::Kernel::SpecialCoordinateSystem coordSystem) { * All the views must be recreated. */ void ConcretePeaksPresenter::produceViews() { - m_viewPeaks = m_viewFactory->createView(m_transform); + + PeakOverlayView_sptr newView = m_viewFactory->createView(this, m_transform); + PeakOverlayView_sptr oldView = m_viewPeaks; + if (oldView) { + newView->takeSettingsFrom(oldView.get()); + } + m_viewPeaks = newView; + + // We reapply any cached edit mode settings we had before. + this->peakEditMode(m_editMode); } /** @@ -118,10 +180,12 @@ ConcretePeaksPresenter::ConcretePeaksPresenter( : m_viewFactory(viewFactory), m_peaksWS(peaksWS), m_transformFactory(transformFactory), m_transform(transformFactory->createDefaultTransform()), m_slicePoint(), - m_owningPresenter(NULL), m_isHidden(false) { + m_owningPresenter(NULL), m_isHidden(false), m_editMode(SliceViewer::None), m_hasAddPeaksMode(canAddPeaksTo(peaksWS.get(), m_transform->getCoordinateSystem())) { // Check that the workspaces appear to be compatible. Log if otherwise. checkWorkspaceCompatibilities(mdWS); + + this->initialize(); } @@ -161,6 +225,21 @@ void ConcretePeaksPresenter::initialize() { */ void ConcretePeaksPresenter::update() { m_viewPeaks->updateView(); } +/** + * Set/update the internal visible peak mask list. + * @param indexes : Indexes of peaks that can be seen. + */ +void ConcretePeaksPresenter::setVisiblePeaks(const std::vector<size_t>& indexes) +{ + std::vector<bool> visible(this->m_peaksWS->getNumberPeaks(), false); // assume all invisible + for (size_t i = 0; i < indexes.size(); ++i) { + visible[indexes[i]] = true; // make the visible indexes visible. Masking type operation. + } + m_viewablePeaks = visible; + + m_viewPeaks->setSlicePoint(m_slicePoint.slicePoint(), m_viewablePeaks); +} + /** * Find the peaks in the region. * Update the view with all those peaks that could be viewable. @@ -169,47 +248,9 @@ void ConcretePeaksPresenter::update() { m_viewPeaks->updateView(); } *user changes the effective radius of the peaks markers. */ void ConcretePeaksPresenter::doFindPeaksInRegion() { - PeakBoundingBox transformedViewableRegion = - m_slicePoint.makeSliceBox(1e-6); // TODO, could actually be calculated as - // a single plane with z = 0 thickness. - transformedViewableRegion.transformBox(m_transform); - - // Don't bother to find peaks in the region if there are no peaks to find. - if (this->m_peaksWS->getNumberPeaks() >= 1) { - double effectiveRadius = - m_viewPeaks - ->getRadius(); // Effective radius of each peak representation. - - Mantid::API::IPeaksWorkspace_sptr peaksWS = - boost::const_pointer_cast<Mantid::API::IPeaksWorkspace>( - this->m_peaksWS); - - Mantid::API::IAlgorithm_sptr alg = - AlgorithmManager::Instance().create("PeaksInRegion"); - alg->setChild(true); - alg->setRethrows(true); - alg->initialize(); - alg->setProperty("InputWorkspace", peaksWS); - alg->setProperty("OutputWorkspace", peaksWS->name() + "_peaks_in_region"); - alg->setProperty("Extents", transformedViewableRegion.toExtents()); - alg->setProperty("CheckPeakExtents", true); - alg->setProperty("PeakRadius", effectiveRadius); - alg->setPropertyValue("CoordinateFrame", m_transform->getFriendlyName()); - alg->execute(); - ITableWorkspace_sptr outTable = alg->getProperty("OutputWorkspace"); - std::vector<bool> viewablePeaks(outTable->rowCount()); - for (size_t i = 0; i < outTable->rowCount(); ++i) { - viewablePeaks[i] = outTable->cell<Boolean>(i, 1); - } - m_viewablePeaks = viewablePeaks; - - } - else{ - // No peaks will be viewable - m_viewablePeaks = std::vector<bool>(); - } - m_viewPeaks->setSlicePoint(m_slicePoint.slicePoint(), m_viewablePeaks); + auto indexes = findVisiblePeakIndexes(m_slicePoint, false /*We want to consider effective radius when deciding what to show*/); + setVisiblePeaks(indexes); } /** @@ -384,16 +425,15 @@ bool ConcretePeaksPresenter::isHidden() const { return m_isHidden; } * @param other * @return */ -bool ConcretePeaksPresenter::contentsDifferent(const PeaksPresenter * other) const -{ - const SetPeaksWorkspaces otherWorkspaces = - other->presentedWorkspaces(); +bool +ConcretePeaksPresenter::contentsDifferent(const PeaksPresenter *other) const { + const SetPeaksWorkspaces otherWorkspaces = other->presentedWorkspaces(); - // Look for this workspace in the others workspace list. - auto iterator = otherWorkspaces.find(this->m_peaksWS); + // Look for this workspace in the others workspace list. + auto iterator = otherWorkspaces.find(this->m_peaksWS); - const bool different = (iterator == otherWorkspaces.end()); - return different; + const bool different = (iterator == otherWorkspaces.end()); + return different; } /** @@ -451,7 +491,8 @@ void ConcretePeaksPresenter::setPeakSizeIntoProjection(const double fraction) { double ConcretePeaksPresenter::getPeakSizeOnProjection() const { double result = 0; - if (m_viewPeaks != NULL && (m_peaksWS->getNumberPeaks() > 0) && m_viewPeaks->positionOnly()) { + if (m_viewPeaks != NULL && (m_peaksWS->getNumberPeaks() > 0) && + m_viewPeaks->positionOnly()) { result = m_viewPeaks->getOccupancyInView(); } return result; @@ -459,7 +500,8 @@ double ConcretePeaksPresenter::getPeakSizeOnProjection() const { double ConcretePeaksPresenter::getPeakSizeIntoProjection() const { double result = 0; - if (m_viewPeaks != NULL && (m_peaksWS->getNumberPeaks() > 0) && m_viewPeaks->positionOnly()) { + if (m_viewPeaks != NULL && (m_peaksWS->getNumberPeaks() > 0) && + m_viewPeaks->positionOnly()) { result = m_viewPeaks->getOccupancyIntoView(); } return result; @@ -485,5 +527,154 @@ void ConcretePeaksPresenter::zoomToPeak(const int peakIndex) { zoomable->zoomToPeak(this, peakIndex); } } + +void ConcretePeaksPresenter::peakEditMode(EditMode mode){ + if(mode == DeletePeaks) { + m_viewPeaks->peakDeletionMode(); + } else if(mode == AddPeaks){ + m_viewPeaks->peakAdditionMode(); + } else { + m_viewPeaks->peakDisplayMode(); + } + // Cache the current edit mode. + m_editMode = mode; +} + +bool ConcretePeaksPresenter::deletePeaksIn(PeakBoundingBox box) { + + Left left(box.left()); + Right right(box.right()); + Bottom bottom(box.bottom()); + Top top(box.top()); + SlicePoint slicePoint(box.slicePoint()); + if (slicePoint() < 0) { // indicates that it should not be used. + slicePoint = SlicePoint(m_slicePoint.slicePoint()); + } + + PeakBoundingBox accurateBox( + left, right, top, bottom, + slicePoint /*Use the current slice position, previously unknown.*/); + + // Tranform box from plot coordinates into orderd HKL, Qx,Qy,Qz etc, then find the visible peaks. + std::vector<size_t> deletionIndexList = findVisiblePeakIndexes(accurateBox, true /*Point only mode. We want to not consider effective radius when deciding what delete if possible.*/); + + // If we have things to remove, do that in one-step. + if (!deletionIndexList.empty()) { + + + Mantid::API::IPeaksWorkspace_sptr peaksWS = + boost::const_pointer_cast<Mantid::API::IPeaksWorkspace>( + this->m_peaksWS); + // Sort the Peaks in-place. + Mantid::API::IAlgorithm_sptr alg = + AlgorithmManager::Instance().create("DeleteTableRows"); + alg->setChild(true); + alg->setRethrows(true); + alg->initialize(); + alg->setProperty("TableWorkspace", peaksWS); + alg->setProperty("Rows", deletionIndexList); + alg->execute(); + + // Reproduce the views. Proxy representations recreated for all peaks. + this->produceViews(); + + // Refind visible peaks and Set the proxy representations to be visible or not. + doFindPeaksInRegion(); + + // Upstream controls need to be regenerated. + this->informOwnerUpdate(); + } + return !deletionIndexList.empty(); +} + +bool ConcretePeaksPresenter::addPeakAt(double plotCoordsPointX, double plotCoordsPointY) +{ + V3D plotCoordsPoint(plotCoordsPointX, plotCoordsPointY, m_slicePoint.slicePoint()); + V3D hkl = m_transform->transformBack(plotCoordsPoint); + + Mantid::API::IPeaksWorkspace_sptr peaksWS = + boost::const_pointer_cast<Mantid::API::IPeaksWorkspace>( + this->m_peaksWS); + + Mantid::API::IAlgorithm_sptr alg = + AlgorithmManager::Instance().create("AddPeakHKL"); + alg->setChild(true); + alg->setRethrows(true); + alg->initialize(); + alg->setProperty("Workspace", peaksWS); + alg->setProperty("HKL", std::vector<double>(hkl)); + alg->execute(); + + // Reproduce the views. Proxy representations recreated for all peaks. + this->produceViews(); + + // Refind visible peaks and Set the proxy representations to be visible or not. + doFindPeaksInRegion(); + + // Upstream controls need to be regenerated. + this->informOwnerUpdate(); + + return alg->isExecuted(); } + +bool ConcretePeaksPresenter::hasPeakAddMode() const +{ + return m_hasAddPeaksMode; } + +std::vector<size_t> +ConcretePeaksPresenter::findVisiblePeakIndexes(const PeakBoundingBox &box, const bool pointOnlyMode) { + std::vector<size_t> indexes; + // Don't bother to find peaks in the region if there are no peaks to find. + if (this->m_peaksWS->getNumberPeaks() >= 1) { + + double radius = + m_viewPeaks + ->getRadius(); // Effective radius of each peak representation. + + /* + If we are position only, there is really no proper radius. This should really be handled internally by the PeakIntersection algorithm. + */ + if(pointOnlyMode && m_viewPeaks->positionOnly()){ + radius =1e-6; + } + + Mantid::API::IPeaksWorkspace_sptr peaksWS = + boost::const_pointer_cast<Mantid::API::IPeaksWorkspace>( + this->m_peaksWS); + + std::vector<std::vector<double>> vertexes = + makeVertexesFromBox(box, m_transform.get()); + + Mantid::API::IAlgorithm_sptr alg = + AlgorithmManager::Instance().create("PeaksOnSurface"); + alg->setChild(true); + alg->setRethrows(true); + alg->initialize(); + alg->setProperty("InputWorkspace", peaksWS); + alg->setProperty("OutputWorkspace", peaksWS->name() + "_peaks_on_surface"); + alg->setProperty("Vertex1", vertexes[0]); + alg->setProperty("Vertex2", vertexes[1]); + alg->setProperty("Vertex3", vertexes[2]); + alg->setProperty("Vertex4", vertexes[3]); + alg->setProperty("PeakRadius", + radius); + alg->setPropertyValue("CoordinateFrame", m_transform->getFriendlyName()); + alg->execute(); + ITableWorkspace_sptr outTable = alg->getProperty("OutputWorkspace"); + + for (size_t i = 0; i < outTable->rowCount(); ++i) { + const bool insideRegion = outTable->cell<Boolean>(i, 1); + if (insideRegion) { + indexes.push_back(i); + } + } + } + return indexes; +} + + + +} +} + diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayInteractive.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayInteractive.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0630465e623ddd098b97ae80c4482a38081ed5f5 --- /dev/null +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayInteractive.cpp @@ -0,0 +1,193 @@ +#include "MantidQtSliceViewer/PeakOverlayInteractive.h" +#include "MantidQtSliceViewer/PeaksPresenter.h" +#include "MantidQtMantidWidgets/InputController.h" +#include <qwt_plot.h> +#include <qwt_plot_canvas.h> +#include <qwt_scale_div.h> +#include <QApplication> +#include <QPaintEvent> +#include <QPainter> + +namespace MantidQt { +namespace SliceViewer { + +PeakOverlayInteractive::PeakOverlayInteractive( + PeaksPresenter *const peaksPresenter, QwtPlot *plot, const int plotXIndex, + const int plotYIndex, QWidget *parent) + : QWidget(parent), m_presenter(peaksPresenter), m_plot(plot), + m_plotXIndex(plotXIndex), m_plotYIndex(plotYIndex), m_tool(NULL) { + + setAttribute(Qt::WA_NoMousePropagation, false); + setAttribute(Qt::WA_MouseTracking, true); + + // Non-editing by default + peakDisplayMode(); + + this->setVisible(true); + setUpdatesEnabled(true); + +} + +PeakOverlayInteractive::~PeakOverlayInteractive() +{ + this->peakDisplayMode(); +} + +void PeakOverlayInteractive::paintEvent(QPaintEvent *event) { + // Only paint to update the interactive tool + if (m_tool) { + QPainter painter(this); + m_tool->onPaint(painter); + painter.end(); + } + // Sub-classes are responsible for painting their respective peak + // representations + this->doPaintPeaks(event); +} + +void PeakOverlayInteractive::captureMouseEvents(bool capture) +{ + setAttribute(Qt::WA_TransparentForMouseEvents, !capture); +} + +void PeakOverlayInteractive::peakDeletionMode() { + captureMouseEvents(true); + QApplication::restoreOverrideCursor(); + auto* temp = m_tool; + auto* eraseTool = new MantidQt::MantidWidgets::InputControllerErase(this); + connect(eraseTool,SIGNAL(erase(QRect)),this,SLOT(erasePeaks(QRect)), Qt::QueuedConnection); + m_tool = eraseTool; + delete temp; +} + +void PeakOverlayInteractive::peakAdditionMode() { + captureMouseEvents(true); + QApplication::restoreOverrideCursor(); + auto* temp = m_tool; + auto* addTool = new MantidQt::MantidWidgets::InputControllerPick(this); + connect(addTool,SIGNAL(pickPointAt(int,int)),this,SLOT(addPeakAt(int,int))); + m_tool = addTool; + delete temp; +} + +void PeakOverlayInteractive::peakDisplayMode() { + captureMouseEvents(false /*pass through mouse events*/); + QApplication::restoreOverrideCursor(); + if(m_tool){ + delete m_tool; + m_tool = NULL; + } +} + +void PeakOverlayInteractive::mousePressEvent(QMouseEvent* e) +{ + if(m_tool) { + m_tool->mousePressEvent( e ); + }else{ + e->ignore(); + } +} + +void PeakOverlayInteractive::mouseMoveEvent(QMouseEvent* e) +{ + if(m_tool) { + m_tool->mouseMoveEvent( e ); + this->update(); + } + e->ignore(); + +} + +void PeakOverlayInteractive::mouseReleaseEvent(QMouseEvent* e) +{ + if(m_tool) { + m_tool->mouseReleaseEvent( e ); + }else{ + e->ignore(); + } +} + +void PeakOverlayInteractive::wheelEvent(QWheelEvent* e) +{ + if(m_tool) { + m_tool->wheelEvent( e ); + }else{ + e->ignore(); + } +} + +void PeakOverlayInteractive::keyPressEvent(QKeyEvent* e) +{ + if(m_tool) { + m_tool->keyPressEvent( e ); + }else{ + e->ignore(); + } +} + +void PeakOverlayInteractive::enterEvent(QEvent *e) +{ + if(m_tool) { + m_tool->enterEvent( e ); + }else{ + e->ignore(); + } +} + +void PeakOverlayInteractive::leaveEvent(QEvent *e) +{ + if(m_tool) { + m_tool->leaveEvent( e ); + }else{ + e->ignore(); + } +} + +void PeakOverlayInteractive::addPeakAt(int coordX, int coordY) { + + QwtScaleMap xMap = m_plot->canvasMap(m_plotXIndex); + QwtScaleMap yMap = m_plot->canvasMap(m_plotYIndex); + + const double plotX = xMap.invTransform(double(coordX)); + const double plotY = yMap.invTransform(double(coordY)); + + m_presenter->addPeakAt(plotX, plotY); +} + + +void PeakOverlayInteractive::erasePeaks(const QRect &rect) +{ + QwtScaleMap xMap = m_plot->canvasMap(m_plotXIndex); + QwtScaleMap yMap = m_plot->canvasMap(m_plotYIndex); + + const Left left(xMap.invTransform(rect.left())); + const Right right(xMap.invTransform(rect.right())); + const Top top(yMap.invTransform(rect.top())); + const Bottom bottom(yMap.invTransform(rect.bottom())); + const SlicePoint slicePoint(-1); // Not required. + + m_presenter->deletePeaksIn(PeakBoundingBox(left, right, top, bottom, slicePoint)); +} + +//---------------------------------------------------------------------------------------------- +/// Return the recommended size of the widget +QSize PeakOverlayInteractive::sizeHint() const +{ + //TODO: Is there a smarter way to find the right size? + return QSize(20000, 20000); + // Always as big as the canvas + //return m_plot->canvas()->size(); +} + +QSize PeakOverlayInteractive::size() const +{ return m_plot->canvas()->size(); } + +int PeakOverlayInteractive::height() const +{ return m_plot->canvas()->height(); } + +int PeakOverlayInteractive::width() const +{ return m_plot->canvas()->width(); } + + +} +} diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCross.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCross.cpp index f51ab66e58eba191f1ce7d8e17f70449df306004..d02a14d84fe5c03593aefd1617ff938ee82b11d1 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCross.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCross.cpp @@ -1,10 +1,14 @@ #include "MantidQtSliceViewer/PeakOverlayMultiCross.h" +#include "MantidQtSliceViewer/PeaksPresenter.h" +#include "MantidQtMantidWidgets/InputController.h" #include <qwt_plot.h> #include <qwt_plot_canvas.h> #include <qwt_scale_div.h> #include <qpainter.h> #include <QPen> #include <QMouseEvent> +#include <QApplication> + using namespace Mantid::Kernel; using namespace Mantid::Geometry; @@ -18,17 +22,21 @@ namespace MantidQt //---------------------------------------------------------------------------------------------- /** Constructor */ - PeakOverlayMultiCross::PeakOverlayMultiCross(QwtPlot * plot, QWidget * parent, const VecPhysicalCrossPeak& vecPhysicalPeaks, const QColor& peakColour) - : QWidget( parent ), - m_plot(plot), + PeakOverlayMultiCross::PeakOverlayMultiCross(PeaksPresenter* const presenter, QwtPlot * plot, QWidget * parent, + const VecPhysicalCrossPeak& vecPhysicalPeaks, const int plotXIndex, const int plotYIndex, const QColor& peakColour) + : PeakOverlayInteractive ( presenter, plot, plotXIndex, plotYIndex, parent ), m_physicalPeaks(vecPhysicalPeaks), - m_peakColour(peakColour) + m_peakColour(peakColour), + m_cachedOccupancyIntoView(0), + m_cachedOccupancyInView(0) { - setAttribute(Qt::WA_NoMousePropagation, false); - this->setVisible(true); - setUpdatesEnabled(true); - - setAttribute(Qt::WA_TransparentForMouseEvents); + if(vecPhysicalPeaks.size() > 0) + { + // Cache the occupancy if we can, that way if all physical peaks are removed, we still keep the occupancy settings. + VecPhysicalCrossPeak::value_type firstPhysicalPeak = vecPhysicalPeaks.front(); + m_cachedOccupancyIntoView = firstPhysicalPeak->getOccupancyIntoView(); + m_cachedOccupancyInView = firstPhysicalPeak->getOccupancyInView(); + } } //---------------------------------------------------------------------------------------------- @@ -59,26 +67,10 @@ namespace MantidQt } - //---------------------------------------------------------------------------------------------- - /// Return the recommended size of the widget - QSize PeakOverlayMultiCross::sizeHint() const - { - //TODO: Is there a smarter way to find the right size? - return QSize(20000, 20000); - // Always as big as the canvas - //return m_plot->canvas()->size(); - } - - QSize PeakOverlayMultiCross::size() const - { return m_plot->canvas()->size(); } - int PeakOverlayMultiCross::height() const - { return m_plot->canvas()->height(); } - int PeakOverlayMultiCross::width() const - { return m_plot->canvas()->width(); } //---------------------------------------------------------------------------------------------- /// Paint the overlay - void PeakOverlayMultiCross::paintEvent(QPaintEvent * /*event*/) + void PeakOverlayMultiCross::doPaintPeaks(QPaintEvent * /*event*/) { for(size_t i = 0; i < m_viewablePeaks.size(); ++i) { @@ -108,6 +100,7 @@ namespace MantidQt painter.drawLine(bottomL, topR); painter.drawLine(bottomR, topL); + painter.end(); } } } @@ -164,6 +157,7 @@ namespace MantidQt { m_physicalPeaks[i]->setOccupancyInView(fraction); } + m_cachedOccupancyInView = fraction; } /** @@ -176,16 +170,17 @@ namespace MantidQt { m_physicalPeaks[i]->setOccupancyIntoView(fraction); } + m_cachedOccupancyIntoView = fraction; } double PeakOverlayMultiCross::getOccupancyInView() const { - return m_physicalPeaks[0]->getOccupancyInView(); + return m_cachedOccupancyInView; } double PeakOverlayMultiCross::getOccupancyIntoView() const { - return m_physicalPeaks[0]->getOccupancyIntoView(); + return m_cachedOccupancyIntoView; } bool PeakOverlayMultiCross::positionOnly() const @@ -213,5 +208,14 @@ namespace MantidQt return m_peakColour; } + void PeakOverlayMultiCross::takeSettingsFrom(const PeakOverlayView * const source) + { + this->changeForegroundColour(source->getForegroundColour()); + this->changeBackgroundColour(source->getBackgroundColour()); + this->changeOccupancyIntoView(source->getOccupancyIntoView()); + this->changeOccupancyInView(source->getOccupancyInView()); + this->showBackgroundRadius(source->isBackgroundShown()); + } + } // namespace Mantid } // namespace SliceViewer diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCrossFactory.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCrossFactory.cpp index 5f929bdd157a8592beb399c72fdb5e30b1bd8add..628c7776ee21b0b928819d6aa5e886c797d93753 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCrossFactory.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiCrossFactory.cpp @@ -1,5 +1,6 @@ #include "MantidQtSliceViewer/PeakOverlayMultiCrossFactory.h" #include "MantidQtSliceViewer/PeakOverlayMultiCross.h" +#include "MantidQtSliceViewer/PeaksPresenter.h" #include "MantidQtSliceViewer/PhysicalCrossPeak.h" #include "MantidKernel/V3D.h" #include "MantidGeometry/Crystal/IPeak.h" @@ -17,8 +18,8 @@ namespace MantidQt namespace SliceViewer { - PeakOverlayMultiCrossFactory::PeakOverlayMultiCrossFactory(boost::shared_ptr<Mantid::API::MDGeometry> mdWS, PeakTransform_const_sptr transform, IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const size_t colourNumber) - : PeakOverlayViewFactoryBase(plot, parent, colourNumber), + PeakOverlayMultiCrossFactory::PeakOverlayMultiCrossFactory(boost::shared_ptr<Mantid::API::MDGeometry> mdWS, PeakTransform_const_sptr transform, IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const int plotXIndex, const int plotYIndex, const size_t colourNumber) + : PeakOverlayViewFactoryBase(plot, parent, plotXIndex, plotYIndex, colourNumber), m_peaksWS(peaksWS), m_zMax(0), m_zMin(0) @@ -39,7 +40,7 @@ namespace MantidQt { } - boost::shared_ptr<PeakOverlayView> PeakOverlayMultiCrossFactory::createView(PeakTransform_const_sptr transform) const + boost::shared_ptr<PeakOverlayView> PeakOverlayMultiCrossFactory::createView(PeaksPresenter* const presenter, PeakTransform_const_sptr transform) const { // Construct all physical peaks VecPhysicalCrossPeak physicalPeaks(m_peaksWS->rowCount()); @@ -51,7 +52,7 @@ namespace MantidQt } // Make the overlay widget. - return boost::make_shared<PeakOverlayMultiCross>(m_plot, m_parent, physicalPeaks, this->m_peakColour); + return boost::make_shared<PeakOverlayMultiCross>(presenter, m_plot, m_parent, physicalPeaks, m_plotXIndex, m_plotYIndex, this->m_peakColour); } int PeakOverlayMultiCrossFactory::FOM() const diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphere.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphere.cpp index 33fa5129d2d18ce1428adf513e1eb9939536e897..f4f04d61b5b058569c3635ff4c34cbc8d870f1ac 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphere.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphere.cpp @@ -4,7 +4,6 @@ #include <qwt_scale_div.h> #include <qpainter.h> #include <QPen> -#include <QMouseEvent> using namespace Mantid::Kernel; using namespace Mantid::Geometry; @@ -15,16 +14,24 @@ namespace MantidQt { //---------------------------------------------------------------------------------------------- - /** Constructor + + + /** + * Constructor + * @param presenter : controller + * @param plot : plot + * @param parent : plot-canvas + * @param vecPhysicalPeaks : List of physical peaks to show + * @param plotXIndex : plot x-index + * @param plotYIndex : plot y-index + * @param peakColour : peak colour + * @param backColour : background colour */ - PeakOverlayMultiSphere::PeakOverlayMultiSphere(QwtPlot * plot, QWidget * parent, const VecPhysicalSphericalPeak& vecPhysicalPeaks , const QColor& peakColour, const QColor& backColour) : - QWidget(parent), m_plot(plot), m_physicalPeaks(vecPhysicalPeaks), m_peakColour(peakColour), m_backColour(backColour), m_showBackground(false) + PeakOverlayMultiSphere::PeakOverlayMultiSphere(PeaksPresenter* const presenter, QwtPlot * plot, QWidget * parent, const VecPhysicalSphericalPeak& vecPhysicalPeaks, + const int plotXIndex, const int plotYIndex, const QColor& peakColour, const QColor& backColour) : + PeakOverlayInteractive(presenter, plot, plotXIndex, plotYIndex, parent), m_physicalPeaks(vecPhysicalPeaks), + m_peakColour(peakColour), m_backColour(backColour), m_showBackground(false) { - setAttribute(Qt::WA_NoMousePropagation, false); - this->setVisible(true); - setUpdatesEnabled(true); - - setAttribute(Qt::WA_TransparentForMouseEvents); } //---------------------------------------------------------------------------------------------- @@ -47,32 +54,9 @@ namespace MantidQt this->update(); //repaint } - //---------------------------------------------------------------------------------------------- - /// Return the recommended size of the widget - QSize PeakOverlayMultiSphere::sizeHint() const - { - //TODO: Is there a smarter way to find the right size? - return QSize(20000, 20000); - // Always as big as the canvas - //return m_plot->canvas()->size(); - } - - QSize PeakOverlayMultiSphere::size() const - { - return m_plot->canvas()->size(); - } - int PeakOverlayMultiSphere::height() const - { - return m_plot->canvas()->height(); - } - int PeakOverlayMultiSphere::width() const - { - return m_plot->canvas()->width(); - } - //---------------------------------------------------------------------------------------------- /// Paint the overlay - void PeakOverlayMultiSphere::paintEvent(QPaintEvent * /*event*/) + void PeakOverlayMultiSphere::doPaintPeaks(QPaintEvent * /*event*/) { for(size_t i = 0; i < m_viewablePeaks.size(); ++i) { @@ -113,6 +97,7 @@ namespace MantidQt QPainterPath backgroundRadiusFill = backgroundOuterPath.subtracted(backgroundInnerPath); painter.fillPath(backgroundRadiusFill, m_backColour); } + painter.end(); } } } @@ -180,12 +165,12 @@ namespace MantidQt double PeakOverlayMultiSphere::getOccupancyInView() const { - throw std::runtime_error("PeakOverlaySphere::getOccupancyInView() not implemented"); + return -1.0; } double PeakOverlayMultiSphere::getOccupancyIntoView() const { - throw std::runtime_error("PeakOverlaySphere::getOccupancyIntoView() not implemented"); + return -1.0; } bool PeakOverlayMultiSphere::positionOnly() const @@ -213,5 +198,13 @@ namespace MantidQt return m_peakColour; } + + void PeakOverlayMultiSphere::takeSettingsFrom(const PeakOverlayView * const source) + { + this->changeForegroundColour(source->getForegroundColour()); + this->changeBackgroundColour(source->getBackgroundColour()); + this->showBackgroundRadius(source->isBackgroundShown()); + } + } // namespace Mantid } // namespace SliceViewer diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphereFactory.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphereFactory.cpp index 05cd9cd8a8f6ddb75a92109a22a8efb316d1edca..fab975427c7149b5ffdfbc77fc6e475554aa4d0f 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphereFactory.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayMultiSphereFactory.cpp @@ -1,23 +1,27 @@ #include "MantidQtSliceViewer/PeakOverlayMultiSphereFactory.h" #include "MantidQtSliceViewer/PeakOverlayMultiSphere.h" +#include "MantidQtSliceViewer/PeaksPresenter.h" +#include "MantidKernel/WarningSuppressions.h" +#include "MantidDataObjects/PeakShapeSpherical.h" #include <boost/make_shared.hpp> using namespace Mantid::API; +using namespace Mantid::DataObjects; namespace MantidQt { namespace SliceViewer { - PeakOverlayMultiSphereFactory::PeakOverlayMultiSphereFactory(IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const size_t colourNumber) : - PeakOverlayViewFactoryBase(plot, parent, colourNumber), + PeakOverlayMultiSphereFactory::PeakOverlayMultiSphereFactory(IPeaksWorkspace_sptr peaksWS, QwtPlot * plot, QWidget * parent, const int plotXIndex, const int plotYIndex, const size_t colourNumber) : + PeakOverlayViewFactoryBase(plot, parent, plotXIndex, plotYIndex, colourNumber), m_peakRadius(0), m_backgroundInnerRadius(0), m_backgroundOuterRadius(0), m_peaksWS(peaksWS), m_FOM(0) { - if (m_peaksWS->hasIntegratedPeaks()) + if (m_peaksWS->hasIntegratedPeaks()) // TODO depends on the shape. { try { @@ -46,19 +50,38 @@ namespace MantidQt } } - boost::shared_ptr<PeakOverlayView> PeakOverlayMultiSphereFactory::createView(Mantid::Geometry::PeakTransform_const_sptr transform) const + GCC_DIAG_OFF(strict-aliasing) + boost::shared_ptr<PeakOverlayView> PeakOverlayMultiSphereFactory::createView(PeaksPresenter* const presenter, Mantid::Geometry::PeakTransform_const_sptr transform) const { // Construct all physical peaks VecPhysicalSphericalPeak physicalPeaks(m_peaksWS->rowCount()); for(size_t i = 0; i < physicalPeaks.size(); ++i) { const Mantid::Geometry::IPeak& peak = m_peaksWS->getPeak(static_cast<int>(i)); + const Mantid::Geometry::PeakShape& peakShape = peak.getPeakShape(); auto position = transform->transformPeak(peak); - physicalPeaks[i] = boost::make_shared<PhysicalSphericalPeak>(position, m_peakRadius[i], m_backgroundInnerRadius[i], m_backgroundOuterRadius[i]); - } + if(const PeakShapeSpherical* sphericalShape = dynamic_cast<const PeakShapeSpherical*>(&peakShape)){ + auto radius = sphericalShape->radius(); + auto optOuterRadius = sphericalShape->backgroundOuterRadius(); + auto optInnerRadius = sphericalShape->backgroundInnerRadius(); + + + auto outerRadius = optOuterRadius.is_initialized() ? optOuterRadius.get() : radius; + auto innerRadius = optInnerRadius.is_initialized() ? optInnerRadius.get() : radius; + + + physicalPeaks[i] = boost::make_shared<PhysicalSphericalPeak>(position, radius, innerRadius, outerRadius); + + } else { + // This method of doing things is effectivlely deprecated now since we have the PeakShape. I will eventually strip this out. + physicalPeaks[i] = boost::make_shared<PhysicalSphericalPeak>(position, m_peakRadius[i], m_backgroundInnerRadius[i], m_backgroundOuterRadius[i]); + + } + + } // Make the overlay widget. - return boost::make_shared<PeakOverlayMultiSphere>(m_plot, m_parent, physicalPeaks, this->m_peakColour, this->m_backColour); + return boost::make_shared<PeakOverlayMultiSphere>(presenter, m_plot, m_parent, physicalPeaks, m_plotXIndex, m_plotYIndex, this->m_peakColour, this->m_backColour); } PeakOverlayMultiSphereFactory::~PeakOverlayMultiSphereFactory() diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayViewFactoryBase.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayViewFactoryBase.cpp index bba810c29d3c2a2504b395fe269ce733ca82c4c9..6f27fe3b3f8df448a630de1977e54a2312d278eb 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayViewFactoryBase.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayViewFactoryBase.cpp @@ -9,7 +9,8 @@ namespace MantidQt namespace SliceViewer { - PeakOverlayViewFactoryBase::PeakOverlayViewFactoryBase(QwtPlot * plot, QWidget * parent, const size_t workspaceNumber) : PeakOverlayViewFactory(), m_plot(plot), m_parent(parent) + PeakOverlayViewFactoryBase::PeakOverlayViewFactoryBase(QwtPlot * plot, QWidget * parent, const int plotXIndex, const int plotYIndex, const size_t workspaceNumber) : PeakOverlayViewFactory(), m_plot(plot), m_parent(parent), + m_plotXIndex(plotXIndex), m_plotYIndex(plotYIndex) { if(!plot) throw std::invalid_argument("PeakOverlayViewFactoryBase plot is null"); @@ -39,4 +40,4 @@ namespace MantidQt { } } -} \ No newline at end of file +} diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeaksViewer.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeaksViewer.cpp index 4ae2961155029590ccf3646276fbf38a26f072fc..9834d2c3118f175e2a5832f9813cf4ba71283abf 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/PeaksViewer.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeaksViewer.cpp @@ -48,15 +48,18 @@ void PeaksViewer::setPresenter( if (layout()) { removeLayout(this); } - this->setLayout(new QVBoxLayout); + QVBoxLayout* masterLayout = new QVBoxLayout; + this->setLayout(masterLayout); + auto it = workspaces.begin(); while (it != workspaces.end()) { Mantid::API::IPeaksWorkspace_const_sptr ws = *it; auto backgroundColour = m_presenter->getBackgroundColour(ws); auto foregroundColour = m_presenter->getForegroundColour(ws); + bool canAddPeaks = m_presenter->hasPeakAddModeFor(ws); auto widget = new PeaksWorkspaceWidget( - ws, coordinateSystem, foregroundColour, backgroundColour, this); + ws, coordinateSystem, foregroundColour, backgroundColour, canAddPeaks , this); connect(widget, SIGNAL(peakColourChanged( Mantid::API::IPeaksWorkspace_const_sptr, QColor)), @@ -118,6 +121,55 @@ PeaksViewer::~PeaksViewer() {} */ bool PeaksViewer::hasThingsToShow() const { return m_presenter->size() >= 1; } +void PeaksViewer:: clearPeaksModeRequest( + const PeaksWorkspaceWidget *const originWidget, const bool on) { + EditMode mode; + if (on) { + QList<PeaksWorkspaceWidget *> children = + qFindChildren<PeaksWorkspaceWidget *>(this); + for (int i = 0; i < children.size(); ++i) { + PeaksWorkspaceWidget *candidateWidget = children.at(i); + // For all but the most recently selected peaks workspace. Exit clear + // mode. + if (candidateWidget != originWidget) { + // Exit clear mode on others. + candidateWidget->exitClearPeaksMode(); + } + // One mode, and One Workspace at a time. Cannot be in Add mode for any + // Workspace while clearing peaks. + candidateWidget->exitAddPeaksMode(); + mode = DeletePeaks; + } + } else { + mode = None; + } + m_presenter->editCommand(mode, originWidget->getPeaksWorkspace()); +} + +void PeaksViewer::addPeaksModeRequest(const PeaksWorkspaceWidget * const originWidget, const bool on) +{ + EditMode mode; + if(on) { + QList<PeaksWorkspaceWidget *> children = + qFindChildren<PeaksWorkspaceWidget *>(this); + for (int i = 0; i < children.size(); ++i) { + PeaksWorkspaceWidget *candidateWidget = children.at(i); + // For all but the most recently selected peaks workspace. Exit clear mode. + if(candidateWidget != originWidget){ + // Exit Add mode on others. + candidateWidget->exitAddPeaksMode(); + } + // One mode, and One Workspace at a time. Cannot be in Clear mode for any Workspace while clearing peaks. + candidateWidget->exitClearPeaksMode(); + mode = AddPeaks; + + } + } else { + mode = None; + } + m_presenter->editCommand(mode, originWidget->getPeaksWorkspace()); +} + /** * Handler for changing the peak radius colour. * @param peaksWS : Peaks workspace to change the foreground colour on. @@ -207,7 +259,6 @@ void PeaksViewer::performUpdate() { // Now find the PeaksWorkspaceWidget corresponding to this workspace name. QList<PeaksWorkspaceWidget *> children = qFindChildren<PeaksWorkspaceWidget *>(this); - Mantid::API::IPeaksWorkspace_sptr targetPeaksWorkspace; for (int i = 0; i < children.size(); ++i) { PeaksWorkspaceWidget *candidateWidget = children.at(i); Mantid::API::IPeaksWorkspace_const_sptr candidateWorkspace = @@ -226,6 +277,8 @@ void PeaksViewer::performUpdate() { } } } + // We also update the widget in case the workspace has changed for added/deleted peaks + candidateWidget->workspaceUpdate(); } } } diff --git a/Code/Mantid/MantidQt/SliceViewer/src/PeaksWorkspaceWidget.cpp b/Code/Mantid/MantidQt/SliceViewer/src/PeaksWorkspaceWidget.cpp index 427a3977b1282eeb7c804f554832c07b6fa79e23..e859bfc1a69b3823545c08be16833de60dd2f395 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/PeaksWorkspaceWidget.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/PeaksWorkspaceWidget.cpp @@ -1,8 +1,26 @@ #include "MantidQtSliceViewer/PeaksWorkspaceWidget.h" +#include "MantidQtSliceViewer/PeaksViewer.h" #include "MantidQtSliceViewer/QPeaksTableModel.h" #include <QColorDialog> #include <QPlastiqueStyle> +namespace { + +class SignalBlocker{ +private: + QObject* m_obj; + +public: + SignalBlocker(QObject* obj) : m_obj(obj) { + m_obj->blockSignals(true); + } + ~SignalBlocker(){ + m_obj->blockSignals(false); + } +}; + +} + namespace MantidQt { namespace SliceViewer { @@ -13,15 +31,17 @@ Constructor @param coordinateSystem : Name of coordinate system used @param defaultForegroundColour : Default peak foreground colour @param defaultBackgroundColour : Default peak background colour +@param canAddPeaks : Flag to indicate that peaks can be added. False for no add mode. @param parent : parent widget */ PeaksWorkspaceWidget::PeaksWorkspaceWidget( Mantid::API::IPeaksWorkspace_const_sptr ws, const std::string &coordinateSystem, const QColor &defaultForegroundColour, - const QColor &defaultBackgroundColour, QWidget *parent) + const QColor &defaultBackgroundColour, const bool canAddPeaks, PeaksViewer *parent) : QWidget(parent), m_ws(ws), m_coordinateSystem(coordinateSystem), m_foregroundColour(defaultForegroundColour), - m_backgroundColour(defaultBackgroundColour) { + m_backgroundColour(defaultBackgroundColour), + m_parent(parent) { ui.setupUi(this); @@ -35,6 +55,8 @@ PeaksWorkspaceWidget::PeaksWorkspaceWidget( connect(ui.btnRemove, SIGNAL(clicked()), this, SLOT(onRemoveWorkspaceClicked())); connect(ui.btnHide, SIGNAL(clicked()), this, SLOT(onToggleHideInPlot())); + connect(ui.btnAddPeak, SIGNAL(toggled(bool)), this, SLOT(onAddPeaksToggled(bool))); + connect(ui.btnRemovePeak, SIGNAL(toggled(bool)), this, SLOT(onClearPeaksToggled(bool))); // Override the styles for the colour buttons, because with some inherited // styles, the button background colour will be hidden. @@ -47,6 +69,9 @@ PeaksWorkspaceWidget::PeaksWorkspaceWidget( ui.ckShowBackground->setVisible(integratedPeaks); ui.lblShowBackgroundColour->setVisible(integratedPeaks); + // Don't allow peaks to be added if it has been forbidden + ui.btnAddPeak->setEnabled(canAddPeaks); + // Populate controls with data. populate(); @@ -276,5 +301,35 @@ void PeaksWorkspaceWidget::onCurrentChanged(QModelIndex index, QModelIndex) } } +/** + * @brief PeaksWorkspaceWidget::onClearPeaksToggled + * @param on : Enter mode + */ +void PeaksWorkspaceWidget::onClearPeaksToggled(bool on) +{ + //We should now tell the PeaksViewer about this. + m_parent->clearPeaksModeRequest(this, on); +} + +/** + * @brief PeaksWorkspaceWidget::onAddPeaksToggled + * @param on : Enter mode + */ +void PeaksWorkspaceWidget::onAddPeaksToggled(bool on) +{ + // We should now tell the PeaksViewer about this. It should have a global mode for AddingPeaks it merely needs to know the destination workspace + m_parent->addPeaksModeRequest(this, on); +} + +void PeaksWorkspaceWidget::exitClearPeaksMode() { + const SignalBlocker blocker(ui.btnRemovePeak); + ui.btnRemovePeak->setChecked(false); +} + +void PeaksWorkspaceWidget::exitAddPeaksMode() { + const SignalBlocker blocker(ui.btnAddPeak); + ui.btnAddPeak->setChecked(false); +} + } // namespace } diff --git a/Code/Mantid/MantidQt/SliceViewer/src/ProxyCompositePeaksPresenter.cpp b/Code/Mantid/MantidQt/SliceViewer/src/ProxyCompositePeaksPresenter.cpp index 75ea63782ff9f686f68a6e3769470047829e0f69..aa1278d6da7d58ac60cfcb05b29baf4e98e30d2a 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/ProxyCompositePeaksPresenter.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/ProxyCompositePeaksPresenter.cpp @@ -145,7 +145,17 @@ ProxyCompositePeaksPresenter::getZoomedPeakPresenter() const { } int ProxyCompositePeaksPresenter::getZoomedPeakIndex() const { - return m_compositePresenter->getZoomedPeakIndex(); + return m_compositePresenter->getZoomedPeakIndex(); } + +void ProxyCompositePeaksPresenter::editCommand(EditMode editMode, boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target) +{ + m_compositePresenter->editCommand(editMode, target); +} + +bool ProxyCompositePeaksPresenter::hasPeakAddModeFor(boost::weak_ptr<const Mantid::API::IPeaksWorkspace> target){ + return m_compositePresenter->hasPeakAddModeFor(target); +} + } } diff --git a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp index bc6309fb090df9348ebe78b134831d9de022836d..8dd715ab7faba3bb5f95a1fec989538cf9f30c00 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp @@ -42,6 +42,7 @@ #include "MantidQtSliceViewer/PeaksViewerOverlayDialog.h" #include "MantidQtSliceViewer/PeakOverlayViewFactorySelector.h" #include "MantidQtMantidWidgets/SelectWorkspacesDialog.h" +#include "MantidQtMantidWidgets/InputController.h" #include <qwt_plot_panner.h> #include <Poco/AutoPtr.h> @@ -82,7 +83,7 @@ SliceViewer::SliceViewer(QWidget *parent) m_peaksPresenter(boost::make_shared<CompositePeaksPresenter>(this)), m_proxyPeaksPresenter( boost::make_shared<ProxyCompositePeaksPresenter>(m_peaksPresenter)), - m_peaksSliderWidget(NULL) { + m_peaksSliderWidget(NULL){ ui.setupUi(this); @@ -2195,12 +2196,14 @@ SliceViewer::setPeaksWorkspaces(const QStringList &list) { // Candidate for overplotting as spherical peaks viewFactorySelector->registerCandidate( boost::make_shared<PeakOverlayMultiSphereFactory>( - peaksWS, m_plot, m_plot->canvas(), numberOfChildPresenters)); + peaksWS, m_plot, m_plot->canvas(), m_spect->xAxis(), + m_spect->yAxis(), numberOfChildPresenters)); // Candiate for plotting as a markers of peak positions viewFactorySelector->registerCandidate( boost::make_shared<PeakOverlayMultiCrossFactory>( m_ws, transformFactory->createDefaultTransform(), peaksWS, m_plot, - m_plot->canvas(), numberOfChildPresenters)); + m_plot->canvas(), m_spect->xAxis(), + m_spect->yAxis(), numberOfChildPresenters)); try { m_peaksPresenter->addPeaksPresenter( boost::make_shared<ConcretePeaksPresenter>( @@ -2409,5 +2412,6 @@ void SliceViewer::dropEvent(QDropEvent *e) { } } + } // namespace } diff --git a/Code/Mantid/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h b/Code/Mantid/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h index 6d6e2bbc190866cecd0b1313540ffea148d6f6e0..96eba7117da3a1427848e5a6815ac9cfca20bb99 100644 --- a/Code/Mantid/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h +++ b/Code/Mantid/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h @@ -941,6 +941,45 @@ public: } + void test_edit_command() + { + + // Prepare subject objects. + Mantid::API::IPeaksWorkspace_sptr peaksWSA = boost::make_shared<Mantid::DataObjects::PeaksWorkspace>(); + SetPeaksWorkspaces setA; + setA.insert(peaksWSA); + auto* pSubjectA = new NiceMock<MockPeaksPresenter>; + PeaksPresenter_sptr subjectA(pSubjectA); + EXPECT_CALL(*pSubjectA, presentedWorkspaces()).WillRepeatedly(Return(setA)); + EXPECT_CALL(*pSubjectA, contentsDifferent(_)).WillOnce(Return(true)); + + Mantid::API::IPeaksWorkspace_sptr peaksWSB = boost::make_shared<Mantid::DataObjects::PeaksWorkspace>(); + SetPeaksWorkspaces setB; + setA.insert(peaksWSB); + auto* pSubjectB = new NiceMock<MockPeaksPresenter>; + PeaksPresenter_sptr subjectB(pSubjectB); + EXPECT_CALL(*pSubjectB, presentedWorkspaces()).WillRepeatedly(Return(setB)); + EXPECT_CALL(*pSubjectB, contentsDifferent(_)).WillOnce(Return(true)); + + // Set a background colour on the composite. + CompositePeaksPresenter composite(&_fakeZoomableView); + composite.addPeaksPresenter(subjectA); + composite.addPeaksPresenter(subjectB); + + /* Now we are going to say that we only want to add peaks to the first peaks workspace of the first presenter. + so lets prep the presenters for this + */ + EXPECT_CALL(*pSubjectA, peakEditMode(AddPeaks)).Times(AtLeast(1)); + EXPECT_CALL(*pSubjectB, peakEditMode(MantidQt::SliceViewer::None)).Times(AtLeast(1)); + // Execute it. + composite.editCommand(AddPeaks, peaksWSA); + + // Check that we used the subjects correctly + TS_ASSERT(Mock::VerifyAndClearExpectations(pSubjectA)); + TS_ASSERT(Mock::VerifyAndClearExpectations(pSubjectB)); + } + + }; diff --git a/Code/Mantid/MantidQt/SliceViewer/test/ConcretePeaksPresenterTest.h b/Code/Mantid/MantidQt/SliceViewer/test/ConcretePeaksPresenterTest.h index 3bdfc87bc841f674e536336195075705e61e7c13..f849197c6cef1c8a666867b5d66d05d0879ec99d 100644 --- a/Code/Mantid/MantidQt/SliceViewer/test/ConcretePeaksPresenterTest.h +++ b/Code/Mantid/MantidQt/SliceViewer/test/ConcretePeaksPresenterTest.h @@ -7,6 +7,8 @@ #include "MantidAPI/FrameworkManager.h" #include "MantidKernel/SpecialCoordinateSystem.h" #include "MantidGeometry/Crystal/PeakTransformFactory.h" +#include "MantidDataObjects/Peak.h" +#include "MantidDataObjects/PeakShapeSpherical.h" #include "MantidQtSliceViewer/ConcretePeaksPresenter.h" #include "MantidQtSliceViewer/PeakOverlayViewFactory.h" #include "MantidDataObjects/PeaksWorkspace.h" @@ -150,16 +152,26 @@ class ConcretePeaksPresenterTest : public CxxTest::TestSuite 1) All constructor parameters can be overriden using methods with....() on the returned builder object 2) The default builder has been set up to create a ubiquitious ConcretePeaksPresenter product. */ - ConcretePeaksPresenterBuilder createStandardBuild(const int expectedNumberPeaks=5) + ConcretePeaksPresenterBuilder createStandardBuild(const int expectedNumberPeaks=5, const double radius=0.0, const SpecialCoordinateSystem frame=QLab) { + // Map enum to string. + std::string frame_str = "Q (lab frame)"; + if(frame == Mantid::Kernel::HKL){ + frame_str = "HKL"; + } else if(frame == QSample) { + frame_str = "Q (sample frame)"; + } + // Create a mock view object that will be returned by the mock factory. auto mockView = boost::shared_ptr<NiceMock<MockPeakOverlayView> >(new NiceMock<MockPeakOverlayView>); + EXPECT_CALL(*mockView.get(), getRadius()).WillRepeatedly(Return(radius)); + // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -172,7 +184,8 @@ class ConcretePeaksPresenterTest : public CxxTest::TestSuite auto pMockTransform = new NiceMock<MockPeakTransform>; PeakTransform_sptr mockTransform(pMockTransform); EXPECT_CALL(*pMockTransform, transformPeak(_)).WillRepeatedly(Return(V3D())); - EXPECT_CALL(*pMockTransform, getFriendlyName()).WillRepeatedly(Return("Q (lab frame)")); + EXPECT_CALL(*pMockTransform, getFriendlyName()).WillRepeatedly(Return(frame_str)); + EXPECT_CALL(*pMockTransform, getCoordinateSystem()).WillRepeatedly(Return(frame)); // Create a mock transform factory. auto pMockTransformFactory = new NiceMock<MockPeakTransformFactory>; @@ -214,13 +227,14 @@ public: // Mock View Factory for integrated peaks. We expect that this will never be used. auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).Times(1).WillRepeatedly(Return(mockView)); // Create a single widget/view for all peaks + EXPECT_CALL(*pMockViewFactory, createView(_,_)).Times(1).WillRepeatedly(Return(mockView)); // Create a single widget/view for all peaks EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillOnce(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillOnce(Return("K")); // Create a mock transform object. auto pMockTransform = new NiceMock<MockPeakTransform>; PeakTransform_sptr mockTransform(pMockTransform); + EXPECT_CALL(*pMockTransform, getCoordinateSystem()).WillRepeatedly(Return(Mantid::Kernel::QLab)); // Create a mock transform factory. auto pMockTransformFactory = new NiceMock<MockPeakTransformFactory>; @@ -255,7 +269,7 @@ public: EXPECT_CALL(*pMockView, updateView()).Times(1); // Single view, for this presenter, will only update once. auto mockView = boost::shared_ptr<NiceMock<MockPeakOverlayView> >(pMockView); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillOnce(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillOnce(Return("K")); @@ -268,6 +282,7 @@ public: auto pMockTransform = new NiceMock<MockPeakTransform>; PeakTransform_sptr mockTransform(pMockTransform); EXPECT_CALL(*pMockTransform, transformPeak(_)).WillRepeatedly(Return(V3D())); + EXPECT_CALL(*pMockTransform, getCoordinateSystem()).WillRepeatedly(Return(Mantid::Kernel::QLab)); // Create a mock transform factory. auto pMockTransformFactory = new NiceMock<MockPeakTransformFactory>; @@ -297,7 +312,7 @@ public: EXPECT_CALL(*pMockView, setSlicePoint(slicePoint, _)).Times(1); // Only one widget for this presenter auto mockView = boost::shared_ptr<NiceMock<MockPeakOverlayView> >(pMockView); - EXPECT_CALL(*mockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*mockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*mockViewFactory, getPlotXLabel()).WillOnce(Return("H")); EXPECT_CALL(*mockViewFactory, getPlotYLabel()).WillOnce(Return("K")); @@ -309,6 +324,7 @@ public: // Create a mock transform object. auto pMockTransform = new NiceMock<MockPeakTransform>; PeakTransform_sptr mockTransform(pMockTransform); + EXPECT_CALL(*pMockTransform, getCoordinateSystem()).WillRepeatedly(Return(Mantid::Kernel::HKL)); EXPECT_CALL(*pMockTransform, getFriendlyName()).WillOnce(Return("HKL")); EXPECT_CALL(*pMockTransform, transformPeak(_)).WillRepeatedly(Return(V3D())); @@ -341,7 +357,7 @@ public: EXPECT_CALL(*pMockView, hideView()).Times(expectedNumberPeaks); auto mockView = boost::shared_ptr<NiceMock<MockPeakOverlayView> >(pMockView); - EXPECT_CALL(*mockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*mockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*mockViewFactory, getPlotXLabel()).WillOnce(Return("H")); EXPECT_CALL(*mockViewFactory, getPlotYLabel()).WillOnce(Return("K")); @@ -358,6 +374,7 @@ public: // Create a mock transform factory. auto pMockTransformFactory = new NiceMock<MockPeakTransformFactory>; PeakTransformFactory_sptr peakTransformFactory(pMockTransformFactory); + EXPECT_CALL(*pMockTransform, getCoordinateSystem()).WillRepeatedly(Return(Mantid::Kernel::QLab)); EXPECT_CALL(*pMockTransformFactory, createDefaultTransform()).WillOnce(Return(mockTransform)); EXPECT_CALL(*pMockTransformFactory, createTransform(_,_)).WillOnce(Return(mockTransform)); @@ -381,7 +398,7 @@ public: EXPECT_CALL(*pMockView, hideView()).Times(expectedNumberPeaks); // This will be called automatically because the presenter won't be able to map Qx (below). auto mockView = boost::shared_ptr<NiceMock<MockPeakOverlayView> >(pMockView); - EXPECT_CALL(*mockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*mockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*mockViewFactory, getPlotXLabel()).WillOnce(Return("Qx")); // Not either H, K or L EXPECT_CALL(*mockViewFactory, getPlotYLabel()).WillOnce(Return("K")); // Create an input MODEL Peaks workspace (INTEGRATED) @@ -392,6 +409,7 @@ public: // Create a mock transform object. auto pMockTransform = new NiceMock<MockPeakTransform>; PeakTransform_sptr mockTransform(pMockTransform); + EXPECT_CALL(*pMockTransform, getCoordinateSystem()).WillRepeatedly(Return(Mantid::Kernel::QLab)); EXPECT_CALL(*pMockTransform, transformPeak(_)).WillRepeatedly(Return(V3D())); // Create a mock transform factory. @@ -418,7 +436,7 @@ public: // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -444,7 +462,7 @@ public: // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -471,7 +489,7 @@ public: // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -516,7 +534,7 @@ public: // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -529,8 +547,6 @@ public: void doTestSorting(const bool sortAscending) { - FrameworkManager::Instance(); - const int expectedNumberOfPeaks = 1; auto concreteBuilder = createStandardBuild(expectedNumberOfPeaks); @@ -540,9 +556,9 @@ public: EXPECT_CALL(*pMockView, setSlicePoint(_,_)).Times(1); // Expect that the slice point will be re-set upon sorting. // Create a widget factory mock - auto pMockViewFactory = new MockPeakOverlayFactory; + auto pMockViewFactory = new NiceMock<MockPeakOverlayFactory>; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -606,7 +622,7 @@ public: // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -632,7 +648,7 @@ public: // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -657,7 +673,7 @@ public: // Create a widget factory mock auto pMockViewFactory = new MockPeakOverlayFactory; PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); - EXPECT_CALL(*pMockViewFactory, createView(_)).WillOnce(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillOnce(Return(mockView)); EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); @@ -673,7 +689,7 @@ public: // We expect the peaks workspace object to be swapped. EXPECT_CALL(*pMockViewFactory, swapPeaksWorkspace(_)).Times(1); // We expect that createViews will be called again, because we'll have to create new representations for each peak - EXPECT_CALL(*pMockViewFactory, createView(_)).WillOnce(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillOnce(Return(mockView)); // We force this concrete presenter to take a new peaks workspace to represent concretePresenter->reInitialize(newPeaksWorkspace); @@ -727,6 +743,105 @@ public: } + void test_test_apply_edit_mode_to_views(){ + const int nPeaks = 1; + + // Create a mock view object/product that will be returned by the mock factory. + auto pMockView = new NiceMock<MockPeakOverlayView>; + auto mockView = boost::shared_ptr<NiceMock<MockPeakOverlayView> >(pMockView); + + // Create a widget factory mock + auto pMockViewFactory = new MockPeakOverlayFactory; + PeakOverlayViewFactory_sptr mockViewFactory = PeakOverlayViewFactory_sptr(pMockViewFactory); + EXPECT_CALL(*pMockViewFactory, createView(_,_)).WillRepeatedly(Return(mockView)); + EXPECT_CALL(*pMockViewFactory, getPlotXLabel()).WillRepeatedly(Return("H")); + EXPECT_CALL(*pMockViewFactory, getPlotYLabel()).WillRepeatedly(Return("K")); + + auto presenterBuilder = createStandardBuild(nPeaks); // Creates a default Concrete presenter product. + presenterBuilder.withViewFactory(mockViewFactory); // Change the view factories to deliver the expected mock object + auto concretePresenter = presenterBuilder.create(); + + // Deletion mode tests + EXPECT_CALL(*pMockView, peakDeletionMode()).Times(1); + concretePresenter->peakEditMode(DeletePeaks); + + // Addition mode tests + EXPECT_CALL(*pMockView, peakAdditionMode()).Times(1); + concretePresenter->peakEditMode(AddPeaks); + + // Neutral mode tests + EXPECT_CALL(*pMockView, peakDisplayMode()).Times(1); + concretePresenter->peakEditMode(MantidQt::SliceViewer::None); + + TSM_ASSERT("MockView not used as expected.", Mock::VerifyAndClearExpectations(pMockView)); + } + + + + //void test_deletePeaksIn(){TSM_ASSERT("Missing test", false);} + + void makeSphericallyIntegrated(IPeak& peak, const double radius) + { + using namespace Mantid::DataObjects; + Peak* pPeak = dynamic_cast<Peak*>(&peak); + pPeak->setPeakShape(boost::make_shared<PeakShapeSpherical>(radius, Mantid::Kernel::HKL)); + } + + void test_delete_in() { + using namespace Mantid::DataObjects; + + const int nPeaks = 3; + const double radius = 0.1; + auto concreteBuilder = createStandardBuild(nPeaks, radius, Mantid::Kernel::HKL); + + // Custom peaks workspace + IPeaksWorkspace_sptr peaksWS = createPeaksWorkspace(nPeaks, radius); + // Customize a peak + IPeak& peakToDelete1 = peaksWS->getPeak(0); + peakToDelete1.setHKL(0,0,0); + makeSphericallyIntegrated(peakToDelete1, radius); + // Customize another peak + IPeak& peakToDelete2 = peaksWS->getPeak(0); + peakToDelete2.setHKL(1,0,0); + makeSphericallyIntegrated(peakToDelete2, radius); + // Customize another peak + peaksWS->getPeak(2).setHKL(10, 10, 10); // Not integrated, will be well out of range anyway. + + /****************** + + x (10,10,10) + + ----------------------- cursor region = 0 to 1 and -0.5 to 0.5 + | x(0,0,0) x(1,0,0) | + ----------------------- + + ******************/ + + + concreteBuilder.withPeaksWorkspace(peaksWS); // Customise builder + + ConcretePeaksPresenter_sptr presenter = concreteBuilder.create(); + + /* + * Create a Cursor region. + */ + Top top(0.5); + Bottom bottom(-0.5); + Left left(0); + Right right(1); + SlicePoint slicePoint(0.0); + PeakBoundingBox cursorRegion(left, right, top, bottom, slicePoint); // psudo viewing frustrum. + + TSM_ASSERT_EQUALS("No peaks should have been removed yet", 3, peaksWS->getNumberPeaks()); + TSM_ASSERT("Point sits on peak radius. We should delete peak.", presenter->deletePeaksIn(cursorRegion)); + TSM_ASSERT_EQUALS("One peaks should remain", 1, peaksWS->getNumberPeaks()); + } + + void test_haspeakaddmode(){ + auto builder = createStandardBuild(5/*N Peaks*/, 1.0/*radius*/, QLab /*CHOSEN FRAME*/); + ConcretePeaksPresenter_sptr concretePeaksPresenter = builder.create(); + TSM_ASSERT("No peak add mode. As is not in the HKL frame", !concretePeaksPresenter->hasPeakAddMode()); + } }; diff --git a/Code/Mantid/MantidQt/SliceViewer/test/MockObjects.h b/Code/Mantid/MantidQt/SliceViewer/test/MockObjects.h index 8161be0cdb5b5ab40eac146cbf578d0cce253235..1a5a50c4feb03077cea2f2b47d54d659d352b8c6 100644 --- a/Code/Mantid/MantidQt/SliceViewer/test/MockObjects.h +++ b/Code/Mantid/MantidQt/SliceViewer/test/MockObjects.h @@ -66,9 +66,14 @@ namespace MOCK_METHOD1(reInitialize, void(boost::shared_ptr<Mantid::API::IPeaksWorkspace> peaksWS)); MOCK_CONST_METHOD1(contentsDifferent, bool(const PeaksPresenter* other)); + MOCK_METHOD1(deletePeaksIn, bool(PeakBoundingBox)); + MOCK_METHOD1(peakEditMode, void(EditMode)); + MOCK_METHOD2(addPeakAt, bool(double, double)); + MOCK_CONST_METHOD0(hasPeakAddMode, bool()); virtual ~MockPeaksPresenter(){} }; + /*------------------------------------------------------------ Mock Peaks Presenter, with additional hooks for verifying destruction. ------------------------------------------------------------*/ @@ -134,7 +139,11 @@ class MockPeakTransformFactory : public Geometry::PeakTransformFactory MOCK_CONST_METHOD0(isBackgroundShown, bool()); MOCK_CONST_METHOD0(getForegroundColour, QColor()); MOCK_CONST_METHOD0(getBackgroundColour, QColor()); - ~MockPeakOverlayView(){} + MOCK_METHOD0(peakDeletionMode, void()); + MOCK_METHOD0(peakAdditionMode, void()); + MOCK_METHOD0(peakDisplayMode, void()); + MOCK_METHOD1(takeSettingsFrom, void(PeakOverlayView const * const)); + virtual ~MockPeakOverlayView(){} }; /*------------------------------------------------------------ @@ -143,7 +152,7 @@ class MockPeakTransformFactory : public Geometry::PeakTransformFactory class MockPeakOverlayFactory : public PeakOverlayViewFactory { public: - MOCK_CONST_METHOD1(createView, boost::shared_ptr<PeakOverlayView>(PeakTransform_const_sptr)); + MOCK_CONST_METHOD2(createView, boost::shared_ptr<PeakOverlayView>(PeaksPresenter*, PeakTransform_const_sptr)); MOCK_CONST_METHOD0(getPlotXLabel, std::string()); MOCK_CONST_METHOD0(getPlotYLabel, std::string()); MOCK_METHOD0(updateView, void()); diff --git a/Code/Mantid/MantidQt/SliceViewer/test/NullPeaksPresenterTest.h b/Code/Mantid/MantidQt/SliceViewer/test/NullPeaksPresenterTest.h index cbb3b8a5cbc2d3ed1ea07aba27efe0a001e9a180..0e7898558c5c7ffeccc4fb8798b90d4b6675a082 100644 --- a/Code/Mantid/MantidQt/SliceViewer/test/NullPeaksPresenterTest.h +++ b/Code/Mantid/MantidQt/SliceViewer/test/NullPeaksPresenterTest.h @@ -121,6 +121,17 @@ public: TS_ASSERT(presenter.contentsDifferent(&other)); } + void test_peakEditMode(){ + NullPeaksPresenter presenter; + TS_ASSERT_THROWS_NOTHING(presenter.peakEditMode(AddPeaks);); + } + + void test_deletePeaksIn(){ + NullPeaksPresenter presenter; + PeakBoundingBox fake; + TS_ASSERT_THROWS_NOTHING(presenter.deletePeaksIn(fake)); + } + }; #endif