diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 63a83647..c9ba555b 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -2784,12 +2784,12 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId) case LC_EDIT_SELECT_NONE: if (ActiveModel) - ActiveModel->ClearSelection(true); + ActiveModel->ClearSelection(); break; case LC_EDIT_SELECT_INVERT: if (ActiveModel) - ActiveModel->InvertSelection(); + ActiveModel->InvertPieceSelection(); break; case LC_EDIT_SELECT_BY_NAME: diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 9119050f..e50aff96 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -1734,12 +1734,10 @@ void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::v void lcModel::RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode) { - std::unique_ptr ModelActionSelection = std::make_unique(ModelActionSelectionMode); + std::unique_ptr ModelActionSelection = std::make_unique(ModelActionSelectionMode, mCurrentStep); ModelActionSelection->SetSelection(mPieces, mCameras, mLights); - RunSelectionAction(ModelActionSelection.get(), true); - mActionSequence.emplace_back(std::move(ModelActionSelection)); } @@ -1757,9 +1755,31 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect switch (ModelActionSelection->GetMode()) { - case lcModelActionSelectionMode::Clear: + case lcModelActionSelectionMode::ClearSelection: if (Apply) - ClearSelection(true); + DeselectAllObjects(); + else + LoadSelection(); + break; + + case lcModelActionSelectionMode::SelectAllPieces: + if (Apply) + { + for (const std::unique_ptr& Piece : mPieces) + if (Piece->IsVisible(ModelActionSelection->GetStep())) + Piece->SetSelected(true); + } + else + LoadSelection(); + break; + + case lcModelActionSelectionMode::InvertPieceSelection: + if (Apply) + { + for (const std::unique_ptr& Piece : mPieces) + if (Piece->IsVisible(ModelActionSelection->GetStep())) + Piece->SetSelected(!Piece->IsSelected()); + } else LoadSelection(); break; @@ -1824,8 +1844,6 @@ void lcModel::RecordGroupPiecesAction(lcModelActionGroupPiecesMode Mode, const Q { std::unique_ptr ModelActionGroupPieces = std::make_unique(Mode, GroupName); - RunGroupPiecesAction(ModelActionGroupPieces.get(), true); - mActionSequence.emplace_back(std::move(ModelActionGroupPieces)); } @@ -1901,12 +1919,18 @@ void lcModel::RunGroupPiecesAction(const lcModelActionGroupPieces* ModelActionGr gMainWindow->UpdateSelectedObjects(true); } -void lcModel::PerformActionSequence(const std::vector>& ActionSequence, bool Apply) +void lcModel::RunActionSequence(const std::vector>& ActionSequence, bool Apply) { - auto PerformAction=[this](const lcModelAction* ModelAction, bool Apply) + bool SelectionChanged = false; + + auto RunAction=[this, &SelectionChanged](const lcModelAction* ModelAction, bool Apply) { if (const lcModelActionSelection* ModelActionSelection = dynamic_cast(ModelAction)) + { RunSelectionAction(ModelActionSelection, Apply); + + SelectionChanged = true; + } else if (const lcModelActionObjectEdit* ModelActionObjectEdit = dynamic_cast(ModelAction)) RunObjectEditAction(ModelActionObjectEdit, Apply); else if (const lcModelActionGroupPieces* ModelActionGroupPieces = dynamic_cast(ModelAction)) @@ -1916,13 +1940,16 @@ void lcModel::PerformActionSequence(const std::vectorget(), true); + RunAction(ModelAction->get(), true); } else { for (auto ModelAction = ActionSequence.rbegin(); ModelAction != ActionSequence.rend(); ++ModelAction) - PerformAction(ModelAction->get(), false); + RunAction(ModelAction->get(), false); } + + if (SelectionChanged) + gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } @@ -1934,6 +1961,11 @@ void lcModel::BeginActionSequence() void lcModel::EndActionSequence(const QString& Description) { + if (mActionSequence.empty()) + return; + + RunActionSequence(mActionSequence, true); + std::unique_ptr ModelHistoryEntry = std::make_unique(lcModelHistoryEntry()); ModelHistoryEntry->Description = Description; @@ -1953,7 +1985,7 @@ void lcModel::DiscardActionSequence() void lcModel::RevertActionSequence() { - PerformActionSequence(mActionSequence, false); + RunActionSequence(mActionSequence, false); mActionSequence.clear(); } @@ -1985,7 +2017,7 @@ void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint, bool Apply) { if (!CheckPoint->ModelActions.empty()) { - PerformActionSequence(CheckPoint->ModelActions, Apply); + RunActionSequence(CheckPoint->ModelActions, Apply); return; } @@ -2362,7 +2394,8 @@ void lcModel::ShowEditGroupsDialog() if (Modified) { - ClearSelection(true); + DeselectAllObjects(); + gMainWindow->UpdateSelectedObjects(true); SaveCheckpoint(tr("Editing Groups")); } } @@ -4373,22 +4406,68 @@ std::vector lcModel::GetSelectionModePieces(const lcPiece* SelectedPi return Pieces; } -void lcModel::ClearSelection(bool UpdateInterface) +void lcModel::ClearSelection() +{ + if (!AnyObjectsSelected()) + return; + + BeginActionSequence(); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelection); + EndActionSequence(tr("Selection")); +} + +void lcModel::SelectAllPieces() +{ + bool UnselectedPieces = false; + + for (const std::unique_ptr& Piece : mPieces) + { + if (Piece->IsVisible(mCurrentStep) && !Piece->IsSelected()) + { + UnselectedPieces = true; + break; + } + } + + if (!UnselectedPieces) + return; + + BeginActionSequence(); + RecordSelectionAction(lcModelActionSelectionMode::SelectAllPieces); + EndActionSequence(tr("Selection")); +} + +void lcModel::InvertPieceSelection() +{ + bool VisiblePieces = false; + + for (const std::unique_ptr& Piece : mPieces) + { + if (Piece->IsVisible(mCurrentStep)) + { + VisiblePieces = true; + break; + } + } + + if (!VisiblePieces) + return; + + BeginActionSequence(); + RecordSelectionAction(lcModelActionSelectionMode::InvertPieceSelection); + EndActionSequence(tr("Selection")); +} + +void lcModel::DeselectAllObjects() { for (const std::unique_ptr& Piece : mPieces) Piece->SetSelected(false); - + for (const std::unique_ptr& Camera : mCameras) Camera->SetSelected(false); - + for (const std::unique_ptr& Light : mLights) Light->SetSelected(false); - - if (UpdateInterface) - { - gMainWindow->UpdateSelectedObjects(true); - UpdateAllViews(); - } } void lcModel::SelectGroup(lcGroup* TopGroup, bool Select) @@ -4448,7 +4527,7 @@ void lcModel::FocusOrDeselectObject(const lcObjectSection& ObjectSection) void lcModel::ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool EnableSelectionMode) { - ClearSelection(false); + DeselectAllObjects(); if (Object) { @@ -4479,7 +4558,7 @@ void lcModel::ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection, bo void lcModel::SetSelectionAndFocus(const std::vector& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode) { - ClearSelection(false); + DeselectAllObjects(); if (Focus) { @@ -4596,27 +4675,6 @@ void lcModel::RemoveFromSelection(const lcObjectSection& ObjectSection) UpdateAllViews(); } -void lcModel::SelectAllPieces() -{ - for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(mCurrentStep)) - Piece->SetSelected(true); - - if (!mIsPreview) - gMainWindow->UpdateSelectedObjects(true); - UpdateAllViews(); -} - -void lcModel::InvertSelection() -{ - for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(mCurrentStep)) - Piece->SetSelected(!Piece->IsSelected()); - - gMainWindow->UpdateSelectedObjects(true); - UpdateAllViews(); -} - void lcModel::HideSelectedPieces() { BeginActionSequence(); diff --git a/common/lc_model.h b/common/lc_model.h index cf699d3d..bd38ce8f 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -323,17 +323,17 @@ public: void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const; void GetSelectionInformation(int* Flags, std::vector& Selection, lcObject** Focus) const; std::vector GetSelectionModePieces(const lcPiece* SelectedPiece) const; - + + void ClearSelection(); + void SelectAllPieces(); + void InvertPieceSelection(); void FocusOrDeselectObject(const lcObjectSection& ObjectSection); - void ClearSelection(bool UpdateInterface); void ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool EnableSelectionMode); void ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection, bool EnableSelectionMode); void SetSelectionAndFocus(const std::vector& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode); void AddToSelection(const std::vector& Objects, bool EnableSelectionMode, bool UpdateInterface); void RemoveFromSelection(const std::vector& Objects); void RemoveFromSelection(const lcObjectSection& ObjectSection); - void SelectAllPieces(); - void InvertSelection(); void HideSelectedPieces(); void HideUnselectedPieces(); @@ -415,7 +415,7 @@ protected: void RecordGroupPiecesAction(lcModelActionGroupPiecesMode Mode, const QString& GroupName); void RunGroupPiecesAction(const lcModelActionGroupPieces* ModelActionGroupPieces, bool Apply); - void PerformActionSequence(const std::vector>& ActionSequence, bool Apply); + void RunActionSequence(const std::vector>& ActionSequence, bool Apply); void BeginActionSequence(); void EndActionSequence(const QString& Description); void DiscardActionSequence(); @@ -429,6 +429,7 @@ protected: bool RemoveSelectedObjects(); void RemoveCameraFromViews(lcCamera* Camera); + void DeselectAllObjects(); void SelectGroup(lcGroup* TopGroup, bool Select); size_t AddPiece(lcPiece* Piece); diff --git a/common/lc_modelaction.cpp b/common/lc_modelaction.cpp index f85660ef..7ecdc9f2 100644 --- a/common/lc_modelaction.cpp +++ b/common/lc_modelaction.cpp @@ -182,8 +182,8 @@ bool lcModelAction::LoadHistoryBuffer(const QByteArray& Buffer, lcModel* Model, return true; } -lcModelActionSelection::lcModelActionSelection(lcModelActionSelectionMode Mode) - : mMode(Mode) +lcModelActionSelection::lcModelActionSelection(lcModelActionSelectionMode Mode, lcStep Step) + : mMode(Mode), mStep(Step) { } diff --git a/common/lc_modelaction.h b/common/lc_modelaction.h index 96d17c04..2268d30d 100644 --- a/common/lc_modelaction.h +++ b/common/lc_modelaction.h @@ -20,7 +20,9 @@ protected: enum class lcModelActionSelectionMode { - Clear, + ClearSelection, + SelectAllPieces, + InvertPieceSelection, Set, Save, Restore @@ -29,14 +31,19 @@ enum class lcModelActionSelectionMode class lcModelActionSelection : public lcModelAction { public: - lcModelActionSelection(lcModelActionSelectionMode Mode); + lcModelActionSelection(lcModelActionSelectionMode Mode, lcStep Step); virtual ~lcModelActionSelection() = default; lcModelActionSelectionMode GetMode() const { return mMode; } - + + lcStep GetStep() const + { + return mStep; + } + 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; @@ -47,7 +54,8 @@ protected: size_t mFocusIndex = SIZE_MAX; uint32_t mFocusSection = 0; lcObjectType mFocusType = (lcObjectType)0; - lcModelActionSelectionMode mMode = lcModelActionSelectionMode::Clear; + lcModelActionSelectionMode mMode; + lcStep mStep; }; enum class lcModelActionObjectEditMode diff --git a/common/lc_view.cpp b/common/lc_view.cpp index 76702dd6..bafd34bb 100644 --- a/common/lc_view.cpp +++ b/common/lc_view.cpp @@ -2494,7 +2494,7 @@ void lcView::CancelTrackingOrClearSelection() { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) - ActiveModel->ClearSelection(true); + ActiveModel->ClearSelection(); } }