Shape2DCollection.h 5.36 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#ifndef MANTIDPLOT_SHAPE2DCOLLECTION_H_
#define MANTIDPLOT_SHAPE2DCOLLECTION_H_

#include "Shape2D.h"
#include "RectF.h"

#include <QList>
#include <QTransform>

class QPainter;
class QMouseEvent;
class QWheelEvent;
class QKeyEvent;

namespace MantidQt
{
	namespace MantidWidgets
	{

		/**
		* Class Shape2DCollection is a collection of 2D shapes.
		* It supports operations on teh shapes such as adding, removing, and aditting either
		* with the mouse via control points (CPs) or via properties.
		*
		* The shapes operate in two coordinate systems:
		* 1. 'Real' or logical coordinates
		* 2. Transformed screen coordinates
		*
		* Shape2DCollection must know the boundaries of the drawing area in logical and transformed screen coords.
		* They are set by calling setWindow(...) method. The first argument is the logical drawing rectangle and
		* the second one is the corresponding screen viewport in pixels. The individual shapes draw themselves in the
		* logical coords and unaware of the screen ones at all. If the size of the screen/widget changes setWindow
		* must be called again. Changing the logical drawing bounds translates and zooms the picture.
		* The transformation is done by Qt's QTransform object.
		*/
		class Shape2DCollection : public QObject, public Shape2D
		{
			Q_OBJECT
		public:
			Shape2DCollection();
41
42
43
44
45
                        ~Shape2DCollection() override;
                        Shape2D *clone() const override { return NULL; }
                        void setWindow(const RectF& surface, const QRect& viewport) const;
                        void draw(QPainter &painter) const override;
                        virtual void addShape(Shape2D*, bool slct = false);
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
			virtual void removeShape(Shape2D*, bool sendSignal = true);
			virtual void removeShapes(const QList<Shape2D*>&);
			virtual void clear();

			void keyPressEvent(QKeyEvent*);

			bool selectAtXY(int x, int y, bool edit = true);
			void deselectAtXY(int x, int y);
			bool selectIn(const QRect& rect);
			void removeCurrentShape();
			bool isEmpty()const { return m_shapes.isEmpty(); }
			size_t size()const { return static_cast<size_t>(m_shapes.size()); }
			void addToSelection(int i);
			bool hasSelection() const;

			RectF getCurrentBoundingRect()const;
			void setCurrentBoundingRect(const RectF &rect);
			// double properties
			QStringList getCurrentDoubleNames()const;
			double getCurrentDouble(const QString& prop) const;
			void setCurrentDouble(const QString& prop, double value);
			// QPointF properties
			QStringList getCurrentPointNames()const;
			QPointF getCurrentPoint(const QString& prop) const;
			void setCurrentPoint(const QString& prop, const QPointF& value);

			using Shape2D::isMasked; // Unhide base class method (avoids Intel compiler warning)
										// is a point in real space masked by any of the shapes
			bool isMasked(double x, double y)const;
			// collect all screen pixels that are masked by the shapes
76
			QList<QPoint> getMaskedPixels()const;
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

			// set the bounding rect of the current shape such that its real rect is given by the argument
			void setCurrentBoundingRectReal(const QRectF& rect);

			/// Change border color of all shapes.
			void changeBorderColor(const QColor& color);

		signals:

			void shapeCreated();
			void shapeSelected();
			void shapesDeselected();
			void shapesRemoved();
			void shapeChanged();
			void shapeChangeFinished();
			void cleared();

			public slots:
			void addShape(const QString& type, int x, int y, const QColor& borderColor, const QColor& fillColor);
			void addFreeShape(const QPolygonF&, const QColor& borderColor, const QColor& fillColor);
			void deselectAll();
			void moveRightBottomTo(int, int);
			void selectShapeOrControlPointAt(int x, int y);
			void addToSelectionShapeAt(int x, int y);
			void moveShapeOrControlPointBy(int dx, int dy);
			void touchShapeOrControlPointAt(int x, int y);
			void removeSelectedShapes();
			void restoreOverrideCursor();
			void drawFree(const QPolygonF& polygon);
			void eraseFree(const QPolygonF& polygon);

		protected:
109
110
111
112
                  void drawShape(QPainter &) const override {} // never called
                  void addToPath(QPainterPath &) const override {}
                  void refit() override;
                  void resetBoundingRect() override;
113

114
                        Shape2D* createShape(const QString& type, int x, int y)const;
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
			bool selectControlPointAt(int x, int y);
			void deselectControlPoint();
			bool isOverCurrentAt(int x, int y);
			bool isOverSelectionAt(int x, int y);
			void addToSelection(Shape2D* shape);
			void removeFromSelection(Shape2D* shape);
			void edit(Shape2D* shape);
			void finishEdit();
			QList<Shape2D*> getSelectedShapes() const { return m_selectedShapes; }

			QList<Shape2D*> m_shapes;
			mutable RectF m_surfaceRect;       ///< original surface window in "real" coordinates
			mutable double m_wx, m_wy;
			mutable int m_h;                   ///< original screen viewport height
			mutable QRect m_viewport;          ///< current screen viewport
			mutable QTransform m_transform;    ///< current transform

			Shape2D*  m_currentShape;          ///< shape selected to edit (change size/shape)
			size_t m_currentCP;                ///< control point of m_currentShape selected to edit
			QList<Shape2D*> m_selectedShapes;  ///< A list of selected shapes (can be moved or deleted)
			bool m_overridingCursor;
		};
	}//MantidWidgets
}//MantidQt

#endif /*MANTIDPLOT_SHAPE2DCOLLECTION_H_*/