Merge branch 'feature/manual-layout' into 'feature/manual-layout'
Feature/manual layout app behaviour optimization See merge request smart-pattern/valentina!7
This commit is contained in:
commit
ddd4d735e8
|
@ -6,11 +6,17 @@ SOURCES += \
|
|||
$$PWD/puzzlecommands.cpp \
|
||||
$$PWD/puzzlemainwindow.cpp \
|
||||
$$PWD/puzzleapplication.cpp \
|
||||
$$PWD/vpiececarrouselpiecepreview.cpp \
|
||||
$$PWD/vpuzzlecommandline.cpp \
|
||||
$$PWD/dialogs/dialogaboutpuzzle.cpp \
|
||||
$$PWD/vpiececarrousel.cpp \
|
||||
$$PWD/vpuzzlegraphicslayout.cpp \
|
||||
$$PWD/vpuzzlegraphicspiece.cpp \
|
||||
$$PWD/vpuzzlelayout.cpp \
|
||||
$$PWD/vpuzzlelayer.cpp \
|
||||
$$PWD/vpuzzlemaingraphicsscene.cpp \
|
||||
$$PWD/vpuzzlemaingraphicsview.cpp \
|
||||
$$PWD/vpuzzlemimedatapiece.cpp \
|
||||
$$PWD/vpuzzlepiece.cpp \
|
||||
$$PWD/xml/layoutliterals.cpp \
|
||||
$$PWD/xml/vpuzzlelayoutfilewriter.cpp \
|
||||
|
@ -25,11 +31,17 @@ HEADERS += \
|
|||
$$PWD/puzzlemainwindow.h \
|
||||
$$PWD/stable.h \
|
||||
$$PWD/puzzleapplication.h \
|
||||
$$PWD/vpiececarrouselpiecepreview.h \
|
||||
$$PWD/vpuzzlecommandline.h \
|
||||
$$PWD/dialogs/dialogaboutpuzzle.h \
|
||||
$$PWD/vpiececarrousel.h \
|
||||
$$PWD/vpuzzlegraphicslayout.h \
|
||||
$$PWD/vpuzzlegraphicspiece.h \
|
||||
$$PWD/vpuzzlelayout.h \
|
||||
$$PWD/vpuzzlelayer.h \
|
||||
$$PWD/vpuzzlemaingraphicsscene.h \
|
||||
$$PWD/vpuzzlemaingraphicsview.h \
|
||||
$$PWD/vpuzzlemimedatapiece.h \
|
||||
$$PWD/vpuzzlepiece.h \
|
||||
$$PWD/xml/layoutliterals.h \
|
||||
$$PWD/xml/vpuzzlelayoutfilewriter.h \
|
||||
|
|
|
@ -59,9 +59,9 @@ PuzzleMainWindow::PuzzleMainWindow(const VPuzzleCommandLinePtr &cmd, QWidget *pa
|
|||
m_layout = new VPuzzleLayout();
|
||||
|
||||
// ----- for test purposes, to be removed------------------
|
||||
m_layout->SetLayoutMarginsConverted(1.5, 2.00, 4.21, 0.25);
|
||||
m_layout->SetLayoutSizeConverted(30.0, 29.7);
|
||||
m_layout->SetPiecesGapConverted(1.27);
|
||||
m_layout->SetLayoutMarginsConverted(2, 2, 2, 2);
|
||||
m_layout->SetLayoutSizeConverted(30.0, 45);
|
||||
m_layout->SetPiecesGapConverted(1);
|
||||
m_layout->SetUnit(Unit::Cm);
|
||||
m_layout->SetWarningSuperpositionOfPieces(true);
|
||||
// --------------------------------------------------------
|
||||
|
@ -71,6 +71,8 @@ PuzzleMainWindow::PuzzleMainWindow(const VPuzzleCommandLinePtr &cmd, QWidget *pa
|
|||
InitMenuBar();
|
||||
InitProperties();
|
||||
InitPieceCarrousel();
|
||||
InitMainGraphics();
|
||||
|
||||
|
||||
SetPropertiesData();
|
||||
}
|
||||
|
@ -142,8 +144,22 @@ void PuzzleMainWindow::ImportRawLayouts(const QStringList &rawLayouts)
|
|||
{
|
||||
VLayoutPiece rawPiece = data.pieces.at(i);
|
||||
|
||||
// TODO for feature "Update piece" : CreateOrUpdate() function indstead of CreatePiece()
|
||||
// We translate the piece, so that the origin of the bounding rect of the piece is at (0,0)
|
||||
// It makes positioning later on easier.
|
||||
QRectF boundingRect = rawPiece.DetailBoundingRect();
|
||||
QPointF topLeft = boundingRect.topLeft();
|
||||
rawPiece.Translate(-topLeft.x(), -topLeft.y());
|
||||
|
||||
|
||||
|
||||
// TODO / FIXME: make a few tests, on the data to check for validity. If not
|
||||
//
|
||||
// If seam allowance enabled, but the path is empty — invalid.
|
||||
// If seam line path not hidden, but the path is empty — invalid.
|
||||
// If seam allowance is built-in, but the seam line path is empty — invalid.
|
||||
|
||||
|
||||
// TODO for feature "Update piece" : CreateOrUpdate() function indstead of CreatePiece()
|
||||
VPuzzlePiece *piece = CreatePiece(rawPiece);
|
||||
m_layout->GetUnplacedPiecesLayer()->AddPiece(piece);
|
||||
}
|
||||
|
@ -168,10 +184,25 @@ VPuzzlePiece* PuzzleMainWindow::CreatePiece(const VLayoutPiece &rawPiece)
|
|||
VPuzzlePiece *piece = new VPuzzlePiece();
|
||||
piece->SetName(rawPiece.GetName());
|
||||
piece->SetUuid(rawPiece.GetUUID());
|
||||
|
||||
piece->SetCuttingLine(rawPiece.GetMappedSeamAllowancePoints());
|
||||
piece->SetSeamLine(rawPiece.GetMappedContourPoints());
|
||||
|
||||
piece->SetIsGrainlineEnabled(rawPiece.IsGrainlineEnabled());
|
||||
if(rawPiece.IsGrainlineEnabled())
|
||||
{
|
||||
piece->SetGrainlineAngle(rawPiece.GrainlineAngle());
|
||||
piece->SetGrainline(rawPiece.GetGrainline());
|
||||
}
|
||||
|
||||
// TODO : set all the information we need for the piece!
|
||||
|
||||
//
|
||||
connect(piece, &VPuzzlePiece::SelectionChanged, this, &PuzzleMainWindow::on_PieceSelectionChanged);
|
||||
connect(piece, &VPuzzlePiece::PositionChanged, this, &PuzzleMainWindow::on_PiecePositionChanged);
|
||||
connect(piece, &VPuzzlePiece::RotationChanged, this, &PuzzleMainWindow::on_PieceRotationChanged);
|
||||
|
||||
|
||||
return piece;
|
||||
}
|
||||
|
||||
|
@ -211,9 +242,9 @@ void PuzzleMainWindow::InitPropertyTabCurrentPiece()
|
|||
|
||||
// ------------------------------ placement -----------------------------------
|
||||
connect(ui->doubleSpinBoxCurrentPieceBoxPositionX, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
|
||||
&PuzzleMainWindow::on_CurrentPiecePositionChanged);
|
||||
&PuzzleMainWindow::on_CurrentPiecePositionEdited);
|
||||
connect(ui->doubleSpinBoxCurrentPieceBoxPositionY, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
|
||||
&PuzzleMainWindow::on_CurrentPiecePositionChanged);
|
||||
&PuzzleMainWindow::on_CurrentPiecePositionEdited);
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,9 +324,6 @@ void PuzzleMainWindow::InitPieceCarrousel()
|
|||
|
||||
connect(ui->dockWidgetPieceCarrousel, QOverload<Qt::DockWidgetArea>::of(&QDockWidget::dockLocationChanged), this,
|
||||
&PuzzleMainWindow::on_PieceCarrouselLocationChanged);
|
||||
|
||||
connect(m_pieceCarrousel, QOverload<VPuzzlePiece*>::of(&VPieceCarrousel::pieceClicked), this,
|
||||
&PuzzleMainWindow::on_PieceSelected);
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,31 +346,45 @@ void PuzzleMainWindow::SetPropertiesData()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::SetPropertyTabCurrentPieceData()
|
||||
{
|
||||
if(m_selectedPiece == nullptr)
|
||||
if(m_selectedPieces.count() == 0)
|
||||
{
|
||||
if(false) // check for multiple piece selection
|
||||
{
|
||||
// TODO in the future
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO : update current piece data to show a "no current piece selected"
|
||||
ui->containerCurrentPieceNoData->setVisible(true);
|
||||
ui->containerCurrentPieceData->setVisible(false);
|
||||
}
|
||||
// show the content "no piece selected"
|
||||
|
||||
ui->containerCurrentPieceNoData->setVisible(true);
|
||||
ui->containerCurrentPieceData->setVisible(false);
|
||||
ui->containerCurrentPieceMultipleData->setVisible(false);
|
||||
}
|
||||
else if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
// show the content "selected piece data"
|
||||
ui->containerCurrentPieceNoData->setVisible(false);
|
||||
ui->containerCurrentPieceData->setVisible(true);
|
||||
ui->containerCurrentPieceMultipleData->setVisible(false);
|
||||
|
||||
VPuzzlePiece *selectedPiece = m_selectedPieces.first();
|
||||
|
||||
// set the value to the current piece
|
||||
ui->lineEditCurrentPieceName->setText(selectedPiece->GetName());
|
||||
|
||||
ui->checkBoxCurrentPieceShowSeamline->setChecked(selectedPiece->GetShowSeamLine());
|
||||
ui->checkBoxCurrentPieceMirrorPiece->setChecked(selectedPiece->GetPieceMirrored());
|
||||
|
||||
QPointF pos = selectedPiece->GetPosition();
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceBoxPositionX, UnitConvertor(pos.x(), Unit::Px, m_layout->GetUnit()));
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceBoxPositionY, UnitConvertor(pos.y(), Unit::Px, m_layout->GetUnit()));
|
||||
|
||||
qreal angle = selectedPiece->GetRotation();
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// show the content "multiple pieces selected"
|
||||
|
||||
ui->containerCurrentPieceNoData->setVisible(false);
|
||||
ui->containerCurrentPieceData->setVisible(true);
|
||||
ui->containerCurrentPieceData->setVisible(false);
|
||||
ui->containerCurrentPieceMultipleData->setVisible(true);
|
||||
|
||||
// set the value to the current piece
|
||||
ui->lineEditCurrentPieceName->setText(m_selectedPiece->GetName());
|
||||
|
||||
ui->checkBoxCurrentPieceShowSeamline->setChecked(m_selectedPiece->GetShowSeamLine());
|
||||
ui->checkBoxCurrentPieceMirrorPiece->setChecked(m_selectedPiece->GetPieceMirrored());
|
||||
|
||||
// TODO:rotation and placement;
|
||||
// if needed in the future, we can show some properties that coul be edited for all the pieces
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,6 +443,15 @@ void PuzzleMainWindow::SetPropertyTabLayersData()
|
|||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::InitMainGraphics()
|
||||
{
|
||||
m_graphicsView = new VPuzzleMainGraphicsView(m_layout, this);
|
||||
ui->centralWidget->layout()->addWidget(m_graphicsView);
|
||||
|
||||
m_graphicsView->RefreshLayout();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::SetDoubleSpinBoxValue(QDoubleSpinBox *spinBox, qreal value)
|
||||
|
@ -644,7 +695,8 @@ void PuzzleMainWindow::on_LayoutSizeChanged()
|
|||
}
|
||||
|
||||
// TODO Undo / Redo
|
||||
// TODO update the QGraphicView
|
||||
|
||||
m_graphicsView->RefreshLayout();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -657,8 +709,11 @@ void PuzzleMainWindow::on_LayoutOrientationChanged()
|
|||
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutWidth, length_before);
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxLayoutLength, width_before);
|
||||
|
||||
m_layout->SetLayoutSizeConverted(ui->doubleSpinBoxLayoutWidth->value(), ui->doubleSpinBoxLayoutLength->value());
|
||||
|
||||
// TODO Undo / Redo
|
||||
// TODO update the QGraphicView
|
||||
|
||||
m_graphicsView->RefreshLayout();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -686,7 +741,8 @@ void PuzzleMainWindow::on_LayoutMarginChanged()
|
|||
);
|
||||
|
||||
// TODO Undo / Redo
|
||||
// TODO update the QGraphicView
|
||||
|
||||
m_graphicsView->RefreshLayout();
|
||||
}
|
||||
|
||||
|
||||
|
@ -759,47 +815,42 @@ void PuzzleMainWindow::on_pushButtonLayoutExport_clicked()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::on_checkBoxCurrentPieceShowSeamline_toggled(bool checked)
|
||||
{
|
||||
if(m_selectedPiece != nullptr)
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPiece->SetShowSeamLine(checked);
|
||||
m_selectedPieces.first()->SetShowSeamLine(checked);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::on_checkBoxCurrentPieceMirrorPiece_toggled(bool checked)
|
||||
{
|
||||
if(m_selectedPiece != nullptr)
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
m_selectedPiece->SetPieceMirrored(checked);
|
||||
m_selectedPieces.first()->SetPieceMirrored(checked);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::on_doubleSpinBoxCurrentPieceAngle_valueChanged(double value)
|
||||
{
|
||||
// just for test purpuses, to be removed:
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("TODO PuzzleMainWindow::CurrentPieceAngleChanged");
|
||||
int ret = msgBox.exec();
|
||||
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(ret);
|
||||
|
||||
// TODO
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
VPuzzlePiece *piece = m_selectedPieces.first();
|
||||
piece->SetRotation(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::on_CurrentPiecePositionChanged()
|
||||
void PuzzleMainWindow::on_CurrentPiecePositionEdited()
|
||||
{
|
||||
// just for test purpuses, to be removed:
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("TODO PuzzleMainWindow::CurrentPiecePositionChanged");
|
||||
int ret = msgBox.exec();
|
||||
|
||||
Q_UNUSED(ret);
|
||||
|
||||
// TODO
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
VPuzzlePiece *piece = m_selectedPieces.first();
|
||||
QPointF pos(UnitConvertor(ui->doubleSpinBoxCurrentPieceBoxPositionX->value(), m_layout->GetUnit(), Unit::Px),
|
||||
UnitConvertor(ui->doubleSpinBoxCurrentPieceBoxPositionY->value(), m_layout->GetUnit(), Unit::Px));
|
||||
piece->SetPosition(pos);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -820,17 +871,37 @@ void PuzzleMainWindow::on_PieceCarrouselLocationChanged(Qt::DockWidgetArea area)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::on_PieceSelected(VPuzzlePiece* piece)
|
||||
void PuzzleMainWindow::on_PieceSelectionChanged()
|
||||
{
|
||||
m_selectedPiece = piece;
|
||||
|
||||
// update the state of the piece carrousel
|
||||
m_pieceCarrousel->SelectPiece(piece);
|
||||
|
||||
// update the Layout
|
||||
|
||||
// TODO
|
||||
m_selectedPieces = m_layout->GetSelectedPieces();
|
||||
|
||||
// update the property of the piece currently selected
|
||||
SetPropertyTabCurrentPieceData();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::on_PiecePositionChanged()
|
||||
{
|
||||
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
VPuzzlePiece *piece = m_selectedPieces.first();
|
||||
QPointF pos = piece->GetPosition();
|
||||
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceBoxPositionX, UnitConvertor(pos.x(), Unit::Px, m_layout->GetUnit()));
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceBoxPositionY, UnitConvertor(pos.y(), Unit::Px, m_layout->GetUnit()));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void PuzzleMainWindow::on_PieceRotationChanged()
|
||||
{
|
||||
if(m_selectedPieces.count() == 1)
|
||||
{
|
||||
VPuzzlePiece *piece = m_selectedPieces.first();
|
||||
qreal angle = piece->GetRotation();
|
||||
|
||||
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "../vmisc/def.h"
|
||||
#include "vpiececarrousel.h"
|
||||
#include "vpuzzlemaingraphicsview.h"
|
||||
#include "vpuzzlelayout.h"
|
||||
#include "vpuzzlepiece.h"
|
||||
#include "../vlayout/vlayoutpiece.h"
|
||||
|
@ -86,12 +87,14 @@ protected:
|
|||
private:
|
||||
Q_DISABLE_COPY(PuzzleMainWindow)
|
||||
Ui::PuzzleMainWindow *ui;
|
||||
|
||||
VPieceCarrousel *m_pieceCarrousel{nullptr};
|
||||
VPuzzleMainGraphicsView *m_graphicsView{nullptr};
|
||||
|
||||
VPuzzleCommandLinePtr m_cmd;
|
||||
|
||||
VPuzzleLayout *m_layout{nullptr};
|
||||
|
||||
VPuzzlePiece *m_selectedPiece{nullptr};
|
||||
QList<VPuzzlePiece *>m_selectedPieces{QList<VPuzzlePiece *>()};
|
||||
|
||||
/**
|
||||
* @brief CreatePiece creates a piece from the given VLayoutPiece data
|
||||
|
@ -134,6 +137,10 @@ private:
|
|||
*/
|
||||
void InitPieceCarrousel();
|
||||
|
||||
/**
|
||||
* @brief InitMainGraphics Initialises the puzzle main graphics
|
||||
*/
|
||||
void InitMainGraphics();
|
||||
|
||||
/**
|
||||
* @brief SetPropertiesData Sets the values of UI elements
|
||||
|
@ -347,7 +354,7 @@ private slots:
|
|||
* @brief on_CurrentPiecePositionChanged When the positionX or the positionY
|
||||
* is changed in the current piece tab
|
||||
*/
|
||||
void on_CurrentPiecePositionChanged();
|
||||
void on_CurrentPiecePositionEdited();
|
||||
|
||||
/**
|
||||
* @brief PieceCarrouselLocationChanged When the piece carrousel's location
|
||||
|
@ -357,10 +364,19 @@ private slots:
|
|||
void on_PieceCarrouselLocationChanged(Qt::DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* @brief on_PieceSelected When a piece has been selected
|
||||
* @param piece the piece that was selected
|
||||
* @brief on_PieceSelectionChanged When the piece selection has changed
|
||||
*/
|
||||
void on_PieceSelected(VPuzzlePiece* piece);
|
||||
void on_PieceSelectionChanged();
|
||||
|
||||
/**
|
||||
* @brief on_PiecePositionChanged When the current piece position has changed
|
||||
*/
|
||||
void on_PiecePositionChanged();
|
||||
|
||||
/**
|
||||
* @brief on_PieceRotationChanged When the current piece rotation has changed
|
||||
*/
|
||||
void on_PieceRotationChanged();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="graphicsView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
|
@ -233,7 +230,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>342</width>
|
||||
<height>894</height>
|
||||
<height>1318</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
|
@ -253,31 +250,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="containerCurrentPieceNoData" native="true">
|
||||
<layout class="QVBoxLayout" name="containerCurrentPieceNoDataLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelCurrentPieceNoPieceSelected">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No piece selected</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="containerCurrentPieceData" native="true">
|
||||
<layout class="QVBoxLayout" name="containerCurrentPieceDataLayout">
|
||||
|
@ -361,7 +333,7 @@
|
|||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -383,6 +355,9 @@
|
|||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxCurrentPieceBoxPositionX">
|
||||
<property name="minimum">
|
||||
<double>-10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000.000000000000000</double>
|
||||
</property>
|
||||
|
@ -400,6 +375,9 @@
|
|||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxCurrentPieceBoxPositionY">
|
||||
<property name="minimum">
|
||||
<double>-10000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000.000000000000000</double>
|
||||
</property>
|
||||
|
@ -414,6 +392,53 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="containerCurrentPieceNoData" native="true">
|
||||
<layout class="QVBoxLayout" name="containerCurrentPieceNoDataLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelCurrentPieceNoPieceSelected">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>No piece selected</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="containerCurrentPieceMultipleData" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelCurrentPieceMultiplePieceSelected">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Multiple pieces selected</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacerCurrentPiece">
|
||||
<property name="orientation">
|
||||
|
@ -1096,7 +1121,6 @@
|
|||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>graphicsView</tabstop>
|
||||
<tabstop>scrollAreaLayout</tabstop>
|
||||
<tabstop>doubleSpinBoxLayoutMarginTop</tabstop>
|
||||
<tabstop>doubleSpinBoxLayoutMarginLeft</tabstop>
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
<file>puzzleicon/64x64/iconPortrait.png</file>
|
||||
<file>puzzleicon/64x64/iconGrainlineVertical.png</file>
|
||||
<file>puzzleicon/64x64/iconGrainlineHorizontal.png</file>
|
||||
<file alias="cursor_rotate">puzzleicon/64x64/cursorRotate.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate.png
Normal file
BIN
src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 33.866666 33.866668"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
sodipodi:docname="icon_rotate.svg"
|
||||
inkscape:export-filename="/home/ronan/Desktop/iconRotate.png"
|
||||
inkscape:export-xdpi="48"
|
||||
inkscape:export-ydpi="48"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="-73.50406"
|
||||
inkscape:cy="-5.7476577"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1487"
|
||||
inkscape:window-height="906"
|
||||
inkscape:window-x="648"
|
||||
inkscape:window-y="365"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-263.13332)">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:0.99622641;stroke:#000000;stroke-width:0.56587124;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 7.0186194,287.41283 -6.32117702,-9.61886 4.59283552,0.0718 c 0.2260142,-13.99266 14.6277861,-19.32352 24.6168741,-9.04316 8.326613,8.56942 1.645094,23.6663 -11.704329,23.56294 l -0.02016,4.07882 -9.3161816,-5.90315 9.3649386,-5.23047 -0.0097,3.75053 c 12.855101,-0.23223 15.657569,-13.03558 9.321879,-19.01152 -6.380838,-6.01853 -18.7084318,-6.45152 -19.0255146,7.87916 l 4.6551916,0.099 z"
|
||||
id="path873"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccscccccsccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
|
@ -28,11 +28,11 @@
|
|||
#include "vpiececarrousel.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "../vmisc/backport/qoverload.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QScrollBar>
|
||||
|
||||
Q_LOGGING_CATEGORY(pCarrousel, "p.carrousel")
|
||||
|
||||
|
@ -75,8 +75,10 @@ void VPieceCarrousel::Init()
|
|||
QVBoxLayout *layersContainerLayout = new QVBoxLayout();
|
||||
layersContainerLayout->setMargin(0);
|
||||
m_layersContainer->setLayout(layersContainerLayout);
|
||||
m_layersContainer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
QSpacerItem *spacer = new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
|
||||
layersContainerWrapperLayout->addWidget(m_layersContainer);
|
||||
layersContainerWrapperLayout->addSpacerItem(spacer);
|
||||
|
||||
|
@ -92,10 +94,7 @@ void VPieceCarrousel::Init()
|
|||
|
||||
// ------ then we fill the carrousel with the layout content
|
||||
Refresh();
|
||||
|
||||
// ------ and make sure the calculation for the qlayout is right
|
||||
SetOrientation(Qt::Vertical);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrousel::Refresh()
|
||||
|
@ -119,13 +118,11 @@ void VPieceCarrousel::Refresh()
|
|||
VPieceCarrouselLayer *carrouselLayer = new VPieceCarrouselLayer(layer, this);
|
||||
m_carrouselLayers.append(carrouselLayer);
|
||||
m_layersContainer->layout()->addWidget(carrouselLayer);
|
||||
|
||||
connect(carrouselLayer, QOverload<VPieceCarrouselPiece*>::of(&VPieceCarrouselLayer::pieceClicked), this,
|
||||
&VPieceCarrousel::on_PieceClicked);
|
||||
|
||||
}
|
||||
|
||||
on_ActiveLayerChanged(0);
|
||||
|
||||
RefreshOrientation();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -159,20 +156,6 @@ void VPieceCarrousel::Clear()
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrousel::SelectPiece(VPuzzlePiece* piece)
|
||||
{
|
||||
for (auto layer : m_carrouselLayers)
|
||||
{
|
||||
QList<VPieceCarrouselPiece*> carrouselPieces = layer->GetCarrouselPieces();
|
||||
for (auto carrouselPiece : carrouselPieces)
|
||||
{
|
||||
carrouselPiece->SetIsSelected(carrouselPiece->GetPiece() == piece);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrousel::on_ActiveLayerChanged(int index)
|
||||
{
|
||||
|
@ -188,8 +171,14 @@ void VPieceCarrousel::on_ActiveLayerChanged(int index)
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrousel::SetOrientation(Qt::Orientation orientation)
|
||||
{
|
||||
m_orientation = orientation;
|
||||
RefreshOrientation();
|
||||
}
|
||||
|
||||
QBoxLayout::Direction direction = (orientation == Qt::Horizontal)?
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrousel::RefreshOrientation()
|
||||
{
|
||||
QBoxLayout::Direction direction = (m_orientation == Qt::Horizontal)?
|
||||
QBoxLayout::LeftToRight
|
||||
:
|
||||
QBoxLayout::TopToBottom;
|
||||
|
@ -207,7 +196,7 @@ void VPieceCarrousel::SetOrientation(Qt::Orientation orientation)
|
|||
}
|
||||
|
||||
// then update the scrollarea min height / width and scrollbar behaviour
|
||||
if(orientation == Qt::Horizontal)
|
||||
if(m_orientation == Qt::Horizontal)
|
||||
{
|
||||
m_comboBoxLayer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
|
@ -223,7 +212,6 @@ void VPieceCarrousel::SetOrientation(Qt::Orientation orientation)
|
|||
{
|
||||
m_comboBoxLayer->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
|
||||
// scroll bar policy of scroll area
|
||||
m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
@ -232,13 +220,10 @@ void VPieceCarrousel::SetOrientation(Qt::Orientation orientation)
|
|||
m_scrollArea->setMinimumWidth(124 + m_scrollArea->verticalScrollBar()->sizeHint().width()+2);
|
||||
// FIXME: find a nicer way than putting directly the 120 width of the piece
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrousel::on_PieceClicked(VPieceCarrouselPiece* carrouselPiece)
|
||||
void VPieceCarrousel::ClearSelection()
|
||||
{
|
||||
emit pieceClicked(carrouselPiece->GetPiece());
|
||||
m_layout->ClearSelection();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,8 +43,19 @@ public:
|
|||
explicit VPieceCarrousel(VPuzzleLayout *layout, QWidget *parent = nullptr);
|
||||
virtual ~VPieceCarrousel();
|
||||
|
||||
/**
|
||||
* @brief SetOrientation Sets the orientation to the given value and refreshes
|
||||
* the orientation of the carrousel.
|
||||
* @param orientation the orientation to set the carrousel to.
|
||||
*/
|
||||
void SetOrientation(Qt::Orientation orientation);
|
||||
|
||||
/**
|
||||
* @brief RefreshOrientation Refreshes the orientation of the carrousel with the
|
||||
* m_orientation value;
|
||||
*/
|
||||
void RefreshOrientation();
|
||||
|
||||
/**
|
||||
* @brief Inits the carroussel
|
||||
*/
|
||||
|
@ -61,18 +72,9 @@ public:
|
|||
void Clear();
|
||||
|
||||
/**
|
||||
* @brief SelectPiece Updates the carrousel so that the given piece is selected
|
||||
* @param piece the piece to select
|
||||
* @brief ClearSelection Clears the selection of the carrousel.
|
||||
*/
|
||||
void SelectPiece(VPuzzlePiece* piece);
|
||||
|
||||
|
||||
signals:
|
||||
void pieceClicked(VPuzzlePiece* piece);
|
||||
|
||||
public slots:
|
||||
void on_PieceClicked(VPieceCarrouselPiece* carrouselPiece);
|
||||
|
||||
void ClearSelection();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPieceCarrousel)
|
||||
|
@ -85,8 +87,15 @@ private:
|
|||
|
||||
QList<VPieceCarrouselLayer*> m_carrouselLayers;
|
||||
|
||||
Qt::Orientation m_orientation{Qt::Vertical};
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
/**
|
||||
* @brief on_ActiveLayerChanged Called when the active layer is changed
|
||||
* @param index
|
||||
*/
|
||||
void on_ActiveLayerChanged(int index);
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vpiececarrousellayer.h"
|
||||
#include "vpiececarrousel.h"
|
||||
#include "../vmisc/backport/qoverload.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
@ -36,9 +37,9 @@
|
|||
Q_LOGGING_CATEGORY(pCarrouselLayer, "p.carrouselLayer")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceCarrouselLayer::VPieceCarrouselLayer(VPuzzleLayer *layer, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
VPieceCarrouselLayer::VPieceCarrouselLayer(VPuzzleLayer *layer, VPieceCarrousel *carrousel) :
|
||||
m_layer(layer),
|
||||
m_carrousel(carrousel),
|
||||
m_carrouselPieces(QList<VPieceCarrouselPiece*>())
|
||||
{
|
||||
Init();
|
||||
|
@ -47,7 +48,7 @@ VPieceCarrouselLayer::VPieceCarrouselLayer(VPuzzleLayer *layer, QWidget *parent)
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceCarrouselLayer::~VPieceCarrouselLayer()
|
||||
{
|
||||
// TODO
|
||||
Clear();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -60,13 +61,16 @@ void VPieceCarrouselLayer::Init()
|
|||
|
||||
// then refresh the content
|
||||
Refresh();
|
||||
|
||||
// add the connections
|
||||
connect(m_layer, &VPuzzleLayer::PieceAdded, this, &VPieceCarrouselLayer::on_PieceAdded);
|
||||
connect(m_layer, &VPuzzleLayer::PieceRemoved, this, &VPieceCarrouselLayer::on_PieceRemoved);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselLayer::Refresh()
|
||||
{
|
||||
// remove the existing carrousel pieces
|
||||
// TODO
|
||||
Clear();
|
||||
|
||||
// Updates the carrousel pieces from the pieces list
|
||||
QList<VPuzzlePiece*> pieces = m_layer->GetPieces();
|
||||
|
@ -77,24 +81,33 @@ void VPieceCarrouselLayer::Refresh()
|
|||
|
||||
// create the corresponding carrousel pieces
|
||||
|
||||
bool _isVisible = isVisible();
|
||||
setVisible(true);
|
||||
for (auto piece : pieces)
|
||||
{
|
||||
// qCDebug(pCarrouselLayer, "piece name : %s", piece->GetName().toStdString().c_str());
|
||||
|
||||
VPieceCarrouselPiece *carrouselPiece = new VPieceCarrouselPiece(piece);
|
||||
VPieceCarrouselPiece *carrouselPiece = new VPieceCarrouselPiece(piece, this);
|
||||
m_carrouselPieces.append(carrouselPiece);
|
||||
layout()->addWidget(carrouselPiece);
|
||||
|
||||
// FIXME? the fitInView inside the refresh of the piece doesn't workd properly.
|
||||
// only by doing the following I did get it to work:
|
||||
setVisible(true);
|
||||
carrouselPiece->CleanPreview();
|
||||
setVisible(false);
|
||||
|
||||
connect(carrouselPiece, QOverload<VPieceCarrouselPiece*>::of(&VPieceCarrouselPiece::clicked), this,
|
||||
&VPieceCarrouselLayer::on_PieceClicked);
|
||||
|
||||
carrouselPiece->CleanPreview(); // fitInView only works if the widget is displayed.
|
||||
}
|
||||
setVisible(_isVisible);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselLayer::Clear()
|
||||
{
|
||||
// Removes and deletes the carrousel pieces from the layer
|
||||
while (!m_carrouselPieces.isEmpty())
|
||||
{
|
||||
VPieceCarrouselPiece *carrouselPiece = m_carrouselPieces.takeLast();
|
||||
|
||||
if(carrouselPiece != nullptr)
|
||||
{
|
||||
layout()->removeWidget(carrouselPiece);
|
||||
delete carrouselPiece;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -104,7 +117,39 @@ QList<VPieceCarrouselPiece*> VPieceCarrouselLayer::GetCarrouselPieces()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselLayer::on_PieceClicked(VPieceCarrouselPiece* carrouselPiece)
|
||||
VPieceCarrousel* VPieceCarrouselLayer::GetCarrousel()
|
||||
{
|
||||
emit pieceClicked(carrouselPiece);
|
||||
return m_carrousel;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleLayer* VPieceCarrouselLayer::GetLayer()
|
||||
{
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselLayer::on_PieceAdded(VPuzzlePiece* piece)
|
||||
{
|
||||
Q_UNUSED(piece)
|
||||
|
||||
// TODO/ FIXME: see if we find a solution more efficient refreshing the complete layout everytime.
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselLayer::on_PieceRemoved(VPuzzlePiece* piece)
|
||||
{
|
||||
for (auto carrouselPiece : m_carrouselPieces)
|
||||
{
|
||||
if(carrouselPiece->GetPiece() == piece)
|
||||
{
|
||||
m_carrouselPieces.removeAll(carrouselPiece);
|
||||
layout()->removeWidget(carrouselPiece);
|
||||
delete carrouselPiece;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,32 +33,52 @@
|
|||
#include "vpuzzlelayer.h"
|
||||
#include "vpiececarrouselpiece.h"
|
||||
|
||||
class VPieceCarrousel;
|
||||
|
||||
class VPieceCarrouselLayer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPieceCarrouselLayer(VPuzzleLayer *layer, QWidget *parent = nullptr);
|
||||
VPieceCarrouselLayer(VPuzzleLayer *layer, VPieceCarrousel *carrousel);
|
||||
~VPieceCarrouselLayer();
|
||||
|
||||
void Init();
|
||||
void Refresh();
|
||||
|
||||
/**
|
||||
* @brief Clear it clears the carrousel layer from its pieces
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
QList<VPieceCarrouselPiece*> GetCarrouselPieces();
|
||||
|
||||
signals:
|
||||
void pieceClicked(VPieceCarrouselPiece* carrouselPiece);
|
||||
VPieceCarrousel* GetCarrousel();
|
||||
|
||||
public slots:
|
||||
void on_PieceClicked(VPieceCarrouselPiece* carrouselPiece);
|
||||
/**
|
||||
* @brief GetPuzzleLayer Returns the corresponding VPuzzleLayer
|
||||
* @return the VPuzzleLayer
|
||||
*/
|
||||
VPuzzleLayer* GetLayer();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPieceCarrouselLayer)
|
||||
|
||||
VPuzzleLayer *m_layer;
|
||||
VPieceCarrousel *m_carrousel;
|
||||
QList<VPieceCarrouselPiece*> m_carrouselPieces;
|
||||
|
||||
private slots:
|
||||
|
||||
/**
|
||||
* @brief on_PieceUpdated This slot is called when a piece was added
|
||||
*/
|
||||
void on_PieceAdded(VPuzzlePiece* piece);
|
||||
|
||||
/**
|
||||
* @brief on_PieceUpdated This slot is called when a piece was removed
|
||||
*/
|
||||
void on_PieceRemoved(VPuzzlePiece* piece);
|
||||
|
||||
};
|
||||
|
||||
#endif // VPIECECARROUSELLAYER_H
|
||||
|
|
|
@ -27,19 +27,30 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vpiececarrouselpiece.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QDrag>
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
|
||||
#include "vpuzzlemimedatapiece.h"
|
||||
#include "vpiececarrousellayer.h"
|
||||
#include "vpiececarrousel.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(pCarrouselPiece, "p.carrouselPiece")
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceCarrouselPiece::VPieceCarrouselPiece(VPuzzlePiece *piece, QWidget *parent) :
|
||||
QFrame(parent),
|
||||
m_piece(piece)
|
||||
VPieceCarrouselPiece::VPieceCarrouselPiece(VPuzzlePiece *piece, VPieceCarrouselLayer *carrouselLayer) :
|
||||
m_piece(piece),
|
||||
m_carrouselLayer(carrouselLayer),
|
||||
m_dragStart(QPoint())
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
@ -48,7 +59,7 @@ VPieceCarrouselPiece::VPieceCarrouselPiece(VPuzzlePiece *piece, QWidget *parent)
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceCarrouselPiece::~VPieceCarrouselPiece()
|
||||
{
|
||||
delete m_graphicsView;
|
||||
delete m_piecePreview;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -64,14 +75,15 @@ void VPieceCarrouselPiece::Init()
|
|||
setStyleSheet("background-color:white; border: 2px solid transparent;");
|
||||
|
||||
// define the preview of the piece
|
||||
m_graphicsView = new QGraphicsView(this);
|
||||
m_piecePreview = new VPieceCarrouselPiecePreview(this);
|
||||
|
||||
// m_graphicsView = new VMainGraphicsView(this);
|
||||
// --> undefined reference to 'VMainGraphicsView::VMainGraphicView(QWidget*)'
|
||||
QGraphicsScene *graphicsScene = new QGraphicsScene(this);
|
||||
m_graphicsView->setScene(graphicsScene);
|
||||
m_graphicsView->setFixedSize(120,100);
|
||||
m_graphicsView->setStyleSheet("border: 4px solid transparent;");
|
||||
m_piecePreview->setScene(graphicsScene);
|
||||
m_piecePreview->setFixedSize(120,100);
|
||||
m_piecePreview->setStyleSheet("border: 4px solid transparent;");
|
||||
m_piecePreview->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
// define the label
|
||||
m_label = new QLabel();
|
||||
|
@ -79,10 +91,15 @@ void VPieceCarrouselPiece::Init()
|
|||
m_label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
|
||||
m_label->setFixedSize(120,24);
|
||||
m_label->setStyleSheet("border: 0px;");
|
||||
m_label->setMouseTracking(false);
|
||||
|
||||
pieceLayout->addWidget(m_graphicsView);
|
||||
pieceLayout->addWidget(m_piecePreview);
|
||||
pieceLayout->addWidget(m_label);
|
||||
|
||||
|
||||
// connect the signals
|
||||
connect(m_piece, &VPuzzlePiece::SelectionChanged, this, &VPieceCarrouselPiece::on_PieceSelectionChanged);
|
||||
|
||||
// then refresh the data
|
||||
Refresh();
|
||||
}
|
||||
|
@ -90,7 +107,7 @@ void VPieceCarrouselPiece::Init()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiece::CleanPreview()
|
||||
{
|
||||
m_graphicsView->fitInView(m_graphicsView->scene()->sceneRect(), Qt::KeepAspectRatio);
|
||||
m_piecePreview->fitInView(m_piecePreview->scene()->sceneRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -98,9 +115,11 @@ void VPieceCarrouselPiece::Refresh()
|
|||
{
|
||||
// update the graphic view / the scene
|
||||
|
||||
// TODO / FIXME : not perfect and maybe not the right way, still need to work on this
|
||||
// for instance: use a painter to habve a better quality, less pixeled.
|
||||
QVector<QPointF> points = m_piece->GetCuttingLine();
|
||||
QVector<QPointF> points = m_piece->GetSeamLine();
|
||||
if(points.isEmpty())
|
||||
{
|
||||
points = m_piece->GetCuttingLine();
|
||||
}
|
||||
|
||||
QPen pen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
pen.setCosmetic(true);
|
||||
|
@ -110,9 +129,9 @@ void VPieceCarrouselPiece::Refresh()
|
|||
path.moveTo(points.first());
|
||||
for (int i = 1; i < points.size(); ++i)
|
||||
path.lineTo(points.at(i));
|
||||
m_graphicsView->scene()->addPath(path, pen, noBrush);
|
||||
m_piecePreview->scene()->addPath(path, pen, noBrush);
|
||||
|
||||
m_graphicsView->fitInView(m_graphicsView->scene()->sceneRect(), Qt::KeepAspectRatio);
|
||||
m_piecePreview->fitInView(m_piecePreview->scene()->sceneRect(), Qt::KeepAspectRatio);
|
||||
|
||||
// update the label of the piece
|
||||
QFontMetrics metrix(m_label->font());
|
||||
|
@ -122,6 +141,9 @@ void VPieceCarrouselPiece::Refresh()
|
|||
|
||||
// set the tooltip
|
||||
setToolTip(m_piece->GetName());
|
||||
|
||||
// set the selection state correctly.
|
||||
on_PieceSelectionChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -131,11 +153,9 @@ VPuzzlePiece * VPieceCarrouselPiece::GetPiece()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiece::SetIsSelected(bool value)
|
||||
void VPieceCarrouselPiece::on_PieceSelectionChanged()
|
||||
{
|
||||
m_isSelected = value;
|
||||
|
||||
if(value)
|
||||
if(m_piece->GetIsSelected())
|
||||
{
|
||||
setStyleSheet("background-color:white; border: 2px solid red;");
|
||||
}
|
||||
|
@ -145,21 +165,121 @@ void VPieceCarrouselPiece::SetIsSelected(bool value)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPieceCarrouselPiece::GetIsSelected()
|
||||
{
|
||||
return m_isSelected;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiece::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
qCDebug(pCarrouselPiece, "mouse pressed");
|
||||
|
||||
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
if(!m_isSelected)
|
||||
if(!(event->modifiers() & Qt::ControlModifier))
|
||||
{
|
||||
emit clicked(this);
|
||||
m_carrouselLayer->GetCarrousel()->ClearSelection();
|
||||
m_piece->SetIsSelected(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_piece->SetIsSelected(!m_piece->GetIsSelected());
|
||||
}
|
||||
|
||||
m_dragStart = event->pos();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiece::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_piece->GetLayer() != m_piece->GetLayer()->GetLayout()->GetUnplacedPiecesLayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if((event->pos() - m_dragStart).manhattanLength() < QApplication::startDragDistance())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure the multiple selection is removed
|
||||
m_carrouselLayer->GetCarrousel()->ClearSelection();
|
||||
m_piece->SetIsSelected(true);
|
||||
|
||||
// starts the dragging
|
||||
QDrag *drag = new QDrag(this);
|
||||
VPuzzleMimeDataPiece *mimeData = new VPuzzleMimeDataPiece();
|
||||
mimeData->SetPiecePtr(m_piece);
|
||||
mimeData->setObjectName("piecePointer");
|
||||
|
||||
// in case we would want to have the pieces original size:
|
||||
//drag->setHotSpot(QPoint(0,0));
|
||||
//QPixmap pixmap(m_piecePreview->sceneRect().size().toSize());
|
||||
|
||||
QPixmap pixmap(112,92);
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
m_piecePreview->scene()->render(&painter);
|
||||
|
||||
drag->setPixmap(pixmap);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiece::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
QMenu contextMenu;
|
||||
|
||||
VPuzzleLayer* unplacedLayer = m_piece->GetLayer()->GetLayout()->GetUnplacedPiecesLayer();
|
||||
QList<VPuzzleLayer*> layers = m_piece->GetLayer()->GetLayout()->GetLayers();
|
||||
|
||||
// move to layer actions -- TODO : To be tested properly when we have several layers
|
||||
layers.removeAll(m_piece->GetLayer());
|
||||
if(layers.count() > 0)
|
||||
{
|
||||
QMenu *moveMenu = contextMenu.addMenu(tr("Move to"));
|
||||
|
||||
// TODO order in alphabetical order
|
||||
|
||||
for (auto layer : layers)
|
||||
{
|
||||
QAction* moveToLayer = moveMenu->addAction(layer->GetName());
|
||||
QVariant data = QVariant::fromValue(layer);
|
||||
moveToLayer->setData(data);
|
||||
|
||||
connect(moveToLayer, &QAction::triggered, this, &VPieceCarrouselPiece::on_ActionPieceMovedToLayer);
|
||||
}
|
||||
}
|
||||
|
||||
// remove from layout action
|
||||
if(m_piece->GetLayer() != unplacedLayer)
|
||||
{
|
||||
QAction *removeAction = contextMenu.addAction(tr("Remove from Layout"));
|
||||
QVariant data = QVariant::fromValue(m_piece->GetLayer()->GetLayout()->GetUnplacedPiecesLayer());
|
||||
removeAction->setData(data);
|
||||
connect(removeAction, &QAction::triggered, this, &VPieceCarrouselPiece::on_ActionPieceMovedToLayer);
|
||||
}
|
||||
|
||||
contextMenu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiece::on_ActionPieceMovedToLayer()
|
||||
{
|
||||
QAction *act = qobject_cast<QAction *>(sender());
|
||||
QVariant v = act->data();
|
||||
VPuzzleLayer *layer = (VPuzzleLayer *) v.value<VPuzzleLayer *>();
|
||||
if(layer != nullptr)
|
||||
{
|
||||
layer->GetLayout()->MovePieceToLayer(m_piece, layer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,13 +34,16 @@
|
|||
#include <QMouseEvent>
|
||||
|
||||
#include "vpuzzlepiece.h"
|
||||
#include "vpiececarrouselpiecepreview.h"
|
||||
|
||||
|
||||
class VPieceCarrouselLayer;
|
||||
|
||||
class VPieceCarrouselPiece : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VPieceCarrouselPiece(VPuzzlePiece *piece, QWidget *parent = nullptr);
|
||||
explicit VPieceCarrouselPiece(VPuzzlePiece *piece, VPieceCarrouselLayer *carrouselLayer);
|
||||
~VPieceCarrouselPiece();
|
||||
|
||||
void Init();
|
||||
|
@ -57,34 +60,34 @@ public:
|
|||
*/
|
||||
VPuzzlePiece * GetPiece();
|
||||
|
||||
/**
|
||||
* @brief SetSelected sets the selected state to the given value
|
||||
* @param value the new selected state
|
||||
*/
|
||||
void SetIsSelected(bool value);
|
||||
|
||||
/**
|
||||
* @brief GetSelected Returns wether the piece is selected or not
|
||||
* @return true if the piece is selected
|
||||
*/
|
||||
bool GetIsSelected();
|
||||
|
||||
signals:
|
||||
void clicked(VPieceCarrouselPiece* m_piece);
|
||||
|
||||
public slots:
|
||||
void on_PieceSelectionChanged();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief on_ActionPieceMovedToLayer Slot called when the piece is moved via the
|
||||
* context menu to anoter layer
|
||||
*/
|
||||
void on_ActionPieceMovedToLayer();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPieceCarrouselPiece)
|
||||
|
||||
VPuzzlePiece *m_piece;
|
||||
QLabel *m_label{nullptr};
|
||||
QGraphicsView *m_graphicsView{nullptr};
|
||||
|
||||
bool m_isSelected = false;
|
||||
VPieceCarrouselLayer *m_carrouselLayer;
|
||||
|
||||
QLabel *m_label{nullptr};
|
||||
VPieceCarrouselPiecePreview *m_piecePreview{nullptr};
|
||||
|
||||
QPoint m_dragStart;
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
55
src/app/puzzle/vpiececarrouselpiecepreview.cpp
Normal file
55
src/app/puzzle/vpiececarrouselpiecepreview.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpiececarrouselpiecepreview.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 "vpiececarrouselpiecepreview.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceCarrouselPiecePreview::VPieceCarrouselPiecePreview(QWidget *parent):
|
||||
QGraphicsView(parent)
|
||||
{
|
||||
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceCarrouselPiecePreview::~VPieceCarrouselPiecePreview()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiecePreview::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceCarrouselPiecePreview::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
|
45
src/app/puzzle/vpiececarrouselpiecepreview.h
Normal file
45
src/app/puzzle/vpiececarrouselpiecepreview.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpiececarrouselpiecepreview.h
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 VPUZZLEPIECECARROUSELPIECEPREVIEW_H
|
||||
#define VPUZZLEPIECECARROUSELPIECEPREVIEW_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
|
||||
class VPieceCarrouselPiecePreview: public QGraphicsView
|
||||
{
|
||||
public:
|
||||
VPieceCarrouselPiecePreview(QWidget *parent = nullptr);
|
||||
~VPieceCarrouselPiecePreview();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
};
|
||||
|
||||
#endif // VPUZZLEPIECECARROUSELPIECEPREVIEW_H
|
92
src/app/puzzle/vpuzzlegraphicslayout.cpp
Normal file
92
src/app/puzzle/vpuzzlegraphicslayout.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlegraphicslayout.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 "vpuzzlegraphicslayout.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleGraphicsLayout::VPuzzleGraphicsLayout(VPuzzleLayout *layout, QGraphicsItem *parent):
|
||||
QGraphicsItem(parent),
|
||||
m_layout(layout),
|
||||
m_boundingRect(GetLayoutRect())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleGraphicsLayout::~VPuzzleGraphicsLayout()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsLayout::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(option);
|
||||
|
||||
QPen pen(QColor(0,179,255), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
pen.setCosmetic(true);
|
||||
QBrush noBrush(Qt::NoBrush);
|
||||
painter->setPen(pen);
|
||||
painter->setBrush(noBrush);
|
||||
|
||||
painter->drawRect(GetMarginsRect());
|
||||
|
||||
pen.setColor(Qt::black);
|
||||
|
||||
painter->setPen(pen);
|
||||
painter->drawRect(GetLayoutRect());
|
||||
|
||||
m_boundingRect = GetLayoutRect();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPuzzleGraphicsLayout::GetLayoutRect() const
|
||||
{
|
||||
QRectF rect = QRectF(QPointF(0,0), m_layout->GetLayoutSize());
|
||||
return rect;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPuzzleGraphicsLayout::GetMarginsRect() const
|
||||
{
|
||||
QMarginsF margins = m_layout->GetLayoutMargins();
|
||||
QSizeF size = m_layout->GetLayoutSize();
|
||||
QRectF rect = QRectF(
|
||||
QPointF(margins.left(),margins.top()),
|
||||
QPointF(size.width()-margins.right(), size.height()-margins.bottom())
|
||||
);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPuzzleGraphicsLayout::boundingRect() const
|
||||
{
|
||||
return m_boundingRect;
|
||||
}
|
58
src/app/puzzle/vpuzzlegraphicslayout.h
Normal file
58
src/app/puzzle/vpuzzlegraphicslayout.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlegraphicslayout.h
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 VPUZZLEGRAPHICSLAYOUT_H
|
||||
#define VPUZZLEGRAPHICSLAYOUT_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QPainter>
|
||||
|
||||
#include "vpuzzlelayout.h"
|
||||
|
||||
class VPuzzleGraphicsLayout : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
VPuzzleGraphicsLayout(VPuzzleLayout *layout, QGraphicsItem *parent = nullptr);
|
||||
~VPuzzleGraphicsLayout();
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) override;
|
||||
|
||||
|
||||
QRectF GetLayoutRect() const;
|
||||
QRectF GetMarginsRect() const;
|
||||
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPuzzleGraphicsLayout)
|
||||
|
||||
VPuzzleLayout *m_layout{nullptr};
|
||||
QRectF m_boundingRect;
|
||||
};
|
||||
|
||||
#endif // VPUZZLEGRAPHICSLAYOUT_H
|
376
src/app/puzzle/vpuzzlegraphicspiece.cpp
Normal file
376
src/app/puzzle/vpuzzlegraphicspiece.cpp
Normal file
|
@ -0,0 +1,376 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlegraphicspiece.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 4 5, 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 "vpuzzlegraphicspiece.h"
|
||||
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
#include <QPainter>
|
||||
#include <QCursor>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
#include <QGraphicsSceneContextMenuEvent>
|
||||
#include <QMenu>
|
||||
#include <QtMath>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
#include "vpuzzlepiece.h"
|
||||
#include "vpuzzlelayer.h"
|
||||
#include "vpuzzlelayout.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleGraphicsPiece::VPuzzleGraphicsPiece(VPuzzlePiece *piece, QGraphicsItem *parent) :
|
||||
QGraphicsObject(parent),
|
||||
m_piece(piece),
|
||||
m_cuttingLine(QPainterPath()),
|
||||
m_seamLine(QPainterPath()),
|
||||
m_grainline(QPainterPath()),
|
||||
m_rotationStartPoint(QPointF())
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleGraphicsPiece::~VPuzzleGraphicsPiece()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::Init()
|
||||
{
|
||||
// set some infos
|
||||
setFlags(ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges);
|
||||
setAcceptHoverEvents(true);
|
||||
setCursor(QCursor(Qt::OpenHandCursor));
|
||||
|
||||
// initialises the seam line
|
||||
QVector<QPointF> seamLinePoints = m_piece->GetSeamLine();
|
||||
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->GetCuttingLine();
|
||||
m_cuttingLine.moveTo(cuttingLinepoints.first());
|
||||
for (int i = 1; i < cuttingLinepoints.size(); ++i)
|
||||
m_cuttingLine.lineTo(cuttingLinepoints.at(i));
|
||||
|
||||
// initialises the grainline
|
||||
QVector<QPointF> grainLinepoints = m_piece->GetGrainline();
|
||||
m_grainline.moveTo(grainLinepoints.first());
|
||||
for (int i = 1; i < grainLinepoints.size(); ++i)
|
||||
m_grainline.lineTo(grainLinepoints.at(i));
|
||||
|
||||
|
||||
// TODO : initialises the other elements labels, passmarks etc.
|
||||
|
||||
// Initialises the connectors
|
||||
connect(m_piece, &VPuzzlePiece::SelectionChanged, this, &VPuzzleGraphicsPiece::on_PieceSelectionChanged);
|
||||
connect(m_piece, &VPuzzlePiece::PositionChanged, this, &VPuzzleGraphicsPiece::on_PiecePositionChanged);
|
||||
connect(m_piece, &VPuzzlePiece::RotationChanged, this, &VPuzzleGraphicsPiece::on_PieceRotationChanged);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzlePiece* VPuzzleGraphicsPiece::GetPiece()
|
||||
{
|
||||
return m_piece;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QRectF VPuzzleGraphicsPiece::boundingRect() const
|
||||
{
|
||||
if(!m_cuttingLine.isEmpty())
|
||||
{
|
||||
return m_cuttingLine.boundingRect();
|
||||
}
|
||||
|
||||
return m_seamLine.boundingRect();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPuzzleGraphicsPiece::shape() const
|
||||
{
|
||||
if(!m_cuttingLine.isEmpty())
|
||||
{
|
||||
return m_cuttingLine;
|
||||
}
|
||||
|
||||
return m_seamLine;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
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));
|
||||
|
||||
painter->setPen(pen);
|
||||
|
||||
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())
|
||||
{
|
||||
painter->drawPath(m_seamLine);
|
||||
}
|
||||
|
||||
painter->setBrush(noBrush);
|
||||
|
||||
// paint the grainline
|
||||
if(!m_grainline.isEmpty())
|
||||
{
|
||||
painter->drawPath(m_grainline);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
bool selectionState = isSelected();
|
||||
//perform the default behaviour
|
||||
QGraphicsItem::mousePressEvent(event);
|
||||
|
||||
// change the cursor when clicking left button
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setSelected(true);
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
setSelected(!selectionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
if((event->button() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier))
|
||||
{
|
||||
m_rotationStartPoint = event->scenePos();
|
||||
|
||||
QPixmap cursor_pixmap = QPixmap(":/cursor_rotate");
|
||||
cursor_pixmap = cursor_pixmap.scaledToWidth(32);
|
||||
QCursor cursor_rotate = QCursor(cursor_pixmap, 16, 16);
|
||||
|
||||
setCursor(cursor_rotate);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
|
||||
{
|
||||
if((event->buttons() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier))
|
||||
{
|
||||
|
||||
QPointF rotationNewPoint = event->scenePos();
|
||||
QPointF rotationCenter = sceneBoundingRect().center();
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
bool selectionState = isSelected();
|
||||
|
||||
//perform the default behaviour
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
|
||||
// change the cursor when clicking left button
|
||||
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 VPuzzleGraphicsPiece::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
|
||||
if(event->modifiers() & Qt::AltModifier)
|
||||
{
|
||||
// TODO FIXME: find a more efficient way
|
||||
|
||||
QPixmap cursor_pixmap = QPixmap(":/cursor_rotate");
|
||||
cursor_pixmap = cursor_pixmap.scaledToWidth(32);
|
||||
QCursor cursor_rotate = QCursor(cursor_pixmap, 16, 16);
|
||||
|
||||
setCursor(cursor_rotate);
|
||||
}
|
||||
else
|
||||
{
|
||||
setCursor(QCursor(Qt::OpenHandCursor));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
||||
{
|
||||
QMenu contextMenu;
|
||||
|
||||
// move to layer actions -- TODO : To be tested properly when we have several layers
|
||||
QList<VPuzzleLayer*> layers = m_piece->GetLayer()->GetLayout()->GetLayers();
|
||||
layers.removeAll(m_piece->GetLayer());
|
||||
|
||||
if(layers.count() > 0)
|
||||
{
|
||||
QMenu *moveMenu = contextMenu.addMenu(tr("Move to"));
|
||||
|
||||
// TODO order in alphabetical order
|
||||
|
||||
for (auto layer : layers)
|
||||
{
|
||||
QAction* moveToLayer = moveMenu->addAction(layer->GetName());
|
||||
QVariant data = QVariant::fromValue(layer);
|
||||
moveToLayer->setData(data);
|
||||
|
||||
connect(moveToLayer, &QAction::triggered, this, &VPuzzleGraphicsPiece::on_ActionPieceMovedToLayer);
|
||||
}
|
||||
}
|
||||
|
||||
// remove from layout action
|
||||
QAction *removeAction = contextMenu.addAction(tr("Remove from Layout"));
|
||||
QVariant data = QVariant::fromValue(m_piece->GetLayer()->GetLayout()->GetUnplacedPiecesLayer());
|
||||
removeAction->setData(data);
|
||||
connect(removeAction, &QAction::triggered, this, &VPuzzleGraphicsPiece::on_ActionPieceMovedToLayer);
|
||||
|
||||
contextMenu.exec(event->screenPos());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::on_ActionPieceMovedToLayer()
|
||||
{
|
||||
QAction *act = qobject_cast<QAction *>(sender());
|
||||
QVariant v = act->data();
|
||||
VPuzzleLayer *layer = v.value<VPuzzleLayer *>();
|
||||
if(layer != nullptr)
|
||||
{
|
||||
layer->GetLayout()->MovePieceToLayer(m_piece, layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::on_PieceSelectionChanged()
|
||||
{
|
||||
setSelected(m_piece->GetIsSelected());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::on_PiecePositionChanged()
|
||||
{
|
||||
setPos(m_piece->GetPosition());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleGraphicsPiece::on_PieceRotationChanged()
|
||||
{
|
||||
setTransformOriginPoint(boundingRect().center());
|
||||
setRotation(-m_piece->GetRotation());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QVariant VPuzzleGraphicsPiece::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (scene()) {
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QGraphicsObject::itemChange(change, value);
|
||||
}
|
||||
|
100
src/app/puzzle/vpuzzlegraphicspiece.h
Normal file
100
src/app/puzzle/vpuzzlegraphicspiece.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlegraphicspiece.h
|
||||
** @author Ronan Le Tiec
|
||||
** @date 4 5, 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 VPUZZLEGRAPHICSPIECE_H
|
||||
#define VPUZZLEGRAPHICSPIECE_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
class VPuzzlePiece;
|
||||
|
||||
class VPuzzleGraphicsPiece : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPuzzleGraphicsPiece(VPuzzlePiece *piece, QGraphicsItem *parent = nullptr);
|
||||
~VPuzzleGraphicsPiece();
|
||||
void Init();
|
||||
|
||||
/**
|
||||
* @brief GetPiece Returns the piece that corresponds to the graphics piece
|
||||
* @return the piece
|
||||
*/
|
||||
VPuzzlePiece* GetPiece();
|
||||
|
||||
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();
|
||||
|
||||
protected:
|
||||
QRectF boundingRect() const override;
|
||||
QPainterPath shape() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) override;
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
|
||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief on_ActionPieceMovedToLayer Slot called when the piece is moved via the
|
||||
* context menu to anoter layer
|
||||
*/
|
||||
void on_ActionPieceMovedToLayer();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPuzzleGraphicsPiece)
|
||||
VPuzzlePiece *m_piece;
|
||||
|
||||
QPainterPath m_cuttingLine;
|
||||
QPainterPath m_seamLine;
|
||||
QPainterPath m_grainline;
|
||||
|
||||
QPointF m_rotationStartPoint;
|
||||
|
||||
};
|
||||
|
||||
#endif // VPUZZLEGRAPHICSPIECE_H
|
|
@ -27,8 +27,15 @@
|
|||
*************************************************************************/
|
||||
#include "vpuzzlelayer.h"
|
||||
|
||||
#include "vpuzzlelayout.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(pLayer, "p.layer")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleLayer::VPuzzleLayer()
|
||||
VPuzzleLayer::VPuzzleLayer(VPuzzleLayout *layout):
|
||||
m_layout(layout)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -39,22 +46,46 @@ VPuzzleLayer::~VPuzzleLayer()
|
|||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleLayout* VPuzzleLayer::GetLayout()
|
||||
{
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QList<VPuzzlePiece *> VPuzzleLayer::GetPieces()
|
||||
{
|
||||
return m_pieces;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleLayer::ClearSelection()
|
||||
{
|
||||
for (auto piece: m_pieces)
|
||||
{
|
||||
piece->SetIsSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleLayer::AddPiece(VPuzzlePiece *piece)
|
||||
{
|
||||
qCDebug(pLayer(), "piece -- %s -- added to %s", qUtf8Printable(piece->GetName()), qUtf8Printable(this->GetName()));
|
||||
|
||||
m_pieces.append(piece);
|
||||
piece->SetLayer(this);
|
||||
|
||||
emit PieceAdded(piece);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleLayer::RemovePiece(VPuzzlePiece *piece)
|
||||
{
|
||||
m_pieces.removeAll(piece);
|
||||
piece->SetLayer(nullptr);
|
||||
|
||||
emit PieceRemoved(piece);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -31,10 +31,13 @@
|
|||
#include <QList>
|
||||
#include "vpuzzlepiece.h"
|
||||
|
||||
class VPuzzleLayer
|
||||
class VPuzzleLayout;
|
||||
|
||||
class VPuzzleLayer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPuzzleLayer();
|
||||
VPuzzleLayer(VPuzzleLayout *layout);
|
||||
~VPuzzleLayer();
|
||||
|
||||
QList<VPuzzlePiece *> GetPieces();
|
||||
|
@ -50,10 +53,36 @@ public:
|
|||
void SetIsVisible(bool value);
|
||||
bool GetIsVisible() const;
|
||||
|
||||
/**
|
||||
* @brief GetLayout Returns the layout in which this layer is
|
||||
* @return the layout of this layer
|
||||
*/
|
||||
VPuzzleLayout* GetLayout();
|
||||
|
||||
/**
|
||||
* @brief ClearSelection Clears the selection of the pieces in this layer
|
||||
*/
|
||||
void ClearSelection();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief PieceAdded The signal is emited when a piece was added
|
||||
*/
|
||||
void PieceAdded(VPuzzlePiece *piece);
|
||||
|
||||
/**
|
||||
* @brief PieceRemoved The signal is emited when a piece was removed
|
||||
*/
|
||||
void PieceRemoved(VPuzzlePiece *piece);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPuzzleLayer)
|
||||
|
||||
QString m_name{};
|
||||
QList<VPuzzlePiece *> m_pieces{};
|
||||
|
||||
VPuzzleLayout *m_layout{nullptr};
|
||||
|
||||
// control
|
||||
bool m_isVisible{true};
|
||||
|
||||
|
|
|
@ -31,14 +31,17 @@
|
|||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleLayout::VPuzzleLayout() :
|
||||
m_unplacedPiecesLayer(new VPuzzleLayer())
|
||||
m_unplacedPiecesLayer(new VPuzzleLayer(this))
|
||||
{
|
||||
m_unplacedPiecesLayer->SetName(QObject::tr("Unplaced pieces"));
|
||||
|
||||
// create a standard default layer:
|
||||
VPuzzleLayer *layer = new VPuzzleLayer();
|
||||
VPuzzleLayer *layer = new VPuzzleLayer(this);
|
||||
layer->SetName(QObject::tr("Layout"));
|
||||
AddLayer(layer);
|
||||
|
||||
// sets the default active layer
|
||||
SetFocusedLayer();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -57,7 +60,7 @@ VPuzzleLayer* VPuzzleLayout::GetUnplacedPiecesLayer()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleLayer* VPuzzleLayout::AddLayer()
|
||||
{
|
||||
VPuzzleLayer *newLayer = new VPuzzleLayer();
|
||||
VPuzzleLayer *newLayer = new VPuzzleLayer(this);
|
||||
m_layers.append(newLayer);
|
||||
return newLayer;
|
||||
}
|
||||
|
@ -75,6 +78,29 @@ QList<VPuzzleLayer *> VPuzzleLayout::GetLayers()
|
|||
return m_layers;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QList<VPuzzlePiece *> VPuzzleLayout::GetSelectedPieces()
|
||||
{
|
||||
QList<VPuzzlePiece *> result = QList<VPuzzlePiece *>();
|
||||
|
||||
QList<VPuzzleLayer *> layers = m_layers;
|
||||
layers.prepend(m_unplacedPiecesLayer);
|
||||
|
||||
for (auto layer : layers)
|
||||
{
|
||||
for (auto piece : layer->GetPieces())
|
||||
{
|
||||
if(piece->GetIsSelected())
|
||||
{
|
||||
result.append(piece);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleLayout::SetUnit(Unit unit)
|
||||
{
|
||||
|
@ -245,3 +271,48 @@ bool VPuzzleLayout::GetStickyEdges() const
|
|||
{
|
||||
return m_stickyEdges;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleLayout::ClearSelection()
|
||||
{
|
||||
m_unplacedPiecesLayer->ClearSelection();
|
||||
|
||||
for (auto layer : m_layers)
|
||||
{
|
||||
layer->ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleLayout::SetFocusedLayer(VPuzzleLayer* focusedLayer)
|
||||
{
|
||||
if(focusedLayer == nullptr)
|
||||
{
|
||||
m_focusedLayer = m_layers.first();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_focusedLayer = focusedLayer;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleLayer* VPuzzleLayout::GetFocusedLayer()
|
||||
{
|
||||
return m_focusedLayer;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleLayout::MovePieceToLayer(VPuzzlePiece* piece, VPuzzleLayer* layer)
|
||||
{
|
||||
VPuzzleLayer* layerBefore = piece->GetLayer();
|
||||
|
||||
if(layerBefore != nullptr)
|
||||
{
|
||||
piece->GetLayer()->RemovePiece(piece);
|
||||
}
|
||||
layer->AddPiece(piece);
|
||||
|
||||
// signal, that a piece was moved
|
||||
emit PieceMovedToLayer(piece, layerBefore,layer);
|
||||
}
|
||||
|
|
|
@ -35,12 +35,14 @@
|
|||
#include "def.h"
|
||||
|
||||
class VPuzzleLayer;
|
||||
class VPuzzlePiece;
|
||||
|
||||
// is this the right place for the definition?
|
||||
enum class FollowGrainline : qint8 { No = 0, Follow90 = 1, Follow180 = 2};
|
||||
|
||||
class VPuzzleLayout
|
||||
class VPuzzleLayout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPuzzleLayout();
|
||||
virtual ~VPuzzleLayout();
|
||||
|
@ -51,7 +53,22 @@ public:
|
|||
VPuzzleLayer* AddLayer(VPuzzleLayer *layer);
|
||||
QList<VPuzzleLayer *> GetLayers();
|
||||
|
||||
/**
|
||||
* @brief GetSelectedPieces Returns the list of the selected pieces
|
||||
* @return the selected pieces
|
||||
*/
|
||||
QList<VPuzzlePiece *> GetSelectedPieces();
|
||||
|
||||
/**
|
||||
* @brief SetUnit Sets the unit of the layout to the given unit
|
||||
* @param unit the new unit
|
||||
*/
|
||||
void SetUnit(Unit unit);
|
||||
|
||||
/**
|
||||
* @brief GetUnit Returns the current unit of the layout
|
||||
* @return the unit
|
||||
*/
|
||||
Unit GetUnit() const;
|
||||
|
||||
/**
|
||||
|
@ -133,7 +150,16 @@ public:
|
|||
*/
|
||||
QMarginsF GetLayoutMarginsConverted() const;
|
||||
|
||||
void SetFollowGrainline(FollowGrainline state);
|
||||
/**
|
||||
* @brief SetFollowGrainline Sets the type of grainline for the pieces to follow
|
||||
* @param state the type of grainline
|
||||
*/
|
||||
void SetFollowGrainline(FollowGrainline state);
|
||||
|
||||
/**
|
||||
* @brief GetFollowGrainline Returns if the layout's pieces follow a grainline or not
|
||||
* @return wether the pieces follow a grainline and if so, which grainline
|
||||
*/
|
||||
FollowGrainline GetFollowGrainline() const;
|
||||
|
||||
/**
|
||||
|
@ -169,11 +195,49 @@ public:
|
|||
void SetStickyEdges(bool state);
|
||||
bool GetStickyEdges() const;
|
||||
|
||||
/**
|
||||
* @brief ClearSelection goes through the layers & pieces and calls
|
||||
* SetIsSelected(false) for the pieces that were selected.
|
||||
*/
|
||||
void ClearSelection();
|
||||
|
||||
/**
|
||||
* @brief SetFocusedLayer Sets the focused layer, to which pieces are added from the carrousel via drag
|
||||
* and drop
|
||||
* @param focusedLayer the new active layer. If nullptr, then it sets automaticaly the first layer from m_layers
|
||||
*/
|
||||
void SetFocusedLayer(VPuzzleLayer* focusedLayer = nullptr);
|
||||
|
||||
/**
|
||||
* @brief GetFocusedLayer Returns the focused layer, to which pieces are added from the carrousel via drag
|
||||
* and drop
|
||||
* @return the focused layer
|
||||
*/
|
||||
VPuzzleLayer* GetFocusedLayer();
|
||||
|
||||
/**
|
||||
* @brief MovePieceToLayer Moves the given piece to the given layer
|
||||
* @param piece the piece to move
|
||||
* @param layer the layer to move the piece to
|
||||
*/
|
||||
void MovePieceToLayer(VPuzzlePiece* piece, VPuzzleLayer* layer);
|
||||
|
||||
signals:
|
||||
|
||||
void PieceMovedToLayer(VPuzzlePiece *piece, VPuzzleLayer *layerBefore, VPuzzleLayer *layerAfter);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPuzzleLayout)
|
||||
|
||||
VPuzzleLayer *m_unplacedPiecesLayer;
|
||||
QList<VPuzzleLayer *> m_layers{};
|
||||
|
||||
/**
|
||||
* @brief m_focusedLayer pointer the the focused layer, to which pieces will be
|
||||
* added via drag and drop, or if no layer is defined.
|
||||
*/
|
||||
VPuzzleLayer *m_focusedLayer{nullptr};
|
||||
|
||||
// format
|
||||
Unit m_unit{Unit::Cm};
|
||||
/**
|
||||
|
|
35
src/app/puzzle/vpuzzlemaingraphicsscene.cpp
Normal file
35
src/app/puzzle/vpuzzlemaingraphicsscene.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlemaingraphicsscene.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 "vpuzzlemaingraphicsscene.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleMainGraphicsScene::VPuzzleMainGraphicsScene(QObject *parent): QGraphicsScene(parent)
|
||||
{
|
||||
|
||||
}
|
44
src/app/puzzle/vpuzzlemaingraphicsscene.h
Normal file
44
src/app/puzzle/vpuzzlemaingraphicsscene.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlemaingraphicsscene.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 VPUZZLEMAINGRAPHICSSCENE_H
|
||||
#define VPUZZLEMAINGRAPHICSSCENE_H
|
||||
|
||||
#include <QGraphicsScene>
|
||||
|
||||
// TODO: When ready, extend from QGraphicsScene instead
|
||||
|
||||
class VPuzzleMainGraphicsScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPuzzleMainGraphicsScene(QObject *parent = nullptr);
|
||||
|
||||
};
|
||||
|
||||
#endif // VPUZZLEMAINGRAPHICSSCENE_H
|
205
src/app/puzzle/vpuzzlemaingraphicsview.cpp
Normal file
205
src/app/puzzle/vpuzzlemaingraphicsview.cpp
Normal file
|
@ -0,0 +1,205 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlemaingraphicsview.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 "vpuzzlemaingraphicsview.h"
|
||||
|
||||
#include <QDragEnterEvent>
|
||||
#include <QMimeData>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "vpuzzlemimedatapiece.h"
|
||||
#include "vpuzzlelayer.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(pMainGraphicsView, "p.mainGraphicsView")
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleMainGraphicsView::VPuzzleMainGraphicsView(VPuzzleLayout *layout, QWidget *parent) :
|
||||
QGraphicsView(parent),
|
||||
m_layout(layout),
|
||||
m_graphicsPieces(QList<VPuzzleGraphicsPiece*>())
|
||||
{
|
||||
m_scene = new VPuzzleMainGraphicsScene(this);
|
||||
setScene(m_scene);
|
||||
|
||||
m_graphicsLayout = new VPuzzleGraphicsLayout(layout);
|
||||
m_graphicsLayout->setPos(0,0);
|
||||
m_scene->addItem(m_graphicsLayout);
|
||||
|
||||
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
// add the connections
|
||||
connect(m_layout, &VPuzzleLayout::PieceMovedToLayer, this, &VPuzzleMainGraphicsView::on_PieceMovedToLayer);
|
||||
connect(m_scene, &VPuzzleMainGraphicsScene::selectionChanged, this, &VPuzzleMainGraphicsView::on_SceneSelectionChanged);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleMainGraphicsView::~VPuzzleMainGraphicsView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::RefreshLayout()
|
||||
{
|
||||
// FIXME: Is that the way to go?
|
||||
|
||||
m_graphicsLayout->update();
|
||||
|
||||
m_scene->update();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
const QMimeData *mime = event->mimeData();
|
||||
|
||||
if(mime->objectName() == "piecePointer")
|
||||
{
|
||||
qCDebug(pMainGraphicsView(), "drag enter");
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
const QMimeData *mime = event->mimeData();
|
||||
|
||||
if(mime->objectName() == "piecePointer")
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::dropEvent(QDropEvent *event)
|
||||
{
|
||||
const QMimeData *mime = event->mimeData();
|
||||
|
||||
qCDebug(pMainGraphicsView(), "drop enter , %s", qUtf8Printable(mime->objectName()));
|
||||
|
||||
if(mime->objectName() == "piecePointer")
|
||||
{
|
||||
const VPuzzleMimeDataPiece *mimePiece = qobject_cast<const VPuzzleMimeDataPiece *> (mime);
|
||||
|
||||
VPuzzlePiece *piece = mimePiece->GetPiecePtr();
|
||||
if(piece != nullptr)
|
||||
{
|
||||
qCDebug(pMainGraphicsView(), "element dropped, %s", qUtf8Printable(piece->GetName()));
|
||||
event->acceptProposedAction();
|
||||
|
||||
QPoint point = event->pos();
|
||||
piece->SetPosition(mapToScene(point));
|
||||
|
||||
// change the layer of the piece
|
||||
VPuzzleLayer *focusedLayer = m_layout->GetFocusedLayer();
|
||||
if(focusedLayer != nullptr)
|
||||
{
|
||||
m_layout->MovePieceToLayer(piece, focusedLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete)
|
||||
{
|
||||
QList<VPuzzleGraphicsPiece*> tmpGraphicsPieces = m_graphicsPieces;
|
||||
|
||||
for(auto graphicsPiece : tmpGraphicsPieces)
|
||||
{
|
||||
VPuzzlePiece *piece = graphicsPiece->GetPiece();
|
||||
|
||||
if(piece->GetIsSelected())
|
||||
{
|
||||
piece->SetIsSelected(false);
|
||||
m_layout->MovePieceToLayer(piece, m_layout->GetUnplacedPiecesLayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::on_PieceMovedToLayer(VPuzzlePiece *piece, VPuzzleLayer *layerBefore, VPuzzleLayer *layerAfter)
|
||||
{
|
||||
Q_UNUSED(layerBefore)
|
||||
|
||||
VPuzzleGraphicsPiece *_graphicsPiece = nullptr;
|
||||
for(auto graphicPiece : m_graphicsPieces)
|
||||
{
|
||||
if(graphicPiece->GetPiece() == piece)
|
||||
{
|
||||
_graphicsPiece = graphicPiece;
|
||||
}
|
||||
}
|
||||
|
||||
if(layerAfter == m_layout->GetUnplacedPiecesLayer() && _graphicsPiece != nullptr)
|
||||
{
|
||||
scene()->removeItem(_graphicsPiece);
|
||||
m_graphicsPieces.removeAll(_graphicsPiece);
|
||||
}
|
||||
else if(layerAfter != m_layout->GetUnplacedPiecesLayer())
|
||||
{
|
||||
if(_graphicsPiece == nullptr)
|
||||
{
|
||||
_graphicsPiece = new VPuzzleGraphicsPiece(piece);
|
||||
m_graphicsPieces.append(_graphicsPiece);
|
||||
}
|
||||
|
||||
scene()->addItem(_graphicsPiece);
|
||||
// not very clean to directly call slots
|
||||
_graphicsPiece->on_PieceSelectionChanged();
|
||||
_graphicsPiece->on_PiecePositionChanged();
|
||||
_graphicsPiece->on_PieceRotationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMainGraphicsView::on_SceneSelectionChanged()
|
||||
{
|
||||
// most of the selection behaviour taks place automatically
|
||||
// but we need to make sure that the unplaced pieces are unselected when the scene selection has changed
|
||||
// because as they are not part of the scene, they are not updated
|
||||
|
||||
m_layout->GetUnplacedPiecesLayer()->ClearSelection();
|
||||
}
|
87
src/app/puzzle/vpuzzlemaingraphicsview.h
Normal file
87
src/app/puzzle/vpuzzlemaingraphicsview.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlemaingraphicsview.h
|
||||
** @author Ronan Le Tiec
|
||||
** @date 3 5, 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 VPUZZLEMAINGRAPHICSVIEW_H
|
||||
#define VPUZZLEMAINGRAPHICSVIEW_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
|
||||
#include "vpuzzlegraphicslayout.h"
|
||||
#include "vpuzzlemaingraphicsscene.h"
|
||||
#include "vpuzzlegraphicspiece.h"
|
||||
|
||||
|
||||
// TODO: when ready, extend the VMainGrapchisView instead
|
||||
|
||||
class VPuzzleMainGraphicsView : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPuzzleMainGraphicsView(VPuzzleLayout *layout, QWidget *parent);
|
||||
~VPuzzleMainGraphicsView();
|
||||
|
||||
/**
|
||||
* @brief RefreshLayout Refreshes the rectangles for the layout border and the margin
|
||||
*/
|
||||
void RefreshLayout();
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief on_PieceMovedToLayer The slot is called when the given piece was moved from the given layer to the other given layer
|
||||
* @param piece the piece that was moved
|
||||
* @param layerBefore the layer before the move
|
||||
* @param layerAfter the layer after the move
|
||||
*/
|
||||
void on_PieceMovedToLayer(VPuzzlePiece *piece, VPuzzleLayer *layerBefore, VPuzzleLayer *layerAfter);
|
||||
|
||||
/**
|
||||
* @brief on_SceneSelectionChanged Slot is called when the scene selection has changed
|
||||
*/
|
||||
void on_SceneSelectionChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPuzzleMainGraphicsView)
|
||||
|
||||
VPuzzleMainGraphicsScene *m_scene{nullptr};
|
||||
|
||||
VPuzzleGraphicsLayout *m_graphicsLayout{nullptr};
|
||||
VPuzzleLayout *m_layout{nullptr};
|
||||
|
||||
QList<VPuzzleGraphicsPiece*> m_graphicsPieces;
|
||||
|
||||
};
|
||||
|
||||
#endif // VPUZZLEMAINGRAPHICVIEW_H
|
53
src/app/puzzle/vpuzzlemimedatapiece.cpp
Normal file
53
src/app/puzzle/vpuzzlemimedatapiece.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlemimedatapiece.cpp
|
||||
** @author Ronan Le Tiec
|
||||
** @date 4 5, 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 "vpuzzlemimedatapiece.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleMimeDataPiece::VPuzzleMimeDataPiece()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleMimeDataPiece::~VPuzzleMimeDataPiece()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzlePiece* VPuzzleMimeDataPiece::GetPiecePtr() const
|
||||
{
|
||||
return m_piece;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzleMimeDataPiece::SetPiecePtr(VPuzzlePiece* piece)
|
||||
{
|
||||
m_piece = piece;
|
||||
}
|
65
src/app/puzzle/vpuzzlemimedatapiece.h
Normal file
65
src/app/puzzle/vpuzzlemimedatapiece.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpuzzlemimedatapiece.h
|
||||
** @author Ronan Le Tiec
|
||||
** @date 4 5, 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 VPUZZLEMIMEDATAPIECE_H
|
||||
#define VPUZZLEMIMEDATAPIECE_H
|
||||
|
||||
#include <QMimeData>
|
||||
|
||||
#include "vpuzzlepiece.h"
|
||||
|
||||
class VPuzzleMimeDataPiece : public QMimeData
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
VPuzzleMimeDataPiece();
|
||||
~VPuzzleMimeDataPiece();
|
||||
|
||||
/**
|
||||
* @brief GetPiecePtr Returns the piece pointer of the mime data
|
||||
* @return piece pointer
|
||||
*/
|
||||
VPuzzlePiece* GetPiecePtr() const;
|
||||
|
||||
/**
|
||||
* @brief SetPiecePtr sets the piece pointer to the given value
|
||||
* @param piece the piece pointer
|
||||
*/
|
||||
void SetPiecePtr(VPuzzlePiece* piece);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPuzzleMimeDataPiece)
|
||||
|
||||
VPuzzlePiece *m_piece{nullptr};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // VPUZZLEMIMEDATAPIECE_H
|
|
@ -27,6 +27,14 @@
|
|||
*************************************************************************/
|
||||
#include "vpuzzlepiece.h"
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
#include "vpuzzlelayer.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(pPiece, "p.piece")
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzlePiece::VPuzzlePiece()
|
||||
{
|
||||
|
@ -79,6 +87,17 @@ void VPuzzlePiece::SetCuttingLine(const QVector<QPointF> &cuttingLine)
|
|||
m_cuttingLine = cuttingLine;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QVector<QPointF> VPuzzlePiece::GetSeamLine() const
|
||||
{
|
||||
return m_seamLine;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzlePiece::SetSeamLine(const QVector<QPointF> &seamLine)
|
||||
{
|
||||
m_seamLine = seamLine;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPuzzlePiece::GetShowSeamLine() const
|
||||
|
@ -90,6 +109,8 @@ bool VPuzzlePiece::GetShowSeamLine() const
|
|||
void VPuzzlePiece::SetShowSeamLine(bool value)
|
||||
{
|
||||
m_showSeamline = value;
|
||||
|
||||
emit PropertiesChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -102,5 +123,133 @@ bool VPuzzlePiece::GetPieceMirrored() const
|
|||
void VPuzzlePiece::SetPieceMirrored(bool value)
|
||||
{
|
||||
m_mirrorPiece = value;
|
||||
|
||||
emit PropertiesChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzlePiece::SetPosition(QPointF point)
|
||||
{
|
||||
m_transform.translate(point.x() - m_transform.dx(), point.y() - m_transform.dy());
|
||||
|
||||
emit PositionChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPointF VPuzzlePiece::GetPosition()
|
||||
{
|
||||
return QPointF(m_transform.dx(), m_transform.dy());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzlePiece::SetRotation(qreal angle)
|
||||
{
|
||||
// qreal currentAngle = GetRotation();
|
||||
// qreal newAngle = angle - currentAngle;
|
||||
|
||||
// m_transform.rotate(newAngle);
|
||||
|
||||
if(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();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
qreal VPuzzlePiece::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 VPuzzlePiece::SetIsSelected(bool value)
|
||||
{
|
||||
if(m_isSelected != value)
|
||||
{
|
||||
m_isSelected = value;
|
||||
emit SelectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPuzzlePiece::GetIsSelected()
|
||||
{
|
||||
return m_isSelected;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzlePiece::SetIsGrainlineEnabled(bool value)
|
||||
{
|
||||
m_isGrainlineEnabled = value;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VPuzzlePiece::GetIsGrainlineEnabled()
|
||||
{
|
||||
return m_isGrainlineEnabled;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzlePiece::SetGrainlineAngle(qreal value)
|
||||
{
|
||||
m_grainlineAngle = value;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
qreal VPuzzlePiece::GetGrainlineAngle()
|
||||
{
|
||||
return m_grainlineAngle;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzlePiece::SetGrainline(QVector<QPointF> grainline)
|
||||
{
|
||||
m_grainline = grainline;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QVector<QPointF> VPuzzlePiece::GetGrainline()
|
||||
{
|
||||
return m_grainline;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPuzzleLayer* VPuzzlePiece::GetLayer()
|
||||
{
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPuzzlePiece::SetLayer(VPuzzleLayer* layer)
|
||||
{
|
||||
if(layer != m_layer)
|
||||
{
|
||||
m_layer = layer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,13 @@
|
|||
#include <QUuid>
|
||||
#include <QVector>
|
||||
#include <QPoint>
|
||||
#include <QTransform>
|
||||
|
||||
class VPuzzlePiece
|
||||
class VPuzzleLayer;
|
||||
|
||||
class VPuzzlePiece : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VPuzzlePiece();
|
||||
~VPuzzlePiece();
|
||||
|
@ -61,10 +65,30 @@ public:
|
|||
*/
|
||||
void SetUuid(const QUuid &uuid);
|
||||
|
||||
/**
|
||||
* @brief GetCuttingLine Returns the vector points of the cutting line
|
||||
* @return the vector points of the cutting line
|
||||
*/
|
||||
QVector<QPointF> GetCuttingLine() const;
|
||||
|
||||
/**
|
||||
* @brief SetCuttingLine Sets the vector points of the cutting line to the given value
|
||||
* @param cuttingLine the new vector points for the cutting line
|
||||
*/
|
||||
void SetCuttingLine(const QVector<QPointF> &cuttingLine);
|
||||
|
||||
/**
|
||||
* @brief GetSeamLine Returns the vector points of the seam line
|
||||
* @return the vector points of the seam line
|
||||
*/
|
||||
QVector<QPointF> GetSeamLine() const;
|
||||
|
||||
/**
|
||||
* @brief SetSeamLine Sets the vector points of the seam line to the given value
|
||||
* @param seamLine the new vector points for the seam line
|
||||
*/
|
||||
void SetSeamLine(const QVector<QPointF> &seamLine);
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
@ -89,13 +113,136 @@ public:
|
|||
*/
|
||||
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 SetIsGrainlineEnabled Wether the piece has a grainline or not
|
||||
* @param value true or false
|
||||
*/
|
||||
void SetIsGrainlineEnabled(bool value);
|
||||
|
||||
/**
|
||||
* @brief GetIsGrainlineEnabled Returns wether the grainline is enabled for this piece
|
||||
* @return true if enabled
|
||||
*/
|
||||
bool GetIsGrainlineEnabled();
|
||||
|
||||
/**
|
||||
* @brief SetGrainlineAngle Sets the angle of the grainline
|
||||
* @param value
|
||||
*/
|
||||
void SetGrainlineAngle(qreal value);
|
||||
|
||||
/**
|
||||
* @brief GetGrainlineAngle Returns the angle of the grainline for this piece
|
||||
* @return the angle
|
||||
*/
|
||||
qreal GetGrainlineAngle();
|
||||
|
||||
/**
|
||||
* @brief SetGrainline Sets the grainline to the given vector of points
|
||||
* @param grainline the grainline
|
||||
*/
|
||||
void SetGrainline(QVector<QPointF> grainline);
|
||||
|
||||
/**
|
||||
* @brief GetGrainline Returns the grainline for this piece
|
||||
* @return the vector
|
||||
*/
|
||||
QVector<QPointF> GetGrainline();
|
||||
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @brief GetLayer Returns the layer in which the piece is.
|
||||
* @return layer of the piece
|
||||
*/
|
||||
VPuzzleLayer* GetLayer();
|
||||
|
||||
/**
|
||||
* @brief SetLayer Sets the layer of the piece to the given layer
|
||||
* @param layer
|
||||
*/
|
||||
void SetLayer(VPuzzleLayer* layer);
|
||||
|
||||
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(VPuzzlePiece)
|
||||
QUuid m_uuid{QUuid()};
|
||||
QString m_name{QString()};
|
||||
QVector<QPointF> m_cuttingLine{QVector<QPointF>()};
|
||||
QVector<QPointF> m_seamLine{QVector<QPointF>()};
|
||||
|
||||
QVector<QPointF> m_grainline{QVector<QPointF>()};
|
||||
bool m_isGrainlineEnabled{false};
|
||||
qreal m_grainlineAngle{0};
|
||||
|
||||
QTransform m_transform{QTransform()};
|
||||
// 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};
|
||||
VPuzzleLayer *m_layer{nullptr};
|
||||
};
|
||||
|
||||
#endif // VPUZZLEPIECE_H
|
||||
|
|
Loading…
Reference in New Issue
Block a user