[qet] [4039] QetShapeItem : add handler for modified the geometry of shapes in the diagram |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/qet Archives
]
Revision: 4039
Author: blacksun
Date: 2015-07-09 20:33:14 +0200 (Thu, 09 Jul 2015)
Log Message:
-----------
QetShapeItem : add handler for modified the geometry of shapes in the diagram
Modified Paths:
--------------
trunk/sources/qetgraphicsitem/qetshapeitem.cpp
trunk/sources/qetgraphicsitem/qetshapeitem.h
Added Paths:
-----------
trunk/sources/QetGraphicsItemModeler/
trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri
trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
Added: trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri
===================================================================
--- trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri (rev 0)
+++ trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri 2015-07-09 18:33:14 UTC (rev 4039)
@@ -0,0 +1,5 @@
+HEADERS += \
+ $$PWD/qetgraphicshandlerutility.h
+
+SOURCES += \
+ $$PWD/qetgraphicshandlerutility.cpp
Property changes on: trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp (rev 0)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp 2015-07-09 18:33:14 UTC (rev 4039)
@@ -0,0 +1,108 @@
+/*
+ Copyright 2006-2015 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 "qetgraphicshandlerutility.h"
+#include <QPixmapCache>
+#include <QPainter>
+
+#define QetGraphicsHandlerSquareSize 10
+
+/**
+ * @brief QetGraphicsHandlerUtility::pixmapHandler
+ * @return The pixmap of an handler
+ */
+QPixmap QetGraphicsHandlerUtility::pixmapHandler()
+{
+ QPixmap handler(QetGraphicsHandlerSquareSize, QetGraphicsHandlerSquareSize);
+
+ if (!QPixmapCache::find("QetGraphicsHandler", handler))
+ { //Pixmap isn't store in the QPixmapCache, we create it
+ QColor inner(0xFF, 0xFF, 0xFF);
+ QColor outer(0x00, 0x61, 0xFF);
+
+ QPainter painter_(&handler);
+ painter_.setBrush(QBrush(inner));
+ QPen square_pen(QBrush(outer), 2.0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
+ square_pen.setCosmetic(true);
+ painter_.setPen(square_pen);
+ painter_.drawRect(0,0,10,10);
+
+ //Store the pixmap in the QPixmapCache
+ QPixmapCache::insert("QetGraphicsHandler", handler);
+ }
+ return handler;
+}
+
+/**
+ * @brief QetGraphicsHandlerUtility::posForHandler
+ * Returns a QPointF at the good coordinates
+ * for draw the handler pixmap centered on the point to modify
+ * @param point : the point to modify
+ * @return : point at the good coordinates to draw handler centered in @point
+ */
+QPointF QetGraphicsHandlerUtility::posForHandler(const QPointF &point)
+{
+ QPointF snap_point = point;
+ snap_point.rx() -= QetGraphicsHandlerSquareSize/2;
+ snap_point.ry() -= QetGraphicsHandlerSquareSize/2;
+ return snap_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)
+{
+ QRectF handler (posForHandler(key_point), QSize(QetGraphicsHandlerSquareSize, QetGraphicsHandlerSquareSize));
+ return handler.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)
+{
+ foreach (QPointF key_point, vector)
+ if (pointIsInHandler(point, key_point))
+ return vector.indexOf(key_point);
+
+ return -1;
+}
+
+/**
+ * @brief QetGraphicsHandlerUtility::handlerRect
+ * Return the rect of pixmap 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)
+{
+ QVector <QRectF> rect_vector;
+ QSize size(QetGraphicsHandlerSquareSize, QetGraphicsHandlerSquareSize);
+
+ foreach(QPointF point, vector)
+ rect_vector << QRectF(posForHandler(point), size);
+
+ return rect_vector;
+}
Added: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h (rev 0)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h 2015-07-09 18:33:14 UTC (rev 4039)
@@ -0,0 +1,38 @@
+/*
+ Copyright 2006-2015 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 QETGRAPHICSHANDLERUTILITY_H
+#define QETGRAPHICSHANDLERUTILITY_H
+
+#include <QPixmap>
+
+/**
+ * @brief The QetGraphicsHandlerUtility class
+ * This class provide some static methods to create and use handler for
+ * modify graphics shape like line rectangle etc...
+ */
+class QetGraphicsHandlerUtility
+{
+ public:
+ static QPixmap pixmapHandler();
+ static QPointF posForHandler(const QPointF &point);
+ static bool pointIsInHandler (const QPointF &point, const QPointF &key_point);
+ static int pointIsHoverHandler (const QPointF &point, const QVector<QPointF> &vector);
+ static QVector<QRectF> handlerRect (const QVector<QPointF> &vector);
+};
+
+#endif // QETGRAPHICSHANDLERUTILITY_H
Modified: trunk/sources/qetgraphicsitem/qetshapeitem.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.cpp 2015-07-07 20:17:14 UTC (rev 4038)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.cpp 2015-07-09 18:33:14 UTC (rev 4039)
@@ -21,7 +21,9 @@
#include "qet.h"
#include "shapegraphicsitempropertieswidget.h"
#include "PropertiesEditor/propertieseditordialog.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
+typedef QetGraphicsHandlerUtility QGHU;
/**
* @brief QetShapeItem::QetShapeItem
@@ -37,7 +39,8 @@
m_shapeStyle(Qt::DashLine),
m_P1 (Diagram::snapToGrid(p1)),
m_P2 (Diagram::snapToGrid(p2)),
- m_hovered(false)
+ m_hovered(false),
+ m_mouse_grab_handler(false)
{
if (type == Polyline) m_polygon << m_P1 << m_P2;
@@ -96,6 +99,39 @@
}
/**
+ * @brief QetShapeItem::setRect
+ * Set this item geometry to rect (only available if shape is a rectangle or an ellipse)
+ * @param rect : new rect
+ * @return : true when shape is rectangle or ellipse, else false
+ */
+bool QetShapeItem::setRect(const QRectF &rect)
+{
+ if (Q_LIKELY(m_shapeType == Rectangle || m_shapeType == Ellipse))
+ {
+ prepareGeometryChange();
+ m_P1 = rect.topLeft();
+ m_P2 = rect.bottomRight();
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @brief QetShapeItem::setPolygon
+ * Set this item geometry to polygon (only available if shape is a polyline)
+ * @param polygon : new polygon
+ * @return true if item is polygon, else false
+ */
+bool QetShapeItem::setPolygon(const QPolygon &polygon)
+{
+ if (Q_UNLIKELY(m_shapeType != Polyline)) return false;
+ prepareGeometryChange();
+ m_polygon = polygon;
+ return true;
+}
+
+/**
* @brief QetShapeItem::pointCount
* @return the number of point in the polygon
*/
@@ -175,8 +211,26 @@
QPainterPathStroker pps;
pps.setWidth(10);
pps.setJoinStyle(Qt::RoundJoin);
+ path = pps.createStroke(path);
- return (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, QGHU::handlerRect(vector))
+ path.addRect(r);
+ }
+
+ return (path);
}
/**
@@ -206,8 +260,9 @@
painter -> setRenderHint(QPainter::Antialiasing, false);
pen.setWidthF(1);
-
- if (m_hovered) {
+ //Draw hovered shadow
+ if (m_hovered)
+ {
painter->save();
QColor color(Qt::darkBlue);
color.setAlpha(25);
@@ -216,26 +271,54 @@
painter -> drawPath (shape());
painter -> restore ();
}
- else if (isSelected()) {
+ //Draw red if selected
+ if (isSelected())
pen.setColor(Qt::red);
- }
painter -> setPen(pen);
- switch (m_shapeType) {
+ //vector use to draw handler if needed
+ QVector <QPointF> point_vector;
+
+ //Draw the shape
+ switch (m_shapeType)
+ {
case Line:
painter->drawLine(QLineF(m_P1, m_P2));
+ if (isSelected())
+ point_vector << m_P1 << m_P2;
break;
+
case Rectangle:
painter->drawRect(QRectF(m_P1, m_P2));
+ if (isSelected())
+ {
+ QRectF rect (m_P1, m_P2);
+ point_vector << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
+ }
break;
+
case Ellipse:
painter->drawEllipse(QRectF(m_P1, m_P2));
+ if (isSelected())
+ {
+ QRectF rect (m_P1, m_P2);
+ point_vector << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
+ }
break;
+
case Polyline:
+ {
painter->drawPolyline(m_polygon);
+ point_vector = m_polygon;
+ }
break;
}
+
+ //Draw handler if shape is selected
+ if (isSelected())
+ foreach(QPointF point, point_vector)
+ painter->drawPixmap(QGHU::posForHandler(point), QGHU::pixmapHandler());
}
/**
@@ -263,6 +346,119 @@
}
/**
+ * @brief QetShapeItem::mousePressEvent
+ * Handle mouse press event
+ * @param event
+ */
+void QetShapeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ //Shape is selected, we see if user click in a handler
+ if (isSelected())
+ {
+ QVector <QPointF> vector;
+ switch (m_shapeType)
+ {
+ case Line:
+ vector << m_P1 << m_P2;
+ break;
+
+ case Rectangle: {
+ QRectF rect (m_P1, m_P2);
+ vector << rect.topLeft() << rect.topRight() << rect.bottomLeft() << rect.bottomRight();
+ }
+ break;
+
+ case Ellipse: {
+ QRectF rect (m_P1, m_P2);
+ vector << rect.topLeft() << rect.topRight() << rect.bottomLeft() << rect.bottomRight();
+ }
+ break;
+
+ case Polyline:
+ vector = m_polygon;
+ break;
+ }
+
+ m_vector_index = QGHU::pointIsHoverHandler(event->pos(), vector);
+ if (m_vector_index != -1)
+ {
+ //User click on an handler
+ m_mouse_grab_handler = true;
+ return;
+ }
+ }
+
+ QetGraphicsItem::mousePressEvent(event);
+}
+
+/**
+ * @brief QetShapeItem::mouseMoveEvent
+ * Handle move event
+ * @param event
+ */
+void QetShapeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (m_mouse_grab_handler)
+ {
+ QPointF new_pos = event->pos();
+ if (event->modifiers() != Qt::ControlModifier)
+ new_pos = mapFromScene(Diagram::snapToGrid(event->scenePos()));
+
+ switch (m_shapeType)
+ {
+ case Line: {
+ prepareGeometryChange();
+ m_vector_index == 0 ? m_P1 = new_pos : m_P2 = new_pos;
+ }
+ break;
+
+ case Rectangle: {
+ QRectF rect(m_P1, m_P2);
+ if (m_vector_index == 0) rect.setTopLeft(new_pos);
+ else if (m_vector_index == 1) rect.setTopRight(new_pos);
+ else if (m_vector_index == 2) rect.setBottomLeft(new_pos);
+ else if (m_vector_index == 3) rect.setBottomRight(new_pos);
+
+ setRect(rect);
+ }
+ break;
+
+ case Ellipse: {
+ QRectF rect(m_P1, m_P2);
+ if (m_vector_index == 0) rect.setTopLeft(new_pos);
+ else if (m_vector_index == 1) rect.setTopRight(new_pos);
+ else if (m_vector_index == 2) rect.setBottomLeft(new_pos);
+ else if (m_vector_index == 3) rect.setBottomRight(new_pos);
+
+ setRect(rect);
+ }
+ break;
+
+ case Polyline: {
+ prepareGeometryChange();
+ m_polygon.replace(m_vector_index, new_pos);
+ }
+ break;
+ } //End switch
+
+ return;
+ }
+
+ QetGraphicsItem::mouseMoveEvent(event);
+}
+
+/**
+ * @brief QetShapeItem::mouseReleaseEvent
+ * Handle mouse release event
+ * @param event
+ */
+void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ m_mouse_grab_handler = false;
+ QetGraphicsItem::mouseReleaseEvent(event);
+}
+
+/**
* @brief QetShapeItem::fromXml
* Build this item from the xml description
* @param e element where is stored this item
@@ -368,22 +564,14 @@
* @brief QetShapeItem::name
* @return the name of the curent shape.
*/
-QString QetShapeItem::name() const {
- switch (m_shapeType) {
- case Line:
- return tr("une ligne");
- break;
- case Rectangle:
- return tr("un rectangle");
- break;
- case Ellipse:
- return tr("une éllipse");
- break;
- case Polyline:
- return tr("une polyligne");
- break;
- default:
- return tr("une shape");
- break;
+QString QetShapeItem::name() const
+{
+ switch (m_shapeType)
+ {
+ case Line: return tr("une ligne"); break;
+ case Rectangle: return tr("un rectangle"); break;
+ case Ellipse: return tr("une éllipse"); break;
+ case Polyline: return tr("une polyligne"); break;
+ default: return tr("une shape"); break;
}
}
Modified: trunk/sources/qetgraphicsitem/qetshapeitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.h 2015-07-07 20:17:14 UTC (rev 4038)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.h 2015-07-09 18:33:14 UTC (rev 4039)
@@ -61,10 +61,12 @@
virtual void editProperty();
virtual QString name() const;
- void setP2 (QPointF P2);
+ void setP2 (QPointF P2);
+ bool setRect (const QRectF &rect);
+ bool setPolygon (const QPolygon &polygon);
//Methods available for polygon shape
- int pointsCount () const;
+ int pointsCount () const;
void setNextPoint (QPointF P);
void removePoints (int number = 1);
@@ -73,8 +75,11 @@
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
- virtual void hoverEnterEvent (QGraphicsSceneHoverEvent *event);
- virtual void hoverLeaveEvent (QGraphicsSceneHoverEvent *event);
+ virtual void hoverEnterEvent (QGraphicsSceneHoverEvent *event);
+ virtual void hoverLeaveEvent (QGraphicsSceneHoverEvent *event);
+ virtual void mousePressEvent (QGraphicsSceneMouseEvent *event);
+ virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
private:
void changeGraphicsItem (const ShapeType &newtype);
@@ -88,6 +93,8 @@
Qt::PenStyle m_shapeStyle;
QPointF m_P1, m_P2;
QPolygonF m_polygon;
- bool m_hovered;
+ bool m_hovered,
+ m_mouse_grab_handler;
+ int m_vector_index;
};
#endif // QETSHAPEITEM_H