Piece rotation.
This commit is contained in:
parent
b366986f7a
commit
3fbe96c2a7
|
@ -33,7 +33,7 @@
|
|||
#include <QFontMetrics>
|
||||
|
||||
#include "../vmisc/backport/qoverload.h"
|
||||
#include "vpsheet.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QMenu>
|
|
@ -32,8 +32,8 @@
|
|||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QScrollArea>
|
||||
#include "vplayout.h"
|
||||
#include "vppiece.h"
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../layout/vppiece.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
|
@ -76,7 +76,7 @@
|
|||
<customwidget>
|
||||
<class>VPCarrouselPieceList</class>
|
||||
<extends>QListWidget</extends>
|
||||
<header>vpcarrouselpiecelist.h</header>
|
||||
<header>carousel/vpcarrouselpiecelist.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
|
@ -35,7 +35,8 @@
|
|||
#include "vpmimedatapiece.h"
|
||||
#include "vpcarrouselpiecelist.h"
|
||||
#include "vpcarrousel.h"
|
||||
#include "vpsheet.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
#include "../layout/vppiece.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
@ -64,7 +65,7 @@ auto VPCarrouselPiece::GetPiece() -> VPPiece *
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPCarrouselPiece::RefreshSelection()
|
||||
{
|
||||
setSelected(m_piece->GetIsSelected());
|
||||
setSelected(m_piece->IsSelected());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
|
@ -31,8 +31,7 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
#include "vppiece.h"
|
||||
|
||||
class VPPiece;
|
||||
|
||||
class VPCarrouselPiece : public QListWidgetItem
|
||||
{
|
|
@ -37,7 +37,7 @@
|
|||
#include "vpcarrouselpiece.h"
|
||||
#include "../vmisc/backport/qoverload.h"
|
||||
#include "vpmimedatapiece.h"
|
||||
#include "vpsheet.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
@ -72,8 +72,7 @@ void VPCarrouselPieceList::Refresh()
|
|||
{
|
||||
// update the label of the piece
|
||||
auto* carrouselpiece = new VPCarrouselPiece(piece, this);
|
||||
carrouselpiece->setSelected(piece->GetIsSelected());
|
||||
connect(piece, &VPPiece::SelectionChanged, this, &VPCarrouselPieceList::on_SelectionChangedExternal);
|
||||
carrouselpiece->setSelected(piece->IsSelected());
|
||||
}
|
||||
sortItems();
|
||||
}
|
||||
|
@ -146,7 +145,7 @@ void VPCarrouselPieceList::startDrag(Qt::DropActions supportedActions)
|
|||
if(drag->exec() == Qt::MoveAction)
|
||||
{
|
||||
m_carrousel->Refresh();
|
||||
piece->SetIsSelected(true);
|
||||
piece->SetSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,6 +31,8 @@
|
|||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "../layout/vppiece.h"
|
||||
|
||||
const QString VPMimeDataPiece::mineFormatPiecePtr = QStringLiteral("application/vnd.puzzle.piece.ptr");
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <QMimeData>
|
||||
|
||||
#include "vppiece.h"
|
||||
class VPPiece;
|
||||
|
||||
class VPMimeDataPiece : public QMimeData
|
||||
{
|
||||
|
@ -65,5 +65,4 @@ private:
|
|||
VPPiece *m_piece{nullptr};
|
||||
};
|
||||
|
||||
|
||||
#endif // VPMIMEDATAPIECE_H
|
|
@ -30,7 +30,6 @@
|
|||
#include "vppiece.h"
|
||||
#include "vpsheet.h"
|
||||
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(pLayout, "p.layout")
|
171
src/app/puzzle/layout/vppiece.cpp
Normal file
171
src/app/puzzle/layout/vppiece.cpp
Normal file
|
@ -0,0 +1,171 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vppiece.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 13 4, 2020
|
||||
**
|
||||
** @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) 2020 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 "vppiece.h"
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
#include "vpsheet.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QLoggingCategory>
|
||||
#include <QPainter>
|
||||
|
||||
Q_LOGGING_CATEGORY(pPiece, "p.piece")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPPiece::VPPiece(const VLayoutPiece &layoutPiece)
|
||||
: VLayoutPiece(layoutPiece)
|
||||
{
|
||||
ClearTransformations();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::ClearTransformations()
|
||||
{
|
||||
// Reset the piece position to the default state
|
||||
QTransform matrix;
|
||||
SetMatrix(matrix);
|
||||
// translate the piece so that the top left corner of the bouding rect of the piece is at the position
|
||||
// (0,0) in the sheet coordinate system
|
||||
const QPointF offset = MappedDetailBoundingRect().topLeft();
|
||||
matrix.translate(-offset.x() ,-offset.y());
|
||||
SetMatrix(matrix);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetPosition(QPointF point)
|
||||
{
|
||||
QTransform matrix = GetMatrix();
|
||||
const QPointF offset = MappedDetailBoundingRect().topLeft();
|
||||
matrix.translate(point.x() - offset.x(), point.y() - offset.y());
|
||||
SetMatrix(matrix);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::GetPosition() -> QPointF
|
||||
{
|
||||
QTransform matrix = GetMatrix();
|
||||
return QPointF(matrix.dx(), matrix.dy());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::RotateToGrainline()
|
||||
{
|
||||
if (not IsGrainlineEnabled() || m_sheet == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector<QPointF> grainlinePoints = GetMappedGrainline();
|
||||
if (grainlinePoints.count() < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QLineF grainline(grainlinePoints.first(), grainlinePoints.last());
|
||||
|
||||
QLineF canonical(grainlinePoints.first().x(), grainlinePoints.first().y(),
|
||||
grainlinePoints.first().x()+100, grainlinePoints.first().y());
|
||||
|
||||
GrainlineType grainlineType = m_sheet->GrainlineType();
|
||||
|
||||
auto DegreesAtFront = [grainline, canonical, grainlineType]()
|
||||
{
|
||||
QLineF atFront = canonical;
|
||||
if (grainlineType == GrainlineType::Vertical)
|
||||
{
|
||||
atFront.setAngle(90);
|
||||
}
|
||||
|
||||
return grainline.angleTo(atFront);
|
||||
};
|
||||
|
||||
auto DegreesAtRear = [grainline, canonical, grainlineType]()
|
||||
{
|
||||
QLineF atRear = canonical;
|
||||
atRear.setAngle(grainlineType == GrainlineType::Vertical ? 270 : 180);
|
||||
|
||||
return grainline.angleTo(atRear);
|
||||
};
|
||||
|
||||
GrainlineArrowDirection type = GrainlineArrowType();
|
||||
qreal degrees = 0;
|
||||
|
||||
if (type == GrainlineArrowDirection::atFront)
|
||||
{
|
||||
degrees = DegreesAtFront();
|
||||
}
|
||||
else if (type == GrainlineArrowDirection::atRear)
|
||||
{
|
||||
degrees = DegreesAtRear();
|
||||
}
|
||||
else
|
||||
{
|
||||
degrees = qMin(DegreesAtFront(), DegreesAtRear());
|
||||
}
|
||||
|
||||
Rotate(MappedDetailBoundingRect().center(), degrees);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetSelected(bool value)
|
||||
{
|
||||
m_isSelected = value;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::IsSelected() const -> bool
|
||||
{
|
||||
return m_isSelected;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::Sheet() const -> VPSheet *
|
||||
{
|
||||
return m_sheet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetSheet(VPSheet *newSheet)
|
||||
{
|
||||
m_sheet = newSheet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::Layout() const -> VPLayout *
|
||||
{
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetLayout(VPLayout *layout)
|
||||
{
|
||||
SCASSERT(layout != nullptr)
|
||||
m_layout = layout;
|
||||
}
|
96
src/app/puzzle/layout/vppiece.h
Normal file
96
src/app/puzzle/layout/vppiece.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vppiece.h
|
||||
** @author Ronan Le Tiec
|
||||
** @date 13 4, 2020
|
||||
**
|
||||
** @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) 2020 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 VPPIECE_H
|
||||
#define VPPIECE_H
|
||||
|
||||
#include <QUuid>
|
||||
#include <QVector>
|
||||
#include <QPoint>
|
||||
#include <QTransform>
|
||||
|
||||
#include "../vlayout/vlayoutpiece.h"
|
||||
|
||||
class VPLayout;
|
||||
class VPSheet;
|
||||
|
||||
class VPPiece : public VLayoutPiece
|
||||
{
|
||||
public:
|
||||
VPPiece() = default;
|
||||
explicit VPPiece(const VLayoutPiece &layoutPiece);
|
||||
|
||||
virtual ~VPPiece() = default;
|
||||
|
||||
void ClearTransformations();
|
||||
|
||||
/**
|
||||
* @brief SetPosition Sets the position of the piece, in relation to the origin of the scene
|
||||
* @param point the point where to set the piece
|
||||
*/
|
||||
void SetPosition(QPointF point);
|
||||
|
||||
/**
|
||||
* @brief GetPosition Returns the position of the piece
|
||||
* @return the position of the piece
|
||||
*/
|
||||
auto GetPosition() -> QPointF;
|
||||
|
||||
/**
|
||||
* @brief RotateToGrainline rotates the piece to follow the grainline
|
||||
*/
|
||||
void RotateToGrainline();
|
||||
|
||||
/**
|
||||
* @brief SetSelected Sets wether the piece is selected
|
||||
* @param value true if the piece is selected
|
||||
*/
|
||||
void SetSelected(bool value);
|
||||
|
||||
/**
|
||||
* @brief IsSelected Returns wether the piece is selected. It emit the signal SelectionChanged
|
||||
* @return true if the piece is selected
|
||||
*/
|
||||
auto IsSelected() const -> bool;
|
||||
|
||||
auto Sheet() const -> VPSheet *;
|
||||
void SetSheet(VPSheet *newSheet);
|
||||
|
||||
auto Layout() const -> VPLayout *;
|
||||
void SetLayout(VPLayout *layout);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPPiece)
|
||||
|
||||
VPLayout *m_layout{nullptr};
|
||||
|
||||
VPSheet *m_sheet{nullptr};
|
||||
|
||||
bool m_isSelected{false};
|
||||
};
|
||||
|
||||
#endif // VPPIECE_H
|
|
@ -85,3 +85,30 @@ void VPSheet::SetVisible(bool visible)
|
|||
{
|
||||
m_visible = visible;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPSheet::GrainlineType() const -> enum GrainlineType
|
||||
{
|
||||
if (m_layout != nullptr)
|
||||
{
|
||||
QSizeF size = m_layout->LayoutSettings().GetSheetSize();
|
||||
if (size.height() < size.width())
|
||||
{
|
||||
return GrainlineType::Horizontal;
|
||||
}
|
||||
}
|
||||
|
||||
return GrainlineType::Vertical;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPSheet::TransformationOrigin() const -> const VPTransformationOrigon &
|
||||
{
|
||||
return m_transformationOrigin;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPSheet::SetTransformationOrigin(const VPTransformationOrigon &newTransformationOrigin)
|
||||
{
|
||||
m_transformationOrigin = newTransformationOrigin;
|
||||
}
|
|
@ -40,6 +40,18 @@
|
|||
class VPLayout;
|
||||
class VPPiece;
|
||||
|
||||
enum class GrainlineType : qint8
|
||||
{
|
||||
Vertical,
|
||||
Horizontal
|
||||
};
|
||||
|
||||
struct VPTransformationOrigon
|
||||
{
|
||||
QPointF origin{};
|
||||
bool custom{false};
|
||||
};
|
||||
|
||||
class VPSheet : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -73,6 +85,11 @@ public:
|
|||
bool IsVisible() const;
|
||||
void SetVisible(bool visible);
|
||||
|
||||
auto GrainlineType() const -> GrainlineType;
|
||||
|
||||
auto TransformationOrigin() const -> const VPTransformationOrigon &;
|
||||
void SetTransformationOrigin(const VPTransformationOrigon &newTransformationOrigin);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPSheet)
|
||||
|
||||
|
@ -83,6 +100,8 @@ private:
|
|||
QUuid m_uuid{QUuid::createUuid()};
|
||||
|
||||
bool m_visible{true};
|
||||
|
||||
VPTransformationOrigon m_transformationOrigin{};
|
||||
};
|
||||
|
||||
#endif // VPSHEET_H
|
|
@ -8,23 +8,24 @@ SOURCES += \
|
|||
$$PWD/dialogs/vpdialogabout.cpp \
|
||||
$$PWD/main.cpp \
|
||||
$$PWD/vpapplication.cpp \
|
||||
$$PWD/vpcarrousel.cpp \
|
||||
$$PWD/vpcarrouselpiece.cpp \
|
||||
$$PWD/vpcarrouselpiecelist.cpp \
|
||||
$$PWD/carousel/vpcarrousel.cpp \
|
||||
$$PWD/carousel/vpcarrouselpiece.cpp \
|
||||
$$PWD/carousel/vpcarrouselpiecelist.cpp \
|
||||
$$PWD/vpcommandline.cpp \
|
||||
$$PWD/vpcommands.cpp \
|
||||
$$PWD/vpexporter.cpp \
|
||||
$$PWD/vpgraphicspiece.cpp \
|
||||
$$PWD/vpgraphicssheet.cpp \
|
||||
$$PWD/vpgraphicstilegrid.cpp \
|
||||
$$PWD/vplayout.cpp \
|
||||
$$PWD/vplayoutsettings.cpp \
|
||||
$$PWD/vpmaingraphicsview.cpp \
|
||||
$$PWD/scene/vpgraphicspiece.cpp \
|
||||
$$PWD/scene/vpgraphicspiececontrols.cpp \
|
||||
$$PWD/scene/vpgraphicssheet.cpp \
|
||||
$$PWD/scene/vpgraphicstilegrid.cpp \
|
||||
$$PWD/layout/vplayout.cpp \
|
||||
$$PWD/layout/vplayoutsettings.cpp \
|
||||
$$PWD/scene/vpmaingraphicsview.cpp \
|
||||
$$PWD/vpmainwindow.cpp \
|
||||
$$PWD/vpmimedatapiece.cpp \
|
||||
$$PWD/vppiece.cpp \
|
||||
$$PWD/carousel/vpmimedatapiece.cpp \
|
||||
$$PWD/layout/vppiece.cpp \
|
||||
$$PWD/vpsettings.cpp \
|
||||
$$PWD/vpsheet.cpp \
|
||||
$$PWD/layout/vpsheet.cpp \
|
||||
$$PWD/vptilefactory.cpp \
|
||||
$$PWD/xml/vplayoutfilereader.cpp \
|
||||
$$PWD/xml/vplayoutfilewriter.cpp \
|
||||
|
@ -37,25 +38,27 @@ HEADERS += \
|
|||
$$PWD/dialogs/configpages/puzzlepreferencespathpage.h \
|
||||
$$PWD/dialogs/dialogpuzzlepreferences.h \
|
||||
$$PWD/dialogs/vpdialogabout.h \
|
||||
$$PWD/scene/scenedef.h \
|
||||
$$PWD/stable.h \
|
||||
$$PWD/vpapplication.h \
|
||||
$$PWD/vpcarrousel.h \
|
||||
$$PWD/vpcarrouselpiece.h \
|
||||
$$PWD/vpcarrouselpiecelist.h \
|
||||
$$PWD/carousel/vpcarrousel.h \
|
||||
$$PWD/carousel/vpcarrouselpiece.h \
|
||||
$$PWD/carousel/vpcarrouselpiecelist.h \
|
||||
$$PWD/vpcommandline.h \
|
||||
$$PWD/vpcommands.h \
|
||||
$$PWD/vpexporter.h \
|
||||
$$PWD/vpgraphicspiece.h \
|
||||
$$PWD/vpgraphicssheet.h \
|
||||
$$PWD/vpgraphicstilegrid.h \
|
||||
$$PWD/vplayout.h \
|
||||
$$PWD/vplayoutsettings.h \
|
||||
$$PWD/vpmaingraphicsview.h \
|
||||
$$PWD/scene/vpgraphicspiece.h \
|
||||
$$PWD/scene/vpgraphicspiececontrols.h \
|
||||
$$PWD/scene/vpgraphicssheet.h \
|
||||
$$PWD/scene/vpgraphicstilegrid.h \
|
||||
$$PWD/layout/vplayout.h \
|
||||
$$PWD/layout/vplayoutsettings.h \
|
||||
$$PWD/scene/vpmaingraphicsview.h \
|
||||
$$PWD/vpmainwindow.h \
|
||||
$$PWD/vpmimedatapiece.h \
|
||||
$$PWD/vppiece.h \
|
||||
$$PWD/carousel/vpmimedatapiece.h \
|
||||
$$PWD/layout/vppiece.h \
|
||||
$$PWD/vpsettings.h \
|
||||
$$PWD/vpsheet.h \
|
||||
$$PWD/layout/vpsheet.h \
|
||||
$$PWD/vptilefactory.h \
|
||||
$$PWD/xml/vplayoutfilereader.h \
|
||||
$$PWD/xml/vplayoutfilewriter.h \
|
||||
|
@ -66,5 +69,5 @@ FORMS += \
|
|||
$$PWD/dialogs/configpages/puzzlepreferencespathpage.ui \
|
||||
$$PWD/dialogs/dialogpuzzlepreferences.ui \
|
||||
$$PWD/dialogs/vpdialogabout.ui \
|
||||
$$PWD/vpcarrousel.ui \
|
||||
$$PWD/carousel/vpcarrousel.ui \
|
||||
$$PWD/vpmainwindow.ui
|
||||
|
|
38
src/app/puzzle/scene/scenedef.h
Normal file
38
src/app/puzzle/scene/scenedef.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file scenedef.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 7 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 SCENEDEF_H
|
||||
#define SCENEDEF_H
|
||||
|
||||
enum class PGraphicsItem : int
|
||||
{
|
||||
Piece = 1,
|
||||
Handles = 2,
|
||||
TransformationOrigin = 3
|
||||
};
|
||||
|
||||
#endif // SCENEDEF_H
|
|
@ -39,9 +39,9 @@
|
|||
#include <QGraphicsScene>
|
||||
#include <QApplication>
|
||||
|
||||
#include "vppiece.h"
|
||||
#include "vplayout.h"
|
||||
#include "vpsheet.h"
|
||||
#include "../layout/vppiece.h"
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
|
||||
#include "vlayoutpiecepath.h"
|
||||
#include "vplacelabelitem.h"
|
||||
|
@ -49,6 +49,11 @@
|
|||
#include <QLoggingCategory>
|
||||
Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece")
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr qreal penWidth = 1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) :
|
||||
QGraphicsObject(parent),
|
||||
|
@ -57,94 +62,12 @@ VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) :
|
|||
QPixmap cursor_pixmap = QIcon("://puzzleicon/svg/cursor_rotate.svg").pixmap(QSize(32,32));
|
||||
m_rotateCursor= QCursor(cursor_pixmap, 16, 16);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::Init()
|
||||
{
|
||||
// set some infos
|
||||
setFlags(ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges);
|
||||
setFlags(ItemIsSelectable | ItemSendsGeometryChanges);
|
||||
setAcceptHoverEvents(true);
|
||||
setCursor(QCursor(Qt::OpenHandCursor));
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
|
||||
// initialises the seam line
|
||||
QVector<QPointF> seamLinePoints = m_piece->GetMappedContourPoints();
|
||||
if(!seamLinePoints.isEmpty())
|
||||
{
|
||||
m_seamLine.moveTo(seamLinePoints.first());
|
||||
for (int i = 1; i < seamLinePoints.size(); i++)
|
||||
{
|
||||
m_seamLine.lineTo(seamLinePoints.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
// initiliases the cutting line
|
||||
QVector<QPointF> cuttingLinepoints = m_piece->GetMappedSeamAllowancePoints();
|
||||
if(!cuttingLinepoints.isEmpty())
|
||||
{
|
||||
m_cuttingLine.moveTo(cuttingLinepoints.first());
|
||||
for (int i = 1; i < cuttingLinepoints.size(); i++)
|
||||
{
|
||||
m_cuttingLine.lineTo(cuttingLinepoints.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
// initialises the grainline
|
||||
if(m_piece->IsGrainlineEnabled())
|
||||
{
|
||||
QVector<QPointF> grainLinepoints = m_piece->GetMappedGrainline();
|
||||
if(!grainLinepoints.isEmpty())
|
||||
{
|
||||
m_grainline.moveTo(grainLinepoints.first());
|
||||
for (int i = 1; i < grainLinepoints.size(); i++)
|
||||
{
|
||||
m_grainline.lineTo(grainLinepoints.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialises the internal paths
|
||||
QVector<VLayoutPiecePath> internalPaths = m_piece->GetInternalPaths();
|
||||
for (const auto& piecePath : internalPaths)
|
||||
{
|
||||
QPainterPath path = m_piece->GetMatrix().map(piecePath.GetPainterPath());
|
||||
m_internalPaths.append(path);
|
||||
m_internalPathsPenStyle.append(piecePath.PenStyle());
|
||||
}
|
||||
|
||||
// initialises the passmarks
|
||||
QVector<VLayoutPassmark> passmarks = m_piece->GetMappedPassmarks();
|
||||
for(auto &passmark : passmarks)
|
||||
{
|
||||
for (auto &line : passmark.lines)
|
||||
{
|
||||
m_passmarks.moveTo(line.p1());
|
||||
m_passmarks.lineTo(line.p2());
|
||||
}
|
||||
}
|
||||
|
||||
// initialises the place labels (buttons etc)
|
||||
QVector<VLayoutPlaceLabel> placeLabels = m_piece->GetPlaceLabels();
|
||||
for(auto &placeLabel : placeLabels)
|
||||
{
|
||||
QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape);
|
||||
m_placeLabels.append(path);
|
||||
}
|
||||
|
||||
// TODO : initialises the text labels
|
||||
|
||||
|
||||
// Init position
|
||||
on_PiecePositionChanged();
|
||||
on_PieceRotationChanged();
|
||||
on_PieceSelectionChanged();
|
||||
|
||||
// Initialises the connectors
|
||||
connect(m_piece, &VPPiece::SelectionChanged, this, &VPGraphicsPiece::on_PieceSelectionChanged);
|
||||
connect(m_piece, &VPPiece::PositionChanged, this, &VPGraphicsPiece::on_PiecePositionChanged);
|
||||
connect(m_piece, &VPPiece::RotationChanged, this, &VPGraphicsPiece::on_PieceRotationChanged);
|
||||
connect(m_piece, &VPPiece::PropertiesChanged, this, &VPGraphicsPiece::on_PiecePropertiesChanged);
|
||||
PaintPiece();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -153,15 +76,23 @@ auto VPGraphicsPiece::GetPiece() -> VPPiece*
|
|||
return m_piece;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::TranslatePiece(const QPointF &p)
|
||||
{
|
||||
m_piece->Translate(p);
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPiece::boundingRect() const -> QRectF
|
||||
{
|
||||
constexpr qreal halfPenWidth = penWidth/2.;
|
||||
if(!m_cuttingLine.isEmpty())
|
||||
{
|
||||
return m_cuttingLine.boundingRect();
|
||||
return m_cuttingLine.boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
||||
}
|
||||
|
||||
return m_seamLine.boundingRect();
|
||||
return m_seamLine.boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -181,170 +112,41 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
|
|||
Q_UNUSED(widget);
|
||||
Q_UNUSED(option);
|
||||
|
||||
QPen pen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
QBrush noBrush(Qt::NoBrush);
|
||||
QBrush selectionBrush(QColor(255,160,160,60));
|
||||
QBrush blackBrush(Qt::black);
|
||||
|
||||
QPen pen(Qt::black, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
painter->setPen(pen);
|
||||
|
||||
// selection
|
||||
if(isSelected())
|
||||
{
|
||||
painter->setBrush(selectionBrush);
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setBrush(noBrush);
|
||||
}
|
||||
|
||||
// paint the cutting line
|
||||
if(!m_cuttingLine.isEmpty())
|
||||
{
|
||||
painter->drawPath(m_cuttingLine);
|
||||
painter->setBrush(noBrush);
|
||||
}
|
||||
|
||||
// paint the seam line
|
||||
if(!m_seamLine.isEmpty() && m_piece->GetShowSeamLine())
|
||||
{
|
||||
painter->drawPath(m_seamLine);
|
||||
}
|
||||
|
||||
painter->setBrush(noBrush);
|
||||
|
||||
// paint the grainline
|
||||
if(!m_grainline.isEmpty())
|
||||
{
|
||||
// here to fill the grainlines arrow. Not wanted for mvp
|
||||
// later maybe if it's configurable
|
||||
// painter->setBrush(blackBrush);
|
||||
|
||||
painter->drawPath(m_grainline);
|
||||
}
|
||||
|
||||
// paint the internal paths
|
||||
painter->setBrush(noBrush);
|
||||
if(!m_internalPaths.isEmpty())
|
||||
{
|
||||
Qt::PenStyle penStyleTmp = pen.style();
|
||||
|
||||
for (int i = 0; i < m_internalPaths.size(); i++)
|
||||
{
|
||||
painter->setPen(m_internalPathsPenStyle.at(i));
|
||||
painter->drawPath(m_internalPaths.at(i));
|
||||
}
|
||||
painter->setPen(penStyleTmp);
|
||||
}
|
||||
|
||||
// paint the passmarks
|
||||
if(!m_passmarks.isEmpty())
|
||||
{
|
||||
painter->drawPath(m_passmarks);
|
||||
}
|
||||
|
||||
// paint the place labels (buttons etc)
|
||||
if(!m_placeLabels.isEmpty())
|
||||
{
|
||||
for(auto &placeLabel : m_placeLabels)
|
||||
{
|
||||
painter->drawPath(placeLabel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO Detail & Piece Label
|
||||
|
||||
// QPointF position = m_piece->GetPatternTextPosition();
|
||||
// QStringList texts = m_piece->GetPatternText();
|
||||
|
||||
// painter->drawText();
|
||||
|
||||
|
||||
|
||||
// when using m_piece->GetItem(), the results were quite bad
|
||||
|
||||
PaintPiece(painter);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
bool selectionState = isSelected();
|
||||
//perform the default behaviour
|
||||
QGraphicsObject::mousePressEvent(event);
|
||||
|
||||
// change the cursor when clicking the left button
|
||||
if((event->button() == Qt::LeftButton))
|
||||
{
|
||||
if((event->modifiers() & Qt::AltModifier) != 0U)
|
||||
{
|
||||
setCursor(m_rotateCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
}
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
|
||||
// change the selected state when clicking left button
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setSelected(true);
|
||||
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
setSelected(!selectionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
if((event->button() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier))
|
||||
{
|
||||
m_rotationStartPoint = event->scenePos();
|
||||
m_moveStartPoint = event->pos();
|
||||
emit HideTransformationHandles(true);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
|
||||
void VPGraphicsPiece::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if((event->buttons() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier))
|
||||
{
|
||||
//FIXME: it flickers between the arrow cursor and the rotate cursor
|
||||
setCursor(m_rotateCursor);
|
||||
QGraphicsObject::mouseMoveEvent(event);
|
||||
|
||||
QPointF rotationNewPoint = event->scenePos();
|
||||
QPointF rotationCenter = sceneBoundingRect().center();
|
||||
GroupMove(event->pos());
|
||||
|
||||
// get the angle from the center to the initial click point
|
||||
qreal init_x = m_rotationStartPoint.x() - rotationCenter.x();
|
||||
qreal init_y = m_rotationStartPoint.y() - rotationCenter.y();
|
||||
qreal initial_angle = qAtan2(init_y, init_x);
|
||||
|
||||
qreal x = rotationNewPoint.x() - rotationCenter.x();
|
||||
qreal y = rotationNewPoint.y() - rotationCenter.y();
|
||||
qreal mv_angle = qAtan2(y,x);
|
||||
|
||||
qreal angle = (initial_angle-mv_angle)*180/M_PI;
|
||||
|
||||
setTransformOriginPoint(boundingRect().center());
|
||||
setRotation(-(angle+m_piece->GetRotation()));
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
QGraphicsItem::mouseMoveEvent(event);
|
||||
}
|
||||
m_moveStartPoint = event->pos();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
bool selectionState = isSelected();
|
||||
|
||||
//perform the default behaviour
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
|
||||
|
@ -352,32 +154,8 @@ void VPGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
|
||||
setSelected(selectionState);
|
||||
|
||||
if(m_piece->GetPosition() != pos())
|
||||
{
|
||||
m_piece->SetPosition(pos());
|
||||
}
|
||||
}
|
||||
|
||||
if((event->button() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier))
|
||||
{
|
||||
m_piece->SetRotation(-rotation());
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
if(event->modifiers() & Qt::AltModifier)
|
||||
{
|
||||
//FIXME: it flickers between the arrow cursor and the rotate cursor
|
||||
setCursor(m_rotateCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
GroupMove(event->pos());
|
||||
emit HideTransformationHandles(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,30 +199,166 @@ void VPGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::on_PieceSelectionChanged()
|
||||
void VPGraphicsPiece::PaintPiece(QPainter *painter)
|
||||
{
|
||||
setSelected(m_piece->GetIsSelected());
|
||||
}
|
||||
QBrush noBrush(Qt::NoBrush);
|
||||
QBrush selectionBrush(QColor(255,160,160,60));
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::on_PiecePositionChanged()
|
||||
{
|
||||
setPos(m_piece->GetPosition());
|
||||
}
|
||||
QRectF rect = m_piece->MappedDetailBoundingRect();
|
||||
QPointF p = rect.topLeft();
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::on_PieceRotationChanged()
|
||||
{
|
||||
setTransformOriginPoint(boundingRect().center());
|
||||
setRotation(-m_piece->GetRotation());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::on_PiecePropertiesChanged()
|
||||
{
|
||||
if(scene() != nullptr)
|
||||
// initialises the seam line
|
||||
QVector<QPointF> seamLinePoints = m_piece->GetMappedContourPoints();
|
||||
if(!seamLinePoints.isEmpty())
|
||||
{
|
||||
scene()->update();
|
||||
m_seamLine = QPainterPath();
|
||||
m_seamLine.moveTo(seamLinePoints.first());
|
||||
for (int i = 1; i < seamLinePoints.size(); i++)
|
||||
{
|
||||
m_seamLine.lineTo(seamLinePoints.at(i));
|
||||
}
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(isSelected() ? selectionBrush : noBrush);
|
||||
painter->drawPath(m_seamLine);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
// initiliases the cutting line
|
||||
QVector<QPointF> cuttingLinepoints = m_piece->GetMappedSeamAllowancePoints();
|
||||
if(!cuttingLinepoints.isEmpty())
|
||||
{
|
||||
m_cuttingLine = QPainterPath();
|
||||
m_cuttingLine.moveTo(cuttingLinepoints.first());
|
||||
for (int i = 1; i < cuttingLinepoints.size(); i++)
|
||||
{
|
||||
m_cuttingLine.lineTo(cuttingLinepoints.at(i));
|
||||
}
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(isSelected() ? selectionBrush : noBrush);
|
||||
painter->drawPath(m_cuttingLine);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
// initialises the grainline
|
||||
if(m_piece->IsGrainlineEnabled())
|
||||
{
|
||||
QVector<QPointF> grainLinepoints = m_piece->GetMappedGrainline();
|
||||
if(!grainLinepoints.isEmpty())
|
||||
{
|
||||
QPainterPath grainline;
|
||||
grainline.moveTo(grainLinepoints.first());
|
||||
for (int i = 1; i < grainLinepoints.size(); i++)
|
||||
{
|
||||
grainline.lineTo(grainLinepoints.at(i));
|
||||
}
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
// here to fill the grainlines arrow. Not wanted for mvp
|
||||
// later maybe if it's configurable
|
||||
// painter->setBrush(blackBrush);
|
||||
|
||||
painter->setBrush(noBrush);
|
||||
painter->drawPath(grainline);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialises the internal paths
|
||||
QVector<VLayoutPiecePath> internalPaths = m_piece->GetInternalPaths();
|
||||
for (const auto& piecePath : internalPaths)
|
||||
{
|
||||
QPainterPath path = m_piece->GetMatrix().map(piecePath.GetPainterPath());
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen(piecePath.PenStyle());
|
||||
painter->drawPath(path);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
// initialises the passmarks
|
||||
QVector<VLayoutPassmark> passmarks = m_piece->GetMappedPassmarks();
|
||||
for(auto &passmark : passmarks)
|
||||
{
|
||||
QPainterPath passmarkPath;
|
||||
for (auto &line : passmark.lines)
|
||||
{
|
||||
passmarkPath.moveTo(line.p1());
|
||||
passmarkPath.lineTo(line.p2());
|
||||
}
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(noBrush);
|
||||
painter->drawPath(passmarkPath);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
// initialises the place labels (buttons etc)
|
||||
QVector<VLayoutPlaceLabel> placeLabels = m_piece->GetPlaceLabels();
|
||||
for(auto &placeLabel : placeLabels)
|
||||
{
|
||||
QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape);
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(noBrush);
|
||||
painter->drawPath(path);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : initialises the text labels
|
||||
|
||||
// QPointF position = m_piece->GetPatternTextPosition();
|
||||
// QStringList texts = m_piece->GetPatternText();
|
||||
|
||||
// painter->drawText();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::GroupMove(const QPointF &pos)
|
||||
{
|
||||
if (scene() != nullptr)
|
||||
{
|
||||
QList<QGraphicsItem *> list = scene()->selectedItems();
|
||||
for (auto *item : list)
|
||||
{
|
||||
if (item->type() == UserType + static_cast<int>(PGraphicsItem::Piece))
|
||||
{
|
||||
auto *pieceItem = dynamic_cast<VPGraphicsPiece*>(item);
|
||||
pieceItem->TranslatePiece(pos-m_moveStartPoint);
|
||||
}
|
||||
}
|
||||
emit PiecePositionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPiece::on_Rotate(const QPointF ¢er, qreal angle)
|
||||
{
|
||||
if (isSelected())
|
||||
{
|
||||
prepareGeometryChange();
|
||||
m_piece->Rotate(center, angle);
|
||||
PaintPiece(); // Update shapes
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,21 +367,10 @@ auto VPGraphicsPiece::itemChange(GraphicsItemChange change, const QVariant &valu
|
|||
{
|
||||
if (scene() != nullptr)
|
||||
{
|
||||
|
||||
// we do this in the mouseRelease button to avoid updated this property all the time.
|
||||
// if(change == ItemPositionHasChanged)
|
||||
// {
|
||||
// blockSignals(true);
|
||||
// m_piece->SetPosition(pos());
|
||||
// blockSignals(false);
|
||||
// }
|
||||
|
||||
if(change == ItemSelectedHasChanged)
|
||||
{
|
||||
if(m_piece->GetIsSelected() != isSelected())
|
||||
{
|
||||
m_piece->SetIsSelected(isSelected());
|
||||
}
|
||||
emit PieceSelectionChanged();
|
||||
m_piece->SetSelected(value.toBool());
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,8 @@
|
|||
#include <QGraphicsItem>
|
||||
#include <QCursor>
|
||||
|
||||
#include "scenedef.h"
|
||||
|
||||
class VPPiece;
|
||||
|
||||
class VPGraphicsPiece : public QGraphicsObject
|
||||
|
@ -41,37 +43,24 @@ public:
|
|||
explicit VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent = nullptr);
|
||||
~VPGraphicsPiece() = default;
|
||||
|
||||
void Init();
|
||||
|
||||
/**
|
||||
* @brief GetPiece Returns the piece that corresponds to the graphics piece
|
||||
* @return the piece
|
||||
*/
|
||||
auto GetPiece() -> VPPiece*;
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + 1};
|
||||
void TranslatePiece(const QPointF &p);
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::Piece)};
|
||||
|
||||
signals:
|
||||
void PieceSelectionChanged();
|
||||
void HideTransformationHandles(bool hide);
|
||||
void PiecePositionChanged();
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief on_PieceSelectionChanged Slot called when the piece selection was changed
|
||||
*/
|
||||
void on_PieceSelectionChanged();
|
||||
|
||||
/**
|
||||
* @brief on_PiecePositionChanged Slot called when the piece position was changed
|
||||
*/
|
||||
void on_PiecePositionChanged();
|
||||
|
||||
/**
|
||||
* @brief on_PieceRotationChanged Slot called when the piece rotation was changed
|
||||
*/
|
||||
void on_PieceRotationChanged();
|
||||
|
||||
/**
|
||||
* @brief on_PiecePropertiesChanged Slot called when the showSeamline / mirrored was changed
|
||||
*/
|
||||
void on_PiecePropertiesChanged();
|
||||
void on_Rotate(const QPointF ¢er, qreal angle);
|
||||
|
||||
protected:
|
||||
auto boundingRect() const -> QRectF override;
|
||||
|
@ -79,11 +68,9 @@ protected:
|
|||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
|
||||
auto itemChange(GraphicsItemChange change, const QVariant &value) -> QVariant override;
|
||||
|
||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||
|
@ -94,17 +81,15 @@ private:
|
|||
|
||||
QPainterPath m_cuttingLine{};
|
||||
QPainterPath m_seamLine{};
|
||||
QPainterPath m_grainline{};
|
||||
QPainterPath m_passmarks{};
|
||||
|
||||
QVector<QPainterPath> m_internalPaths{};
|
||||
QVector<Qt::PenStyle> m_internalPathsPenStyle{};
|
||||
|
||||
QVector<QPainterPath> m_placeLabels{};
|
||||
|
||||
QPointF m_moveStartPoint{};
|
||||
QPointF m_rotationStartPoint{};
|
||||
|
||||
QCursor m_rotateCursor{};
|
||||
|
||||
void PaintPiece(QPainter *painter=nullptr);
|
||||
|
||||
void GroupMove(const QPointF &pos);
|
||||
};
|
||||
|
||||
#endif // VPGRAPHICSPIECE_H
|
736
src/app/puzzle/scene/vpgraphicspiececontrols.cpp
Normal file
736
src/app/puzzle/scene/vpgraphicspiececontrols.cpp
Normal file
|
@ -0,0 +1,736 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpgraphicspiececontrols.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 2 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 "vpgraphicspiececontrols.h"
|
||||
|
||||
#include <QCursor>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "../vmisc/compatibility.h"
|
||||
#include "../vwidgets/global.h"
|
||||
#include "../layout/vplayout.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const qreal arcStartAngle = 105;
|
||||
const qreal arcAngle = 25;
|
||||
const qreal arcRadius = 15;
|
||||
|
||||
const qreal arrowTail = 2;
|
||||
const qreal arrowSide = 2;
|
||||
const qreal arrowLength = 4;
|
||||
const qreal arrow1Angle = 13;
|
||||
const qreal arrow2Angle = 38;
|
||||
|
||||
constexpr qreal penWidth = 2;
|
||||
|
||||
const qreal centerRadius1 = 5;
|
||||
const qreal centerRadius2 = 10;
|
||||
|
||||
const QColor defaultColor = Qt::black;
|
||||
const QColor hoverColor = Qt::green;
|
||||
|
||||
enum class HandleCorner : int
|
||||
{
|
||||
Invalid = 0,
|
||||
TopLeft = 1,
|
||||
TopRight = 2,
|
||||
BottomRight = 3,
|
||||
BottomLeft = 4
|
||||
};
|
||||
|
||||
auto TransformationOrigin(VPLayout *layout, const QRectF &boundingRect) -> QPointF
|
||||
{
|
||||
SCASSERT(layout != nullptr)
|
||||
VPSheet *sheet = layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
return origin.origin;
|
||||
}
|
||||
|
||||
return boundingRect.center();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsTransformationOrigin::VPGraphicsTransformationOrigin(VPLayout *layout, QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent),
|
||||
m_layout(layout),
|
||||
m_color(defaultColor)
|
||||
{
|
||||
SCASSERT(m_layout != nullptr)
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
setZValue(1);
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::SetTransformationOrigin()
|
||||
{
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::on_HideHandles(bool hide)
|
||||
{
|
||||
m_originVisible = not hide;
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::on_ShowOrigin(bool show)
|
||||
{
|
||||
setVisible(show);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsTransformationOrigin::boundingRect() const
|
||||
{
|
||||
constexpr qreal halfPenWidth = penWidth/2.;
|
||||
return Center2().boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsTransformationOrigin::shape() const
|
||||
{
|
||||
return Center2();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(option);
|
||||
|
||||
const qreal scale = SceneScale(scene());
|
||||
|
||||
QPen pen(m_color, penWidth/scale, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
|
||||
painter->setPen(pen);
|
||||
|
||||
if (m_originVisible)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(QBrush(m_color));
|
||||
painter->drawPath(Center1());
|
||||
painter->restore();
|
||||
|
||||
painter->save();
|
||||
painter->setBrush(QBrush());
|
||||
painter->drawPath(Center2());
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
// change the cursor when clicking the left button
|
||||
if((event->button() == Qt::LeftButton))
|
||||
{
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
//perform the default behaviour
|
||||
QGraphicsObject::mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
origin.origin = event->scenePos();
|
||||
origin.custom = true;
|
||||
sheet->SetTransformationOrigin(origin);
|
||||
}
|
||||
prepareGeometryChange();
|
||||
|
||||
QGraphicsObject::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
//perform the default behaviour
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
|
||||
// change the cursor when clicking left button
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
m_color = hoverColor;
|
||||
QGraphicsObject::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsTransformationOrigin::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
m_color = defaultColor;
|
||||
QGraphicsObject::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsTransformationOrigin::RotationCenter(QPainter *painter) const -> QPainterPath
|
||||
{
|
||||
QPainterPath path;
|
||||
|
||||
const qreal scale = SceneScale(scene());
|
||||
qreal radius = centerRadius1/scale;
|
||||
QPointF transformationOrigin = TransformationOrigin(m_layout, QRectF());
|
||||
QRectF rect(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
|
||||
|
||||
QPainterPath center1;
|
||||
center1.addEllipse(rect);
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(QBrush(m_color));
|
||||
painter->drawPath(Center1());
|
||||
painter->restore();
|
||||
}
|
||||
path.addPath(center1);
|
||||
|
||||
radius = centerRadius2/scale;
|
||||
rect = QRectF(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
|
||||
|
||||
QPainterPath center2;
|
||||
center2.addEllipse(rect);
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(QBrush());
|
||||
painter->drawPath(Center2());
|
||||
painter->restore();
|
||||
}
|
||||
path.addPath(center2);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsTransformationOrigin::Center1() const
|
||||
{
|
||||
const qreal scale = SceneScale(scene());
|
||||
qreal radius = centerRadius1/scale;
|
||||
QPointF transformationOrigin = TransformationOrigin(m_layout, QRectF());
|
||||
QRectF rect(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
|
||||
|
||||
QPainterPath center1;
|
||||
center1.addEllipse(rect);
|
||||
|
||||
return center1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsTransformationOrigin::Center2() const
|
||||
{
|
||||
const qreal scale = SceneScale(scene());
|
||||
qreal radius = centerRadius2/scale;
|
||||
QPointF transformationOrigin = TransformationOrigin(m_layout, QRectF());
|
||||
QRectF rect = QRectF(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
|
||||
|
||||
QPainterPath center2;
|
||||
center2.addEllipse(rect);
|
||||
|
||||
return center2;
|
||||
}
|
||||
|
||||
// VPGraphicsPieceControls
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsPieceControls::VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent),
|
||||
m_layout(layout)
|
||||
{
|
||||
SCASSERT(m_layout != nullptr)
|
||||
QPixmap cursor_pixmap = QIcon("://puzzleicon/svg/cursor_rotate.svg").pixmap(QSize(32,32));
|
||||
setCursor(QCursor(cursor_pixmap, 16, 16));
|
||||
setZValue(1);
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::on_UpdateControls()
|
||||
{
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
setVisible(not m_pieceRect.isNull());
|
||||
|
||||
if (not m_pieceRect.isNull())
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
if (not origin.custom)
|
||||
{
|
||||
origin.origin = m_pieceRect.center();
|
||||
sheet->SetTransformationOrigin(origin);
|
||||
emit TransformationOriginChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit ShowOrigin(not m_pieceRect.isNull());
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::on_HideHandles(bool hide)
|
||||
{
|
||||
m_controlsVisible = not hide;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::boundingRect() const -> QRectF
|
||||
{
|
||||
constexpr qreal halfPenWidth = penWidth/2.;
|
||||
return Handles().boundingRect().adjusted(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::shape() const -> QPainterPath
|
||||
{
|
||||
return Handles();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(option);
|
||||
|
||||
const qreal scale = SceneScale(scene());
|
||||
|
||||
QPen pen(defaultColor, penWidth/scale, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
|
||||
painter->setPen(pen);
|
||||
|
||||
if (m_controlsVisible)
|
||||
{
|
||||
TopLeftControl(painter);
|
||||
TopRightControl(painter);
|
||||
BottomLeftControl(painter);
|
||||
BottomRightControl(painter);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_rotationStartPoint = event->scenePos();
|
||||
m_controlsVisible = false;
|
||||
m_handleCorner = HandleCorner(event->scenePos());
|
||||
prepareGeometryChange();
|
||||
}
|
||||
else
|
||||
{
|
||||
QGraphicsObject::mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if((event->modifiers() & Qt::ShiftModifier) != 0U
|
||||
&& static_cast<enum HandleCorner>(m_handleCorner) != HandleCorner::Invalid)
|
||||
{
|
||||
if (not m_originSaved)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
m_savedOrigin = sheet->TransformationOrigin();
|
||||
m_originSaved = true;
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
|
||||
VPTransformationOrigon origin;
|
||||
origin.custom = true;
|
||||
|
||||
if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::TopLeft)
|
||||
{
|
||||
origin.origin = m_pieceRect.topLeft();
|
||||
}
|
||||
else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::TopRight)
|
||||
{
|
||||
origin.origin = m_pieceRect.topRight();
|
||||
}
|
||||
else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::BottomRight)
|
||||
{
|
||||
origin.origin = m_pieceRect.bottomRight();
|
||||
}
|
||||
else if (static_cast<enum HandleCorner>(m_handleCorner) == HandleCorner::BottomLeft)
|
||||
{
|
||||
origin.origin = m_pieceRect.bottomLeft();
|
||||
}
|
||||
|
||||
sheet->SetTransformationOrigin(origin);
|
||||
emit TransformationOriginChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_originSaved)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
if (not m_savedOrigin.custom)
|
||||
{
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
m_savedOrigin.origin = m_pieceRect.center();
|
||||
}
|
||||
sheet->SetTransformationOrigin(m_savedOrigin);
|
||||
emit TransformationOriginChanged();
|
||||
}
|
||||
m_originSaved = false;
|
||||
}
|
||||
}
|
||||
|
||||
QPointF rotationNewPoint = event->scenePos();
|
||||
|
||||
// get the angle from the center to the initial click point
|
||||
QPointF rotationOrigin = TransformationOrigin(m_layout, m_pieceRect);
|
||||
QLineF initPosition(rotationOrigin, m_rotationStartPoint);
|
||||
QLineF initRotationPosition(rotationOrigin, rotationNewPoint);
|
||||
|
||||
qreal angle = initPosition.angleTo(initRotationPosition);
|
||||
|
||||
if (not qFuzzyIsNull(angle))
|
||||
{
|
||||
emit Rotate(rotationOrigin, angle);
|
||||
}
|
||||
|
||||
if (m_originSaved && m_savedOrigin.custom)
|
||||
{
|
||||
QLineF line(rotationOrigin, m_savedOrigin.origin);
|
||||
line.setAngle(line.angle()+angle);
|
||||
m_savedOrigin.origin = line.p2();
|
||||
}
|
||||
|
||||
m_rotationStartPoint = rotationNewPoint;
|
||||
QGraphicsObject::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_controlsVisible = true;
|
||||
|
||||
if (m_originSaved)
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
if (not m_savedOrigin.custom)
|
||||
{
|
||||
m_pieceRect = PiecesBoundingRect();
|
||||
m_savedOrigin.origin = m_pieceRect.center();
|
||||
}
|
||||
sheet->SetTransformationOrigin(m_savedOrigin);
|
||||
emit TransformationOriginChanged();
|
||||
}
|
||||
m_originSaved = false;
|
||||
}
|
||||
|
||||
on_UpdateControls();
|
||||
}
|
||||
QGraphicsObject::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::TopLeftControl(QPainter *painter) const -> QPainterPath
|
||||
{
|
||||
return Controller(QTransform(), painter);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::TopRightControl(QPainter *painter) const -> QPainterPath
|
||||
{
|
||||
QTransform t;
|
||||
t.scale(-1, 1);
|
||||
t.translate(-(m_pieceRect.topLeft().x() * 2. + m_pieceRect.width()), 0);
|
||||
|
||||
return Controller(t, painter);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::BottomLeftControl(QPainter *painter) const -> QPainterPath
|
||||
{
|
||||
QTransform t;
|
||||
t.scale(1, -1);
|
||||
t.translate(0, -(m_pieceRect.topLeft().y() * 2. + m_pieceRect.height()));
|
||||
|
||||
return Controller(t, painter);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::BottomRightControl(QPainter *painter) const -> QPainterPath
|
||||
{
|
||||
QTransform t;
|
||||
t.scale(-1, -1);
|
||||
t.translate(-(m_pieceRect.topLeft().x() * 2. + m_pieceRect.width()),
|
||||
-(m_pieceRect.topLeft().y() * 2. + m_pieceRect.height()));
|
||||
|
||||
return Controller(t, painter);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPGraphicsPieceControls::Handles() const
|
||||
{
|
||||
QPainterPath path;
|
||||
|
||||
path.addPath(TopLeftControl());
|
||||
path.addPath(TopRightControl());
|
||||
path.addPath(BottomLeftControl());
|
||||
path.addPath(BottomRightControl());
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::Controller(const QTransform &t, QPainter *painter) const -> QPainterPath
|
||||
{
|
||||
if (painter != nullptr)
|
||||
{
|
||||
QPen pen = painter->pen();
|
||||
pen.setColor(defaultColor);
|
||||
painter->setPen(pen);
|
||||
}
|
||||
|
||||
QBrush colorBrush(defaultColor);
|
||||
|
||||
QPainterPath controller = ArrowPath();
|
||||
controller = t.map(controller);
|
||||
|
||||
if (painter != nullptr)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(colorBrush);
|
||||
painter->drawPath(controller);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::ControllersRect() const -> QRectF
|
||||
{
|
||||
const qreal scale = SceneScale(scene());
|
||||
|
||||
const qreal gap = 2;
|
||||
QRectF rect = m_pieceRect;
|
||||
const qreal minWidth = arcRadius/scale+gap;
|
||||
const qreal minHeight = arcRadius/scale+gap;
|
||||
|
||||
if (m_pieceRect.width() < minWidth)
|
||||
{
|
||||
qreal diff = minWidth - m_pieceRect.width();
|
||||
rect.adjust(-diff/2., 0, diff/2., 0);
|
||||
}
|
||||
|
||||
if (m_pieceRect.height() < minHeight)
|
||||
{
|
||||
qreal diff = minHeight - m_pieceRect.height();
|
||||
rect.adjust(0, -diff/2., 0, diff/2.);
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::ArrowPath() const -> QPainterPath
|
||||
{
|
||||
const qreal scale = SceneScale(scene());
|
||||
QPainterPath arrow;
|
||||
|
||||
QRectF pieceRect = ControllersRect();
|
||||
|
||||
QLineF start(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius+1)/scale);
|
||||
start.setAngle(arcStartAngle);
|
||||
|
||||
arrow.moveTo(start.p2());
|
||||
|
||||
QLineF baseLine(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
||||
baseLine.setAngle(arrow1Angle);
|
||||
arrow.lineTo(baseLine.p2());
|
||||
|
||||
QLineF leftSide = QLineF(baseLine.p2(), baseLine.p1());
|
||||
leftSide.setLength(arrowSide/scale);
|
||||
leftSide.setAngle(leftSide.angle()-90);
|
||||
arrow.lineTo(leftSide.p2());
|
||||
|
||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - arcRadius/scale);
|
||||
start.setAngle(arcStartAngle);
|
||||
|
||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+(arrowTail+arrowLength)/scale, start.p2().y()));
|
||||
baseLine.setAngle(arrow1Angle);
|
||||
arrow.lineTo(baseLine.p2());
|
||||
|
||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius-1)/scale);
|
||||
start.setAngle(arcStartAngle);
|
||||
|
||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
||||
baseLine.setAngle(arrow1Angle);
|
||||
|
||||
QLineF rightSide = QLineF(baseLine.p2(), baseLine.p1());
|
||||
rightSide.setLength(arrowSide/scale);
|
||||
rightSide.setAngle(rightSide.angle()+90);
|
||||
arrow.lineTo(rightSide.p2());
|
||||
|
||||
arrow.lineTo(baseLine.p2());
|
||||
arrow.lineTo(start.p2());
|
||||
|
||||
// arc 1
|
||||
QRectF arc1Rect(pieceRect.topLeft().x()-(arcRadius-1)/scale, pieceRect.topLeft().y()-(arcRadius-1)/scale,
|
||||
(arcRadius-1)/scale*2, (arcRadius-1)/scale*2);
|
||||
arrow.arcTo(arc1Rect, arcStartAngle, arcAngle);
|
||||
|
||||
// arrow 2
|
||||
|
||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius-1)/scale);
|
||||
start.setAngle(arcStartAngle+arcAngle);
|
||||
|
||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
||||
baseLine.setAngle(arrow2Angle+180);
|
||||
arrow.lineTo(baseLine.p2());
|
||||
|
||||
leftSide = QLineF(baseLine.p2(), baseLine.p1());
|
||||
leftSide.setLength(arrowSide/scale);
|
||||
leftSide.setAngle(leftSide.angle()-90);
|
||||
arrow.lineTo(leftSide.p2());
|
||||
|
||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - arcRadius/scale);
|
||||
start.setAngle(arcStartAngle+arcAngle);
|
||||
|
||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+(arrowTail+arrowLength)/scale, start.p2().y()));
|
||||
baseLine.setAngle(arrow2Angle+180);
|
||||
arrow.lineTo(baseLine.p2());
|
||||
|
||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius+1)/scale);
|
||||
start.setAngle(arcStartAngle+arcAngle);
|
||||
|
||||
baseLine = QLineF(start.p2(), QPointF(start.p2().x()+arrowTail/scale, start.p2().y()));
|
||||
baseLine.setAngle(arrow2Angle+180);
|
||||
|
||||
rightSide = QLineF(baseLine.p2(), baseLine.p1());
|
||||
rightSide.setLength(arrowSide/scale);
|
||||
rightSide.setAngle(rightSide.angle()+90);
|
||||
arrow.lineTo(rightSide.p2());
|
||||
|
||||
arrow.lineTo(baseLine.p2());
|
||||
arrow.lineTo(start.p2());
|
||||
|
||||
// arc 2
|
||||
QRectF arc2Rect(pieceRect.topLeft().x()-(arcRadius+1)/scale, pieceRect.topLeft().y()-(arcRadius+1)/scale,
|
||||
(arcRadius+1)/scale*2, (arcRadius+1)/scale*2);
|
||||
QPainterPath arc;
|
||||
start = QLineF(pieceRect.topLeft().x(), pieceRect.topLeft().y(),
|
||||
pieceRect.topLeft().x(), pieceRect.topLeft().y() - (arcRadius+1)/scale);
|
||||
start.setAngle(arcStartAngle);
|
||||
|
||||
arc.moveTo(start.p2());
|
||||
arc.arcTo(arc2Rect, arcStartAngle, arcAngle);
|
||||
arrow.addPath(arc.toReversed());
|
||||
|
||||
return arrow;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPGraphicsPieceControls::PiecesBoundingRect() const
|
||||
{
|
||||
QRectF rect;
|
||||
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))
|
||||
{
|
||||
rect = rect.united(item->sceneBoundingRect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::HandleCorner(const QPointF &pos) const -> int
|
||||
{
|
||||
if (TopLeftControl().boundingRect().contains(pos))
|
||||
{
|
||||
return static_cast<int>(HandleCorner::BottomRight);
|
||||
}
|
||||
|
||||
if (TopRightControl().boundingRect().contains(pos))
|
||||
{
|
||||
return static_cast<int>(HandleCorner::BottomLeft);
|
||||
}
|
||||
|
||||
if (BottomLeftControl().boundingRect().contains(pos))
|
||||
{
|
||||
return static_cast<int>(HandleCorner::TopRight);
|
||||
}
|
||||
|
||||
if (BottomRightControl().boundingRect().contains(pos))
|
||||
{
|
||||
return static_cast<int>(HandleCorner::TopLeft);
|
||||
}
|
||||
|
||||
return static_cast<int>(HandleCorner::Invalid);
|
||||
}
|
129
src/app/puzzle/scene/vpgraphicspiececontrols.h
Normal file
129
src/app/puzzle/scene/vpgraphicspiececontrols.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpgraphicspiececontrols.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 2 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 VPGRAPHICSPIECECONTROLS_H
|
||||
#define VPGRAPHICSPIECECONTROLS_H
|
||||
|
||||
#include <QColor>
|
||||
#include <QGraphicsObject>
|
||||
|
||||
#include "scenedef.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
|
||||
class VPLayout;
|
||||
|
||||
class VPGraphicsTransformationOrigin : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPGraphicsTransformationOrigin(VPLayout *layout, QGraphicsItem * parent = nullptr);
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::TransformationOrigin)};
|
||||
|
||||
public slots:
|
||||
void SetTransformationOrigin();
|
||||
void on_HideHandles(bool hide);
|
||||
void on_ShowOrigin(bool show);
|
||||
|
||||
protected:
|
||||
auto boundingRect() const -> QRectF override;
|
||||
auto shape() const -> QPainterPath override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPGraphicsTransformationOrigin)
|
||||
|
||||
bool m_originVisible{true};
|
||||
VPLayout *m_layout;
|
||||
QColor m_color;
|
||||
|
||||
auto RotationCenter(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
auto Center1() const -> QPainterPath;
|
||||
auto Center2() const -> QPainterPath;
|
||||
};
|
||||
|
||||
class VPGraphicsPieceControls : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPGraphicsPieceControls(VPLayout *layout, QGraphicsItem * parent = nullptr);
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(PGraphicsItem::Handles)};
|
||||
|
||||
signals:
|
||||
void Rotate(const QPointF ¢er, qreal angle);
|
||||
void ShowOrigin(bool show);
|
||||
void TransformationOriginChanged();
|
||||
|
||||
public slots:
|
||||
void on_UpdateControls();
|
||||
void on_HideHandles(bool hide);
|
||||
|
||||
protected:
|
||||
auto boundingRect() const -> QRectF override;
|
||||
auto shape() const -> QPainterPath override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPGraphicsPieceControls)
|
||||
QRectF m_pieceRect{};
|
||||
QPointF m_rotationStartPoint{};
|
||||
bool m_controlsVisible{true};
|
||||
VPLayout *m_layout;
|
||||
int m_handleCorner{0};
|
||||
VPTransformationOrigon m_savedOrigin{};
|
||||
bool m_originSaved{false};
|
||||
|
||||
auto TopLeftControl(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
auto TopRightControl(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
auto BottomLeftControl(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
auto BottomRightControl(QPainter *painter = nullptr) const -> QPainterPath;
|
||||
|
||||
auto Handles() const -> QPainterPath;
|
||||
auto Controller(const QTransform &t, QPainter *painter = nullptr) const -> QPainterPath;
|
||||
auto ControllersRect() const -> QRectF;
|
||||
|
||||
auto ArrowPath() const -> QPainterPath;
|
||||
|
||||
auto PiecesBoundingRect() const -> QRectF;
|
||||
auto HandleCorner(const QPointF &pos) const -> int;
|
||||
};
|
||||
|
||||
#endif // VPGRAPHICSPIECECONTROLS_H
|
|
@ -27,7 +27,9 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vpgraphicssheet.h"
|
||||
#include "vplayout.h"
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
|
@ -32,7 +32,7 @@
|
|||
#include <QGraphicsItem>
|
||||
#include <QPainter>
|
||||
|
||||
#include "vpsheet.h"
|
||||
class VPSheet;
|
||||
|
||||
class VPGraphicsSheet : public QGraphicsItem
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
#include "vpgraphicstilegrid.h"
|
||||
|
||||
#include "vptilefactory.h"
|
||||
#include "vplayout.h"
|
||||
#include "../vptilefactory.h"
|
||||
#include "../layout/vplayout.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPGraphicsTileGrid::VPGraphicsTileGrid(VPLayout *layout, VPTileFactory *tileFactory,QGraphicsItem *parent):
|
|
@ -33,16 +33,27 @@
|
|||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
|
||||
#include "vpmimedatapiece.h"
|
||||
#include "vplayout.h"
|
||||
#include "vpsheet.h"
|
||||
#include "../scene/vpgraphicssheet.h"
|
||||
#include "../scene/vpgraphicspiece.h"
|
||||
#include "../vptilefactory.h"
|
||||
#include "../scene/vpgraphicstilegrid.h"
|
||||
#include "../carousel/vpmimedatapiece.h"
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
#include "../layout/vppiece.h"
|
||||
#include "../vwidgets/vmaingraphicsscene.h"
|
||||
#include "vptilefactory.h"
|
||||
#include "vpgraphicspiececontrols.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(pMainGraphicsView, "p.mainGraphicsView")
|
||||
|
||||
namespace
|
||||
{
|
||||
const QKeySequence restoreOriginShortcut = QKeySequence(Qt::ControlModifier + Qt::Key_Asterisk);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFactory, QWidget *parent) :
|
||||
|
@ -53,17 +64,65 @@ VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFact
|
|||
SCASSERT(m_layout != nullptr)
|
||||
setScene(m_scene);
|
||||
|
||||
m_graphicsSheet = new VPGraphicsSheet(layout->GetFocusedSheet());
|
||||
m_graphicsSheet = new VPGraphicsSheet(m_layout->GetFocusedSheet());
|
||||
m_graphicsSheet->setPos(0, 0);
|
||||
m_scene->addItem(m_graphicsSheet);
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
m_graphicsTileGrid = new VPGraphicsTileGrid(layout, tileFactory);
|
||||
m_graphicsTileGrid = new VPGraphicsTileGrid(m_layout, tileFactory);
|
||||
m_scene->addItem(m_graphicsTileGrid);
|
||||
|
||||
m_rotationControls = new VPGraphicsPieceControls(m_layout);
|
||||
m_rotationControls->setVisible(false);
|
||||
m_scene->addItem(m_rotationControls);
|
||||
|
||||
m_rotationOrigin = new VPGraphicsTransformationOrigin(m_layout);
|
||||
m_rotationOrigin->setVisible(false);
|
||||
m_scene->addItem(m_rotationOrigin);
|
||||
|
||||
connect(m_rotationControls, &VPGraphicsPieceControls::ShowOrigin,
|
||||
m_rotationOrigin, &VPGraphicsTransformationOrigin::on_ShowOrigin);
|
||||
connect(m_rotationControls, &VPGraphicsPieceControls::TransformationOriginChanged,
|
||||
m_rotationOrigin, &VPGraphicsTransformationOrigin::SetTransformationOrigin);
|
||||
|
||||
// add the connections
|
||||
connect(m_layout, &VPLayout::PieceSheetChanged, this, &VPMainGraphicsView::on_PieceSheetChanged);
|
||||
|
||||
auto *restoreOrigin = new QAction(this);
|
||||
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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -94,8 +153,8 @@ void VPMainGraphicsView::RefreshPieces()
|
|||
{
|
||||
auto *graphicsPiece = new VPGraphicsPiece(piece);
|
||||
m_graphicsPieces.append(graphicsPiece);
|
||||
|
||||
scene()->addItem(graphicsPiece);
|
||||
ConnectPiece(graphicsPiece);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,9 +239,8 @@ void VPMainGraphicsView::dropEvent(QDropEvent *event)
|
|||
qCDebug(pMainGraphicsView(), "element dropped, %s", qUtf8Printable(piece->GetName()));
|
||||
event->acceptProposedAction();
|
||||
|
||||
QPoint point = event->pos();
|
||||
piece->SetPosition(mapToScene(point));
|
||||
piece->SetRotation(0);
|
||||
piece->ClearTransformations();
|
||||
piece->SetPosition(mapToScene(event->pos()));
|
||||
|
||||
// change the piecelist of the piece
|
||||
piece->SetSheet(m_layout->GetFocusedSheet());
|
||||
|
@ -192,6 +250,8 @@ void VPMainGraphicsView::dropEvent(QDropEvent *event)
|
|||
|
||||
scene()->addItem(graphicsPiece);
|
||||
|
||||
ConnectPiece(graphicsPiece);
|
||||
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
@ -208,9 +268,9 @@ void VPMainGraphicsView::keyPressEvent(QKeyEvent *event)
|
|||
{
|
||||
VPPiece *piece = graphicsPiece->GetPiece();
|
||||
|
||||
if(piece->GetIsSelected())
|
||||
if(piece->IsSelected())
|
||||
{
|
||||
piece->SetIsSelected(false);
|
||||
piece->SetSelected(false);
|
||||
piece->SetSheet(nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -228,10 +288,14 @@ void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event)
|
|||
}
|
||||
|
||||
QMenu menu;
|
||||
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
|
||||
QAction *restoreOriginAction = menu.addAction(tr("Restore transformation origin"));
|
||||
restoreOriginAction->setShortcut(restoreOriginShortcut);
|
||||
restoreOriginAction->setEnabled(sheet != nullptr && sheet->TransformationOrigin().custom);
|
||||
|
||||
QAction *removeSheetAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Remove sheet"));
|
||||
removeSheetAction->setEnabled(sheet != nullptr && m_layout->GetSheets().size() > 1);
|
||||
removeSheetAction->setEnabled(sheet != nullptr && m_layout->GetSheets().size() > 1);
|
||||
|
||||
QAction *selectedAction = menu.exec(event->globalPos());
|
||||
if (selectedAction == removeSheetAction)
|
||||
|
@ -251,6 +315,104 @@ void VPMainGraphicsView::contextMenuEvent(QContextMenuEvent *event)
|
|||
emit on_SheetRemoved();
|
||||
RefreshPieces();
|
||||
}
|
||||
else if (selectedAction == restoreOriginAction)
|
||||
{
|
||||
RestoreOrigin();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RestoreOrigin() const
|
||||
{
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet != nullptr)
|
||||
{
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
origin.custom = false;
|
||||
sheet->SetTransformationOrigin(origin);
|
||||
m_rotationControls->on_UpdateControls();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
SCASSERT(piece != nullptr)
|
||||
|
||||
connect(piece, &VPGraphicsPiece::PieceSelectionChanged,
|
||||
m_rotationControls, &VPGraphicsPieceControls::on_UpdateControls);
|
||||
connect(piece, &VPGraphicsPiece::PiecePositionChanged,
|
||||
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,
|
||||
m_rotationOrigin, &VPGraphicsTransformationOrigin::on_HideHandles);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPMainGraphicsView::RotatePiecesByAngle(qreal angle) const
|
||||
{
|
||||
QGraphicsScene *scene = this->scene();
|
||||
if (scene == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPSheet *sheet = m_layout->GetFocusedSheet();
|
||||
if (sheet == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VPTransformationOrigon origin = sheet->TransformationOrigin();
|
||||
|
||||
QList<QGraphicsItem *> list = scene->selectedItems();
|
||||
for (auto *item : list)
|
||||
{
|
||||
if (item->type() == VPGraphicsPiece::Type)
|
||||
{
|
||||
auto *pieceItem = dynamic_cast<VPGraphicsPiece*>(item);
|
||||
pieceItem->on_Rotate(origin.origin, angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -279,8 +441,10 @@ void VPMainGraphicsView::on_PieceSheetChanged(VPPiece *piece)
|
|||
{
|
||||
if(_graphicsPiece == nullptr)
|
||||
{
|
||||
piece->ClearTransformations();
|
||||
_graphicsPiece = new VPGraphicsPiece(piece);
|
||||
m_graphicsPieces.append(_graphicsPiece);
|
||||
ConnectPiece(_graphicsPiece);
|
||||
}
|
||||
scene()->addItem(_graphicsPiece);
|
||||
}
|
|
@ -29,15 +29,17 @@
|
|||
#ifndef VPMAINGRAPHICSVIEW_H
|
||||
#define VPMAINGRAPHICSVIEW_H
|
||||
|
||||
#include "vpgraphicssheet.h"
|
||||
#include "vpgraphicspiece.h"
|
||||
#include "vptilefactory.h"
|
||||
#include "vpgraphicstilegrid.h"
|
||||
#include "../vwidgets/vmaingraphicsview.h"
|
||||
|
||||
class VMainGraphicsScene;
|
||||
|
||||
class VPGraphicsPieceControls;
|
||||
class VPGraphicsTransformationOrigin;
|
||||
class VPTileFactory;
|
||||
class VPGraphicsPiece;
|
||||
class VPLayout;
|
||||
class VPGraphicsTileGrid;
|
||||
class VPGraphicsSheet;
|
||||
class VPPiece;
|
||||
|
||||
class VPMainGraphicsView : public VMainGraphicsView
|
||||
{
|
||||
|
@ -92,6 +94,15 @@ protected:
|
|||
|
||||
void drawTilesLine();
|
||||
|
||||
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)
|
||||
|
||||
|
@ -101,6 +112,9 @@ private:
|
|||
|
||||
VPGraphicsTileGrid *m_graphicsTileGrid{nullptr};
|
||||
|
||||
VPGraphicsPieceControls *m_rotationControls{nullptr};
|
||||
VPGraphicsTransformationOrigin *m_rotationOrigin{nullptr};
|
||||
|
||||
VPLayout *m_layout;
|
||||
|
||||
QList<VPGraphicsPiece*> m_graphicsPieces{};
|
||||
|
@ -115,6 +129,10 @@ private:
|
|||
*/
|
||||
bool m_showGridTmp{false};
|
||||
|
||||
void ConnectPiece(VPGraphicsPiece *piece);
|
||||
|
||||
void RotatePiecesByAngle(qreal angle) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // VPMAINGRAPHICSVIEW_H
|
|
@ -4,8 +4,8 @@
|
|||
#include <QMessageBox>
|
||||
|
||||
#include "../vwidgets/vmaingraphicsscene.h"
|
||||
#include "vpsheet.h"
|
||||
#include "vpmaingraphicsview.h"
|
||||
#include "layout/vpsheet.h"
|
||||
#include "scene/vpmaingraphicsview.h"
|
||||
#include "../vobj/vobjpaintdevice.h"
|
||||
#include "../vdxf/vdxfpaintdevice.h"
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include "vplayout.h"
|
||||
#include "layout/vplayout.h"
|
||||
#include "../vmisc/def.h"
|
||||
#include "vcommonsettings.h"
|
||||
#include "../vlayout/vlayoutdef.h"
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "../ifc/xml/vlayoutconverter.h"
|
||||
#include "../ifc/exception/vexception.h"
|
||||
#include "../vwidgets/vmaingraphicsscene.h"
|
||||
#include "vpsheet.h"
|
||||
#include "layout/vpsheet.h"
|
||||
#include "dialogs/dialogpuzzlepreferences.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
|
||||
|
@ -322,11 +322,6 @@ VPPiece* VPMainWindow::CreatePiece(const VLayoutPiece &rawPiece)
|
|||
|
||||
// TODO : set all the information we need for the piece!
|
||||
|
||||
//
|
||||
connect(piece, &VPPiece::SelectionChanged, this, &VPMainWindow::on_PieceSelectionChanged);
|
||||
connect(piece, &VPPiece::PositionChanged, this, &VPMainWindow::on_PiecePositionChanged);
|
||||
connect(piece, &VPPiece::RotationChanged, this, &VPMainWindow::on_PieceRotationChanged);
|
||||
|
||||
|
||||
return piece;
|
||||
}
|
||||
|
@ -603,8 +598,8 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
|
|||
ui->lineEditCurrentPieceName->setText(selectedPiece->GetName());
|
||||
ui->plainTextEditCurrentPieceUUID->setPlainText(selectedPiece->GetUUID().toString());
|
||||
|
||||
ui->checkBoxCurrentPieceShowSeamline->setChecked(selectedPiece->GetShowSeamLine());
|
||||
ui->checkBoxCurrentPieceMirrorPiece->setChecked(selectedPiece->GetPieceMirrored());
|
||||
// ui->checkBoxCurrentPieceShowSeamline->setChecked(selectedPiece->GetShowSeamLine());
|
||||
ui->checkBoxCurrentPieceMirrorPiece->setChecked(selectedPiece->IsMirror());
|
||||
|
||||
QPointF pos = selectedPiece->GetPosition();
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceBoxPositionX,
|
||||
|
@ -612,8 +607,8 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
|
|||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceBoxPositionY,
|
||||
UnitConvertor(pos.y(), Unit::Px, m_layout->LayoutSettings().GetUnit()));
|
||||
|
||||
qreal angle = selectedPiece->GetRotation();
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle);
|
||||
// qreal angle = selectedPiece->GetRotation();
|
||||
// SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1694,7 +1689,7 @@ void VPMainWindow::on_checkBoxCurrentPieceShowSeamline_toggled(bool checked)
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPieces.first()->SetShowSeamLine(checked);
|
||||
// m_selectedPieces.first()->SetShowSeamLine(checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1703,7 +1698,7 @@ void VPMainWindow::on_checkBoxCurrentPieceMirrorPiece_toggled(bool checked)
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPieces.first()->SetPieceMirrored(checked);
|
||||
m_selectedPieces.first()->SetMirror(checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1712,7 +1707,7 @@ void VPMainWindow::on_pushButtonCurrentPieceRotate90Anticlockwise_clicked()
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPieces.first()->RotateBy(90);
|
||||
// m_selectedPieces.first()->RotateBy(90);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1721,7 +1716,7 @@ void VPMainWindow::on_pushButtonCurrentPieceRotate90Clockwise_clicked()
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPieces.first()->RotateBy(-90);
|
||||
// m_selectedPieces.first()->RotateBy(-90);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1730,7 +1725,7 @@ void VPMainWindow::on_pushButtonCurrentPieceRotateGrainlineVertical_clicked()
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPieces.first()->RotateToGrainline(90, true);
|
||||
// m_selectedPieces.first()->RotateToGrainline(90, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1739,7 +1734,7 @@ void VPMainWindow::on_pushButtonCurrentPieceRotateGrainlineHorizontal_clicked()
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPieces.first()->RotateToGrainline(0, true);
|
||||
// m_selectedPieces.first()->RotateToGrainline(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1748,8 +1743,8 @@ void VPMainWindow::on_doubleSpinBoxCurrentPieceAngle_valueChanged(double value)
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
VPPiece *piece = m_selectedPieces.first();
|
||||
piece->SetRotation(value);
|
||||
// VPPiece *piece = m_selectedPieces.first();
|
||||
// piece->SetRotation(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1811,10 +1806,10 @@ void VPMainWindow::on_PieceRotationChanged()
|
|||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
VPPiece *piece = m_selectedPieces.first();
|
||||
qreal angle = piece->GetRotation();
|
||||
// VPPiece *piece = m_selectedPieces.first();
|
||||
// qreal angle = piece->GetRotation();
|
||||
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle);
|
||||
// SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@
|
|||
#include <QPointer>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
#include "vpcarrousel.h"
|
||||
#include "vpmaingraphicsview.h"
|
||||
#include "vplayout.h"
|
||||
#include "vppiece.h"
|
||||
#include "carousel/vpcarrousel.h"
|
||||
#include "scene/vpmaingraphicsview.h"
|
||||
#include "layout/vplayout.h"
|
||||
#include "layout/vppiece.h"
|
||||
#include "../vlayout/vlayoutpiece.h"
|
||||
#include "vptilefactory.h"
|
||||
#include "vpexporter.h"
|
||||
|
|
|
@ -669,7 +669,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<y>-170</y>
|
||||
<width>342</width>
|
||||
<height>870</height>
|
||||
</rect>
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vppiece.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 13 4, 2020
|
||||
**
|
||||
** @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) 2020 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 "vppiece.h"
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QLoggingCategory>
|
||||
#include <QPainter>
|
||||
|
||||
Q_LOGGING_CATEGORY(pPiece, "p.piece")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPPiece::VPPiece(VLayoutPiece layoutPiece): VLayoutPiece(layoutPiece)
|
||||
{
|
||||
// Resets the translation of the matrix
|
||||
QTransform matrix = GetMatrix();
|
||||
matrix.translate(-matrix.dx() ,-matrix.dy());
|
||||
SetMatrix(matrix);
|
||||
|
||||
// then translate the piece so that the top left corner of the bouding rect of the piece is at the position
|
||||
// (0,0) in the sheet coordinate system
|
||||
QRectF boundingRect = MappedDetailBoundingRect();
|
||||
QPointF offset = boundingRect.topLeft();
|
||||
matrix = GetMatrix();
|
||||
matrix.translate(-offset.x() ,-offset.y());
|
||||
SetMatrix(matrix);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPPiece::~VPPiece()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPPiece::GetShowSeamLine() const
|
||||
{
|
||||
return m_showSeamline;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetShowSeamLine(bool value)
|
||||
{
|
||||
m_showSeamline = value;
|
||||
|
||||
emit PropertiesChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPPiece::GetPieceMirrored() const
|
||||
{
|
||||
return m_mirrorPiece;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetPieceMirrored(bool value)
|
||||
{
|
||||
m_mirrorPiece = value;
|
||||
|
||||
emit PropertiesChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetPosition(QPointF point)
|
||||
{
|
||||
m_transform.translate(point.x() - m_transform.dx(), point.y() - m_transform.dy());
|
||||
|
||||
emit PositionChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPointF VPPiece::GetPosition()
|
||||
{
|
||||
return QPointF(m_transform.dx(),m_transform.dy());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetRotation(qreal angle)
|
||||
{
|
||||
// qreal currentAngle = GetRotation();
|
||||
// qreal newAngle = angle - currentAngle;
|
||||
|
||||
// m_transform.rotate(newAngle);
|
||||
|
||||
if(not VFuzzyComparePossibleNulls(m_pieceAngle, angle))
|
||||
{
|
||||
m_pieceAngle = angle;
|
||||
|
||||
// make sure the angle is [0 <= angle < 360]
|
||||
while(m_pieceAngle >= 360)
|
||||
{
|
||||
m_pieceAngle -= 360;
|
||||
}
|
||||
|
||||
while(m_pieceAngle < 0)
|
||||
{
|
||||
m_pieceAngle += 360;
|
||||
}
|
||||
|
||||
emit RotationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::RotateBy(qreal angle)
|
||||
{
|
||||
SetRotation(m_pieceAngle + angle);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::RotateToGrainline(qreal angleOfGrainline, bool add180IfAlreadyInPosition)
|
||||
{
|
||||
qreal newAngle = -GrainlineAngle() + angleOfGrainline;
|
||||
if(newAngle < 0)
|
||||
{
|
||||
newAngle += 360;
|
||||
}
|
||||
|
||||
if(not VFuzzyComparePossibleNulls(m_pieceAngle, newAngle))
|
||||
{
|
||||
SetRotation(newAngle);
|
||||
}
|
||||
else if(add180IfAlreadyInPosition)
|
||||
{
|
||||
newAngle += 180;
|
||||
SetRotation(newAngle);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
qreal VPPiece::GetRotation()
|
||||
{
|
||||
return m_pieceAngle;
|
||||
|
||||
// We don't use the QTransform vor now because the math behind it to retrieve the angle is not trivial.
|
||||
// TODO / FIXME: we can use QTransform later for optimization
|
||||
|
||||
|
||||
// QTransform tmpTransform = m_transform;
|
||||
// tmpTransform.translate(-tmpTransform.dx(), -tmpTransform.dy()); // make sure there is only the rotation in the matrix
|
||||
|
||||
// qreal angle = qRadiansToDegrees(qAcos(tmpTransform.m11()));
|
||||
|
||||
// qCDebug(pPiece, "new angle : %f", angle);
|
||||
|
||||
// return angle;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetIsSelected(bool value)
|
||||
{
|
||||
if(m_isSelected != value)
|
||||
{
|
||||
m_isSelected = value;
|
||||
emit SelectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPPiece::GetIsSelected()
|
||||
{
|
||||
return m_isSelected;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::Sheet() const -> VPSheet *
|
||||
{
|
||||
return m_sheet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetSheet(VPSheet *newSheet)
|
||||
{
|
||||
m_sheet = newSheet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPPiece::Layout() const -> VPLayout *
|
||||
{
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetLayout(VPLayout *layout)
|
||||
{
|
||||
SCASSERT(layout != nullptr)
|
||||
m_layout = layout;
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vppiece.h
|
||||
** @author Ronan Le Tiec
|
||||
** @date 13 4, 2020
|
||||
**
|
||||
** @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) 2020 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 VPPIECE_H
|
||||
#define VPPIECE_H
|
||||
|
||||
#include <QUuid>
|
||||
#include <QVector>
|
||||
#include <QPoint>
|
||||
#include <QTransform>
|
||||
|
||||
#include "../vlayout/vlayoutpiece.h"
|
||||
|
||||
class VPLayout;
|
||||
class VPSheet;
|
||||
|
||||
class VPPiece : public QObject, public VLayoutPiece
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPPiece() = default;
|
||||
explicit VPPiece(VLayoutPiece layoutPiece);
|
||||
|
||||
virtual ~VPPiece();
|
||||
|
||||
/**
|
||||
* @brief GetShowSeamLine returns wether the seam line of the piece has to be shown or not
|
||||
* @return true if the seamline has to be shown
|
||||
*/
|
||||
bool GetShowSeamLine() const;
|
||||
|
||||
/**
|
||||
* @brief SetShowSeamLine sets wether the seam line of the piece has to be shown or not
|
||||
* @param value true if the seamline has to be shown
|
||||
*/
|
||||
void SetShowSeamLine(bool value);
|
||||
|
||||
/**
|
||||
* @brief GetMirrorPiece returns wether the piece is mirrored or not
|
||||
* @return true if the piece is mirrored
|
||||
*/
|
||||
bool GetPieceMirrored() const;
|
||||
|
||||
/**
|
||||
* @brief SetMirrorPiece sets wether the piece is mirrored or not
|
||||
* @param value true if the piece will be mirrored
|
||||
*/
|
||||
void SetPieceMirrored(bool value);
|
||||
|
||||
/**
|
||||
* @brief SetPosition Sets the position of the piece, in relation to the origin of the scene
|
||||
* @param point the point where to set the piece
|
||||
*/
|
||||
void SetPosition(QPointF point);
|
||||
|
||||
/**
|
||||
* @brief GetPosition Returns the position of the piece
|
||||
* @return the position of the piece
|
||||
*/
|
||||
QPointF GetPosition();
|
||||
|
||||
/**
|
||||
* @brief SetRotation Sets the rotation of the piece to the given angle.
|
||||
* @param angle the angle of the rotation in degree
|
||||
*/
|
||||
void SetRotation(qreal angle);
|
||||
|
||||
/**
|
||||
* @brief GetRotation Returns the angle of rotation
|
||||
* @return the angle of rotation
|
||||
*/
|
||||
qreal GetRotation();
|
||||
|
||||
/**
|
||||
* @brief rotateBy adds the given angle to the current rotation (anti-clockwise)
|
||||
* @param angle the angle to add
|
||||
*/
|
||||
void RotateBy(qreal angle);
|
||||
|
||||
/**
|
||||
* @brief RotateToGrainline rotates the piece, so that the grainline has
|
||||
* the given angle
|
||||
*
|
||||
* @param angleOfGrainline angle of grainline
|
||||
* @param add180IfAlreadyInPosition automatically adds 180, if the piece is
|
||||
* already in the grainline position
|
||||
*/
|
||||
void RotateToGrainline(qreal angleOfGrainline, bool add180IfAlreadyInPosition = false);
|
||||
|
||||
/**
|
||||
* @brief SetIsSelected Sets wether the piece is selected
|
||||
* @param value true if the piece is selected
|
||||
*/
|
||||
void SetIsSelected(bool value);
|
||||
|
||||
/**
|
||||
* @brief GetIsSelected Returns wether the piece is selected. It emit the signal SelectionChanged
|
||||
* @return true if the piece is selected
|
||||
*/
|
||||
bool GetIsSelected();
|
||||
|
||||
QIcon PieceIcon(const QSize &size) const;
|
||||
|
||||
auto Sheet() const -> VPSheet *;
|
||||
void SetSheet(VPSheet *newSheet);
|
||||
|
||||
auto Layout() const -> VPLayout *;
|
||||
void SetLayout(VPLayout *layout);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief SelectionChanged emited when the selection of the piece was
|
||||
* changed through the SetIsSelected function
|
||||
*/
|
||||
void SelectionChanged();
|
||||
|
||||
/**
|
||||
* @brief PositionChanged emited when the position of the piece was
|
||||
* changed through the SetPosition function
|
||||
*/
|
||||
void PositionChanged();
|
||||
|
||||
/**
|
||||
* @brief RotationChanged emited when the position of the piece was
|
||||
* changed through the function SetRotation
|
||||
*/
|
||||
void RotationChanged();
|
||||
|
||||
/**
|
||||
* @brief PropertiesChanged emited when of the properties showSemaline
|
||||
* or mirrorpiece where changed.
|
||||
*/
|
||||
void PropertiesChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPPiece)
|
||||
|
||||
VPLayout *m_layout{nullptr};
|
||||
|
||||
VPSheet *m_sheet{nullptr};
|
||||
|
||||
QVector<QPointF> m_grainline{};
|
||||
bool m_isGrainlineEnabled{false};
|
||||
|
||||
// for now separate the position of the piece to the matrix coming from vlayoutpiece
|
||||
// because it's difficult to have the origin of the piece by (0,0)
|
||||
QTransform m_transform{};
|
||||
// use a separate value for now because it's not easy to get the angle from the transform matrix
|
||||
qreal m_pieceAngle{0};
|
||||
|
||||
bool m_showSeamline{true};
|
||||
bool m_mirrorPiece{false};
|
||||
|
||||
bool m_isSelected{false};
|
||||
};
|
||||
|
||||
#endif // VPPIECE_H
|
|
@ -3,9 +3,11 @@
|
|||
#include <QtSvg>
|
||||
|
||||
#include "../vwidgets/vmaingraphicsscene.h"
|
||||
#include "vpsheet.h"
|
||||
#include "vpmaingraphicsview.h"
|
||||
|
||||
#include "layout/vpsheet.h"
|
||||
#include "scene/vpmaingraphicsview.h"
|
||||
#include "layout/vplayout.h"
|
||||
#include "../vmisc/def.h"
|
||||
#include "../vmisc/vcommonsettings.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPTileFactory::VPTileFactory(VPLayout *layout, VCommonSettings *commonSettings):
|
||||
|
@ -21,7 +23,6 @@ VPTileFactory::~VPTileFactory()
|
|||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPTileFactory::refreshTileInfos()
|
||||
{
|
||||
|
|
|
@ -32,11 +32,10 @@
|
|||
#include <QtMath>
|
||||
#include <QObject>
|
||||
|
||||
#include "vplayout.h"
|
||||
#include "../vmisc/def.h"
|
||||
#include "vcommonsettings.h"
|
||||
|
||||
class VPMainGraphicsView;
|
||||
class VPLayout;
|
||||
class VCommonSettings;
|
||||
class QPainter;
|
||||
|
||||
class VPTileFactory : QObject
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "vplayoutfilereader.h"
|
||||
#include "vplayoutfilewriter.h"
|
||||
#include "vplayoutliterals.h"
|
||||
#include "vpsheet.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
#include "../ifc/exception/vexception.h"
|
||||
#include "../ifc/exception/vexceptionconversionerror.h"
|
||||
|
||||
|
@ -297,11 +297,11 @@ void VPLayoutFileReader::ReadPiece(VPPiece *piece)
|
|||
QString uuidStr = ReadAttributeString(attribs, ML::AttrID, QUuid::createUuid().toString());
|
||||
piece->SetUUID(QUuid(uuidStr));
|
||||
|
||||
bool showSeamline = ReadAttributeBool(attribs, ML::AttrShowSeamline, trueStr);
|
||||
piece->SetShowSeamLine(showSeamline);
|
||||
// bool showSeamline = ReadAttributeBool(attribs, ML::AttrShowSeamline, trueStr);
|
||||
// piece->SetShowSeamLine(showSeamline);
|
||||
|
||||
bool pieceMirrored = ReadAttributeBool(attribs, ML::AttrMirrored, falseStr);
|
||||
piece->SetPieceMirrored(pieceMirrored);
|
||||
piece->SetMirror(pieceMirrored);
|
||||
// TODO read the further attributes
|
||||
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
|
||||
#include <QXmlStreamReader>
|
||||
#include "../ifc/xml/vabstractconverter.h"
|
||||
#include "vplayout.h"
|
||||
#include "vppiece.h"
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../layout/vppiece.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vplayoutfilewriter.h"
|
||||
#include "vplayout.h"
|
||||
#include "vpsheet.h"
|
||||
#include "vppiece.h"
|
||||
#include "../layout/vplayout.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
#include "../layout/vppiece.h"
|
||||
#include "vplayoutliterals.h"
|
||||
#include "../ifc/xml/vlayoutconverter.h"
|
||||
#include "../vmisc/projectversion.h"
|
||||
|
@ -142,8 +142,8 @@ void VPLayoutFileWriter::WritePiece(VPPiece *piece)
|
|||
writeStartElement(ML::TagPiece);
|
||||
SetAttribute(ML::AttrID, piece->GetUUID().toString());
|
||||
SetAttribute(ML::AttrName, piece->GetName());
|
||||
SetAttribute(ML::AttrMirrored, piece->GetPieceMirrored());
|
||||
SetAttribute(ML::AttrShowSeamline, piece->GetShowSeamLine());
|
||||
SetAttribute(ML::AttrMirrored, piece->IsMirror());
|
||||
// SetAttribute(ML::AttrShowSeamline, piece->GetShowSeamLine());
|
||||
SetAttribute(ML::AttrTransform, "string representation of the transformation"); // TODO / Fixme get the right value
|
||||
|
||||
// TODO cuttingLine
|
||||
|
|
|
@ -876,9 +876,15 @@ void VLayoutPiece::SetId(vidtype id)
|
|||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::Translate(qreal dx, qreal dy)
|
||||
{
|
||||
Translate(QPointF(dx, dy));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::Translate(const QPointF &p)
|
||||
{
|
||||
QTransform m;
|
||||
m.translate(dx, dy);
|
||||
m.translate(p.x(), p.y());
|
||||
d->matrix *= m;
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ public:
|
|||
bool IsMirror() const;
|
||||
void SetMirror(bool value);
|
||||
|
||||
void Translate(const QPointF &p);
|
||||
void Translate(qreal dx, qreal dy);
|
||||
void Scale(qreal sx, qreal sy);
|
||||
void Rotate(const QPointF &originPoint, qreal degrees);
|
||||
|
|
Loading…
Reference in New Issue
Block a user