Undo/Redo transformation origin move.

This commit is contained in:
Roman Telezhynskyi 2021-08-19 12:36:39 +03:00
parent 9a7e4e5ea6
commit 18d9417c96
15 changed files with 270 additions and 77 deletions

View file

@ -28,6 +28,7 @@
#ifndef LAYOUTDEF_H
#define LAYOUTDEF_H
#include <QPointF>
#include <QSharedPointer>
class VPLayout;
@ -42,4 +43,16 @@ class VPSheet;
using VPSheetPtr = QSharedPointer<VPSheet>;
using VPSheetWeakPtr = QWeakPointer<VPSheet>;
enum class GrainlineType : qint8
{
Vertical,
Horizontal
};
struct VPTransformationOrigon
{
QPointF origin{};
bool custom{false};
};
#endif // LAYOUTDEF_H

View file

@ -88,6 +88,7 @@ signals:
void PieceSheetChanged(const VPPiecePtr &piece);
void ActiveSheetChanged(const VPSheetPtr &focusedSheet);
void PieceTransformationChanged(const VPPiecePtr &piece);
void TransformationOriginChanged();
protected:
explicit VPLayout(QUndoStack *undoStack);

View file

@ -40,18 +40,6 @@
class VPLayout;
class VPPiece;
enum class GrainlineType : qint8
{
Vertical,
Horizontal
};
struct VPTransformationOrigon
{
QPointF origin{};
bool custom{false};
};
class VPSheet
{
public:

View file

@ -8,6 +8,7 @@ SOURCES += \
$$PWD/dialogs/vpdialogabout.cpp \
$$PWD/main.cpp \
$$PWD/undocommands/vpundocommand.cpp \
$$PWD/undocommands/vpundooriginmove.cpp \
$$PWD/undocommands/vpundopiecemove.cpp \
$$PWD/undocommands/vpundopiecerotate.cpp \
$$PWD/vpapplication.cpp \
@ -45,6 +46,7 @@ HEADERS += \
$$PWD/scene/scenedef.h \
$$PWD/stable.h \
$$PWD/undocommands/vpundocommand.h \
$$PWD/undocommands/vpundooriginmove.h \
$$PWD/undocommands/vpundopiecemove.h \
$$PWD/undocommands/vpundopiecerotate.h \
$$PWD/vpapplication.h \

View file

@ -38,6 +38,7 @@
#include "../vwidgets/global.h"
#include "../layout/vplayout.h"
#include "../undocommands/vpundopiecerotate.h"
#include "../undocommands/vpundooriginmove.h"
#include "vpgraphicspiece.h"
namespace
@ -93,12 +94,16 @@ VPGraphicsTransformationOrigin::VPGraphicsTransformationOrigin(const VPLayoutPtr
setCursor(Qt::OpenHandCursor);
setZValue(1);
setAcceptHoverEvents(true);
connect(layout.get(), &VPLayout::TransformationOriginChanged, this,
&VPGraphicsTransformationOrigin::SetTransformationOrigin);
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsTransformationOrigin::SetTransformationOrigin()
{
prepareGeometryChange();
update();
}
//---------------------------------------------------------------------------------------------------------------------
@ -181,11 +186,14 @@ void VPGraphicsTransformationOrigin::mouseMoveEvent(QGraphicsSceneMouseEvent *ev
VPTransformationOrigon origin = sheet->TransformationOrigin();
origin.origin = event->scenePos();
origin.custom = true;
sheet->SetTransformationOrigin(origin);
auto *command = new VPUndoOriginMove(sheet, origin, m_allowChangeMerge);
layout->UndoStack()->push(command);
}
prepareGeometryChange();
}
m_allowChangeMerge = true;
QGraphicsObject::mouseMoveEvent(event);
}
@ -199,6 +207,7 @@ void VPGraphicsTransformationOrigin::mouseReleaseEvent(QGraphicsSceneMouseEvent
if (event->button() == Qt::LeftButton)
{
setCursor(Qt::OpenHandCursor);
m_allowChangeMerge = false;
}
}
@ -779,7 +788,7 @@ auto VPGraphicsPieceControls::SelectedPieces() const -> QVector<VPGraphicsPiece
}
//---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsPieceControls::PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) const -> QRectF
auto VPGraphicsPieceControls::PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) -> QRectF
{
QRectF rect;
for (auto *item : selectedPieces)

View file

@ -69,6 +69,7 @@ private:
bool m_originVisible{true};
VPLayoutWeakPtr m_layout{};
QColor m_color;
bool m_allowChangeMerge{false};
auto RotationCenter(QPainter *painter = nullptr) const -> QPainterPath;
auto Center1() const -> QPainterPath;
@ -127,9 +128,10 @@ private:
auto ArrowPath() const -> QPainterPath;
auto SelectedPieces() const -> QVector<VPGraphicsPiece *>;
auto PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) const -> QRectF;
auto HandleCorner(const QPointF &pos) const -> int;
auto SelectedPieces() const -> QVector<VPGraphicsPiece *>;
static auto PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) -> QRectF;
};
#endif // VPGRAPHICSPIECECONTROLS_H

