Sticky edges.
This commit is contained in:
parent
3d9a4f6f65
commit
b877009d90
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "../vmisc/def.h"
|
||||
#include "vpsheet.h"
|
||||
#include "vplayout.h"
|
||||
#include "../vlayout/vtextmanager.h"
|
||||
|
||||
#include <QIcon>
|
||||
|
@ -39,6 +40,86 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(pPiece, "p.piece")
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr qreal minStickyDistance = ToPixel(3, Unit::Mm);
|
||||
constexpr qreal maxStickyDistance = ToPixel(10, Unit::Mm);
|
||||
constexpr qreal stickyShift = ToPixel(1, Unit::Mm);
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto CutEdge(const QLineF &edge) -> QVector<QPointF>
|
||||
{
|
||||
QVector<QPointF> points;
|
||||
if (qFuzzyIsNull(stickyShift))
|
||||
{
|
||||
points.append(edge.p1());
|
||||
points.append(edge.p2());
|
||||
}
|
||||
else
|
||||
{
|
||||
const int n = qFloor(edge.length()/stickyShift);
|
||||
|
||||
if (n <= 0)
|
||||
{
|
||||
points.append(edge.p1());
|
||||
points.append(edge.p2());
|
||||
}
|
||||
else
|
||||
{
|
||||
points.reserve(n);
|
||||
const qreal nShift = edge.length()/n;
|
||||
for (int i = 1; i <= n+1; ++i)
|
||||
{
|
||||
QLineF l1 = edge;
|
||||
l1.setLength(nShift*(i-1));
|
||||
points.append(l1.p2());
|
||||
}
|
||||
}
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto PrepareStickyPath(const QVector<QPointF> &path) -> QVector<QPointF>
|
||||
{
|
||||
if (path.size() < 2)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
QVector<QPointF> stickyPath;
|
||||
|
||||
for (int i=0; i<path.size(); ++i)
|
||||
{
|
||||
stickyPath += CutEdge(QLineF(path.at(i), path.at(i < path.size()-1 ? i+1 : 0)));
|
||||
}
|
||||
|
||||
return stickyPath;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto ClosestDistance(const QVector<QPointF> &path1, const QVector<QPointF> &path2) -> QLineF
|
||||
{
|
||||
qreal distance = INT_MAX;
|
||||
QLineF closestDistance;
|
||||
|
||||
for (auto p1 : path1)
|
||||
{
|
||||
for (auto p2 : path2)
|
||||
{
|
||||
QLineF d(p1, p2);
|
||||
if (d.length() <= distance)
|
||||
{
|
||||
distance = d.length();
|
||||
closestDistance = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closestDistance;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPPiece::VPPiece(const VLayoutPiece &layoutPiece)
|
||||
: VLayoutPiece(layoutPiece)
|
||||
|
@ -239,3 +320,111 @@ void VPPiece::Flip()
|
|||
SetMatrix(pieceMatrix);
|
||||
SetMirror(!IsMirror());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::StickyPosition(qreal &dx, qreal &dy) const -> bool
|
||||
{
|
||||
VPLayoutPtr layout = Layout();
|
||||
if (layout.isNull() || not layout->LayoutSettings().GetStickyEdges())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const qreal pieceGap = layout->LayoutSettings().GetPiecesGap();
|
||||
if (pieceGap <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
VPSheetPtr sheet = Sheet();
|
||||
if (sheet.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<VPPiecePtr> allPieces = sheet->GetPieces();
|
||||
|
||||
if (allPieces.count() < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<QPointF> path = GetMappedExternalContourPoints();
|
||||
QRectF boundingRect = VLayoutPiece::BoundingRect(path);
|
||||
const qreal stickyDistance = pieceGap+minStickyDistance;
|
||||
QRectF stickyZone = QRectF(boundingRect.topLeft().x()-stickyDistance, boundingRect.topLeft().y()-stickyDistance,
|
||||
boundingRect.width()+stickyDistance*2, boundingRect.height()+stickyDistance*2);
|
||||
|
||||
QVector<QPointF> stickyPath = PrepareStickyPath(path);
|
||||
QLineF closestDistance;
|
||||
|
||||
for (const auto& piece : allPieces)
|
||||
{
|
||||
if (piece.isNull() || piece->GetUniqueID() == GetUniqueID())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<QPointF> piecePath = piece->GetMappedExternalContourPoints();
|
||||
QRectF pieceBoundingRect = VLayoutPiece::BoundingRect(piecePath);
|
||||
|
||||
if (stickyZone.intersects(pieceBoundingRect) || pieceBoundingRect.contains(stickyZone) ||
|
||||
stickyZone.contains(pieceBoundingRect))
|
||||
{
|
||||
if (not VPPiece::PathsSuperposition(path, piecePath))
|
||||
{
|
||||
QVector<QPointF> pieceStickyPath = PrepareStickyPath(piecePath);
|
||||
closestDistance = ClosestDistance(stickyPath, pieceStickyPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closestDistance.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const qreal extraZone = qBound(minStickyDistance, pieceGap * 50 / 100, maxStickyDistance);
|
||||
const qreal length = closestDistance.length();
|
||||
|
||||
if (length > pieceGap && length <= pieceGap + extraZone)
|
||||
{
|
||||
closestDistance.setLength(length - pieceGap);
|
||||
QPointF diff = closestDistance.p2() - closestDistance.p1();
|
||||
dx = diff.x();
|
||||
dy = diff.y();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (length < pieceGap && length >= pieceGap - extraZone)
|
||||
{
|
||||
closestDistance.setAngle(closestDistance.angle() + 180);
|
||||
closestDistance.setLength(pieceGap - length);
|
||||
QPointF diff = closestDistance.p2() - closestDistance.p1();
|
||||
dx = diff.x();
|
||||
dy = diff.y();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::PathsSuperposition(const QVector<QPointF> &path1, const QVector<QPointF> &path2) -> bool
|
||||
{
|
||||
const QRectF path1Rect = VLayoutPiece::BoundingRect(path1);
|
||||
const QPainterPath path1Path = VAbstractPiece::PainterPath(path1);
|
||||
|
||||
const QRectF path2Rect = VLayoutPiece::BoundingRect(path2);
|
||||
const QPainterPath path2Path = VAbstractPiece::PainterPath(path2);
|
||||
|
||||
if (path1Rect.intersects(path2Rect) || path2Rect.contains(path1Rect) || path1Rect.contains(path2Rect))
|
||||
{
|
||||
if (path1Path.contains(path2Path) || path2Path.contains(path1Path) || path1Path.intersects(path2Path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -112,6 +112,10 @@ public:
|
|||
auto HasSuperpositionWithPieces() const -> bool;
|
||||
void SetHasSuperpositionWithPieces(bool newHasSuperpositionWithPieces);
|
||||
|
||||
auto StickyPosition(qreal &dx, qreal &dy) const -> bool;
|
||||
|
||||
static auto PathsSuperposition(const QVector<QPointF> &path1, const QVector<QPointF> &path2) -> bool;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPPiece)
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ void VPSheet::ValidateSuperpositionOfPieces() const
|
|||
|
||||
QVector<QPointF> path2 = p->GetMappedExternalContourPoints();
|
||||
|
||||
bool superposition = PathsSuperposition(path1, path2);
|
||||
bool superposition = VPPiece::PathsSuperposition(path1, path2);
|
||||
if (superposition)
|
||||
{
|
||||
hasSuperposition = superposition;
|
||||
|
@ -313,23 +313,3 @@ void VPSheet::CheckPiecePositionValidity(const VPPiecePtr &piece) const
|
|||
ValidateSuperpositionOfPieces();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPSheet::PathsSuperposition(const QVector<QPointF> &path1, const QVector<QPointF> &path2) const -> bool
|
||||
{
|
||||
const QRectF path1Rect = VLayoutPiece::BoundingRect(path1);
|
||||
const QPainterPath path1Path = VAbstractPiece::PainterPath(path1);
|
||||
|
||||
const QRectF path2Rect = VLayoutPiece::BoundingRect(path2);
|
||||
const QPainterPath path2Path = VAbstractPiece::PainterPath(path2);
|
||||
|
||||
if (path1Rect.intersects(path2Rect) || path2Rect.contains(path1Rect) || path1Rect.contains(path2Rect))
|
||||
{
|
||||
if (path1Path.contains(path2Path) || path2Path.contains(path1Path) || path1Path.intersects(path2Path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ private:
|
|||
|
||||
VPTransformationOrigon m_transformationOrigin{};
|
||||
|
||||
auto PathsSuperposition(const QVector<QPointF> &path1, const QVector<QPointF> &path2) const -> bool;
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(VPSheetPtr)
|
||||
|
|
|
@ -94,6 +94,7 @@ auto VPGraphicsPiece::boundingRect() const -> QRectF
|
|||
shape.addPath(m_internalPaths);
|
||||
shape.addPath(m_passmarks);
|
||||
shape.addPath(m_placeLabels);
|
||||
shape.addPath(m_stickyPath);
|
||||
|
||||
constexpr qreal halfPenWidth = penWidth/2.;
|
||||
|
||||
|
@ -136,6 +137,7 @@ void VPGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
|
||||
m_moveStartPoint = event->pos();
|
||||
emit HideTransformationHandles(true);
|
||||
m_hasStickyPosition = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +163,26 @@ void VPGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
emit HideTransformationHandles(false);
|
||||
|
||||
VPPiecePtr piece = m_piece.toStrongRef();
|
||||
if (not piece.isNull())
|
||||
{
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
if (layout->LayoutSettings().GetStickyEdges() && m_hasStickyPosition)
|
||||
{
|
||||
auto *command = new VPUndoPieceMove(piece, m_stickyTranslateX, m_stickyTranslateY,
|
||||
allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
|
||||
SetStickyPoints(QVector<QPointF>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allowChangeMerge = false;
|
||||
m_hasStickyPosition = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,6 +239,15 @@ void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::SetStickyPoints(const QVector<QPointF> &newStickyPoint)
|
||||
{
|
||||
m_stickyPoints = newStickyPoint;
|
||||
|
||||
prepareGeometryChange();
|
||||
PaintPiece(); // refresh shapes
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::PaintPieceLabel(const QVector<QPointF> &labelShape, const VTextManager &tm, QPainter *painter)
|
||||
{
|
||||
|
@ -329,6 +359,7 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
m_internalPaths = QPainterPath();
|
||||
m_passmarks = QPainterPath();
|
||||
m_placeLabels = QPainterPath();
|
||||
m_stickyPath = QPainterPath();
|
||||
|
||||
VPPiecePtr piece = m_piece.toStrongRef();
|
||||
if (piece.isNull())
|
||||
|
@ -457,6 +488,29 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
|
||||
PaintPieceLabel(piece->GetPieceLabelRect(), piece->GetPieceLabelData(), painter);
|
||||
PaintPieceLabel(piece->GetPatternLabelRect(), piece->GetPatternLabelData(), painter);
|
||||
|
||||
if (not m_stickyPoints.isEmpty())
|
||||
{
|
||||
m_stickyPath.moveTo(m_stickyPoints.first());
|
||||
for (int i = 1; i < m_stickyPoints.size(); i++)
|
||||
{
|
||||
m_stickyPath.lineTo(m_stickyPoints.at(i));
|
||||
}
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(QBrush(Qt::BDiagPattern));
|
||||
|
||||
QPen pen = painter->pen();
|
||||
pen.setStyle(Qt::DashLine);
|
||||
pen.setColor(mainColor);
|
||||
painter->setPen(pen);
|
||||
|
||||
painter->drawPath(m_stickyPath);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -497,8 +551,28 @@ void VPGraphicsPiece::GroupMove(const QPointF &pos)
|
|||
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
auto *command = new VPUndoPieceMove(pieces.first(), newPos.x(), newPos.y(), allowChangeMerge);
|
||||
VPPiecePtr p = pieces.first();
|
||||
auto *command = new VPUndoPieceMove(piece, newPos.x(), newPos.y(), allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
|
||||
if (layout->LayoutSettings().GetStickyEdges())
|
||||
{
|
||||
QVector<QPointF> path;
|
||||
if (not p.isNull() && p->StickyPosition(m_stickyTranslateX, m_stickyTranslateY))
|
||||
{
|
||||
path = p->GetMappedExternalContourPoints();
|
||||
QTransform m;
|
||||
m.translate(m_stickyTranslateX, m_stickyTranslateY);
|
||||
path = m.map(path);
|
||||
m_hasStickyPosition = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hasStickyPosition = false;
|
||||
}
|
||||
|
||||
SetStickyPoints(path);
|
||||
}
|
||||
}
|
||||
else if (pieces.size() > 1)
|
||||
{
|
||||
|
|
|
@ -53,6 +53,8 @@ public:
|
|||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::Piece)};
|
||||
|
||||
void SetStickyPoints(const QVector<QPointF> &newStickyPoint);
|
||||
|
||||
signals:
|
||||
void HideTransformationHandles(bool hide);
|
||||
void PieceTransformationChanged();
|
||||
|
@ -91,6 +93,13 @@ private:
|
|||
|
||||
bool allowChangeMerge{false};
|
||||
|
||||
QVector<QPointF> m_stickyPoints{};
|
||||
QPainterPath m_stickyPath{};
|
||||
|
||||
bool m_hasStickyPosition{false};
|
||||
qreal m_stickyTranslateX{0};
|
||||
qreal m_stickyTranslateY{0};
|
||||
|
||||
void PaintPieceLabel(const QVector<QPointF> &labelShape, const VTextManager &tm, QPainter *painter=nullptr);
|
||||
void PaintPiece(QPainter *painter=nullptr);
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ void VPMainGraphicsView::keyPressEvent(QKeyEvent *event)
|
|||
}
|
||||
else
|
||||
{
|
||||
TranslatePiecesOn(0, 1);
|
||||
TranslatePiecesOn(0, -1);
|
||||
}
|
||||
}
|
||||
else if (event->key() == Qt::Key_Down)
|
||||
|
@ -360,7 +360,48 @@ void VPMainGraphicsView::keyReleaseEvent(QKeyEvent *event)
|
|||
{
|
||||
if (not event->isAutoRepeat())
|
||||
{
|
||||
if (m_hasStickyPosition && not m_graphicsPieces.isEmpty())
|
||||
{
|
||||
VPPiecePtr piece = m_graphicsPieces.first()->GetPiece();
|
||||
if (not piece.isNull())
|
||||
{
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
if (not layout.isNull() && layout->LayoutSettings().GetStickyEdges())
|
||||
{
|
||||
auto PreparePieces = [layout]()
|
||||
{
|
||||
QList<VPPiecePtr> pieces;
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
pieces = sheet->GetSelectedPieces();
|
||||
}
|
||||
|
||||
return pieces;
|
||||
};
|
||||
|
||||
QList<VPPiecePtr> pieces = PreparePieces();
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
VPPiecePtr p = pieces.first();
|
||||
|
||||
auto *command = new VPUndoPieceMove(p, m_stickyTranslateX, m_stickyTranslateY,
|
||||
m_allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
|
||||
VPGraphicsPiece * gPiece = ScenePiece(p);
|
||||
if (gPiece != nullptr)
|
||||
{
|
||||
gPiece->SetStickyPoints(QVector<QPointF>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
m_allowChangeMerge = false;
|
||||
m_hasStickyPosition = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,8 +673,32 @@ void VPMainGraphicsView::TranslatePiecesOn(qreal dx, qreal dy)
|
|||
QList<VPPiecePtr> pieces = PreparePieces();
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
auto *command = new VPUndoPieceMove(pieces.first(), dx, dy, m_allowChangeMerge);
|
||||
VPPiecePtr p = pieces.first();
|
||||
auto *command = new VPUndoPieceMove(p, dx, dy, m_allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
|
||||
if (layout->LayoutSettings().GetStickyEdges())
|
||||
{
|
||||
QVector<QPointF> path;
|
||||
if (not p.isNull() && p->StickyPosition(m_stickyTranslateX, m_stickyTranslateY))
|
||||
{
|
||||
path = p->GetMappedExternalContourPoints();
|
||||
QTransform m;
|
||||
m.translate(m_stickyTranslateX, m_stickyTranslateY);
|
||||
path = m.map(path);
|
||||
m_hasStickyPosition = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hasStickyPosition = false;
|
||||
}
|
||||
|
||||
VPGraphicsPiece *gPiece = ScenePiece(p);
|
||||
if (gPiece != nullptr)
|
||||
{
|
||||
gPiece->SetStickyPoints(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pieces.size() > 1)
|
||||
{
|
||||
|
@ -645,7 +710,7 @@ void VPMainGraphicsView::TranslatePiecesOn(qreal dx, qreal dy)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::on_PieceSheetChanged(const VPPiecePtr &piece)
|
||||
auto VPMainGraphicsView::ScenePiece(const VPPiecePtr &piece) const -> VPGraphicsPiece *
|
||||
{
|
||||
VPGraphicsPiece *_graphicsPiece = nullptr;
|
||||
for(auto *graphicPiece : m_graphicsPieces)
|
||||
|
@ -656,6 +721,14 @@ void VPMainGraphicsView::on_PieceSheetChanged(const VPPiecePtr &piece)
|
|||
}
|
||||
}
|
||||
|
||||
return _graphicsPiece;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::on_PieceSheetChanged(const VPPiecePtr &piece)
|
||||
{
|
||||
VPGraphicsPiece *graphicsPiece = ScenePiece(piece);
|
||||
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
if (layout.isNull())
|
||||
{
|
||||
|
@ -665,22 +738,22 @@ void VPMainGraphicsView::on_PieceSheetChanged(const VPPiecePtr &piece)
|
|||
if (piece->Sheet().isNull() || piece->Sheet() == layout->GetTrashSheet() ||
|
||||
piece->Sheet() != layout->GetFocusedSheet()) // remove
|
||||
{
|
||||
if (_graphicsPiece != nullptr)
|
||||
if (graphicsPiece != nullptr)
|
||||
{
|
||||
scene()->removeItem(_graphicsPiece);
|
||||
m_graphicsPieces.removeAll(_graphicsPiece);
|
||||
delete _graphicsPiece;
|
||||
scene()->removeItem(graphicsPiece);
|
||||
m_graphicsPieces.removeAll(graphicsPiece);
|
||||
delete graphicsPiece;
|
||||
}
|
||||
}
|
||||
else // add
|
||||
{
|
||||
if(_graphicsPiece == nullptr)
|
||||
if(graphicsPiece == nullptr)
|
||||
{
|
||||
_graphicsPiece = new VPGraphicsPiece(piece);
|
||||
m_graphicsPieces.append(_graphicsPiece);
|
||||
ConnectPiece(_graphicsPiece);
|
||||
graphicsPiece = new VPGraphicsPiece(piece);
|
||||
m_graphicsPieces.append(graphicsPiece);
|
||||
ConnectPiece(graphicsPiece);
|
||||
}
|
||||
scene()->addItem(_graphicsPiece);
|
||||
scene()->addItem(graphicsPiece);
|
||||
}
|
||||
|
||||
VMainGraphicsView::NewSceneRect(scene(), this);
|
||||
|
|
|
@ -126,11 +126,16 @@ private:
|
|||
|
||||
qreal m_rotationSum{0};
|
||||
|
||||
bool m_hasStickyPosition{false};
|
||||
qreal m_stickyTranslateX{0};
|
||||
qreal m_stickyTranslateY{0};
|
||||
|
||||
void ConnectPiece(VPGraphicsPiece *piece);
|
||||
|
||||
void RotatePiecesByAngle(qreal angle);
|
||||
void TranslatePiecesOn(qreal dx, qreal dy);
|
||||
|
||||
auto ScenePiece(const VPPiecePtr &piece) const -> VPGraphicsPiece *;
|
||||
};
|
||||
|
||||
#endif // VPMAINGRAPHICSVIEW_H
|
||||
|
|
|
@ -909,7 +909,6 @@ void VPMainWindow::InitPropertyTabLayout()
|
|||
{
|
||||
m_layout->LayoutSettings().SetPiecesGapConverted(d);
|
||||
LayoutWasSaved(false);
|
||||
// TODO update the QGraphicView
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2539,6 +2538,19 @@ void VPMainWindow::on_ApplyPieceTransformation()
|
|||
|
||||
auto *command = new VPUndoPieceMove(piece, pieceDx, pieceDy);
|
||||
m_layout->UndoStack()->push(command);
|
||||
|
||||
if (m_layout->LayoutSettings().GetStickyEdges())
|
||||
{
|
||||
qreal stickyTranslateX = 0;
|
||||
qreal stickyTranslateY = 0;
|
||||
if (piece->StickyPosition(stickyTranslateX, stickyTranslateY))
|
||||
{
|
||||
bool allowMerge = selectedPieces.size() == 1;
|
||||
auto *stickyCommand = new VPUndoPieceMove(piece, stickyTranslateX, stickyTranslateY,
|
||||
allowMerge);
|
||||
m_layout->UndoStack()->push(stickyCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -297,7 +297,7 @@ void VPLayoutFileReader::ReadControl(const VPLayoutPtr &layout)
|
|||
ReadAttributeBool(attribs, ML::AttrWarningSuperposition, trueStr));
|
||||
layout->LayoutSettings().SetWarningPiecesOutOfBound(ReadAttributeBool(attribs, ML::AttrWarningOutOfBound, trueStr));
|
||||
layout->LayoutSettings().SetStickyEdges(ReadAttributeBool(attribs, ML::AttrStickyEdges, trueStr));
|
||||
layout->LayoutSettings().SetPiecesGap(ReadAttributeDouble(attribs, ML::AttrPiecesGap, QChar('0')));
|
||||
layout->LayoutSettings().SetPiecesGap(qMax(ReadAttributeDouble(attribs, ML::AttrPiecesGap, QChar('0')), 0.0));
|
||||
layout->LayoutSettings().SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr));
|
||||
|
||||
readElementText();
|
||||
|
|
Loading…
Reference in New Issue
Block a user