QElectroTech  0.70
partellipse.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2006-2019 The QElectroTech Team
3  This file is part of QElectroTech.
4 
5  QElectroTech is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 2 of the License, or
8  (at your option) any later version.
9 
10  QElectroTech is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "partellipse.h"
20 #include "elementscene.h"
23 
30 PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
31  AbstractPartEllipse(editor, parent),
32  m_undo_command(nullptr)
33 {}
34 
40 {
41  if(m_undo_command) delete m_undo_command;
42  removeHandler();
43 }
44 
52 void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
53 {
54  Q_UNUSED(widget);
55  applyStylesToQPainter(*painter);
56 
57  QPen t = painter -> pen();
58  t.setCosmetic(options && options -> levelOfDetail < 1.0);
59 
60  if (isSelected())
61  t.setColor(Qt::red);
62 
63  painter -> setPen(t);
64  painter -> drawEllipse(rect());
65 
66  if (m_hovered)
67  drawShadowShape(painter);
68 
69  if (isSelected())
70  drawCross(m_rect.center(), painter);
71 }
72 
79 const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const
80 {
81  QDomElement xml_element;
82  if (qFuzzyCompare(rect().width(), rect().height()))
83  {
84  xml_element = xml_document.createElement("circle");
85  xml_element.setAttribute("diameter", QString("%1").arg(rect().width()));
86  }
87  else
88  {
89  xml_element = xml_document.createElement("ellipse");
90  xml_element.setAttribute("width", QString("%1").arg(rect().width()));
91  xml_element.setAttribute("height", QString("%1").arg(rect().height()));
92  }
93 
94  QPointF top_left(sceneTopLeft());
95  xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
96  xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
97 
98  stylesToXml(xml_element);
99 
100  return(xml_element);
101 }
102 
108 void PartEllipse::fromXml(const QDomElement &qde)
109 {
110  stylesFromXml(qde);
111  qreal width, height;
112 
113  if (qde.tagName() == "ellipse")
114  {
115  width = qde.attribute("width", "0").toDouble();
116  height = qde.attribute("height", "0").toDouble();
117  }
118  else
119  width = height = qde.attribute("diameter", "0").toDouble();
120 
121  m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
122  qde.attribute("y", "0").toDouble()),
123  QSizeF(width, height));
124 }
125 
130 QPainterPath PartEllipse::shape() const
131 {
132  QPainterPath shape;
133  shape.addEllipse(m_rect);
134 
135  QPainterPathStroker pps;
136  pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
137  shape = pps.createStroke(shape);
138 
139  return shape;
140 }
141 
142 QPainterPath PartEllipse::shadowShape() const
143 {
144  QPainterPath shape;
145  shape.addEllipse(m_rect);
146 
147  QPainterPathStroker pps;
148  pps.setWidth(penWeight());
149 
150  return (pps.createStroke(shape));
151 }
152 
158 void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
159 {
160  if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
162 
164 }
165 
172 QVariant PartEllipse::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
173 {
174  if (change == ItemSelectedHasChanged && scene())
175  {
176  if (value.toBool() == true)
177  {
178  //When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
179  //according to the number of selected items.
180  connect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
181 
182  if (scene()->selectedItems().size() == 1)
183  addHandler();
184  }
185  else
186  {
187  disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
188  removeHandler();
189  }
190  }
191  else if (change == ItemPositionHasChanged)
192  {
194  }
195  else if (change == ItemSceneChange)
196  {
197  if(scene())
198  disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
199 
200  setSelected(false); //This item is removed from scene, then we deselect this, and so, the handlers is also removed.
201  }
202 
203  return QGraphicsItem::itemChange(change, value);
204 }
205 
212 bool PartEllipse::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
213 {
214  //Watched must be an handler
215  if(watched->type() == QetGraphicsHandlerItem::Type)
216  {
217  QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
218 
219  if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
220  {
221  m_vector_index = m_handler_vector.indexOf(qghi);
222  if (m_vector_index != -1)
223  {
224  if(event->type() == QEvent::GraphicsSceneMousePress) //Click
225  {
226  handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
227  return true;
228  }
229  else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
230  {
231  handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
232  return true;
233  }
234  else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
235  {
236  handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
237  return true;
238  }
239  }
240  }
241  }
242 
243  return false;
244 }
245 
247 {
248  if (m_resize_mode == 1)
249  {
250  m_resize_mode = 2;
252  qghi->setColor(Qt::darkGreen);
253  }
254  else
255  {
256  m_resize_mode = 1;
258  qghi->setColor(Qt::blue);
259  }
260 }
261 
266 {
267  if (m_handler_vector.isEmpty())
268  return;
269 
270  QVector <QPointF> points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect);
271 
272  if (m_handler_vector.size() == points_vector.size())
273  {
274  points_vector = mapToScene(points_vector);
275  for (int i = 0 ; i < points_vector.size() ; ++i)
276  m_handler_vector.at(i)->setPos(points_vector.at(i));
277  }
278 }
279 
285 void PartEllipse::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
286 {
287  Q_UNUSED(qghi);
288  Q_UNUSED(event);
289 
290  m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
291  m_undo_command->setText(tr("Modifier un rectangle"));
293  return;
294 }
295 
301 void PartEllipse::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
302 {
303  Q_UNUSED(qghi);
304 
305  QPointF new_pos = event->scenePos();
306  if (event->modifiers() != Qt::ControlModifier)
307  new_pos = elementScene()->snapToGrid(event->scenePos());
308  new_pos = mapFromScene(new_pos);
309 
310  if (m_resize_mode == 1)
312  else
314 
316 }
317 
323 void PartEllipse::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
324 {
325  Q_UNUSED(qghi);
326  Q_UNUSED(event);
327 
328  m_undo_command->setNewValue(QVariant(m_rect));
330  m_undo_command = nullptr;
331  m_vector_index = -1;
332 }
333 
339 {
340  if (this->isSelected() && scene()->selectedItems().size() == 1)
341  addHandler();
342  else
343  removeHandler();
344 }
345 
351 {
352  if (m_handler_vector.isEmpty() && scene())
353  {
355 
357  {
358  QColor color = Qt::blue;
359  if (m_resize_mode == 2)
360  color = Qt::darkGreen;
361 
362  handler->setColor(color);
363  scene()->addItem(handler);
364  handler->installSceneEventFilter(this);
365  handler->setZValue(this->zValue()+1);
366  }
367  }
368 }
369 
375 {
376  if (!m_handler_vector.isEmpty())
377  {
378  qDeleteAll(m_handler_vector);
379  m_handler_vector.clear();
380  }
381 }
The QPropertyUndoCommand class This undo command manage QProperty of a QObject. This undo command can...
QPainterPath shape() const override
PartEllipse::shape.
PartEllipse(QETElementEditor *editor, QGraphicsItem *parent=nullptr)
PartEllipse::PartEllipse Constructor.
Definition: partellipse.cpp:30
const QDomElement toXml(QDomDocument &) const override
PartEllipse::toXml Export this ellipse in xml.
Definition: partellipse.cpp:79
~PartEllipse() override
PartEllipse::~PartEllipse Destructor.
Definition: partellipse.cpp:39
The QetGraphicsHandlerItem class This graphics item represents a point, destined to be used as an han...
int m_vector_index
Definition: partellipse.h:80
void handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
PartEllipse::handlerMousePressEvent.
void fromXml(const QDomElement &) override
PartEllipse::fromXml Import the properties of this ellipse from a xml element.
QRectF rect() const
void handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
PartEllipse::handlerMouseMoveEvent.
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override
PartEllipse::sceneEventFilter.
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *=nullptr) override
PartEllipse::paint Draw this ellpise.
Definition: partellipse.cpp:52
void enableAnimation(bool animate=true)
QPropertyUndoCommand::enableAnimation True to enable animation.
static void drawCross(const QPointF &center, QPainter *painter)
CustomElementGraphicPart::drawCross Draw a cross at pos center.
QVector< QetGraphicsHandlerItem * > m_handler_vector
QUndoStack & undoStack()
The AbstractPartEllipse class This is the base class for all ellipse based item like ellipse...
static QRectF mirrorRectForPosAtIndex(const QRectF &old_rect, const QPointF &pos, int index)
QetGraphicsHandlerUtility::mirrorRectForPosAtIndex Return a rectangle after modification of the point...
void sceneSelectionChanged()
PartEllipse::sceneSelectionChanged When the scene selection change, if there are several primitive se...
void removeHandler()
PartEllipse::removeHandler Remove the handlers of this item.
void stylesToXml(QDomElement &) const
CustomElementGraphicPart::stylesToXml Write the curent style to xml element. The style are stored lik...
static QRectF rectForPosAtIndex(const QRectF &old_rect, const QPointF &pos, int index)
QetGraphicsHandlerUtility::rectForPosAtIndex Return a rectangle after modification of the point &#39;&#39; at...
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
void adjusteHandlerPos()
PartEllipse::adjusteHandlerPos.
QIcon tr
Definition: qeticons.cpp:204
int m_resize_mode
Definition: partellipse.h:79
QPropertyUndoCommand * m_undo_command
Definition: partellipse.h:78
void setRect(const QRectF &rect) override
AbstractPartEllipse::setRect Sets the item&#39;s ellipse geometry to rect. The rectangle&#39;s left edge defi...
Definition: partellipse.h:59
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
PartEllipse::mouseReleaseEvent Handle mouse release event.
virtual QPointF sceneTopLeft() const
AbstractPartEllipse::sceneTopLeft.
void handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
PartEllipse::handlerMouseReleaseEvent.
void switchResizeMode()
void stylesFromXml(const QDomElement &)
CustomElementGraphicPart::stylesFromXml Read the style used by this, from a xml element.
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
PartEllipse::itemChange.
static QVector< QPointF > pointsForRect(const QRectF &rect)
QetGraphicsHandlerUtility::pointsForRect Return the keys points of the rectangle, stored in a vector...
void addHandler()
PartEllipse::addHandler Add handlers for this item.
QPainterPath shadowShape() const override
virtual ElementScene * elementScene() const
#define SHADOWS_HEIGHT
static QVector< QetGraphicsHandlerItem * > handlerForPoint(const QVector< QPointF > &points, int size=10)
QetGraphicsHandlerItem::handlerForPoint.
qreal penWeight() const
CustomElementGraphicPart::penWeight.
void applyStylesToQPainter(QPainter &) const
CustomElementGraphicPart::applyStylesToQPainter Apply the current style to the QPainter.
QPointF snapToGrid(QPointF point)
void setNewValue(const QVariant &new_value)
QPropertyUndoCommand::setNewValue Set the new value of the property (set with redo) to ...
void drawShadowShape(QPainter *painter)
CustomElementGraphicPart::drawShadowShape Draw a transparent blue shadow arround the shape of this it...