View file

@ -47,6 +47,7 @@
#include "vpgraphicspiececontrols.h"
#include "../undocommands/vpundopiecemove.h"
#include "../undocommands/vpundopiecerotate.h"
#include "../undocommands/vpundooriginmove.h"
#include <QLoggingCategory>
@ -440,9 +441,23 @@ void VPMainGraphicsView::RestoreOrigin() const
if (not sheet.isNull())
{
VPTransformationOrigon origin = sheet->TransformationOrigin();
origin.custom = false;
sheet->SetTransformationOrigin(origin);
m_rotationControls->on_UpdateControls();
if (origin.custom)
{ // ignore if not custom. Prevent double call
origin.custom = false;
QRectF boundingRect;
for (auto *graphicsPiece : m_graphicsPieces)
{
if (graphicsPiece->isSelected())
{
boundingRect = boundingRect.united(graphicsPiece->sceneBoundingRect());
}
}
origin.origin = boundingRect.center();
auto *command = new VPUndoOriginMove(sheet, origin);
layout->UndoStack()->push(command);
}
}
}

View file

@ -30,6 +30,7 @@
Q_LOGGING_CATEGORY(vpUndo, "vp.undo")
//---------------------------------------------------------------------------------------------------------------------
VPUndoCommand::VPUndoCommand(QUndoCommand *parent)
: QUndoCommand(parent)
VPUndoCommand::VPUndoCommand(bool allowMerge, QUndoCommand *parent)
: QUndoCommand(parent),
m_allowMerge(allowMerge)
{}

View file

@ -40,6 +40,7 @@ enum class UndoCommand: qint8
MovePieces = 1,
RotatePiece = 2,
RotatePieces = 3,
MoveOrigin = 4,
};
}
@ -49,11 +50,23 @@ class VPUndoCommand : public QObject, public QUndoCommand
{
Q_OBJECT
public:
explicit VPUndoCommand(QUndoCommand *parent = nullptr);
explicit VPUndoCommand(bool allowMerge = false, QUndoCommand *parent = nullptr);
virtual ~VPUndoCommand() =default;
auto AllowMerge() const -> bool;
protected:
bool m_allowMerge;
private:
Q_DISABLE_COPY(VPUndoCommand)
};
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoCommand::AllowMerge() const -> bool
{
return m_allowMerge;
}
#endif // VPUNDOCOMMAND_H

View file

