[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


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/