Toatly revamp of the handlers use to modify primitves, shapes and conductors.

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5001 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2017-08-02 15:26:14 +00:00
parent 86cb13f74d
commit 618683d962
27 changed files with 2255 additions and 1307 deletions

View File

@@ -118,6 +118,7 @@ void AbstractPartEllipse::setRect(const QRectF &rect)
if (rect == m_rect) return;
prepareGeometryChange();
m_rect = rect;
emit rectChanged();
}

View File

@@ -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,20 +63,21 @@ class AbstractPartEllipse : public CustomElementGraphicPart
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_;
QRectF m_rect;
qreal m_start_angle;
qreal m_span_angle;
QVector<QetGraphicsHandlerItem *> m_handler_vector;
};
#endif // ABSTRACTPARTELLIPSE_H

View File

@@ -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 @@ PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent) :
* @brief PartArc::~PartArc
* Destructor
*/
PartArc::~PartArc() {
PartArc::~PartArc()
{
if(m_undo_command) delete m_undo_command;
removeHandler();
}
/**
@@ -82,15 +86,7 @@ void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options,
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 @@ void PartArc::fromXml(const QDomElement &qde) {
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 @@ QPainterPath PartArc::shape() const
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,135 +154,6 @@ QPainterPath PartArc::shadowShape() const
return (pps.createStroke(shape));
}
void PartArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
if (!isSelected())
{
CustomElementGraphicPart::hoverMoveEvent(event);
return;
}
if (m_resize_mode == 1 || m_resize_mode == 2) {
int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
if (handler >= 0)
{
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;
}
}
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;
}
}
CustomElementGraphicPart::hoverMoveEvent(event);
}
/**
* @brief PartArc::mousePressEvent
* Handle mouse press event
* @param event
*/
void PartArc::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
setCursor(Qt::ClosedHandCursor);
if (isSelected())
{
//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_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
m_undo_command->setText(tr("Modifier un arc"));
m_undo_command->enableAnimation();
return;
}
}
//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 (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;
}
}
}
}
CustomElementGraphicPart::mousePressEvent(event);
}
/**
* @brief PartArc::mouseMoveEvent
* Handle mouse move event
* @param event
*/
void PartArc::mouseMoveEvent(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();
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));
return;
}
}
else if (m_resize_mode == 3) {
if (m_handler_index == 0 || m_handler_index == 1) {
QLineF line(m_rect.center(), event->pos());
prepareGeometryChange();
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);
}
return;
}
}
CustomElementGraphicPart::mouseMoveEvent(event);
}
/**
* @brief PartArc::mouseReleaseEvent
* Handle mouse release event
@@ -308,59 +161,317 @@ void PartArc::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
*/
void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
setCursor(Qt::OpenHandCursor);
if (event->buttonDownPos(Qt::LeftButton) == event->pos())
switchResizeMode();
}
if (event->button() == Qt::LeftButton && 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();
CustomElementGraphicPart::mouseReleaseEvent(event);
}
m_undo_command->setNewValue(QVariant(m_rect));
elementScene()->undoStack().push(m_undo_command);
m_undo_command = nullptr;
m_handler_index = -1;
return;
/**
* @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)
{
//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
{
disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartArc::sceneSelectionChanged);
removeHandler();
}
}
else if (m_resize_mode == 3) {
if (m_handler_index == 0) {
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::sceneEventFilter
* @param watched
* @param event
* @return
*/
bool PartArc::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;
}
/**
* @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::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::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
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);
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();
}
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 //resize rect
{
m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
m_undo_command->setText(tr("Modifier un arc"));
m_undo_command->enableAnimation();
}
}
/**
* @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();
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);
}
}
}
/**
* @brief PartArc::handlerMouseReleaseEvent
* @param qghi
* @param event
*/
void PartArc::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
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);
}
else if (m_resize_mode == 2 ) {
m_resize_mode = 3;
m_handler.setOuterColor(Qt::magenta);
}
else {
m_resize_mode = 1;
m_handler.setOuterColor(Qt::blue);
}
update();
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);
}
}
}
/**
* @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();
}
}

View File

@@ -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 @@ class PartArc : public AbstractPartEllipse
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

View File

@@ -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 @@ PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
* @brief PartEllipse::~PartEllipse
* Destructor
*/
PartEllipse::~PartEllipse() {
PartEllipse::~PartEllipse()
{
if(m_undo_command) delete m_undo_command;
removeHandler();
}
/**
@@ -65,11 +67,7 @@ void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
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 @@ void PartEllipse::fromXml(const QDomElement &qde)
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 @@ QPainterPath PartEllipse::shape() const
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,77 +150,6 @@ QPainterPath PartEllipse::shadowShape() const
return (pps.createStroke(shape));
}
void PartEllipse::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
if (!isSelected())
{
CustomElementGraphicPart::hoverMoveEvent(event);
return;
}
int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
if (handler >= 0)
{
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
CustomElementGraphicPart::hoverMoveEvent(event);
}
/**
* @brief PartEllipse::mousePressEvent
* Handle mouse press event
* @param event
*/
void PartEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
setCursor(Qt::ClosedHandCursor);
if (isSelected())
{
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_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
m_undo_command->setText(tr("Modifier une ellipse"));
m_undo_command->enableAnimation();
return;
}
}
}
CustomElementGraphicPart::mousePressEvent(event);
}
/**
* @brief PartEllipse::mouseMoveEvent
* Handle mouse move event
* @param event
*/
void PartEllipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(m_handler_index >= 0 && m_handler_index <= 7)
{
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));
}
else
CustomElementGraphicPart::mouseMoveEvent(event);
}
/**
* @brief PartEllipse::mouseReleaseEvent
* Handle mouse release event
@@ -244,35 +157,225 @@ void PartEllipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
*/
void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
setCursor(Qt::OpenHandCursor);
if (event->buttonDownPos(Qt::LeftButton) == event->pos())
switchResizeMode();
}
if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
switchResizeMode();
CustomElementGraphicPart::mouseReleaseEvent(event);
}
if (m_handler_index >= 0 && m_handler_index <= 7)
/**
* @brief PartEllipse::itemChange
* @param change
* @param value
* @return
*/
QVariant PartEllipse::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == ItemSelectedHasChanged && scene())
{
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;
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();
}
}
else
CustomElementGraphicPart::mouseReleaseEvent(event);
else if (change == ItemPositionHasChanged)
{
adjusteHandlerPos();
}
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::sceneEventFilter
* @param watched
* @param event
* @return
*/
bool PartEllipse::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;
}
void PartEllipse::switchResizeMode()
{
if (m_resize_mode == 1) {
if (m_resize_mode == 1)
{
m_resize_mode = 2;
m_handler.setOuterColor(Qt::darkGreen);
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
qghi->setColor(Qt::darkGreen);
}
else {
else
{
m_resize_mode = 1;
m_handler.setOuterColor(Qt::blue);
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
qghi->setColor(Qt::blue);
}
}
/**
* @brief PartEllipse::adjusteHandlerPos
*/
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())
{
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 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
setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
adjusteHandlerPos();
}
/**
* @brief PartEllipse::handlerMouseReleaseEvent
* @param qghi
* @param event
*/
void PartEllipse::handlerMouseReleaseEvent(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_vector_index = -1;
}
/**
* @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();
}
/**
* @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);
}
}
}
/**
* @brief PartEllipse::removeHandler
* Remove the handlers of this item
*/
void PartEllipse::removeHandler()
{
if (!m_handler_vector.isEmpty())
{
qDeleteAll(m_handler_vector);
m_handler_vector.clear();
}
update();
}

View File

@@ -19,7 +19,6 @@
#define PART_ELLIPSE_H
#include "abstractpartellipse.h"
#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
class QPropertyUndoCommand;
@@ -55,24 +54,29 @@ class PartEllipse : public AbstractPartEllipse
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

View File

@@ -19,6 +19,7 @@
#include <cmath>
#include "elementscene.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
/**
@@ -33,14 +34,16 @@ PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent) :
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 @@ void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options,
if (m_hovered)
drawShadowShape(painter);
if (isSelected() && scene()->selectedItems().size() == 1)
m_handler.drawHandler(painter, m_handler.pointsForLine(m_line));
painter->restore();
}
@@ -140,69 +140,206 @@ void PartLine::fromXml(const QDomElement &qde) {
}
/**
* @brief PartLine::mousePressEvent
* Handle mouse press event
* @param event
* @brief PartLine::itemChange
* @param change
* @param value
* @return
*/
void PartLine::mousePressEvent(QGraphicsSceneMouseEvent *event)
QVariant PartLine::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if(event->button() == Qt::LeftButton)
if (change == ItemSelectedHasChanged && scene())
{
setCursor(Qt::ClosedHandCursor);
if (isSelected())
if (value.toBool() == true)
{
m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForLine(m_line));
//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);
}
if(m_handler_index >= 0 && m_handler_index <= 1) //User click on an handler
/**
* @brief PartLine::sceneEventFilter
* @param watched
* @param event
* @return
*/
bool PartLine::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)
{
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;
}
}
}
}
CustomElementGraphicPart::mousePressEvent(event);
return false;
}
/**
* @brief PartLine::mouseMoveEvent
* Handle pouse move event
* @param event
* @brief PartLine::adjusteHandlerPos
* Adjust the position of the handler item
*/
void PartLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
void PartLine::adjusteHandlerPos()
{
if(m_handler_index >= 0 && m_handler_index <= 1)
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())
{
QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
prepareGeometryChange();
setLine(m_handler.lineForPosAtIndex(m_line, pos_, m_handler_index));
points_vector = mapToScene(points_vector);
for (int i = 0 ; i < points_vector.size() ; ++i)
m_handler_vector.at(i)->setPos(points_vector.at(i));
}
else
CustomElementGraphicPart::mouseMoveEvent(event);
}
/**
* @brief PartLine::mouseReleaseEvent
* Handle mouse release event
* @brief PartLine::handlerMousePressEvent
* @param qghi
* @param event
*/
void PartLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
void PartLine::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, "line", QVariant(m_line));
m_undo_command->setText(tr("Modifier une ligne"));
m_undo_command->enableAnimation();
return;
}
if (m_handler_index >= 0 && m_handler_index <= 1)
{
m_undo_command->setNewValue(QVariant(m_line));
elementScene()->undoStack().push(m_undo_command);
m_undo_command = nullptr;
m_handler_index = -1;
}
/**
* @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::mouseReleaseEvent(event);
m_line.setP2(new_pos);
adjusteHandlerPos();
}
/**
* @brief PartLine::handlerMouseReleaseEvent
* @param qghi
* @param event
*/
void PartLine::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
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;
}
/**
* @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())
{
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);
}
}
}
/**
* @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();
}
}
/**
@@ -243,10 +380,6 @@ QPainterPath PartLine::shape() const
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 @@ QRectF PartLine::boundingRect() const
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 @@ void PartLine::setLine(const QLineF &line)
if (m_line == line) return;
prepareGeometryChange();
m_line = line;
adjusteHandlerPos();
emit lineChanged();
}
@@ -533,20 +664,6 @@ void PartLine::setSecondEndLength(const qreal &l)
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.

View File

@@ -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 @@ class PartLine : public CustomElementGraphicPart
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 @@ class PartLine : public CustomElementGraphicPart
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

View File

@@ -18,6 +18,7 @@
#include "partpolygon.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementscene.h"
#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
/**
@@ -29,16 +30,16 @@
PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) :
CustomElementGraphicPart(editor, parent),
m_closed(false),
m_handler(10),
m_handler_index(-1),
m_undo_command(nullptr)
{}
/**
* @brief PartPolygon::~PartPolygon
*/
PartPolygon::~PartPolygon() {
PartPolygon::~PartPolygon()
{
if(m_undo_command) delete m_undo_command;
removeHandler();
}
/**
@@ -64,9 +65,6 @@ void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
if (m_hovered)
drawShadowShape(painter);
if (isSelected() && scene()->selectedItems().size() == 1)
m_handler.drawHandler(painter, m_polygon);
}
/**
@@ -199,6 +197,7 @@ void PartPolygon::setPolygon(const QPolygonF &polygon)
if (m_polygon == polygon) return;
prepareGeometryChange();
m_polygon = polygon;
adjusteHandlerPos();
emit polygonChanged();
}
@@ -248,83 +247,195 @@ void PartPolygon::setClosed(bool close)
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)
{
m_undo_command->setNewValue(QVariant(m_polygon));
elementScene()->undoStack().push(m_undo_command);
m_undo_command = nullptr;
m_handler_index = -1;
}
/**
* @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
CustomElementGraphicPart::mouseReleaseEvent(event);
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())
{
qDeleteAll(m_handler_vector);
m_handler_vector.clear();
}
}
/**
@@ -343,10 +454,6 @@ QPainterPath PartPolygon::shape() const
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 @@ QRectF PartPolygon::boundingRect() const
r.adjust(-adjust, -adjust, adjust, adjust);
foreach(QRectF rect, m_handler.handlerRect(m_polygon))
r |=rect;
return(r);
}

View File

@@ -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 @@ class PartPolygon : public CustomElementGraphicPart
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

View File

@@ -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,16 +29,16 @@
*/
PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) :
CustomElementGraphicPart(editor, parent),
m_handler(10),
m_handler_index(-1),
m_undo_command(nullptr)
{}
/**
* @brief PartRectangle::~PartRectangle
*/
PartRectangle::~PartRectangle() {
PartRectangle::~PartRectangle()
{
if(m_undo_command) delete m_undo_command;
removeHandler();
}
/**
@@ -69,11 +71,7 @@ void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt
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 @@ void PartRectangle::setRect(const QRectF &rect)
if (rect == m_rect) return;
prepareGeometryChange();
m_rect = rect;
adjusteHandlerPos();
emit rectChanged();
}
@@ -164,10 +163,6 @@ QPainterPath PartRectangle::shape() const
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 PartRectangle::boundingRect() const
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,77 +229,6 @@ void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rec
setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
}
void PartRectangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
if (!isSelected())
{
CustomElementGraphicPart::hoverMoveEvent(event);
return;
}
int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
if (handler >= 0)
{
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
CustomElementGraphicPart::hoverMoveEvent(event);
}
/**
* @brief PartRectangle::mousePressEvent
* Handle mouse press event
* @param event
*/
void PartRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
setCursor(Qt::ClosedHandCursor);
if(isSelected())
{
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_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
m_undo_command->setText(tr("Modifier un rectangle"));
m_undo_command->enableAnimation();
return;
}
}
}
CustomElementGraphicPart::mousePressEvent(event);
}
/**
* @brief PartRectangle::mouseMoveEvent
* Handle mouse press event
* @param event
*/
void PartRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(m_handler_index >= 0 && m_handler_index <= 7)
{
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));
}
else
CustomElementGraphicPart::mouseMoveEvent(event);
}
/**
* @brief PartRectangle::mouseReleaseEvent
* Handle mouse release event
@@ -315,35 +236,223 @@ void PartRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
*/
void PartRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
setCursor(Qt::OpenHandCursor);
if (event->buttonDownPos(Qt::LeftButton) == event->pos())
switchResizeMode();
}
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;
}
else
CustomElementGraphicPart::mouseReleaseEvent(event);
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())
{
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();
}
}
else if (change == ItemPositionHasChanged)
{
adjusteHandlerPos();
}
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::sceneEventFilter
* @param watched
* @param event
* @return
*/
bool PartRectangle::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;
}
/**
* @brief PartRectangle::switchResizeMode
*/
void PartRectangle::switchResizeMode()
{
if (m_resize_mode == 1) {
if (m_resize_mode == 1)
{
m_resize_mode = 2;
m_handler.setOuterColor(Qt::darkGreen);
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
qghi->setColor(Qt::darkGreen);
}
else {
else
{
m_resize_mode = 1;
m_handler.setOuterColor(Qt::blue);
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
qghi->setColor(Qt::blue);
}
}
/**
* @brief PartRectangle::adjusteHandlerPos
*/
void PartRectangle::adjusteHandlerPos()
{
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));
}
}
/**
* @brief PartRectangle::handlerMousePressEvent
* @param qghi
* @param event
*/
void PartRectangle::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 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
setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
adjusteHandlerPos();
}
void PartRectangle::handlerMouseReleaseEvent(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_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);
}
}
}
/**
* @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();
}

View File

@@ -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 @@ class PartRectangle : public CustomElementGraphicPart
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