[qet] qet/qet: [5436] QETshapeItem rectangle can have rounded corner. |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/qet Archives
]
Revision: 5436
Author: blacksun
Date: 2018-07-12 12:01:34 +0200 (Thu, 12 Jul 2018)
Log Message:
-----------
QETshapeItem rectangle can have rounded corner.
Modified Paths:
--------------
trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
trunk/sources/diagramevent/diagrameventaddshape.cpp
trunk/sources/qetgraphicsitem/qetshapeitem.cpp
trunk/sources/qetgraphicsitem/qetshapeitem.h
Modified: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp 2018-07-11 09:28:38 UTC (rev 5435)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp 2018-07-12 10:01:34 UTC (rev 5436)
@@ -16,8 +16,6 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "qetgraphicshandlerutility.h"
-//#include <QVector>
-//#include <QPointF>
#include <QPainterPath>
@@ -241,3 +239,80 @@
polygon.insert(index, pos);
return polygon;
}
+
+/**
+ * @brief QetGraphicsHandlerUtility::pointForRadiusRect
+ * @param rect the rectangle.
+ * @param xRadius : x radius
+ * @param yRadius : y radius
+ * @param mode : absolute or relative size: NOTE this argument is not used, this function always compute with relative size.
+ * @return the points of x and y radius of a rounded rect.
+ * The points are always based on the top right corner of the rect.
+ * the first point of vector is X the second Y
+ */
+#include <QDebug>
+QVector<QPointF> QetGraphicsHandlerUtility::pointForRadiusRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
+{
+ Q_UNUSED(mode)
+ QVector<QPointF> v;
+
+ qreal half_width = rect.width()/2;
+ qreal x_percent = std::min(xRadius, 100.00)/100;
+ QPointF X(rect.right() - half_width*x_percent,
+ rect.top());
+ v << X;
+
+ qreal half_height = rect.height()/2;
+ qreal y_percent = std::min(yRadius, 100.00)/100;
+ QPointF Y(rect.right(),
+ rect.top()+ half_height*y_percent);
+ v << Y;
+
+ return v;
+}
+
+/**
+ * @brief QetGraphicsHandlerUtility::radiusForPosAtIndex
+ * @param rect the rectangle
+ * @param pos : the pos of the new radius
+ * @param index : index of radius 0=X 1=Y
+ * @param mode
+ * @return
+ */
+qreal QetGraphicsHandlerUtility::radiusForPosAtIndex(const QRectF &rect, const QPointF &pos, int index, Qt::SizeMode mode)
+{
+ Q_UNUSED(mode)
+
+ if(index == 0) //X
+ {
+ if (pos.x() < rect.center().x()) {
+ return 100;
+ }
+ else if (pos.x() > rect.right()) {
+ return 0;
+ }
+ else {
+ return (100 - percentageInRange(rect.center().x(), rect.right(), pos.x()));
+ }
+ }
+ else if (index == 1) //Y
+ {
+ if (pos.y() < rect.top()) {
+ return 0;
+ }
+ else if (pos.y() > rect.center().y()) {
+ return 100;
+ }
+ else {
+ return percentageInRange(rect.top(), rect.center().y(), pos.y());
+ }
+ }
+ else {
+ return 0;
+ }
+}
+
+qreal QetGraphicsHandlerUtility::percentageInRange(qreal min, qreal max, qreal value) {
+ return ((value - min) * 100) / (max - min);
+}
+
Modified: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h 2018-07-11 09:28:38 UTC (rev 5435)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h 2018-07-12 10:01:34 UTC (rev 5436)
@@ -41,6 +41,9 @@
static QRectF mirrorRectForPosAtIndex (const QRectF &old_rect, const QPointF &pos, int index);
static QLineF lineForPosAtIndex (const QLineF &old_line, const QPointF &pos, int index);
static QPolygonF polygonForInsertPoint(const QPolygonF &old_polygon, bool closed, const QPointF &pos);
+ static QVector <QPointF> pointForRadiusRect (const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize);
+ static qreal radiusForPosAtIndex (const QRectF &rect, const QPointF &pos, int index, Qt::SizeMode mode = Qt::AbsoluteSize);
+ static qreal percentageInRange(qreal min, qreal max, qreal value);
};
#endif // QETGRAPHICSHANDLERUTILITY_H
Modified: trunk/sources/diagramevent/diagrameventaddshape.cpp
===================================================================
--- trunk/sources/diagramevent/diagrameventaddshape.cpp 2018-07-11 09:28:38 UTC (rev 5435)
+++ trunk/sources/diagramevent/diagrameventaddshape.cpp 2018-07-12 10:01:34 UTC (rev 5436)
@@ -82,6 +82,9 @@
if (m_shape_type != QetShapeItem::Polygon)
{
m_shape_item->setP2 (pos);
+ if(m_shape_item->shapeType() == QetShapeItem::Rectangle || m_shape_item->shapeType() == QetShapeItem::Ellipse) {
+ m_shape_item->setRect(m_shape_item->rect().normalized());
+ }
m_diagram->undoStack().push (new AddItemCommand<QetShapeItem *> (m_shape_item, m_diagram));
m_shape_item = nullptr; //< set to nullptr for create new shape at next left clic
}
Modified: trunk/sources/qetgraphicsitem/qetshapeitem.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.cpp 2018-07-11 09:28:38 UTC (rev 5435)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.cpp 2018-07-12 10:01:34 UTC (rev 5436)
@@ -159,7 +159,9 @@
*/
bool QetShapeItem::setPolygon(const QPolygonF &polygon)
{
- if (Q_UNLIKELY(m_shapeType != Polygon)) return false;
+ if (Q_UNLIKELY(m_shapeType != Polygon)) {
+ return false;
+ }
prepareGeometryChange();
m_polygon = polygon;
adjusteHandlerPos();
@@ -181,6 +183,22 @@
}
}
+void QetShapeItem::setXRadius(qreal X)
+{
+ m_xRadius = X;
+ update();
+ adjusteHandlerPos();
+ emit XRadiusChanged();
+}
+
+void QetShapeItem::setYRadius(qreal Y)
+{
+ m_yRadius = Y;
+ update();
+ adjusteHandlerPos();
+ emit YRadiusChanged();
+}
+
/**
* @brief QetShapeItem::pointCount
* @return the number of point in the polygon
@@ -246,7 +264,7 @@
path.lineTo(m_P2);
break;
case Rectangle:
- path.addRect(QRectF(m_P1, m_P2));
+ path.addRoundedRect(QRectF(m_P1, m_P2), m_xRadius, m_yRadius, Qt::RelativeSize);
break;
case Ellipse:
path.addEllipse(QRectF(m_P1, m_P2));
@@ -301,7 +319,7 @@
switch (m_shapeType)
{
case Line: painter->drawLine(QLineF(m_P1, m_P2)); break;
- case Rectangle: painter->drawRect(QRectF(m_P1, m_P2)); break;
+ case Rectangle: painter->drawRoundedRect(QRectF(m_P1, m_P2), m_xRadius, m_yRadius, Qt::RelativeSize); break;
case Ellipse: painter->drawEllipse(QRectF(m_P1, m_P2)); break;
case Polygon: m_closed ? painter->drawPolygon(m_polygon) : painter->drawPolyline(m_polygon); break;
}
@@ -331,17 +349,16 @@
QetGraphicsItem::hoverLeaveEvent(event);
}
-/**
- * @brief QetShapeItem::mouseReleaseEvent
- * Handle mouse release event
- * @param event
- */
-void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void QetShapeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
- if (event->buttonDownPos(Qt::LeftButton) == event->pos())
+ event->ignore();
+ if (event->button() == Qt::LeftButton) {
switchResizeMode();
-
- QetGraphicsItem::mouseReleaseEvent(event);
+ event->accept();
+ }
+ else {
+ QetGraphicsItem::mousePressEvent(event);
+ }
}
/**
@@ -364,10 +381,10 @@
qDeleteAll(m_handler_vector);
m_handler_vector.clear();
}
+ m_resize_mode = 1;
}
}
- else if (change == ItemPositionHasChanged)
- {
+ else if (change == ItemPositionHasChanged) {
adjusteHandlerPos();
}
else if (change == ItemSceneHasChanged)
@@ -485,19 +502,51 @@
*/
void QetShapeItem::switchResizeMode()
{
- if (m_shapeType & (Rectangle | Ellipse))
+ if (m_shapeType == Ellipse)
{
if (m_resize_mode == 1)
{
m_resize_mode = 2;
- for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+ 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);
+ }
+ }
+ }
+ else if (m_shapeType == Rectangle)
+ {
+ 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;
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
+ addHandler();
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector) {
+ qghi->setColor(Qt::magenta);
+ }
+ }
+ else if (m_resize_mode == 3)
+ {
+ m_resize_mode = 1;
+ qDeleteAll(m_handler_vector);
+ m_handler_vector.clear();
+ addHandler();
+ for (QetGraphicsHandlerItem *qghi : m_handler_vector) {
qghi->setColor(Qt::blue);
+ }
+
}
}
}
@@ -509,10 +558,23 @@
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;
+ case Line:
+ points_vector << m_P1 << m_P2;
+ break;
+ case Rectangle:
+ if (m_resize_mode == 3) {
+ points_vector = QetGraphicsHandlerUtility::pointForRadiusRect(QRectF(m_P1, m_P2), m_xRadius, m_yRadius);
+ }
+ else {
+ 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())
@@ -536,13 +598,34 @@
*/
void QetShapeItem::adjusteHandlerPos()
{
+ if (m_handler_vector.isEmpty()) {
+ return;
+ }
+
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;
+ case Line: {
+ points_vector << m_P1 << m_P2;
+ break;
+ }
+ case Rectangle: {
+ if (m_resize_mode != 3) {
+ points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2));
+ }
+ else {
+ points_vector = QetGraphicsHandlerUtility::pointForRadiusRect(QRectF(m_P1, m_P2), m_xRadius, m_yRadius);
+ }
+ 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())
@@ -621,6 +704,11 @@
m_old_P1 = m_P1;
m_old_P2 = m_P2;
m_old_polygon = m_polygon;
+ m_old_xRadius = m_xRadius;
+ m_old_yRadius = m_yRadius;
+ if(m_xRadius == 0 && m_yRadius == 0) {
+ m_modifie_radius_equaly = true;
+ }
}
/**
@@ -650,10 +738,25 @@
setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
break;
}
- else {
+ else if (m_resize_mode == 2) {
setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
break;
}
+ else {
+ qreal radius = QetGraphicsHandlerUtility::radiusForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index);
+ if(m_modifie_radius_equaly) {
+ setXRadius(radius);
+ setYRadius(radius);
+ }
+ else if(m_vector_index == 0) {
+ setXRadius(radius);
+ }
+ else {
+ setYRadius(radius);
+ }
+ adjusteHandlerPos();
+ break;
+ }
case Ellipse:
if (m_resize_mode == 1) {
setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
@@ -682,19 +785,42 @@
Q_UNUSED(qghi);
Q_UNUSED(event);
+ m_modifie_radius_equaly = false;
+
if (diagram())
{
QPropertyUndoCommand *undo = nullptr;
- if ((m_shapeType & (Line | Rectangle | Ellipse)) && (m_P1 != m_old_P1 || m_P2 != m_old_P2))
+ if ((m_shapeType & (Line | Rectangle | Ellipse)) && ((m_P1 != m_old_P1 || m_P2 != m_old_P2) ||
+ (m_old_xRadius != XRadius() || m_old_yRadius != m_yRadius))
+ )
{
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 Line: {
+ undo = new QPropertyUndoCommand(this, "line",QLineF(m_old_P1, m_old_P2), QLineF(m_P1, m_P2));
+ break;
+ }
+ case Rectangle: {
+ if (m_resize_mode == 1 || m_resize_mode == 2) {
+ undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2).normalized());
+ }
+ else if (m_resize_mode == 3)
+ {
+ undo = new QPropertyUndoCommand(this, "xRadius", m_old_xRadius, m_xRadius);
+ QPropertyUndoCommand *undo_ = new QPropertyUndoCommand(this, "yRadius", m_old_yRadius, m_yRadius, undo);
+ undo_->setAnimated();
+ }
+ break;
+ }
+ case Ellipse: {
+ undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2).normalized());
+ break;
+ }
case Polygon: break;
}
- if (undo) undo->enableAnimation();
+ if (undo) {
+ undo->setAnimated(true, false);
+ }
}
else if (m_shapeType == Polygon && (m_polygon != m_old_polygon))
undo = new QPropertyUndoCommand(this, "polygon", m_old_polygon, m_polygon);
Modified: trunk/sources/qetgraphicsitem/qetshapeitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.h 2018-07-11 09:28:38 UTC (rev 5435)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.h 2018-07-12 10:01:34 UTC (rev 5436)
@@ -36,18 +36,23 @@
{
Q_OBJECT
- Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
- Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
- Q_PROPERTY(QRectF rect READ rect WRITE setRect)
- Q_PROPERTY(QLineF line READ line WRITE setLine)
- Q_PROPERTY(QPolygonF polygon READ polygon WRITE setPolygon)
- Q_PROPERTY(bool close READ isClosed WRITE setClosed NOTIFY closeChanged)
+ Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
+ Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
+ Q_PROPERTY(QRectF rect READ rect WRITE setRect)
+ Q_PROPERTY(QLineF line READ line WRITE setLine)
+ Q_PROPERTY(QPolygonF polygon READ polygon WRITE setPolygon)
+ Q_PROPERTY(bool close READ isClosed WRITE setClosed NOTIFY closeChanged)
+ Q_PROPERTY(qreal xRadius READ XRadius WRITE setXRadius NOTIFY XRadiusChanged)
+ Q_PROPERTY(qreal yRadius READ YRadius WRITE setYRadius NOTIFY YRadiusChanged)
signals:
void penChanged();
void brushChanged();
void closeChanged();
-
+ void XRadiusChanged();
+ void YRadiusChanged();
+
+
public:
Q_ENUMS(ShapeType)
enum ShapeType {Line =1,
@@ -86,6 +91,10 @@
bool setPolygon (const QPolygonF &polygon);
bool isClosed() const {return m_closed;}
void setClosed (bool close);
+ qreal XRadius() const {return m_xRadius;}
+ void setXRadius(qreal X);
+ qreal YRadius() const {return m_yRadius;}
+ void setYRadius(qreal Y);
//Methods available for polygon shape
int pointsCount () const;
@@ -99,7 +108,7 @@
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void hoverEnterEvent (QGraphicsSceneHoverEvent *event) override;
void hoverLeaveEvent (QGraphicsSceneHoverEvent *event) override;
- void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
+ void mousePressEvent (QGraphicsSceneMouseEvent *event) override;
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override;
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
@@ -128,10 +137,15 @@
QPolygonF m_polygon, m_old_polygon;
bool m_hovered;
int m_vector_index;
- bool m_closed = false;
+ bool m_closed = false,
+ m_modifie_radius_equaly = false;
int m_resize_mode = 1;
QVector<QetGraphicsHandlerItem *> m_handler_vector;
QAction *m_insert_point,
*m_remove_point;
+ qreal m_xRadius = 0,
+ m_yRadius = 0,
+ m_old_xRadius,
+ m_old_yRadius;
};
#endif // QETSHAPEITEM_H