mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 20:50:34 +01:00
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:
@@ -21,6 +21,3 @@ part terminal + 1106
|
||||
part text + 1107
|
||||
part text field + 1108
|
||||
part rectangle + 1109
|
||||
|
||||
###QetGraphicsHandlerItem###
|
||||
QetGraphicsHandlerItem = 1200
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
HEADERS += \
|
||||
$$PWD/qetgraphicshandlerutility.h
|
||||
$$PWD/qetgraphicshandlerutility.h \
|
||||
$$PWD/qetgraphicshandleritem.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qetgraphicshandlerutility.cpp
|
||||
$$PWD/qetgraphicshandlerutility.cpp \
|
||||
$$PWD/qetgraphicshandleritem.cpp
|
||||
|
||||
99
sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp
Normal file
99
sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qetgraphicshandleritem.h"
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerItem::QetGraphicsHandlerItem
|
||||
* @param size, the size of the handler
|
||||
*/
|
||||
QetGraphicsHandlerItem::QetGraphicsHandlerItem(qreal size) :
|
||||
m_size(size)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerItem::boundingRect
|
||||
* @return
|
||||
*/
|
||||
QRectF QetGraphicsHandlerItem::boundingRect() const
|
||||
{
|
||||
qreal rect_size = m_size * m_previous_zoom_factor;
|
||||
QRectF rect(0-rect_size/2, 0-rect_size/2, rect_size, rect_size);
|
||||
rect.adjust(-2, -2, 2, 2);
|
||||
return rect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerItem::setColor
|
||||
* @param color, set the color of the handler
|
||||
*/
|
||||
void QetGraphicsHandlerItem::setColor(QColor color)
|
||||
{
|
||||
m_color = color;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerItem::paint
|
||||
* @param painter
|
||||
* @param option
|
||||
* @param widget
|
||||
*/
|
||||
void QetGraphicsHandlerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
qreal zoom_factor = 1.0/painter->transform().m11();
|
||||
if(zoom_factor != m_previous_zoom_factor)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
m_previous_zoom_factor = zoom_factor;
|
||||
}
|
||||
|
||||
qreal rect_size = m_size * m_previous_zoom_factor;
|
||||
QRectF rect(0-rect_size/2, 0-rect_size/2, rect_size, rect_size);
|
||||
|
||||
painter->save();
|
||||
painter->setBrush(QBrush(m_color));
|
||||
QPen pen(QBrush(m_color), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
|
||||
pen.setCosmetic(true);
|
||||
painter->setPen(pen);
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
painter->drawEllipse(rect);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerItem::handlerForPoint
|
||||
* @param points
|
||||
* @return A list of handler with pos at point
|
||||
*/
|
||||
QVector<QetGraphicsHandlerItem *> QetGraphicsHandlerItem::handlerForPoint(const QVector<QPointF> &points, int size)
|
||||
{
|
||||
QVector <QetGraphicsHandlerItem *> list_;
|
||||
for (QPointF point : points)
|
||||
{
|
||||
QetGraphicsHandlerItem *qghi = new QetGraphicsHandlerItem(size);
|
||||
qghi->setPos(point);
|
||||
list_ << qghi;
|
||||
}
|
||||
|
||||
return list_;
|
||||
}
|
||||
53
sources/QetGraphicsItemModeler/qetgraphicshandleritem.h
Normal file
53
sources/QetGraphicsItemModeler/qetgraphicshandleritem.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef QETGRAPHICSHANDLERITEM_H
|
||||
#define QETGRAPHICSHANDLERITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
/**
|
||||
* @brief The QetGraphicsHandlerItem class
|
||||
* This graphics item represents a point, destined to be used as an handler,
|
||||
* for modifie the geometrie of a another graphics item (like shapes).
|
||||
* The graphics item to be modified, must call "installSceneEventFilter" of this item with itself for argument,.
|
||||
* The ghraphics item to be modified, need to reimplement "sceneEventFilter" for create the modification behavior.
|
||||
*/
|
||||
class QetGraphicsHandlerItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
QetGraphicsHandlerItem(qreal size = 15);
|
||||
virtual QRectF boundingRect() const;
|
||||
|
||||
enum { Type = UserType + 1200};
|
||||
virtual int type() const {return Type;}
|
||||
|
||||
void setColor(QColor color);
|
||||
|
||||
protected:
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
private:
|
||||
qreal m_size,
|
||||
m_previous_zoom_factor = 1;
|
||||
QColor m_color;
|
||||
|
||||
public:
|
||||
static QVector<QetGraphicsHandlerItem *> handlerForPoint(const QVector<QPointF> &points, int size = 15);
|
||||
};
|
||||
|
||||
#endif // QETGRAPHICSHANDLERITEM_H
|
||||
@@ -16,111 +16,10 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qetgraphicshandlerutility.h"
|
||||
#include <QPainter>
|
||||
//#include <QVector>
|
||||
//#include <QPointF>
|
||||
#include <QPainterPath>
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::QetGraphicsHandlerUtility
|
||||
* Constructor
|
||||
* @param size : the size of the handler
|
||||
*/
|
||||
QetGraphicsHandlerUtility::QetGraphicsHandlerUtility(qreal size) :
|
||||
m_size (size)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::drawHandler
|
||||
* Draw the handler at pos @point, using the QPainter @painter.
|
||||
* @param painter : painter to use for drawing the handler
|
||||
* @param point : point to draw the handler
|
||||
*/
|
||||
void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QPointF &point)
|
||||
{
|
||||
//Setup the zoom factor to draw the handler in the same size at screen,
|
||||
//no matter the zoom of the QPainter
|
||||
m_zoom_factor = 1.0/painter->transform().m11();
|
||||
|
||||
painter->save();
|
||||
painter->setBrush(QBrush(m_inner_color));
|
||||
QPen square_pen(QBrush(m_outer_color), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
|
||||
square_pen.setCosmetic(true);
|
||||
painter->setPen(square_pen);
|
||||
painter->drawRect(getRect(point));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::drawHandler
|
||||
* Conveniance method for void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QPointF &point)
|
||||
* @param painter
|
||||
* @param points
|
||||
* @param color2
|
||||
*/
|
||||
void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QVector<QPointF> &points) {
|
||||
foreach(QPointF point, points)
|
||||
drawHandler(painter, point);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::pointIsInHandler
|
||||
* @param point : point to compare
|
||||
* @param key_point : point at the center of handler (the point to modify, for exemple the corner of a rectangle)
|
||||
* @return true if point is in a handler. else false
|
||||
*/
|
||||
bool QetGraphicsHandlerUtility::pointIsInHandler(const QPointF &point, const QPointF &key_point) const {
|
||||
return (getRect(key_point).contains(point));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::pointIsHoverHandler
|
||||
* @param point : point to compare
|
||||
* @param vector : vector of key_point (the point to modify, for exemple the corners of a rectangle)
|
||||
* @return if point is hover an handler, return the index of the hovered key_point in the vector, else return -1
|
||||
*/
|
||||
int QetGraphicsHandlerUtility::pointIsHoverHandler(const QPointF &point, const QVector<QPointF> &vector) const
|
||||
{
|
||||
foreach (QPointF key_point, vector)
|
||||
if (pointIsInHandler(point, key_point))
|
||||
return vector.indexOf(key_point);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::handlerRect
|
||||
* Return the rect of the handler for all key_point in vector (the point to modify, for exemple the corners of a rectangle)
|
||||
* The order of rect in the returned vector is the same as the given vector.
|
||||
* @param vector
|
||||
* @return
|
||||
*/
|
||||
QVector<QRectF> QetGraphicsHandlerUtility::handlerRect(const QVector<QPointF> &vector) const
|
||||
{
|
||||
QVector <QRectF> rect_vector;
|
||||
|
||||
foreach(QPointF point, vector)
|
||||
rect_vector << getRect(point);
|
||||
|
||||
return rect_vector;
|
||||
}
|
||||
|
||||
void QetGraphicsHandlerUtility::setInnerColor(QColor color) {
|
||||
m_inner_color = color;
|
||||
}
|
||||
|
||||
void QetGraphicsHandlerUtility::setOuterColor(QColor color) {
|
||||
m_outer_color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::getRect
|
||||
* @param point
|
||||
* @return
|
||||
*/
|
||||
QRectF QetGraphicsHandlerUtility::getRect(const QPointF &point) const
|
||||
{
|
||||
qreal rect_size = m_size * m_zoom_factor;
|
||||
QRectF rect(point.x() - rect_size/2, point.y() - rect_size/2, rect_size, rect_size);
|
||||
return rect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::pointsForRect
|
||||
@@ -169,7 +68,6 @@ QVector<QPointF> QetGraphicsHandlerUtility::pointsForLine(const QLineF &line) {
|
||||
return (QVector<QPointF> {line.p1(), line.p2()});
|
||||
}
|
||||
|
||||
#include <QDebug>
|
||||
/**
|
||||
* @brief QetGraphicsHandlerUtility::pointsForArc
|
||||
* Return the points for the given arc.
|
||||
|
||||
@@ -32,25 +32,6 @@ class QPainter;
|
||||
*/
|
||||
class QetGraphicsHandlerUtility
|
||||
{
|
||||
public:
|
||||
QetGraphicsHandlerUtility (qreal size = 1);
|
||||
void setSize(qreal size) {m_size = size;}
|
||||
void drawHandler (QPainter *painter, const QPointF & point);
|
||||
void drawHandler(QPainter *painter, const QVector<QPointF> &points);
|
||||
QPointF posForHandler(const QPointF &point) const;
|
||||
bool pointIsInHandler (const QPointF &point, const QPointF &key_point) const;
|
||||
int pointIsHoverHandler (const QPointF &point, const QVector<QPointF> &vector) const;
|
||||
QVector<QRectF> handlerRect (const QVector<QPointF> &vector) const;
|
||||
void setInnerColor (QColor color);
|
||||
void setOuterColor (QColor color);
|
||||
|
||||
private:
|
||||
QRectF getRect (const QPointF &point) const;
|
||||
qreal m_size;
|
||||
qreal m_zoom_factor = 1;
|
||||
QColor m_inner_color = Qt::white,
|
||||
m_outer_color = Qt::blue;
|
||||
|
||||
public:
|
||||
static QVector <QPointF> pointsForRect (const QRectF &rect);
|
||||
static QVector <QPointF> pointsForLine (const QLineF &line);
|
||||
|
||||
@@ -91,10 +91,7 @@ Diagram::Diagram(QETProject *project) :
|
||||
* @brief Diagram::~Diagram
|
||||
* Destructor
|
||||
*/
|
||||
Diagram::~Diagram()
|
||||
{
|
||||
//First clear every selection to close an hypothetical editor
|
||||
clearSelection();
|
||||
Diagram::~Diagram() {
|
||||
// clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
|
||||
undoStack().clear();
|
||||
//delete of QGIManager, every elements he knows are removed
|
||||
@@ -106,15 +103,19 @@ Diagram::~Diagram()
|
||||
delete elements_mover_;
|
||||
delete element_texts_mover_;
|
||||
|
||||
if (m_event_interface)
|
||||
delete m_event_interface;
|
||||
if (m_event_interface) delete m_event_interface;
|
||||
|
||||
// list removable items
|
||||
QList<QGraphicsItem *> deletable_items;
|
||||
for(QGraphicsItem *qgi : items())
|
||||
{
|
||||
if (qgi -> parentItem()) continue;
|
||||
if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
|
||||
if (qgi->parentItem())
|
||||
continue;
|
||||
if (qgi->type() == Conductor::Type)
|
||||
continue;
|
||||
if (qgi->type() == QetGraphicsHandlerItem::Type)
|
||||
continue;
|
||||
|
||||
deletable_items << qgi;
|
||||
}
|
||||
|
||||
@@ -377,6 +378,8 @@ void Diagram::keyReleaseEvent(QKeyEvent *e)
|
||||
* Diagram become the ownership of event_interface
|
||||
* If there is a previous interface, they will be delete before
|
||||
* and call init() to the new interface.
|
||||
* The derivated class of DiagramEventInterface need to emit the signal "finish" when the job is done,
|
||||
* diagram use this signal to delete the interface. If the signal isn't send, the interface will never be deleted.
|
||||
* @param event_interface
|
||||
*/
|
||||
void Diagram::setEventInterface(DiagramEventInterface *event_interface)
|
||||
|
||||
@@ -24,23 +24,24 @@
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
#include <QGraphicsScene>
|
||||
#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
|
||||
|
||||
/**
|
||||
Constructor
|
||||
@param parent Parent QGraphicsItem
|
||||
*/
|
||||
ElementPrimitiveDecorator::ElementPrimitiveDecorator(QGraphicsItem *parent):
|
||||
QGraphicsObject(parent),
|
||||
m_handler(10)
|
||||
QGraphicsObject(parent)
|
||||
{
|
||||
init();
|
||||
m_handler.setOuterColor(Qt::darkGreen);
|
||||
}
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
ElementPrimitiveDecorator::~ElementPrimitiveDecorator() {
|
||||
ElementPrimitiveDecorator::~ElementPrimitiveDecorator()
|
||||
{
|
||||
removeHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,12 +69,7 @@ QRectF ElementPrimitiveDecorator::internalBoundingRect() const {
|
||||
*/
|
||||
QRectF ElementPrimitiveDecorator::boundingRect() const
|
||||
{
|
||||
QVector<QRectF> rect_vector = m_handler.handlerRect(getResizingsPoints());
|
||||
|
||||
QRectF rect = effective_bounding_rect_;
|
||||
rect |= rect_vector.first();
|
||||
rect |= rect_vector.last();
|
||||
return(rect);
|
||||
return effective_bounding_rect_;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,9 +93,6 @@ void ElementPrimitiveDecorator::paint(QPainter *painter, const QStyleOptionGraph
|
||||
painter -> setPen(pen);
|
||||
painter -> drawRect(modified_bounding_rect_);
|
||||
|
||||
//Draw the handlers
|
||||
m_handler.drawHandler(painter, getResizingsPoints());
|
||||
|
||||
// uncomment to draw the real bouding rect (=adjusted internal bounding rect)
|
||||
// painter -> setBrush(QBrush(QColor(240, 0, 0, 127)));
|
||||
// painter -> drawRect(boundingRect());
|
||||
@@ -118,15 +111,19 @@ void ElementPrimitiveDecorator::setItems(const QList<CustomElementPart *> &items
|
||||
if (focusItem() != this) {
|
||||
setFocus();
|
||||
}
|
||||
adjusteHandlerPos();
|
||||
}
|
||||
|
||||
/**
|
||||
@param items the new list of items this decorator is suposed to manipulate.
|
||||
*/
|
||||
void ElementPrimitiveDecorator::setItems(const QList<QGraphicsItem *> &items) {
|
||||
void ElementPrimitiveDecorator::setItems(const QList<QGraphicsItem *> &items)
|
||||
{
|
||||
QList<CustomElementPart *> primitives;
|
||||
foreach (QGraphicsItem *item, items) {
|
||||
if (CustomElementPart *part_item = dynamic_cast<CustomElementPart *>(item)) {
|
||||
for(QGraphicsItem *item : items)
|
||||
{
|
||||
if (CustomElementPart *part_item = dynamic_cast<CustomElementPart *>(item))
|
||||
{
|
||||
primitives << part_item;
|
||||
}
|
||||
}
|
||||
@@ -157,72 +154,31 @@ QList<QGraphicsItem *> ElementPrimitiveDecorator::graphicsItems() const {
|
||||
Adjust the visual decorator according to the currently assigned items.
|
||||
It is notably called by setItems().
|
||||
*/
|
||||
void ElementPrimitiveDecorator::adjust() {
|
||||
void ElementPrimitiveDecorator::adjust()
|
||||
{
|
||||
saveOriginalBoundingRect();
|
||||
modified_bounding_rect_ = original_bounding_rect_;
|
||||
adjustEffectiveBoundingRect();
|
||||
}
|
||||
|
||||
/**
|
||||
Handle events generated when the mouse hovers over the decorator.
|
||||
@param event Object describing the hover event.
|
||||
*/
|
||||
void ElementPrimitiveDecorator::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
int p = m_handler.pointIsHoverHandler(event->pos(), getResizingsPoints());
|
||||
|
||||
if (p == 0 || p == 7)
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
else if (p == 2 || p == 5)
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
else if (p == 1 || p ==6)
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
else if (p == 3 || p == 4)
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
else if (p == -1 && modified_bounding_rect_.normalized().contains(event->pos()))
|
||||
setCursor(Qt::SizeAllCursor);
|
||||
else
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
/**
|
||||
Handle event generated when mouse buttons are pressed.
|
||||
@param event Object describing the mouse event
|
||||
*/
|
||||
void ElementPrimitiveDecorator::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QPointF pos = event -> pos();
|
||||
QVector <QPointF> points = getResizingsPoints();
|
||||
|
||||
current_operation_square_ = m_handler.pointIsHoverHandler(pos, points);
|
||||
bool accept = false;
|
||||
|
||||
if (current_operation_square_ != QET::NoOperation)
|
||||
accept = true;
|
||||
else
|
||||
{
|
||||
if (internalBoundingRect().contains(pos))
|
||||
if (internalBoundingRect().contains(event->pos()))
|
||||
{
|
||||
current_operation_square_ = QET::MoveArea;
|
||||
accept = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (accept)
|
||||
{
|
||||
if (current_operation_square_ > QET::NoOperation)
|
||||
first_pos_ = latest_pos_ = mapToScene(points.at(current_operation_square_));
|
||||
else
|
||||
{
|
||||
first_pos_ = decorated_items_.at(0) -> toItem() -> scenePos();
|
||||
latest_pos_ = event -> scenePos();
|
||||
mouse_offset_ = event -> scenePos() - first_pos_;
|
||||
}
|
||||
startMovement();
|
||||
event -> accept();
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
event -> ignore();
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,46 +191,12 @@ void ElementPrimitiveDecorator::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
QPointF scene_pos = event -> scenePos();
|
||||
QPointF movement = scene_pos - latest_pos_;
|
||||
|
||||
if (current_operation_square_ > QET::NoOperation) {
|
||||
// This is a scaling operation.
|
||||
|
||||
// For convenience purposes, we may need to adjust mouse movements.
|
||||
QET::ScalingMethod scaling_method = scalingMethod(event);
|
||||
if (scaling_method > QET::FreeScaling) {
|
||||
// real, non-rounded movement from the mouse press event
|
||||
QPointF global_movement = scene_pos - first_pos_;
|
||||
|
||||
QPointF rounded_global_movement;
|
||||
if (scaling_method == QET::SnapScalingPointToGrid) {
|
||||
// real, rounded movement from the mouse press event
|
||||
rounded_global_movement = snapConstPointToGrid(global_movement);
|
||||
}
|
||||
else {
|
||||
QRectF new_bounding_rect = original_bounding_rect_;
|
||||
applyMovementToRect(current_operation_square_, global_movement, new_bounding_rect);
|
||||
|
||||
const qreal scale_epsilon = 20.0; // rounds to 0.05
|
||||
QPointF delta = deltaForRoundScaling(original_bounding_rect_, new_bounding_rect, scale_epsilon);
|
||||
|
||||
// real, rounded movement from the mouse press event
|
||||
rounded_global_movement = global_movement + delta;
|
||||
}
|
||||
|
||||
// rounded position of the current mouse move event
|
||||
QPointF rounded_scene_pos = first_pos_ + rounded_global_movement;
|
||||
|
||||
// when scaling the selection, consider the center of the currently dragged resizing rectangle
|
||||
QPointF current_position = mapToScene(getResizingsPoints().at(current_operation_square_));
|
||||
// determine the final, effective movement
|
||||
movement = rounded_scene_pos - current_position;
|
||||
}
|
||||
}
|
||||
else if (current_operation_square_ == QET::MoveArea) {
|
||||
if (current_operation_square_ == QET::MoveArea)
|
||||
{
|
||||
// When moving the selection, consider the position of the first selected item
|
||||
QPointF current_position = scene_pos - mouse_offset_;
|
||||
QPointF rounded_current_position = snapConstPointToGrid(current_position);
|
||||
movement = rounded_current_position - decorated_items_.at(0) -> toItem() -> scenePos();
|
||||
}
|
||||
|
||||
QRectF bounding_rect = modified_bounding_rect_;
|
||||
applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
|
||||
@@ -282,12 +204,12 @@ void ElementPrimitiveDecorator::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
adjustEffectiveBoundingRect();
|
||||
}
|
||||
latest_pos_ = event -> scenePos();
|
||||
|
||||
if (current_operation_square_ == QET::MoveArea) {
|
||||
translateItems(movement);
|
||||
} else {
|
||||
scaleItems(original_bounding_rect_, modified_bounding_rect_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,31 +218,25 @@ void ElementPrimitiveDecorator::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
@param event Object describing the mouse event
|
||||
@see QGraphicsScene::mouseGrabberItem()
|
||||
*/
|
||||
void ElementPrimitiveDecorator::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||
void ElementPrimitiveDecorator::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
ElementEditionCommand *command = 0;
|
||||
if (current_operation_square_ > QET::NoOperation) {
|
||||
ScalePartsCommand *scale_command = new ScalePartsCommand();
|
||||
scale_command -> setScaledPrimitives(items());
|
||||
scale_command -> setTransformation(
|
||||
mapToScene(original_bounding_rect_).boundingRect(),
|
||||
mapToScene(modified_bounding_rect_).boundingRect()
|
||||
);
|
||||
command = scale_command;
|
||||
} else if (current_operation_square_ == QET::MoveArea) {
|
||||
|
||||
if (current_operation_square_ == QET::MoveArea)
|
||||
{
|
||||
QPointF movement = mapToScene(modified_bounding_rect_.topLeft()) - mapToScene(original_bounding_rect_.topLeft());
|
||||
if (!movement.isNull()) {
|
||||
if (!movement.isNull())
|
||||
{
|
||||
MovePartsCommand *move_command = new MovePartsCommand(movement, 0, graphicsItems());
|
||||
command = move_command;
|
||||
}
|
||||
}
|
||||
|
||||
if (command) {
|
||||
emit(actionFinished(command));
|
||||
}
|
||||
|
||||
if (current_operation_square_ != QET::NoOperation) {
|
||||
adjust();
|
||||
}
|
||||
|
||||
@@ -376,7 +292,8 @@ void ElementPrimitiveDecorator::keyReleaseEvent(QKeyEvent *e) {
|
||||
/**
|
||||
Initialize an ElementPrimitiveDecorator
|
||||
*/
|
||||
void ElementPrimitiveDecorator::init() {
|
||||
void ElementPrimitiveDecorator::init()
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemIsFocusable, true);
|
||||
grid_step_x_ = grid_step_y_ = 1;
|
||||
setAcceptHoverEvents(true);
|
||||
@@ -397,6 +314,7 @@ void ElementPrimitiveDecorator::adjustEffectiveBoundingRect() {
|
||||
prepareGeometryChange();
|
||||
effective_bounding_rect_ = modified_bounding_rect_ | effective_bounding_rect_;
|
||||
update();
|
||||
adjusteHandlerPos();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,6 +446,152 @@ QVector<QPointF> ElementPrimitiveDecorator::getResizingsPoints() const
|
||||
return vector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::adjusteHandlerPos
|
||||
*/
|
||||
void ElementPrimitiveDecorator::adjusteHandlerPos()
|
||||
{
|
||||
QVector <QPointF> points_vector = mapToScene(getResizingsPoints());
|
||||
for (int i = 0 ; i < points_vector.size() ; ++i)
|
||||
m_handler_vector.at(i)->setPos(points_vector.at(i));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::handlerMousePressEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void ElementPrimitiveDecorator::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QVector <QPointF> points = getResizingsPoints();
|
||||
|
||||
current_operation_square_ = m_handler_vector.indexOf(qghi);
|
||||
|
||||
first_pos_ = latest_pos_ = mapToScene(points.at(current_operation_square_));
|
||||
startMovement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::handlerMouseMoveEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void ElementPrimitiveDecorator::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(qghi);
|
||||
|
||||
QPointF scene_pos = event -> scenePos();
|
||||
QPointF movement = scene_pos - latest_pos_;
|
||||
|
||||
// For convenience purposes, we may need to adjust mouse movements.
|
||||
QET::ScalingMethod scaling_method = scalingMethod(event);
|
||||
if (scaling_method > QET::FreeScaling)
|
||||
{
|
||||
// real, non-rounded movement from the mouse press event
|
||||
QPointF global_movement = scene_pos - first_pos_;
|
||||
|
||||
QPointF rounded_global_movement;
|
||||
if (scaling_method == QET::SnapScalingPointToGrid)
|
||||
{
|
||||
// real, rounded movement from the mouse press event
|
||||
rounded_global_movement = snapConstPointToGrid(global_movement);
|
||||
}
|
||||
else
|
||||
{
|
||||
QRectF new_bounding_rect = original_bounding_rect_;
|
||||
applyMovementToRect(current_operation_square_, global_movement, new_bounding_rect);
|
||||
|
||||
const qreal scale_epsilon = 20.0; // rounds to 0.05
|
||||
QPointF delta = deltaForRoundScaling(original_bounding_rect_, new_bounding_rect, scale_epsilon);
|
||||
|
||||
// real, rounded movement from the mouse press event
|
||||
rounded_global_movement = global_movement + delta;
|
||||
}
|
||||
|
||||
// rounded position of the current mouse move event
|
||||
QPointF rounded_scene_pos = first_pos_ + rounded_global_movement;
|
||||
|
||||
// when scaling the selection, consider the center of the currently dragged resizing rectangle
|
||||
QPointF current_position = mapToScene(getResizingsPoints().at(current_operation_square_));
|
||||
// determine the final, effective movement
|
||||
movement = rounded_scene_pos - current_position;
|
||||
}
|
||||
|
||||
QRectF bounding_rect = modified_bounding_rect_;
|
||||
applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
|
||||
if (modified_bounding_rect_ != bounding_rect) {
|
||||
adjustEffectiveBoundingRect();
|
||||
}
|
||||
latest_pos_ = event -> scenePos();
|
||||
scaleItems(original_bounding_rect_, modified_bounding_rect_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::handlerMouseReleaseEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void ElementPrimitiveDecorator::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
ElementEditionCommand *command = 0;
|
||||
if (current_operation_square_ > QET::NoOperation)
|
||||
{
|
||||
ScalePartsCommand *scale_command = new ScalePartsCommand();
|
||||
scale_command -> setScaledPrimitives(items());
|
||||
scale_command -> setTransformation(
|
||||
mapToScene(original_bounding_rect_).boundingRect(),
|
||||
mapToScene(modified_bounding_rect_).boundingRect()
|
||||
);
|
||||
command = scale_command;
|
||||
}
|
||||
|
||||
if (command) {
|
||||
emit(actionFinished(command));
|
||||
}
|
||||
|
||||
adjust();
|
||||
|
||||
current_operation_square_ = QET::NoOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::addHandler
|
||||
* Add handlers for this item
|
||||
*/
|
||||
void ElementPrimitiveDecorator::addHandler()
|
||||
{
|
||||
if (m_handler_vector.isEmpty() && scene())
|
||||
{
|
||||
m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapFromScene(getResizingsPoints()));
|
||||
|
||||
for(QetGraphicsHandlerItem *handler : m_handler_vector)
|
||||
{
|
||||
scene()->addItem(handler);
|
||||
handler->setColor(Qt::darkGreen);
|
||||
handler->installSceneEventFilter(this);
|
||||
handler->setZValue(this->zValue()+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::removeHandler
|
||||
* Remove the handlers of this item
|
||||
*/
|
||||
void ElementPrimitiveDecorator::removeHandler()
|
||||
{
|
||||
if (!m_handler_vector.isEmpty())
|
||||
{
|
||||
qDeleteAll(m_handler_vector);
|
||||
m_handler_vector.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Receive two rects, assuming they share a common corner and current is a \a
|
||||
scaled version of \a original.
|
||||
@@ -597,3 +661,73 @@ QET::ScalingMethod ElementPrimitiveDecorator::scalingMethod(QGraphicsSceneMouseE
|
||||
}
|
||||
return QET::RoundScaleRatios;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::itemChange
|
||||
* @param change
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
QVariant ElementPrimitiveDecorator::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemSceneHasChanged)
|
||||
{
|
||||
if(scene()) //Item is added to scene, we also add handlers
|
||||
addHandler();
|
||||
else //Item is removed from scene, we also remove the handlers
|
||||
removeHandler();
|
||||
}
|
||||
else if (change == ItemVisibleHasChanged)
|
||||
{
|
||||
bool visible = value.toBool();
|
||||
for(QetGraphicsHandlerItem *qghi : m_handler_vector)
|
||||
qghi->setVisible(visible);
|
||||
}
|
||||
else if (change == ItemZValueHasChanged && !m_handler_vector.isEmpty())
|
||||
{
|
||||
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
|
||||
qghi->setZValue(this->zValue()+1);
|
||||
}
|
||||
|
||||
return QGraphicsObject::itemChange(change, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ElementPrimitiveDecorator::sceneEventFilter
|
||||
* @param watched
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
bool ElementPrimitiveDecorator::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
|
||||
{
|
||||
//Watched must be an handler
|
||||
if(watched->type() == QetGraphicsHandlerItem::Type)
|
||||
{
|
||||
QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
|
||||
|
||||
if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
|
||||
{
|
||||
m_vector_index = m_handler_vector.indexOf(qghi);
|
||||
if (m_vector_index != -1)
|
||||
{
|
||||
if(event->type() == QEvent::GraphicsSceneMousePress) //Click
|
||||
{
|
||||
handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
|
||||
return true;
|
||||
}
|
||||
else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
|
||||
{
|
||||
handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
|
||||
return true;
|
||||
}
|
||||
else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
|
||||
{
|
||||
handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
|
||||
#include <QGraphicsObject>
|
||||
#include "qet.h"
|
||||
#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
|
||||
|
||||
class ElementEditionCommand;
|
||||
class ElementScene;
|
||||
class CustomElementPart;
|
||||
class QetGraphicsHandlerItem;
|
||||
|
||||
/**
|
||||
This class represents a decorator rendered above selected items so users
|
||||
@@ -64,7 +64,6 @@ class ElementPrimitiveDecorator : public QGraphicsObject
|
||||
void actionFinished(ElementEditionCommand *);
|
||||
|
||||
protected:
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
|
||||
@@ -75,6 +74,8 @@ class ElementPrimitiveDecorator : public QGraphicsObject
|
||||
void snapPointToGrid(QPointF &) const;
|
||||
bool mustSnapToGrid(QGraphicsSceneMouseEvent *);
|
||||
QET::ScalingMethod scalingMethod(QGraphicsSceneMouseEvent *);
|
||||
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
void init();
|
||||
@@ -88,8 +89,19 @@ class ElementPrimitiveDecorator : public QGraphicsObject
|
||||
QRectF getSceneBoundingRect(QGraphicsItem *) const;
|
||||
QVector <QPointF> getResizingsPoints() const;
|
||||
|
||||
// attributes
|
||||
|
||||
private:
|
||||
void adjusteHandlerPos();
|
||||
void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
|
||||
void addHandler();
|
||||
void removeHandler();
|
||||
|
||||
|
||||
|
||||
|
||||
QList<CustomElementPart *> decorated_items_;
|
||||
QRectF effective_bounding_rect_; ///< actual, effective bounding rect -- never shrinks
|
||||
QRectF original_bounding_rect_; ///< original bounding rect
|
||||
@@ -107,7 +119,8 @@ class ElementPrimitiveDecorator : public QGraphicsObject
|
||||
QPointF mouse_offset_; ///< Offset between the mouse position and the point to be snapped to grid when moving selection
|
||||
bool moving_by_keys_; ///< Whether we are currently moving our decorated items using the arrow keys
|
||||
QPointF keys_movement_; ///< Movement applied to our decorated items using the arrow keys
|
||||
QetGraphicsHandlerUtility m_handler;
|
||||
QVector<QetGraphicsHandlerItem *> m_handler_vector;
|
||||
int m_vector_index = -1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
#include "nameslist.h"
|
||||
#include "ui/elementpropertieseditorwidget.h"
|
||||
#include "eseventinterface.h"
|
||||
#include <algorithm>
|
||||
#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <QKeyEvent>
|
||||
|
||||
/**
|
||||
@@ -524,27 +525,45 @@ QETElementEditor* ElementScene::editor() const {
|
||||
}
|
||||
|
||||
/**
|
||||
Selectionne une liste de parties
|
||||
@param content liste des parties a selectionner
|
||||
*/
|
||||
void ElementScene::slot_select(const ElementContent &content) {
|
||||
* @brief ElementScene::slot_select
|
||||
* Select the item in content, every others items in the scene are deselected
|
||||
* @param content
|
||||
*/
|
||||
void ElementScene::slot_select(const ElementContent &content)
|
||||
{
|
||||
blockSignals(true);
|
||||
|
||||
//Befor clear selection, we must to remove the handlers items in @content,
|
||||
//because if in @content there are a selected item, but also its handlers items,
|
||||
//When item is deselected, the item delete its handlers items,
|
||||
//then handlers in content doesn't exist anymore and cause segfault
|
||||
QList<QGraphicsItem*> items_list;
|
||||
for (QGraphicsItem *qgi : content)
|
||||
{
|
||||
if(qgi->type() != QetGraphicsHandlerItem::Type)
|
||||
items_list << qgi;
|
||||
}
|
||||
clearSelection();
|
||||
foreach(QGraphicsItem *qgi, content) qgi -> setSelected(true);
|
||||
|
||||
foreach(QGraphicsItem *qgi, items_list)
|
||||
qgi -> setSelected(true);
|
||||
|
||||
blockSignals(false);
|
||||
emit(selectionChanged());
|
||||
}
|
||||
|
||||
/**
|
||||
Selectionne tout
|
||||
*/
|
||||
* @brief ElementScene::slot_selectAll
|
||||
* Select all items
|
||||
*/
|
||||
void ElementScene::slot_selectAll() {
|
||||
slot_select(items());
|
||||
}
|
||||
|
||||
/**
|
||||
Deselectionne tout
|
||||
*/
|
||||
* @brief ElementScene::slot_deselectAll
|
||||
* deselect all item
|
||||
*/
|
||||
void ElementScene::slot_deselectAll() {
|
||||
slot_select(ElementContent());
|
||||
}
|
||||
@@ -811,7 +830,15 @@ void ElementScene::reset()
|
||||
clearSelection();
|
||||
undoStack().clear();
|
||||
|
||||
foreach (QGraphicsItem *qgi, items())
|
||||
//We don't add handlers, because it's the role of the primitive or decorator to remove it.
|
||||
QList<QGraphicsItem*> items_list;
|
||||
for (QGraphicsItem *qgi : items())
|
||||
{
|
||||
if(qgi->type() != QetGraphicsHandlerItem::Type)
|
||||
items_list << qgi;
|
||||
}
|
||||
|
||||
for (QGraphicsItem *qgi : items_list)
|
||||
{
|
||||
removeItem(qgi);
|
||||
qgiManager().release(qgi);
|
||||
@@ -1065,9 +1092,16 @@ void ElementScene::managePrimitivesGroups()
|
||||
// should we hide the decorator?
|
||||
QList<QGraphicsItem *> selected_items = zItems(ElementScene::Selected | ElementScene::IncludeTerminals);
|
||||
if (selected_items.size() <= 1)
|
||||
{
|
||||
m_decorator -> hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(QGraphicsItem *qgi : selected_items)
|
||||
{
|
||||
//We recall set selected, then every primitive will remove there handler because there are several item selected
|
||||
qgi->setSelected(true);
|
||||
}
|
||||
m_decorator -> setZValue(1000000);
|
||||
m_decorator -> setPos(0, 0);
|
||||
m_decorator -> setItems(selected_items);
|
||||
|
||||
@@ -82,7 +82,7 @@ class ElementScene : public QGraphicsScene
|
||||
QETElementEditor *m_element_editor = nullptr;
|
||||
|
||||
/// Variables to manage the paste area on the scene
|
||||
QGraphicsRectItem *m_paste_area = nullptr;
|
||||
QGraphicsRectItem *m_paste_area;
|
||||
QRectF m_defined_paste_area;
|
||||
|
||||
/// Variables to handle copy/paste with offset
|
||||
|
||||
@@ -118,6 +118,7 @@ void AbstractPartEllipse::setRect(const QRectF &rect)
|
||||
if (rect == m_rect) return;
|
||||
prepareGeometryChange();
|
||||
m_rect = rect;
|
||||
|
||||
emit rectChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,68 +154,173 @@ QPainterPath PartArc::shadowShape() const
|
||||
return (pps.createStroke(shape));
|
||||
}
|
||||
|
||||
void PartArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
/**
|
||||
* @brief PartArc::mouseReleaseEvent
|
||||
* Handle mouse release event
|
||||
* @param event
|
||||
*/
|
||||
void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!isSelected())
|
||||
{
|
||||
CustomElementGraphicPart::hoverMoveEvent(event);
|
||||
return;
|
||||
}
|
||||
if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
|
||||
switchResizeMode();
|
||||
|
||||
if (m_resize_mode == 1 || m_resize_mode == 2) {
|
||||
int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
|
||||
|
||||
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);
|
||||
CustomElementGraphicPart::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartArc::mousePressEvent
|
||||
* Handle mouse press event
|
||||
* @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 (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::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartArc::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, 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));
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler
|
||||
if (m_resize_mode == 3) //Resize angle
|
||||
{
|
||||
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);
|
||||
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"));
|
||||
@@ -242,125 +329,149 @@ void PartArc::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
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) {
|
||||
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();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementGraphicPart::mousePressEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartArc::mouseMoveEvent
|
||||
* Handle mouse move event
|
||||
* @brief PartArc::handlerMouseMoveEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartArc::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartArc::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_resize_mode == 1 || m_resize_mode == 2) {
|
||||
if (m_handler_index >= 0 && m_handler_index <= 7) {
|
||||
QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
|
||||
prepareGeometryChange();
|
||||
Q_UNUSED(qghi);
|
||||
|
||||
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(m_handler.rectForPosAtIndex(m_rect, pos_, m_handler_index));
|
||||
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
|
||||
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());
|
||||
{
|
||||
QLineF line(m_rect.center(), mapFromItem(qghi, event->pos()));
|
||||
prepareGeometryChange();
|
||||
|
||||
if (m_handler_index == 0) {
|
||||
if (m_vector_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));
|
||||
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);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementGraphicPart::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartArc::mouseReleaseEvent
|
||||
* Handle mouse release event
|
||||
* @brief PartArc::handlerMouseReleaseEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartArc::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
if (event->buttonDownPos(Qt::LeftButton) == event->pos())
|
||||
switchResizeMode();
|
||||
}
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
if (m_resize_mode == 1 || m_resize_mode == 2) {
|
||||
if (m_handler_index >= 0 && m_handler_index <= 7) {
|
||||
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_vector_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_vector_index = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_rect.isValid())
|
||||
m_rect = m_rect.normalized();
|
||||
|
||||
m_undo_command->setNewValue(QVariant(m_rect));
|
||||
elementScene()->undoStack().push(m_undo_command);
|
||||
m_undo_command = nullptr;
|
||||
m_handler_index = -1;
|
||||
return;
|
||||
m_vector_index = -1;
|
||||
}
|
||||
}
|
||||
else if (m_resize_mode == 3) {
|
||||
if (m_handler_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;
|
||||
}
|
||||
else if (m_handler_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;
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementGraphicPart::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
|
||||
switchResizeMode();
|
||||
}
|
||||
|
||||
if (m_handler_index >= 0 && m_handler_index <= 7)
|
||||
CustomElementGraphicPart::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
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);
|
||||
|
||||
m_undo_command->setNewValue(QVariant(m_rect));
|
||||
elementScene()->undoStack().push(m_undo_command);
|
||||
m_undo_command = nullptr;
|
||||
m_handler_index = -1;
|
||||
if (scene()->selectedItems().size() == 1)
|
||||
addHandler();
|
||||
}
|
||||
else
|
||||
CustomElementGraphicPart::mouseReleaseEvent(event);
|
||||
{
|
||||
disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
|
||||
removeHandler();
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
* @brief PartLine::itemChange
|
||||
* @param change
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
QVariant PartLine::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemSelectedHasChanged && scene())
|
||||
{
|
||||
if (value.toBool() == true)
|
||||
{
|
||||
//When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
|
||||
//according to the number of selected items.
|
||||
connect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
|
||||
|
||||
if (scene()->selectedItems().size() == 1)
|
||||
addHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
|
||||
removeHandler();
|
||||
}
|
||||
}
|
||||
else if (change == ItemPositionHasChanged)
|
||||
{
|
||||
adjusteHandlerPos();
|
||||
}
|
||||
else if (change == ItemSceneChange)
|
||||
{
|
||||
if(scene())
|
||||
disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
|
||||
|
||||
setSelected(false); //This is item removed from scene, then we deselect this, and so, the handlers is also removed.
|
||||
}
|
||||
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartLine::sceneEventFilter
|
||||
* @param watched
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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 PartLine::adjusteHandlerPos
|
||||
* Adjust the position of the handler item
|
||||
*/
|
||||
void PartLine::adjusteHandlerPos()
|
||||
{
|
||||
if(m_handler_vector.isEmpty())
|
||||
return;
|
||||
|
||||
QVector<QPointF> points_vector;
|
||||
points_vector << m_line.p1() << m_line.p2();
|
||||
|
||||
if (m_handler_vector.size() == points_vector.size())
|
||||
{
|
||||
points_vector = mapToScene(points_vector);
|
||||
for (int i = 0 ; i < points_vector.size() ; ++i)
|
||||
m_handler_vector.at(i)->setPos(points_vector.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartLine::handlerMousePressEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartLine::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartLine::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
if (isSelected())
|
||||
{
|
||||
m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForLine(m_line));
|
||||
|
||||
if(m_handler_index >= 0 && m_handler_index <= 1) //User click on an handler
|
||||
{
|
||||
m_undo_command = new QPropertyUndoCommand(this, "line", QVariant(m_line));
|
||||
m_undo_command->setText(tr("Modifier une ligne"));
|
||||
m_undo_command->enableAnimation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementGraphicPart::mousePressEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartLine::mouseMoveEvent
|
||||
* Handle pouse move event
|
||||
* @brief PartLine::handlerMouseMoveEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartLine::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if(m_handler_index >= 0 && m_handler_index <= 1)
|
||||
{
|
||||
QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
|
||||
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();
|
||||
setLine(m_handler.lineForPosAtIndex(m_line, pos_, m_handler_index));
|
||||
}
|
||||
if (m_vector_index == 0)
|
||||
m_line.setP1(new_pos);
|
||||
else
|
||||
CustomElementGraphicPart::mouseMoveEvent(event);
|
||||
m_line.setP2(new_pos);
|
||||
|
||||
adjusteHandlerPos();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartLine::mouseReleaseEvent
|
||||
* Handle mouse release event
|
||||
* @brief PartLine::handlerMouseReleaseEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartLine::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
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;
|
||||
}
|
||||
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
|
||||
CustomElementGraphicPart::mouseReleaseEvent(event);
|
||||
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.
|
||||
|
||||
@@ -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:
|
||||
QPainterPath path() const;
|
||||
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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
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.
|
||||
}
|
||||
|
||||
if (m_handler.pointIsHoverHandler(event->pos(), m_polygon) >= 0)
|
||||
setCursor(Qt::SizeAllCursor);
|
||||
else
|
||||
CustomElementGraphicPart::hoverMoveEvent(event);
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartPolygon::mousePressEvent
|
||||
* Handle mouse press event
|
||||
* @brief PartPolygon::sceneEventFilter
|
||||
* @param watched
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
bool PartPolygon::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 PartPolygon::adjusteHandlerPos
|
||||
*/
|
||||
void PartPolygon::adjusteHandlerPos()
|
||||
{
|
||||
if(m_handler_vector.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_handler_vector.size() == m_polygon.size())
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartPolygon::handlerMousePressEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartPolygon::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartPolygon::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
if(isSelected())
|
||||
{
|
||||
m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_polygon);
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
if(m_handler_index >= 0) //User click on an handler
|
||||
{
|
||||
m_undo_command = new QPropertyUndoCommand(this, "polygon", QVariant(m_polygon));
|
||||
m_undo_command->setText(tr("Modifier un polygone"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementGraphicPart::mousePressEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartPolygon::mouseMoveEvent
|
||||
* Handle mouse move event
|
||||
* @brief PartPolygon::handlerMouseMoveEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartPolygon::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartPolygon::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if(m_handler_index >= 0)
|
||||
{
|
||||
QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
|
||||
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_handler_index, pos_);
|
||||
m_polygon.replace(m_vector_index, new_pos);
|
||||
adjusteHandlerPos();
|
||||
emit polygonChanged();
|
||||
}
|
||||
else
|
||||
CustomElementGraphicPart::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PartPolygon::mouseReleaseEvent
|
||||
* Handle mouse release event
|
||||
* @brief PartPolygon::handlerMouseReleaseEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void PartPolygon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
void PartPolygon::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
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.
|
||||
}
|
||||
|
||||
if (m_handler_index >= 0 && m_handler_index <= 7)
|
||||
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)
|
||||
{
|
||||
if (!m_rect.isValid())
|
||||
m_rect = m_rect.normalized();
|
||||
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)
|
||||
{
|
||||
m_resize_mode = 2;
|
||||
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
|
||||
qghi->setColor(Qt::darkGreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_resize_mode = 1;
|
||||
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
|
||||
qghi->setColor(Qt::blue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 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_handler_index = -1;
|
||||
}
|
||||
else
|
||||
CustomElementGraphicPart::mouseReleaseEvent(event);
|
||||
m_vector_index = -1;
|
||||
}
|
||||
|
||||
void PartRectangle::switchResizeMode()
|
||||
/**
|
||||
* @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 (m_resize_mode == 1) {
|
||||
m_resize_mode = 2;
|
||||
m_handler.setOuterColor(Qt::darkGreen);
|
||||
}
|
||||
else {
|
||||
m_resize_mode = 1;
|
||||
m_handler.setOuterColor(Qt::blue);
|
||||
}
|
||||
update();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -78,17 +78,16 @@ Conductor::Conductor(Terminal *p1, Terminal* p2) :
|
||||
terminal1(p1),
|
||||
terminal2(p2),
|
||||
m_mouse_over(false),
|
||||
m_handler(10),
|
||||
m_text_item(0),
|
||||
segments(NULL),
|
||||
moving_segment(false),
|
||||
m_moving_segment(false),
|
||||
modified_path(false),
|
||||
has_to_save_profile(false),
|
||||
must_highlight_(Conductor::None)
|
||||
{
|
||||
//set Zvalue at 11 to be upper than the DiagramImageItem and element
|
||||
setZValue(11);
|
||||
previous_z_value = zValue();
|
||||
m_previous_z_value = zValue();
|
||||
|
||||
//Add this conductor to the list of conductor of each of the two terminal
|
||||
bool ajout_p1 = terminal1 -> addConductor(this);
|
||||
@@ -117,7 +116,7 @@ Conductor::Conductor(Terminal *p1, Terminal* p2) :
|
||||
|
||||
//Generate the path of this conductor.
|
||||
generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
|
||||
setFlags(QGraphicsItem::ItemIsSelectable);
|
||||
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsScenePositionChanges);
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
// Add the text field
|
||||
@@ -137,6 +136,7 @@ Conductor::Conductor(Terminal *p1, Terminal* p2) :
|
||||
*/
|
||||
Conductor::~Conductor()
|
||||
{
|
||||
removeHandler();
|
||||
terminal1->removeConductor(this);
|
||||
terminal2->removeConductor(this);
|
||||
deleteSegments();
|
||||
@@ -171,30 +171,39 @@ void Conductor::updatePath(const QRectF &rect) {
|
||||
}
|
||||
|
||||
/**
|
||||
Genere le QPainterPath a partir de la liste des points
|
||||
*/
|
||||
void Conductor::segmentsToPath() {
|
||||
// chemin qui sera dessine
|
||||
* @brief Conductor::segmentsToPath
|
||||
* Generate the QPainterPath from the list of points
|
||||
*/
|
||||
void Conductor::segmentsToPath()
|
||||
{
|
||||
QPainterPath path;
|
||||
|
||||
// s'il n'y a pa des segments, on arrete la
|
||||
if (segments == NULL) setPath(path);
|
||||
if (segments == NULL)
|
||||
setPath(path);
|
||||
|
||||
// demarre le chemin
|
||||
//Start the path
|
||||
path.moveTo(segments -> firstPoint());
|
||||
|
||||
// parcourt les segments pour dessiner le chemin
|
||||
//Each segments
|
||||
ConductorSegment *segment = segments;
|
||||
while(segment -> hasNextSegment()) {
|
||||
path.lineTo(segment -> secondPoint());
|
||||
segment = segment -> nextSegment();
|
||||
}
|
||||
|
||||
// termine le chemin
|
||||
//Finish the path
|
||||
path.lineTo(segment -> secondPoint());
|
||||
|
||||
// affecte le chemin au conducteur
|
||||
setPath(path);
|
||||
|
||||
//If conductor is selected and he's not being modified
|
||||
//we update the position of the handlers
|
||||
if (isSelected() && !m_moving_segment)
|
||||
{
|
||||
if(handlerPoints().size() == m_handler_vector.size())
|
||||
adjusteHandlerPos();
|
||||
else
|
||||
removeHandler();
|
||||
addHandler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,12 +465,11 @@ QPointF Conductor::extendTerminal(const QPointF &terminal, Qet::Orientation term
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::paint
|
||||
* Draw the conductor
|
||||
* @param qp
|
||||
* @param options
|
||||
* @param qw
|
||||
*/
|
||||
Dessine le conducteur sans antialiasing.
|
||||
@param qp Le QPainter a utiliser pour dessiner le conducteur
|
||||
@param options Les options de style pour le conducteur
|
||||
@param qw Le QWidget sur lequel on dessine
|
||||
*/
|
||||
void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWidget *qw)
|
||||
{
|
||||
Q_UNUSED(qw);
|
||||
@@ -501,7 +509,7 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
|
||||
final_conductor_pen.setCosmetic(true);
|
||||
}
|
||||
|
||||
qp->setPen(final_conductor_pen);
|
||||
qp -> setPen(final_conductor_pen);
|
||||
|
||||
//Draw the conductor
|
||||
qp -> drawPath(path());
|
||||
@@ -529,23 +537,18 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
|
||||
if (isSelected()) qp -> setBrush(Qt::NoBrush);
|
||||
}
|
||||
|
||||
//Draw the squares used to modify the path of conductor when he is selected
|
||||
if (isSelected())
|
||||
m_handler.drawHandler(qp, handlerPoints());
|
||||
|
||||
//Draw the junctions
|
||||
const QList<QPointF> junctions_list = junctions();
|
||||
if (!junctions_list.isEmpty())
|
||||
{
|
||||
QList<QPointF> junctions_list = junctions();
|
||||
if (!junctions_list.isEmpty()) {
|
||||
final_conductor_pen.setStyle(Qt::SolidLine);
|
||||
QBrush junction_brush(final_conductor_color, Qt::SolidPattern);
|
||||
qp -> setPen(final_conductor_pen);
|
||||
qp -> setBrush(junction_brush);
|
||||
qp -> setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
for(QPointF point : junctions_list)
|
||||
foreach(QPointF point, junctions_list) {
|
||||
qp -> drawEllipse(QRectF(point.x() - 1.5, point.y() - 1.5, 3.0, 3.0));
|
||||
}
|
||||
}
|
||||
|
||||
qp -> restore();
|
||||
}
|
||||
@@ -603,70 +606,18 @@ void Conductor::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
|
||||
*/
|
||||
void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
//Left clic
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
//If user click on a handler (square used to modify the path of conductor),
|
||||
//we get the segment corresponding to the handler
|
||||
int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
|
||||
if (index > -1)
|
||||
{
|
||||
moving_segment = true;
|
||||
moved_segment = segmentsList().at(index+1);
|
||||
before_mov_text_pos_ = m_text_item -> pos();
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsPathItem::mousePressEvent(event);
|
||||
|
||||
if (event -> modifiers() & Qt::ControlModifier)
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
setSelected(!isSelected());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::mouseMoveEvent
|
||||
* Manage the mouse move event
|
||||
* @param event
|
||||
*/
|
||||
void Conductor::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
//Left clic
|
||||
if ((event->buttons() & Qt::LeftButton) && moving_segment)
|
||||
{
|
||||
//Snap the mouse pos to grid
|
||||
QPointF pos_ = Diagram::snapToGrid(event->pos());
|
||||
|
||||
//Position of the last point
|
||||
QPointF p = moved_segment -> middle();
|
||||
|
||||
//Calcul the movement
|
||||
moved_segment -> moveX(pos_.x() - p.x());
|
||||
moved_segment -> moveY(pos_.y() - p.y());
|
||||
|
||||
//Apply the movement
|
||||
modified_path = true;
|
||||
has_to_save_profile = true;
|
||||
segmentsToPath();
|
||||
calculateTextItemPosition();
|
||||
}
|
||||
|
||||
QGraphicsPathItem::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::mouseReleaseEvent
|
||||
* Manage the mouse release event
|
||||
* @param event
|
||||
*/
|
||||
void Conductor::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
moving_segment = false;
|
||||
if (has_to_save_profile)
|
||||
{
|
||||
saveProfile();
|
||||
has_to_save_profile = false;
|
||||
}
|
||||
|
||||
if (!(event -> modifiers() & Qt::ControlModifier))
|
||||
QGraphicsPathItem::mouseReleaseEvent(event);
|
||||
}
|
||||
@@ -694,56 +645,209 @@ void Conductor::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::hoverMoveEvent conductor
|
||||
* @param e QGraphicsSceneHoverEvent describing the event
|
||||
* @brief Conductor::itemChange
|
||||
* @param change
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
void Conductor::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (isSelected())
|
||||
if (change == QGraphicsItem::ItemSelectedChange)
|
||||
{
|
||||
//If user hover an handler (square used to modify the path of conductor),
|
||||
//we get the segment corresponding to the handler
|
||||
int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
|
||||
if (index > -1)
|
||||
if (value.toBool())
|
||||
{
|
||||
ConductorSegment *segment_ = segmentsList().at(index+1);
|
||||
if (m_handler.pointIsInHandler(event->pos(), segment_->secondPoint()))
|
||||
setCursor(Qt::ForbiddenCursor);
|
||||
else if (m_handler.pointIsInHandler(event->pos(), segment_->middle()))
|
||||
setCursor(segmentsList().at(index+1)->isVertical() ? Qt::SplitHCursor : Qt::SplitVCursor);
|
||||
m_previous_z_value = zValue();
|
||||
setZValue(qAbs(m_previous_z_value) + 10000);
|
||||
addHandler();
|
||||
}
|
||||
else
|
||||
setCursor(Qt::ArrowCursor);
|
||||
{
|
||||
setZValue(m_previous_z_value);
|
||||
removeHandler();
|
||||
}
|
||||
}
|
||||
else if (change == QGraphicsItem::ItemSceneHasChanged)
|
||||
{
|
||||
calculateTextItemPosition();
|
||||
|
||||
if(!scene())
|
||||
removeHandler();
|
||||
else if (scene() && isSelected())
|
||||
addHandler();
|
||||
}
|
||||
else if (change == QGraphicsItem::ItemVisibleHasChanged) {
|
||||
calculateTextItemPosition();
|
||||
}
|
||||
else if (change == QGraphicsItem::ItemPositionHasChanged && isSelected()) {
|
||||
adjusteHandlerPos();
|
||||
}
|
||||
|
||||
QGraphicsPathItem::hoverMoveEvent(event);
|
||||
return(QGraphicsPathItem::itemChange(change, value));
|
||||
}
|
||||
|
||||
/**
|
||||
Gere les changements relatifs au conducteur
|
||||
Reimplemente ici pour :
|
||||
* positionner le conducteur en avant-plan lorsqu'il est selectionne
|
||||
@param change Type de changement
|
||||
@param value Valeur relative au changement
|
||||
*/
|
||||
QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||
if (change == QGraphicsItem::ItemSelectedChange) {
|
||||
if (value.toBool()) {
|
||||
// le conducteur vient de se faire selectionner
|
||||
previous_z_value = zValue();
|
||||
setZValue(qAbs(previous_z_value) + 10000);
|
||||
} else {
|
||||
// le conducteur vient de se faire deselectionner
|
||||
setZValue(previous_z_value);
|
||||
* @brief Conductor::sceneEventFilter
|
||||
* @param watched
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
bool Conductor::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
|
||||
{
|
||||
//Watched must be an handler
|
||||
if(watched->type() == QetGraphicsHandlerItem::Type)
|
||||
{
|
||||
QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
|
||||
|
||||
if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
|
||||
{
|
||||
m_vector_index = m_handler_vector.indexOf(qghi);
|
||||
if (m_vector_index != -1)
|
||||
{
|
||||
if(event->type() == QEvent::GraphicsSceneMousePress) //Click
|
||||
{
|
||||
handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
|
||||
return true;
|
||||
}
|
||||
} else if (change == QGraphicsItem::ItemSceneHasChanged) {
|
||||
// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
|
||||
calculateTextItemPosition();
|
||||
} else if (change == QGraphicsItem::ItemVisibleHasChanged) {
|
||||
// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
|
||||
calculateTextItemPosition();
|
||||
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 Conductor::adjusteHandlerPos
|
||||
* Adjust the position of the handler item
|
||||
*/
|
||||
void Conductor::adjusteHandlerPos()
|
||||
{
|
||||
if (m_handler_vector.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_handler_vector.size() == handlerPoints().size())
|
||||
{
|
||||
QVector <QPointF> points_vector = mapToScene(handlerPoints());
|
||||
for (int i = 0 ; i < points_vector.size() ; ++i)
|
||||
m_handler_vector.at(i)->setPos(points_vector.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::handlerMousePressEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void Conductor::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
//we get the segment corresponding to the handler
|
||||
if (m_vector_index > -1)
|
||||
{
|
||||
qghi->setColor(Qt::cyan);
|
||||
m_moving_segment = true;
|
||||
m_moved_segment = segmentsList().at(m_vector_index+1);
|
||||
before_mov_text_pos_ = m_text_item -> pos();
|
||||
|
||||
for(QetGraphicsHandlerItem *handler : m_handler_vector)
|
||||
if(handler != qghi)
|
||||
handler->hide();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::handlerMouseMoveEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void Conductor::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_moving_segment)
|
||||
{
|
||||
//Snap the mouse pos to grid
|
||||
QPointF pos_ = Diagram::snapToGrid(mapFromItem(qghi, event->pos()));
|
||||
|
||||
//Position of the last point
|
||||
QPointF p = m_moved_segment -> middle();
|
||||
|
||||
//Calcul the movement
|
||||
m_moved_segment -> moveX(pos_.x() - p.x());
|
||||
m_moved_segment -> moveY(pos_.y() - p.y());
|
||||
|
||||
//Apply the movement
|
||||
modified_path = true;
|
||||
has_to_save_profile = true;
|
||||
segmentsToPath();
|
||||
calculateTextItemPosition();
|
||||
qghi->setPos(mapToScene(m_moved_segment->middle()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::handlerMouseReleaseEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void Conductor::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(qghi);
|
||||
|
||||
m_vector_index = -1;
|
||||
|
||||
m_moving_segment = false;
|
||||
if (has_to_save_profile)
|
||||
{
|
||||
saveProfile();
|
||||
has_to_save_profile = false;
|
||||
}
|
||||
//When handler is released, the conductor can have more segment than befor the handler was moved
|
||||
//then we remove all handles and new ones are added
|
||||
removeHandler();
|
||||
addHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::addHandler
|
||||
* Add handlers for this item
|
||||
*/
|
||||
void Conductor::addHandler()
|
||||
{
|
||||
if (m_handler_vector.isEmpty() && scene())
|
||||
{
|
||||
m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(handlerPoints()));
|
||||
|
||||
for(QetGraphicsHandlerItem *handler : m_handler_vector)
|
||||
{
|
||||
handler->setColor(Qt::blue);
|
||||
scene()->addItem(handler);
|
||||
handler->installSceneEventFilter(this);
|
||||
handler->setZValue(this->zValue()+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conductor::removeHandler
|
||||
* Remove the handlers of this item
|
||||
*/
|
||||
void Conductor::removeHandler()
|
||||
{
|
||||
if (!m_handler_vector.isEmpty())
|
||||
{
|
||||
qDeleteAll(m_handler_vector);
|
||||
m_handler_vector.clear();
|
||||
}
|
||||
return(QGraphicsPathItem::itemChange(change, value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -769,22 +873,6 @@ QPainterPath Conductor::shape() const
|
||||
|
||||
QPainterPath shape_(pps.createStroke(path()));
|
||||
|
||||
/**
|
||||
Add handle rect to path, occur a weird bug.
|
||||
when the conductor is removed from the scene he continue to be painted in the scene and make artefact.
|
||||
If we save (exactly when we clear the undo stack of project when saving), Qet crash,
|
||||
Don't add the handle rect to the path seem to work well.
|
||||
More information here :
|
||||
https://qelectrotech.org/bugtracker/view.php?id=107
|
||||
https://qelectrotech.org/forum/viewtopic.php?pid=5619#p5619
|
||||
https://qelectrotech.org/forum/viewtopic.php?pid=5067#p5067
|
||||
**/
|
||||
// if (isSelected()) {
|
||||
// foreach (QRectF rect, m_handler.handlerRect(handlerPoints())) {
|
||||
// shape_.addRect(rect);
|
||||
// }
|
||||
// }
|
||||
|
||||
return shape_;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "conductorproperties.h"
|
||||
#include <QGraphicsPathItem>
|
||||
#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
|
||||
#include "assignvariables.h"
|
||||
|
||||
class ConductorProfile;
|
||||
@@ -32,6 +31,8 @@ class ConductorTextItem;
|
||||
class Element;
|
||||
class QETDiagramEditor;
|
||||
class NumerotationContext;
|
||||
class QetGraphicsHandlerItem;
|
||||
|
||||
typedef QPair<QPointF, Qt::Corner> ConductorBend;
|
||||
typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
|
||||
/**
|
||||
@@ -133,16 +134,25 @@ class Conductor : public QObject, public QGraphicsPathItem
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
|
||||
virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||
virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
void adjusteHandlerPos();
|
||||
|
||||
void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
void addHandler();
|
||||
void removeHandler();
|
||||
|
||||
|
||||
QVector<QetGraphicsHandlerItem *> m_handler_vector;
|
||||
int m_vector_index = -1;
|
||||
bool m_mouse_over;
|
||||
QetGraphicsHandlerUtility m_handler;
|
||||
/// Functional properties
|
||||
ConductorProperties m_properties;
|
||||
/// Text input for non simple, non-singleline conductors
|
||||
@@ -150,10 +160,10 @@ class Conductor : public QObject, public QGraphicsPathItem
|
||||
/// Segments composing the conductor
|
||||
ConductorSegment *segments;
|
||||
/// Attributs related to mouse interaction
|
||||
bool moving_segment;
|
||||
bool m_moving_segment;
|
||||
int moved_point;
|
||||
qreal previous_z_value;
|
||||
ConductorSegment *moved_segment;
|
||||
qreal m_previous_z_value;
|
||||
ConductorSegment *m_moved_segment;
|
||||
QPointF before_mov_text_pos_;
|
||||
/// Whether the conductor was manually modified by users
|
||||
bool modified_path;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "shapegraphicsitempropertieswidget.h"
|
||||
#include "PropertiesEditor/propertieseditordialog.h"
|
||||
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
|
||||
#include "qetxml.h"
|
||||
|
||||
/**
|
||||
@@ -37,18 +38,20 @@ QetShapeItem::QetShapeItem(QPointF p1, QPointF p2, ShapeType type, QGraphicsItem
|
||||
m_shapeType(type),
|
||||
m_P1 (p1),
|
||||
m_P2 (p2),
|
||||
m_hovered(false),
|
||||
m_mouse_grab_handler(false),
|
||||
m_handler(10)
|
||||
m_hovered(false)
|
||||
{
|
||||
if (type == Polygon) m_polygon << m_P1 << m_P2;
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
|
||||
setAcceptHoverEvents(true);
|
||||
m_pen.setStyle(Qt::DashLine);
|
||||
|
||||
}
|
||||
|
||||
QetShapeItem::~QetShapeItem() {}
|
||||
QetShapeItem::~QetShapeItem()
|
||||
{
|
||||
if(!m_handler_vector.isEmpty())
|
||||
qDeleteAll(m_handler_vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::setPen
|
||||
@@ -109,6 +112,7 @@ bool QetShapeItem::setLine(const QLineF &line)
|
||||
prepareGeometryChange();
|
||||
m_P1 = line.p1();
|
||||
m_P2 = line.p2();
|
||||
adjusteHandlerPos();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -125,6 +129,7 @@ bool QetShapeItem::setRect(const QRectF &rect)
|
||||
prepareGeometryChange();
|
||||
m_P1 = rect.topLeft();
|
||||
m_P2 = rect.bottomRight();
|
||||
adjusteHandlerPos();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,6 +147,7 @@ bool QetShapeItem::setPolygon(const QPolygonF &polygon)
|
||||
if (Q_UNLIKELY(m_shapeType != Polygon)) return false;
|
||||
prepareGeometryChange();
|
||||
m_polygon = polygon;
|
||||
adjusteHandlerPos();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -246,23 +252,6 @@ QPainterPath QetShapeItem::shape() const
|
||||
pps.setJoinStyle(Qt::RoundJoin);
|
||||
path = pps.createStroke(path);
|
||||
|
||||
if (isSelected())
|
||||
{
|
||||
QVector <QPointF> vector;
|
||||
|
||||
if (m_shapeType == Line)
|
||||
vector << m_P1 << m_P2;
|
||||
else if (m_shapeType == Rectangle || m_shapeType == Ellipse) {
|
||||
QRectF rect (m_P1, m_P2);
|
||||
vector << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
|
||||
}
|
||||
else
|
||||
vector = m_polygon;
|
||||
|
||||
foreach(QRectF r, m_handler.handlerRect(vector))
|
||||
path.addRect(r);
|
||||
}
|
||||
|
||||
return (path);
|
||||
}
|
||||
|
||||
@@ -294,33 +283,14 @@ void QetShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
painter -> restore ();
|
||||
}
|
||||
|
||||
//Draw the shape and handlers if is selected
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case Line:
|
||||
painter->drawLine(QLineF(m_P1, m_P2));
|
||||
if (isSelected())
|
||||
m_handler.drawHandler(painter, QVector<QPointF>{m_P1, m_P2});
|
||||
break;
|
||||
|
||||
case Rectangle:
|
||||
painter->drawRect(QRectF(m_P1, m_P2));
|
||||
if (isSelected())
|
||||
m_handler.drawHandler(painter, m_handler.pointsForRect(QRectF(m_P1, m_P2)));
|
||||
break;
|
||||
|
||||
case Ellipse:
|
||||
painter->drawEllipse(QRectF(m_P1, m_P2));
|
||||
if (isSelected())
|
||||
m_handler.drawHandler(painter, m_handler.pointsForRect(QRectF(m_P1, m_P2)));
|
||||
break;
|
||||
|
||||
case Polygon:
|
||||
m_close ? painter->drawPolygon(m_polygon) : painter->drawPolyline(m_polygon);
|
||||
if (isSelected())
|
||||
m_handler.drawHandler(painter, m_polygon);
|
||||
break;
|
||||
case Line: painter->drawLine(QLineF(m_P1, m_P2)); break;
|
||||
case Rectangle: painter->drawRect(QRectF(m_P1, m_P2)); break;
|
||||
case Ellipse: painter->drawEllipse(QRectF(m_P1, m_P2)); break;
|
||||
case Polygon: m_close ? painter->drawPolygon(m_polygon) : painter->drawPolyline(m_polygon); break;
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
@@ -329,142 +299,23 @@ void QetShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
* Handle hover enter event
|
||||
* @param event
|
||||
*/
|
||||
void QetShapeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
|
||||
void QetShapeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
m_hovered = true;
|
||||
QetGraphicsItem::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
void QetShapeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
if (!isSelected()) return;
|
||||
|
||||
QVector <QPointF> vector;
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case Line: vector << m_P1 << m_P2; break;
|
||||
case Rectangle: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Ellipse: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Polygon: vector = m_polygon; break;
|
||||
}
|
||||
|
||||
int handler = m_handler.pointIsHoverHandler(event->pos(), vector);
|
||||
if (handler >= 0)
|
||||
{
|
||||
if (m_shapeType & (Line | Polygon)) {
|
||||
setCursor(Qt::SizeAllCursor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (handler == 0 || handler == 2 || handler == 5 || handler == 7)
|
||||
setCursor(Qt::SizeAllCursor);
|
||||
else if (handler == 1 || handler == 6)
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
else if (handler == 3 || handler == 4)
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
}
|
||||
else
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::hoverLeaveEvent
|
||||
* Handle hover leave event
|
||||
* @param event
|
||||
*/
|
||||
void QetShapeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
|
||||
void QetShapeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
m_hovered = false;
|
||||
unsetCursor();
|
||||
QetGraphicsItem::hoverLeaveEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::mousePressEvent
|
||||
* Handle mouse press event
|
||||
* @param event
|
||||
*/
|
||||
void QetShapeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
//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: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Ellipse: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Polygon: vector = m_polygon; break;
|
||||
}
|
||||
|
||||
m_vector_index = m_handler.pointIsHoverHandler(event->pos(), vector);
|
||||
if (m_vector_index != -1)
|
||||
{
|
||||
//User click on an handler
|
||||
m_mouse_grab_handler = true;
|
||||
m_old_P1 = m_P1;
|
||||
m_old_P2 = m_P2;
|
||||
m_old_polygon = m_polygon;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
if (m_resize_mode == 1) {
|
||||
setRect(m_handler.rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
setRect(m_handler.mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
case Ellipse:
|
||||
if (m_resize_mode == 1) {
|
||||
setRect(m_handler.rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
setRect(m_handler.mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
|
||||
case Polygon:
|
||||
prepareGeometryChange();
|
||||
m_polygon.replace(m_vector_index, new_pos);
|
||||
break;
|
||||
} //End switch
|
||||
return;
|
||||
}
|
||||
|
||||
QetGraphicsItem::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::mouseReleaseEvent
|
||||
* Handle mouse release event
|
||||
@@ -472,12 +323,228 @@ void QetShapeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
*/
|
||||
void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if ((m_shapeType & (Rectangle | Ellipse)) && event->buttonDownPos(Qt::LeftButton) == event->pos())
|
||||
if (event->buttonDownPos(Qt::LeftButton) == event->pos())
|
||||
switchResizeMode();
|
||||
|
||||
if (m_mouse_grab_handler)
|
||||
QetGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::itemChange
|
||||
* @param change
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
QVariant QetShapeItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemSelectedHasChanged)
|
||||
{
|
||||
m_mouse_grab_handler = false;
|
||||
if (value.toBool() == true) //If this is selected, wa add handlers.
|
||||
{
|
||||
QVector <QPointF> points_vector;
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case Line: points_vector << m_P1 << m_P2; break;
|
||||
case Rectangle: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Ellipse: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Polygon: points_vector = m_polygon; break;
|
||||
}
|
||||
|
||||
if(!points_vector.isEmpty() && scene())
|
||||
{
|
||||
m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(points_vector));
|
||||
|
||||
for(QetGraphicsHandlerItem *handler : m_handler_vector)
|
||||
{
|
||||
handler->setColor(Qt::blue);
|
||||
scene()->addItem(handler);
|
||||
handler->installSceneEventFilter(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
else //Else this is deselected, we remove handlers
|
||||
{
|
||||
if(!m_handler_vector.isEmpty())
|
||||
{
|
||||
qDeleteAll(m_handler_vector);
|
||||
m_handler_vector.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (change == ItemPositionHasChanged)
|
||||
{
|
||||
adjusteHandlerPos();
|
||||
}
|
||||
else if (change == ItemSceneHasChanged)
|
||||
{
|
||||
if (!scene()) //This is removed from scene, then we deselect this, and so, the handlers is also removed.
|
||||
{
|
||||
setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::sceneEventFilter
|
||||
* @param watched
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
bool QetShapeItem::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 QetShapeItem::switchResizeMode
|
||||
*/
|
||||
void QetShapeItem::switchResizeMode()
|
||||
{
|
||||
if (m_shapeType & (Rectangle | Ellipse))
|
||||
{
|
||||
if (m_resize_mode == 1)
|
||||
{
|
||||
m_resize_mode = 2;
|
||||
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
|
||||
qghi->setColor(Qt::darkGreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_resize_mode = 1;
|
||||
for (QetGraphicsHandlerItem *qghi : m_handler_vector)
|
||||
qghi->setColor(Qt::blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::adjusteHandlerPos
|
||||
* Adjust the position of the handler item
|
||||
*/
|
||||
void QetShapeItem::adjusteHandlerPos()
|
||||
{
|
||||
QVector <QPointF> points_vector;
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case Line: points_vector << m_P1 << m_P2; break;
|
||||
case Rectangle: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Ellipse: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
|
||||
case Polygon: points_vector = m_polygon; break;
|
||||
}
|
||||
|
||||
if (m_handler_vector.size() == points_vector.size())
|
||||
{
|
||||
points_vector = mapToScene(points_vector);
|
||||
for (int i = 0 ; i < points_vector.size() ; ++i)
|
||||
m_handler_vector.at(i)->setPos(points_vector.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::handlerMousePressEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
m_old_P1 = m_P1;
|
||||
m_old_P2 = m_P2;
|
||||
m_old_polygon = m_polygon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::handlerMouseMoveEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void QetShapeItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(qghi);
|
||||
|
||||
QPointF new_pos = event->scenePos();
|
||||
if (event->modifiers() != Qt::ControlModifier)
|
||||
new_pos = Diagram::snapToGrid(event->scenePos());
|
||||
new_pos = mapFromScene(new_pos);
|
||||
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case Line:
|
||||
prepareGeometryChange();
|
||||
m_vector_index == 0 ? m_P1 = new_pos : m_P2 = new_pos;
|
||||
adjusteHandlerPos();
|
||||
break;
|
||||
|
||||
case Rectangle:
|
||||
if (m_resize_mode == 1) {
|
||||
setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
case Ellipse:
|
||||
if (m_resize_mode == 1) {
|
||||
setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
|
||||
break;
|
||||
}
|
||||
|
||||
case Polygon:
|
||||
prepareGeometryChange();
|
||||
m_polygon.replace(m_vector_index, new_pos);
|
||||
adjusteHandlerPos();
|
||||
break;
|
||||
} //End switch
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QetShapeItem::handlerMouseReleaseEvent
|
||||
* @param qghi
|
||||
* @param event
|
||||
*/
|
||||
void QetShapeItem::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(qghi);
|
||||
Q_UNUSED(event);
|
||||
|
||||
if (diagram())
|
||||
{
|
||||
QPropertyUndoCommand *undo = nullptr;
|
||||
@@ -501,23 +568,6 @@ void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
diagram()->undoStack().push(undo);
|
||||
}
|
||||
}
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
QetGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void QetShapeItem::switchResizeMode()
|
||||
{
|
||||
if (m_resize_mode == 1) {
|
||||
m_resize_mode = 2;
|
||||
m_handler.setOuterColor(Qt::darkGreen);
|
||||
}
|
||||
else {
|
||||
m_resize_mode = 1;
|
||||
m_handler.setOuterColor(Qt::blue);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
#include <QPen>
|
||||
#include "qetgraphicsitem.h"
|
||||
#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
|
||||
#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
|
||||
|
||||
class QDomElement;
|
||||
class QDomDocument;
|
||||
class QetGraphicsHandlerItem;
|
||||
|
||||
/**
|
||||
* @brief The QetShapeItem class
|
||||
@@ -96,14 +97,18 @@ class QetShapeItem : public QetGraphicsItem
|
||||
protected:
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
virtual void hoverEnterEvent (QGraphicsSceneHoverEvent *event);
|
||||
virtual void hoverMoveEvent (QGraphicsSceneHoverEvent *event);
|
||||
virtual void hoverLeaveEvent (QGraphicsSceneHoverEvent *event);
|
||||
virtual void mousePressEvent (QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event);
|
||||
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
|
||||
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
void switchResizeMode();
|
||||
void adjusteHandlerPos();
|
||||
|
||||
void handlerMousePressEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
void handlerMouseMoveEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
|
||||
|
||||
///ATTRIBUTES
|
||||
private:
|
||||
@@ -112,11 +117,10 @@ class QetShapeItem : public QetGraphicsItem
|
||||
QBrush m_brush;
|
||||
QPointF m_P1, m_P2, m_old_P1, m_old_P2;
|
||||
QPolygonF m_polygon, m_old_polygon;
|
||||
bool m_hovered,
|
||||
m_mouse_grab_handler;
|
||||
bool m_hovered;
|
||||
int m_vector_index;
|
||||
QetGraphicsHandlerUtility m_handler;
|
||||
bool m_close = false;
|
||||
int m_resize_mode = 1;
|
||||
QVector<QetGraphicsHandlerItem *> m_handler_vector;
|
||||
};
|
||||
#endif // QETSHAPEITEM_H
|
||||
|
||||
Reference in New Issue
Block a user