Engauge Digitizer  2
GraphicsPoint.cpp
1 #include "CurveStyle.h"
2 #include "DataKey.h"
3 #include "EnumsToQt.h"
4 #include "GraphicsItemType.h"
5 #include "GraphicsPoint.h"
6 #include "GraphicsPointEllipse.h"
7 #include "GraphicsPointPolygon.h"
8 #include "Logger.h"
9 #include "PointStyle.h"
10 #include <QGraphicsEllipseItem>
11 #include <QGraphicsPolygonItem>
12 #include <QGraphicsScene>
13 #include <QGraphicsSceneContextMenuEvent>
14 #include <QPen>
15 #include <QTextStream>
16 #include "QtToString.h"
17 
18 const double ZERO_WIDTH = 0.0;
19 const double Z_VALUE = 100.0; // Put on top of Segments in DlgSettingsSegments
20 
21 GraphicsPoint::GraphicsPoint(QGraphicsScene &scene,
22  const QString &identifier,
23  const QPointF &posScreen,
24  const QColor &color,
25  unsigned int radius,
26  double lineWidth) :
28  m_scene (scene),
29  m_graphicsItemEllipse (0),
30  m_shadowZeroWidthEllipse (0),
31  m_graphicsItemPolygon (0),
32  m_shadowZeroWidthPolygon (0),
33  m_identifier (identifier),
34  m_posScreen (posScreen),
35  m_color (color),
36  m_lineWidth (lineWidth),
37  m_wanted (true)
38 {
39  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsPoint::GraphicsPoint"
40  << " identifier=" << identifier.toLatin1 ().data ();
41 
42  createPointEllipse (radius);
43 }
44 
45 GraphicsPoint::GraphicsPoint(QGraphicsScene &scene,
46  const QString &identifier,
47  const QPointF &posScreen,
48  const QColor &color,
49  const QPolygonF &polygon,
50  double lineWidth) :
52  m_scene (scene),
53  m_graphicsItemEllipse (0),
54  m_shadowZeroWidthEllipse (0),
55  m_graphicsItemPolygon (0),
56  m_shadowZeroWidthPolygon (0),
57  m_identifier (identifier),
58  m_posScreen (posScreen),
59  m_color (color),
60  m_lineWidth (lineWidth),
61  m_wanted (true)
62 {
63  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsPoint::GraphicsPoint "
64  << " identifier=" << identifier.toLatin1 ().data ();
65 
66  createPointPolygon (polygon);
67 }
68 
70 {
71  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsPoint::~GraphicsPoint";
72 
73  if (m_graphicsItemEllipse == 0) {
74 
75  QGraphicsScene *scene = m_graphicsItemPolygon->scene();
76 
77  // Since m_shadowZeroWidthPolygon is a child of m_graphicsItemPolygon, removing the parent removes both
78  scene->removeItem (m_graphicsItemPolygon);
79  delete m_graphicsItemPolygon;
80  m_graphicsItemPolygon = 0;
81  m_shadowZeroWidthPolygon = 0;
82 
83 
84  } else {
85 
86  QGraphicsScene *scene = m_graphicsItemEllipse->scene();
87 
88  // Since m_shadowZeroWidthEllipse is a child of m_graphicsItemEllipse, removing the parent removes both
89  scene->removeItem (m_graphicsItemEllipse);
90  delete m_graphicsItemEllipse;
91  m_graphicsItemEllipse = 0;
92  m_shadowZeroWidthEllipse = 0;
93 
94  }
95 }
96 
97 void GraphicsPoint::createPointEllipse (unsigned int radius)
98 {
99  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsPoint::createPointEllipse";
100 
101  m_graphicsItemEllipse = new GraphicsPointEllipse (*this,
102  QRect (- radius,
103  - radius,
104  2 * radius + 1,
105  2 * radius + 1));
106  m_scene.addItem (m_graphicsItemEllipse);
107 
108  m_graphicsItemEllipse->setZValue (Z_VALUE);
109  m_graphicsItemEllipse->setData (DATA_KEY_IDENTIFIER, m_identifier);
110  m_graphicsItemEllipse->setData (DATA_KEY_GRAPHICS_ITEM_TYPE, GRAPHICS_ITEM_TYPE_POINT);
111  m_graphicsItemEllipse->setPos (m_posScreen.x (),
112  m_posScreen.y ());
113  m_graphicsItemEllipse->setPen (QPen (QBrush (m_color), m_lineWidth));
114  m_graphicsItemEllipse->setEnabled (true);
115  m_graphicsItemEllipse->setFlags (QGraphicsItem::ItemIsSelectable |
116  QGraphicsItem::ItemIsMovable |
117  QGraphicsItem::ItemSendsGeometryChanges);
118 
119  m_graphicsItemEllipse->setToolTip (m_identifier);
120  m_graphicsItemEllipse->setData (DATA_KEY_GRAPHICS_ITEM_TYPE, GRAPHICS_ITEM_TYPE_POINT);
121 
122  // Shadow item is not selectable so it needs no stored data. Do NOT
123  // call QGraphicsScene::addItem since the QGraphicsItem::setParentItem call adds the item
124  m_shadowZeroWidthEllipse = new GraphicsPointEllipse (*this,
125  QRect (- radius,
126  - radius,
127  2 * radius + 1,
128  2 * radius + 1));
129  m_shadowZeroWidthEllipse->setParentItem(m_graphicsItemPolygon); // Dragging parent also drags child
130 
131  m_shadowZeroWidthEllipse->setPen (QPen (QBrush (m_color), ZERO_WIDTH));
132  m_shadowZeroWidthEllipse->setEnabled (true);
133 }
134 
135 void GraphicsPoint::createPointPolygon (const QPolygonF &polygon)
136 {
137  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsPoint::createPointPolygon";
138 
139  m_graphicsItemPolygon = new GraphicsPointPolygon (*this,
140  polygon);
141  m_scene.addItem (m_graphicsItemPolygon);
142 
143  m_graphicsItemPolygon->setZValue (Z_VALUE);
144  m_graphicsItemPolygon->setData (DATA_KEY_IDENTIFIER, m_identifier);
145  m_graphicsItemPolygon->setData (DATA_KEY_GRAPHICS_ITEM_TYPE, GRAPHICS_ITEM_TYPE_POINT);
146  m_graphicsItemPolygon->setPos (m_posScreen.x (),
147  m_posScreen.y ());
148  m_graphicsItemPolygon->setPen (QPen (QBrush (m_color), m_lineWidth));
149  m_graphicsItemPolygon->setEnabled (true);
150  m_graphicsItemPolygon->setFlags (QGraphicsItem::ItemIsSelectable |
151  QGraphicsItem::ItemIsMovable |
152  QGraphicsItem::ItemSendsGeometryChanges);
153 
154  m_graphicsItemPolygon->setToolTip (m_identifier);
155  m_graphicsItemPolygon->setData (DATA_KEY_GRAPHICS_ITEM_TYPE, GRAPHICS_ITEM_TYPE_POINT);
156 
157  // Shadow item is not selectable so it needs no stored data. Do NOT
158  // call QGraphicsScene::addItem since the QGraphicsItem::setParentItem call adds the item
159  m_shadowZeroWidthPolygon = new GraphicsPointPolygon (*this,
160  polygon);
161  m_shadowZeroWidthPolygon->setParentItem(m_graphicsItemPolygon); // Dragging parent also drags child
162 
163  m_shadowZeroWidthPolygon->setPen (QPen (QBrush (m_color), ZERO_WIDTH));
164  m_shadowZeroWidthPolygon->setEnabled (true);
165 }
166 
167 QVariant GraphicsPoint::data (int key) const
168 {
169  if (m_graphicsItemEllipse == 0) {
170  return m_graphicsItemPolygon->data (key);
171  } else {
172  return m_graphicsItemEllipse->data (key);
173  }
174 }
175 
176 QPointF GraphicsPoint::pos () const
177 {
178  if (m_graphicsItemEllipse == 0) {
179  return m_graphicsItemPolygon->pos ();
180  } else {
181  return m_graphicsItemEllipse->pos ();
182  }
183 }
184 
185 void GraphicsPoint::printStream (QString indentation,
186  QTextStream &str,
187  double ordinalKey) const
188 {
189  str << indentation << "GraphicsPoint\n";
190 
191  indentation += INDENTATION_DELTA;
192 
193  QString identifier;
194  QString pointType;
195  QPointF pos;
196  if (m_graphicsItemEllipse == 0) {
197  identifier = m_graphicsItemPolygon->data (DATA_KEY_IDENTIFIER).toString ();
198  pointType = "polygon";
199  pos = m_graphicsItemPolygon->pos();
200  } else {
201  identifier = m_graphicsItemEllipse->data (DATA_KEY_IDENTIFIER).toString ();
202  pointType = "ellipse";
203  pos = m_graphicsItemEllipse->pos();
204  }
205 
206  DataKey type = (DataKey) data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt();
207 
208  str << indentation << identifier
209  << " ordinalKey=" << ordinalKey
210  << " dataIdentifier=" << data (DATA_KEY_IDENTIFIER).toString().toLatin1().data()
211  << " dataType=" << dataKeyToString (type).toLatin1().data()
212  << " " << pointType << "Pos=" << QPointFToString (pos) << "\n";
213 }
214 
216 {
217  m_wanted = false;
218 }
219 
220 void GraphicsPoint::setData (int key, const QVariant &data)
221 {
222  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsPoint::setData"
223  << " key=" << dataKeyToString ((DataKey) key).toLatin1().data()
224  << " data=" << data.toString().toLatin1().data();
225 
226  if (m_graphicsItemEllipse == 0) {
227  m_graphicsItemPolygon->setData (key, data);
228  } else {
229  m_graphicsItemEllipse->setData (key, data);
230  }
231 }
232 
234 {
235  // Setting pen and radius of parent graphics items below also affects the child shadows
236  // (m_shadowItemPolygon and m_shadowItemEllipse)
237  if (m_graphicsItemEllipse == 0) {
238  if (pointStyle.shape() == POINT_SHAPE_CIRCLE) {
239 
240  // Transition from non-circle to circle. Deleting parent also deletes child shadow
241  delete m_graphicsItemPolygon;
242  m_graphicsItemPolygon = 0;
243  m_shadowZeroWidthPolygon = 0;
244 
245  createPointEllipse (pointStyle.radius());
246 
247  } else {
248 
249  // Update polygon
250  m_graphicsItemPolygon->setPen (QPen (ColorPaletteToQColor(pointStyle.paletteColor()),
251  pointStyle.lineWidth()));
252  m_shadowZeroWidthPolygon->setPen (QPen (ColorPaletteToQColor(pointStyle.paletteColor()),
253  pointStyle.lineWidth()));
254  m_graphicsItemPolygon->setPolygon (pointStyle.polygon());
255  m_shadowZeroWidthPolygon->setPolygon (pointStyle.polygon());
256 
257  }
258  } else {
259  if (pointStyle.shape() != POINT_SHAPE_CIRCLE) {
260 
261  // Transition from circle to non-circlee. Deleting parent also deletes child shadow
262  delete m_graphicsItemEllipse;
263  m_graphicsItemEllipse = 0;
264  m_shadowZeroWidthEllipse = 0;
265 
266  createPointPolygon (pointStyle.polygon());
267 
268  } else {
269 
270  // Update circle
271  m_graphicsItemEllipse->setPen (QPen (ColorPaletteToQColor(pointStyle.paletteColor()),
272  pointStyle.lineWidth()));
273  m_shadowZeroWidthEllipse->setPen (QPen (ColorPaletteToQColor(pointStyle.paletteColor()),
274  pointStyle.lineWidth()));
275  m_graphicsItemEllipse->setRadius (pointStyle.radius());
276  m_shadowZeroWidthEllipse->setRadius (pointStyle.radius());
277  }
278  }
279 }
280 
281 void GraphicsPoint::setPos (const QPointF pos)
282 {
283  if (m_graphicsItemEllipse == 0) {
284  return m_graphicsItemPolygon->setPos (pos);
285  } else {
286  return m_graphicsItemEllipse->setPos (pos);
287  }
288 }
289 
290 void GraphicsPoint::setToolTip (const QString &toolTip)
291 {
292  if (m_graphicsItemEllipse == 0) {
293  m_graphicsItemPolygon->setToolTip (toolTip);
294  } else {
295  m_graphicsItemEllipse->setToolTip (toolTip);
296  }
297 }
298 
300 {
301  m_wanted = true;
302 }
303 
305 {
306  setPointStyle (curveStyle.pointStyle()); // This point
307 }
308 
310 {
311  return m_wanted;
312 }
void setWanted()
Mark point as wanted. Marking as unwanted is done by the reset function.
int lineWidth() const
Get method for line width.
Definition: PointStyle.cpp:77
void printStream(QString indentation, QTextStream &str, double ordinalKey) const
Debugging method that supports print method of this class and printStream method of some other class(...
QPolygonF polygon() const
Return the polygon for creating a QGraphicsPolygonItem. The size is determined by the radius...
Definition: PointStyle.cpp:113
Base class for adding identifiers to graphics items that represent Points.
PointStyle pointStyle() const
Get method for PointStyle.
Definition: CurveStyle.cpp:69
void setData(int key, const QVariant &data)
Proxy method for QGraphicsItem::setData.
void setPos(const QPointF pos)
Update the position.
bool wanted() const
Identify point as wanted//unwanted.
void setPointStyle(const PointStyle &pointStyle)
Update the point style.
void updateCurveStyle(const CurveStyle &curveStyle)
Update point and line styles that comprise the curve style.
This class add event handling to QGraphicsEllipseItem.
Details for a specific Point.
Definition: PointStyle.h:14
~GraphicsPoint()
Destructor. This remove the graphics item from the scene.
ColorPalette paletteColor() const
Get method for point color.
Definition: PointStyle.cpp:108
Container for LineStyle and PointStyle for one Curve.
Definition: CurveStyle.h:12
int radius() const
Radius of point. For a circle this is all that is needed to draw a circle. For a polygon, the radius determines the size of the polygon.
Definition: PointStyle.cpp:211
This class add event handling to QGraphicsPolygonItem.
QPointF pos() const
Proxy method for QGraphicsItem::pos.
GraphicsPoint(QGraphicsScene &scene, const QString &identifier, const QPointF &posScreen, const QColor &color, unsigned int radius, double lineWidth)
Constructor of circular point.
QVariant data(int key) const
Proxy method for QGraphicsItem::data.
void setToolTip(const QString &toolTip)
Proxy method for QGraphicsItem::setToolTip.
PointShape shape() const
Get method for point shape.
Definition: PointStyle.cpp:250
void setRadius(int radius)
Update the radius.
void reset()
Mark point as unwanted, and unbind any bound lines.