Improve Puzzle's piece rotation handlers.
This commit is contained in:
parent
23e6d524b1
commit
b75292c341
|
@ -54,7 +54,6 @@ VPSheetSceneData::VPSheetSceneData(const VPLayoutPtr &layout, const QUuid &sheet
|
||||||
m_scene->addItem(m_graphicsTileGrid);
|
m_scene->addItem(m_graphicsTileGrid);
|
||||||
|
|
||||||
m_rotationControls = new VPGraphicsPieceControls(layout);
|
m_rotationControls = new VPGraphicsPieceControls(layout);
|
||||||
m_rotationControls->setVisible(false);
|
|
||||||
m_scene->addItem(m_rotationControls);
|
m_scene->addItem(m_rotationControls);
|
||||||
|
|
||||||
m_rotationOrigin = new VPGraphicsTransformationOrigin(layout);
|
m_rotationOrigin = new VPGraphicsTransformationOrigin(layout);
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
#include "../vmisc/compatibility.h"
|
#include "../vmisc/compatibility.h"
|
||||||
#include "../vwidgets/global.h"
|
#include "../vwidgets/global.h"
|
||||||
|
@ -40,20 +42,13 @@
|
||||||
#include "../layout/vppiece.h"
|
#include "../layout/vppiece.h"
|
||||||
#include "../undocommands/vpundopiecerotate.h"
|
#include "../undocommands/vpundopiecerotate.h"
|
||||||
#include "../undocommands/vpundooriginmove.h"
|
#include "../undocommands/vpundooriginmove.h"
|
||||||
|
#include "qgraphicsscene.h"
|
||||||
|
#include "qgraphicsview.h"
|
||||||
|
#include "qnamespace.h"
|
||||||
#include "vpgraphicspiece.h"
|
#include "vpgraphicspiece.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const qreal arcStartAngle = 105;
|
|
||||||
const qreal arcAngle = 25;
|
|
||||||
const qreal arcRadius = 15;
|
|
||||||
|
|
||||||
const qreal arrowTail = 2;
|
|
||||||
const qreal arrowSide = 2;
|
|
||||||
const qreal arrowLength = 4;
|
|
||||||
const qreal arrow1Angle = 13;
|
|
||||||
const qreal arrow2Angle = 38;
|
|
||||||
|
|
||||||
constexpr qreal penWidth = 2;
|
constexpr qreal penWidth = 2;
|
||||||
|
|
||||||
const qreal centerRadius1 = 5;
|
const qreal centerRadius1 = 5;
|
||||||
|
@ -62,15 +57,6 @@ const qreal centerRadius2 = 10;
|
||||||
const QColor defaultColor = Qt::black;
|
const QColor defaultColor = Qt::black;
|
||||||
const QColor hoverColor = Qt::green;
|
const QColor hoverColor = Qt::green;
|
||||||
|
|
||||||
enum class HandleCorner : int
|
|
||||||
{
|
|
||||||
Invalid = 0,
|
|
||||||
TopLeft = 1,
|
|
||||||
TopRight = 2,
|
|
||||||
BottomRight = 3,
|
|
||||||
BottomLeft = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
auto TransformationOrigin(const VPLayoutPtr &layout, const QRectF &boundingRect) -> VPTransformationOrigon
|
auto TransformationOrigin(const VPLayoutPtr &layout, const QRectF &boundingRect) -> VPTransformationOrigon
|
||||||
{
|
{
|
||||||
SCASSERT(layout != nullptr)
|
SCASSERT(layout != nullptr)
|
||||||
|
@ -310,10 +296,12 @@ VPGraphicsPieceControls::VPGraphicsPieceControls(const VPLayoutPtr &layout, QGra
|
||||||
m_layout(layout)
|
m_layout(layout)
|
||||||
{
|
{
|
||||||
SCASSERT(m_layout != nullptr)
|
SCASSERT(m_layout != nullptr)
|
||||||
QPixmap cursor_pixmap = QIcon("://puzzleicon/svg/cursor_rotate.svg").pixmap(QSize(32,32));
|
setCursor(QCursor(Qt::OpenHandCursor));
|
||||||
setCursor(QCursor(cursor_pixmap, 16, 16));
|
setZValue(100);
|
||||||
setZValue(1);
|
setFlag(QGraphicsItem::ItemIgnoresTransformations);
|
||||||
setAcceptHoverEvents(true);
|
setAcceptHoverEvents(true);
|
||||||
|
|
||||||
|
InitPixmaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -326,7 +314,7 @@ void VPGraphicsPieceControls::on_UpdateControls()
|
||||||
|
|
||||||
m_selectedPieces = SelectedPieces();
|
m_selectedPieces = SelectedPieces();
|
||||||
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
|
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
|
||||||
setVisible(not m_pieceRect.isNull());
|
m_controlsVisible = not m_pieceRect.isNull();
|
||||||
|
|
||||||
if (not m_pieceRect.isNull())
|
if (not m_pieceRect.isNull())
|
||||||
{
|
{
|
||||||
|
@ -361,8 +349,20 @@ void VPGraphicsPieceControls::on_HideHandles(bool hide)
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VPGraphicsPieceControls::boundingRect() const -> QRectF
|
auto VPGraphicsPieceControls::boundingRect() const -> QRectF
|
||||||
{
|
{
|
||||||
constexpr qreal halfPenWidth = penWidth/2.;
|
QRectF boundingRect;
|
||||||
return Handles().boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
|
||||||
|
auto HandlerBoundingRect = [this, &boundingRect](VPHandleCorner corner, VPHandleCornerType type, QPointF pos)
|
||||||
|
{
|
||||||
|
QPixmap handler = HandlerPixmap(m_handleCorner == corner, type);
|
||||||
|
boundingRect = boundingRect.united(QRectF(pos, handler.size() / handler.devicePixelRatio()));
|
||||||
|
};
|
||||||
|
|
||||||
|
HandlerBoundingRect(VPHandleCorner::TopLeft, VPHandleCornerType::TopLeft, TopLeftHandlerPosition());
|
||||||
|
HandlerBoundingRect(VPHandleCorner::TopRight, VPHandleCornerType::TopRight, TopRightHandlerPosition());
|
||||||
|
HandlerBoundingRect(VPHandleCorner::BottomRight, VPHandleCornerType::BottomRight, BottomRightHandlerPosition());
|
||||||
|
HandlerBoundingRect(VPHandleCorner::BottomLeft, VPHandleCornerType::BottomLeft, BottomLeftHandlerPosition());
|
||||||
|
|
||||||
|
return boundingRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -377,32 +377,52 @@ void VPGraphicsPieceControls::paint(QPainter *painter, const QStyleOptionGraphic
|
||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
Q_UNUSED(option);
|
Q_UNUSED(option);
|
||||||
|
|
||||||
const qreal scale = SceneScale(scene());
|
|
||||||
|
|
||||||
QPen pen(defaultColor, penWidth/scale, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
|
||||||
|
|
||||||
painter->setPen(pen);
|
|
||||||
|
|
||||||
if (m_controlsVisible)
|
if (m_controlsVisible)
|
||||||
{
|
{
|
||||||
TopLeftControl(painter);
|
painter->drawPixmap(TopLeftHandlerPosition(),
|
||||||
TopRightControl(painter);
|
HandlerPixmap(m_handleCorner == VPHandleCorner::TopLeft,
|
||||||
BottomLeftControl(painter);
|
VPHandleCornerType::TopLeft));
|
||||||
BottomRightControl(painter);
|
|
||||||
|
painter->drawPixmap(TopRightHandlerPosition(),
|
||||||
|
HandlerPixmap(m_handleCorner == VPHandleCorner::TopRight,
|
||||||
|
VPHandleCornerType::TopRight));
|
||||||
|
|
||||||
|
painter->drawPixmap(BottomRightHandlerPosition(),
|
||||||
|
HandlerPixmap(m_handleCorner == VPHandleCorner::BottomRight,
|
||||||
|
VPHandleCornerType::BottomRight));
|
||||||
|
|
||||||
|
painter->drawPixmap(BottomLeftHandlerPosition(),
|
||||||
|
HandlerPixmap(m_handleCorner == VPHandleCorner::BottomLeft,
|
||||||
|
VPHandleCornerType::BottomLeft));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
if(event->button() == Qt::LeftButton)
|
if(event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
||||||
{
|
{
|
||||||
m_rotationStartPoint = event->scenePos();
|
m_rotationStartPoint = event->scenePos();
|
||||||
m_rotationSum = 0;
|
m_rotationSum = 0;
|
||||||
m_controlsVisible = false;
|
m_controlsVisible = false;
|
||||||
m_handleCorner = SelectedHandleCorner(event->scenePos());
|
m_handleCorner = SelectedHandleCorner(event->pos());
|
||||||
m_ignorePieceTransformation = true;
|
m_ignorePieceTransformation = true;
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
if (m_handleCorner != VPHandleCorner::Invalid)
|
||||||
|
{
|
||||||
|
setCursor(QCursor(Qt::ClosedHandCursor));
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QGraphicsView *view = ItemView();
|
||||||
|
if (view != nullptr)
|
||||||
|
{
|
||||||
|
setCursor(view->viewport()->cursor());
|
||||||
|
}
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -413,8 +433,7 @@ void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
if((event->modifiers() & Qt::ShiftModifier) != 0U
|
if((event->modifiers() & Qt::ShiftModifier) && m_handleCorner != VPHandleCorner::Invalid)
|
||||||
&& static_cast<HandleCorner>(m_handleCorner) != HandleCorner::Invalid)
|
|
||||||
{
|
{
|
||||||
if (not m_originSaved)
|
if (not m_originSaved)
|
||||||
{
|
{
|
||||||
|
@ -431,22 +450,22 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
VPTransformationOrigon origin;
|
VPTransformationOrigon origin;
|
||||||
origin.custom = true;
|
origin.custom = true;
|
||||||
|
|
||||||
if (static_cast<HandleCorner>(m_handleCorner) == HandleCorner::TopLeft)
|
if (m_handleCorner == VPHandleCorner::TopLeft)
|
||||||
{
|
|
||||||
origin.origin = m_pieceRect.topLeft();
|
|
||||||
}
|
|
||||||
else if (static_cast<HandleCorner>(m_handleCorner) == HandleCorner::TopRight)
|
|
||||||
{
|
|
||||||
origin.origin = m_pieceRect.topRight();
|
|
||||||
}
|
|
||||||
else if (static_cast<HandleCorner>(m_handleCorner) == HandleCorner::BottomRight)
|
|
||||||
{
|
{
|
||||||
origin.origin = m_pieceRect.bottomRight();
|
origin.origin = m_pieceRect.bottomRight();
|
||||||
}
|
}
|
||||||
else if (static_cast<HandleCorner>(m_handleCorner) == HandleCorner::BottomLeft)
|
else if (m_handleCorner == VPHandleCorner::TopRight)
|
||||||
{
|
{
|
||||||
origin.origin = m_pieceRect.bottomLeft();
|
origin.origin = m_pieceRect.bottomLeft();
|
||||||
}
|
}
|
||||||
|
else if (m_handleCorner == VPHandleCorner::BottomRight)
|
||||||
|
{
|
||||||
|
origin.origin = m_pieceRect.topLeft();
|
||||||
|
}
|
||||||
|
else if (m_handleCorner == VPHandleCorner::BottomLeft)
|
||||||
|
{
|
||||||
|
origin.origin = m_pieceRect.topRight();
|
||||||
|
}
|
||||||
|
|
||||||
sheet->SetTransformationOrigin(origin);
|
sheet->SetTransformationOrigin(origin);
|
||||||
emit TransformationOriginChanged();
|
emit TransformationOriginChanged();
|
||||||
|
@ -565,6 +584,19 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
m_controlsVisible = true;
|
m_controlsVisible = true;
|
||||||
m_ignorePieceTransformation = false;
|
m_ignorePieceTransformation = false;
|
||||||
|
|
||||||
|
if (SelectedHandleCorner(event->pos()) != VPHandleCorner::Invalid)
|
||||||
|
{
|
||||||
|
setCursor(QCursor(Qt::OpenHandCursor));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QGraphicsView *view = ItemView();
|
||||||
|
if (view != nullptr)
|
||||||
|
{
|
||||||
|
setCursor(view->viewport()->cursor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_originSaved)
|
if (m_originSaved)
|
||||||
{
|
{
|
||||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||||
|
@ -591,49 +623,152 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
QGraphicsObject::mouseReleaseEvent(event);
|
QGraphicsObject::mouseReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VPGraphicsPieceControls::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||||
|
{
|
||||||
|
UpdateCursor(SelectedHandleCorner(event->pos()));
|
||||||
|
QGraphicsObject::hoverEnterEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VPGraphicsPieceControls::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||||
|
{
|
||||||
|
UpdateCursor(SelectedHandleCorner(event->pos()));
|
||||||
|
QGraphicsObject::hoverMoveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VPGraphicsPieceControls::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||||
|
{
|
||||||
|
UpdateCursor(VPHandleCorner::Invalid);
|
||||||
|
QGraphicsObject::hoverLeaveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VPGraphicsPieceControls::InitPixmaps()
|
||||||
|
{
|
||||||
|
m_handlePixmaps.clear();
|
||||||
|
m_handleHoverPixmaps.clear();
|
||||||
|
m_handlePaths.clear();
|
||||||
|
|
||||||
|
auto InitPixmap = [this](VPHandleCornerType type, const QString &fileName)
|
||||||
|
{
|
||||||
|
const QFileInfo fileInfo(fileName);
|
||||||
|
const QString imageName = fileInfo.baseName();
|
||||||
|
|
||||||
|
const QString fileNameHover = QStringLiteral("%1/%2-hover.%3")
|
||||||
|
.arg(fileInfo.absolutePath(), imageName, fileInfo.suffix());
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
|
||||||
|
if (QGuiApplication::primaryScreen()->devicePixelRatio() >= 2 )
|
||||||
|
{
|
||||||
|
const QString fileName2x = QStringLiteral("%1/%2@2x.%3")
|
||||||
|
.arg(fileInfo.absolutePath(), imageName, fileInfo.suffix());
|
||||||
|
|
||||||
|
const QString fileName2xHover = QStringLiteral("%1/%2-hover@2x.%3")
|
||||||
|
.arg(fileInfo.absolutePath(), imageName, fileInfo.suffix());
|
||||||
|
|
||||||
|
m_handlePixmaps.insert(type, QPixmap(fileName2x));
|
||||||
|
m_handleHoverPixmaps.insert(type, QPixmap(fileName2xHover));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_handlePixmaps.insert(type, QPixmap(fileName));
|
||||||
|
m_handleHoverPixmaps.insert(type, QPixmap(fileNameHover));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
m_handlePixmaps.insert(type, QPixmap(fileName));
|
||||||
|
m_handleHoverPixmaps.insert(type, QPixmap(fileNameHover));
|
||||||
|
#endif
|
||||||
|
QPainterPath p = PixmapToPainterPath(m_handlePixmaps.value(type));
|
||||||
|
p.setFillRule(Qt::WindingFill);
|
||||||
|
p.closeSubpath();
|
||||||
|
m_handlePaths.insert(type, p);
|
||||||
|
};
|
||||||
|
|
||||||
|
InitPixmap(VPHandleCornerType::TopLeft, QStringLiteral("://icon/32x32/rotate-top-left.png"));
|
||||||
|
InitPixmap(VPHandleCornerType::TopRight, QStringLiteral("://icon/32x32/rotate-top-right.png"));
|
||||||
|
InitPixmap(VPHandleCornerType::BottomRight, QStringLiteral("://icon/32x32/rotate-bottom-right.png"));
|
||||||
|
InitPixmap(VPHandleCornerType::BottomLeft, QStringLiteral("://icon/32x32/rotate-bottom-left.png"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::TopLeftHandlerPosition() const -> QPointF
|
||||||
|
{
|
||||||
|
return ControllersRect().topLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::TopRightHandlerPosition() const -> QPointF
|
||||||
|
{
|
||||||
|
QRectF rect = ControllersRect();
|
||||||
|
QPixmap handler = m_handlePixmaps.value(VPHandleCornerType::TopRight);
|
||||||
|
QSize size = handler.size() / handler.devicePixelRatio();
|
||||||
|
return {rect.topLeft().x() + (rect.width() - size.width()), rect.topLeft().y()};
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::BottomRightHandlerPosition() const -> QPointF
|
||||||
|
{
|
||||||
|
QRectF rect = ControllersRect();
|
||||||
|
QPixmap handler = m_handlePixmaps.value(VPHandleCornerType::BottomRight);
|
||||||
|
QSize size = handler.size() / handler.devicePixelRatio();
|
||||||
|
return {rect.topLeft().x() + (rect.width() - size.width()),
|
||||||
|
rect.topLeft().y() + (rect.height() - size.height())};
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::BottomLeftHandlerPosition() const -> QPointF
|
||||||
|
{
|
||||||
|
QRectF rect = ControllersRect();
|
||||||
|
QPixmap handler = m_handlePixmaps.value(VPHandleCornerType::BottomLeft);
|
||||||
|
QSize size = handler.size() / handler.devicePixelRatio();
|
||||||
|
return {rect.topLeft().x(), rect.topLeft().y() + (rect.height() - size.height())};
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::ControllerPath(VPHandleCornerType type, QPointF pos) const -> QPainterPath
|
||||||
|
{
|
||||||
|
QTransform t;
|
||||||
|
t.translate(pos.x(), pos.y());
|
||||||
|
|
||||||
|
QPainterPath controller = m_handlePaths.value(type);
|
||||||
|
|
||||||
|
controller = t.map(controller);
|
||||||
|
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::TopLeftControl() const -> QPainterPath
|
||||||
|
{
|
||||||
|
return ControllerPath(VPHandleCornerType::TopLeft, TopLeftHandlerPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::TopRightControl() const -> QPainterPath
|
||||||
|
{
|
||||||
|
return ControllerPath(VPHandleCornerType::TopRight, TopRightHandlerPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::BottomRightControl() const -> QPainterPath
|
||||||
|
{
|
||||||
|
return ControllerPath(VPHandleCornerType::BottomRight, BottomRightHandlerPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::BottomLeftControl() const -> QPainterPath
|
||||||
|
{
|
||||||
|
return ControllerPath(VPHandleCornerType::BottomLeft, BottomLeftHandlerPosition());
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VPGraphicsPieceControls::SetIgnorePieceTransformation(bool newIgnorePieceTransformation)
|
void VPGraphicsPieceControls::SetIgnorePieceTransformation(bool newIgnorePieceTransformation)
|
||||||
{
|
{
|
||||||
m_ignorePieceTransformation = newIgnorePieceTransformation;
|
m_ignorePieceTransformation = newIgnorePieceTransformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
auto VPGraphicsPieceControls::TopLeftControl(QPainter *painter) const -> QPainterPath
|
|
||||||
{
|
|
||||||
return Controller(QTransform(), painter);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
auto VPGraphicsPieceControls::TopRightControl(QPainter *painter) const -> QPainterPath
|
|
||||||
{
|
|
||||||
QTransform t;
|
|
||||||
t.scale(-1, 1);
|
|
||||||
t.translate(-(m_pieceRect.topLeft().x() * 2. + m_pieceRect.width()), 0);
|
|
||||||
|
|
||||||
return Controller(t, painter);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
auto VPGraphicsPieceControls::BottomLeftControl(QPainter *painter) const -> QPainterPath
|
|
||||||
{
|
|
||||||
QTransform t;
|
|
||||||
t.scale(1, -1);
|
|
||||||
t.translate(0, -(m_pieceRect.topLeft().y() * 2. + m_pieceRect.height()));
|
|
||||||
|
|
||||||
return Controller(t, painter);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
auto VPGraphicsPieceControls::BottomRightControl(QPainter *painter) const -> QPainterPath
|
|
||||||
{
|
|
||||||
QTransform t;
|
|
||||||
t.scale(-1, -1);
|
|
||||||
t.translate(-(m_pieceRect.topLeft().x() * 2. + m_pieceRect.width()),
|
|
||||||
-(m_pieceRect.topLeft().y() * 2. + m_pieceRect.height()));
|
|
||||||
|
|
||||||
return Controller(t, painter);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VPGraphicsPieceControls::Handles() const -> QPainterPath
|
auto VPGraphicsPieceControls::Handles() const -> QPainterPath
|
||||||
{
|
{
|
||||||
|
@ -647,161 +782,34 @@ auto VPGraphicsPieceControls::Handles() const -> QPainterPath
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
auto VPGraphicsPieceControls::Controller(const QTransform &t, QPainter *painter) const -> QPainterPath
|
|
||||||
{
|
|
||||||
if (painter != nullptr)
|
|
||||||
{
|
|
||||||
QPen pen = painter->pen();
|
|
||||||
pen.setColor(defaultColor);
|
|
||||||
painter->setPen(pen);
|
|
||||||
}
|
|
||||||
|
|
||||||
QBrush colorBrush(defaultColor);
|
|
||||||
|
|
||||||
QPainterPath controller = ArrowPath();
|
|
||||||
controller = t.map(controller);
|
|
||||||
|
|
||||||
if (painter != nullptr)
|
|
||||||
{
|
|
||||||
painter->save();
|
|
||||||
painter->setBrush(colorBrush);
|
|
||||||
painter->drawPath(controller);
|
|
||||||
painter->restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
return controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VPGraphicsPieceControls::ControllersRect() const -> QRectF
|
auto VPGraphicsPieceControls::ControllersRect() const -> QRectF
|
||||||
{
|
{
|
||||||
const qreal scale = SceneScale(scene());
|
const qreal scale = SceneScale(scene());
|
||||||
|
QPixmap handler = m_handlePixmaps.value(VPHandleCornerType::TopLeft);
|
||||||
|
QRectF pieceRect = m_pieceRect;
|
||||||
|
|
||||||
|
pieceRect = QRectF(pieceRect.topLeft()*scale, QSizeF(pieceRect.width()*scale, pieceRect.height()*scale));
|
||||||
|
QRectF rect = pieceRect;
|
||||||
|
|
||||||
|
if (pieceRect.width() < handler.width())
|
||||||
|
{
|
||||||
|
qreal diff = handler.width() - pieceRect.width();
|
||||||
|
rect.adjust(0, 0, diff, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pieceRect.height() < handler.height())
|
||||||
|
{
|
||||||
|
qreal diff = handler.height() - pieceRect.height();
|
||||||
|
rect.adjust(0, 0, 0, diff);
|
||||||
|
}
|
||||||
|
|
||||||
const qreal gap = 2;
|
const qreal gap = 2;
|
||||||
QRectF rect = m_pieceRect;
|
rect.adjust(- (handler.width() + gap), - (handler.height() + gap), handler.width() + gap, handler.height() + gap);
|
||||||
const qreal minWidth = arcRadius/scale+gap;
|
|
||||||
const qreal minHeight = arcRadius/scale+gap;
|
|
||||||
|
|
||||||
if (m_pieceRect.width() < minWidth)
|
|
||||||
{
|
|
||||||
qreal diff = minWidth - m_pieceRect.width();
|
|
||||||
rect.adjust(-diff/2., 0, diff/2., 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pieceRect.height() < minHeight)
|
|
||||||
{
|
|
||||||
qreal diff = minHeight - m_pieceRect.height();
|
|
||||||
rect.adjust(0, -diff/2., 0, diff/2.);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
auto VPGraphicsPieceControls::ArrowPath() const -> QPainterPath
|
|
||||||
{
|
|
||||||
const qreal scale = SceneScale(scene())/2;
|
|
||||||
QPainterPath arrow;
|
|
||||||
|
|
||||||
QRectF pieceRect = ControllersRect();
|
|
||||||
|
|
||||||
QLineF start(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
|
||||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius+1)/scale);
|
|
||||||
start.setAngle(arcStartAngle);
|
|
||||||
|
|
||||||
arrow.moveTo(start.p2());
|
|
||||||
|
|
||||||
QLineF baseLine(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
|
||||||
baseLine.setAngle(arrow1Angle);
|
|
||||||
arrow.lineTo(baseLine.p2());
|
|
||||||
|
|
||||||
QLineF leftSide = QLineF(baseLine.p2(), baseLine.p1());
|
|
||||||
leftSide.setLength(arrowSide/scale);
|
|
||||||
leftSide.setAngle(leftSide.angle()-90);
|
|
||||||
arrow.lineTo(leftSide.p2());
|
|
||||||
|
|
||||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
|
||||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - arcRadius/scale);
|
|
||||||
start.setAngle(arcStartAngle);
|
|
||||||
|
|
||||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+(arrowTail+arrowLength)/scale, start.p2().y()));
|
|
||||||
baseLine.setAngle(arrow1Angle);
|
|
||||||
arrow.lineTo(baseLine.p2());
|
|
||||||
|
|
||||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
|
||||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius-1)/scale);
|
|
||||||
start.setAngle(arcStartAngle);
|
|
||||||
|
|
||||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
|
||||||
baseLine.setAngle(arrow1Angle);
|
|
||||||
|
|
||||||
QLineF rightSide = QLineF(baseLine.p2(), baseLine.p1());
|
|
||||||
rightSide.setLength(arrowSide/scale);
|
|
||||||
rightSide.setAngle(rightSide.angle()+90);
|
|
||||||
arrow.lineTo(rightSide.p2());
|
|
||||||
|
|
||||||
arrow.lineTo(baseLine.p2());
|
|
||||||
arrow.lineTo(start.p2());
|
|
||||||
|
|
||||||
// arc 1
|
|
||||||
QRectF arc1Rect(pieceRect.topLeft().x()-(arcRadius-1)/scale, pieceRect.topLeft().y()-(arcRadius-1)/scale,
|
|
||||||
(arcRadius-1)/scale*2, (arcRadius-1)/scale*2);
|
|
||||||
arrow.arcTo(arc1Rect, arcStartAngle, arcAngle);
|
|
||||||
|
|
||||||
// arrow 2
|
|
||||||
|
|
||||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
|
||||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius-1)/scale);
|
|
||||||
start.setAngle(arcStartAngle+arcAngle);
|
|
||||||
|
|
||||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
|
||||||
baseLine.setAngle(arrow2Angle+180);
|
|
||||||
arrow.lineTo(baseLine.p2());
|
|
||||||
|
|
||||||
leftSide = QLineF(baseLine.p2(), baseLine.p1());
|
|
||||||
leftSide.setLength(arrowSide/scale);
|
|
||||||
leftSide.setAngle(leftSide.angle()-90);
|
|
||||||
arrow.lineTo(leftSide.p2());
|
|
||||||
|
|
||||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
|
||||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - arcRadius/scale);
|
|
||||||
start.setAngle(arcStartAngle+arcAngle);
|
|
||||||
|
|
||||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+(arrowTail+arrowLength)/scale, start.p2().y()));
|
|
||||||
baseLine.setAngle(arrow2Angle+180);
|
|
||||||
arrow.lineTo(baseLine.p2());
|
|
||||||
|
|
||||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
|
||||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius+1)/scale);
|
|
||||||
start.setAngle(arcStartAngle+arcAngle);
|
|
||||||
|
|
||||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
|
||||||
baseLine.setAngle(arrow2Angle+180);
|
|
||||||
|
|
||||||
rightSide = QLineF(baseLine.p2(), baseLine.p1());
|
|
||||||
rightSide.setLength(arrowSide/scale);
|
|
||||||
rightSide.setAngle(rightSide.angle()+90);
|
|
||||||
arrow.lineTo(rightSide.p2());
|
|
||||||
|
|
||||||
arrow.lineTo(baseLine.p2());
|
|
||||||
arrow.lineTo(start.p2());
|
|
||||||
|
|
||||||
// arc 2
|
|
||||||
QRectF arc2Rect(pieceRect.topLeft().x()-(arcRadius+1)/scale, pieceRect.topLeft().y()-(arcRadius+1)/scale,
|
|
||||||
(arcRadius+1)/scale*2, (arcRadius+1)/scale*2);
|
|
||||||
QPainterPath arc;
|
|
||||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
|
||||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius+1)/scale);
|
|
||||||
start.setAngle(arcStartAngle);
|
|
||||||
|
|
||||||
arc.moveTo(start.p2());
|
|
||||||
arc.arcTo(arc2Rect, arcStartAngle, arcAngle);
|
|
||||||
arrow.addPath(arc.toReversed());
|
|
||||||
|
|
||||||
return arrow;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VPGraphicsPieceControls::SelectedPieces() const -> QList<VPPiecePtr>
|
auto VPGraphicsPieceControls::SelectedPieces() const -> QList<VPPiecePtr>
|
||||||
{
|
{
|
||||||
|
@ -836,27 +844,74 @@ auto VPGraphicsPieceControls::PiecesBoundingRect(const QList<VPPiecePtr> &select
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VPGraphicsPieceControls::SelectedHandleCorner(const QPointF &pos) const -> int
|
auto VPGraphicsPieceControls::ItemView() -> QGraphicsView *
|
||||||
{
|
{
|
||||||
if (TopLeftControl().boundingRect().contains(pos))
|
QGraphicsScene *scene = this->scene();
|
||||||
|
if (scene != nullptr)
|
||||||
{
|
{
|
||||||
return static_cast<int>(HandleCorner::BottomRight);
|
QList<QGraphicsView *> views = scene->views();
|
||||||
|
if (not views.isEmpty())
|
||||||
|
{
|
||||||
|
return views.at(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TopRightControl().boundingRect().contains(pos))
|
return nullptr;
|
||||||
{
|
}
|
||||||
return static_cast<int>(HandleCorner::BottomLeft);
|
|
||||||
}
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VPGraphicsPieceControls::UpdateCursor(VPHandleCorner corner)
|
||||||
if (BottomLeftControl().boundingRect().contains(pos))
|
{
|
||||||
{
|
m_handleCorner = corner;
|
||||||
return static_cast<int>(HandleCorner::TopRight);
|
|
||||||
}
|
if (m_handleCorner != VPHandleCorner::Invalid)
|
||||||
|
{
|
||||||
if (BottomRightControl().boundingRect().contains(pos))
|
setCursor(QCursor(Qt::OpenHandCursor));
|
||||||
{
|
}
|
||||||
return static_cast<int>(HandleCorner::TopLeft);
|
else
|
||||||
}
|
{
|
||||||
|
QGraphicsView *view = ItemView();
|
||||||
return static_cast<int>(HandleCorner::Invalid);
|
if (view != nullptr)
|
||||||
|
{
|
||||||
|
setCursor(view->viewport()->cursor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::SelectedHandleCorner(const QPointF &pos) const -> VPHandleCorner
|
||||||
|
{
|
||||||
|
QMap<VPHandleCorner, QPainterPath> corners
|
||||||
|
{
|
||||||
|
{VPHandleCorner::TopLeft, TopLeftControl()},
|
||||||
|
{VPHandleCorner::TopRight, TopRightControl()},
|
||||||
|
{VPHandleCorner::BottomRight, BottomRightControl()},
|
||||||
|
{VPHandleCorner::BottomLeft, BottomLeftControl()},
|
||||||
|
};
|
||||||
|
|
||||||
|
QPainterPath circle;
|
||||||
|
circle.addEllipse(pos.x()-4, pos.y()-4, 8, 8);
|
||||||
|
|
||||||
|
auto CheckCorner = [circle](const QPainterPath &handler)
|
||||||
|
{
|
||||||
|
return handler.intersects(circle) || handler.contains(circle);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto i = corners.constBegin();
|
||||||
|
while (i != corners.constEnd())
|
||||||
|
{
|
||||||
|
if (CheckCorner(i.value()))
|
||||||
|
{
|
||||||
|
return i.key();
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VPHandleCorner::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VPGraphicsPieceControls::HandlerPixmap(bool hover, VPHandleCornerType type) const -> QPixmap
|
||||||
|
{
|
||||||
|
return hover ? m_handleHoverPixmaps.value(type) : m_handlePixmaps.value(type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,16 +34,38 @@
|
||||||
#include "scenedef.h"
|
#include "scenedef.h"
|
||||||
#include "../layout/vpsheet.h"
|
#include "../layout/vpsheet.h"
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||||
|
#include "../vmisc/defglobal.h"
|
||||||
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||||
|
|
||||||
class VPLayout;
|
class VPLayout;
|
||||||
class VPGraphicsPiece;
|
class VPGraphicsPiece;
|
||||||
|
class QGraphicsView;
|
||||||
|
|
||||||
|
enum class VPHandleCorner : int
|
||||||
|
{
|
||||||
|
Invalid = 0,
|
||||||
|
TopLeft = 1,
|
||||||
|
TopRight = 2,
|
||||||
|
BottomRight = 3,
|
||||||
|
BottomLeft = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class VPHandleCornerType
|
||||||
|
{
|
||||||
|
TopLeft,
|
||||||
|
TopRight,
|
||||||
|
BottomRight,
|
||||||
|
BottomLeft
|
||||||
|
};
|
||||||
|
|
||||||
class VPGraphicsTransformationOrigin : public QGraphicsObject
|
class VPGraphicsTransformationOrigin : public QGraphicsObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT // NOLINT
|
||||||
public:
|
public:
|
||||||
explicit VPGraphicsTransformationOrigin(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
|
explicit VPGraphicsTransformationOrigin(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
|
||||||
|
|
||||||
virtual int type() const override {return Type;}
|
auto type() const -> int override {return Type;}
|
||||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::TransformationOrigin)};
|
enum { Type = UserType + static_cast<int>(PGraphicsItem::TransformationOrigin)};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -64,7 +86,7 @@ protected:
|
||||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(VPGraphicsTransformationOrigin)
|
Q_DISABLE_COPY_MOVE(VPGraphicsTransformationOrigin) // NOLINT
|
||||||
|
|
||||||
bool m_originVisible{true};
|
bool m_originVisible{true};
|
||||||
VPLayoutWeakPtr m_layout{};
|
VPLayoutWeakPtr m_layout{};
|
||||||
|
@ -78,11 +100,11 @@ private:
|
||||||
|
|
||||||
class VPGraphicsPieceControls : public QGraphicsObject
|
class VPGraphicsPieceControls : public QGraphicsObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT // NOLINT
|
||||||
public:
|
public:
|
||||||
explicit VPGraphicsPieceControls(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
|
explicit VPGraphicsPieceControls(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
|
||||||
|
|
||||||
virtual int type() const override {return Type;}
|
auto type() const -> int override {return Type;}
|
||||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::Handles)};
|
enum { Type = UserType + static_cast<int>(PGraphicsItem::Handles)};
|
||||||
|
|
||||||
void SetIgnorePieceTransformation(bool newIgnorePieceTransformation);
|
void SetIgnorePieceTransformation(bool newIgnorePieceTransformation);
|
||||||
|
@ -100,39 +122,58 @@ protected:
|
||||||
auto shape() const -> QPainterPath override;
|
auto shape() const -> QPainterPath override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||||
|
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent * event) override;
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event) override;
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||||
|
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||||
|
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(VPGraphicsPieceControls)
|
Q_DISABLE_COPY_MOVE(VPGraphicsPieceControls) // NOLINT
|
||||||
|
|
||||||
QRectF m_pieceRect{};
|
QRectF m_pieceRect{};
|
||||||
QPointF m_rotationStartPoint{};
|
QPointF m_rotationStartPoint{};
|
||||||
qreal m_rotationSum{0};
|
qreal m_rotationSum{0};
|
||||||
bool m_controlsVisible{true};
|
bool m_controlsVisible{false};
|
||||||
VPLayoutWeakPtr m_layout{};
|
VPLayoutWeakPtr m_layout{};
|
||||||
int m_handleCorner{0};
|
VPHandleCorner m_handleCorner{VPHandleCorner::Invalid};
|
||||||
VPTransformationOrigon m_savedOrigin{};
|
VPTransformationOrigon m_savedOrigin{};
|
||||||
bool m_originSaved{false};
|
bool m_originSaved{false};
|
||||||
bool allowChangeMerge{false};
|
bool allowChangeMerge{false};
|
||||||
QList<VPPiecePtr> m_selectedPieces{};
|
QList<VPPiecePtr> m_selectedPieces{};
|
||||||
bool m_ignorePieceTransformation{false};
|
bool m_ignorePieceTransformation{false};
|
||||||
|
|
||||||
auto TopLeftControl(QPainter *painter = nullptr) const -> QPainterPath;
|
QMap<VPHandleCornerType, QPixmap> m_handlePixmaps{};
|
||||||
auto TopRightControl(QPainter *painter = nullptr) const -> QPainterPath;
|
QMap<VPHandleCornerType, QPixmap> m_handleHoverPixmaps{};
|
||||||
auto BottomLeftControl(QPainter *painter = nullptr) const -> QPainterPath;
|
QMap<VPHandleCornerType, QPainterPath> m_handlePaths{};
|
||||||
auto BottomRightControl(QPainter *painter = nullptr) const -> QPainterPath;
|
|
||||||
|
void InitPixmaps();
|
||||||
|
|
||||||
|
auto TopLeftHandlerPosition() const -> QPointF;
|
||||||
|
auto TopRightHandlerPosition() const -> QPointF;
|
||||||
|
auto BottomRightHandlerPosition() const -> QPointF;
|
||||||
|
auto BottomLeftHandlerPosition() const -> QPointF;
|
||||||
|
|
||||||
|
auto ControllerPath(VPHandleCornerType type, QPointF pos) const -> QPainterPath;
|
||||||
|
auto TopLeftControl() const -> QPainterPath;
|
||||||
|
auto TopRightControl() const -> QPainterPath;
|
||||||
|
auto BottomRightControl() const -> QPainterPath;
|
||||||
|
auto BottomLeftControl() const -> QPainterPath;
|
||||||
|
|
||||||
auto Handles() const -> QPainterPath;
|
auto Handles() const -> QPainterPath;
|
||||||
auto Controller(const QTransform &t, QPainter *painter = nullptr) const -> QPainterPath;
|
|
||||||
auto ControllersRect() const -> QRectF;
|
auto ControllersRect() const -> QRectF;
|
||||||
|
|
||||||
auto ArrowPath() const -> QPainterPath;
|
auto SelectedHandleCorner(const QPointF &pos) const -> VPHandleCorner;
|
||||||
|
|
||||||
auto SelectedHandleCorner(const QPointF &pos) const -> int;
|
auto HandlerPixmap(bool hover, VPHandleCornerType type) const -> QPixmap;
|
||||||
|
|
||||||
auto SelectedPieces() const -> QList<VPPiecePtr>;
|
auto SelectedPieces() const -> QList<VPPiecePtr>;
|
||||||
static auto PiecesBoundingRect(const QList<VPPiecePtr> &selectedPieces) -> QRectF;
|
static auto PiecesBoundingRect(const QList<VPPiecePtr> &selectedPieces) -> QRectF;
|
||||||
|
|
||||||
|
auto ItemView() -> QGraphicsView *;
|
||||||
|
|
||||||
|
void UpdateCursor(VPHandleCorner corner);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VPGRAPHICSPIECECONTROLS_H
|
#endif // VPGRAPHICSPIECECONTROLS_H
|
||||||
|
|
|
@ -474,25 +474,6 @@ void VPMainGraphicsView::RestoreOrigin() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
void VPMainGraphicsView::on_ItemClicked(QGraphicsItem *item)
|
|
||||||
{
|
|
||||||
if (item == nullptr || (item->type() != VPGraphicsPiece::Type &&
|
|
||||||
item->type() != VPGraphicsPieceControls::Type &&
|
|
||||||
item->type() != VPGraphicsTransformationOrigin::Type))
|
|
||||||
{
|
|
||||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
|
||||||
if (not layout.isNull())
|
|
||||||
{
|
|
||||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
|
||||||
if (not sheet.isNull())
|
|
||||||
{
|
|
||||||
sheet->ClearSelection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VPMainGraphicsView::on_SceneMouseMove(const QPointF &scenePos)
|
void VPMainGraphicsView::on_SceneMouseMove(const QPointF &scenePos)
|
||||||
{
|
{
|
||||||
|
@ -657,8 +638,6 @@ void VPMainGraphicsView::SwitchScene(const VPSheetPtr &sheet)
|
||||||
{
|
{
|
||||||
VMainGraphicsScene *scene = sheet->SceneData()->Scene();
|
VMainGraphicsScene *scene = sheet->SceneData()->Scene();
|
||||||
setScene(scene);
|
setScene(scene);
|
||||||
connect(scene, &VMainGraphicsScene::ItemByMousePress, this, &VPMainGraphicsView::on_ItemClicked,
|
|
||||||
Qt::UniqueConnection);
|
|
||||||
connect(scene, &VMainGraphicsScene::mouseMove, this, &VPMainGraphicsView::on_SceneMouseMove,
|
connect(scene, &VMainGraphicsScene::mouseMove, this, &VPMainGraphicsView::on_SceneMouseMove,
|
||||||
Qt::UniqueConnection);
|
Qt::UniqueConnection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,6 @@ protected:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void RestoreOrigin() const;
|
void RestoreOrigin() const;
|
||||||
void on_ItemClicked(QGraphicsItem* item);
|
|
||||||
void on_SceneMouseMove(const QPointF &scenePos);
|
void on_SceneMouseMove(const QPointF &scenePos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -45,25 +45,8 @@
|
||||||
#include "../vmisc/vmath.h"
|
#include "../vmisc/vmath.h"
|
||||||
#include "../vwidgets/vmaingraphicsview.h"
|
#include "../vwidgets/vmaingraphicsview.h"
|
||||||
|
|
||||||
extern auto qt_regionToPath(const QRegion ®ion) -> QPainterPath;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
auto PixmapToPainterPath(const QPixmap &pixmap) -> QPainterPath
|
|
||||||
{
|
|
||||||
if (not pixmap.isNull())
|
|
||||||
{
|
|
||||||
QBitmap mask = pixmap.mask();
|
|
||||||
if (not mask.isNull())
|
|
||||||
{
|
|
||||||
return qt_regionToPath(QRegion(mask));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto RectTopPoint(const QRectF &rect) -> QPointF
|
auto RectTopPoint(const QRectF &rect) -> QPointF
|
||||||
{
|
{
|
||||||
|
@ -466,68 +449,21 @@ void VBackgroundImageControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VBackgroundImageControls::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
void VBackgroundImageControls::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||||
{
|
{
|
||||||
m_handleCornerHover = SelectedHandleCorner(event->pos());
|
UpdateCursor(SelectedHandleCorner(event->pos()));
|
||||||
|
|
||||||
if (m_handleCornerHover != BIHandleCorner::Invalid)
|
|
||||||
{
|
|
||||||
if (not m_image.Hold())
|
|
||||||
{
|
|
||||||
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
|
||||||
}
|
|
||||||
QGraphicsObject::hoverEnterEvent(event);
|
QGraphicsObject::hoverEnterEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VBackgroundImageControls::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
void VBackgroundImageControls::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||||
{
|
{
|
||||||
m_handleCornerHover = SelectedHandleCorner(event->pos());
|
UpdateCursor(SelectedHandleCorner(event->pos()));
|
||||||
if (m_handleCornerHover != BIHandleCorner::Invalid)
|
|
||||||
{
|
|
||||||
if (not m_image.Hold())
|
|
||||||
{
|
|
||||||
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
|
||||||
}
|
|
||||||
QGraphicsObject::hoverMoveEvent(event);
|
QGraphicsObject::hoverMoveEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VBackgroundImageControls::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
void VBackgroundImageControls::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||||
{
|
{
|
||||||
m_handleCornerHover = BIHandleCorner::Invalid;
|
UpdateCursor(BIHandleCorner::Invalid);
|
||||||
|
|
||||||
if (SelectedHandleCorner(event->pos()) != BIHandleCorner::Invalid)
|
|
||||||
{
|
|
||||||
if (not m_image.Hold())
|
|
||||||
{
|
|
||||||
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
|
||||||
}
|
|
||||||
QGraphicsObject::hoverLeaveEvent(event);
|
QGraphicsObject::hoverLeaveEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1894,3 +1830,25 @@ void VBackgroundImageControls::RotateImage(QGraphicsSceneMouseEvent *event)
|
||||||
m_allowChangeMerge = true;
|
m_allowChangeMerge = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VBackgroundImageControls::UpdateCursor(BIHandleCorner corner)
|
||||||
|
{
|
||||||
|
m_handleCornerHover = corner;
|
||||||
|
|
||||||
|
if (m_handleCornerHover != BIHandleCorner::Invalid)
|
||||||
|
{
|
||||||
|
if (not m_image.Hold())
|
||||||
|
{
|
||||||
|
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setCursor(VAbstractValApplication::VApp()->getSceneView()->viewport()->cursor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ enum class BIHandleCornerType
|
||||||
|
|
||||||
class VBackgroundImageControls : public QGraphicsObject
|
class VBackgroundImageControls : public QGraphicsObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT // NOLINT
|
||||||
public:
|
public:
|
||||||
explicit VBackgroundImageControls(VAbstractPattern *doc, QGraphicsItem * parent = nullptr);
|
explicit VBackgroundImageControls(VAbstractPattern *doc, QGraphicsItem * parent = nullptr);
|
||||||
~VBackgroundImageControls() override = default;
|
~VBackgroundImageControls() override = default;
|
||||||
|
@ -104,7 +104,7 @@ private slots:
|
||||||
void ScreenChanged();
|
void ScreenChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY_MOVE(VBackgroundImageControls)
|
Q_DISABLE_COPY_MOVE(VBackgroundImageControls) // NOLINT
|
||||||
|
|
||||||
QUuid m_id{};
|
QUuid m_id{};
|
||||||
VAbstractPattern *m_doc;
|
VAbstractPattern *m_doc;
|
||||||
|
@ -180,6 +180,8 @@ private:
|
||||||
|
|
||||||
void ScaleImage(QGraphicsSceneMouseEvent * event);
|
void ScaleImage(QGraphicsSceneMouseEvent * event);
|
||||||
void RotateImage(QGraphicsSceneMouseEvent * event);
|
void RotateImage(QGraphicsSceneMouseEvent * event);
|
||||||
|
|
||||||
|
void UpdateCursor(BIHandleCorner corner);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VBACKGROUNDIMAGECONTROLS_H
|
#endif // VBACKGROUNDIMAGECONTROLS_H
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "../vmisc/vabstractapplication.h"
|
#include "../vmisc/vabstractapplication.h"
|
||||||
#include "../vmisc/compatibility.h"
|
#include "../vmisc/compatibility.h"
|
||||||
|
|
||||||
|
#include <QBitmap>
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
@ -38,6 +39,8 @@
|
||||||
|
|
||||||
const qreal minVisibleFontSize = 5;
|
const qreal minVisibleFontSize = 5;
|
||||||
|
|
||||||
|
extern auto qt_regionToPath(const QRegion ®ion) -> QPainterPath;
|
||||||
|
|
||||||
inline qreal DefPointRadiusPixel()
|
inline qreal DefPointRadiusPixel()
|
||||||
{
|
{
|
||||||
return (VAbstractApplication::VApp()->Settings()->GetLineWidth() + 0.8) / 25.4 * PrintDPI;
|
return (VAbstractApplication::VApp()->Settings()->GetLineWidth() + 0.8) / 25.4 * PrintDPI;
|
||||||
|
@ -140,6 +143,21 @@ QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto PixmapToPainterPath(const QPixmap &pixmap) -> QPainterPath
|
||||||
|
{
|
||||||
|
if (not pixmap.isNull())
|
||||||
|
{
|
||||||
|
QBitmap mask = pixmap.mask();
|
||||||
|
if (not mask.isNull())
|
||||||
|
{
|
||||||
|
return qt_regionToPath(QRegion(mask));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void GraphicsItemHighlightSelected(const QRectF &boundingRect, qreal itemPenWidth, QPainter *painter,
|
void GraphicsItemHighlightSelected(const QRectF &boundingRect, qreal itemPenWidth, QPainter *painter,
|
||||||
const QStyleOptionGraphicsItem *option)
|
const QStyleOptionGraphicsItem *option)
|
||||||
|
|
|
@ -57,6 +57,8 @@ qreal ScaleWidth(qreal width, qreal scale);
|
||||||
|
|
||||||
QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen);
|
QPainterPath ItemShapeFromPath(const QPainterPath &path, const QPen &pen);
|
||||||
|
|
||||||
|
auto PixmapToPainterPath(const QPixmap &pixmap) -> QPainterPath;
|
||||||
|
|
||||||
void GraphicsItemHighlightSelected(const QRectF &boundingRect, qreal itemPenWidth, QPainter *painter,
|
void GraphicsItemHighlightSelected(const QRectF &boundingRect, qreal itemPenWidth, QPainter *painter,
|
||||||
const QStyleOptionGraphicsItem *option);
|
const QStyleOptionGraphicsItem *option);
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,11 @@
|
||||||
#include <QStringData>
|
#include <QStringData>
|
||||||
#include <QStringDataPtr>
|
#include <QStringDataPtr>
|
||||||
#include <Qt>
|
#include <Qt>
|
||||||
|
#include <QGraphicsView>
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "../vmisc/vabstractapplication.h"
|
#include "../vmisc/vabstractapplication.h"
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* @brief VMainGraphicsScene default constructor.
|
* @brief VMainGraphicsScene default constructor.
|
||||||
|
@ -95,11 +95,17 @@ void VMainGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
||||||
{
|
{
|
||||||
emit MouseLeftPressed();
|
emit MouseLeftPressed();
|
||||||
|
|
||||||
|
QTransform deviceTransform;
|
||||||
|
auto *view = qobject_cast<QGraphicsView *>(event->widget());
|
||||||
|
if (view != nullptr)
|
||||||
|
{
|
||||||
|
deviceTransform = view->transform();
|
||||||
|
}
|
||||||
|
emit ItemByMousePress(itemAt(event->scenePos(), deviceTransform));
|
||||||
}
|
}
|
||||||
|
|
||||||
QGraphicsScene::mousePressEvent(event);
|
QGraphicsScene::mousePressEvent(event);
|
||||||
|
|
||||||
emit ItemByMousePress(itemAt(event->scenePos(), {}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -108,7 +114,14 @@ void VMainGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
||||||
{
|
{
|
||||||
emit MouseLeftReleased();
|
emit MouseLeftReleased();
|
||||||
emit ItemByMouseRelease(itemAt(event->scenePos(), {}));
|
|
||||||
|
QTransform deviceTransform;
|
||||||
|
auto *view = qobject_cast<QGraphicsView *>(event->widget());
|
||||||
|
if (view != nullptr)
|
||||||
|
{
|
||||||
|
deviceTransform = view->transform();
|
||||||
|
}
|
||||||
|
emit ItemByMouseRelease(itemAt(event->scenePos(), deviceTransform));
|
||||||
}
|
}
|
||||||
QGraphicsScene::mouseReleaseEvent(event);
|
QGraphicsScene::mouseReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user