diff --git a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp index 853500a58..19e5146a0 100644 --- a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp +++ b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp @@ -155,6 +155,17 @@ QVector QetGraphicsHandlerUtility::pointsForRect(const QRectF &rect) return vector; } +/** + * @brief QetGraphicsHandlerUtility::pointsForLine + * The point that define a line in a QVector. + * there is two points. + * @param line + * @return + */ +QVector QetGraphicsHandlerUtility::pointsForLine(const QLineF &line) { + return (QVector {line.p1(), line.p2()}); +} + /** * @brief QetGraphicsHandlerUtility::rectForPosAtIndex * Return a rectangle after modification of the point '@pos' at index '@index' of original rectangle '@old_rect'. @@ -180,3 +191,17 @@ QRectF QetGraphicsHandlerUtility::rectForPosAtIndex(const QRectF &old_rect, cons return rect; } + +/** + * @brief QetGraphicsHandlerUtility::lineForPosAtIndex + * Return a line after modification of @pos at index @index of @old_line. + * @param old_line + * @param pos + * @param index + * @return + */ +QLineF QetGraphicsHandlerUtility::lineForPosAtIndex(const QLineF &old_line, const QPointF &pos, int index) { + QLineF line = old_line; + index == 0 ? line.setP1(pos) : line.setP2(pos); + return line; +} diff --git a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h index cfbb31632..0681fab5b 100644 --- a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h +++ b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h @@ -19,6 +19,7 @@ #define QETGRAPHICSHANDLERUTILITY_H #include +#include class QPainter; @@ -47,7 +48,9 @@ class QetGraphicsHandlerUtility public: static QVector pointsForRect (const QRectF &rect); + static QVector pointsForLine (const QLineF &line); static QRectF rectForPosAtIndex (const QRectF &old_rect, const QPointF &pos, int index); + static QLineF lineForPosAtIndex (const QLineF &old_line, const QPointF &pos, int index); }; #endif // QETGRAPHICSHANDLERUTILITY_H diff --git a/sources/editor/editorcommands.cpp b/sources/editor/editorcommands.cpp index 7970166ed..300a70f0d 100644 --- a/sources/editor/editorcommands.cpp +++ b/sources/editor/editorcommands.cpp @@ -322,21 +322,32 @@ ChangePartCommand::ChangePartCommand( ElementEditionCommand(QString(QObject::tr("modification %1", "undo caption")).arg(name), 0, 0, parent), cep(part), property(prop), - old_value(old_v), - new_value(new_v) + m_old_value(old_v), + m_new_value(new_v) { } +ChangePartCommand::ChangePartCommand(const QString &part_name, CustomElementPart *part, const char *property_name, const QVariant &old_value, QUndoCommand *parent) : + ElementEditionCommand(QString(QObject::tr("modification %1", "undo caption")).arg(part_name), 0, 0, parent), + cep(part), + property(property_name), + m_old_value(old_value) +{} + /// Destructeur ChangePartCommand::~ChangePartCommand() { } +void ChangePartCommand::setNewValue(const QVariant &new_value) { + m_new_value = new_value; +} + /** * @brief ChangePartCommand::undo */ void ChangePartCommand::undo() { - cep -> setProperty(property, old_value); + cep -> setProperty(property, m_old_value); ElementEditionCommand::undo(); } @@ -345,7 +356,7 @@ void ChangePartCommand::undo() */ void ChangePartCommand::redo() { - cep -> setProperty(property, new_value); + cep -> setProperty(property, m_new_value); ElementEditionCommand::redo(); } diff --git a/sources/editor/editorcommands.h b/sources/editor/editorcommands.h index 417752b92..59299fbd5 100644 --- a/sources/editor/editorcommands.h +++ b/sources/editor/editorcommands.h @@ -175,29 +175,30 @@ class AddPartCommand : public ElementEditionCommand { This command changes a property of a primitive when editing an electrical element. */ -class ChangePartCommand : public ElementEditionCommand { - // constructors, destructor +class ChangePartCommand : public ElementEditionCommand +{ + // constructors, destructor public: - ChangePartCommand(const QString &, CustomElementPart *, const char *, const QVariant &, const QVariant &, QUndoCommand * = 0); - virtual ~ChangePartCommand(); + ChangePartCommand(const QString &, CustomElementPart *, const char *, const QVariant &, const QVariant &, QUndoCommand * = 0); + ChangePartCommand(const QString &part_name, CustomElementPart *part, const char *property_name, const QVariant &old_value, QUndoCommand *parent = 0); + virtual ~ChangePartCommand(); + + void setNewValue(const QVariant &new_value); + private: - ChangePartCommand(const ChangePartCommand &); + ChangePartCommand(const ChangePartCommand &); - // methods + // methods public: - virtual void undo(); - virtual void redo(); + virtual void undo(); + virtual void redo(); - // attributes + // attributes private: - /// Changed primitive - CustomElementPart *cep; - /// Changed property - const char *property; - /// Former value - QVariant old_value; - /// New value - QVariant new_value; + CustomElementPart *cep; + const char *property; + QVariant m_old_value; + QVariant m_new_value; }; /** diff --git a/sources/editor/elementscene.cpp b/sources/editor/elementscene.cpp index da046cba1..0328a00d6 100644 --- a/sources/editor/elementscene.cpp +++ b/sources/editor/elementscene.cpp @@ -1031,11 +1031,16 @@ void ElementScene::managePrimitivesGroups() { decorator_ -> hide(); } - // should we hide the decorator? + // should we hide the decorator? QList selected_items = zItems(ElementScene::Selected | ElementScene::IncludeTerminals); - if (!selected_items.count()) { + if (selected_items.size() == 0) decorator_ -> hide(); - } else { + else if (selected_items.size() == 1 && + selected_items.first()->type() != PartText::Type && + selected_items.first()->type() != PartTextField::Type) + decorator_->hide(); + else + { decorator_ -> setZValue(1000000); decorator_ -> setPos(0, 0); decorator_ -> setItems(selected_items); diff --git a/sources/editor/graphicspart/abstractpartellipse.h b/sources/editor/graphicspart/abstractpartellipse.h index f89b67177..110cc204f 100644 --- a/sources/editor/graphicspart/abstractpartellipse.h +++ b/sources/editor/graphicspart/abstractpartellipse.h @@ -39,6 +39,7 @@ class AbstractPartEllipse : public CustomElementGraphicPart Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY) Q_PROPERTY(qreal diameter_h READ width WRITE setWidth) Q_PROPERTY(qreal diameter_v READ height WRITE setHeight) + Q_PROPERTY(QRectF rect READ rect WRITE setRect) // constructors, destructor public: diff --git a/sources/editor/graphicspart/customelementgraphicpart.cpp b/sources/editor/graphicspart/customelementgraphicpart.cpp index 8b8a53f1b..73880d7e8 100644 --- a/sources/editor/graphicspart/customelementgraphicpart.cpp +++ b/sources/editor/graphicspart/customelementgraphicpart.cpp @@ -16,6 +16,8 @@ along with QElectroTech. If not, see . */ #include "customelementgraphicpart.h" +#include "elementscene.h" +#include "editorcommands.h" /** * @brief CustomElementGraphicPart::CustomElementGraphicPart @@ -34,7 +36,7 @@ CustomElementGraphicPart::CustomElementGraphicPart(QETElementEditor *editor, QGr _color(BlackColor), _antialiased(false) { - setFlags(QGraphicsItem::ItemIsSelectable); + setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); #if QT_VERSION >= 0x040600 setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); #endif @@ -437,3 +439,30 @@ void CustomElementGraphicPart::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) m_hovered = false; QGraphicsObject::hoverLeaveEvent(event); } + +void CustomElementGraphicPart::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + m_origin_pos = this->pos(); + + QGraphicsObject::mousePressEvent(event); +} + +void CustomElementGraphicPart::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if((event->buttons() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable)) + { + QPointF pos = event->scenePos() + (m_origin_pos - event->buttonDownScenePos(Qt::LeftButton)); + event->modifiers() == Qt::ControlModifier ? setPos(pos) : setPos(elementScene()->snapToGrid(pos)); + } + else + QGraphicsObject::mouseMoveEvent(event); +} + +void CustomElementGraphicPart::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if((event->button() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable) && m_origin_pos != pos()) + elementScene()->stackAction(new MovePartsCommand(pos() - m_origin_pos, 0, QList{this})); + + QGraphicsObject::mouseReleaseEvent(event); +} diff --git a/sources/editor/graphicspart/customelementgraphicpart.h b/sources/editor/graphicspart/customelementgraphicpart.h index 3eb1eabad..0eb4aab70 100644 --- a/sources/editor/graphicspart/customelementgraphicpart.h +++ b/sources/editor/graphicspart/customelementgraphicpart.h @@ -103,6 +103,10 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + // attributes bool m_hovered; private: @@ -111,6 +115,7 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar Filling _filling ; Color _color; bool _antialiased; + QPointF m_origin_pos, m_mouse_to_origin_pos; }; typedef CustomElementGraphicPart CEGP; diff --git a/sources/editor/graphicspart/partarc.cpp b/sources/editor/graphicspart/partarc.cpp index f268dd52e..5a2ddf475 100644 --- a/sources/editor/graphicspart/partarc.cpp +++ b/sources/editor/graphicspart/partarc.cpp @@ -16,6 +16,7 @@ along with QElectroTech. If not, see . */ #include "partarc.h" +#include "editorcommands.h" /** * @brief PartArc::PartArc @@ -24,7 +25,9 @@ * @param parent : parent item */ PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent) : - AbstractPartEllipse(editor, parent) + AbstractPartEllipse(editor, parent), + m_handler(10), + m_handler_index(-1) { m_start_angle = 0; m_span_angle = -1440; @@ -34,7 +37,9 @@ PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent) : * @brief PartArc::~PartArc * Destructor */ -PartArc::~PartArc() {} +PartArc::~PartArc() { + if(m_undo_command) delete m_undo_command; +} /** * @brief PartArc::paint @@ -71,7 +76,11 @@ void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, drawShadowShape(painter); if (isSelected()) + { drawCross(m_rect.center(), painter); + if (scene()->selectedItems().size() == 1) + m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect)); + } } /** @@ -122,6 +131,69 @@ QPainterPath PartArc::shape() const QPainterPathStroker pps; pps.setWidth(penWeight()); + shape = pps.createStroke(shape); - return (pps.createStroke(shape)); + if (isSelected()) + foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect))) + shape.addRect(rect); + + return shape; +} + +/** + * @brief PartArc::mousePressEvent + * Handle mouse press event + * @param event + */ +void PartArc::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (isSelected() && event->button() == Qt::LeftButton) + { + 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 ChangePartCommand(tr("Arc"), this, "rect", QVariant(m_rect)); + else + CustomElementGraphicPart::mousePressEvent(event); + } + else + CustomElementGraphicPart::mousePressEvent(event); +} + +/** + * @brief PartArc::mouseMoveEvent + * Handle mouse move event + * @param event + */ +void PartArc::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(); + setRect(m_handler.rectForPosAtIndex(m_rect, pos_, m_handler_index)); + } + else + CustomElementGraphicPart::mouseMoveEvent(event); +} + +/** + * @brief PartArc::mouseReleaseEvent + * Handle mouse release event + * @param event + */ +void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + 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()->stackAction(m_undo_command); + m_undo_command = nullptr; + m_handler_index = -1; + } + else + CustomElementGraphicPart::mouseReleaseEvent(event); } diff --git a/sources/editor/graphicspart/partarc.h b/sources/editor/graphicspart/partarc.h index f8bb84e71..3121bf821 100644 --- a/sources/editor/graphicspart/partarc.h +++ b/sources/editor/graphicspart/partarc.h @@ -19,6 +19,9 @@ #define PART_ARC_H #include "abstractpartellipse.h" +#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" + +class ChangePartCommand; /** * @brief The PartArc class @@ -53,5 +56,15 @@ class PartArc : public AbstractPartEllipse virtual void fromXml (const QDomElement &); virtual QPainterPath shape() const; + + protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + private: + QetGraphicsHandlerUtility m_handler; + int m_handler_index; + ChangePartCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partellipse.cpp b/sources/editor/graphicspart/partellipse.cpp index 3044b9f12..0d1f993bb 100644 --- a/sources/editor/graphicspart/partellipse.cpp +++ b/sources/editor/graphicspart/partellipse.cpp @@ -16,6 +16,7 @@ along with QElectroTech. If not, see . */ #include "partellipse.h" +#include "editorcommands.h" /** * @brief PartEllipse::PartEllipse @@ -24,14 +25,18 @@ * @param parent : parent item */ PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) : - AbstractPartEllipse(editor, parent) + AbstractPartEllipse(editor, parent), + m_handler(10), + m_handler_index(-1) {} /** * @brief PartEllipse::~PartEllipse * Destructor */ -PartEllipse::~PartEllipse() {} +PartEllipse::~PartEllipse() { + if(m_undo_command) delete m_undo_command; +} /** * @brief PartEllipse::paint @@ -58,7 +63,11 @@ void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio drawShadowShape(painter); if (isSelected()) + { drawCross(m_rect.center(), painter); + if (scene()->selectedItems().size() == 1) + m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect)); + } } /** @@ -125,6 +134,69 @@ QPainterPath PartEllipse::shape() const QPainterPathStroker pps; pps.setWidth(penWeight()); + shape = pps.createStroke(shape); - return (pps.createStroke(shape)); + if (isSelected()) + foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect))) + shape.addRect(rect); + + return shape; +} + +/** + * @brief PartEllipse::mousePressEvent + * Handle mouse press event + * @param event + */ +void PartEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (isSelected() && event->button() == Qt::LeftButton) + { + 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 ChangePartCommand(tr("Ellipse"), this, "rect", QVariant(m_rect)); + else + CustomElementGraphicPart::mousePressEvent(event); + } + else + 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(); + setRect(m_handler.rectForPosAtIndex(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 (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()->stackAction(m_undo_command); + m_undo_command = nullptr; + m_handler_index = -1; + } + else + CustomElementGraphicPart::mouseReleaseEvent(event); } diff --git a/sources/editor/graphicspart/partellipse.h b/sources/editor/graphicspart/partellipse.h index 8fb3824b3..bfe121c89 100644 --- a/sources/editor/graphicspart/partellipse.h +++ b/sources/editor/graphicspart/partellipse.h @@ -19,6 +19,9 @@ #define PART_ELLIPSE_H #include "abstractpartellipse.h" +#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" + +class ChangePartCommand; /** * @brief The PartEllipse class @@ -54,5 +57,15 @@ class PartEllipse : public AbstractPartEllipse virtual void fromXml (const QDomElement &); virtual QPainterPath shape() const; + + protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + private: + QetGraphicsHandlerUtility m_handler; + int m_handler_index; + ChangePartCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partline.cpp b/sources/editor/graphicspart/partline.cpp index bad313515..6f67a81eb 100644 --- a/sources/editor/graphicspart/partline.cpp +++ b/sources/editor/graphicspart/partline.cpp @@ -17,6 +17,7 @@ */ #include "partline.h" #include +#include "editorcommands.h" /** @@ -30,11 +31,15 @@ PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent) : first_end(Qet::None), first_length(1.5), second_end(Qet::None), - second_length(1.5) + second_length(1.5), + m_handler(10), + m_handler_index(-1) {} /// Destructeur -PartLine::~PartLine() {} +PartLine::~PartLine() { + if(m_undo_command) delete m_undo_command; +} /** * @brief PartLine::requiredLengthForEndType @@ -65,13 +70,13 @@ void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, Q_UNUSED(widget); if (isUseless()) return; + painter->save(); applyStylesToQPainter(*painter); QPen t = painter -> pen(); t.setJoinStyle(Qt::MiterJoin); t.setCosmetic(options && options -> levelOfDetail < 1.0); - if (isSelected()) - t.setColor(Qt::red); + if (isSelected()) t.setColor(Qt::red); painter -> setPen(t); @@ -82,6 +87,11 @@ void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, if (m_hovered) drawShadowShape(painter); + + if (isSelected() && scene()->selectedItems().size() == 1) + m_handler.drawHandler(painter, m_handler.pointsForLine(m_line)); + + painter->restore(); } /** @@ -167,6 +177,61 @@ void PartLine::setP2(const QPointF &p2) m_line.setP2(p2); } +/** + * @brief PartLine::mousePressEvent + * Handle mouse press event + * @param event + */ +void PartLine::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if(isSelected() && event->button() == Qt::LeftButton) + { + m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForLine(m_line)); + + if(m_handler_index >= 0 && m_handler_index <= 1) //User click on an handler + m_undo_command = new ChangePartCommand(tr("Ligne"), this, "line", QVariant(m_line)); + else + CustomElementGraphicPart::mousePressEvent(event); + } + else + CustomElementGraphicPart::mousePressEvent(event); +} + +/** + * @brief PartLine::mouseMoveEvent + * Handle pouse move event + * @param event + */ +void PartLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if(m_handler_index >= 0 && m_handler_index <= 1) + { + QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos())); + prepareGeometryChange(); + setLine(m_handler.lineForPosAtIndex(m_line, pos_, m_handler_index)); + } + else + CustomElementGraphicPart::mouseMoveEvent(event); +} + +/** + * @brief PartLine::mouseReleaseEvent + * Handle mouse release event + * @param event + */ +void PartLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (m_handler_index >= 0 && m_handler_index <= 1) + { + m_undo_command->setNewValue(QVariant(m_line)); + elementScene()->stackAction(m_undo_command); + m_undo_command = nullptr; + m_handler_index = -1; + } + else + CustomElementGraphicPart::mouseReleaseEvent(event); +} + /** * @brief PartLine::sceneP1 * @return the point p1 in scene coordinate @@ -420,6 +485,19 @@ QList PartLine::fourEndPoints(const QPointF &end_point, const QPointF & return(QList() << o << a << b << c); } +QLineF PartLine::line() const { + return m_line; +} + +void PartLine::setLine(const QLineF &line) +{ + if (m_line != line) + { + prepareGeometryChange(); + m_line = line; + } +} + /** * @brief PartLine::path * @return this line has a QPainterPath. diff --git a/sources/editor/graphicspart/partline.h b/sources/editor/graphicspart/partline.h index 38b89ded2..95a3762d2 100644 --- a/sources/editor/graphicspart/partline.h +++ b/sources/editor/graphicspart/partline.h @@ -20,6 +20,10 @@ #include "customelementgraphicpart.h" #include "qet.h" +#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" + +class ChangePartCommand; + /** This class represents a line primitive which may be used to compose the drawing of an electrical element within the element editor. Lines may have @@ -39,6 +43,7 @@ class PartLine : public CustomElementGraphicPart Q_PROPERTY(Qet::EndType end2 READ secondEndType WRITE setSecondEndType) Q_PROPERTY(qreal length1 READ firstEndLength WRITE setFirstEndLength) Q_PROPERTY(qreal length2 READ secondEndLength WRITE setSecondEndLength) + Q_PROPERTY(QLineF line READ line WRITE setLine) // constructors, destructor public: @@ -77,6 +82,8 @@ class PartLine : public CustomElementGraphicPart static uint requiredLengthForEndType(const Qet::EndType &); static QList fourEndPoints(const QPointF &, const QPointF &, const qreal &); + QLineF line() const; + void setLine(const QLineF &line); QPointF p1() const; void setP1 (const QPointF &p1); QPointF p2 () const; @@ -89,6 +96,11 @@ class PartLine : public CustomElementGraphicPart void setFirstEndLength(const qreal &l) {first_length = qMin(qAbs(l), m_line.length());} qreal secondEndLength() const {return second_length;} void setSecondEndLength(const qreal &l) {second_length = qMin(qAbs(l), m_line.length());} + + protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); private: QPainterPath path() const; @@ -105,5 +117,8 @@ class PartLine : public CustomElementGraphicPart qreal second_length; QList saved_points_; QLineF m_line; + QetGraphicsHandlerUtility m_handler; + int m_handler_index; + ChangePartCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partpolygon.cpp b/sources/editor/graphicspart/partpolygon.cpp index 7454c363c..618a585aa 100644 --- a/sources/editor/graphicspart/partpolygon.cpp +++ b/sources/editor/graphicspart/partpolygon.cpp @@ -16,6 +16,8 @@ along with QElectroTech. If not, see . */ #include "partpolygon.h" +#include "editorcommands.h" + /** * @brief PartPolygon::PartPolygon @@ -25,7 +27,9 @@ */ PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) : CustomElementGraphicPart(editor, parent), - m_closed(false) + m_closed(false), + m_handler(10), + m_handler_index(-1) {} /** @@ -56,6 +60,9 @@ void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio if (m_hovered) drawShadowShape(painter); + + if (isSelected() && scene()->selectedItems().size() == 1) + m_handler.drawHandler(painter, m_polygon); } /** @@ -228,6 +235,61 @@ void PartPolygon::removeLastPoint() } } +/** + * @brief PartPolygon::mousePressEvent + * Handle mouse press event + * @param event + */ +void PartPolygon::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (isSelected() && event->button() == Qt::LeftButton) + { + m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_polygon); + + if(m_handler_index >= 0) //User click on an handler + m_undo_command = new ChangePartCommand(tr("Polygone"), this, "polygon", QVariant(m_polygon)); + else + CustomElementGraphicPart::mousePressEvent(event); + } + else + CustomElementGraphicPart::mousePressEvent(event); +} + +/** + * @brief PartPolygon::mouseMoveEvent + * Handle mouse move event + * @param event + */ +void PartPolygon::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if(m_handler_index >= 0) + { + QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos())); + prepareGeometryChange(); + m_polygon.replace(m_handler_index, pos_); + } + else + CustomElementGraphicPart::mouseMoveEvent(event); +} + +/** + * @brief PartPolygon::mouseReleaseEvent + * Handle mouse release event + * @param event + */ +void PartPolygon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (m_handler_index >= 0) + { + m_undo_command->setNewValue(QVariant(m_polygon)); + elementScene()->stackAction(m_undo_command); + m_undo_command = nullptr; + m_handler_index = -1; + } + else + CustomElementGraphicPart::mouseReleaseEvent(event); +} + /** * @brief PartPolygon::shape * @return the shape of this item diff --git a/sources/editor/graphicspart/partpolygon.h b/sources/editor/graphicspart/partpolygon.h index 33f0cc48f..c6b863a4d 100644 --- a/sources/editor/graphicspart/partpolygon.h +++ b/sources/editor/graphicspart/partpolygon.h @@ -20,6 +20,10 @@ #include #include "customelementgraphicpart.h" +#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" + + +class ChangePartCommand; /** * @brief The PartPolygon class @@ -31,6 +35,7 @@ class PartPolygon : public CustomElementGraphicPart Q_OBJECT Q_PROPERTY(bool closed READ isClosed WRITE setClosed) + Q_PROPERTY(QPolygonF polygon READ polygon WRITE setPolygon) // constructors, destructor public: @@ -73,10 +78,18 @@ class PartPolygon : public CustomElementGraphicPart bool isClosed () const {return m_closed;} void setClosed (bool c) {m_closed = c;} + + protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); private: bool m_closed; QList saved_points_; QPolygonF m_polygon; + QetGraphicsHandlerUtility m_handler; + int m_handler_index; + ChangePartCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partrectangle.cpp b/sources/editor/graphicspart/partrectangle.cpp index 0f60e948c..70f0658cc 100644 --- a/sources/editor/graphicspart/partrectangle.cpp +++ b/sources/editor/graphicspart/partrectangle.cpp @@ -16,6 +16,8 @@ along with QElectroTech. If not, see . */ #include "partrectangle.h" +#include "elementscene.h" +#include "editorcommands.h" /** * @brief PartRectangle::PartRectangle @@ -24,13 +26,17 @@ * @param parent parent item */ PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) : - CustomElementGraphicPart(editor, parent) + CustomElementGraphicPart(editor, parent), + m_handler(10), + m_handler_index(-1) {} /** * @brief PartRectangle::~PartRectangle */ -PartRectangle::~PartRectangle() {} +PartRectangle::~PartRectangle() { + if(m_undo_command) delete m_undo_command; +} /** * @brief PartRectangle::paint @@ -62,7 +68,11 @@ void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt drawShadowShape(painter); if (isSelected()) + { drawCross(m_rect.center(), painter); + if (scene()->selectedItems().size() == 1) + m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect)); + } } /** @@ -91,10 +101,13 @@ const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const void PartRectangle::fromXml(const QDomElement &qde) { stylesFromXml(qde); - setRect(QRectF(mapFromScene(qde.attribute("x", "0").toDouble(), - qde.attribute("y", "0").toDouble()), - QSizeF(qde.attribute("width", "0").toDouble(), - qde.attribute("height", "0").toDouble()))); + setPos(mapFromScene(qde.attribute("x", "0").toDouble(), + qde.attribute("y", "0").toDouble())); + + QRectF rect(QPointF(0,0), QSizeF(qde.attribute("width", "0").toDouble(), + qde.attribute("height", "0").toDouble())); + + setRect(rect.normalized()); } /** @@ -242,3 +255,61 @@ void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rec QList mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_); setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1)))); } + +/** + * @brief PartRectangle::mousePressEvent + * Handle mouse press event + * @param event + */ +void PartRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (isSelected() && event->button() == Qt::LeftButton) + { + 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 ChangePartCommand(tr("Rectangle"), this, "rect", QVariant(m_rect)); + else + CustomElementGraphicPart::mousePressEvent(event); + } + else + CustomElementGraphicPart::mousePressEvent(event); +} + +/** + * @brief PartRectangle::mouseMoveEvent + * Handle mouse press event + * @param event + */ +void PartRectangle::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(); + setRect(m_handler.rectForPosAtIndex(m_rect, pos_, m_handler_index)); + } + else + CustomElementGraphicPart::mouseMoveEvent(event); +} + +/** + * @brief PartRectangle::mouseReleaseEvent + * Handle mouse release event + * @param event + */ +void PartRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + 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()->stackAction(m_undo_command); + m_undo_command = nullptr; + m_handler_index = -1; + } + else + CustomElementGraphicPart::mouseReleaseEvent(event); +} diff --git a/sources/editor/graphicspart/partrectangle.h b/sources/editor/graphicspart/partrectangle.h index 375fcce25..75c4ba24f 100644 --- a/sources/editor/graphicspart/partrectangle.h +++ b/sources/editor/graphicspart/partrectangle.h @@ -19,6 +19,9 @@ #define PART_RECTANGLE_H #include "customelementgraphicpart.h" +#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" + +class ChangePartCommand; /** * This class represents a rectangle primitive which may be used to compose the @@ -32,6 +35,7 @@ class PartRectangle : public CustomElementGraphicPart Q_PROPERTY(QPointF rectTopLeft READ rectTopLeft WRITE setRectTopLeft) Q_PROPERTY(qreal width READ width WRITE setWidth) Q_PROPERTY(qreal height READ height WRITE setHeight) + Q_PROPERTY(QRectF rect READ rect WRITE setRect) // constructors, destructor public: @@ -77,9 +81,17 @@ class PartRectangle : public CustomElementGraphicPart virtual void startUserTransformation(const QRectF &); virtual void handleUserTransformation(const QRectF &, const QRectF &); + + protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); private: QRectF m_rect; QList saved_points_; + QetGraphicsHandlerUtility m_handler; + int m_handler_index; + ChangePartCommand *m_undo_command; }; #endif