Undo/Redo piece rotate.
This commit is contained in:
parent
0908b5a1f7
commit
a35e46f845
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "../vmisc/backport/qoverload.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
#include "../layout/vplayout.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QMenu>
|
||||
|
@ -42,12 +43,12 @@
|
|||
Q_LOGGING_CATEGORY(pCarrousel, "p.carrousel")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPCarrousel::VPCarrousel(VPLayout *layout, QWidget *parent) :
|
||||
VPCarrousel::VPCarrousel(const VPLayoutPtr &layout, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::VPCarrousel),
|
||||
m_layout(layout)
|
||||
{
|
||||
SCASSERT(m_layout != nullptr)
|
||||
SCASSERT(not layout.isNull())
|
||||
ui->setupUi(this);
|
||||
ui->listWidget->SetCarrousel(this);
|
||||
|
||||
|
@ -55,6 +56,8 @@ VPCarrousel::VPCarrousel(VPLayout *layout, QWidget *parent) :
|
|||
connect(ui->comboBoxPieceList, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&VPCarrousel::on_ActivePieceListChanged);
|
||||
|
||||
connect(layout.get(), &VPLayout::ActiveSheetChanged, this, &VPCarrousel::on_ActiveSheetChanged);
|
||||
|
||||
// ------ then we fill the carrousel with the layout content
|
||||
Refresh();
|
||||
}
|
||||
|
@ -73,26 +76,27 @@ void VPCarrousel::Refresh()
|
|||
// Do not rely on m_layout because we do not control it.
|
||||
m_pieceLists = QList<VPCarrouselSheet>();
|
||||
|
||||
if (m_layout != nullptr)
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
{
|
||||
VPCarrouselSheet carrouselSheet;
|
||||
carrouselSheet.unplaced = true;
|
||||
carrouselSheet.active = false;
|
||||
carrouselSheet.name = tr("Unplaced pieces");
|
||||
carrouselSheet.pieces = m_layout->GetUnplacedPieces();
|
||||
carrouselSheet.pieces = layout->GetUnplacedPieces();
|
||||
|
||||
m_pieceLists.append(carrouselSheet);
|
||||
}
|
||||
|
||||
QList<VPSheet *> sheets = m_layout->GetSheets();
|
||||
for (auto *sheet : sheets)
|
||||
QList<VPSheetPtr> sheets = layout->GetSheets();
|
||||
for (const auto &sheet : sheets)
|
||||
{
|
||||
if (sheet->IsVisible())
|
||||
if (not sheet.isNull() && sheet->IsVisible())
|
||||
{
|
||||
VPCarrouselSheet carrouselSheet;
|
||||
carrouselSheet.unplaced = false;
|
||||
carrouselSheet.active = (sheet == m_layout->GetFocusedSheet());
|
||||
carrouselSheet.active = (sheet == layout->GetFocusedSheet());
|
||||
carrouselSheet.name = sheet->GetName();
|
||||
carrouselSheet.pieces = sheet->GetPieces();
|
||||
carrouselSheet.sheetUuid = sheet->Uuid();
|
||||
|
@ -121,18 +125,41 @@ void VPCarrousel::Refresh()
|
|||
RefreshOrientation();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPCarrousel::on_ActiveSheetChanged(const VPSheetPtr &sheet)
|
||||
{
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
int index = ui->comboBoxPieceList->findData(sheet->Uuid());
|
||||
if (index != -1)
|
||||
{
|
||||
ui->comboBoxPieceList->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->comboBoxPieceList->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPCarrousel::RefreshSheetNames()
|
||||
{
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; i < m_pieceLists.size(); ++i)
|
||||
{
|
||||
if (not m_pieceLists.at(i).unplaced)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetSheet(m_pieceLists.at(i).sheetUuid);
|
||||
if (sheet != nullptr)
|
||||
VPSheetPtr sheet = layout->GetSheet(m_pieceLists.at(i).sheetUuid);
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
m_pieceLists[i].name = sheet->GetName();
|
||||
m_pieceLists[i].active = (sheet == m_layout->GetFocusedSheet());
|
||||
m_pieceLists[i].active = (sheet == layout->GetFocusedSheet());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -158,6 +185,12 @@ void VPCarrousel::on_ActivePieceListChanged(int index)
|
|||
{
|
||||
qCDebug(pCarrousel, "index changed %i", index);
|
||||
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (not m_pieceLists.isEmpty() && index >= 0 && index < m_pieceLists.size())
|
||||
{
|
||||
ui->listWidget->SetCurrentPieceList(m_pieceLists.at(index).pieces);
|
||||
|
@ -165,20 +198,22 @@ void VPCarrousel::on_ActivePieceListChanged(int index)
|
|||
if (index > 0)
|
||||
{
|
||||
QUuid sheetUuid = ui->comboBoxPieceList->currentData().toUuid();
|
||||
VPSheet *sheet = m_layout->GetSheet(sheetUuid);
|
||||
VPSheetPtr sheet = layout->GetSheet(sheetUuid);
|
||||
|
||||
if (sheet != nullptr)
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
m_layout->SetFocusedSheet(sheet);
|
||||
emit on_ActiveSheetChanged();
|
||||
m_ignoreActiveSheetChange = true;
|
||||
layout->SetFocusedSheet(sheet);
|
||||
m_ignoreActiveSheetChange = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->listWidget->SetCurrentPieceList(QList<VPPiece *>());
|
||||
m_layout->SetFocusedSheet(nullptr);
|
||||
emit on_ActiveSheetChanged();
|
||||
ui->listWidget->SetCurrentPieceList(QList<VPPiecePtr>());
|
||||
m_ignoreActiveSheetChange = true;
|
||||
layout->SetFocusedSheet(VPSheetPtr());
|
||||
m_ignoreActiveSheetChange = false;
|
||||
}
|
||||
|
||||
RefreshSheetNames();
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QScrollArea>
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../layout/vppiece.h"
|
||||
#include "../layout/layoutdef.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ struct VPCarrouselSheet
|
|||
bool unplaced{true};
|
||||
bool active{false};
|
||||
QString name{};
|
||||
QList<VPPiece *> pieces{};
|
||||
QList<VPPiecePtr> pieces{};
|
||||
QUuid sheetUuid{};
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,7 @@ class VPCarrousel : public QWidget
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPCarrousel(VPLayout *layout, QWidget *parent = nullptr);
|
||||
explicit VPCarrousel(const VPLayoutPtr &layout, QWidget *parent = nullptr);
|
||||
virtual ~VPCarrousel() = default;
|
||||
|
||||
/**
|
||||
|
@ -69,8 +69,6 @@ public:
|
|||
*/
|
||||
void RefreshOrientation();
|
||||
|
||||
|
||||
|
||||
void RefreshSheetNames();
|
||||
|
||||
/**
|
||||
|
@ -78,14 +76,12 @@ public:
|
|||
*/
|
||||
void Clear();
|
||||
|
||||
signals:
|
||||
void on_ActiveSheetChanged();
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Refresh Refreshes the content of the carrousel
|
||||
*/
|
||||
void Refresh();
|
||||
void on_ActiveSheetChanged(const VPSheetPtr &sheet);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* event) override;
|
||||
|
@ -102,12 +98,14 @@ private:
|
|||
Q_DISABLE_COPY(VPCarrousel)
|
||||
Ui::VPCarrousel *ui;
|
||||
|
||||
VPLayout *m_layout{nullptr};
|
||||
VPLayoutWeakPtr m_layout{};
|
||||
|
||||
QList<VPCarrouselSheet> m_pieceLists{};
|
||||
|
||||
Qt::Orientation m_orientation{Qt::Vertical};
|
||||
|
||||
bool m_ignoreActiveSheetChange{false};
|
||||
|
||||
static auto GetSheetName(const VPCarrouselSheet &sheet) -> QString;
|
||||
};
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ Q_LOGGING_CATEGORY(pCarrouselPiece, "p.carrouselPiece")
|
|||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPCarrouselPiece::VPCarrouselPiece(VPPiece *piece, QListWidget* parent) :
|
||||
VPCarrouselPiece::VPCarrouselPiece(const VPPiecePtr &piece, QListWidget* parent) :
|
||||
QListWidgetItem(parent, Type),
|
||||
m_piece(piece)
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ VPCarrouselPiece::VPCarrouselPiece(VPPiece *piece, QListWidget* parent) :
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPCarrouselPiece::GetPiece() -> VPPiece *
|
||||
auto VPCarrouselPiece::GetPiece() const -> VPPiecePtr
|
||||
{
|
||||
return m_piece;
|
||||
}
|
||||
|
@ -65,13 +65,23 @@ auto VPCarrouselPiece::GetPiece() -> VPPiece *
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPCarrouselPiece::RefreshSelection()
|
||||
{
|
||||
setSelected(m_piece->IsSelected());
|
||||
VPPiecePtr piece = GetPiece();
|
||||
if (not piece.isNull())
|
||||
{
|
||||
setSelected(piece->IsSelected());
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const -> QIcon
|
||||
{
|
||||
QRectF boundingRect = m_piece->DetailBoundingRect();
|
||||
VPPiecePtr piece = GetPiece();
|
||||
if (piece.isNull())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QRectF boundingRect = piece->DetailBoundingRect();
|
||||
qreal canvasSize = qMax(boundingRect.height(), boundingRect.width());
|
||||
QRectF canvas = QRectF(0, 0, canvasSize, canvasSize);
|
||||
|
||||
|
@ -133,7 +143,7 @@ auto VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const
|
|||
painter.setBrush(QBrush(Qt::white));
|
||||
}
|
||||
|
||||
m_piece->DrawMiniature(painter);
|
||||
piece->DrawMiniature(painter);
|
||||
|
||||
painter.end();
|
||||
|
||||
|
|
|
@ -31,21 +31,21 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
class VPPiece;
|
||||
#include "../layout/layoutdef.h"
|
||||
|
||||
class VPCarrouselPiece : public QListWidgetItem
|
||||
{
|
||||
public:
|
||||
enum { Type = UserType + 1};
|
||||
|
||||
explicit VPCarrouselPiece(VPPiece *piece, QListWidget* parent);
|
||||
explicit VPCarrouselPiece(const VPPiecePtr &piece, QListWidget* parent);
|
||||
virtual ~VPCarrouselPiece() = default;
|
||||
|
||||
/**
|
||||
* @brief GetPiece Returns the corresponding layout piece
|
||||
* @return the corresponding layout piece
|
||||
*/
|
||||
auto GetPiece() -> VPPiece *;
|
||||
auto GetPiece() const -> VPPiecePtr;
|
||||
|
||||
/**
|
||||
* @brief RefreshSelection refreshes the selection of the piece according to the selection information of m_piece
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPCarrouselPiece)
|
||||
VPPiece *m_piece;
|
||||
VPPieceWeakPtr m_piece;
|
||||
};
|
||||
|
||||
#endif // VPCARROUSELPIECE_H
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "../vmisc/backport/qoverload.h"
|
||||
#include "vpmimedatapiece.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
#include "../layout/vplayout.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
@ -68,18 +69,21 @@ void VPCarrouselPieceList::Refresh()
|
|||
if(not m_pieceList.isEmpty())
|
||||
{
|
||||
// create the corresponding carrousel pieces
|
||||
for (auto *piece : m_pieceList)
|
||||
for (auto piece : m_pieceList)
|
||||
{
|
||||
if (not piece.isNull())
|
||||
{
|
||||
// update the label of the piece
|
||||
auto* carrouselpiece = new VPCarrouselPiece(piece, this);
|
||||
carrouselpiece->setSelected(piece->IsSelected());
|
||||
}
|
||||
}
|
||||
sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPCarrouselPieceList::SetCurrentPieceList(const QList<VPPiece *> &pieceList)
|
||||
void VPCarrouselPieceList::SetCurrentPieceList(const QList<VPPiecePtr> &pieceList)
|
||||
{
|
||||
m_pieceList = pieceList;
|
||||
|
||||
|
@ -135,7 +139,7 @@ void VPCarrouselPieceList::startDrag(Qt::DropActions supportedActions)
|
|||
// starts the dragging
|
||||
auto *drag = new QDrag(this);
|
||||
auto *mimeData = new VPMimeDataPiece();
|
||||
VPPiece* piece = pieceItem->GetPiece();
|
||||
VPPiecePtr piece = pieceItem->GetPiece();
|
||||
mimeData->SetPiecePtr(piece);
|
||||
|
||||
QPixmap pixmap = pieceItem->CreatePieceIcon(QSize(120, 120), true).pixmap(QSize(120, 120));
|
||||
|
@ -189,18 +193,23 @@ void VPCarrouselPieceList::contextMenuEvent(QContextMenuEvent *event)
|
|||
|
||||
QAction *selectedAction = menu.exec(event->globalPos());
|
||||
|
||||
VPPiece *piece = pieceItem->GetPiece();
|
||||
VPLayout *layout = piece->Layout();
|
||||
VPPiecePtr piece = pieceItem->GetPiece();
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
|
||||
if (piece.isNull() || layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedAction == moveAction)
|
||||
{
|
||||
VPSheet *sheet = layout->GetFocusedSheet();
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
piece->SetSheet(sheet);
|
||||
emit layout->PieceSheetChanged(piece);
|
||||
}
|
||||
else if (selectedAction == deleteAction)
|
||||
{
|
||||
VPSheet *sheet = layout->GetTrashSheet();
|
||||
VPSheetPtr sheet = layout->GetTrashSheet();
|
||||
piece->SetSheet(sheet);
|
||||
emit layout->PieceSheetChanged(piece);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
* @brief SetCurrentPieceList Sets the current piece list to the given piece list and redraw
|
||||
* the carrousel.
|
||||
*/
|
||||
void SetCurrentPieceList(const QList<VPPiece *> &pieceList);
|
||||
void SetCurrentPieceList(const QList<VPPiecePtr> &pieceList);
|
||||
|
||||
/**
|
||||
* @brief SetCarrousel Sets the carrousel corresponding to the list
|
||||
|
@ -76,7 +76,7 @@ protected:
|
|||
private:
|
||||
Q_DISABLE_COPY(VPCarrouselPieceList)
|
||||
|
||||
QList<VPPiece *> m_pieceList{};
|
||||
QList<VPPiecePtr> m_pieceList{};
|
||||
QPoint m_dragStart{};
|
||||
VPCarrousel *m_carrousel{nullptr};
|
||||
};
|
||||
|
|
45
src/app/puzzle/layout/layoutdef.h
Normal file
45
src/app/puzzle/layout/layoutdef.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file layoutdef.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 16 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 LAYOUTDEF_H
|
||||
#define LAYOUTDEF_H
|
||||
|
||||
#include <QSharedPointer>
|
||||
|
||||
class VPLayout;
|
||||
using VPLayoutPtr = QSharedPointer<VPLayout>;
|
||||
using VPLayoutWeakPtr = QWeakPointer<VPLayout>;
|
||||
|
||||
class VPPiece;
|
||||
using VPPiecePtr = QSharedPointer<VPPiece>;
|
||||
using VPPieceWeakPtr = QWeakPointer<VPPiece>;
|
||||
|
||||
class VPSheet;
|
||||
using VPSheetPtr = QSharedPointer<VPSheet>;
|
||||
using VPSheetWeakPtr = QWeakPointer<VPSheet>;
|
||||
|
||||
#endif // LAYOUTDEF_H
|
|
@ -31,109 +31,118 @@
|
|||
#include "vpsheet.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QUndoStack>
|
||||
|
||||
Q_LOGGING_CATEGORY(pLayout, "p.layout")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPLayout::VPLayout(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_trashSheet(new VPSheet(this))
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPLayout::~VPLayout()
|
||||
VPLayout::VPLayout(QUndoStack *undoStack) :
|
||||
m_undoStack(undoStack)
|
||||
{
|
||||
qDeleteAll(m_pieces);
|
||||
SCASSERT(m_undoStack != nullptr)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayout::AddPiece(VPPiece *piece)
|
||||
VPLayoutPtr VPLayout::CreateLayout(QUndoStack *undoStack)
|
||||
{
|
||||
if ((piece != nullptr) && not m_pieces.contains(piece))
|
||||
SCASSERT(undoStack != nullptr)
|
||||
undoStack->clear();
|
||||
VPLayoutPtr layout(new VPLayout(undoStack));
|
||||
layout->AddTrashSheet(VPSheetPtr(new VPSheet(layout)));
|
||||
return layout;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayout::AddPiece(const VPLayoutPtr &layout, const VPPiecePtr &piece)
|
||||
{
|
||||
piece->SetLayout(layout);
|
||||
layout->AddPiece(piece);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayout::AddPiece(const VPPiecePtr &piece)
|
||||
{
|
||||
if ((piece != nullptr) && not m_pieces.contains(piece->GetUniqueID()))
|
||||
{
|
||||
piece->SetLayout(this);
|
||||
m_pieces.append(piece);
|
||||
m_pieces.insert(piece->GetUniqueID(), piece);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::GetPieces() const -> QList<VPPiece *>
|
||||
auto VPLayout::GetPieces() const -> QList<VPPiecePtr>
|
||||
{
|
||||
return m_pieces;
|
||||
return m_pieces.values();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::GetUnplacedPieces() const -> QList<VPPiece *>
|
||||
auto VPLayout::GetUnplacedPieces() const -> QList<VPPiecePtr>
|
||||
{
|
||||
return PiecesForSheet(nullptr);
|
||||
return PiecesForSheet(VPSheetPtr());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::GetTrashedPieces() const -> QList<VPPiece *>
|
||||
auto VPLayout::GetTrashedPieces() const -> QList<VPPiecePtr>
|
||||
{
|
||||
return PiecesForSheet(m_trashSheet);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::AddSheet() -> VPSheet*
|
||||
{
|
||||
auto *newSheet = new VPSheet(this);
|
||||
m_sheets.append(newSheet);
|
||||
return newSheet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::AddSheet(VPSheet *sheet) -> VPSheet*
|
||||
{
|
||||
if ((sheet != nullptr) && not m_sheets.contains(sheet))
|
||||
if (m_trashSheet.isNull())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
return PiecesForSheet(m_trashSheet->Uuid());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::AddSheet(const VPSheetPtr &sheet) -> VPSheetPtr
|
||||
{
|
||||
if (not sheet.isNull() && GetSheet(sheet->Uuid()).isNull())
|
||||
{
|
||||
sheet->setParent(this);
|
||||
m_sheets.append(sheet);
|
||||
}
|
||||
return sheet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::GetSheets() -> QList<VPSheet *>
|
||||
auto VPLayout::GetSheets() -> QList<VPSheetPtr>
|
||||
{
|
||||
return m_sheets;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::GetSheet(const QUuid &uuid) -> VPSheet *
|
||||
auto VPLayout::GetSheet(const QUuid &uuid) -> VPSheetPtr
|
||||
{
|
||||
for (auto *sheet : m_sheets)
|
||||
auto sheet = std::find_if(m_sheets.begin(), m_sheets.end(),
|
||||
[uuid](const VPSheetPtr &sheet) { return sheet->Uuid() == uuid; });
|
||||
|
||||
if (sheet != m_sheets.end())
|
||||
{
|
||||
if (sheet->Uuid() == uuid)
|
||||
{
|
||||
return sheet;
|
||||
}
|
||||
return *sheet;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayout::SetFocusedSheet(VPSheet *focusedSheet)
|
||||
void VPLayout::SetFocusedSheet(const VPSheetPtr &focusedSheet)
|
||||
{
|
||||
if (m_sheets.isEmpty())
|
||||
{
|
||||
m_focusedSheet = nullptr;
|
||||
m_focusedSheet = {};
|
||||
}
|
||||
else
|
||||
{
|
||||
m_focusedSheet = focusedSheet == nullptr ? m_sheets.first() : focusedSheet;
|
||||
m_focusedSheet = focusedSheet.isNull() ? m_sheets.first() : focusedSheet;
|
||||
}
|
||||
|
||||
emit ActiveSheetChanged(m_focusedSheet);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::GetFocusedSheet() -> VPSheet*
|
||||
auto VPLayout::GetFocusedSheet() -> VPSheetPtr
|
||||
{
|
||||
return m_focusedSheet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::GetTrashSheet() -> VPSheet*
|
||||
auto VPLayout::GetTrashSheet() -> VPSheetPtr
|
||||
{
|
||||
return m_trashSheet;
|
||||
}
|
||||
|
@ -145,14 +154,14 @@ auto VPLayout::LayoutSettings() -> VPLayoutSettings &
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayout::PiecesForSheet(const VPSheet *sheet) const -> QList<VPPiece *>
|
||||
auto VPLayout::PiecesForSheet(const VPSheetPtr &sheet) const -> QList<VPPiecePtr>
|
||||
{
|
||||
QList<VPPiece *> list;
|
||||
QList<VPPiecePtr> list;
|
||||
list.reserve(m_pieces.size());
|
||||
|
||||
for (auto *piece : m_pieces)
|
||||
for (auto piece : m_pieces)
|
||||
{
|
||||
if ((piece != nullptr) && piece->Sheet() == sheet)
|
||||
if (not piece.isNull() && piece->Sheet() == sheet)
|
||||
{
|
||||
list.append(piece);
|
||||
}
|
||||
|
@ -160,3 +169,57 @@ auto VPLayout::PiecesForSheet(const VPSheet *sheet) const -> QList<VPPiece *>
|
|||
|
||||
return list;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QList<VPPiecePtr> VPLayout::PiecesForSheet(const QUuid &uuid) const
|
||||
{
|
||||
QList<VPPiecePtr> list;
|
||||
list.reserve(m_pieces.size());
|
||||
|
||||
for (auto piece : m_pieces)
|
||||
{
|
||||
if (not piece.isNull())
|
||||
{
|
||||
VPSheetPtr sheet = piece->Sheet();
|
||||
if (not sheet.isNull() && sheet->Uuid() == uuid)
|
||||
{
|
||||
list.append(piece);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QUndoStack *VPLayout::UndoStack() const
|
||||
{
|
||||
return m_undoStack;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayout::SetUndoStack(QUndoStack *newUndoStack)
|
||||
{
|
||||
m_undoStack = newUndoStack;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayout::Clear()
|
||||
{
|
||||
if (m_undoStack != nullptr)
|
||||
{
|
||||
m_undoStack->clear();
|
||||
}
|
||||
|
||||
m_pieces.clear();
|
||||
m_trashSheet->Clear();
|
||||
m_sheets.clear();
|
||||
m_focusedSheet.clear();
|
||||
m_layoutSettings = VPLayoutSettings();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayout::AddTrashSheet(const VPSheetPtr &sheet)
|
||||
{
|
||||
m_trashSheet = sheet;
|
||||
}
|
||||
|
|
|
@ -29,64 +29,86 @@
|
|||
#define VPLAYOUT_H
|
||||
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
|
||||
#include "def.h"
|
||||
#include "vplayoutsettings.h"
|
||||
#include "layoutdef.h"
|
||||
|
||||
class VPPiece;
|
||||
class VPSheet;
|
||||
class QUndoStack;
|
||||
|
||||
class VPLayout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPLayout(QObject *parent=nullptr);
|
||||
virtual ~VPLayout();
|
||||
virtual ~VPLayout() = default;
|
||||
|
||||
void AddPiece(VPPiece *piece);
|
||||
auto GetPieces() const -> QList<VPPiece *>;
|
||||
auto GetUnplacedPieces() const -> QList<VPPiece *>;
|
||||
auto GetTrashedPieces() const -> QList<VPPiece *>;
|
||||
static auto CreateLayout(QUndoStack *undoStack) -> VPLayoutPtr;
|
||||
static void AddPiece(const VPLayoutPtr &layout, const VPPiecePtr &piece);
|
||||
|
||||
auto AddSheet() -> VPSheet*;
|
||||
auto AddSheet(VPSheet *sheet) -> VPSheet*;
|
||||
auto GetSheets() -> QList<VPSheet *>;
|
||||
auto GetSheet(const QUuid &uuid) -> VPSheet *;
|
||||
auto GetPieces() const -> QList<VPPiecePtr>;
|
||||
auto GetUnplacedPieces() const -> QList<VPPiecePtr>;
|
||||
auto GetTrashedPieces() const -> QList<VPPiecePtr>;
|
||||
|
||||
auto AddSheet(const VPSheetPtr &sheet) -> VPSheetPtr;
|
||||
auto GetSheets() -> QList<VPSheetPtr>;
|
||||
auto GetSheet(const QUuid &uuid) -> VPSheetPtr;
|
||||
|
||||
/**
|
||||
* @brief SetFocusedSheet Sets the focused sheet, to which pieces are added from the carrousel via drag
|
||||
* and drop
|
||||
* @param focusedSheet the new active sheet. If nullptr, then it sets automaticaly the first sheet from m_sheets
|
||||
*/
|
||||
void SetFocusedSheet(VPSheet *focusedSheet = nullptr);
|
||||
void SetFocusedSheet(const VPSheetPtr &focusedSheet = VPSheetPtr());
|
||||
|
||||
/**
|
||||
* @brief GetFocusedSheet Returns the focused sheet, to which pieces are added from the carrousel via drag
|
||||
* and drop
|
||||
* @return the focused sheet
|
||||
*/
|
||||
auto GetFocusedSheet() -> VPSheet*;
|
||||
auto GetFocusedSheet() -> VPSheetPtr;
|
||||
|
||||
auto GetTrashSheet() -> VPSheet*;
|
||||
void AddTrashSheet(const VPSheetPtr &sheet);
|
||||
auto GetTrashSheet() -> VPSheetPtr;
|
||||
|
||||
auto LayoutSettings() -> VPLayoutSettings &;
|
||||
|
||||
auto PiecesForSheet(const VPSheet* sheet) const -> QList<VPPiece *>;
|
||||
auto PiecesForSheet(const VPSheetPtr &sheet) const -> QList<VPPiecePtr>;
|
||||
auto PiecesForSheet(const QUuid &uuid) const -> QList<VPPiecePtr>;
|
||||
|
||||
QUndoStack *UndoStack() const;
|
||||
|
||||
void SetUndoStack(QUndoStack *newUndoStack);
|
||||
|
||||
void Clear();
|
||||
|
||||
signals:
|
||||
void PieceSheetChanged(VPPiece *piece);
|
||||
void PieceSheetChanged(const VPPiecePtr &piece);
|
||||
void ActiveSheetChanged(const VPSheetPtr &focusedSheet);
|
||||
void PieceTransformationChanged(const VPPiecePtr &piece);
|
||||
|
||||
protected:
|
||||
explicit VPLayout(QUndoStack *undoStack);
|
||||
|
||||
void AddPiece(const VPPiecePtr &piece);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPLayout)
|
||||
|
||||
QList<VPPiece *> m_pieces{};
|
||||
QMap<QString, VPPiecePtr> m_pieces{};
|
||||
|
||||
VPSheet* m_trashSheet;
|
||||
VPSheetPtr m_trashSheet{};
|
||||
|
||||
QList<VPSheet*> m_sheets{};
|
||||
VPSheet *m_focusedSheet{nullptr};
|
||||
QList<VPSheetPtr> m_sheets{};
|
||||
VPSheetPtr m_focusedSheet{};
|
||||
|
||||
VPLayoutSettings m_layoutSettings{};
|
||||
|
||||
QUndoStack *m_undoStack;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(VPLayoutPtr)
|
||||
|
||||
#endif // VPLAYOUT_H
|
||||
|
|
|
@ -7,6 +7,9 @@ SOURCES += \
|
|||
$$PWD/dialogs/dialogpuzzlepreferences.cpp \
|
||||
$$PWD/dialogs/vpdialogabout.cpp \
|
||||
$$PWD/main.cpp \
|
||||
$$PWD/undocommands/vpundocommand.cpp \
|
||||
$$PWD/undocommands/vpundopiecemove.cpp \
|
||||
$$PWD/undocommands/vpundopiecerotate.cpp \
|
||||
$$PWD/vpapplication.cpp \
|
||||
$$PWD/carousel/vpcarrousel.cpp \
|
||||
$$PWD/carousel/vpcarrouselpiece.cpp \
|
||||
|
@ -38,8 +41,12 @@ HEADERS += \
|
|||
$$PWD/dialogs/configpages/puzzlepreferencespathpage.h \
|
||||
$$PWD/dialogs/dialogpuzzlepreferences.h \
|
||||
$$PWD/dialogs/vpdialogabout.h \
|
||||
$$PWD/layout/layoutdef.h \
|
||||
$$PWD/scene/scenedef.h \
|
||||
$$PWD/stable.h \
|
||||
$$PWD/undocommands/vpundocommand.h \
|
||||
$$PWD/undocommands/vpundopiecemove.h \
|
||||
$$PWD/undocommands/vpundopiecerotate.h \
|
||||
$$PWD/vpapplication.h \
|
||||
$$PWD/carousel/vpcarrousel.h \
|
||||
$$PWD/carousel/vpcarrouselpiece.h \
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "vlayoutpiecepath.h"
|
||||
#include "vplacelabelitem.h"
|
||||
|
||||
#include "undocommands/vpundopiecemove.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece")
|
||||
|
||||
|
@ -55,7 +57,7 @@ constexpr qreal penWidth = 1;
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) :
|
||||
VPGraphicsPiece::VPGraphicsPiece(const VPPiecePtr &piece, QGraphicsItem *parent) :
|
||||
QGraphicsObject(parent),
|
||||
m_piece(piece)
|
||||
{
|
||||
|
@ -71,25 +73,11 @@ VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) :
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPiece::GetPiece() -> VPPiece*
|
||||
auto VPGraphicsPiece::GetPiece() -> VPPiecePtr
|
||||
{
|
||||
return m_piece;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::TranslatePiece(qreal dx, qreal dy)
|
||||
{
|
||||
TranslatePiece(QPointF(dx, dy));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::TranslatePiece(const QPointF &p)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
m_piece->Translate(p);
|
||||
PaintPiece(); // refresh shapes
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPiece::boundingRect() const -> QRectF
|
||||
{
|
||||
|
@ -149,6 +137,7 @@ void VPGraphicsPiece::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
GroupMove(event->pos());
|
||||
|
||||
m_moveStartPoint = event->pos();
|
||||
allowChangeMerge = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -161,18 +150,29 @@ void VPGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
GroupMove(event->pos());
|
||||
emit HideTransformationHandles(false);
|
||||
allowChangeMerge = false;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
||||
{
|
||||
QMenu menu;
|
||||
VPPiecePtr piece = m_piece.toStrongRef();
|
||||
if (piece.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<VPSheet *> sheets = m_piece->Layout()->GetSheets();
|
||||
sheets.removeAll(m_piece->Sheet());
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu menu;
|
||||
QList<VPSheetPtr> sheets = layout->GetSheets();
|
||||
sheets.removeAll(piece->Sheet());
|
||||
|
||||
QVector<QAction*> moveToActions;
|
||||
|
||||
|
@ -180,13 +180,16 @@ void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|||
{
|
||||
QMenu *moveMenu = menu.addMenu(tr("Move to"));
|
||||
|
||||
for (auto *sheet : sheets)
|
||||
for (const auto &sheet : sheets)
|
||||
{
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
QAction* moveToSheet = moveMenu->addAction(sheet->GetName());
|
||||
moveToSheet->setData(QVariant::fromValue(sheet));
|
||||
moveToActions.append(moveToSheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove from layout action
|
||||
QAction *removeAction = menu.addAction(tr("Remove from Sheet"));
|
||||
|
@ -195,13 +198,13 @@ void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|||
|
||||
if (moveToActions.contains(selectedAction))
|
||||
{
|
||||
m_piece->SetSheet(qvariant_cast<VPSheet *>(selectedAction->data()));
|
||||
emit m_piece->Layout()->PieceSheetChanged(m_piece);
|
||||
piece->SetSheet(qvariant_cast<VPSheetPtr>(selectedAction->data()));
|
||||
emit layout->PieceSheetChanged(piece);
|
||||
}
|
||||
else if (selectedAction == removeAction)
|
||||
{
|
||||
m_piece->SetSheet(nullptr);
|
||||
emit m_piece->Layout()->PieceSheetChanged(m_piece);
|
||||
piece->SetSheet(nullptr);
|
||||
emit layout->PieceSheetChanged(piece);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,11 +214,14 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
QBrush noBrush(Qt::NoBrush);
|
||||
QBrush selectionBrush(QColor(255,160,160,60));
|
||||
|
||||
QRectF rect = m_piece->MappedDetailBoundingRect();
|
||||
QPointF p = rect.topLeft();
|
||||
VPPiecePtr piece = m_piece.toStrongRef();
|
||||
if (piece.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// initialises the seam line
|
||||
QVector<QPointF> seamLinePoints = m_piece->GetMappedContourPoints();
|
||||
QVector<QPointF> seamLinePoints = piece->GetMappedContourPoints();
|
||||
if(!seamLinePoints.isEmpty())
|
||||
{
|
||||
m_seamLine = QPainterPath();
|
||||
|
@ -235,7 +241,7 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
}
|
||||
|
||||
// initiliases the cutting line
|
||||
QVector<QPointF> cuttingLinepoints = m_piece->GetMappedSeamAllowancePoints();
|
||||
QVector<QPointF> cuttingLinepoints = piece->GetMappedSeamAllowancePoints();
|
||||
if(!cuttingLinepoints.isEmpty())
|
||||
{
|
||||
m_cuttingLine = QPainterPath();
|
||||
|
@ -255,9 +261,9 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
}
|
||||
|
||||
// initialises the grainline
|
||||
if(m_piece->IsGrainlineEnabled())
|
||||
if(piece->IsGrainlineEnabled())
|
||||
{
|
||||
QVector<QPointF> grainLinepoints = m_piece->GetMappedGrainline();
|
||||
QVector<QPointF> grainLinepoints = piece->GetMappedGrainline();
|
||||
if(!grainLinepoints.isEmpty())
|
||||
{
|
||||
QPainterPath grainline;
|
||||
|
@ -282,10 +288,10 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
}
|
||||
|
||||
// initialises the internal paths
|
||||
QVector<VLayoutPiecePath> internalPaths = m_piece->GetInternalPaths();
|
||||
QVector<VLayoutPiecePath> internalPaths = piece->GetInternalPaths();
|
||||
for (const auto& piecePath : internalPaths)
|
||||
{
|
||||
QPainterPath path = m_piece->GetMatrix().map(piecePath.GetPainterPath());
|
||||
QPainterPath path = piece->GetMatrix().map(piecePath.GetPainterPath());
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
|
@ -297,7 +303,7 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
}
|
||||
|
||||
// initialises the passmarks
|
||||
QVector<VLayoutPassmark> passmarks = m_piece->GetMappedPassmarks();
|
||||
QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks();
|
||||
for(auto &passmark : passmarks)
|
||||
{
|
||||
QPainterPath passmarkPath;
|
||||
|
@ -317,7 +323,7 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
|||
}
|
||||
|
||||
// initialises the place labels (buttons etc)
|
||||
QVector<VLayoutPlaceLabel> placeLabels = m_piece->GetMappedPlaceLabels();
|
||||
QVector<VLayoutPlaceLabel> placeLabels = piece->GetMappedPlaceLabels();
|
||||
for(auto &placeLabel : placeLabels)
|
||||
{
|
||||
QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape);
|
||||
|
@ -345,27 +351,63 @@ void VPGraphicsPiece::GroupMove(const QPointF &pos)
|
|||
if (scene() != nullptr)
|
||||
{
|
||||
QList<QGraphicsItem *> list = scene()->selectedItems();
|
||||
|
||||
if (list.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPPiecePtr piece = m_piece.toStrongRef();
|
||||
if (piece.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto PreparePieces = [list]()
|
||||
{
|
||||
QVector<VPPiecePtr> pieces;
|
||||
for (auto *item : list)
|
||||
{
|
||||
if (item->type() == UserType + static_cast<int>(PGraphicsItem::Piece))
|
||||
if (item->type() == VPGraphicsPiece::Type)
|
||||
{
|
||||
auto *pieceItem = dynamic_cast<VPGraphicsPiece*>(item);
|
||||
pieceItem->TranslatePiece(pos-m_moveStartPoint);
|
||||
pieces.append(pieceItem->GetPiece());
|
||||
}
|
||||
}
|
||||
emit PiecePositionChanged();
|
||||
|
||||
return pieces;
|
||||
};
|
||||
|
||||
QVector<VPPiecePtr> pieces = PreparePieces();
|
||||
QPointF newPos = pos - m_moveStartPoint;
|
||||
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
auto *command = new VPUndoPieceMove(pieces.first(), newPos.x(), newPos.y(), allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
}
|
||||
else if (pieces.size() > 1)
|
||||
{
|
||||
auto *command = new VPUndoPiecesMove(pieces, newPos.x(), newPos.y(), allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::on_Rotate(const QPointF ¢er, qreal angle)
|
||||
void VPGraphicsPiece::on_RefreshPiece(const VPPiecePtr &piece)
|
||||
{
|
||||
if (isSelected())
|
||||
if (m_piece == piece)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
m_piece->Rotate(center, angle);
|
||||
PaintPiece(); // Update shapes
|
||||
update();
|
||||
PaintPiece(); // refresh shapes
|
||||
emit PieceTransformationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,9 +417,13 @@ auto VPGraphicsPiece::itemChange(GraphicsItemChange change, const QVariant &valu
|
|||
if (scene() != nullptr)
|
||||
{
|
||||
if(change == ItemSelectedHasChanged)
|
||||
{
|
||||
VPPiecePtr piece = m_piece.toStrongRef();
|
||||
if (not piece.isNull())
|
||||
{
|
||||
emit PieceSelectionChanged();
|
||||
m_piece->SetSelected(value.toBool());
|
||||
piece->SetSelected(value.toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,24 +33,20 @@
|
|||
#include <QCursor>
|
||||
|
||||
#include "scenedef.h"
|
||||
|
||||
class VPPiece;
|
||||
#include "../layout/layoutdef.h"
|
||||
|
||||
class VPGraphicsPiece : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent = nullptr);
|
||||
explicit VPGraphicsPiece(const VPPiecePtr &piece, QGraphicsItem *parent = nullptr);
|
||||
~VPGraphicsPiece() = default;
|
||||
|
||||
/**
|
||||
* @brief GetPiece Returns the piece that corresponds to the graphics piece
|
||||
* @return the piece
|
||||
*/
|
||||
auto GetPiece() -> VPPiece*;
|
||||
|
||||
void TranslatePiece(qreal dx, qreal dy);
|
||||
void TranslatePiece(const QPointF &p);
|
||||
auto GetPiece() -> VPPiecePtr;
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::Piece)};
|
||||
|
@ -58,10 +54,10 @@ public:
|
|||
signals:
|
||||
void PieceSelectionChanged();
|
||||
void HideTransformationHandles(bool hide);
|
||||
void PiecePositionChanged();
|
||||
void PieceTransformationChanged();
|
||||
|
||||
public slots:
|
||||
void on_Rotate(const QPointF ¢er, qreal angle);
|
||||
void on_RefreshPiece(const VPPiecePtr &piece);
|
||||
|
||||
protected:
|
||||
auto boundingRect() const -> QRectF override;
|
||||
|
@ -78,7 +74,7 @@ protected:
|
|||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPGraphicsPiece)
|
||||
VPPiece *m_piece;
|
||||
VPPieceWeakPtr m_piece;
|
||||
|
||||
QPainterPath m_cuttingLine{};
|
||||
QPainterPath m_seamLine{};
|
||||
|
@ -88,6 +84,8 @@ private:
|
|||
|
||||
QCursor m_rotateCursor{};
|
||||
|
||||
bool allowChangeMerge{false};
|
||||
|
||||
void PaintPiece(QPainter *painter=nullptr);
|
||||
|
||||
void GroupMove(const QPointF &pos);
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "../vmisc/compatibility.h"
|
||||
#include "../vwidgets/global.h"
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../undocommands/vpundopiecerotate.h"
|
||||
#include "vpgraphicspiece.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -67,11 +69,11 @@ enum class HandleCorner : int
|
|||
BottomLeft = 4
|
||||
};
|
||||
|
||||
auto TransformationOrigin(VPLayout *layout, const QRectF &boundingRect) -> QPointF
|
||||
auto TransformationOrigin(const VPLayoutPtr &layout, const QRectF &boundingRect) -> QPointF
|
||||
{
|
||||
SCASSERT(layout != nullptr)
|
||||
VPSheet *sheet = layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
return origin.origin;
|
||||
|
@ -82,7 +84,7 @@ auto TransformationOrigin(VPLayout *layout, const QRectF &boundingRect) -> QPoin
|
|||
} // namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsTransformationOrigin::VPGraphicsTransformationOrigin(VPLayout *layout, QGraphicsItem *parent)
|
||||
VPGraphicsTransformationOrigin::VPGraphicsTransformationOrigin(const VPLayoutPtr &layout, QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent),
|
||||
m_layout(layout),
|
||||
m_color(defaultColor)
|
||||
|
@ -113,14 +115,14 @@ void VPGraphicsTransformationOrigin::on_ShowOrigin(bool show)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsTransformationOrigin::boundingRect() const
|
||||
auto VPGraphicsTransformationOrigin::boundingRect() const -> QRectF
|
||||
{
|
||||
constexpr qreal halfPenWidth = penWidth/2.;
|
||||
return Center2().boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsTransformationOrigin::shape() const
|
||||
auto VPGraphicsTransformationOrigin::shape() const -> QPainterPath
|
||||
{
|
||||
return Center2();
|
||||
}
|
||||
|
@ -170,8 +172,11 @@ void VPGraphicsTransformationOrigin::mousePressEvent(QGraphicsSceneMouseEvent *e
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
origin.origin = event->scenePos();
|
||||
|
@ -179,6 +184,7 @@ void VPGraphicsTransformationOrigin::mouseMoveEvent(QGraphicsSceneMouseEvent *ev
|
|||
sheet->SetTransformationOrigin(origin);
|
||||
}
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
QGraphicsObject::mouseMoveEvent(event);
|
||||
}
|
||||
|
@ -251,7 +257,7 @@ auto VPGraphicsTransformationOrigin::RotationCenter(QPainter *painter) const ->
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsTransformationOrigin::Center1() const
|
||||
auto VPGraphicsTransformationOrigin::Center1() const -> QPainterPath
|
||||
{
|
||||
const qreal scale = SceneScale(scene());
|
||||
qreal radius = centerRadius1/scale;
|
||||
|
@ -265,7 +271,7 @@ QPainterPath VPGraphicsTransformationOrigin::Center1() const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsTransformationOrigin::Center2() const
|
||||
auto VPGraphicsTransformationOrigin::Center2() const -> QPainterPath
|
||||
{
|
||||
const qreal scale = SceneScale(scene());
|
||||
qreal radius = centerRadius2/scale;
|
||||
|
@ -280,7 +286,7 @@ QPainterPath VPGraphicsTransformationOrigin::Center2() const
|
|||
|
||||
// VPGraphicsPieceControls
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsPieceControls::VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem *parent)
|
||||
VPGraphicsPieceControls::VPGraphicsPieceControls(const VPLayoutPtr &layout, QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent),
|
||||
m_layout(layout)
|
||||
{
|
||||
|
@ -294,13 +300,22 @@ VPGraphicsPieceControls::VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::on_UpdateControls()
|
||||
{
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
if (m_ignorePieceTransformation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_selectedPieces = SelectedPieces();
|
||||
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
|
||||
setVisible(not m_pieceRect.isNull());
|
||||
|
||||
if (not m_pieceRect.isNull())
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
if (not origin.custom)
|
||||
|
@ -311,6 +326,7 @@ void VPGraphicsPieceControls::on_UpdateControls()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit ShowOrigin(not m_pieceRect.isNull());
|
||||
prepareGeometryChange();
|
||||
|
@ -320,6 +336,7 @@ void VPGraphicsPieceControls::on_UpdateControls()
|
|||
void VPGraphicsPieceControls::on_HideHandles(bool hide)
|
||||
{
|
||||
m_controlsVisible = not hide;
|
||||
update();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -364,6 +381,7 @@ void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
m_rotationStartPoint = event->scenePos();
|
||||
m_controlsVisible = false;
|
||||
m_handleCorner = HandleCorner(event->scenePos());
|
||||
m_ignorePieceTransformation = true;
|
||||
prepareGeometryChange();
|
||||
}
|
||||
else
|
||||
|
@ -380,12 +398,15 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
{
|
||||
if (not m_originSaved)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
m_savedOrigin = sheet->TransformationOrigin();
|
||||
m_originSaved = true;
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
|
||||
|
||||
VPTransformationOrigon origin;
|
||||
origin.custom = true;
|
||||
|
@ -412,16 +433,20 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_originSaved)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
if (not m_savedOrigin.custom)
|
||||
{
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
|
||||
m_savedOrigin.origin = m_pieceRect.center();
|
||||
}
|
||||
sheet->SetTransformationOrigin(m_savedOrigin);
|
||||
|
@ -430,6 +455,7 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
m_originSaved = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPointF rotationNewPoint = event->scenePos();
|
||||
|
||||
|
@ -442,7 +468,33 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
|
||||
if (not qFuzzyIsNull(angle))
|
||||
{
|
||||
emit Rotate(rotationOrigin, angle);
|
||||
auto PreparePieces = [this]()
|
||||
{
|
||||
QVector<VPPiecePtr> pieces;
|
||||
for (auto *item : m_selectedPieces)
|
||||
{
|
||||
pieces.append(item->GetPiece());
|
||||
}
|
||||
|
||||
return pieces;
|
||||
};
|
||||
|
||||
QVector<VPPiecePtr> pieces = PreparePieces();
|
||||
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
auto *command = new VPUndoPieceRotate(pieces.first(), rotationOrigin, angle, allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
}
|
||||
else if (pieces.size() > 1)
|
||||
{
|
||||
auto *command = new VPUndoPiecesRotate(pieces, rotationOrigin, angle, allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_originSaved && m_savedOrigin.custom)
|
||||
|
@ -453,6 +505,7 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
}
|
||||
|
||||
m_rotationStartPoint = rotationNewPoint;
|
||||
allowChangeMerge = true;
|
||||
QGraphicsObject::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
|
@ -462,15 +515,19 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_controlsVisible = true;
|
||||
m_ignorePieceTransformation = false;
|
||||
|
||||
if (m_originSaved)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
{
|
||||
VPSheetPtr sheet = layout->GetFocusedSheet();
|
||||
if (not sheet.isNull())
|
||||
{
|
||||
if (not m_savedOrigin.custom)
|
||||
{
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
m_pieceRect = PiecesBoundingRect(m_selectedPieces);
|
||||
m_savedOrigin.origin = m_pieceRect.center();
|
||||
}
|
||||
sheet->SetTransformationOrigin(m_savedOrigin);
|
||||
|
@ -478,12 +535,20 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
}
|
||||
m_originSaved = false;
|
||||
}
|
||||
}
|
||||
|
||||
on_UpdateControls();
|
||||
allowChangeMerge = false;
|
||||
}
|
||||
QGraphicsObject::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::SetIgnorePieceTransformation(bool newIgnorePieceTransformation)
|
||||
{
|
||||
m_ignorePieceTransformation = newIgnorePieceTransformation;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::TopLeftControl(QPainter *painter) const -> QPainterPath
|
||||
{
|
||||
|
@ -522,7 +587,7 @@ auto VPGraphicsPieceControls::BottomRightControl(QPainter *painter) const -> QPa
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsPieceControls::Handles() const
|
||||
auto VPGraphicsPieceControls::Handles() const -> QPainterPath
|
||||
{
|
||||
QPainterPath path;
|
||||
|
||||
|
@ -690,21 +755,37 @@ auto VPGraphicsPieceControls::ArrowPath() const -> QPainterPath
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsPieceControls::PiecesBoundingRect() const
|
||||
auto VPGraphicsPieceControls::SelectedPieces() const -> QVector<VPGraphicsPiece *>
|
||||
{
|
||||
QRectF rect;
|
||||
QVector<VPGraphicsPiece *> pieces;
|
||||
QGraphicsScene *scene = this->scene();
|
||||
if (scene != nullptr)
|
||||
{
|
||||
QList<QGraphicsItem *> list = scene->selectedItems();
|
||||
for (auto *item : list)
|
||||
{
|
||||
if (item->type() == UserType + static_cast<int>(PGraphicsItem::Piece))
|
||||
if (item->type() == VPGraphicsPiece::Type)
|
||||
{
|
||||
auto *pieceItem = dynamic_cast<VPGraphicsPiece*>(item);
|
||||
if (pieceItem != nullptr)
|
||||
{
|
||||
pieces.append(pieceItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pieces;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) const -> QRectF
|
||||
{
|
||||
QRectF rect;
|
||||
for (auto *item : selectedPieces)
|
||||
{
|
||||
rect = rect.united(item->sceneBoundingRect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
|
|
@ -35,12 +35,13 @@
|
|||
#include "../layout/vpsheet.h"
|
||||
|
||||
class VPLayout;
|
||||
class VPGraphicsPiece;
|
||||
|
||||
class VPGraphicsTransformationOrigin : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPGraphicsTransformationOrigin(VPLayout *layout, QGraphicsItem * parent = nullptr);
|
||||
explicit VPGraphicsTransformationOrigin(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::TransformationOrigin)};
|
||||
|
@ -66,7 +67,7 @@ private:
|
|||
Q_DISABLE_COPY(VPGraphicsTransformationOrigin)
|
||||
|
||||
bool m_originVisible{true};
|
||||
VPLayout *m_layout;
|
||||
VPLayoutWeakPtr m_layout{};
|
||||
QColor m_color;
|
||||
|
||||
auto RotationCenter(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
|
@ -78,13 +79,14 @@ class VPGraphicsPieceControls : public QGraphicsObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem * parent = nullptr);
|
||||
explicit VPGraphicsPieceControls(const VPLayoutPtr &layout, QGraphicsItem * parent = nullptr);
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::Handles)};
|
||||
|
||||
void SetIgnorePieceTransformation(bool newIgnorePieceTransformation);
|
||||
|
||||
signals:
|
||||
void Rotate(const QPointF ¢er, qreal angle);
|
||||
void ShowOrigin(bool show);
|
||||
void TransformationOriginChanged();
|
||||
|
||||
|
@ -106,10 +108,13 @@ private:
|
|||
QRectF m_pieceRect{};
|
||||
QPointF m_rotationStartPoint{};
|
||||
bool m_controlsVisible{true};
|
||||
VPLayout *m_layout;
|
||||
VPLayoutWeakPtr m_layout{};
|
||||
int m_handleCorner{0};
|
||||
VPTransformationOrigon m_savedOrigin{};
|
||||
bool m_originSaved{false};
|
||||
bool allowChangeMerge{false};
|
||||
QVector<VPGraphicsPiece *> m_selectedPieces{};
|
||||
bool m_ignorePieceTransformation{false};
|
||||
|
||||
auto TopLeftControl(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
auto TopRightControl(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
|
@ -122,7 +127,8 @@ private:
|
|||
|
||||
auto ArrowPath() const -> QPainterPath;
|
||||
|
||||
auto PiecesBoundingRect() const -> QRectF;
|
||||
auto SelectedPieces() const -> QVector<VPGraphicsPiece *>;
|
||||
auto PiecesBoundingRect(const QVector<VPGraphicsPiece *> &selectedPieces) const -> QRectF;
|
||||
auto HandleCorner(const QPointF &pos) const -> int;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/************************************************************************
|
||||
/*******************************************************************
|
||||
**
|
||||
** @file vpgraphicssheet.cpp
|
||||
** @author Ronan Le Tiec
|
||||
|
@ -33,7 +33,7 @@
|
|||
#include <QtMath>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsSheet::VPGraphicsSheet(VPLayout *layout, QGraphicsItem *parent):
|
||||
VPGraphicsSheet::VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent):
|
||||
QGraphicsItem(parent),
|
||||
m_layout(layout),
|
||||
m_boundingRect(GetSheetRect())
|
||||
|
@ -66,12 +66,14 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
|
|||
painter->drawRect(sheetRect);
|
||||
}
|
||||
|
||||
if(m_layout->LayoutSettings().GetShowGrid())
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
|
||||
if(not layout.isNull() && layout->LayoutSettings().GetShowGrid())
|
||||
{
|
||||
pen.setColor(QColor(204,204,204));
|
||||
painter->setPen(pen);
|
||||
|
||||
qreal colWidth = m_layout->LayoutSettings().GetGridColWidth();
|
||||
qreal colWidth = layout->LayoutSettings().GetGridColWidth();
|
||||
if(colWidth > 0)
|
||||
{
|
||||
qreal colX = colWidth;
|
||||
|
@ -83,7 +85,7 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
|
|||
}
|
||||
}
|
||||
|
||||
qreal rowHeight = m_layout->LayoutSettings().GetGridRowHeight();
|
||||
qreal rowHeight = layout->LayoutSettings().GetGridRowHeight();
|
||||
if(rowHeight > 0)
|
||||
{
|
||||
qreal rowY = rowHeight;
|
||||
|
@ -101,11 +103,17 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsSheet::GetSheetRect() const
|
||||
auto VPGraphicsSheet::GetSheetRect() const -> QRectF
|
||||
{
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QPoint topLeft = QPoint(0,0);
|
||||
QSizeF size = m_layout->LayoutSettings().GetSheetSize();
|
||||
if(m_layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape)
|
||||
QSizeF size = layout->LayoutSettings().GetSheetSize();
|
||||
if(layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape)
|
||||
{
|
||||
size.transpose();
|
||||
}
|
||||
|
@ -114,20 +122,24 @@ QRectF VPGraphicsSheet::GetSheetRect() const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsSheet::GetMarginsRect() const
|
||||
auto VPGraphicsSheet::GetMarginsRect() const -> QRectF
|
||||
{
|
||||
QMarginsF margins = m_layout->LayoutSettings().GetSheetMargins();
|
||||
QSizeF size = m_layout->LayoutSettings().GetSheetSize();
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if(m_layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape)
|
||||
QMarginsF margins = layout->LayoutSettings().GetSheetMargins();
|
||||
QSizeF size = layout->LayoutSettings().GetSheetSize();
|
||||
|
||||
if(layout->LayoutSettings().GetOrientation() == PageOrientation::Landscape)
|
||||
{
|
||||
size.transpose();
|
||||
}
|
||||
|
||||
QRectF rect = QRectF(
|
||||
QPointF(margins.left(),margins.top()),
|
||||
QPointF(size.width()-margins.right(), size.height()-margins.bottom())
|
||||
);
|
||||
QRectF rect = QRectF(QPointF(margins.left(),margins.top()),
|
||||
QPointF(size.width()-margins.right(), size.height()-margins.bottom()));
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
@ -144,7 +156,7 @@ void VPGraphicsSheet::SetShowBorder(bool value)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsSheet::boundingRect() const
|
||||
auto VPGraphicsSheet::boundingRect() const -> QRectF
|
||||
{
|
||||
return m_boundingRect;
|
||||
}
|
||||
|
|
|
@ -32,19 +32,21 @@
|
|||
#include <QGraphicsItem>
|
||||
#include <QPainter>
|
||||
|
||||
#include "../layout/layoutdef.h"
|
||||
|
||||
class VPLayout;
|
||||
|
||||
class VPGraphicsSheet : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
explicit VPGraphicsSheet(VPLayout *sheet, QGraphicsItem *parent = nullptr);
|
||||
explicit VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent = nullptr);
|
||||
~VPGraphicsSheet()=default;
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
auto boundingRect() const -> QRectF override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
QRectF GetSheetRect() const;
|
||||
QRectF GetMarginsRect() const;
|
||||
auto GetSheetRect() const -> QRectF;
|
||||
auto GetMarginsRect() const -> QRectF;
|
||||
|
||||
/**
|
||||
* @brief SetShowMargin Sets Wether we see the margin
|
||||
|
@ -61,7 +63,7 @@ public:
|
|||
private:
|
||||
Q_DISABLE_COPY(VPGraphicsSheet)
|
||||
|
||||
VPLayout *m_layout{nullptr};
|
||||
VPLayoutWeakPtr m_layout{};
|
||||
QRectF m_boundingRect;
|
||||
|
||||
bool m_showMargin{true};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "../layout/vplayout.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsTileGrid::VPGraphicsTileGrid(VPLayout *layout, VPTileFactory *tileFactory,QGraphicsItem *parent):
|
||||
VPGraphicsTileGrid::VPGraphicsTileGrid(const VPLayoutPtr &layout, VPTileFactory *tileFactory, QGraphicsItem *parent):
|
||||
QGraphicsItem(parent),
|
||||
m_tileFactory(tileFactory),
|
||||
m_layout(layout)
|
||||
|
@ -21,7 +21,8 @@ VPGraphicsTileGrid::~VPGraphicsTileGrid()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsTileGrid::boundingRect() const
|
||||
{
|
||||
if(m_layout->LayoutSettings().GetShowTiles())
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if(not layout.isNull() && layout->LayoutSettings().GetShowTiles())
|
||||
{
|
||||
return QRectF(0,
|
||||
0,
|
||||
|
@ -39,7 +40,8 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem
|
|||
Q_UNUSED(widget);
|
||||
Q_UNUSED(option);
|
||||
|
||||
if(m_layout->LayoutSettings().GetShowTiles())
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if(not layout.isNull() && layout->LayoutSettings().GetShowTiles())
|
||||
{
|
||||
QPen pen(QColor(255,0,0,127), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
pen.setCosmetic(true);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <QPainter>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
#include "../layout/layoutdef.h"
|
||||
|
||||
class VPTileFactory;
|
||||
class VPLayout;
|
||||
|
@ -40,7 +41,7 @@ class VPLayout;
|
|||
class VPGraphicsTileGrid : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
explicit VPGraphicsTileGrid(VPLayout* layout, VPTileFactory *tileFactory, QGraphicsItem *parent = nullptr);
|
||||
explicit VPGraphicsTileGrid(const VPLayoutPtr &layout, VPTileFactory *tileFactory, QGraphicsItem *parent = nullptr);
|
||||
~VPGraphicsTileGrid();
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
|
@ -50,8 +51,8 @@ public:
|
|||
private:
|
||||
Q_DISABLE_COPY(VPGraphicsTileGrid)
|
||||
|
||||
VPTileFactory *m_tileFactory{nullptr};
|
||||
VPLayout *m_layout{nullptr};
|
||||
VPTileFactory * m_tileFactory{nullptr};
|
||||
VPLayoutWeakPtr m_layout{};
|
||||
};
|
||||
|
||||
#endif // VPGRAPHICSTILEGRID_H
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "vptilefactory.h"
|
||||
#include "vpgraphicspiececontrols.h"
|
||||
#include "../undocommands/vpundopiecemove.h"
|
||||
#include "../undocommands/vpundopiecerotate.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
@ -95,36 +96,6 @@ VPMainGraphicsView::VPMainGraphicsView(const VPLayoutPtr &layout, VPTileFactory
|
|||
restoreOrigin->setShortcut(restoreOriginShortcut);
|
||||
connect(restoreOrigin, &QAction::triggered, this, &VPMainGraphicsView::RestoreOrigin);
|
||||
this->addAction(restoreOrigin);
|
||||
|
||||
auto *rotateByPlus15 = new QAction(this);
|
||||
rotateByPlus15->setShortcut(QKeySequence(Qt::Key_BracketLeft));
|
||||
connect(rotateByPlus15, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByPlus15);
|
||||
this->addAction(rotateByPlus15);
|
||||
|
||||
auto *rotateByMinus15 = new QAction(this);
|
||||
rotateByMinus15->setShortcut(QKeySequence(Qt::Key_BracketRight));
|
||||
connect(rotateByMinus15, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByMinus15);
|
||||
this->addAction(rotateByMinus15);
|
||||
|
||||
auto *rotateByPlus90 = new QAction(this);
|
||||
rotateByPlus90->setShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_BracketLeft));
|
||||
connect(rotateByPlus90, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByPlus90);
|
||||
this->addAction(rotateByPlus90);
|
||||
|
||||
auto *rotateByMinus90 = new QAction(this);
|
||||
rotateByMinus90->setShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_BracketRight));
|
||||
connect(rotateByMinus90, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByMinus90);
|
||||
this->addAction(rotateByMinus90);
|
||||
|
||||
auto *rotateByPlus1 = new QAction(this);
|
||||
rotateByPlus1->setShortcut(QKeySequence(Qt::AltModifier + Qt::Key_BracketLeft));
|
||||
connect(rotateByPlus1, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByPlus1);
|
||||
this->addAction(rotateByPlus1);
|
||||
|
||||
auto *rotateByMinus1 = new QAction(this);
|
||||
rotateByMinus1->setShortcut(QKeySequence(Qt::AltModifier + Qt::Key_BracketRight));
|
||||
connect(rotateByMinus1, &QAction::triggered, this, &VPMainGraphicsView::RotatePiecesByMinus1);
|
||||
this->addAction(rotateByMinus1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -342,17 +313,62 @@ void VPMainGraphicsView::keyPressEvent(QKeyEvent *event)
|
|||
TranslatePiecesOn(0, 1);
|
||||
}
|
||||
}
|
||||
else if (event->key() == Qt::Key_BracketLeft)
|
||||
{
|
||||
if((event->modifiers() & Qt::ControlModifier) != 0U)
|
||||
{
|
||||
RotatePiecesByAngle(90);
|
||||
}
|
||||
else if((event->modifiers() & Qt::AltModifier) != 0U)
|
||||
{
|
||||
RotatePiecesByAngle(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RotatePiecesByAngle(15);
|
||||
}
|
||||
}
|
||||
else if (event->key() == Qt::Key_BracketRight)
|
||||
{
|
||||
if((event->modifiers() & Qt::ControlModifier) != 0U)
|
||||
{
|
||||
RotatePiecesByAngle(-90);
|
||||
}
|
||||
else if((event->modifiers() & Qt::AltModifier) != 0U)
|
||||
{
|
||||
RotatePiecesByAngle(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RotatePiecesByAngle(-15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
VMainGraphicsView::keyReleaseEvent(event);
|
||||
if (event->key() != Qt::Key_Left && event->key() != Qt::Key_Right && event->key() != Qt::Key_Up &&
|
||||
event->key() != Qt::Key_Down)
|
||||
if (event->key() == Qt::Key_Left ||
|
||||
event->key() == Qt::Key_Right ||
|
||||
event->key() == Qt::Key_Up ||
|
||||
event->key() == Qt::Key_Down ||
|
||||
event->key() == Qt::Key_BracketLeft ||
|
||||
event->key() == Qt::Key_BracketRight)
|
||||
{
|
||||
if (not event->isAutoRepeat())
|
||||
{
|
||||
m_allowChangeMerge = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->key() == Qt::Key_BracketLeft || event->key() == Qt::Key_BracketRight)
|
||||
{
|
||||
if (not event->isAutoRepeat())
|
||||
{
|
||||
m_rotationControls->SetIgnorePieceTransformation(false);
|
||||
}
|
||||
}
|
||||
VMainGraphicsView::keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -428,42 +444,6 @@ void VPMainGraphicsView::RestoreOrigin() const
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByPlus15() const
|
||||
{
|
||||
RotatePiecesByAngle(15);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByMinus15() const
|
||||
{
|
||||
RotatePiecesByAngle(-15);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByPlus90() const
|
||||
{
|
||||
RotatePiecesByAngle(90);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByMinus90() const
|
||||
{
|
||||
RotatePiecesByAngle(-90);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByPlus1() const
|
||||
{
|
||||
RotatePiecesByAngle(1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByMinus1() const
|
||||
{
|
||||
RotatePiecesByAngle(-1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
|
||||
{
|
||||
|
@ -477,7 +457,6 @@ void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
|
|||
m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls);
|
||||
connect(piece, &VPGraphicsPiece::PieceTransformationChanged,
|
||||
m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls);
|
||||
connect(m_rotationControls, &VPGraphicsPieceControls::Rotate, piece, &VPGraphicsPiece::on_Rotate);
|
||||
connect(piece, &VPGraphicsPiece::HideTransformationHandles,
|
||||
m_rotationControls, &VPGraphicsPieceControls::on_HideHandles);
|
||||
connect(piece, &VPGraphicsPiece::HideTransformationHandles,
|
||||
|
@ -485,8 +464,10 @@ void VPMainGraphicsView::ConnectPiece(VPGraphicsPiece *piece)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const
|
||||
void VPMainGraphicsView::RotatePiecesByAngle(qreal angle)
|
||||
{
|
||||
m_rotationControls->SetIgnorePieceTransformation(true);
|
||||
|
||||
VPLayoutPtr layout = m_layout.toStrongRef();
|
||||
if (layout.isNull())
|
||||
{
|
||||
|
@ -501,14 +482,34 @@ void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const
|
|||
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
|
||||
for(auto *graphicsPiece : m_graphicsPieces)
|
||||
auto PreparePieces = [this]()
|
||||
{
|
||||
if (graphicsPiece->isSelected())
|
||||
QVector<VPPiecePtr> pieces;
|
||||
for (auto *item : m_graphicsPieces)
|
||||
{
|
||||
graphicsPiece->on_Rotate(origin.origin, angle);
|
||||
m_rotationControls->on_UpdateControls();
|
||||
if (item->isSelected())
|
||||
{
|
||||
pieces.append(item->GetPiece());
|
||||
}
|
||||
}
|
||||
|
||||
return pieces;
|
||||
};
|
||||
|
||||
QVector<VPPiecePtr> pieces = PreparePieces();
|
||||
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
auto *command = new VPUndoPieceRotate(pieces.first(), origin.origin, angle, m_allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
}
|
||||
else if (pieces.size() > 1)
|
||||
{
|
||||
auto *command = new VPUndoPiecesRotate(pieces, origin.origin, angle, m_allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
}
|
||||
|
||||
m_allowChangeMerge = true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -98,12 +98,6 @@ protected:
|
|||
|
||||
private slots:
|
||||
void RestoreOrigin() const;
|
||||
void RotatePiecesByPlus15() const;
|
||||
void RotatePiecesByMinus15() const;
|
||||
void RotatePiecesByPlus90() const;
|
||||
void RotatePiecesByMinus90() const;
|
||||
void RotatePiecesByPlus1() const;
|
||||
void RotatePiecesByMinus1() const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPMainGraphicsView)
|
||||
|
@ -134,7 +128,7 @@ private:
|
|||
|
||||
void ConnectPiece(VPGraphicsPiece *piece);
|
||||
|
||||
void RotatePiecesByAngle(qreal angle) const;
|
||||
void RotatePiecesByAngle(qreal angle);
|
||||
void TranslatePiecesOn(qreal dx, qreal dy);
|
||||
|
||||
};
|
||||
|
|
|
@ -37,7 +37,9 @@ namespace ML
|
|||
enum class UndoCommand: qint8
|
||||
{
|
||||
MovePiece = 0,
|
||||
MovePieces = 1
|
||||
MovePieces = 1,
|
||||
RotatePiece = 2,
|
||||
RotatePieces = 3,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
266
src/app/puzzle/undocommands/vpundopiecerotate.cpp
Normal file
266
src/app/puzzle/undocommands/vpundopiecerotate.cpp
Normal file
|
@ -0,0 +1,266 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpundopiecerotate.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 18 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 "vpundopiecerotate.h"
|
||||
#include "../layout/vppiece.h"
|
||||
#include "../layout/vplayout.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPUndoPieceRotate::VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &origin, qreal angle, bool allowMerge,
|
||||
QUndoCommand *parent)
|
||||
: VPUndoCommand(parent),
|
||||
m_piece(piece),
|
||||
m_origin(origin),
|
||||
m_angle(angle),
|
||||
m_allowMerge(allowMerge)
|
||||
{
|
||||
SCASSERT(not piece.isNull())
|
||||
|
||||
m_oldTransform = piece->GetMatrix();
|
||||
|
||||
setText(QObject::tr("rotate piece"));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPUndoPieceRotate::undo()
|
||||
{
|
||||
VPPiecePtr piece = Piece();
|
||||
if (piece.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
layout->SetFocusedSheet(piece->Sheet());
|
||||
|
||||
piece->SetMatrix(m_oldTransform);
|
||||
emit layout->PieceTransformationChanged(piece);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPUndoPieceRotate::redo()
|
||||
{
|
||||
VPPiecePtr piece = Piece();
|
||||
if (piece.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPLayoutPtr layout = piece->Layout();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
layout->SetFocusedSheet(piece->Sheet());
|
||||
|
||||
piece->Rotate(m_origin, m_angle);
|
||||
emit layout->PieceTransformationChanged(piece);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPUndoPieceRotate::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 VPUndoPieceRotate *>(command);
|
||||
SCASSERT(moveCommand != nullptr)
|
||||
|
||||
VPPiecePtr piece = Piece();
|
||||
if (not moveCommand->AllowMerge() || (moveCommand->Piece().isNull() || piece.isNull()) ||
|
||||
moveCommand->Piece() != piece || moveCommand->Origin() != m_origin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_angle += moveCommand->Angle();
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPUndoPieceRotate::id() const -> int
|
||||
{
|
||||
return static_cast<int>(ML::UndoCommand::RotatePiece);
|
||||
}
|
||||
|
||||
// rotate pieces
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPUndoPiecesRotate::VPUndoPiecesRotate(const QVector<VPPiecePtr> &pieces, const QPointF &origin, qreal angle,
|
||||
bool allowMerge, QUndoCommand *parent)
|
||||
: VPUndoCommand(parent),
|
||||
m_origin(origin),
|
||||
m_angle(angle),
|
||||
m_allowMerge(allowMerge)
|
||||
{
|
||||
setText(QObject::tr("rotate pieces"));
|
||||
|
||||
for (const auto& piece : pieces)
|
||||
{
|
||||
if (not piece.isNull())
|
||||
{
|
||||
m_pieces.append(piece);
|
||||
m_oldTransforms.insert(piece->GetUniqueID(), piece->GetMatrix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPUndoPiecesRotate::undo()
|
||||
{
|
||||
if (m_pieces.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPLayoutPtr layout = Layout();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
layout->SetFocusedSheet(Sheet());
|
||||
|
||||
for (const auto& piece : m_pieces)
|
||||
{
|
||||
VPPiecePtr p = piece.toStrongRef();
|
||||
if (not p.isNull())
|
||||
{
|
||||
if (m_oldTransforms.contains(p->GetUniqueID()))
|
||||
{
|
||||
p->SetMatrix(m_oldTransforms.value(p->GetUniqueID()));
|
||||
emit layout->PieceTransformationChanged(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPUndoPiecesRotate::redo()
|
||||
{
|
||||
if (m_pieces.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPLayoutPtr layout = Layout();
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
layout->SetFocusedSheet(Sheet());
|
||||
|
||||
for (const auto& piece : m_pieces)
|
||||
{
|
||||
VPPiecePtr p = piece.toStrongRef();
|
||||
if (not p.isNull())
|
||||
{
|
||||
p->Rotate(m_origin, m_angle);
|
||||
emit layout->PieceTransformationChanged(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPUndoPiecesRotate::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 VPUndoPiecesRotate *>(command);
|
||||
SCASSERT(moveCommand != nullptr)
|
||||
|
||||
if (not moveCommand->AllowMerge() || moveCommand->PieceIds() != PieceIds() || moveCommand->Origin() != m_origin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_angle += moveCommand->Angle();
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPUndoPiecesRotate::id() const -> int
|
||||
{
|
||||
return static_cast<int>(ML::UndoCommand::RotatePieces);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPUndoPiecesRotate::PieceIds() const -> QSet<QString>
|
||||
{
|
||||
QSet<QString> ids;
|
||||
for (const auto& piece : m_pieces)
|
||||
{
|
||||
VPPiecePtr p = piece.toStrongRef();
|
||||
if (not p.isNull())
|
||||
{
|
||||
ids.insert(p->GetUniqueID());
|
||||
}
|
||||
};
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPUndoPiecesRotate::Layout() const -> VPLayoutPtr
|
||||
{
|
||||
for (const auto& piece : m_pieces)
|
||||
{
|
||||
VPPiecePtr p = piece.toStrongRef();
|
||||
if (not p.isNull())
|
||||
{
|
||||
return p->Layout();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPUndoPiecesRotate::Sheet() const -> VPSheetPtr
|
||||
{
|
||||
for (const auto& piece : m_pieces)
|
||||
{
|
||||
VPPiecePtr p = piece.toStrongRef();
|
||||
if (not p.isNull())
|
||||
{
|
||||
return p->Sheet();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
142
src/app/puzzle/undocommands/vpundopiecerotate.h
Normal file
142
src/app/puzzle/undocommands/vpundopiecerotate.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpundopiecerotate.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 18 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 VPUNDOPIECEROTATE_H
|
||||
#define VPUNDOPIECEROTATE_H
|
||||
|
||||
#include "vpundocommand.h"
|
||||
|
||||
#include <QTransform>
|
||||
|
||||
#include "../layout/layoutdef.h"
|
||||
|
||||
class VPUndoPieceRotate : public VPUndoCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &origin, qreal angle, bool allowMerge,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
virtual ~VPUndoPieceRotate()=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 Piece() const -> VPPiecePtr;
|
||||
auto Origin() const -> QPointF;
|
||||
auto Angle() const -> qreal;
|
||||
auto AllowMerge() const -> bool;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPUndoPieceRotate)
|
||||
|
||||
VPPieceWeakPtr m_piece;
|
||||
QTransform m_oldTransform{};
|
||||
QPointF m_origin;
|
||||
qreal m_angle;
|
||||
bool m_allowMerge;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto VPUndoPieceRotate::Piece() const -> VPPiecePtr
|
||||
{
|
||||
return m_piece;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto VPUndoPieceRotate::Origin() const -> QPointF
|
||||
{
|
||||
return m_origin;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto VPUndoPieceRotate::Angle() const -> qreal
|
||||
{
|
||||
return m_angle;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto VPUndoPieceRotate::AllowMerge() const -> bool
|
||||
{
|
||||
return m_allowMerge;
|
||||
}
|
||||
|
||||
// Rotate pieces
|
||||
class VPUndoPiecesRotate : public VPUndoCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPUndoPiecesRotate(const QVector<VPPiecePtr> &pieces, const QPointF &origin, qreal angle, bool allowMerge,
|
||||
QUndoCommand *parent = nullptr);
|
||||
virtual ~VPUndoPiecesRotate()=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 PieceIds() const -> QSet<QString>;
|
||||
auto Origin() const -> QPointF;
|
||||
auto Angle() const -> qreal;
|
||||
auto AllowMerge() const -> bool;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPUndoPiecesRotate)
|
||||
|
||||
QVector<VPPieceWeakPtr> m_pieces{};
|
||||
QMap<QString, QTransform> m_oldTransforms{};
|
||||
QPointF m_origin;
|
||||
qreal m_angle;
|
||||
bool m_allowMerge;
|
||||
|
||||
auto Layout() const -> VPLayoutPtr;
|
||||
auto Sheet() const -> VPSheetPtr;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto VPUndoPiecesRotate::Origin() const -> QPointF
|
||||
{
|
||||
return m_origin;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto VPUndoPiecesRotate::Angle() const -> qreal
|
||||
{
|
||||
return m_angle;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto VPUndoPiecesRotate::AllowMerge() const -> bool
|
||||
{
|
||||
return m_allowMerge;
|
||||
}
|
||||
|
||||
#endif // VPUNDOPIECEROTATE_H
|
|
@ -179,7 +179,7 @@ auto StringToMarkerShape(const QString &string) -> PlaceLabelImg
|
|||
} // namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file) -> bool
|
||||
auto VPLayoutFileReader::ReadFile(const VPLayoutPtr &layout, QFile *file) -> bool
|
||||
{
|
||||
setDevice(file);
|
||||
|
||||
|
@ -199,7 +199,7 @@ auto VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file) -> bool
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadLayout(VPLayout *layout)
|
||||
void VPLayoutFileReader::ReadLayout(const VPLayoutPtr &layout)
|
||||
{
|
||||
AssertRootTag(ML::TagLayout);
|
||||
|
||||
|
@ -232,7 +232,7 @@ void VPLayoutFileReader::ReadLayout(VPLayout *layout)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadProperties(VPLayout *layout)
|
||||
void VPLayoutFileReader::ReadProperties(const VPLayoutPtr &layout)
|
||||
{
|
||||
AssertRootTag(ML::TagProperties);
|
||||
|
||||
|
@ -288,7 +288,7 @@ void VPLayoutFileReader::ReadProperties(VPLayout *layout)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadControl(VPLayout *layout)
|
||||
void VPLayoutFileReader::ReadControl(const VPLayoutPtr &layout)
|
||||
{
|
||||
AssertRootTag(ML::TagControl);
|
||||
|
||||
|
@ -304,7 +304,7 @@ void VPLayoutFileReader::ReadControl(VPLayout *layout)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadUnplacedPieces(VPLayout *layout)
|
||||
void VPLayoutFileReader::ReadUnplacedPieces(const VPLayoutPtr &layout)
|
||||
{
|
||||
AssertRootTag(ML::TagUnplacedPieces);
|
||||
|
||||
|
@ -312,7 +312,7 @@ void VPLayoutFileReader::ReadUnplacedPieces(VPLayout *layout)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadTiles(VPLayout *layout)
|
||||
void VPLayoutFileReader::ReadTiles(const VPLayoutPtr &layout)
|
||||
{
|
||||
AssertRootTag(ML::TagTiles);
|
||||
|
||||
|
@ -347,7 +347,7 @@ void VPLayoutFileReader::ReadTiles(VPLayout *layout)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadSheets(VPLayout *layout)
|
||||
void VPLayoutFileReader::ReadSheets(const VPLayoutPtr &layout)
|
||||
{
|
||||
AssertRootTag(ML::TagSheets);
|
||||
|
||||
|
@ -366,7 +366,7 @@ void VPLayoutFileReader::ReadSheets(VPLayout *layout)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadSheet(VPLayout *layout)
|
||||
void VPLayoutFileReader::ReadSheet(const VPLayoutPtr &layout)
|
||||
{
|
||||
AssertRootTag(ML::TagSheet);
|
||||
|
||||
|
@ -376,7 +376,7 @@ void VPLayoutFileReader::ReadSheet(VPLayout *layout)
|
|||
ML::TagPieces // 1
|
||||
};
|
||||
|
||||
QScopedPointer<VPSheet> sheet (new VPSheet(layout));
|
||||
VPSheetPtr sheet(new VPSheet(layout));
|
||||
|
||||
while (readNextStartElement())
|
||||
{
|
||||
|
@ -386,11 +386,7 @@ void VPLayoutFileReader::ReadSheet(VPLayout *layout)
|
|||
sheet->SetName(readElementText());
|
||||
break;
|
||||
case 1: // pieces
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
||||
ReadPieces(layout, sheet.get());
|
||||
#else
|
||||
ReadPieces(layout, sheet.data());
|
||||
#endif
|
||||
ReadPieces(layout, sheet);
|
||||
break;
|
||||
default:
|
||||
qCDebug(MLReader, "Ignoring tag %s", qUtf8Printable(name().toString()));
|
||||
|
@ -401,21 +397,21 @@ void VPLayoutFileReader::ReadSheet(VPLayout *layout)
|
|||
|
||||
readElementText();
|
||||
|
||||
layout->AddSheet(sheet.take());
|
||||
layout->AddSheet(sheet);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadPieces(VPLayout *layout, VPSheet *sheet)
|
||||
void VPLayoutFileReader::ReadPieces(const VPLayoutPtr &layout, const VPSheetPtr &sheet)
|
||||
{
|
||||
while (readNextStartElement())
|
||||
{
|
||||
if (name() == ML::TagPiece)
|
||||
{
|
||||
QScopedPointer<VPPiece>piece(new VPPiece());
|
||||
ReadPiece(piece.data());
|
||||
VPPiecePtr piece(new VPPiece());
|
||||
ReadPiece(piece);
|
||||
piece->SetSheet(sheet);
|
||||
layout->AddPiece(piece.take());
|
||||
VPLayout::AddPiece(layout, piece);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -426,7 +422,7 @@ void VPLayoutFileReader::ReadPieces(VPLayout *layout, VPSheet *sheet)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadPiece(VPPiece *piece)
|
||||
void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
|
||||
{
|
||||
AssertRootTag(ML::TagPiece);
|
||||
|
||||
|
@ -490,7 +486,7 @@ void VPLayoutFileReader::ReadPiece(VPPiece *piece)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadSeamAllowance(VPPiece *piece)
|
||||
void VPLayoutFileReader::ReadSeamAllowance(const VPPiecePtr &piece)
|
||||
{
|
||||
AssertRootTag(ML::TagSeamAllowance);
|
||||
|
||||
|
@ -512,7 +508,7 @@ void VPLayoutFileReader::ReadSeamAllowance(VPPiece *piece)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadGrainline(VPPiece *piece)
|
||||
void VPLayoutFileReader::ReadGrainline(const VPPiecePtr &piece)
|
||||
{
|
||||
AssertRootTag(ML::TagGrainline);
|
||||
|
||||
|
@ -533,7 +529,7 @@ void VPLayoutFileReader::ReadGrainline(VPPiece *piece)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadNotches(VPPiece *piece)
|
||||
void VPLayoutFileReader::ReadNotches(const VPPiecePtr &piece)
|
||||
{
|
||||
AssertRootTag(ML::TagNotches);
|
||||
|
||||
|
@ -576,7 +572,7 @@ auto VPLayoutFileReader::ReadNotch() -> VLayoutPassmark
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadInternalPaths(VPPiece *piece)
|
||||
void VPLayoutFileReader::ReadInternalPaths(const VPPiecePtr &piece)
|
||||
{
|
||||
AssertRootTag(ML::TagInternalPaths);
|
||||
|
||||
|
@ -615,7 +611,7 @@ auto VPLayoutFileReader::ReadInternalPath() -> VLayoutPiecePath
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadMarkers(VPPiece *piece)
|
||||
void VPLayoutFileReader::ReadMarkers(const VPPiecePtr &piece)
|
||||
{
|
||||
AssertRootTag(ML::TagMarkers);
|
||||
|
||||
|
@ -658,7 +654,7 @@ auto VPLayoutFileReader::ReadMarker() -> VLayoutPlaceLabel
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPLayoutFileReader::ReadLabels(VPPiece *piece)
|
||||
void VPLayoutFileReader::ReadLabels(const VPPiecePtr &piece)
|
||||
{
|
||||
AssertRootTag(ML::TagLabels);
|
||||
|
||||
|
|
|
@ -1630,6 +1630,12 @@ void VAbstractPiece::SetUUID(const QString &uuid)
|
|||
d->m_uuid = temp.isNull() ? QUuid::createUuid() : temp;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QString VAbstractPiece::GetUniqueID() const
|
||||
{
|
||||
return d->m_uuid.toString();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
qreal VSAPoint::GetSABefore(qreal width) const
|
||||
{
|
||||
|
|
|
@ -96,6 +96,12 @@ public:
|
|||
void SetUUID(const QUuid &uuid);
|
||||
void SetUUID(const QString &uuid);
|
||||
|
||||
/**
|
||||
* @brief GetUniqueID returns unique piece id. Combines UUID and gradation label.
|
||||
* @return unique piece id.
|
||||
*/
|
||||
QString GetUniqueID() const;
|
||||
|
||||
static QVector<QPointF> Equidistant(QVector<VSAPoint> points, qreal width, const QString &name);
|
||||
static qreal SumTrapezoids(const QVector<QPointF> &points);
|
||||
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
|
||||
|
|
Loading…
Reference in New Issue
Block a user