[qet] qet/qet: [5001] Toatly revamp of the handlers use to modify primitves, shapes and conductors. |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/qet Archives
]
Revision: 5001
Author: blacksun
Date: 2017-08-02 17:26:14 +0200 (Wed, 02 Aug 2017)
Log Message:
-----------
Toatly revamp of the handlers use to modify primitves, shapes and conductors.
Modified Paths:
--------------
trunk/dev_doc/enum_type_of_QGraphicsItem
trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri
trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
trunk/sources/diagram.cpp
trunk/sources/editor/elementprimitivedecorator.cpp
trunk/sources/editor/elementprimitivedecorator.h
trunk/sources/editor/elementscene.cpp
trunk/sources/editor/elementscene.h
trunk/sources/editor/graphicspart/abstractpartellipse.cpp
trunk/sources/editor/graphicspart/abstractpartellipse.h
trunk/sources/editor/graphicspart/partarc.cpp
trunk/sources/editor/graphicspart/partarc.h
trunk/sources/editor/graphicspart/partellipse.cpp
trunk/sources/editor/graphicspart/partellipse.h
trunk/sources/editor/graphicspart/partline.cpp
trunk/sources/editor/graphicspart/partline.h
trunk/sources/editor/graphicspart/partpolygon.cpp
trunk/sources/editor/graphicspart/partpolygon.h
trunk/sources/editor/graphicspart/partrectangle.cpp
trunk/sources/editor/graphicspart/partrectangle.h
trunk/sources/qetgraphicsitem/conductor.cpp
trunk/sources/qetgraphicsitem/conductor.h
trunk/sources/qetgraphicsitem/qetshapeitem.cpp
trunk/sources/qetgraphicsitem/qetshapeitem.h
Added Paths:
-----------
trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp
trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h
Modified: trunk/dev_doc/enum_type_of_QGraphicsItem
===================================================================
--- trunk/dev_doc/enum_type_of_QGraphicsItem 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/dev_doc/enum_type_of_QGraphicsItem 2017-08-02 15:26:14 UTC (rev 5001)
@@ -21,6 +21,3 @@
part text + 1107
part text field + 1108
part rectangle + 1109
-
-###QetGraphicsHandlerItem###
-QetGraphicsHandlerItem = 1200
Modified: trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri
===================================================================
--- trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri 2017-08-02 15:26:14 UTC (rev 5001)
@@ -1,5 +1,7 @@
HEADERS += \
- $$PWD/qetgraphicshandlerutility.h
+ $$PWD/qetgraphicshandlerutility.h \
+ $$PWD/qetgraphicshandleritem.h
SOURCES += \
- $$PWD/qetgraphicshandlerutility.cpp
+ $$PWD/qetgraphicshandlerutility.cpp \
+ $$PWD/qetgraphicshandleritem.cpp
Added: trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp (rev 0)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -0,0 +1,99 @@
+/*
+ Copyright 2006-2017 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 <http://www.gnu.org/licenses/>.
+*/
+#include "qetgraphicshandleritem.h"
+#include <QPainter>
+#include <QDebug>
+
+/**
+ * @brief QetGraphicsHandlerItem::QetGraphicsHandlerItem
+ * @param size, the size of the handler
+ */
+QetGraphicsHandlerItem::QetGraphicsHandlerItem(qreal size) :
+ m_size(size)
+{}
+
+/**
+ * @brief QetGraphicsHandlerItem::boundingRect
+ * @return
+ */
+QRectF QetGraphicsHandlerItem::boundingRect() const
+{
+ qreal rect_size = m_size * m_previous_zoom_factor;
+ QRectF rect(0-rect_size/2, 0-rect_size/2, rect_size, rect_size);
+ rect.adjust(-2, -2, 2, 2);
+ return rect;
+}
+
+/**
+ * @brief QetGraphicsHandlerItem::setColor
+ * @param color, set the color of the handler
+ */
+void QetGraphicsHandlerItem::setColor(QColor color)
+{
+ m_color = color;
+ update();
+}
+
+/**
+ * @brief QetGraphicsHandlerItem::paint
+ * @param painter
+ * @param option
+ * @param widget
+ */
+void QetGraphicsHandlerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ qreal zoom_factor = 1.0/painter->transform().m11();
+ if(zoom_factor != m_previous_zoom_factor)
+ {
+ prepareGeometryChange();
+ m_previous_zoom_factor = zoom_factor;
+ }
+
+ qreal rect_size = m_size * m_previous_zoom_factor;
+ QRectF rect(0-rect_size/2, 0-rect_size/2, rect_size, rect_size);
+
+ painter->save();
+ painter->setBrush(QBrush(m_color));
+ QPen pen(QBrush(m_color), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
+ pen.setCosmetic(true);
+ painter->setPen(pen);
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ painter->drawEllipse(rect);
+ painter->restore();
+}
+
+/**
+ * @brief QetGraphicsHandlerItem::handlerForPoint
+ * @param points
+ * @return A list of handler with pos at point
+ */
+QVector<QetGraphicsHandlerItem *> QetGraphicsHandlerItem::handlerForPoint(const QVector<QPointF> &points, int size)
+{
+ QVector <QetGraphicsHandlerItem *> list_;
+ for (QPointF point : points)
+ {
+ QetGraphicsHandlerItem *qghi = new QetGraphicsHandlerItem(size);
+ qghi->setPos(point);
+ list_ << qghi;
+ }
+
+ return list_;
+}
Added: trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h (rev 0)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -0,0 +1,53 @@
+/*
+ Copyright 2006-2017 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QETGRAPHICSHANDLERITEM_H
+#define QETGRAPHICSHANDLERITEM_H
+
+#include <QGraphicsItem>
+
+/**
+ * @brief The QetGraphicsHandlerItem class
+ * This graphics item represents a point, destined to be used as an handler,
+ * for modifie the geometrie of a another graphics item (like shapes).
+ * The graphics item to be modified, must call "installSceneEventFilter" of this item with itself for argument,.
+ * The ghraphics item to be modified, need to reimplement "sceneEventFilter" for create the modification behavior.
+ */
+class QetGraphicsHandlerItem : public QGraphicsItem
+{
+ public:
+ QetGraphicsHandlerItem(qreal size = 15);
+ virtual QRectF boundingRect() const;
+
+ enum { Type = UserType + 1200};
+ virtual int type() const {return Type;}
+
+ void setColor(QColor color);
+
+ protected:
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ private:
+ qreal m_size,
+ m_previous_zoom_factor = 1;
+ QColor m_color;
+
+ public:
+ static QVector<QetGraphicsHandlerItem *> handlerForPoint(const QVector<QPointF> &points, int size = 15);
+};
+
+#endif // QETGRAPHICSHANDLERITEM_H
Modified: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -16,113 +16,12 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "qetgraphicshandlerutility.h"
-#include <QPainter>
+//#include <QVector>
+//#include <QPointF>
+#include <QPainterPath>
-/**
- * @brief QetGraphicsHandlerUtility::QetGraphicsHandlerUtility
- * Constructor
- * @param size : the size of the handler
- */
-QetGraphicsHandlerUtility::QetGraphicsHandlerUtility(qreal size) :
- m_size (size)
-{}
/**
- * @brief QetGraphicsHandlerUtility::drawHandler
- * Draw the handler at pos @point, using the QPainter @painter.
- * @param painter : painter to use for drawing the handler
- * @param point : point to draw the handler
- */
-void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QPointF &point)
-{
- //Setup the zoom factor to draw the handler in the same size at screen,
- //no matter the zoom of the QPainter
- m_zoom_factor = 1.0/painter->transform().m11();
-
- painter->save();
- painter->setBrush(QBrush(m_inner_color));
- QPen square_pen(QBrush(m_outer_color), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
- square_pen.setCosmetic(true);
- painter->setPen(square_pen);
- painter->drawRect(getRect(point));
- painter->restore();
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::drawHandler
- * Conveniance method for void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QPointF &point)
- * @param painter
- * @param points
- * @param color2
- */
-void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QVector<QPointF> &points) {
- foreach(QPointF point, points)
- drawHandler(painter, point);
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::pointIsInHandler
- * @param point : point to compare
- * @param key_point : point at the center of handler (the point to modify, for exemple the corner of a rectangle)
- * @return true if point is in a handler. else false
- */
-bool QetGraphicsHandlerUtility::pointIsInHandler(const QPointF &point, const QPointF &key_point) const {
- return (getRect(key_point).contains(point));
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::pointIsHoverHandler
- * @param point : point to compare
- * @param vector : vector of key_point (the point to modify, for exemple the corners of a rectangle)
- * @return if point is hover an handler, return the index of the hovered key_point in the vector, else return -1
- */
-int QetGraphicsHandlerUtility::pointIsHoverHandler(const QPointF &point, const QVector<QPointF> &vector) const
-{
- foreach (QPointF key_point, vector)
- if (pointIsInHandler(point, key_point))
- return vector.indexOf(key_point);
-
- return -1;
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::handlerRect
- * Return the rect of the handler for all key_point in vector (the point to modify, for exemple the corners of a rectangle)
- * The order of rect in the returned vector is the same as the given vector.
- * @param vector
- * @return
- */
-QVector<QRectF> QetGraphicsHandlerUtility::handlerRect(const QVector<QPointF> &vector) const
-{
- QVector <QRectF> rect_vector;
-
- foreach(QPointF point, vector)
- rect_vector << getRect(point);
-
- return rect_vector;
-}
-
-void QetGraphicsHandlerUtility::setInnerColor(QColor color) {
- m_inner_color = color;
-}
-
-void QetGraphicsHandlerUtility::setOuterColor(QColor color) {
- m_outer_color = color;
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::getRect
- * @param point
- * @return
- */
-QRectF QetGraphicsHandlerUtility::getRect(const QPointF &point) const
-{
- qreal rect_size = m_size * m_zoom_factor;
- QRectF rect(point.x() - rect_size/2, point.y() - rect_size/2, rect_size, rect_size);
- return rect;
-}
-
-/**
* @brief QetGraphicsHandlerUtility::pointsForRect
* Return the keys points of the rectangle, stored in a vector.
* The points in the vector are stored like this :
@@ -169,7 +68,6 @@
return (QVector<QPointF> {line.p1(), line.p2()});
}
-#include <QDebug>
/**
* @brief QetGraphicsHandlerUtility::pointsForArc
* Return the points for the given arc.
Modified: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -33,25 +33,6 @@
class QetGraphicsHandlerUtility
{
public:
- QetGraphicsHandlerUtility (qreal size = 1);
- void setSize(qreal size) {m_size = size;}
- void drawHandler (QPainter *painter, const QPointF & point);
- void drawHandler(QPainter *painter, const QVector<QPointF> &points);
- QPointF posForHandler(const QPointF &point) const;
- bool pointIsInHandler (const QPointF &point, const QPointF &key_point) const;
- int pointIsHoverHandler (const QPointF &point, const QVector<QPointF> &vector) const;
- QVector<QRectF> handlerRect (const QVector<QPointF> &vector) const;
- void setInnerColor (QColor color);
- void setOuterColor (QColor color);
-
- private:
- QRectF getRect (const QPointF &point) const;
- qreal m_size;
- qreal m_zoom_factor = 1;
- QColor m_inner_color = Qt::white,
- m_outer_color = Qt::blue;
-
- public:
static QVector <QPointF> pointsForRect (const QRectF &rect);
static QVector <QPointF> pointsForLine (const QLineF &line);
static QVector <QPointF> pointsForArc (const QRectF &rect, qreal start_angle, qreal span_angle);
Modified: trunk/sources/diagram.cpp
===================================================================
--- trunk/sources/diagram.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/diagram.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -91,30 +91,31 @@
* @brief Diagram::~Diagram
* Destructor
*/
-Diagram::~Diagram()
-{
- //First clear every selection to close an hypothetical editor
- clearSelection();
- // clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
+Diagram::~Diagram() {
+ // clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
undoStack().clear();
- //delete of QGIManager, every elements he knows are removed
+ //delete of QGIManager, every elements he knows are removed
delete qgi_manager_;
- // remove of conductor setter
+ // remove of conductor setter
delete conductor_setter_;
- // delete of object for manage movement
+ // delete of object for manage movement
delete elements_mover_;
delete element_texts_mover_;
- if (m_event_interface)
- delete m_event_interface;
+ if (m_event_interface) delete m_event_interface;
- // list removable items
+ // list removable items
QList<QGraphicsItem *> deletable_items;
for(QGraphicsItem *qgi : items())
- {
- if (qgi -> parentItem()) continue;
- if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
+ {
+ if (qgi->parentItem())
+ continue;
+ if (qgi->type() == Conductor::Type)
+ continue;
+ if (qgi->type() == QetGraphicsHandlerItem::Type)
+ continue;
+
deletable_items << qgi;
}
@@ -377,6 +378,8 @@
* Diagram become the ownership of event_interface
* If there is a previous interface, they will be delete before
* and call init() to the new interface.
+ * The derivated class of DiagramEventInterface need to emit the signal "finish" when the job is done,
+ * diagram use this signal to delete the interface. If the signal isn't send, the interface will never be deleted.
* @param event_interface
*/
void Diagram::setEventInterface(DiagramEventInterface *event_interface)
Modified: trunk/sources/editor/elementprimitivedecorator.cpp
===================================================================
--- trunk/sources/editor/elementprimitivedecorator.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementprimitivedecorator.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -24,6 +24,7 @@
#include <QGraphicsSceneHoverEvent>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsScene>
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
/**
Constructor
@@ -30,17 +31,17 @@
@param parent Parent QGraphicsItem
*/
ElementPrimitiveDecorator::ElementPrimitiveDecorator(QGraphicsItem *parent):
- QGraphicsObject(parent),
- m_handler(10)
+ QGraphicsObject(parent)
{
init();
- m_handler.setOuterColor(Qt::darkGreen);
}
/**
Destructor
*/
-ElementPrimitiveDecorator::~ElementPrimitiveDecorator() {
+ElementPrimitiveDecorator::~ElementPrimitiveDecorator()
+{
+ removeHandler();
}
/**
@@ -68,12 +69,7 @@
*/
QRectF ElementPrimitiveDecorator::boundingRect() const
{
- QVector<QRectF> rect_vector = m_handler.handlerRect(getResizingsPoints());
-
- QRectF rect = effective_bounding_rect_;
- rect |= rect_vector.first();
- rect |= rect_vector.last();
- return(rect);
+ return effective_bounding_rect_;
}
/**
@@ -96,9 +92,6 @@
pen.setCosmetic(true);
painter -> setPen(pen);
painter -> drawRect(modified_bounding_rect_);
-
- //Draw the handlers
- m_handler.drawHandler(painter, getResizingsPoints());
// uncomment to draw the real bouding rect (=adjusted internal bounding rect)
// painter -> setBrush(QBrush(QColor(240, 0, 0, 127)));
@@ -118,15 +111,19 @@
if (focusItem() != this) {
setFocus();
}
+ adjusteHandlerPos();
}
/**
@param items the new list of items this decorator is suposed to manipulate.
*/
-void ElementPrimitiveDecorator::setItems(const QList<QGraphicsItem *> &items) {
+void ElementPrimitiveDecorator::setItems(const QList<QGraphicsItem *> &items)
+{
QList<CustomElementPart *> primitives;
- foreach (QGraphicsItem *item, items) {
- if (CustomElementPart *part_item = dynamic_cast<CustomElementPart *>(item)) {
+ for(QGraphicsItem *item : items)
+ {
+ if (CustomElementPart *part_item = dynamic_cast<CustomElementPart *>(item))
+ {
primitives << part_item;
}
}
@@ -157,7 +154,8 @@
Adjust the visual decorator according to the currently assigned items.
It is notably called by setItems().
*/
-void ElementPrimitiveDecorator::adjust() {
+void ElementPrimitiveDecorator::adjust()
+{
saveOriginalBoundingRect();
modified_bounding_rect_ = original_bounding_rect_;
adjustEffectiveBoundingRect();
@@ -164,65 +162,23 @@
}
/**
- Handle events generated when the mouse hovers over the decorator.
- @param event Object describing the hover event.
-*/
-void ElementPrimitiveDecorator::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- int p = m_handler.pointIsHoverHandler(event->pos(), getResizingsPoints());
-
- if (p == 0 || p == 7)
- setCursor(Qt::SizeFDiagCursor);
- else if (p == 2 || p == 5)
- setCursor(Qt::SizeBDiagCursor);
- else if (p == 1 || p ==6)
- setCursor(Qt::SizeVerCursor);
- else if (p == 3 || p == 4)
- setCursor(Qt::SizeHorCursor);
- else if (p == -1 && modified_bounding_rect_.normalized().contains(event->pos()))
- setCursor(Qt::SizeAllCursor);
- else
- setCursor(Qt::ArrowCursor);
-}
-
-/**
Handle event generated when mouse buttons are pressed.
@param event Object describing the mouse event
*/
void ElementPrimitiveDecorator::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- QPointF pos = event -> pos();
- QVector <QPointF> points = getResizingsPoints();
-
- current_operation_square_ = m_handler.pointIsHoverHandler(pos, points);
- bool accept = false;
-
- if (current_operation_square_ != QET::NoOperation)
- accept = true;
- else
+{
+ if (internalBoundingRect().contains(event->pos()))
{
- if (internalBoundingRect().contains(pos))
- {
- current_operation_square_ = QET::MoveArea;
- accept = true;
- }
- }
-
- if (accept)
- {
- if (current_operation_square_ > QET::NoOperation)
- first_pos_ = latest_pos_ = mapToScene(points.at(current_operation_square_));
- else
- {
- first_pos_ = decorated_items_.at(0) -> toItem() -> scenePos();
- latest_pos_ = event -> scenePos();
- mouse_offset_ = event -> scenePos() - first_pos_;
- }
+ current_operation_square_ = QET::MoveArea;
+
+ first_pos_ = decorated_items_.at(0) -> toItem() -> scenePos();
+ latest_pos_ = event -> scenePos();
+ mouse_offset_ = event -> scenePos() - first_pos_;
startMovement();
- event -> accept();
+ event->accept();
}
else
- event -> ignore();
+ event->ignore();
}
/**
@@ -235,59 +191,25 @@
QPointF scene_pos = event -> scenePos();
QPointF movement = scene_pos - latest_pos_;
- if (current_operation_square_ > QET::NoOperation) {
- // This is a scaling operation.
-
- // For convenience purposes, we may need to adjust mouse movements.
- QET::ScalingMethod scaling_method = scalingMethod(event);
- if (scaling_method > QET::FreeScaling) {
- // real, non-rounded movement from the mouse press event
- QPointF global_movement = scene_pos - first_pos_;
-
- QPointF rounded_global_movement;
- if (scaling_method == QET::SnapScalingPointToGrid) {
- // real, rounded movement from the mouse press event
- rounded_global_movement = snapConstPointToGrid(global_movement);
- }
- else {
- QRectF new_bounding_rect = original_bounding_rect_;
- applyMovementToRect(current_operation_square_, global_movement, new_bounding_rect);
-
- const qreal scale_epsilon = 20.0; // rounds to 0.05
- QPointF delta = deltaForRoundScaling(original_bounding_rect_, new_bounding_rect, scale_epsilon);
-
- // real, rounded movement from the mouse press event
- rounded_global_movement = global_movement + delta;
- }
-
- // rounded position of the current mouse move event
- QPointF rounded_scene_pos = first_pos_ + rounded_global_movement;
-
- // when scaling the selection, consider the center of the currently dragged resizing rectangle
- QPointF current_position = mapToScene(getResizingsPoints().at(current_operation_square_));
- // determine the final, effective movement
- movement = rounded_scene_pos - current_position;
- }
- }
- else if (current_operation_square_ == QET::MoveArea) {
+ if (current_operation_square_ == QET::MoveArea)
+ {
// When moving the selection, consider the position of the first selected item
QPointF current_position = scene_pos - mouse_offset_;
QPointF rounded_current_position = snapConstPointToGrid(current_position);
movement = rounded_current_position - decorated_items_.at(0) -> toItem() -> scenePos();
+
+ QRectF bounding_rect = modified_bounding_rect_;
+ applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
+ if (modified_bounding_rect_ != bounding_rect) {
+ adjustEffectiveBoundingRect();
+ }
+ latest_pos_ = event -> scenePos();
+ translateItems(movement);
}
- QRectF bounding_rect = modified_bounding_rect_;
- applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
- if (modified_bounding_rect_ != bounding_rect) {
- adjustEffectiveBoundingRect();
- }
- latest_pos_ = event -> scenePos();
+
- if (current_operation_square_ == QET::MoveArea) {
- translateItems(movement);
- } else {
- scaleItems(original_bounding_rect_, modified_bounding_rect_);
- }
+
}
/**
@@ -296,31 +218,25 @@
@param event Object describing the mouse event
@see QGraphicsScene::mouseGrabberItem()
*/
-void ElementPrimitiveDecorator::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
+void ElementPrimitiveDecorator::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
Q_UNUSED(event)
ElementEditionCommand *command = 0;
- if (current_operation_square_ > QET::NoOperation) {
- ScalePartsCommand *scale_command = new ScalePartsCommand();
- scale_command -> setScaledPrimitives(items());
- scale_command -> setTransformation(
- mapToScene(original_bounding_rect_).boundingRect(),
- mapToScene(modified_bounding_rect_).boundingRect()
- );
- command = scale_command;
- } else if (current_operation_square_ == QET::MoveArea) {
+
+ if (current_operation_square_ == QET::MoveArea)
+ {
QPointF movement = mapToScene(modified_bounding_rect_.topLeft()) - mapToScene(original_bounding_rect_.topLeft());
- if (!movement.isNull()) {
+ if (!movement.isNull())
+ {
MovePartsCommand *move_command = new MovePartsCommand(movement, 0, graphicsItems());
command = move_command;
}
- }
-
- if (command) {
- emit(actionFinished(command));
- }
-
- if (current_operation_square_ != QET::NoOperation) {
+
+ if (command) {
+ emit(actionFinished(command));
+ }
+
adjust();
}
@@ -376,7 +292,8 @@
/**
Initialize an ElementPrimitiveDecorator
*/
-void ElementPrimitiveDecorator::init() {
+void ElementPrimitiveDecorator::init()
+{
setFlag(QGraphicsItem::ItemIsFocusable, true);
grid_step_x_ = grid_step_y_ = 1;
setAcceptHoverEvents(true);
@@ -397,6 +314,7 @@
prepareGeometryChange();
effective_bounding_rect_ = modified_bounding_rect_ | effective_bounding_rect_;
update();
+ adjusteHandlerPos();
}
/**
@@ -529,6 +447,152 @@
}
/**
+ * @brief ElementPrimitiveDecorator::adjusteHandlerPos
+ */
+void ElementPrimitiveDecorator::adjusteHandlerPos()
+{
+ QVector <QPointF> points_vector = mapToScene(getResizingsPoints());
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void ElementPrimitiveDecorator::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+
+ QVector <QPointF> points = getResizingsPoints();
+
+ current_operation_square_ = m_handler_vector.indexOf(qghi);
+
+ first_pos_ = latest_pos_ = mapToScene(points.at(current_operation_square_));
+ startMovement();
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void ElementPrimitiveDecorator::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+
+ QPointF scene_pos = event -> scenePos();
+ QPointF movement = scene_pos - latest_pos_;
+
+ // For convenience purposes, we may need to adjust mouse movements.
+ QET::ScalingMethod scaling_method = scalingMethod(event);
+ if (scaling_method > QET::FreeScaling)
+ {
+ // real, non-rounded movement from the mouse press event
+ QPointF global_movement = scene_pos - first_pos_;
+
+ QPointF rounded_global_movement;
+ if (scaling_method == QET::SnapScalingPointToGrid)
+ {
+ // real, rounded movement from the mouse press event
+ rounded_global_movement = snapConstPointToGrid(global_movement);
+ }
+ else
+ {
+ QRectF new_bounding_rect = original_bounding_rect_;
+ applyMovementToRect(current_operation_square_, global_movement, new_bounding_rect);
+
+ const qreal scale_epsilon = 20.0; // rounds to 0.05
+ QPointF delta = deltaForRoundScaling(original_bounding_rect_, new_bounding_rect, scale_epsilon);
+
+ // real, rounded movement from the mouse press event
+ rounded_global_movement = global_movement + delta;
+ }
+
+ // rounded position of the current mouse move event
+ QPointF rounded_scene_pos = first_pos_ + rounded_global_movement;
+
+ // when scaling the selection, consider the center of the currently dragged resizing rectangle
+ QPointF current_position = mapToScene(getResizingsPoints().at(current_operation_square_));
+ // determine the final, effective movement
+ movement = rounded_scene_pos - current_position;
+ }
+
+ QRectF bounding_rect = modified_bounding_rect_;
+ applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
+ if (modified_bounding_rect_ != bounding_rect) {
+ adjustEffectiveBoundingRect();
+ }
+ latest_pos_ = event -> scenePos();
+ scaleItems(original_bounding_rect_, modified_bounding_rect_);
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void ElementPrimitiveDecorator::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ ElementEditionCommand *command = 0;
+ if (current_operation_square_ > QET::NoOperation)
+ {
+ ScalePartsCommand *scale_command = new ScalePartsCommand();
+ scale_command -> setScaledPrimitives(items());
+ scale_command -> setTransformation(
+ mapToScene(original_bounding_rect_).boundingRect(),
+ mapToScene(modified_bounding_rect_).boundingRect()
+ );
+ command = scale_command;
+ }
+
+ if (command) {
+ emit(actionFinished(command));
+ }
+
+ adjust();
+
+ current_operation_square_ = QET::NoOperation;
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::addHandler
+ * Add handlers for this item
+ */
+void ElementPrimitiveDecorator::addHandler()
+{
+ if (m_handler_vector.isEmpty() && scene())
+ {
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapFromScene(getResizingsPoints()));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ scene()->addItem(handler);
+ handler->setColor(Qt::darkGreen);
+ handler->installSceneEventFilter(this);
+ handler->setZValue(this->zValue()+1);
+ }
+ }
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::removeHandler
+ * Remove the handlers of this item
+ */
+void ElementPrimitiveDecorator::removeHandler()
+{
+ if (!m_handler_vector.isEmpty())
+ {
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
+ }
+}
+
+/**
Receive two rects, assuming they share a common corner and current is a \a
scaled version of \a original.
Calculate the scale ratios implied by this assumption, round them to the
@@ -597,3 +661,73 @@
}
return QET::RoundScaleRatios;
}
+
+/**
+ * @brief ElementPrimitiveDecorator::itemChange
+ * @param change
+ * @param value
+ * @return
+ */
+QVariant ElementPrimitiveDecorator::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemSceneHasChanged)
+ {
+ if(scene()) //Item is added to scene, we also add handlers
+ addHandler();
+ else //Item is removed from scene, we also remove the handlers
+ removeHandler();
+ }
+ else if (change == ItemVisibleHasChanged)
+ {
+ bool visible = value.toBool();
+ for(QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setVisible(visible);
+ }
+ else if (change == ItemZValueHasChanged && !m_handler_vector.isEmpty())
+ {
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setZValue(this->zValue()+1);
+ }
+
+ return QGraphicsObject::itemChange(change, value);
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::sceneEventFilter
+ * @param watched
+ * @param event
+ * @return
+ */
+bool ElementPrimitiveDecorator::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+{
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
+ {
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
+ {
+ m_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
+ {
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+ {
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
Modified: trunk/sources/editor/elementprimitivedecorator.h
===================================================================
--- trunk/sources/editor/elementprimitivedecorator.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementprimitivedecorator.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,11 +20,11 @@
#include <QGraphicsObject>
#include "qet.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
class ElementEditionCommand;
class ElementScene;
class CustomElementPart;
+class QetGraphicsHandlerItem;
/**
This class represents a decorator rendered above selected items so users
@@ -42,72 +42,85 @@
Q_OBJECT
public:
- ElementPrimitiveDecorator(QGraphicsItem * = 0);
- virtual ~ElementPrimitiveDecorator();
+ ElementPrimitiveDecorator(QGraphicsItem * = 0);
+ virtual ~ElementPrimitiveDecorator();
+
+ enum { Type = UserType + 2200 };
+
+ // methods
+ QRectF internalBoundingRect() const;
+ virtual QRectF boundingRect () const;
+ virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
+ virtual int type() const { return Type; }
+ void setItems(const QList<QGraphicsItem *> &);
+ void setItems(const QList<CustomElementPart *> &);
+ QList<CustomElementPart *> items() const;
+ QList<QGraphicsItem *> graphicsItems() const;
- enum { Type = UserType + 2200 };
-
- // methods
- QRectF internalBoundingRect() const;
- virtual QRectF boundingRect () const;
- virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
- virtual int type() const { return Type; }
- void setItems(const QList<QGraphicsItem *> &);
- void setItems(const QList<CustomElementPart *> &);
- QList<CustomElementPart *> items() const;
- QList<QGraphicsItem *> graphicsItems() const;
-
public slots:
- void adjust();
+ void adjust();
signals:
- void actionFinished(ElementEditionCommand *);
+ void actionFinished(ElementEditionCommand *);
protected:
- void hoverMoveEvent(QGraphicsSceneHoverEvent *);
- void mousePressEvent(QGraphicsSceneMouseEvent *);
- void mouseMoveEvent(QGraphicsSceneMouseEvent *);
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
- void keyPressEvent(QKeyEvent *);
- void keyReleaseEvent(QKeyEvent *);
- QPointF deltaForRoundScaling(const QRectF &, const QRectF &, qreal);
- QPointF snapConstPointToGrid(const QPointF &) const;
- void snapPointToGrid(QPointF &) const;
- bool mustSnapToGrid(QGraphicsSceneMouseEvent *);
- QET::ScalingMethod scalingMethod(QGraphicsSceneMouseEvent *);
+ void mousePressEvent(QGraphicsSceneMouseEvent *);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void keyReleaseEvent(QKeyEvent *);
+ QPointF deltaForRoundScaling(const QRectF &, const QRectF &, qreal);
+ QPointF snapConstPointToGrid(const QPointF &) const;
+ void snapPointToGrid(QPointF &) const;
+ bool mustSnapToGrid(QGraphicsSceneMouseEvent *);
+ QET::ScalingMethod scalingMethod(QGraphicsSceneMouseEvent *);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
private:
- void init();
- void saveOriginalBoundingRect();
- void adjustEffectiveBoundingRect();
- void startMovement();
- void applyMovementToRect(int, const QPointF &, QRectF &);
- CustomElementPart *singleItem() const;
- void translateItems(const QPointF &);
- void scaleItems(const QRectF &, const QRectF &);
- QRectF getSceneBoundingRect(QGraphicsItem *) const;
- QVector <QPointF> getResizingsPoints() const;
+ void init();
+ void saveOriginalBoundingRect();
+ void adjustEffectiveBoundingRect();
+ void startMovement();
+ void applyMovementToRect(int, const QPointF &, QRectF &);
+ CustomElementPart *singleItem() const;
+ void translateItems(const QPointF &);
+ void scaleItems(const QRectF &, const QRectF &);
+ QRectF getSceneBoundingRect(QGraphicsItem *) const;
+ QVector <QPointF> getResizingsPoints() const;
- // attributes
+
private:
- QList<CustomElementPart *> decorated_items_;
- QRectF effective_bounding_rect_; ///< actual, effective bounding rect -- never shrinks
- QRectF original_bounding_rect_; ///< original bounding rect
- QRectF modified_bounding_rect_; ///< new bounding rect, after the user moved or resized items
+ void adjusteHandlerPos();
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+
+ void addHandler();
+ void removeHandler();
+
+
+
+
+ QList<CustomElementPart *> decorated_items_;
+ QRectF effective_bounding_rect_; ///< actual, effective bounding rect -- never shrinks
+ QRectF original_bounding_rect_; ///< original bounding rect
+ QRectF modified_bounding_rect_; ///< new bounding rect, after the user moved or resized items
- /**
- Index of the square leading the current operation (resizing, etc.) or -1 if no
- operation is occurring, -2 for a move operation.
- */
- int current_operation_square_;
- int grid_step_x_; ///< Grid horizontal step
- int grid_step_y_; ///< Grid horizontal step
- QPointF first_pos_; ///< First point involved within the current resizing operation
- QPointF latest_pos_; ///< Latest point involved within the current resizing operation
- QPointF mouse_offset_; ///< Offset between the mouse position and the point to be snapped to grid when moving selection
- bool moving_by_keys_; ///< Whether we are currently moving our decorated items using the arrow keys
- QPointF keys_movement_; ///< Movement applied to our decorated items using the arrow keys
- QetGraphicsHandlerUtility m_handler;
+ /**
+ Index of the square leading the current operation (resizing, etc.) or -1 if no
+ operation is occurring, -2 for a move operation.
+ */
+ int current_operation_square_;
+ int grid_step_x_; ///< Grid horizontal step
+ int grid_step_y_; ///< Grid horizontal step
+ QPointF first_pos_; ///< First point involved within the current resizing operation
+ QPointF latest_pos_; ///< Latest point involved within the current resizing operation
+ QPointF mouse_offset_; ///< Offset between the mouse position and the point to be snapped to grid when moving selection
+ bool moving_by_keys_; ///< Whether we are currently moving our decorated items using the arrow keys
+ QPointF keys_movement_; ///< Movement applied to our decorated items using the arrow keys
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
+ int m_vector_index = -1;
};
#endif
Modified: trunk/sources/editor/elementscene.cpp
===================================================================
--- trunk/sources/editor/elementscene.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementscene.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -32,8 +32,9 @@
#include "nameslist.h"
#include "ui/elementpropertieseditorwidget.h"
#include "eseventinterface.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+
#include <algorithm>
-
#include <QKeyEvent>
/**
@@ -524,27 +525,45 @@
}
/**
- Selectionne une liste de parties
- @param content liste des parties a selectionner
-*/
-void ElementScene::slot_select(const ElementContent &content) {
+ * @brief ElementScene::slot_select
+ * Select the item in content, every others items in the scene are deselected
+ * @param content
+ */
+void ElementScene::slot_select(const ElementContent &content)
+{
blockSignals(true);
+
+ //Befor clear selection, we must to remove the handlers items in @content,
+ //because if in @content there are a selected item, but also its handlers items,
+ //When item is deselected, the item delete its handlers items,
+ //then handlers in content doesn't exist anymore and cause segfault
+ QList<QGraphicsItem*> items_list;
+ for (QGraphicsItem *qgi : content)
+ {
+ if(qgi->type() != QetGraphicsHandlerItem::Type)
+ items_list << qgi;
+ }
clearSelection();
- foreach(QGraphicsItem *qgi, content) qgi -> setSelected(true);
+
+ foreach(QGraphicsItem *qgi, items_list)
+ qgi -> setSelected(true);
+
blockSignals(false);
emit(selectionChanged());
}
/**
- Selectionne tout
-*/
+ * @brief ElementScene::slot_selectAll
+ * Select all items
+ */
void ElementScene::slot_selectAll() {
slot_select(items());
}
/**
- Deselectionne tout
-*/
+ * @brief ElementScene::slot_deselectAll
+ * deselect all item
+ */
void ElementScene::slot_deselectAll() {
slot_select(ElementContent());
}
@@ -811,8 +830,16 @@
clearSelection();
undoStack().clear();
- foreach (QGraphicsItem *qgi, items())
+ //We don't add handlers, because it's the role of the primitive or decorator to remove it.
+ QList<QGraphicsItem*> items_list;
+ for (QGraphicsItem *qgi : items())
{
+ if(qgi->type() != QetGraphicsHandlerItem::Type)
+ items_list << qgi;
+ }
+
+ for (QGraphicsItem *qgi : items_list)
+ {
removeItem(qgi);
qgiManager().release(qgi);
}
@@ -1065,9 +1092,16 @@
// should we hide the decorator?
QList<QGraphicsItem *> selected_items = zItems(ElementScene::Selected | ElementScene::IncludeTerminals);
if (selected_items.size() <= 1)
+ {
m_decorator -> hide();
+ }
else
{
+ for(QGraphicsItem *qgi : selected_items)
+ {
+ //We recall set selected, then every primitive will remove there handler because there are several item selected
+ qgi->setSelected(true);
+ }
m_decorator -> setZValue(1000000);
m_decorator -> setPos(0, 0);
m_decorator -> setItems(selected_items);
Modified: trunk/sources/editor/elementscene.h
===================================================================
--- trunk/sources/editor/elementscene.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementscene.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -44,13 +44,13 @@
public:
enum Behavior { Normal, PasteArea, AddPart };
enum ItemOption {
- SortByZValue = 1,
- IncludeTerminals = 2,
- IncludeHelperItems = 4,
- Selected = 8,
- NonSelected = 16,
- SelectedOrNot = 24
- };
+ SortByZValue = 1,
+ IncludeTerminals = 2,
+ IncludeHelperItems = 4,
+ Selected = 8,
+ NonSelected = 16,
+ SelectedOrNot = 24
+ };
Q_DECLARE_FLAGS(ItemOptions, ItemOption)
// constructors, destructor
@@ -82,7 +82,7 @@
QETElementEditor *m_element_editor = nullptr;
/// Variables to manage the paste area on the scene
- QGraphicsRectItem *m_paste_area = nullptr;
+ QGraphicsRectItem *m_paste_area;
QRectF m_defined_paste_area;
/// Variables to handle copy/paste with offset
Modified: trunk/sources/editor/graphicspart/abstractpartellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -118,6 +118,7 @@
if (rect == m_rect) return;
prepareGeometryChange();
m_rect = rect;
+
emit rectChanged();
}
Modified: trunk/sources/editor/graphicspart/abstractpartellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,6 +20,8 @@
#include "customelementgraphicpart.h"
+class QetGraphicsHandlerItem;
+
/**
* @brief The AbstractPartEllipse class
* This is the base class for all ellipse based item like ellipse, circle, arc.
@@ -61,14 +63,14 @@
virtual QPointF sceneTopLeft() const;
QRectF rect() const;
- void setRect (const QRectF &rect);
+ virtual void setRect (const QRectF &rect);
virtual bool isUseless() const;
int startAngle() const {return m_start_angle;}
- void setStartAngle (const int &start_angle);
+ virtual void setStartAngle (const int &start_angle);
int spanAngle () const {return m_span_angle;}
- void setSpanAngle (const int &span_angle);
+ virtual void setSpanAngle (const int &span_angle);
protected:
QList<QPointF> saved_points_;
@@ -75,6 +77,7 @@
QRectF m_rect;
qreal m_start_angle;
qreal m_span_angle;
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
};
#endif // ABSTRACTPARTELLIPSE_H
Modified: trunk/sources/editor/graphicspart/partarc.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partarc.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partarc.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,8 @@
#include "partarc.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementscene.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
/**
@@ -37,8 +39,10 @@
* @brief PartArc::~PartArc
* Destructor
*/
-PartArc::~PartArc() {
+PartArc::~PartArc()
+{
if(m_undo_command) delete m_undo_command;
+ removeHandler();
}
/**
@@ -82,15 +86,7 @@
drawShadowShape(painter);
if (isSelected())
- {
drawCross(m_rect.center(), painter);
- if (scene()->selectedItems().size() == 1) {
- if (m_resize_mode == 3)
- m_handler.drawHandler(painter, m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16));
- else
- m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect));
- }
- }
}
/**
@@ -129,16 +125,6 @@
m_span_angle = qde.attribute("angle", "-1440").toDouble() * 16;
}
-QRectF PartArc::boundingRect() const
-{
- QRectF r = AbstractPartEllipse::boundingRect();
-
- foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
- r |= rect;
-
- return r;
-}
-
/**
* @brief PartArc::shape
* @return the shape of this item
@@ -153,10 +139,6 @@
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;
}
@@ -172,195 +154,324 @@
return (pps.createStroke(shape));
}
-void PartArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartArc::mouseReleaseEvent
+ * Handle mouse release event
+ * @param event
+ */
+void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
- if (!isSelected())
- {
- CustomElementGraphicPart::hoverMoveEvent(event);
- return;
- }
+ if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
+ switchResizeMode();
- if (m_resize_mode == 1 || m_resize_mode == 2) {
- int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
+ CustomElementGraphicPart::mouseReleaseEvent(event);
+}
- if (handler >= 0)
+/**
+ * @brief PartArc::itemChange
+ * @param change
+ * @param value
+ * @return
+ */
+QVariant PartArc::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemSelectedHasChanged && scene())
+ {
+ if (value.toBool() == true)
{
- 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);
-
- return;
+ //When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+ //according to the number of selected items.
+ connect(scene(), &QGraphicsScene::selectionChanged, this, &PartArc::sceneSelectionChanged);
+
+ if (scene()->selectedItems().size() == 1)
+ addHandler();
}
- }
- else if (m_resize_mode == 3) {
- if (m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16)) >= 0) {
- setCursor(Qt::SizeAllCursor);
- return;
+ else
+ {
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartArc::sceneSelectionChanged);
+ removeHandler();
}
}
-
- CustomElementGraphicPart::hoverMoveEvent(event);
+ else if (change == ItemPositionHasChanged)
+ {
+ adjusteHandlerPos();
+ }
+ else if (change == ItemSceneChange)
+ {
+ if(scene())
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartArc::sceneSelectionChanged);
+
+ setSelected(false); //This is item removed from scene, then we deselect this, and so, the handlers is also removed.
+ }
+
+ return QGraphicsItem::itemChange(change, value);
}
/**
- * @brief PartArc::mousePressEvent
- * Handle mouse press event
+ * @brief PartArc::sceneEventFilter
+ * @param watched
* @param event
+ * @return
*/
-void PartArc::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartArc::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
- if (event->button() == Qt::LeftButton)
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
{
- setCursor(Qt::ClosedHandCursor);
- if (isSelected())
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
{
- //resize rect
- if (m_resize_mode == 1 || m_resize_mode == 2) {
- 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_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
+ {
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
{
- m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
- m_undo_command->setText(tr("Modifier un arc"));
- m_undo_command->enableAnimation();
- return;
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
}
- }
- //resize angle
- if (m_resize_mode == 3) {
- m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16));
- if (m_handler_index == 0) {
- m_span_point = m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16).at(1);
-
- m_undo_command = new QPropertyUndoCommand(this, "startAngle", QVariant(m_start_angle));
- m_undo_command->setText(tr("Modifier un arc"));
- m_undo_command->enableAnimation();
-
- m_undo_command2 = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle), m_undo_command);
- m_undo_command2->setText(tr("Modifier un arc"));
- m_undo_command2->enableAnimation();
-
- return;
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
}
- else if (m_handler_index == 1) {
- m_undo_command = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle));
- m_undo_command->setText(tr("Modifier un arc"));
- m_undo_command->enableAnimation();
-
- return;
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
}
}
-
}
}
+
+ return false;
+}
- CustomElementGraphicPart::mousePressEvent(event);
+/**
+ * @brief PartArc::switchResizeMode
+ */
+void PartArc::switchResizeMode()
+{
+ if (m_resize_mode == 1)
+ {
+ m_resize_mode = 2;
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::darkGreen);
+ }
+ else if (m_resize_mode == 2)
+ {
+ m_resize_mode = 3;
+
+ //From rect mode to angle mode, then numbers of handlers change
+ removeHandler();
+ addHandler();
+
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::magenta);
+ }
+ else
+ {
+ m_resize_mode = 1;
+
+ //From angle mode to rect mode, then numbers of handlers change
+ removeHandler();
+ addHandler();
+
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::blue);
+ }
}
/**
- * @brief PartArc::mouseMoveEvent
- * Handle mouse move event
+ * @brief PartArc::adjusteHandlerPos
+ */
+void PartArc::adjusteHandlerPos()
+{
+ if (m_handler_vector.isEmpty())
+ return;
+
+ QVector <QPointF> points_vector;
+
+ if(m_resize_mode == 3)
+ points_vector = QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle/16, m_span_angle/16);
+ else
+ points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect);
+
+
+ if (m_handler_vector.size() == points_vector.size())
+ {
+ points_vector = mapToScene(points_vector);
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
+ }
+}
+
+/**
+ * @brief PartArc::handlerMousePressEvent
+ * @param qghi
* @param event
*/
-void PartArc::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartArc::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if (m_resize_mode == 1 || m_resize_mode == 2) {
- if (m_handler_index >= 0 && m_handler_index <= 7) {
- QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
- prepareGeometryChange();
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ if (m_resize_mode == 3) //Resize angle
+ {
+ if (m_vector_index == 0)
+ {
+ m_span_point = QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle /16, m_span_angle /16).at(1);
- 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));
+ m_undo_command = new QPropertyUndoCommand(this, "startAngle", QVariant(m_start_angle));
+ m_undo_command->setText(tr("Modifier un arc"));
+ m_undo_command->enableAnimation();
- return;
+ m_undo_command2 = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle), m_undo_command);
+ m_undo_command2->setText(tr("Modifier un arc"));
+ m_undo_command2->enableAnimation();
}
+ else if (m_vector_index == 1)
+ {
+ m_undo_command = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle));
+ m_undo_command->setText(tr("Modifier un arc"));
+ m_undo_command->enableAnimation();
+ }
}
- else if (m_resize_mode == 3) {
- if (m_handler_index == 0 || m_handler_index == 1) {
- QLineF line(m_rect.center(), event->pos());
- prepareGeometryChange();
+ else //resize rect
+ {
+ m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
+ m_undo_command->setText(tr("Modifier un arc"));
+ m_undo_command->enableAnimation();
+ }
+}
- if (m_handler_index == 0) {
- setStartAngle(line.angle()*16);
- setSpanAngle(line.angleTo(QLineF(m_rect.center(), m_span_point))*16);
- }
- else if (m_handler_index == 1) {
- QLineF line2(m_rect.center(), m_handler.pointsForArc(m_rect, m_start_angle/16, m_span_angle/16).at(0));
- setSpanAngle (line2.angleTo(line)*16);
- }
+/**
+ * @brief PartArc::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartArc::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+
+ QPointF new_pos = event->scenePos();
+ if (event->modifiers() != Qt::ControlModifier)
+ new_pos = elementScene()->snapToGrid(event->scenePos());
+ new_pos = mapFromScene(new_pos);
+
+ if (m_resize_mode == 1)
+ setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(m_rect, new_pos, m_vector_index));
+ else if (m_resize_mode == 2)
+ setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
+ else
+ {
+ QLineF line(m_rect.center(), mapFromItem(qghi, event->pos()));
+ prepareGeometryChange();
- return;
+ if (m_vector_index == 0) {
+ setStartAngle(line.angle()*16);
+ setSpanAngle(line.angleTo(QLineF(m_rect.center(), m_span_point))*16);
}
+ else if (m_vector_index == 1) {
+ QLineF line2(m_rect.center(), QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle/16, m_span_angle/16).at(0));
+ setSpanAngle (line2.angleTo(line)*16);
+ }
}
-
- CustomElementGraphicPart::mouseMoveEvent(event);
}
/**
- * @brief PartArc::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartArc::handlerMouseReleaseEvent
+ * @param qghi
* @param event
*/
-void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartArc::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if (event->button() == Qt::LeftButton) {
- setCursor(Qt::OpenHandCursor);
- if (event->buttonDownPos(Qt::LeftButton) == event->pos())
- switchResizeMode();
- }
-
- if (m_resize_mode == 1 || m_resize_mode == 2) {
- 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;
- return;
- }
- }
- else if (m_resize_mode == 3) {
- if (m_handler_index == 0) {
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ if (m_resize_mode == 3)
+ {
+ if (m_vector_index == 0)
+ {
m_undo_command->setNewValue(QVariant(m_start_angle));
m_undo_command2->setNewValue(QVariant(m_span_angle));
elementScene()->undoStack().push(m_undo_command);
m_undo_command = nullptr;
m_undo_command2 = nullptr;
- m_handler_index = -1;
- return;
+ m_vector_index = -1;
}
- else if (m_handler_index == 1) {
+ else if (m_vector_index == 1)
+ {
m_undo_command->setNewValue(QVariant(m_span_angle));
elementScene()->undoStack().push(m_undo_command);
m_undo_command = nullptr;
- m_handler_index = -1;
- return;
+ m_vector_index = -1;
}
}
+ else
+ {
+ if (!m_rect.isValid())
+ m_rect = m_rect.normalized();
- CustomElementGraphicPart::mouseReleaseEvent(event);
+ m_undo_command->setNewValue(QVariant(m_rect));
+ elementScene()->undoStack().push(m_undo_command);
+ m_undo_command = nullptr;
+ m_vector_index = -1;
+ }
}
-void PartArc::switchResizeMode()
+/**
+ * @brief PartArc::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartArc::sceneSelectionChanged()
{
- if (m_resize_mode == 1) {
- m_resize_mode = 2;
- m_handler.setOuterColor(Qt::darkGreen);
+ if (this->isSelected() && scene()->selectedItems().size() == 1)
+ addHandler();
+ else
+ removeHandler();
+}
+
+/**
+ * @brief PartArc::addHandler
+ * Add handlers for this item
+ */
+void PartArc::addHandler()
+{
+ if (m_handler_vector.isEmpty() && scene())
+ {
+ if(m_resize_mode == 3)
+ {
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle/16, m_span_angle/16)));
+ }
+ else
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect)));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ QColor color = Qt::blue;
+ if (m_resize_mode == 2)
+ color = Qt::darkGreen;
+ else if (m_resize_mode == 3)
+ color = Qt::magenta;
+
+ handler->setColor(color);
+ scene()->addItem(handler);
+ handler->installSceneEventFilter(this);
+ handler->setZValue(this->zValue()+1);
+ }
}
- else if (m_resize_mode == 2 ) {
- m_resize_mode = 3;
- m_handler.setOuterColor(Qt::magenta);
+}
+
+/**
+ * @brief PartArc::removeHandler
+ * Remove the handlers of this item
+ */
+void PartArc::removeHandler()
+{
+ if (!m_handler_vector.isEmpty())
+ {
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
}
- else {
- m_resize_mode = 1;
- m_handler.setOuterColor(Qt::blue);
- }
- update();
}
Modified: trunk/sources/editor/graphicspart/partarc.h
===================================================================
--- trunk/sources/editor/graphicspart/partarc.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partarc.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,9 +19,9 @@
#define PART_ARC_H
#include "abstractpartellipse.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
/**
* @brief The PartArc class
@@ -54,25 +54,34 @@
virtual const QDomElement toXml (QDomDocument &) const;
virtual void fromXml (const QDomElement &);
- virtual QRectF boundingRect() const;
virtual QPainterPath shape() const;
virtual QPainterPath shadowShape() const;
+ virtual void setRect(const QRectF &rect) {AbstractPartEllipse::setRect(rect); adjusteHandlerPos();}
+ virtual void setStartAngle(const int &start_angle) {AbstractPartEllipse::setStartAngle(start_angle); adjusteHandlerPos();}
+ virtual void setSpanAngle(const int &span_angle) {AbstractPartEllipse::setSpanAngle(span_angle); adjusteHandlerPos();}
protected:
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
private:
void switchResizeMode();
+ void adjusteHandlerPos();
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void sceneSelectionChanged ();
+
+ void addHandler();
+ void removeHandler();
private:
- QetGraphicsHandlerUtility m_handler = 10;
- int m_handler_index = -1;
QPropertyUndoCommand *m_undo_command = nullptr;
QPropertyUndoCommand *m_undo_command2 = nullptr;
- int m_resize_mode = 1;
+ int m_resize_mode = 1,
+ m_vector_index = -1;
QPointF m_span_point;
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
};
#endif
Modified: trunk/sources/editor/graphicspart/partellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partellipse.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,8 @@
#include "partellipse.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementscene.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
/**
* @brief PartEllipse::PartEllipse
@@ -27,8 +29,6 @@
*/
PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
AbstractPartEllipse(editor, parent),
- m_handler(10),
- m_handler_index(-1),
m_undo_command(nullptr)
{}
@@ -36,8 +36,10 @@
* @brief PartEllipse::~PartEllipse
* Destructor
*/
-PartEllipse::~PartEllipse() {
+PartEllipse::~PartEllipse()
+{
if(m_undo_command) delete m_undo_command;
+ removeHandler();
}
/**
@@ -65,11 +67,7 @@
drawShadowShape(painter);
if (isSelected())
- {
drawCross(m_rect.center(), painter);
- if (scene()->selectedItems().size() == 1)
- m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect));
- }
}
/**
@@ -125,16 +123,6 @@
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
@@ -148,10 +136,6 @@
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;
}
@@ -166,113 +150,232 @@
return (pps.createStroke(shape));
}
-void PartEllipse::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartEllipse::mouseReleaseEvent
+ * Handle mouse release event
+ * @param event
+ */
+void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
- if (!isSelected())
+ if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
+ switchResizeMode();
+
+ CustomElementGraphicPart::mouseReleaseEvent(event);
+}
+
+/**
+ * @brief PartEllipse::itemChange
+ * @param change
+ * @param value
+ * @return
+ */
+QVariant PartEllipse::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemSelectedHasChanged && scene())
{
- CustomElementGraphicPart::hoverMoveEvent(event);
- return;
+ if (value.toBool() == true)
+ {
+ //When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+ //according to the number of selected items.
+ connect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
+
+ if (scene()->selectedItems().size() == 1)
+ addHandler();
+ }
+ else
+ {
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
+ removeHandler();
+ }
}
-
- int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
-
- if (handler >= 0)
+ else if (change == ItemPositionHasChanged)
{
- 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);
+ adjusteHandlerPos();
}
- else
- CustomElementGraphicPart::hoverMoveEvent(event);
+ else if (change == ItemSceneChange)
+ {
+ if(scene())
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
+
+ setSelected(false); //This item is removed from scene, then we deselect this, and so, the handlers is also removed.
+ }
+
+ return QGraphicsItem::itemChange(change, value);
}
/**
- * @brief PartEllipse::mousePressEvent
- * Handle mouse press event
+ * @brief PartEllipse::sceneEventFilter
+ * @param watched
* @param event
+ * @return
*/
-void PartEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartEllipse::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
- if (event->button() == Qt::LeftButton)
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
{
- setCursor(Qt::ClosedHandCursor);
- if (isSelected())
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
{
- 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_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
{
- m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
- m_undo_command->setText(tr("Modifier une ellipse"));
- m_undo_command->enableAnimation();
- return;
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+ {
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
}
}
}
+
+ return false;
+}
- CustomElementGraphicPart::mousePressEvent(event);
+void PartEllipse::switchResizeMode()
+{
+ if (m_resize_mode == 1)
+ {
+ m_resize_mode = 2;
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::darkGreen);
+ }
+ else
+ {
+ m_resize_mode = 1;
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::blue);
+ }
}
/**
- * @brief PartEllipse::mouseMoveEvent
- * Handle mouse move event
- * @param event
+ * @brief PartEllipse::adjusteHandlerPos
*/
-void PartEllipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- if(m_handler_index >= 0 && m_handler_index <= 7)
+void PartEllipse::adjusteHandlerPos()
+{
+ if (m_handler_vector.isEmpty())
+ return;
+
+ QVector <QPointF> points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect);
+
+ if (m_handler_vector.size() == points_vector.size())
{
- QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
- prepareGeometryChange();
+ points_vector = mapToScene(points_vector);
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
+ }
+}
- 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));
- }
+/**
+ * @brief PartEllipse::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void PartEllipse::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
+ m_undo_command->setText(tr("Modifier un rectangle"));
+ m_undo_command->enableAnimation();
+ return;
+}
+
+/**
+ * @brief PartEllipse::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartEllipse::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+
+ QPointF new_pos = event->scenePos();
+ if (event->modifiers() != Qt::ControlModifier)
+ new_pos = elementScene()->snapToGrid(event->scenePos());
+ new_pos = mapFromScene(new_pos);
+
+ if (m_resize_mode == 1)
+ setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(m_rect, new_pos, m_vector_index));
else
- CustomElementGraphicPart::mouseMoveEvent(event);
+ setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
+
+ adjusteHandlerPos();
}
/**
- * @brief PartEllipse::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartEllipse::handlerMouseReleaseEvent
+ * @param qghi
* @param event
*/
-void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartEllipse::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if (event->button() == Qt::LeftButton) {
- setCursor(Qt::OpenHandCursor);
- if (event->buttonDownPos(Qt::LeftButton) == event->pos())
- switchResizeMode();
- }
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_undo_command->setNewValue(QVariant(m_rect));
+ elementScene()->undoStack().push(m_undo_command);
+ m_undo_command = nullptr;
+ m_vector_index = -1;
+}
- if (m_handler_index >= 0 && m_handler_index <= 7)
- {
- if (!m_rect.isValid())
- m_rect = m_rect.normalized();
+/**
+ * @brief PartEllipse::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartEllipse::sceneSelectionChanged()
+{
+ if (this->isSelected() && scene()->selectedItems().size() == 1)
+ addHandler();
+ else
+ removeHandler();
+}
- m_undo_command->setNewValue(QVariant(m_rect));
- elementScene()->undoStack().push(m_undo_command);
- m_undo_command = nullptr;
- m_handler_index = -1;
+/**
+ * @brief PartEllipse::addHandler
+ * Add handlers for this item
+ */
+void PartEllipse::addHandler()
+{
+ if (m_handler_vector.isEmpty() && scene())
+ {
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect)));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ QColor color = Qt::blue;
+ if (m_resize_mode == 2)
+ color = Qt::darkGreen;
+
+ handler->setColor(color);
+ scene()->addItem(handler);
+ handler->installSceneEventFilter(this);
+ handler->setZValue(this->zValue()+1);
+ }
}
- else
- CustomElementGraphicPart::mouseReleaseEvent(event);
}
-void PartEllipse::switchResizeMode()
+/**
+ * @brief PartEllipse::removeHandler
+ * Remove the handlers of this item
+ */
+void PartEllipse::removeHandler()
{
- if (m_resize_mode == 1) {
- m_resize_mode = 2;
- m_handler.setOuterColor(Qt::darkGreen);
+ if (!m_handler_vector.isEmpty())
+ {
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
}
- else {
- m_resize_mode = 1;
- m_handler.setOuterColor(Qt::blue);
- }
- update();
}
Modified: trunk/sources/editor/graphicspart/partellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partellipse.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,7 +19,6 @@
#define PART_ELLIPSE_H
#include "abstractpartellipse.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
class QPropertyUndoCommand;
@@ -55,24 +54,29 @@
virtual QString xmlName() const { return(QString("ellipse")); }
virtual const QDomElement toXml (QDomDocument &) const;
virtual void fromXml (const QDomElement &);
-
- virtual QRectF boundingRect() const;
virtual QPainterPath shape() const;
virtual QPainterPath shadowShape() const;
+ virtual void setRect(const QRectF &rect) {AbstractPartEllipse::setRect(rect); adjusteHandlerPos();}
protected:
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
private:
void switchResizeMode();
+ void adjusteHandlerPos();
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void sceneSelectionChanged ();
+
+ void addHandler();
+ void removeHandler();
private:
- QetGraphicsHandlerUtility m_handler;
- int m_handler_index;
QPropertyUndoCommand *m_undo_command;
- int m_resize_mode = 1;
+ int m_resize_mode = 1,
+ m_vector_index = -1;
};
#endif
Modified: trunk/sources/editor/graphicspart/partline.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partline.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partline.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,6 +19,7 @@
#include <cmath>
#include "elementscene.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
/**
@@ -33,14 +34,16 @@
first_length(1.5),
second_end(Qet::None),
second_length(1.5),
- m_handler(10),
- m_handler_index(-1),
m_undo_command(nullptr)
{}
/// Destructeur
-PartLine::~PartLine() {
- if(m_undo_command) delete m_undo_command;
+PartLine::~PartLine()
+{
+ if(m_undo_command)
+ delete m_undo_command;
+
+ removeHandler();
}
/**
@@ -90,9 +93,6 @@
if (m_hovered)
drawShadowShape(painter);
- if (isSelected() && scene()->selectedItems().size() == 1)
- m_handler.drawHandler(painter, m_handler.pointsForLine(m_line));
-
painter->restore();
}
@@ -140,72 +140,209 @@
}
/**
- * @brief PartLine::mousePressEvent
- * Handle mouse press event
+ * @brief PartLine::itemChange
+ * @param change
+ * @param value
+ * @return
+ */
+QVariant PartLine::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemSelectedHasChanged && scene())
+ {
+ if (value.toBool() == true)
+ {
+ //When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+ //according to the number of selected items.
+ connect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
+
+ if (scene()->selectedItems().size() == 1)
+ addHandler();
+ }
+ else
+ {
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
+ removeHandler();
+ }
+ }
+ else if (change == ItemPositionHasChanged)
+ {
+ adjusteHandlerPos();
+ }
+ else if (change == ItemSceneChange)
+ {
+ if(scene())
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
+
+ setSelected(false); //This is item removed from scene, then we deselect this, and so, the handlers is also removed.
+ }
+
+ return QGraphicsItem::itemChange(change, value);
+}
+
+/**
+ * @brief PartLine::sceneEventFilter
+ * @param watched
* @param event
+ * @return
*/
-void PartLine::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartLine::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
- if(event->button() == Qt::LeftButton)
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
{
- setCursor(Qt::ClosedHandCursor);
-
- if (isSelected())
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
{
- 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_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
{
- m_undo_command = new QPropertyUndoCommand(this, "line", QVariant(m_line));
- m_undo_command->setText(tr("Modifier une ligne"));
- m_undo_command->enableAnimation();
- return;
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+ {
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
}
}
}
+
+ return false;
+}
- CustomElementGraphicPart::mousePressEvent(event);
+/**
+ * @brief PartLine::adjusteHandlerPos
+ * Adjust the position of the handler item
+ */
+void PartLine::adjusteHandlerPos()
+{
+ if(m_handler_vector.isEmpty())
+ return;
+
+ QVector<QPointF> points_vector;
+ points_vector << m_line.p1() << m_line.p2();
+
+ if (m_handler_vector.size() == points_vector.size())
+ {
+ points_vector = mapToScene(points_vector);
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
+ }
}
/**
- * @brief PartLine::mouseMoveEvent
- * Handle pouse move event
+ * @brief PartLine::handlerMousePressEvent
+ * @param qghi
* @param event
*/
-void PartLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartLine::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, 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));
- }
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_undo_command = new QPropertyUndoCommand(this, "line", QVariant(m_line));
+ m_undo_command->setText(tr("Modifier une ligne"));
+ m_undo_command->enableAnimation();
+ return;
+}
+
+/**
+ * @brief PartLine::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartLine::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+
+ QPointF new_pos = event->scenePos();
+ if (event->modifiers() != Qt::ControlModifier)
+ new_pos = elementScene()->snapToGrid(event->scenePos());
+ new_pos = mapFromScene(new_pos);
+
+ prepareGeometryChange();
+ if (m_vector_index == 0)
+ m_line.setP1(new_pos);
else
- CustomElementGraphicPart::mouseMoveEvent(event);
+ m_line.setP2(new_pos);
+
+ adjusteHandlerPos();
}
/**
- * @brief PartLine::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartLine::handlerMouseReleaseEvent
+ * @param qghi
* @param event
*/
-void PartLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartLine::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if (event->button() == Qt::LeftButton)
- setCursor(Qt::OpenHandCursor);
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_undo_command->setNewValue(QVariant(m_line));
+ elementScene()->undoStack().push(m_undo_command);
+ m_undo_command = nullptr;
+ m_vector_index = -1;
+}
- if (m_handler_index >= 0 && m_handler_index <= 1)
+/**
+ * @brief PartLine::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartLine::sceneSelectionChanged()
+{
+ if (this->isSelected() && scene()->selectedItems().size() == 1)
+ addHandler();
+ else
+ removeHandler();
+}
+
+/**
+ * @brief PartLine::addHandler
+ * Add handlers for this item
+ */
+void PartLine::addHandler()
+{
+ if (m_handler_vector.isEmpty() && scene())
{
- m_undo_command->setNewValue(QVariant(m_line));
- elementScene()->undoStack().push(m_undo_command);
- m_undo_command = nullptr;
- m_handler_index = -1;
+ QVector<QPointF> points_vector;
+ points_vector << m_line.p1() << m_line.p2();
+
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(points_vector));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ handler->setColor(Qt::blue);
+ scene()->addItem(handler);
+ handler->installSceneEventFilter(this);
+ handler->setZValue(this->zValue()+1);
+ }
}
- else
- CustomElementGraphicPart::mouseReleaseEvent(event);
}
/**
+ * @brief PartLine::removeHandler
+ * Remove the handlers of this item
+ */
+void PartLine::removeHandler()
+{
+ if (!m_handler_vector.isEmpty())
+ {
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
+ }
+}
+
+/**
* @brief PartLine::sceneP1
* @return the point p1 in scene coordinate
*/
@@ -243,10 +380,6 @@
pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
shape = pps.createStroke(shape);
- if (isSelected())
- foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForLine(m_line)))
- shape.addRect(rect);
-
return shape;
}
@@ -402,9 +535,6 @@
bound = bound.normalized();
bound.adjust(-adjust, -adjust, adjust, adjust);
- foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForLine(m_line)))
- bound |= rect;
-
return bound;
}
@@ -496,6 +626,7 @@
if (m_line == line) return;
prepareGeometryChange();
m_line = line;
+ adjusteHandlerPos();
emit lineChanged();
}
@@ -533,20 +664,6 @@
emit secondEndLengthChanged();
}
-void PartLine::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- if (!isSelected())
- {
- CustomElementGraphicPart::hoverMoveEvent(event);
- return;
- }
-
- if (m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForLine(m_line)) >= 0)
- setCursor(Qt::SizeAllCursor);
- else
- CustomElementGraphicPart::hoverMoveEvent(event);
-}
-
/**
* @brief PartLine::path
* @return this line has a QPainterPath.
Modified: trunk/sources/editor/graphicspart/partline.h
===================================================================
--- trunk/sources/editor/graphicspart/partline.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partline.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,9 +20,9 @@
#include "customelementgraphicpart.h"
#include "qet.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
/**
This class represents a line primitive which may be used to compose the
@@ -96,19 +96,26 @@
void setSecondEndLength(const qreal &l);
protected:
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
-
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
+
private:
+ void adjusteHandlerPos();
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void sceneSelectionChanged ();
+
+ void addHandler();
+ void removeHandler();
+
QPainterPath path() const;
-
QList<QPointF> fourShapePoints() const;
QRectF firstEndCircleRect() const;
QRectF secondEndCircleRect() const;
void debugPaint(QPainter *);
+ /*****************/
Qet::EndType first_end;
qreal first_length;
@@ -116,8 +123,8 @@
qreal second_length;
QList<QPointF> saved_points_;
QLineF m_line;
- QetGraphicsHandlerUtility m_handler;
- int m_handler_index;
+ int m_vector_index = -1;
QPropertyUndoCommand *m_undo_command;
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
};
#endif
Modified: trunk/sources/editor/graphicspart/partpolygon.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partpolygon.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,7 @@
#include "partpolygon.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementscene.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
/**
@@ -29,8 +30,6 @@
PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) :
CustomElementGraphicPart(editor, parent),
m_closed(false),
- m_handler(10),
- m_handler_index(-1),
m_undo_command(nullptr)
{}
@@ -37,8 +36,10 @@
/**
* @brief PartPolygon::~PartPolygon
*/
-PartPolygon::~PartPolygon() {
+PartPolygon::~PartPolygon()
+{
if(m_undo_command) delete m_undo_command;
+ removeHandler();
}
/**
@@ -64,9 +65,6 @@
if (m_hovered)
drawShadowShape(painter);
-
- if (isSelected() && scene()->selectedItems().size() == 1)
- m_handler.drawHandler(painter, m_polygon);
}
/**
@@ -199,6 +197,7 @@
if (m_polygon == polygon) return;
prepareGeometryChange();
m_polygon = polygon;
+ adjusteHandlerPos();
emit polygonChanged();
}
@@ -248,83 +247,195 @@
emit closedChange();
}
-void PartPolygon::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartPolygon::itemChange
+ * @param change
+ * @param value
+ * @return
+ */
+QVariant PartPolygon::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
- if (!isSelected())
+ if (change == ItemSelectedHasChanged && scene())
{
- CustomElementGraphicPart::hoverMoveEvent(event);
- return;
+ if (value.toBool() == true)
+ {
+ //When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+ //according to the number of selected items.
+ connect(scene(), &QGraphicsScene::selectionChanged, this, &PartPolygon::sceneSelectionChanged);
+
+ if (scene()->selectedItems().size() == 1)
+ addHandler();
+ }
+ else
+ {
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartPolygon::sceneSelectionChanged);
+ removeHandler();
+ }
}
-
- if (m_handler.pointIsHoverHandler(event->pos(), m_polygon) >= 0)
- setCursor(Qt::SizeAllCursor);
- else
- CustomElementGraphicPart::hoverMoveEvent(event);
+ else if (change == ItemPositionHasChanged)
+ {
+ adjusteHandlerPos();
+ }
+ else if (change == ItemSceneChange)
+ {
+ if(scene())
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartPolygon::sceneSelectionChanged);
+
+ setSelected(false); //This is item removed from scene, then we deselect this, and so, the handlers is also removed.
+ }
+
+ return QGraphicsItem::itemChange(change, value);
}
/**
- * @brief PartPolygon::mousePressEvent
- * Handle mouse press event
+ * @brief PartPolygon::sceneEventFilter
+ * @param watched
* @param event
+ * @return
*/
-void PartPolygon::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartPolygon::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
- if (event->button() == Qt::LeftButton)
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
{
- setCursor(Qt::ClosedHandCursor);
- if(isSelected())
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
{
- m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_polygon);
-
- if(m_handler_index >= 0) //User click on an handler
+ m_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
{
- m_undo_command = new QPropertyUndoCommand(this, "polygon", QVariant(m_polygon));
- m_undo_command->setText(tr("Modifier un polygone"));
- return;
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+ {
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
}
}
}
-
- CustomElementGraphicPart::mousePressEvent(event);
+
+ return false;
}
/**
- * @brief PartPolygon::mouseMoveEvent
- * Handle mouse move event
- * @param event
+ * @brief PartPolygon::adjusteHandlerPos
*/
-void PartPolygon::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartPolygon::adjusteHandlerPos()
{
- if(m_handler_index >= 0)
+ if(m_handler_vector.isEmpty())
+ return;
+
+ if (m_handler_vector.size() == m_polygon.size())
{
- QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
- prepareGeometryChange();
- m_polygon.replace(m_handler_index, pos_);
- emit polygonChanged();
+ QVector <QPointF> points_vector = mapToScene(m_polygon);
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
}
- else
- CustomElementGraphicPart::mouseMoveEvent(event);
}
/**
- * @brief PartPolygon::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartPolygon::handlerMousePressEvent
+ * @param qghi
* @param event
*/
-void PartPolygon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartPolygon::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if (event->button() == Qt::LeftButton)
- setCursor(Qt::OpenHandCursor);
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_undo_command = new QPropertyUndoCommand(this, "polygon", QVariant(m_polygon));
+ m_undo_command->setText(tr("Modifier un polygone"));
+}
- if (m_handler_index >= 0)
+/**
+ * @brief PartPolygon::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartPolygon::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+
+ QPointF new_pos = event->scenePos();
+ if (event->modifiers() != Qt::ControlModifier)
+ new_pos = elementScene()->snapToGrid(event->scenePos());
+ new_pos = mapFromScene(new_pos);
+
+ prepareGeometryChange();
+ m_polygon.replace(m_vector_index, new_pos);
+ adjusteHandlerPos();
+ emit polygonChanged();
+}
+
+/**
+ * @brief PartPolygon::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void PartPolygon::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_undo_command->setNewValue(QVariant(m_polygon));
+ elementScene()->undoStack().push(m_undo_command);
+ m_undo_command = nullptr;
+ m_vector_index = -1;
+}
+
+/**
+ * @brief PartPolygon::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartPolygon::sceneSelectionChanged()
+{
+ if (this->isSelected() && scene()->selectedItems().size() == 1)
+ addHandler();
+ else
+ removeHandler();
+}
+
+/**
+ * @brief PartPolygon::addHandler
+ * Add handlers for this item
+ */
+void PartPolygon::addHandler()
+{
+ if (m_handler_vector.isEmpty() && scene())
+ {
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(m_polygon));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ handler->setColor(Qt::blue);
+ scene()->addItem(handler);
+ handler->installSceneEventFilter(this);
+ handler->setZValue(this->zValue()+1);
+ }
+ }
+}
+
+/**
+ * @brief PartPolygon::removeHandler
+ * Remove the handlers of this item
+ */
+void PartPolygon::removeHandler()
+{
+ if (!m_handler_vector.isEmpty())
{
- m_undo_command->setNewValue(QVariant(m_polygon));
- elementScene()->undoStack().push(m_undo_command);
- m_undo_command = nullptr;
- m_handler_index = -1;
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
}
- else
- CustomElementGraphicPart::mouseReleaseEvent(event);
}
/**
@@ -343,10 +454,6 @@
pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
shape = pps.createStroke(shape);
- if (isSelected())
- foreach(QRectF rect, m_handler.handlerRect(m_polygon))
- shape.addRect(rect);
-
return shape;
}
@@ -379,8 +486,5 @@
r.adjust(-adjust, -adjust, adjust, adjust);
- foreach(QRectF rect, m_handler.handlerRect(m_polygon))
- r |=rect;
-
return(r);
}
Modified: trunk/sources/editor/graphicspart/partpolygon.h
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partpolygon.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,10 +20,9 @@
#include <QPolygonF>
#include "customelementgraphicpart.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
-
class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
/**
* @brief The PartPolygon class
@@ -85,17 +84,25 @@
void setClosed (bool close);
protected:
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
private:
+ void adjusteHandlerPos();
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void sceneSelectionChanged ();
+
+ void addHandler();
+ void removeHandler();
+
+
bool m_closed;
QList<QPointF> saved_points_;
QPolygonF m_polygon;
- QetGraphicsHandlerUtility m_handler;
- int m_handler_index;
QPropertyUndoCommand *m_undo_command;
+ int m_vector_index = -1;
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
};
#endif
Modified: trunk/sources/editor/graphicspart/partrectangle.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partrectangle.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,8 @@
#include "partrectangle.h"
#include "elementscene.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
/**
* @brief PartRectangle::PartRectangle
@@ -27,8 +29,6 @@
*/
PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) :
CustomElementGraphicPart(editor, parent),
- m_handler(10),
- m_handler_index(-1),
m_undo_command(nullptr)
{}
@@ -35,8 +35,10 @@
/**
* @brief PartRectangle::~PartRectangle
*/
-PartRectangle::~PartRectangle() {
+PartRectangle::~PartRectangle()
+{
if(m_undo_command) delete m_undo_command;
+ removeHandler();
}
/**
@@ -69,11 +71,7 @@
drawShadowShape(painter);
if (isSelected())
- {
drawCross(m_rect.center(), painter);
- if (scene()->selectedItems().size() == 1)
- m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect));
- }
}
/**
@@ -129,6 +127,7 @@
if (rect == m_rect) return;
prepareGeometryChange();
m_rect = rect;
+ adjusteHandlerPos();
emit rectChanged();
}
@@ -164,10 +163,6 @@
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;
}
@@ -196,9 +191,6 @@
QRectF r = m_rect.normalized();
r.adjust(-adjust, -adjust, adjust, adjust);
- foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
- r |= rect;
-
return(r);
}
@@ -237,113 +229,230 @@
setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
}
-void PartRectangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartRectangle::mouseReleaseEvent
+ * Handle mouse release event
+ * @param event
+ */
+void PartRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
- if (!isSelected())
+ if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
+ switchResizeMode();
+
+ CustomElementGraphicPart::mouseReleaseEvent(event);
+}
+
+/**
+ * @brief PartRectangle::itemChange
+ * @param change
+ * @param value
+ * @return
+ */
+QVariant PartRectangle::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemSelectedHasChanged && scene())
{
- CustomElementGraphicPart::hoverMoveEvent(event);
- return;
+ if (value.toBool() == true)
+ {
+ //When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+ //according to the number of selected items.
+ connect(scene(), &QGraphicsScene::selectionChanged, this, &PartRectangle::sceneSelectionChanged);
+
+ if (scene()->selectedItems().size() == 1)
+ addHandler();
+ }
+ else
+ {
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartRectangle::sceneSelectionChanged);
+ removeHandler();
+ }
}
-
- int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
-
- if (handler >= 0)
+ else if (change == ItemPositionHasChanged)
{
- 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);
+ adjusteHandlerPos();
}
- else
- CustomElementGraphicPart::hoverMoveEvent(event);
+ else if (change == ItemSceneChange)
+ {
+ if(scene())
+ disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartRectangle::sceneSelectionChanged);
+
+ setSelected(false); //This item is removed from scene, then we deselect this, and so, the handlers is also removed.
+ }
+
+ return QGraphicsItem::itemChange(change, value);
}
/**
- * @brief PartRectangle::mousePressEvent
- * Handle mouse press event
+ * @brief PartRectangle::sceneEventFilter
+ * @param watched
* @param event
+ * @return
*/
-void PartRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartRectangle::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
- if (event->button() == Qt::LeftButton)
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
{
- setCursor(Qt::ClosedHandCursor);
- if(isSelected())
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
{
- 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_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
{
- m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
- m_undo_command->setText(tr("Modifier un rectangle"));
- m_undo_command->enableAnimation();
- return;
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+ {
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
}
}
}
-
- CustomElementGraphicPart::mousePressEvent(event);
+
+ return false;
}
/**
- * @brief PartRectangle::mouseMoveEvent
- * Handle mouse press event
- * @param event
+ * @brief PartRectangle::switchResizeMode
*/
-void PartRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartRectangle::switchResizeMode()
{
- if(m_handler_index >= 0 && m_handler_index <= 7)
+ if (m_resize_mode == 1)
{
- 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));
+ m_resize_mode = 2;
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::darkGreen);
}
else
- CustomElementGraphicPart::mouseMoveEvent(event);
+ {
+ m_resize_mode = 1;
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::blue);
+ }
}
/**
- * @brief PartRectangle::mouseReleaseEvent
- * Handle mouse release event
- * @param event
+ * @brief PartRectangle::adjusteHandlerPos
*/
-void PartRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartRectangle::adjusteHandlerPos()
{
- if (event->button() == Qt::LeftButton) {
- setCursor(Qt::OpenHandCursor);
- if (event->buttonDownPos(Qt::LeftButton) == event->pos())
- switchResizeMode();
+ if (m_handler_vector.isEmpty())
+ return;
+
+ QVector <QPointF> points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect);
+
+ if (m_handler_vector.size() == points_vector.size())
+ {
+ points_vector = mapToScene(points_vector);
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
}
+}
- if (m_handler_index >= 0 && m_handler_index <= 7)
- {
- if (!m_rect.isValid())
- m_rect = m_rect.normalized();
+/**
+ * @brief PartRectangle::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void PartRectangle::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
- m_undo_command->setNewValue(QVariant(m_rect));
- elementScene()->undoStack().push(m_undo_command);
- m_undo_command = nullptr;
- m_handler_index = -1;
- }
+ m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
+ m_undo_command->setText(tr("Modifier un rectangle"));
+ m_undo_command->enableAnimation();
+ return;
+}
+
+/**
+ * @brief PartRectangle::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartRectangle::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+
+ QPointF new_pos = event->scenePos();
+ if (event->modifiers() != Qt::ControlModifier)
+ new_pos = elementScene()->snapToGrid(event->scenePos());
+ new_pos = mapFromScene(new_pos);
+
+ if (m_resize_mode == 1)
+ setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(m_rect, new_pos, m_vector_index));
else
- CustomElementGraphicPart::mouseReleaseEvent(event);
+ setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
+
+ adjusteHandlerPos();
}
-void PartRectangle::switchResizeMode()
+void PartRectangle::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if (m_resize_mode == 1) {
- m_resize_mode = 2;
- m_handler.setOuterColor(Qt::darkGreen);
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_undo_command->setNewValue(QVariant(m_rect));
+ elementScene()->undoStack().push(m_undo_command);
+ m_undo_command = nullptr;
+ m_vector_index = -1;
+}
+
+/**
+ * @brief PartRectangle::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartRectangle::sceneSelectionChanged()
+{
+ if (this->isSelected() && scene()->selectedItems().size() == 1)
+ addHandler();
+ else
+ removeHandler();
+}
+
+/**
+ * @brief PartRectangle::addHandler
+ * Add handlers for this item
+ */
+void PartRectangle::addHandler()
+{
+ if (m_handler_vector.isEmpty() && scene())
+ {
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect)));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ QColor color = Qt::blue;
+ if (m_resize_mode == 2)
+ color = Qt::darkGreen;
+
+ handler->setColor(color);
+ scene()->addItem(handler);
+ handler->installSceneEventFilter(this);
+ handler->setZValue(this->zValue()+1);
+ }
}
- else {
- m_resize_mode = 1;
- m_handler.setOuterColor(Qt::blue);
+}
+
+/**
+ * @brief PartRectangle::removeHandler
+ * Remove the handlers of this item
+ */
+void PartRectangle::removeHandler()
+{
+ if (!m_handler_vector.isEmpty())
+ {
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
}
- update();
}
Modified: trunk/sources/editor/graphicspart/partrectangle.h
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partrectangle.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,9 +19,9 @@
#define PART_RECTANGLE_H
#include "customelementgraphicpart.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
/**
* This class represents a rectangle primitive which may be used to compose the
@@ -75,20 +75,27 @@
virtual void handleUserTransformation(const QRectF &, const QRectF &);
protected:
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
private:
void switchResizeMode();
+ void adjusteHandlerPos();
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void sceneSelectionChanged ();
+
+ void addHandler();
+ void removeHandler();
private:
QRectF m_rect;
QList<QPointF> saved_points_;
- QetGraphicsHandlerUtility m_handler;
- int m_handler_index;
QPropertyUndoCommand *m_undo_command;
- int m_resize_mode = 1;
+ int m_resize_mode = 1,
+ m_vector_index = -1;
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
};
#endif
Modified: trunk/sources/qetgraphicsitem/conductor.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/conductor.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/conductor.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -78,10 +78,9 @@
terminal1(p1),
terminal2(p2),
m_mouse_over(false),
- m_handler(10),
m_text_item(0),
segments(NULL),
- moving_segment(false),
+ m_moving_segment(false),
modified_path(false),
has_to_save_profile(false),
must_highlight_(Conductor::None)
@@ -88,7 +87,7 @@
{
//set Zvalue at 11 to be upper than the DiagramImageItem and element
setZValue(11);
- previous_z_value = zValue();
+ m_previous_z_value = zValue();
//Add this conductor to the list of conductor of each of the two terminal
bool ajout_p1 = terminal1 -> addConductor(this);
@@ -117,7 +116,7 @@
//Generate the path of this conductor.
generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
- setFlags(QGraphicsItem::ItemIsSelectable);
+ setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsScenePositionChanges);
setAcceptHoverEvents(true);
// Add the text field
@@ -137,6 +136,7 @@
*/
Conductor::~Conductor()
{
+ removeHandler();
terminal1->removeConductor(this);
terminal2->removeConductor(this);
deleteSegments();
@@ -171,30 +171,39 @@
}
/**
- Genere le QPainterPath a partir de la liste des points
-*/
-void Conductor::segmentsToPath() {
- // chemin qui sera dessine
+ * @brief Conductor::segmentsToPath
+ * Generate the QPainterPath from the list of points
+ */
+void Conductor::segmentsToPath()
+{
QPainterPath path;
- // s'il n'y a pa des segments, on arrete la
- if (segments == NULL) setPath(path);
+ if (segments == NULL)
+ setPath(path);
- // demarre le chemin
+ //Start the path
path.moveTo(segments -> firstPoint());
-
- // parcourt les segments pour dessiner le chemin
+ //Each segments
ConductorSegment *segment = segments;
while(segment -> hasNextSegment()) {
path.lineTo(segment -> secondPoint());
segment = segment -> nextSegment();
}
-
- // termine le chemin
+ //Finish the path
path.lineTo(segment -> secondPoint());
- // affecte le chemin au conducteur
setPath(path);
+
+ //If conductor is selected and he's not being modified
+ //we update the position of the handlers
+ if (isSelected() && !m_moving_segment)
+ {
+ if(handlerPoints().size() == m_handler_vector.size())
+ adjusteHandlerPos();
+ else
+ removeHandler();
+ addHandler();
+ }
}
/**
@@ -456,12 +465,11 @@
}
/**
- * @brief Conductor::paint
- * Draw the conductor
- * @param qp
- * @param options
- * @param qw
- */
+ Dessine le conducteur sans antialiasing.
+ @param qp Le QPainter a utiliser pour dessiner le conducteur
+ @param options Les options de style pour le conducteur
+ @param qw Le QWidget sur lequel on dessine
+*/
void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWidget *qw)
{
Q_UNUSED(qw);
@@ -501,7 +509,7 @@
final_conductor_pen.setCosmetic(true);
}
- qp->setPen(final_conductor_pen);
+ qp -> setPen(final_conductor_pen);
//Draw the conductor
qp -> drawPath(path());
@@ -529,22 +537,17 @@
if (isSelected()) qp -> setBrush(Qt::NoBrush);
}
- //Draw the squares used to modify the path of conductor when he is selected
- if (isSelected())
- m_handler.drawHandler(qp, handlerPoints());
-
//Draw the junctions
- const QList<QPointF> junctions_list = junctions();
- if (!junctions_list.isEmpty())
- {
+ QList<QPointF> junctions_list = junctions();
+ if (!junctions_list.isEmpty()) {
final_conductor_pen.setStyle(Qt::SolidLine);
QBrush junction_brush(final_conductor_color, Qt::SolidPattern);
qp -> setPen(final_conductor_pen);
qp -> setBrush(junction_brush);
qp -> setRenderHint(QPainter::Antialiasing, true);
-
- for(QPointF point : junctions_list)
+ foreach(QPointF point, junctions_list) {
qp -> drawEllipse(QRectF(point.x() - 1.5, point.y() - 1.5, 3.0, 3.0));
+ }
}
qp -> restore();
@@ -603,70 +606,18 @@
*/
void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
- //Left clic
- if (event->buttons() & Qt::LeftButton)
- {
- //If user click on a handler (square used to modify the path of conductor),
- //we get the segment corresponding to the handler
- int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
- if (index > -1)
- {
- moving_segment = true;
- moved_segment = segmentsList().at(index+1);
- before_mov_text_pos_ = m_text_item -> pos();
- }
- }
-
QGraphicsPathItem::mousePressEvent(event);
-
- if (event -> modifiers() & Qt::ControlModifier)
+
+ if (event->modifiers() & Qt::ControlModifier)
setSelected(!isSelected());
}
/**
- * @brief Conductor::mouseMoveEvent
- * Manage the mouse move event
- * @param event
- */
-void Conductor::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- //Left clic
- if ((event->buttons() & Qt::LeftButton) && moving_segment)
- {
- //Snap the mouse pos to grid
- QPointF pos_ = Diagram::snapToGrid(event->pos());
-
- //Position of the last point
- QPointF p = moved_segment -> middle();
-
- //Calcul the movement
- moved_segment -> moveX(pos_.x() - p.x());
- moved_segment -> moveY(pos_.y() - p.y());
-
- //Apply the movement
- modified_path = true;
- has_to_save_profile = true;
- segmentsToPath();
- calculateTextItemPosition();
- }
-
- QGraphicsPathItem::mouseMoveEvent(event);
-}
-
-/**
* @brief Conductor::mouseReleaseEvent
- * Manage the mouse release event
* @param event
*/
void Conductor::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
- moving_segment = false;
- if (has_to_save_profile)
- {
- saveProfile();
- has_to_save_profile = false;
- }
-
if (!(event -> modifiers() & Qt::ControlModifier))
QGraphicsPathItem::mouseReleaseEvent(event);
}
@@ -694,59 +645,212 @@
}
/**
- * @brief Conductor::hoverMoveEvent conductor
- * @param e QGraphicsSceneHoverEvent describing the event
+ * @brief Conductor::itemChange
+ * @param change
+ * @param value
+ * @return
*/
-void Conductor::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value)
{
- if (isSelected())
+ if (change == QGraphicsItem::ItemSelectedChange)
{
- //If user hover an handler (square used to modify the path of conductor),
- //we get the segment corresponding to the handler
- int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
- if (index > -1)
+ if (value.toBool())
{
- ConductorSegment *segment_ = segmentsList().at(index+1);
- if (m_handler.pointIsInHandler(event->pos(), segment_->secondPoint()))
- setCursor(Qt::ForbiddenCursor);
- else if (m_handler.pointIsInHandler(event->pos(), segment_->middle()))
- setCursor(segmentsList().at(index+1)->isVertical() ? Qt::SplitHCursor : Qt::SplitVCursor);
+ m_previous_z_value = zValue();
+ setZValue(qAbs(m_previous_z_value) + 10000);
+ addHandler();
}
else
- setCursor(Qt::ArrowCursor);
+ {
+ setZValue(m_previous_z_value);
+ removeHandler();
+ }
}
+ else if (change == QGraphicsItem::ItemSceneHasChanged)
+ {
+ calculateTextItemPosition();
+
+ if(!scene())
+ removeHandler();
+ else if (scene() && isSelected())
+ addHandler();
+ }
+ else if (change == QGraphicsItem::ItemVisibleHasChanged) {
+ calculateTextItemPosition();
+ }
+ else if (change == QGraphicsItem::ItemPositionHasChanged && isSelected()) {
+ adjusteHandlerPos();
+ }
+
+ return(QGraphicsPathItem::itemChange(change, value));
+}
- QGraphicsPathItem::hoverMoveEvent(event);
+/**
+ * @brief Conductor::sceneEventFilter
+ * @param watched
+ * @param event
+ * @return
+ */
+bool Conductor::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+{
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
+ {
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
+ {
+ m_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
+ {
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+ {
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
}
/**
- Gere les changements relatifs au conducteur
- Reimplemente ici pour :
- * positionner le conducteur en avant-plan lorsqu'il est selectionne
- @param change Type de changement
- @param value Valeur relative au changement
-*/
-QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value) {
- if (change == QGraphicsItem::ItemSelectedChange) {
- if (value.toBool()) {
- // le conducteur vient de se faire selectionner
- previous_z_value = zValue();
- setZValue(qAbs(previous_z_value) + 10000);
- } else {
- // le conducteur vient de se faire deselectionner
- setZValue(previous_z_value);
- }
- } else if (change == QGraphicsItem::ItemSceneHasChanged) {
- // permet de positionner correctement le texte du conducteur lors de son ajout a un schema
+ * @brief Conductor::adjusteHandlerPos
+ * Adjust the position of the handler item
+ */
+void Conductor::adjusteHandlerPos()
+{
+ if (m_handler_vector.isEmpty())
+ return;
+
+ if (m_handler_vector.size() == handlerPoints().size())
+ {
+ QVector <QPointF> points_vector = mapToScene(handlerPoints());
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
+ }
+}
+
+/**
+ * @brief Conductor::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void Conductor::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+
+ //we get the segment corresponding to the handler
+ if (m_vector_index > -1)
+ {
+ qghi->setColor(Qt::cyan);
+ m_moving_segment = true;
+ m_moved_segment = segmentsList().at(m_vector_index+1);
+ before_mov_text_pos_ = m_text_item -> pos();
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ if(handler != qghi)
+ handler->hide();
+ }
+}
+
+/**
+ * @brief Conductor::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void Conductor::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ if (m_moving_segment)
+ {
+ //Snap the mouse pos to grid
+ QPointF pos_ = Diagram::snapToGrid(mapFromItem(qghi, event->pos()));
+
+ //Position of the last point
+ QPointF p = m_moved_segment -> middle();
+
+ //Calcul the movement
+ m_moved_segment -> moveX(pos_.x() - p.x());
+ m_moved_segment -> moveY(pos_.y() - p.y());
+
+ //Apply the movement
+ modified_path = true;
+ has_to_save_profile = true;
+ segmentsToPath();
calculateTextItemPosition();
- } else if (change == QGraphicsItem::ItemVisibleHasChanged) {
- // permet de positionner correctement le texte du conducteur lors de son ajout a un schema
- calculateTextItemPosition();
+ qghi->setPos(mapToScene(m_moved_segment->middle()));
}
- return(QGraphicsPathItem::itemChange(change, value));
}
/**
+ * @brief Conductor::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void Conductor::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+ Q_UNUSED(qghi);
+
+ m_vector_index = -1;
+
+ m_moving_segment = false;
+ if (has_to_save_profile)
+ {
+ saveProfile();
+ has_to_save_profile = false;
+ }
+ //When handler is released, the conductor can have more segment than befor the handler was moved
+ //then we remove all handles and new ones are added
+ removeHandler();
+ addHandler();
+}
+
+/**
+ * @brief Conductor::addHandler
+ * Add handlers for this item
+ */
+void Conductor::addHandler()
+{
+ if (m_handler_vector.isEmpty() && scene())
+ {
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(handlerPoints()));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ handler->setColor(Qt::blue);
+ scene()->addItem(handler);
+ handler->installSceneEventFilter(this);
+ handler->setZValue(this->zValue()+1);
+ }
+ }
+}
+
+/**
+ * @brief Conductor::removeHandler
+ * Remove the handlers of this item
+ */
+void Conductor::removeHandler()
+{
+ if (!m_handler_vector.isEmpty())
+ {
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
+ }
+}
+
+/**
* @brief Conductor::boundingRect
* @return
*/
@@ -768,23 +872,7 @@
pps.setJoinStyle(conductor_pen.joinStyle());
QPainterPath shape_(pps.createStroke(path()));
-
- /**
- Add handle rect to path, occur a weird bug.
- when the conductor is removed from the scene he continue to be painted in the scene and make artefact.
- If we save (exactly when we clear the undo stack of project when saving), Qet crash,
- Don't add the handle rect to the path seem to work well.
- More information here :
- https://qelectrotech.org/bugtracker/view.php?id=107
- https://qelectrotech.org/forum/viewtopic.php?pid=5619#p5619
- https://qelectrotech.org/forum/viewtopic.php?pid=5067#p5067
- **/
-// if (isSelected()) {
-// foreach (QRectF rect, m_handler.handlerRect(handlerPoints())) {
-// shape_.addRect(rect);
-// }
-// }
-
+
return shape_;
}
Modified: trunk/sources/qetgraphicsitem/conductor.h
===================================================================
--- trunk/sources/qetgraphicsitem/conductor.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/conductor.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,7 +20,6 @@
#include "conductorproperties.h"
#include <QGraphicsPathItem>
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
#include "assignvariables.h"
class ConductorProfile;
@@ -32,6 +31,8 @@
class Element;
class QETDiagramEditor;
class NumerotationContext;
+class QetGraphicsHandlerItem;
+
typedef QPair<QPointF, Qt::Corner> ConductorBend;
typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
/**
@@ -133,36 +134,45 @@
protected:
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
private:
+ void adjusteHandlerPos();
+
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void addHandler();
+ void removeHandler();
+
+
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
+ int m_vector_index = -1;
bool m_mouse_over;
- QetGraphicsHandlerUtility m_handler;
- /// Functional properties
+ /// Functional properties
ConductorProperties m_properties;
- /// Text input for non simple, non-singleline conductors
+ /// Text input for non simple, non-singleline conductors
ConductorTextItem *m_text_item;
- /// Segments composing the conductor
+ /// Segments composing the conductor
ConductorSegment *segments;
- /// Attributs related to mouse interaction
- bool moving_segment;
+ /// Attributs related to mouse interaction
+ bool m_moving_segment;
int moved_point;
- qreal previous_z_value;
- ConductorSegment *moved_segment;
+ qreal m_previous_z_value;
+ ConductorSegment *m_moved_segment;
QPointF before_mov_text_pos_;
- /// Whether the conductor was manually modified by users
+ /// Whether the conductor was manually modified by users
bool modified_path;
- /// Whether the current profile should be saved as soon as possible
+ /// Whether the current profile should be saved as soon as possible
bool has_to_save_profile;
- /// conductor profile: "photography" of what the conductor is supposed to look
- /// like - there is one profile per kind of traject
+ /// conductor profile: "photography" of what the conductor is supposed to look
+ /// like - there is one profile per kind of traject
ConductorProfilesGroup conductor_profiles;
- /// Define whether and how the conductor should be highlighted
+ /// Define whether and how the conductor should be highlighted
Highlight must_highlight_;
bool m_valid;
bool m_freeze_label = false;
Modified: trunk/sources/qetgraphicsitem/qetshapeitem.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.cpp 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.cpp 2017-08-02 15:26:14 UTC (rev 5001)
@@ -22,6 +22,7 @@
#include "shapegraphicsitempropertieswidget.h"
#include "PropertiesEditor/propertieseditordialog.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
#include "qetxml.h"
/**
@@ -37,18 +38,20 @@
m_shapeType(type),
m_P1 (p1),
m_P2 (p2),
- m_hovered(false),
- m_mouse_grab_handler(false),
- m_handler(10)
+ m_hovered(false)
{
if (type == Polygon) m_polygon << m_P1 << m_P2;
- setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+ setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
setAcceptHoverEvents(true);
m_pen.setStyle(Qt::DashLine);
}
-QetShapeItem::~QetShapeItem() {}
+QetShapeItem::~QetShapeItem()
+{
+ if(!m_handler_vector.isEmpty())
+ qDeleteAll(m_handler_vector);
+}
/**
* @brief QetShapeItem::setPen
@@ -109,6 +112,7 @@
prepareGeometryChange();
m_P1 = line.p1();
m_P2 = line.p2();
+ adjusteHandlerPos();
return true;
}
@@ -125,6 +129,7 @@
prepareGeometryChange();
m_P1 = rect.topLeft();
m_P2 = rect.bottomRight();
+ adjusteHandlerPos();
return true;
}
@@ -142,6 +147,7 @@
if (Q_UNLIKELY(m_shapeType != Polygon)) return false;
prepareGeometryChange();
m_polygon = polygon;
+ adjusteHandlerPos();
return true;
}
@@ -246,23 +252,6 @@
pps.setJoinStyle(Qt::RoundJoin);
path = pps.createStroke(path);
- if (isSelected())
- {
- QVector <QPointF> vector;
-
- if (m_shapeType == Line)
- vector << m_P1 << m_P2;
- else if (m_shapeType == Rectangle || m_shapeType == Ellipse) {
- QRectF rect (m_P1, m_P2);
- vector << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
- }
- else
- vector = m_polygon;
-
- foreach(QRectF r, m_handler.handlerRect(vector))
- path.addRect(r);
- }
-
return (path);
}
@@ -293,35 +282,16 @@
painter -> drawPath (shape());
painter -> restore ();
}
-
- //Draw the shape and handlers if is selected
- switch (m_shapeType)
- {
- case Line:
- painter->drawLine(QLineF(m_P1, m_P2));
- if (isSelected())
- m_handler.drawHandler(painter, QVector<QPointF>{m_P1, m_P2});
- break;
-
- case Rectangle:
- painter->drawRect(QRectF(m_P1, m_P2));
- if (isSelected())
- m_handler.drawHandler(painter, m_handler.pointsForRect(QRectF(m_P1, m_P2)));
- break;
-
- case Ellipse:
- painter->drawEllipse(QRectF(m_P1, m_P2));
- if (isSelected())
- m_handler.drawHandler(painter, m_handler.pointsForRect(QRectF(m_P1, m_P2)));
- break;
-
- case Polygon:
- m_close ? painter->drawPolygon(m_polygon) : painter->drawPolyline(m_polygon);
- if (isSelected())
- m_handler.drawHandler(painter, m_polygon);
- break;
- }
- painter->restore();
+
+ switch (m_shapeType)
+ {
+ case Line: painter->drawLine(QLineF(m_P1, m_P2)); break;
+ case Rectangle: painter->drawRect(QRectF(m_P1, m_P2)); break;
+ case Ellipse: painter->drawEllipse(QRectF(m_P1, m_P2)); break;
+ case Polygon: m_close ? painter->drawPolygon(m_polygon) : painter->drawPolyline(m_polygon); break;
+ }
+
+ painter->restore();
}
/**
@@ -329,195 +299,275 @@
* Handle hover enter event
* @param event
*/
-void QetShapeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
+void QetShapeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
m_hovered = true;
QetGraphicsItem::hoverEnterEvent(event);
}
-void QetShapeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- if (!isSelected()) return;
-
- QVector <QPointF> vector;
- switch (m_shapeType)
- {
- case Line: vector << m_P1 << m_P2; break;
- case Rectangle: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
- case Ellipse: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
- case Polygon: vector = m_polygon; break;
- }
-
- int handler = m_handler.pointIsHoverHandler(event->pos(), vector);
- if (handler >= 0)
- {
- if (m_shapeType & (Line | Polygon)) {
- setCursor(Qt::SizeAllCursor);
- return;
- }
-
- 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
- setCursor(Qt::OpenHandCursor);
-}
-
/**
* @brief QetShapeItem::hoverLeaveEvent
* Handle hover leave event
* @param event
*/
-void QetShapeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
+void QetShapeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
m_hovered = false;
- unsetCursor();
QetGraphicsItem::hoverLeaveEvent(event);
}
/**
- * @brief QetShapeItem::mousePressEvent
- * Handle mouse press event
+ * @brief QetShapeItem::mouseReleaseEvent
+ * Handle mouse release event
* @param event
*/
-void QetShapeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
- if (event->button() == Qt::LeftButton)
+ if (event->buttonDownPos(Qt::LeftButton) == event->pos())
+ switchResizeMode();
+
+ QetGraphicsItem::mouseReleaseEvent(event);
+}
+
+/**
+ * @brief QetShapeItem::itemChange
+ * @param change
+ * @param value
+ * @return
+ */
+QVariant QetShapeItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemSelectedHasChanged)
+ {
+ if (value.toBool() == true) //If this is selected, wa add handlers.
+ {
+ QVector <QPointF> points_vector;
+ switch (m_shapeType)
+ {
+ case Line: points_vector << m_P1 << m_P2; break;
+ case Rectangle: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+ case Ellipse: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+ case Polygon: points_vector = m_polygon; break;
+ }
+
+ if(!points_vector.isEmpty() && scene())
+ {
+ m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(points_vector));
+
+ for(QetGraphicsHandlerItem *handler : m_handler_vector)
+ {
+ handler->setColor(Qt::blue);
+ scene()->addItem(handler);
+ handler->installSceneEventFilter(this);
+ }
+ }
+ }
+ else //Else this is deselected, we remove handlers
+ {
+ if(!m_handler_vector.isEmpty())
+ {
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
+ }
+ }
+ }
+ else if (change == ItemPositionHasChanged)
+ {
+ adjusteHandlerPos();
+ }
+ else if (change == ItemSceneHasChanged)
{
- setCursor(Qt::ClosedHandCursor);
- //Shape is selected, we see if user click in a handler
- if (isSelected())
+ if (!scene()) //This is removed from scene, then we deselect this, and so, the handlers is also removed.
{
- QVector <QPointF> vector;
- switch (m_shapeType)
- {
- case Line: vector << m_P1 << m_P2; break;
- case Rectangle: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
- case Ellipse: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
- case Polygon: vector = m_polygon; break;
- }
-
- m_vector_index = m_handler.pointIsHoverHandler(event->pos(), vector);
- if (m_vector_index != -1)
- {
- //User click on an handler
- m_mouse_grab_handler = true;
- m_old_P1 = m_P1;
- m_old_P2 = m_P2;
- m_old_polygon = m_polygon;
- return;
- }
+ setSelected(false);
}
}
- QetGraphicsItem::mousePressEvent(event);
+ return QGraphicsItem::itemChange(change, value);
}
/**
- * @brief QetShapeItem::mouseMoveEvent
- * Handle move event
+ * @brief QetShapeItem::sceneEventFilter
+ * @param watched
* @param event
+ * @return
*/
-void QetShapeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+bool QetShapeItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
- if (m_mouse_grab_handler)
+ //Watched must be an handler
+ if(watched->type() == QetGraphicsHandlerItem::Type)
{
- QPointF new_pos = event->pos();
- if (event->modifiers() != Qt::ControlModifier)
- new_pos = mapFromScene(Diagram::snapToGrid(event->scenePos()));
-
- switch (m_shapeType)
+ QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+
+ if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
{
- case Line:
- prepareGeometryChange();
- m_vector_index == 0 ? m_P1 = new_pos : m_P2 = new_pos;
- break;
-
- case Rectangle:
- if (m_resize_mode == 1) {
- setRect(m_handler.rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
- break;
+ m_vector_index = m_handler_vector.indexOf(qghi);
+ if (m_vector_index != -1)
+ {
+ if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+ {
+ handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
}
- else {
- setRect(m_handler.mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
- break;
+ else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+ {
+ handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
}
- case Ellipse:
- if (m_resize_mode == 1) {
- setRect(m_handler.rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
- break;
+ else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+ {
+ handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+ return true;
}
- else {
- setRect(m_handler.mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
- break;
- }
+ }
+ }
+ }
+
+ return false;
+}
- case Polygon:
- prepareGeometryChange();
- m_polygon.replace(m_vector_index, new_pos);
- break;
- } //End switch
- return;
+/**
+ * @brief QetShapeItem::switchResizeMode
+ */
+void QetShapeItem::switchResizeMode()
+{
+ if (m_shapeType & (Rectangle | Ellipse))
+ {
+ if (m_resize_mode == 1)
+ {
+ m_resize_mode = 2;
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::darkGreen);
+ }
+ else
+ {
+ m_resize_mode = 1;
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ qghi->setColor(Qt::blue);
+ }
}
+}
- QetGraphicsItem::mouseMoveEvent(event);
+/**
+ * @brief QetShapeItem::adjusteHandlerPos
+ * Adjust the position of the handler item
+ */
+void QetShapeItem::adjusteHandlerPos()
+{
+ QVector <QPointF> points_vector;
+ switch (m_shapeType)
+ {
+ case Line: points_vector << m_P1 << m_P2; break;
+ case Rectangle: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+ case Ellipse: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+ case Polygon: points_vector = m_polygon; break;
+ }
+
+ if (m_handler_vector.size() == points_vector.size())
+ {
+ points_vector = mapToScene(points_vector);
+ for (int i = 0 ; i < points_vector.size() ; ++i)
+ m_handler_vector.at(i)->setPos(points_vector.at(i));
+ }
}
/**
- * @brief QetShapeItem::mouseReleaseEvent
- * Handle mouse release event
+ * @brief QetShapeItem::handlerMousePressEvent
+ * @param qghi
* @param event
*/
-void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if ((m_shapeType & (Rectangle | Ellipse)) && event->buttonDownPos(Qt::LeftButton) == event->pos())
- switchResizeMode();
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ m_old_P1 = m_P1;
+ m_old_P2 = m_P2;
+ m_old_polygon = m_polygon;
+}
- if (m_mouse_grab_handler)
+/**
+ * @brief QetShapeItem::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void QetShapeItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(qghi);
+
+ QPointF new_pos = event->scenePos();
+ if (event->modifiers() != Qt::ControlModifier)
+ new_pos = Diagram::snapToGrid(event->scenePos());
+ new_pos = mapFromScene(new_pos);
+
+ switch (m_shapeType)
{
- m_mouse_grab_handler = false;
- if (diagram())
- {
- QPropertyUndoCommand *undo = nullptr;
- if ((m_shapeType & (Line | Rectangle | Ellipse)) && (m_P1 != m_old_P1 || m_P2 != m_old_P2))
- {
- switch(m_shapeType)
- {
- case Line: undo = new QPropertyUndoCommand(this, "line",QLineF(m_old_P1, m_old_P2), QLineF(m_P1, m_P2)); break;
- case Rectangle: undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
- case Ellipse: undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
- case Polygon: break;
- }
- if (undo) undo->enableAnimation();
- }
- else if (m_shapeType == Polygon && (m_polygon != m_old_polygon))
- undo = new QPropertyUndoCommand(this, "polygon", m_old_polygon, m_polygon);
+ case Line:
+ prepareGeometryChange();
+ m_vector_index == 0 ? m_P1 = new_pos : m_P2 = new_pos;
+ adjusteHandlerPos();
+ break;
- if(undo)
- {
- undo->setText(tr("Modifier %1").arg(name()));
- diagram()->undoStack().push(undo);
+ case Rectangle:
+ if (m_resize_mode == 1) {
+ setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+ break;
}
- }
- setCursor(Qt::OpenHandCursor);
- }
+ else {
+ setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+ break;
+ }
+ case Ellipse:
+ if (m_resize_mode == 1) {
+ setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+ break;
+ }
+ else {
+ setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+ break;
+ }
- QetGraphicsItem::mouseReleaseEvent(event);
+ case Polygon:
+ prepareGeometryChange();
+ m_polygon.replace(m_vector_index, new_pos);
+ adjusteHandlerPos();
+ break;
+ } //End switch
}
-void QetShapeItem::switchResizeMode()
+/**
+ * @brief QetShapeItem::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void QetShapeItem::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
- if (m_resize_mode == 1) {
- m_resize_mode = 2;
- m_handler.setOuterColor(Qt::darkGreen);
+ Q_UNUSED(qghi);
+ Q_UNUSED(event);
+
+ if (diagram())
+ {
+ QPropertyUndoCommand *undo = nullptr;
+ if ((m_shapeType & (Line | Rectangle | Ellipse)) && (m_P1 != m_old_P1 || m_P2 != m_old_P2))
+ {
+ switch(m_shapeType)
+ {
+ case Line: undo = new QPropertyUndoCommand(this, "line",QLineF(m_old_P1, m_old_P2), QLineF(m_P1, m_P2)); break;
+ case Rectangle: undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
+ case Ellipse: undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
+ case Polygon: break;
+ }
+ if (undo) undo->enableAnimation();
+ }
+ else if (m_shapeType == Polygon && (m_polygon != m_old_polygon))
+ undo = new QPropertyUndoCommand(this, "polygon", m_old_polygon, m_polygon);
+
+ if(undo)
+ {
+ undo->setText(tr("Modifier %1").arg(name()));
+ diagram()->undoStack().push(undo);
+ }
}
- else {
- m_resize_mode = 1;
- m_handler.setOuterColor(Qt::blue);
- }
- update();
}
/**
Modified: trunk/sources/qetgraphicsitem/qetshapeitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.h 2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.h 2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,10 +20,11 @@
#include <QPen>
#include "qetgraphicsitem.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
class QDomElement;
class QDomDocument;
+class QetGraphicsHandlerItem;
/**
* @brief The QetShapeItem class
@@ -96,14 +97,18 @@
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual void hoverEnterEvent (QGraphicsSceneHoverEvent *event);
- virtual void hoverMoveEvent (QGraphicsSceneHoverEvent *event);
virtual void hoverLeaveEvent (QGraphicsSceneHoverEvent *event);
- virtual void mousePressEvent (QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
private:
void switchResizeMode();
+ void adjusteHandlerPos();
+
+ void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+ void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
///ATTRIBUTES
private:
@@ -112,11 +117,10 @@
QBrush m_brush;
QPointF m_P1, m_P2, m_old_P1, m_old_P2;
QPolygonF m_polygon, m_old_polygon;
- bool m_hovered,
- m_mouse_grab_handler;
+ bool m_hovered;
int m_vector_index;
- QetGraphicsHandlerUtility m_handler;
bool m_close = false;
int m_resize_mode = 1;
+ QVector<QetGraphicsHandlerItem *> m_handler_vector;
};
#endif // QETSHAPEITEM_H