diff --git a/ChangeLog b/ChangeLog index 18f30a402..e2a552869 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ * Context menu display only enabled actions. * Add new feature -> alignment. * Alignment of text field can be edited. +* Add two new actions in context menu for insert or remove point of a selected polygon. * Diagram editor : * Conductors can now be drawn with two colors. diff --git a/sources/editor/elementscene.cpp b/sources/editor/elementscene.cpp index f93692d06..70a10cb33 100644 --- a/sources/editor/elementscene.cpp +++ b/sources/editor/elementscene.cpp @@ -240,6 +240,10 @@ void ElementScene::keyPressEvent(QKeyEvent *event) */ void ElementScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { + QGraphicsScene::contextMenuEvent(event); + if(event->isAccepted()) + return; + if (m_behavior == ElementScene::Normal) m_element_editor -> contextMenu(event->screenPos()); } @@ -302,11 +306,14 @@ void ElementScene::clearEventInterface() * Modifie the current behavior of this scene * @param b */ -void ElementScene::setBehavior(ElementScene::Behavior b) -{ +void ElementScene::setBehavior(ElementScene::Behavior b) { m_behavior = b; } +ElementScene::Behavior ElementScene::behavior() const { + return m_behavior; +} + /** @return la taille horizontale de la grille */ diff --git a/sources/editor/elementscene.h b/sources/editor/elementscene.h index 3904ac64e..9910f783b 100644 --- a/sources/editor/elementscene.h +++ b/sources/editor/elementscene.h @@ -91,6 +91,7 @@ class ElementScene : public QGraphicsScene void setEventInterface (ESEventInterface *event_interface); void clearEventInterface(); void setBehavior (ElementScene::Behavior); + ElementScene::Behavior behavior() const; QPointF snapToGrid(QPointF point); void setNames(const NamesList &); NamesList names() const; diff --git a/sources/editor/graphicspart/customelementgraphicpart.cpp b/sources/editor/graphicspart/customelementgraphicpart.cpp index b28948316..e6fb0124d 100644 --- a/sources/editor/graphicspart/customelementgraphicpart.cpp +++ b/sources/editor/graphicspart/customelementgraphicpart.cpp @@ -424,14 +424,6 @@ void CustomElementGraphicPart::hoverEnterEvent(QGraphicsSceneHoverEvent *event) QGraphicsObject::hoverEnterEvent(event); } -void CustomElementGraphicPart::hoverMoveEvent(QGraphicsSceneHoverEvent *event) -{ - if (isSelected()) - setCursor(Qt::OpenHandCursor); - - QGraphicsObject::hoverMoveEvent(event); -} - /** * @brief CustomElementGraphicPart::hoverLeaveEvent * Reimplemented from QGraphicsObject. @@ -441,7 +433,6 @@ void CustomElementGraphicPart::hoverMoveEvent(QGraphicsSceneHoverEvent *event) void CustomElementGraphicPart::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { m_hovered = false; - unsetCursor(); QGraphicsObject::hoverLeaveEvent(event); } diff --git a/sources/editor/graphicspart/customelementgraphicpart.h b/sources/editor/graphicspart/customelementgraphicpart.h index ac48ac694..7ffdbee27 100644 --- a/sources/editor/graphicspart/customelementgraphicpart.h +++ b/sources/editor/graphicspart/customelementgraphicpart.h @@ -103,7 +103,6 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; - void hoverMoveEvent (QGraphicsSceneHoverEvent *event) override; void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; void mousePressEvent(QGraphicsSceneMouseEvent *event) override; diff --git a/sources/editor/graphicspart/partpolygon.cpp b/sources/editor/graphicspart/partpolygon.cpp index 8d157325f..5a0ac4ed0 100644 --- a/sources/editor/graphicspart/partpolygon.cpp +++ b/sources/editor/graphicspart/partpolygon.cpp @@ -19,6 +19,8 @@ #include "QPropertyUndoCommand/qpropertyundocommand.h" #include "elementscene.h" #include "QetGraphicsItemModeler/qetgraphicshandleritem.h" +#include "qetelementeditor.h" +#include "qeticons.h" /** @@ -31,7 +33,14 @@ PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) : CustomElementGraphicPart(editor, parent), m_closed(false), m_undo_command(nullptr) -{} +{ + m_insert_point = new QAction(tr("Ajouter un point"), this); + m_insert_point->setIcon(QET::Icons::Add); + connect(m_insert_point, &QAction::triggered, this, &PartPolygon::insertPoint); + m_remove_point = new QAction(tr("Supprimer ce point"), this); + m_remove_point->setIcon(QET::Icons::Remove); + connect(m_remove_point, &QAction::triggered, this, &PartPolygon::removePoint); +} /** * @brief PartPolygon::~PartPolygon @@ -327,6 +336,30 @@ bool PartPolygon::sceneEventFilter(QGraphicsItem *watched, QEvent *event) return false; } +void PartPolygon::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + m_context_menu_pos = event->pos(); + event->ignore(); + if (isSelected() && elementScene() && (elementScene()->behavior() == ElementScene::Normal)) + { + QList list; + list << m_insert_point; + if (m_handler_vector.count() > 2) + { + for (QetGraphicsHandlerItem *qghi : m_handler_vector) + { + if (qghi->contains(qghi->mapFromScene(event->scenePos()))) + { + list << m_remove_point; + break; + } + } + } + elementScene()->editor()->contextMenu(event->screenPos(), list); + event->accept(); + } +} + /** * @brief PartPolygon::adjusteHandlerPos */ @@ -341,6 +374,12 @@ void PartPolygon::adjusteHandlerPos() for (int i = 0 ; i < points_vector.size() ; ++i) m_handler_vector.at(i)->setPos(points_vector.at(i)); } + else + { + qDeleteAll(m_handler_vector); + m_handler_vector.clear(); + addHandler(); + } } /** @@ -438,6 +477,95 @@ void PartPolygon::removeHandler() } } +/** + * @brief PartPolygon::insertPoint + * Insert a point in this polygone + */ +void PartPolygon::insertPoint() +{ + qreal max_angle = 0; + int index = 0; + + for (int i=1 ; i max_angle) + { + max_angle = angle; + index=i; + } + } + //Special case when polygon is close + if (m_closed) + { + QLineF line_a(m_polygon.last(), m_context_menu_pos); + QLineF line_b(m_context_menu_pos, m_polygon.first()); + + qreal angle = line_a.angleTo(line_b); + if (angle<180) + angle = 360-angle; + + if (angle > max_angle) + { + max_angle = angle; + index=m_polygon.size(); + } + } + + QPolygonF polygon = this->polygon(); + polygon.insert(index, elementScene()->snapToGrid(m_context_menu_pos)); + + //Wrap the undo for avoid to merge the undo commands when user add several points. + QUndoCommand *undo = new QUndoCommand(tr("Ajouter un point à un polygone")); + new QPropertyUndoCommand(this, "polygon", this->polygon(), polygon, undo); + elementScene()->undoStack().push(undo); +} + +/** + * @brief PartPolygon::removePoint + * remove a point on this polygon + */ +void PartPolygon::removePoint() +{ + if (m_handler_vector.size() == 2) + return; + + QPointF point = mapToScene(m_context_menu_pos); + int index = -1; + for (int i=0 ; icontains(qghi->mapFromScene(point))) + { + index = i; + break; + } + } + if (index > -1 && indexpolygon(); + polygon.removeAt(index); + + //Wrap the undo for avoid to merge the undo commands when user add several points. + QUndoCommand *undo = new QUndoCommand(tr("Supprimer un point d'un polygone")); + new QPropertyUndoCommand(this, "polygon", this->polygon(), polygon, undo); + elementScene()->undoStack().push(undo); + } + +} + /** * @brief PartPolygon::shape * @return the shape of this item diff --git a/sources/editor/graphicspart/partpolygon.h b/sources/editor/graphicspart/partpolygon.h index 27098ae44..5d5001acb 100644 --- a/sources/editor/graphicspart/partpolygon.h +++ b/sources/editor/graphicspart/partpolygon.h @@ -23,6 +23,7 @@ class QPropertyUndoCommand; class QetGraphicsHandlerItem; +class QAction; /** * @brief The PartPolygon class @@ -86,6 +87,7 @@ class PartPolygon : public CustomElementGraphicPart protected: QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override; + void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; private: void adjusteHandlerPos(); @@ -96,6 +98,8 @@ class PartPolygon : public CustomElementGraphicPart void addHandler(); void removeHandler(); + void insertPoint(); + void removePoint(); bool m_closed; @@ -104,5 +108,8 @@ class PartPolygon : public CustomElementGraphicPart QPropertyUndoCommand *m_undo_command; int m_vector_index = -1; QVector m_handler_vector; + QAction *m_insert_point, + *m_remove_point; + QPointF m_context_menu_pos; }; #endif diff --git a/sources/editor/qetelementeditor.cpp b/sources/editor/qetelementeditor.cpp index 200a42fbb..975199235 100644 --- a/sources/editor/qetelementeditor.cpp +++ b/sources/editor/qetelementeditor.cpp @@ -400,12 +400,16 @@ void QETElementEditor::setupMenus() { } /** - * @brief QETElementEditor::contextMenuEvent - * @param event + * @brief QETElementEditor::contextMenu + * Display a context menu, with all available action. + * @param p, the pos of the menu, in screen coordinate + * @param actions, a list of actions who can be prepended to the context menu. */ -void QETElementEditor::contextMenu(QPoint p) +void QETElementEditor::contextMenu(QPoint p, QList actions) { QMenu menu(this); + menu.addActions(actions); + menu.addSeparator(); menu.addAction(undo); menu.addAction(redo); menu.addAction(selectall); @@ -423,14 +427,14 @@ void QETElementEditor::contextMenu(QPoint p) menu.addActions(m_depth_action_group -> actions()); //Remove from the context menu the actions which are disabled. - const QListactions = menu.actions(); - for(QAction *action : actions) + const QListmenu_actions = menu.actions(); + for(QAction *action : menu_actions) { if(!action->isEnabled()) menu.removeAction(action); } menu.exec(p); - } +} /** diff --git a/sources/editor/qetelementeditor.h b/sources/editor/qetelementeditor.h index 5754abca2..810aafccd 100644 --- a/sources/editor/qetelementeditor.h +++ b/sources/editor/qetelementeditor.h @@ -92,25 +92,25 @@ class QETElementEditor : public QETMainWindow { // methods public: - void setNames(const NamesList &); - void setLocation(const ElementsLocation &); - ElementsLocation location() const; - void setFileName(const QString &); - QString fileName() const; - void setReadOnly(bool); - bool isReadOnly() const; - void fromFile(const QString &); - void fromLocation(const ElementsLocation &); - bool toFile(const QString &); - bool toLocation(const ElementsLocation &location); - bool isEditing(const ElementsLocation &); - bool isEditing(const QString &); - ElementScene *elementScene() const; - void readSettings(); - void writeSettings(); - static QPointF pasteOffset(); - static QString getOpenElementFileName(QWidget * = nullptr, const QString & = QString()); - void contextMenu(QPoint p); + void setNames(const NamesList &); + void setLocation(const ElementsLocation &); + ElementsLocation location() const; + void setFileName(const QString &); + QString fileName() const; + void setReadOnly(bool); + bool isReadOnly() const; + void fromFile(const QString &); + void fromLocation(const ElementsLocation &); + bool toFile(const QString &); + bool toLocation(const ElementsLocation &location); + bool isEditing(const ElementsLocation &); + bool isEditing(const QString &); + ElementScene *elementScene() const; + void readSettings(); + void writeSettings(); + static QPointF pasteOffset(); + static QString getOpenElementFileName(QWidget * = nullptr, const QString & = QString()); + void contextMenu(QPoint p, QList actions = QList()); signals: void saveToLocation(ElementsLocation loc);