From d1064ad5c11a09b5de1e077b033d80e24c918d03 Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sun, 19 Oct 2025 10:57:50 -0700 Subject: [PATCH] New undo system. --- common/lc_global.h | 2 + common/lc_model.cpp | 346 +++++++++++++++++++++++++++++++------- common/lc_model.h | 39 +++-- common/lc_modelaction.cpp | 133 +++++++++++++++ common/lc_modelaction.h | 100 +++++++++++ leocad.pro | 2 + qt/lc_qutils.h | 2 + 7 files changed, 553 insertions(+), 71 deletions(-) create mode 100644 common/lc_modelaction.cpp create mode 100644 common/lc_modelaction.h diff --git a/common/lc_global.h b/common/lc_global.h index 2d1f72e5..9146f242 100644 --- a/common/lc_global.h +++ b/common/lc_global.h @@ -3,6 +3,7 @@ #ifdef __cplusplus +#define QT_NO_DEPRECATED_WARNINGS #include #include #include @@ -88,6 +89,7 @@ class lcLight; enum class lcLightType; enum class lcLightAreaShape; class lcGroup; +class lcModelAction; class PieceInfo; typedef std::map> lcPartsList; struct lcModelPartsEntry; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 8995966f..dd68c180 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -1,6 +1,6 @@ #include "lc_global.h" #include "lc_model.h" -#include +#include "lc_modelaction.h" #include "piece.h" #include "camera.h" #include "light.h" @@ -26,6 +26,7 @@ #include "lc_lxf.h" #include "lc_previewwidget.h" #include "lc_findreplacewidget.h" +#include void lcModelProperties::LoadDefaults() { @@ -203,7 +204,6 @@ lcModel::~lcModel() } DeleteModel(); - DeleteHistory(); } bool lcModel::GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const @@ -245,16 +245,6 @@ bool lcModel::IncludesModel(const lcModel* Model) const return false; } -void lcModel::DeleteHistory() -{ - for (lcModelHistoryEntry* Entry : mUndoHistory) - delete Entry; - mUndoHistory.clear(); - for (lcModelHistoryEntry* Entry : mRedoHistory) - delete Entry; - mRedoHistory.clear(); -} - void lcModel::DeleteModel() { if (gMainWindow) @@ -1723,8 +1713,245 @@ void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::v Piece->SubModelAddBoundingBoxPoints(WorldMatrix, Points); } -void lcModel::SaveCheckpoint(const QString& Description) +void lcModel::RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode) { + std::unique_ptr ModelActionSelection = std::make_unique(ModelActionSelectionMode); + + ModelActionSelection->SetSelection(mPieces, mCameras, mLights); + + RunSelectionAction(ModelActionSelection.get(), true); + + mActionSequence.emplace_back(std::move(ModelActionSelection)); +} + +void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelection, bool Apply) +{ + if (!ModelActionSelection) + return; + + switch (ModelActionSelection->GetMode()) + { + case lcModelActionSelectionMode::Clear: + if (Apply) + { + ClearSelection(true); + } + else + { + auto [SelectedObjects, FocusObject, FocusSection] = ModelActionSelection->GetSelection(mPieces, mCameras, mLights); + + SetSelectionAndFocus(SelectedObjects, FocusObject, FocusSection, false); + } + break; + + case lcModelActionSelectionMode::Save: + if (Apply) + { + } + else + { + auto [SelectedObjects, FocusObject, FocusSection] = ModelActionSelection->GetSelection(mPieces, mCameras, mLights); + + SetSelectionAndFocus(SelectedObjects, FocusObject, FocusSection, false); + } + break; + } +} + +void lcModel::RecordAddPiecesAction(const std::vector& PieceInfoTransforms, lcModelActionAddPieceSelectionMode SelectionMode) +{ + std::unique_ptr ModelActionAddPieces = std::make_unique(mCurrentStep, SelectionMode); + + ModelActionAddPieces->SetPieceData(PieceInfoTransforms); + + RunAddPiecesAction(ModelActionAddPieces.get(), true); + + mActionSequence.emplace_back(std::move(ModelActionAddPieces)); +} + +void lcModel::RunAddPiecesAction(const lcModelActionAddPieces* ModelActionAddPieces, bool Apply) +{ + if (!ModelActionAddPieces) + return; + + if (Apply) + { + std::vector Pieces; + lcStep Step = ModelActionAddPieces->GetStep(); + + for (const lcModelActionAddPieces::PieceData& PieceData : ModelActionAddPieces->GetPieceData()) + { + PieceInfo* PieceInfo = lcGetPiecesLibrary()->FindPiece(PieceData.PieceId.c_str(), nullptr, true, false); + + if (!PieceInfo) + continue; + + lcPiece* Piece = new lcPiece(PieceInfo); + + Piece->Initialize(PieceData.Transform, Step); + Piece->SetColorIndex(lcGetColorIndex(PieceData.ColorCode)); + Piece->UpdatePosition(Step); + + AddPiece(Piece); + Pieces.push_back(Piece); + } + + if (Pieces.empty()) + return; + + gMainWindow->UpdateTimeline(false, false); + gMainWindow->UpdateInUseCategory(); + + switch (ModelActionAddPieces->GetSelectionMode()) + { + case lcModelActionAddPieceSelectionMode::FocusLast: + ClearSelectionAndSetFocus(Pieces.back(), LC_PIECE_SECTION_POSITION, false); + UpdateTrainTrackConnections(dynamic_cast(Pieces.back()), false); + break; + + case lcModelActionAddPieceSelectionMode::SelectAll: + SetSelectionAndFocus(Pieces, nullptr, 0, false); + break; + } + } + else + { + if (RemoveSelectedObjects()) + { + gMainWindow->UpdateTimeline(false, false); + gMainWindow->UpdateSelectedObjects(true); + gMainWindow->UpdateInUseCategory(); + } + } +} + +void lcModel::RecordGroupPiecesAction(const QString& GroupName) +{ + std::unique_ptr ModelActionGroupPieces = std::make_unique(GroupName); + + RunGroupPiecesAction(ModelActionGroupPieces.get(), true); + + mActionSequence.emplace_back(std::move(ModelActionGroupPieces)); +} + +void lcModel::RunGroupPiecesAction(const lcModelActionGroupPieces* ModelActionGroupPieces, bool Apply) +{ + if (!ModelActionGroupPieces) + return; + + if (Apply) + { + lcGroup* NewGroup = AddGroup(ModelActionGroupPieces->GetGroupName(), nullptr); + + for (const std::unique_ptr& Piece : mPieces) + { + if (Piece->IsSelected()) + { + lcGroup* TopGroup = Piece->GetTopGroup(); + + if (!TopGroup) + Piece->SetGroup(NewGroup); + else if (TopGroup != NewGroup) + TopGroup->mGroup = NewGroup; + } + } + } + else + { + std::set SelectedGroups; + + for (const std::unique_ptr& Piece : mPieces) + { + if (Piece->IsSelected()) + { + lcGroup* Group = Piece->GetTopGroup(); + + if (SelectedGroups.insert(Group).second) + { + for (std::vector>::iterator GroupIt = mGroups.begin(); GroupIt != mGroups.end(); GroupIt++) + { + if (GroupIt->get() == Group) + { + GroupIt->release(); + mGroups.erase(GroupIt); + break; + } + } + } + } + } + + for (const std::unique_ptr& Piece : mPieces) + { + lcGroup* Group = Piece->GetGroup(); + + if (SelectedGroups.find(Group) != SelectedGroups.end()) + Piece->SetGroup(nullptr); + } + + for (const std::unique_ptr& Group : mGroups) + if (SelectedGroups.find(Group->mGroup) != SelectedGroups.end()) + Group->mGroup = nullptr; + + for (lcGroup* Group : SelectedGroups) + delete Group; + + RemoveEmptyGroups(); + } +} + +void lcModel::PerformActionSequence(const std::vector>& ActionSequence, bool Apply) +{ + auto PerformAction=[this](const lcModelAction* ModelAction, bool Apply) + { + if (const lcModelActionSelection* ModelActionSelection = dynamic_cast(ModelAction)) + RunSelectionAction(ModelActionSelection, Apply); + else if (const lcModelActionAddPieces* ModelActionAddPieces = dynamic_cast(ModelAction)) + RunAddPiecesAction(ModelActionAddPieces, Apply); + else if (const lcModelActionGroupPieces* ModelActionGroupPieces = dynamic_cast(ModelAction)) + RunGroupPiecesAction(ModelActionGroupPieces, Apply); + }; + + if (Apply) + { + for (auto ModelAction = ActionSequence.begin(); ModelAction != ActionSequence.end(); ++ModelAction) + PerformAction(ModelAction->get(), true); + } + else + { + for (auto ModelAction = ActionSequence.rbegin(); ModelAction != ActionSequence.rend(); ++ModelAction) + PerformAction(ModelAction->get(), false); + } + + UpdateAllViews(); +} + +void lcModel::BeginActionSequence() +{ + mActionSequence.clear(); +} + +void lcModel::EndActionSequence(const QString& Description) +{ + std::unique_ptr ModelHistoryEntry = std::make_unique(lcModelHistoryEntry()); + + ModelHistoryEntry->Description = Description; + ModelHistoryEntry->ModelActions = std::move(mActionSequence); + + mUndoHistory.insert(mUndoHistory.begin(), std::move(ModelHistoryEntry)); + mRedoHistory.clear(); + + gMainWindow->UpdateModified(IsModified()); + gMainWindow->UpdateUndoRedo(!mUndoHistory.empty() ? mUndoHistory.front()->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory.front()->Description : nullptr); +} + +void lcModel::CancelActionSequence() +{ +} + +void lcModel::SaveCheckpoint(const QString& ) +{ + /* lcModelHistoryEntry* ModelHistoryEntry = new lcModelHistoryEntry(); ModelHistoryEntry->Description = Description; @@ -1742,10 +1969,18 @@ void lcModel::SaveCheckpoint(const QString& Description) gMainWindow->UpdateModified(IsModified()); gMainWindow->UpdateUndoRedo(mUndoHistory.size() > 1 ? mUndoHistory[0]->Description : QString(), !mRedoHistory.empty() ? mRedoHistory[0]->Description : QString()); } + */ } -void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint) +void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint, bool Apply) { + if (!CheckPoint->ModelActions.empty()) + { + PerformActionSequence(CheckPoint->ModelActions, Apply); + + return; + } + lcPiecesLibrary* Library = lcGetPiecesLibrary(); std::vector LoadedInfos; @@ -3457,8 +3692,7 @@ void lcModel::EndPropertyEdit(lcObjectPropertyId PropertyId, bool Accept) { if (!Accept) { - if (!mUndoHistory.empty()) - LoadCheckPoint(mUndoHistory.front()); + CancelActionSequence(); return; } @@ -4494,17 +4728,18 @@ void lcModel::FindReplacePiece(bool SearchForward, bool FindAll, bool Replace) void lcModel::UndoAction() { - if (mUndoHistory.size() < 2) + if (mUndoHistory.empty()) return; - lcModelHistoryEntry* Undo = mUndoHistory.front(); - mUndoHistory.erase(mUndoHistory.begin()); - mRedoHistory.insert(mRedoHistory.begin(), Undo); + std::unique_ptr Undo = std::move(mUndoHistory.front()); - LoadCheckPoint(mUndoHistory[0]); + LoadCheckPoint(Undo.get(), false); + + mUndoHistory.erase(mUndoHistory.begin()); + mRedoHistory.insert(mRedoHistory.begin(), std::move(Undo)); gMainWindow->UpdateModified(IsModified()); - gMainWindow->UpdateUndoRedo(mUndoHistory.size() > 1 ? mUndoHistory[0]->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory[0]->Description : nullptr); + gMainWindow->UpdateUndoRedo(!mUndoHistory.empty() ? mUndoHistory.front()->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory.front()->Description : nullptr); } void lcModel::RedoAction() @@ -4512,14 +4747,15 @@ void lcModel::RedoAction() if (mRedoHistory.empty()) return; - lcModelHistoryEntry* Redo = mRedoHistory.front(); - mRedoHistory.erase(mRedoHistory.begin()); - mUndoHistory.insert(mUndoHistory.begin(), Redo); + std::unique_ptr Redo = std::move(mRedoHistory.front()); - LoadCheckPoint(Redo); + LoadCheckPoint(Redo.get(), true); + + mRedoHistory.erase(mRedoHistory.begin()); + mUndoHistory.insert(mUndoHistory.begin(), std::move(Redo)); gMainWindow->UpdateModified(IsModified()); - gMainWindow->UpdateUndoRedo(mUndoHistory.size() > 1 ? mUndoHistory[0]->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory[0]->Description : nullptr); + gMainWindow->UpdateUndoRedo(!mUndoHistory.empty() ? mUndoHistory.front()->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory.front()->Description : nullptr); } void lcModel::BeginMouseTool() @@ -4532,8 +4768,7 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept) { if (!Accept) { - if (!mUndoHistory.empty()) - LoadCheckPoint(mUndoHistory.front()); + CancelActionSequence(); return; } @@ -4596,26 +4831,16 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept) void lcModel::InsertPieceToolClicked(const std::vector& PieceInfoTransforms) { - lcPiece* Piece = nullptr; - - for (const lcInsertPieceInfo& PieceInfoTransform : PieceInfoTransforms) - { - Piece = new lcPiece(PieceInfoTransform.Info); - Piece->Initialize(PieceInfoTransform.Transform, mCurrentStep); - Piece->SetColorIndex(PieceInfoTransform.ColorIndex); - Piece->UpdatePosition(mCurrentStep); - AddPiece(Piece); - } - - if (!Piece) + if (PieceInfoTransforms.empty()) return; - gMainWindow->UpdateTimeline(false, false); - ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, false); + BeginActionSequence(); - UpdateTrainTrackConnections(Piece, false); + RecordSelectionAction(lcModelActionSelectionMode::Save); + RecordAddPiecesAction(PieceInfoTransforms, lcModelActionAddPieceSelectionMode::FocusLast); + RecordSelectionAction(lcModelActionSelectionMode::Save); - SaveCheckpoint(tr("Insert")); + EndActionSequence(tr("Add Piece")); } void lcModel::InsertLightToolClicked(const lcVector3& Position, lcLightType LightType) @@ -5109,30 +5334,29 @@ void lcModel::ShowMinifigDialog() gMainWindow->GetActiveView()->MakeCurrent(); - lcGroup* Group = AddGroup(tr("Minifig #"), nullptr); - std::vector Pieces; - Pieces.reserve(LC_MFW_NUMITEMS); + std::vector PieceInfoTransforms; lcMinifig& Minifig = Dialog.mMinifigWizard->mMinifig; - for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++) + for (int PartIndex = 0; PartIndex < LC_MFW_NUMITEMS; PartIndex++) { - if (Minifig.Parts[PartIdx] == nullptr) + if (!Minifig.Parts[PartIndex]) continue; - lcPiece* Piece = new lcPiece(Minifig.Parts[PartIdx]); + lcInsertPieceInfo& InsertPieceInfo = PieceInfoTransforms.emplace_back(); - Piece->Initialize(Minifig.Matrices[PartIdx], mCurrentStep); - Piece->SetColorIndex(Minifig.ColorIndices[PartIdx]); - Piece->SetGroup(Group); - AddPiece(Piece); - Piece->UpdatePosition(mCurrentStep); - - Pieces.emplace_back(Piece); + InsertPieceInfo.Info = Minifig.Parts[PartIndex]; + InsertPieceInfo.Transform = Minifig.Matrices[PartIndex]; + InsertPieceInfo.ColorIndex = Minifig.ColorIndices[PartIndex]; } - SetSelectionAndFocus(Pieces, nullptr, 0, false); - gMainWindow->UpdateTimeline(false, false); - SaveCheckpoint(tr("Minifig")); + BeginActionSequence(); + + RecordSelectionAction(lcModelActionSelectionMode::Save); + RecordAddPiecesAction(PieceInfoTransforms, lcModelActionAddPieceSelectionMode::SelectAll); + RecordGroupPiecesAction(tr("Minifig #")); + RecordSelectionAction(lcModelActionSelectionMode::Save); + + EndActionSequence(tr("Add Minifig")); } void lcModel::SetMinifig(const lcMinifig& Minifig) diff --git a/common/lc_model.h b/common/lc_model.h index a81ee024..6a33269d 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -4,6 +4,12 @@ #include "lc_commands.h" enum class lcObjectPropertyId; +class lcModelAction; +class lcModelActionSelection; +class lcModelActionAddPieces; +class lcModelActionGroupPieces; +enum class lcModelActionSelectionMode; +enum class lcModelActionAddPieceSelectionMode; #define LC_SEL_NO_PIECES 0x0001 // No pieces in model #define LC_SEL_PIECE 0x0002 // At least 1 piece selected @@ -99,6 +105,7 @@ public: struct lcModelHistoryEntry { + std::vector> ModelActions; QByteArray File; QString Description; }; @@ -121,7 +128,10 @@ public: bool IsModified() const { - return mSavedHistory != mUndoHistory[0]; + if (mUndoHistory.empty()) + return mSavedHistory != nullptr; + else + return mSavedHistory != mUndoHistory.front().get(); } bool IsActive() const @@ -253,11 +263,7 @@ public: void SetSaved() { - if (mUndoHistory.empty()) - SaveCheckpoint(QString()); - - if (!mIsPreview) - mSavedHistory = mUndoHistory[0]; + mSavedHistory = mUndoHistory.empty() ? nullptr : mUndoHistory.front().get(); } void SetMinifig(const lcMinifig& Minifig); @@ -392,9 +398,21 @@ public: protected: void DeleteModel(); - void DeleteHistory(); + + void RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode); + void RunSelectionAction(const lcModelActionSelection* ModelActionSelection, bool Apply); + void RecordAddPiecesAction(const std::vector& PieceInfoTransforms, lcModelActionAddPieceSelectionMode SelectionMode); + void RunAddPiecesAction(const lcModelActionAddPieces* ModelActionAddPieces, bool Apply); + void RecordGroupPiecesAction(const QString& GroupName); + void RunGroupPiecesAction(const lcModelActionGroupPieces* ModelActionGroupPieces, bool Apply); + + void PerformActionSequence(const std::vector>& ActionSequence, bool Apply); + void BeginActionSequence(); + void EndActionSequence(const QString& Description); + void CancelActionSequence(); + void SaveCheckpoint(const QString& Description); - void LoadCheckPoint(lcModelHistoryEntry* CheckPoint); + void LoadCheckPoint(lcModelHistoryEntry* CheckPoint, bool Apply); QString GetGroupName(const QString& Prefix); void RemoveEmptyGroups(); @@ -422,9 +440,10 @@ protected: std::vector> mGroups; QStringList mFileLines; + std::vector> mActionSequence; lcModelHistoryEntry* mSavedHistory; - std::vector mUndoHistory; - std::vector mRedoHistory; + std::vector> mUndoHistory; + std::vector> mRedoHistory; Q_DECLARE_TR_FUNCTIONS(lcModel); }; diff --git a/common/lc_modelaction.cpp b/common/lc_modelaction.cpp new file mode 100644 index 00000000..e4da549b --- /dev/null +++ b/common/lc_modelaction.cpp @@ -0,0 +1,133 @@ +#include "lc_global.h" +#include "lc_modelaction.h" +#include "lc_model.h" +#include "piece.h" +#include "camera.h" +#include "light.h" +#include "pieceinf.h" +#include "lc_colors.h" + +lcModelActionSelection::lcModelActionSelection(lcModelActionSelectionMode Mode) + : mMode(Mode) +{ +} + +void lcModelActionSelection::SetSelection(const std::vector>& Pieces, const std::vector>& Cameras, const std::vector>& Lights) +{ + mSelectedPieces.clear(); + mSelectedCameras.clear(); + mSelectedLights.clear(); + + for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++) + { + lcPiece* Piece = Pieces[PieceIndex].get(); + + if (!Piece->IsSelected()) + continue; + + mSelectedPieces.push_back(PieceIndex); + + if (Piece->IsFocused()) + { + mFocusIndex = PieceIndex; + mFocusSection = Piece->GetFocusSection(); + mFocusType = lcObjectType::Piece; + } + } + + for (size_t CameraIndex = 0; CameraIndex < Cameras.size(); CameraIndex++) + { + lcCamera* Camera = Cameras[CameraIndex].get(); + + if (!Camera->IsSelected()) + continue; + + mSelectedCameras.push_back(CameraIndex); + + if (Camera->IsFocused()) + { + mFocusIndex = CameraIndex; + mFocusSection = Camera->GetFocusSection(); + mFocusType = lcObjectType::Camera; + } + } + + for (size_t LightIndex = 0; LightIndex < Lights.size(); LightIndex++) + { + lcLight* Light = Lights[LightIndex].get(); + + if (!Light->IsSelected()) + continue; + + if (Light->IsFocused()) + { + mFocusIndex = LightIndex; + mFocusSection = Light->GetFocusSection(); + mFocusType = lcObjectType::Light; + } + } +} + +std::tuple, lcObject*, uint32_t> lcModelActionSelection::GetSelection(const std::vector>& Pieces, const std::vector>& Cameras, const std::vector>& Lights) const +{ + std::vector SelectedObjects; + lcObject* FocusObject = nullptr; + + for (size_t PieceIndex : mSelectedPieces) + if (PieceIndex < Pieces.size()) + SelectedObjects.push_back(Pieces[PieceIndex].get()); + + for (size_t CameraIndex : mSelectedCameras) + if (CameraIndex < Cameras.size()) + SelectedObjects.push_back(Cameras[CameraIndex].get()); + + for (size_t LightIndex : mSelectedLights) + if (LightIndex < Lights.size()) + SelectedObjects.push_back(Lights[LightIndex].get()); + + if (mFocusIndex != SIZE_MAX) + { + switch (mFocusType) + { + case lcObjectType::Piece: + if (mFocusIndex < Pieces.size()) + FocusObject = Pieces[mFocusIndex].get(); + break; + case lcObjectType::Camera: + if (mFocusIndex < Cameras.size()) + FocusObject = Cameras[mFocusIndex].get(); + break; + case lcObjectType::Light: + if (mFocusIndex < Lights.size()) + FocusObject = Lights[mFocusIndex].get(); + break; + } + } + + return { SelectedObjects, FocusObject, mFocusSection }; +} + +lcModelActionAddPieces::lcModelActionAddPieces(lcStep Step, lcModelActionAddPieceSelectionMode SelectionMode) + : mStep(Step), mSelectionMode(SelectionMode) +{ +} + +void lcModelActionAddPieces::SetPieceData(const std::vector& PieceInfoTransforms) +{ + mPieceData.clear(); + mPieceData.reserve(PieceInfoTransforms.size()); + + for (const lcInsertPieceInfo& PieceInfoTransform : PieceInfoTransforms) + { + lcModelActionAddPieces::PieceData& PieceData = mPieceData.emplace_back(); + + PieceData.PieceId = PieceInfoTransform.Info->mFileName; + PieceData.Transform = PieceInfoTransform.Transform; + PieceData.ColorCode = lcGetColorCode(PieceInfoTransform.ColorIndex); + } +} + +lcModelActionGroupPieces::lcModelActionGroupPieces(const QString& GroupName) + : mGroupName(GroupName) +{ +} diff --git a/common/lc_modelaction.h b/common/lc_modelaction.h new file mode 100644 index 00000000..8003d377 --- /dev/null +++ b/common/lc_modelaction.h @@ -0,0 +1,100 @@ +#pragma once + +#include "lc_math.h" + +struct lcInsertPieceInfo; +enum class lcObjectType; + +class lcModelAction +{ +public: + lcModelAction() = default; + virtual ~lcModelAction() = default; +}; + +enum class lcModelActionSelectionMode +{ + Clear, + Save +}; + +class lcModelActionSelection : public lcModelAction +{ +public: + lcModelActionSelection(lcModelActionSelectionMode Mode); + virtual ~lcModelActionSelection() = default; + + lcModelActionSelectionMode GetMode() const + { + return mMode; + } + + void SetSelection(const std::vector>& Pieces, const std::vector>& Cameras, const std::vector>& Lights); + std::tuple, lcObject*, uint32_t> GetSelection(const std::vector>& Pieces, const std::vector>& Cameras, const std::vector>& Lights) const; + +protected: + std::vector mSelectedPieces; + std::vector mSelectedCameras; + std::vector mSelectedLights; + size_t mFocusIndex = SIZE_MAX; + uint32_t mFocusSection = 0; + lcObjectType mFocusType = (lcObjectType)0; + lcModelActionSelectionMode mMode = lcModelActionSelectionMode::Clear; +}; + +enum class lcModelActionAddPieceSelectionMode +{ + FocusLast, + SelectAll +}; + +class lcModelActionAddPieces : public lcModelAction +{ +public: + lcModelActionAddPieces(lcStep Step, lcModelActionAddPieceSelectionMode SelectionMode); + virtual ~lcModelActionAddPieces() = default; + + struct PieceData + { + std::string PieceId; + lcMatrix44 Transform; + quint32 ColorCode; + }; + + void SetPieceData(const std::vector& PieceInfoTransforms); + + const std::vector& GetPieceData() const + { + return mPieceData; + } + + lcStep GetStep() const + { + return mStep; + } + + lcModelActionAddPieceSelectionMode GetSelectionMode() const + { + return mSelectionMode; + } + +protected: + std::vector mPieceData; + lcStep mStep; + lcModelActionAddPieceSelectionMode mSelectionMode; +}; + +class lcModelActionGroupPieces : public lcModelAction +{ +public: + lcModelActionGroupPieces(const QString& GroupName); + virtual ~lcModelActionGroupPieces() = default; + + const QString& GetGroupName() const + { + return mGroupName; + } + +protected: + QString mGroupName; +}; diff --git a/leocad.pro b/leocad.pro index c23bb676..adabb7da 100644 --- a/leocad.pro +++ b/leocad.pro @@ -207,6 +207,7 @@ SOURCES += \ common/lc_meshloader.cpp \ common/lc_minifigdialog.cpp \ common/lc_model.cpp \ + common/lc_modelaction.cpp \ common/lc_modellistdialog.cpp \ common/lc_objectproperty.cpp \ common/lc_pagesetupdialog.cpp \ @@ -286,6 +287,7 @@ HEADERS += \ common/lc_meshloader.h \ common/lc_minifigdialog.h \ common/lc_model.h \ + common/lc_modelaction.h \ common/lc_modellistdialog.h \ common/lc_objectproperty.h \ common/lc_pagesetupdialog.h \ diff --git a/qt/lc_qutils.h b/qt/lc_qutils.h index 3383e1ee..5e7716a2 100644 --- a/qt/lc_qutils.h +++ b/qt/lc_qutils.h @@ -12,6 +12,8 @@ float lcParseValueLocalized(const QString& Value); #ifdef Q_OS_WIN +#include + int lcTerminateChildProcess(QWidget* Parent, const qint64 Pid, const qint64 Ppid); bool lcRunElevatedProcess(const LPCWSTR ExeName, const LPCWSTR Arguments, const LPCWSTR WorkingFolder);