@ -0,0 +1,121 @@
/************************************************************************
**
** @file vpundooriginmove.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 19 8, 2021
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2021 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina 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 3 of the License, or
** (at your option) any later version.
**
** Valentina 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 Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vpundooriginmove.h"
#include "../vmisc/def.h"
#include "../layout/vpsheet.h"
#include "../layout/vplayout.h"
//---------------------------------------------------------------------------------------------------------------------
VPUndoOriginMove::VPUndoOriginMove(const VPSheetPtr &sheet, const VPTransformationOrigon &origin, bool allowMerge,
QUndoCommand *parent)
: VPUndoCommand(allowMerge, parent),
m_sheet(sheet),
m_origin(origin)
{
SCASSERT(not sheet.isNull())
m_oldOrigin = sheet->TransformationOrigin();
setText(QObject::tr("move transformation origin"));
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoOriginMove::undo()
{
VPSheetPtr sheet = m_sheet.toStrongRef();
if (sheet.isNull())
{
return;
}
VPLayoutPtr layout = sheet->GetLayout();
if (layout.isNull())
{
return;
}
layout->SetFocusedSheet(sheet);
sheet->SetTransformationOrigin(m_oldOrigin);
layout->TransformationOriginChanged();
}
//---------------------------------------------------------------------------------------------------------------------
void VPUndoOriginMove::redo()
{
VPSheetPtr sheet = m_sheet.toStrongRef();
if (sheet.isNull())
{
return;
}
VPLayoutPtr layout = sheet->GetLayout();
if (layout.isNull())
{
return;
}
layout->SetFocusedSheet(sheet);
sheet->SetTransformationOrigin(m_origin);
layout->TransformationOriginChanged();
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoOriginMove::mergeWith(const QUndoCommand *command) -> bool
{
if (command->id() != id()) // make sure other is also an VPUndoPieceMove command
{
return false;
}
const auto *moveCommand = dynamic_cast<const VPUndoOriginMove *>(command);
SCASSERT(moveCommand != nullptr)
VPSheetPtr sheet = Sheet();
if (moveCommand->Sheet().isNull() || sheet.isNull() || not moveCommand->AllowMerge())
{
return false;
}
VPTransformationOrigon origin = moveCommand->Origin();
if (origin.custom != m_origin.custom)
{
return false;
}
m_origin.origin += origin.origin;
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPUndoOriginMove::id() const -> int
{
return static_cast<int>(ML::UndoCommand::MoveOrigin);
}

View file

@ -0,0 +1,73 @@
/************************************************************************
**
** @file vpundooriginmove.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 19 8, 2021
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2021 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina 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 3 of the License, or
** (at your option) any later version.
**
** Valentina 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 Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPUNDOORIGINMOVE_H
#define VPUNDOORIGINMOVE_H
#include "vpundocommand.h"
#include "../layout/layoutdef.h"
class VPUndoOriginMove : public VPUndoCommand
{
Q_OBJECT
public:
VPUndoOriginMove(const VPSheetPtr &sheet, const VPTransformationOrigon &origin, bool allowMerge = false,
QUndoCommand *parent = nullptr);
virtual ~VPUndoOriginMove()=default;
virtual void undo() override;
virtual void redo() override;
// cppcheck-suppress unusedFunction
virtual auto mergeWith(const QUndoCommand *command) -> bool override;
virtual auto id() const -> int override ;
auto Sheet() const -> VPSheetWeakPtr;
auto Origin() const -> const VPTransformationOrigon &;
private:
Q_DISABLE_COPY(VPUndoOriginMove)
VPSheetWeakPtr m_sheet;
VPTransformationOrigon m_oldOrigin{};
VPTransformationOrigon m_origin{};
};
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoOriginMove::Sheet() const -> VPSheetWeakPtr
{
return m_sheet;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoOriginMove::Origin() const ->const VPTransformationOrigon &
{
return m_origin;
}
#endif // VPUNDOORIGINMOVE_H

View file

@ -32,11 +32,10 @@
//---------------------------------------------------------------------------------------------------------------------
VPUndoPieceMove::VPUndoPieceMove(const VPPiecePtr &piece, qreal dx, qreal dy, bool allowMerge, QUndoCommand *parent)
: VPUndoCommand(parent),
: VPUndoCommand(allowMerge, parent),
m_piece(piece),
m_dx(dx),
m_dy(dy),
m_allowMerge(allowMerge)
m_dy(dy)
{
SCASSERT(not piece.isNull())
@ -99,17 +98,8 @@ auto VPUndoPieceMove::mergeWith(const QUndoCommand *command) -> bool
SCASSERT(moveCommand != nullptr)
VPPiecePtr piece = Piece();
if (moveCommand->Piece().isNull() || piece.isNull())
{
return false;
}
if (moveCommand->Piece() != piece)
{
return false;
}
if (not moveCommand->AllowMerge())
if (moveCommand->Piece().isNull() || piece.isNull() || moveCommand->Piece() != piece ||
not moveCommand->AllowMerge())
{
return false;
}
@ -129,10 +119,9 @@ auto VPUndoPieceMove::id() const -> int
//---------------------------------------------------------------------------------------------------------------------
VPUndoPiecesMove::VPUndoPiecesMove(const QVector<VPPiecePtr> &pieces, qreal dx, qreal dy, bool allowMerge,
QUndoCommand *parent)
: VPUndoCommand(parent),
: VPUndoCommand(allowMerge, parent),
m_dx(dx),
m_dy(dy),
m_allowMerge(allowMerge)
m_dy(dy)
{
setText(QObject::tr("move pieces"));

View file

@ -51,7 +51,6 @@ public:
auto Piece() const -> VPPiecePtr;
auto Dx() const -> qreal;
auto Dy() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPieceMove)
@ -60,7 +59,6 @@ private:
QTransform m_oldTransform{};
qreal m_dx;
qreal m_dy;
bool m_allowMerge;
};
//---------------------------------------------------------------------------------------------------------------------
@ -81,12 +79,6 @@ inline auto VPUndoPieceMove::Dy() const -> qreal
return m_dy;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceMove::AllowMerge() const -> bool
{
return m_allowMerge;
}
// Move pieces
class VPUndoPiecesMove : public VPUndoCommand
{
@ -105,7 +97,6 @@ public:
auto PieceIds() const -> QSet<QString>;
auto Dx() const -> qreal;
auto Dy() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPiecesMove)
@ -114,7 +105,6 @@ private:
QMap<QString, QTransform> m_oldTransforms{};
qreal m_dx;
qreal m_dy;
bool m_allowMerge;
auto Layout() const -> VPLayoutPtr;
auto Sheet() const -> VPSheetPtr;
@ -132,10 +122,4 @@ inline auto VPUndoPiecesMove::Dy() const -> qreal
return m_dy;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesMove::AllowMerge() const -> bool
{
return m_allowMerge;
}
#endif // VPUNDOPIECEMOVE_H

View file

@ -32,11 +32,10 @@
//---------------------------------------------------------------------------------------------------------------------
VPUndoPieceRotate::VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &origin, qreal angle, bool allowMerge,
QUndoCommand *parent)
: VPUndoCommand(parent),
: VPUndoCommand(allowMerge, parent),
m_piece(piece),
m_origin(origin),
m_angle(angle),
m_allowMerge(allowMerge)
m_angle(angle)
{
SCASSERT(not piece.isNull())
@ -119,10 +118,9 @@ auto VPUndoPieceRotate::id() const -> int
//---------------------------------------------------------------------------------------------------------------------
VPUndoPiecesRotate::VPUndoPiecesRotate(const QVector<VPPiecePtr> &pieces, const QPointF &origin, qreal angle,
bool allowMerge, QUndoCommand *parent)
: VPUndoCommand(parent),
: VPUndoCommand(allowMerge, parent),
m_origin(origin),
m_angle(angle),
m_allowMerge(allowMerge)
m_angle(angle)
{
setText(QObject::tr("rotate pieces"));

View file

@ -52,7 +52,6 @@ public:
auto Piece() const -> VPPiecePtr;
auto Origin() const -> QPointF;
auto Angle() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPieceRotate)
@ -61,7 +60,6 @@ private:
QTransform m_oldTransform{};
QPointF m_origin;
qreal m_angle;
bool m_allowMerge;
};
//---------------------------------------------------------------------------------------------------------------------
@ -82,12 +80,6 @@ inline auto VPUndoPieceRotate::Angle() const -> qreal
return m_angle;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceRotate::AllowMerge() const -> bool
{
return m_allowMerge;
}
// Rotate pieces
class VPUndoPiecesRotate : public VPUndoCommand
{
@ -106,7 +98,6 @@ public:
auto PieceIds() const -> QSet<QString>;
auto Origin() const -> QPointF;
auto Angle() const -> qreal;
auto AllowMerge() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPiecesRotate)
@ -115,7 +106,6 @@ private:
QMap<QString, QTransform> m_oldTransforms{};
QPointF m_origin;
qreal m_angle;
bool m_allowMerge;
auto Layout() const -> VPLayoutPtr;
auto Sheet() const -> VPSheetPtr;
@ -133,10 +123,4 @@ inline auto VPUndoPiecesRotate::Angle() const -> qreal
return m_angle;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesRotate::AllowMerge() const -> bool
{
return m_allowMerge;
}
#endif // VPUNDOPIECEROTATE_H