/* Copyright 2006-2016 The QElectroTech Team This file is part of QElectroTech. QElectroTech 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 2 of the License, or (at your option) any later version. QElectroTech 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 QElectroTech. If not, see . */ #include "partellipse.h" #include "QPropertyUndoCommand/qpropertyundocommand.h" #include "elementscene.h" /** * @brief PartEllipse::PartEllipse * Constructor * @param editor : QETElementEditor of this part * @param parent : parent item */ PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) : AbstractPartEllipse(editor, parent), m_handler(10), m_handler_index(-1), m_undo_command(nullptr) {} /** * @brief PartEllipse::~PartEllipse * Destructor */ PartEllipse::~PartEllipse() { if(m_undo_command) delete m_undo_command; } /** * @brief PartEllipse::paint * Draw this ellpise * @param painter * @param options * @param widget */ void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) { Q_UNUSED(widget); applyStylesToQPainter(*painter); QPen t = painter -> pen(); t.setCosmetic(options && options -> levelOfDetail < 1.0); if (isSelected()) t.setColor(Qt::red); painter -> setPen(t); painter -> drawEllipse(rect()); if (m_hovered) drawShadowShape(painter); if (isSelected()) { drawCross(m_rect.center(), painter); if (scene()->selectedItems().size() == 1) m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect)); } } /** * @brief PartEllipse::toXml * Export this ellipse in xml * @param xml_document : Xml document to use for create the xml element. * @return : an xml element that describe this ellipse */ const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const { QDomElement xml_element; if (qFuzzyCompare(rect().width(), rect().height())) { xml_element = xml_document.createElement("circle"); xml_element.setAttribute("diameter", QString("%1").arg(rect().width())); } else { xml_element = xml_document.createElement("ellipse"); xml_element.setAttribute("width", QString("%1").arg(rect().width())); xml_element.setAttribute("height", QString("%1").arg(rect().height())); } QPointF top_left(sceneTopLeft()); xml_element.setAttribute("x", QString("%1").arg(top_left.x())); xml_element.setAttribute("y", QString("%1").arg(top_left.y())); stylesToXml(xml_element); return(xml_element); } /** * @brief PartEllipse::fromXml * Import the properties of this ellipse from a xml element. * @param qde : Xml document to use. */ void PartEllipse::fromXml(const QDomElement &qde) { stylesFromXml(qde); qreal width, height; if (qde.tagName() == "ellipse") { width = qde.attribute("width", "0").toDouble(); height = qde.attribute("height", "0").toDouble(); } else width = height = qde.attribute("diameter", "0").toDouble(); m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(), qde.attribute("y", "0").toDouble()), QSizeF(width, height)); } QRectF PartEllipse::boundingRect() const { QRectF r = AbstractPartEllipse::boundingRect(); foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect))) r |= rect; return r; } /** * @brief PartEllipse::shape * @return the shape of this item */ QPainterPath PartEllipse::shape() const { QPainterPath shape; shape.addEllipse(m_rect); QPainterPathStroker pps; pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight()); shape = pps.createStroke(shape); if (isSelected()) foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect))) shape.addRect(rect); return shape; } QPainterPath PartEllipse::shadowShape() const { QPainterPath shape; shape.addEllipse(m_rect); QPainterPathStroker pps; pps.setWidth(penWeight()); return (pps.createStroke(shape)); } void PartEllipse::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { if (!isSelected()) { CustomElementGraphicPart::hoverMoveEvent(event); return; } int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect)); if (handler >= 0) { if (handler == 0 || handler == 2 || handler == 5 || handler == 7) setCursor(Qt::SizeAllCursor); else if (handler == 1 || handler == 6) setCursor(Qt::SizeVerCursor); else if (handler == 3 || handler == 4) setCursor(Qt::SizeHorCursor); } else CustomElementGraphicPart::hoverMoveEvent(event); } /** * @brief PartEllipse::mousePressEvent * Handle mouse press event * @param event */ void PartEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { setCursor(Qt::ClosedHandCursor); if (isSelected()) { m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect)); if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler { m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect)); m_undo_command->setText(tr("Modifier une ellipse")); m_undo_command->enableAnimation(); return; } } } CustomElementGraphicPart::mousePressEvent(event); } /** * @brief PartEllipse::mouseMoveEvent * Handle mouse move event * @param event */ void PartEllipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if(m_handler_index >= 0 && m_handler_index <= 7) { QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos())); prepareGeometryChange(); if (m_resize_mode == 1) setRect(m_handler.rectForPosAtIndex(m_rect, pos_, m_handler_index)); else setRect(m_handler.mirrorRectForPosAtIndex(m_rect, pos_, m_handler_index)); } else CustomElementGraphicPart::mouseMoveEvent(event); } /** * @brief PartEllipse::mouseReleaseEvent * Handle mouse release event * @param event */ void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { setCursor(Qt::OpenHandCursor); if (event->buttonDownPos(Qt::LeftButton) == event->pos()) switchResizeMode(); } if (m_handler_index >= 0 && m_handler_index <= 7) { if (!m_rect.isValid()) m_rect = m_rect.normalized(); m_undo_command->setNewValue(QVariant(m_rect)); elementScene()->undoStack().push(m_undo_command); m_undo_command = nullptr; m_handler_index = -1; } else CustomElementGraphicPart::mouseReleaseEvent(event); } void PartEllipse::switchResizeMode() { if (m_resize_mode == 1) { m_resize_mode = 2; m_handler.setOuterColor(Qt::darkGreen); } else { m_resize_mode = 1; m_handler.setOuterColor(Qt::blue); } update(); }