diff --git a/common/lc_model.cpp b/common/lc_model.cpp index e50aff96..23fe8f1d 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -1230,7 +1230,8 @@ void lcModel::Paste(bool PasteToCurrentStep) SaveCheckpoint(tr("Pasting")); if (SelectedObjects.size() == 1) - ClearSelectionAndSetFocus(SelectedObjects[0], LC_PIECE_SECTION_POSITION, false); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, SelectedObjects.front(), LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); +// ClearSelectionAndSetFocus(SelectedObjects[0], LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); else SetSelectionAndFocus(SelectedObjects, nullptr, 0, false); @@ -1732,13 +1733,12 @@ void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::v Piece->SubModelAddBoundingBoxPoints(WorldMatrix, Points); } -void lcModel::RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode) +void lcModel::RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode) { std::unique_ptr ModelActionSelection = std::make_unique(ModelActionSelectionMode, mCurrentStep); - ModelActionSelection->SetSelection(mPieces, mCameras, mLights); - - mActionSequence.emplace_back(std::move(ModelActionSelection)); + if (ModelActionSelection->Initialize(this, FocusObject, FocusSection, SelectionMode)) + mActionSequence.emplace_back(std::move(ModelActionSelection)); } void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelection, bool Apply) @@ -1752,7 +1752,9 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect SetSelectionAndFocus(SelectedObjects, FocusObject, FocusSection, false); }; - + + lcStep Step = ModelActionSelection->GetStep(); + switch (ModelActionSelection->GetMode()) { case lcModelActionSelectionMode::ClearSelection: @@ -1761,12 +1763,38 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect else LoadSelection(); break; + + case lcModelActionSelectionMode::ClearSelectionAndSetFocus: + if (Apply) + { + DeselectAllObjects(); + + lcObject* NewFocusObject = ModelActionSelection->GetNewFocusObject(this); + + if (NewFocusObject) + { + NewFocusObject->SetFocused(ModelActionSelection->GetNewFocusSection(), true); + + if (NewFocusObject->IsPiece()) + { + lcPiece* Piece = dynamic_cast(NewFocusObject); + + SelectGroup(Piece->GetTopGroup(), Step, true); + + std::vector Pieces = GetSelectionModePieces(ModelActionSelection->GetSelectionMode(), Piece, Step); + SelectObjects(Pieces, Step); + } + } + } + else + LoadSelection(); + break; case lcModelActionSelectionMode::SelectAllPieces: if (Apply) { for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(ModelActionSelection->GetStep())) + if (Piece->IsVisible(Step)) Piece->SetSelected(true); } else @@ -1777,7 +1805,7 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect if (Apply) { for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(ModelActionSelection->GetStep())) + if (Piece->IsVisible(Step)) Piece->SetSelected(!Piece->IsSelected()); } else @@ -2088,7 +2116,7 @@ void lcModel::CalculateStep(lcStep Step) if (!Piece->IsVisible(Step)) Piece->SetSelected(false); else - SelectGroup(Piece->GetTopGroup(), true); + SelectGroup(Piece->GetTopGroup(), Step, true); } } @@ -2266,9 +2294,9 @@ void lcModel::GroupSelection() BeginActionSequence(); - RecordSelectionAction(lcModelActionSelectionMode::Restore); + RecordSelectionAction(lcModelActionSelectionMode::Restore, nullptr, 0, lcSelectionMode::Single); RecordGroupPiecesAction(lcModelActionGroupPiecesMode::Group, Dialog.mName); - RecordSelectionAction(lcModelActionSelectionMode::Save); + RecordSelectionAction(lcModelActionSelectionMode::Save, nullptr, 0, lcSelectionMode::Single); EndActionSequence(tr("Group")); } @@ -2300,9 +2328,9 @@ void lcModel::UngroupSelection() BeginActionSequence(); - RecordSelectionAction(lcModelActionSelectionMode::Restore); + RecordSelectionAction(lcModelActionSelectionMode::Restore, nullptr, 0, lcSelectionMode::Single); RecordGroupPiecesAction(lcModelActionGroupPiecesMode::Ungroup, QString()); - RecordSelectionAction(lcModelActionSelectionMode::Save); + RecordSelectionAction(lcModelActionSelectionMode::Save, nullptr, 0, lcSelectionMode::Single); EndActionSequence(tr("Ungroup")); } @@ -2628,7 +2656,8 @@ lcPiece* lcModel::AddPiece(PieceInfo* Info, quint32 Section) } gMainWindow->UpdateTimeline(false, false); - ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, false); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); +// ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); SaveCheckpoint(tr("Adding Piece")); @@ -3186,7 +3215,8 @@ void lcModel::MoveSelectionToModel(lcModel* Model) SaveCheckpoint(tr("New Model")); gMainWindow->UpdateTimeline(false, false); - ClearSelectionAndSetFocus(ModelPiece, LC_PIECE_SECTION_POSITION, false); +// ClearSelectionAndSetFocus(ModelPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, ModelPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); } void lcModel::InlineSelectedModels() @@ -4373,32 +4403,32 @@ void lcModel::GetSelectionInformation(int* Flags, std::vector& Select } } -std::vector lcModel::GetSelectionModePieces(const lcPiece* SelectedPiece) const +std::vector lcModel::GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece, lcStep Step) const { const PieceInfo* Info = SelectedPiece->mPieceInfo; const int ColorIndex = SelectedPiece->GetColorIndex(); std::vector Pieces; - switch (gMainWindow->GetSelectionMode()) + switch (SelectionMode) { case lcSelectionMode::Single: break; case lcSelectionMode::Piece: for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(mCurrentStep) && Piece->mPieceInfo == Info && Piece.get() != SelectedPiece) + if (Piece->IsVisible(Step) && Piece->mPieceInfo == Info && Piece.get() != SelectedPiece) Pieces.emplace_back(Piece.get()); break; case lcSelectionMode::Color: for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(mCurrentStep) && Piece->GetColorIndex() == ColorIndex && Piece.get() != SelectedPiece) + if (Piece->IsVisible(Step) && Piece->GetColorIndex() == ColorIndex && Piece.get() != SelectedPiece) Pieces.emplace_back(Piece.get()); break; case lcSelectionMode::PieceColor: for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(mCurrentStep) && Piece->mPieceInfo == Info && Piece->GetColorIndex() == ColorIndex && Piece.get() != SelectedPiece) + if (Piece->IsVisible(Step) && Piece->mPieceInfo == Info && Piece->GetColorIndex() == ColorIndex && Piece.get() != SelectedPiece) Pieces.emplace_back(Piece.get()); break; } @@ -4408,53 +4438,29 @@ std::vector lcModel::GetSelectionModePieces(const lcPiece* SelectedPi void lcModel::ClearSelection() { - if (!AnyObjectsSelected()) - return; - BeginActionSequence(); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelection); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelection, nullptr, 0, lcSelectionMode::Single); EndActionSequence(tr("Selection")); } +void lcModel::ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, lcSelectionMode SelectionMode) +{ + BeginActionSequence(); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, Object, Section, SelectionMode); + 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); + RecordSelectionAction(lcModelActionSelectionMode::SelectAllPieces, nullptr, 0, lcSelectionMode::Single); 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); + RecordSelectionAction(lcModelActionSelectionMode::InvertPieceSelection, nullptr, 0, lcSelectionMode::Single); EndActionSequence(tr("Selection")); } @@ -4470,13 +4476,28 @@ void lcModel::DeselectAllObjects() Light->SetSelected(false); } -void lcModel::SelectGroup(lcGroup* TopGroup, bool Select) +void lcModel::SelectObjects(const std::vector& Objects, lcStep Step) +{ + for (lcObject* Object : Objects) + { + const bool WasSelected = Object->IsSelected(); + Object->SetSelected(true); + + if (Object->IsPiece()) + { + if (!WasSelected) + SelectGroup(((lcPiece*)Object)->GetTopGroup(), Step, true); + } + } +} + +void lcModel::SelectGroup(lcGroup* TopGroup, lcStep Step, bool Select) { if (!TopGroup) return; for (const std::unique_ptr& Piece : mPieces) - if (!Piece->IsSelected() && Piece->IsVisible(mCurrentStep) && (Piece->GetTopGroup() == TopGroup)) + if (!Piece->IsSelected() && Piece->IsVisible(Step) && (Piece->GetTopGroup() == TopGroup)) Piece->SetSelected(Select); } @@ -4507,10 +4528,10 @@ void lcModel::FocusOrDeselectObject(const lcObjectSection& ObjectSection) lcPiece* Piece = (lcPiece*)Object; if (gMainWindow->GetSelectionMode() == lcSelectionMode::Single) - SelectGroup(Piece->GetTopGroup(), IsSelected); + SelectGroup(Piece->GetTopGroup(), mCurrentStep, IsSelected); else { - std::vector Pieces = GetSelectionModePieces(Piece); + std::vector Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), Piece, mCurrentStep); AddToSelection(Pieces, false, false); } } @@ -4525,37 +4546,6 @@ void lcModel::FocusOrDeselectObject(const lcObjectSection& ObjectSection) UpdateAllViews(); } -void lcModel::ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool EnableSelectionMode) -{ - DeselectAllObjects(); - - if (Object) - { - Object->SetFocused(Section, true); - - if (Object->IsPiece()) - { - lcPiece* Piece = dynamic_cast(Object); - - SelectGroup(Piece->GetTopGroup(), true); - - if (EnableSelectionMode) - { - std::vector Pieces = GetSelectionModePieces(Piece); - AddToSelection(Pieces, false, false); - } - } - } - - gMainWindow->UpdateSelectedObjects(true); - UpdateAllViews(); -} - -void lcModel::ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection, bool EnableSelectionMode) -{ - ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, EnableSelectionMode); -} - void lcModel::SetSelectionAndFocus(const std::vector& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode) { DeselectAllObjects(); @@ -4566,11 +4556,11 @@ void lcModel::SetSelectionAndFocus(const std::vector& Selection, lcOb if (Focus->IsPiece()) { - SelectGroup(((lcPiece*)Focus)->GetTopGroup(), true); + SelectGroup(((lcPiece*)Focus)->GetTopGroup(), mCurrentStep, true); if (EnableSelectionMode) { - std::vector Pieces = GetSelectionModePieces((lcPiece*)Focus); + std::vector Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), dynamic_cast(Focus), mCurrentStep); AddToSelection(Pieces, false, false); } } @@ -4589,11 +4579,11 @@ void lcModel::AddToSelection(const std::vector& Objects, bool EnableS if (Object->IsPiece()) { if (!WasSelected) - SelectGroup(((lcPiece*)Object)->GetTopGroup(), true); + SelectGroup(((lcPiece*)Object)->GetTopGroup(), mCurrentStep, true); if (EnableSelectionMode) { - std::vector Pieces = GetSelectionModePieces((lcPiece*)Object); + std::vector Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), dynamic_cast(Object), mCurrentStep); AddToSelection(Pieces, false, false); } } @@ -4618,17 +4608,17 @@ void lcModel::RemoveFromSelection(const std::vector& Objects) lcPiece* Piece = (lcPiece*)SelectedObject; if (gMainWindow->GetSelectionMode() == lcSelectionMode::Single) - SelectGroup(Piece->GetTopGroup(), false); + SelectGroup(Piece->GetTopGroup(), mCurrentStep, false); else { - std::vector Pieces = GetSelectionModePieces(Piece); + std::vector Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), Piece, mCurrentStep); for (lcObject* Object : Pieces) { if (Object->IsSelected()) { Object->SetSelected(false); - SelectGroup(((lcPiece*)Object)->GetTopGroup(), false); + SelectGroup(((lcPiece*)Object)->GetTopGroup(), mCurrentStep, false); } } } @@ -4655,17 +4645,17 @@ void lcModel::RemoveFromSelection(const lcObjectSection& ObjectSection) lcPiece* Piece = (lcPiece*)SelectedObject; if (gMainWindow->GetSelectionMode() == lcSelectionMode::Single) - SelectGroup(Piece->GetTopGroup(), false); + SelectGroup(Piece->GetTopGroup(), mCurrentStep, false); else { - std::vector Pieces = GetSelectionModePieces(Piece); + std::vector Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), Piece, mCurrentStep); for (lcObject* Object : Pieces) { if (Object->IsSelected()) { Object->SetSelected(false); - SelectGroup(((lcPiece*)Object)->GetTopGroup(), false); + SelectGroup(((lcPiece*)Object)->GetTopGroup(), mCurrentStep, false); } } } @@ -4912,7 +4902,8 @@ void lcModel::FindReplacePiece(bool SearchForward, bool FindAll, bool Replace) if (FindAll) SetSelectionAndFocus(Selection, nullptr, 0, false); else - ClearSelectionAndSetFocus(Focus, LC_PIECE_SECTION_POSITION, false); +// ClearSelectionAndSetFocus(Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); if (ReplacedCount) { @@ -5100,13 +5091,14 @@ void lcModel::InsertPieceToolClicked(const std::vector& Piece } EndObjectEditAction(std::move(PieceIndices)); + + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + EndActionSequence(tr("Add Piece")); gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateInUseCategory(); - ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, false); - UpdateTrainTrackConnections(Piece, false); } @@ -5121,9 +5113,10 @@ void lcModel::InsertCameraToolClicked(const lcVector3& Position) mCameras.emplace_back(Camera); EndObjectEditAction({ mCameras.size() - 1 }); - EndActionSequence(tr("Add Camera")); - ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_POSITION, false); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, Camera, LC_CAMERA_SECTION_POSITION, lcSelectionMode::Single); + + EndActionSequence(tr("Add Camera")); } void lcModel::InsertLightToolClicked(const lcVector3& Position, lcLightType LightType) @@ -5161,9 +5154,10 @@ void lcModel::InsertLightToolClicked(const lcVector3& Position, lcLightType Ligh mLights.emplace_back(Light); EndObjectEditAction({ mLights.size() - 1 }); - EndActionSequence(ActionName); - ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION, false); + RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, Light, LC_LIGHT_SECTION_POSITION, lcSelectionMode::Single); + + EndActionSequence(ActionName); } void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag) diff --git a/common/lc_model.h b/common/lc_model.h index bd38ce8f..79f60fb7 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -322,14 +322,13 @@ public: void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList, bool Cumulative) const; 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 ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, lcSelectionMode SelectionMode); void SelectAllPieces(); void InvertPieceSelection(); + // to update: void FocusOrDeselectObject(const lcObjectSection& ObjectSection); - 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); @@ -407,7 +406,7 @@ public: protected: void DeleteModel(); - void RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode); + void RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode); void RunSelectionAction(const lcModelActionSelection* ModelActionSelection, bool Apply); void BeginObjectEditAction(lcModelActionObjectEditMode ModelActionObjectEditMode, const lcCamera* Camera); void EndObjectEditAction(std::vector&& ObjectIndices = std::vector(), std::vector&& GroupIndices = std::vector()); @@ -428,9 +427,11 @@ protected: void RemoveEmptyGroups(); bool RemoveSelectedObjects(); void RemoveCameraFromViews(lcCamera* Camera); - + + std::vector GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece, lcStep Step) const; void DeselectAllObjects(); - void SelectGroup(lcGroup* TopGroup, bool Select); + void SelectObjects(const std::vector& Objects, lcStep Step); + void SelectGroup(lcGroup* TopGroup, lcStep Step, bool Select); size_t AddPiece(lcPiece* Piece); diff --git a/common/lc_modelaction.cpp b/common/lc_modelaction.cpp index 7ecdc9f2..e38a81a3 100644 --- a/common/lc_modelaction.cpp +++ b/common/lc_modelaction.cpp @@ -187,11 +187,80 @@ lcModelActionSelection::lcModelActionSelection(lcModelActionSelectionMode Mode, { } -void lcModelActionSelection::SetSelection(const std::vector>& Pieces, const std::vector>& Cameras, const std::vector>& Lights) +bool lcModelActionSelection::Initialize(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode) { - mSelectedPieces.clear(); - mSelectedCameras.clear(); - mSelectedLights.clear(); + if (!HasChanges(Model, FocusObject, FocusSection)) + return false; + + mSelectionMode = SelectionMode; + + SaveSelection(Model); + SaveNewFocusObject(Model, FocusObject, FocusSection); + + return true; +} + +bool lcModelActionSelection::HasChanges(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection) const +{ + const std::vector>& Pieces = Model->GetPieces(); + const std::vector>& Cameras = Model->GetCameras(); + const std::vector>& Lights = Model->GetLights(); + + switch (mMode) + { + case lcModelActionSelectionMode::ClearSelection: + return Model->AnyObjectsSelected(); + + case lcModelActionSelectionMode::ClearSelectionAndSetFocus: + if (FocusObject && !FocusObject->IsFocused(FocusSection)) + return true; + + for (const std::unique_ptr& Piece : Pieces) + if (Piece->IsSelected() && Piece.get() != FocusObject) + return true; + + for (const std::unique_ptr& Camera : Cameras) + if (Camera->IsSelected() && Camera.get() != FocusObject) + return true; + + for (const std::unique_ptr& Light : Lights) + if (Light->IsSelected() && Light.get() != FocusObject) + return true; + + return false; + + case lcModelActionSelectionMode::SelectAllPieces: + for (const std::unique_ptr& Piece : Pieces) + if (Piece->IsVisible(mStep) && !Piece->IsSelected()) + return true; + + return false; + + case lcModelActionSelectionMode::InvertPieceSelection: + for (const std::unique_ptr& Piece : Pieces) + if (Piece->IsVisible(mStep)) + return true; + + return false; + + case lcModelActionSelectionMode::Set: + case lcModelActionSelectionMode::Save: + case lcModelActionSelectionMode::Restore: + break; + } + + return true; +} + +void lcModelActionSelection::SaveSelection(const lcModel* Model) +{ + const std::vector>& Pieces = Model->GetPieces(); + const std::vector>& Cameras = Model->GetCameras(); + const std::vector>& Lights = Model->GetLights(); + + mPreviousSelectedPieces.clear(); + mPreviousSelectedCameras.clear(); + mPreviousSelectedLights.clear(); for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++) { @@ -200,13 +269,13 @@ void lcModelActionSelection::SetSelection(const std::vectorIsSelected()) continue; - mSelectedPieces.push_back(PieceIndex); + mPreviousSelectedPieces.push_back(PieceIndex); if (Piece->IsFocused()) { - mFocusIndex = PieceIndex; - mFocusSection = Piece->GetFocusSection(); - mFocusType = lcObjectType::Piece; + mPreviousFocusIndex = PieceIndex; + mPreviousFocusSection = Piece->GetFocusSection(); + mPreviousFocusObjectType = lcObjectType::Piece; } } @@ -217,13 +286,13 @@ void lcModelActionSelection::SetSelection(const std::vectorIsSelected()) continue; - mSelectedCameras.push_back(CameraIndex); + mPreviousSelectedCameras.push_back(CameraIndex); if (Camera->IsFocused()) { - mFocusIndex = CameraIndex; - mFocusSection = Camera->GetFocusSection(); - mFocusType = lcObjectType::Camera; + mPreviousFocusIndex = CameraIndex; + mPreviousFocusSection = Camera->GetFocusSection(); + mPreviousFocusObjectType = lcObjectType::Camera; } } @@ -236,50 +305,142 @@ void lcModelActionSelection::SetSelection(const std::vectorIsFocused()) { - mFocusIndex = LightIndex; - mFocusSection = Light->GetFocusSection(); - mFocusType = lcObjectType::Light; + mPreviousFocusIndex = LightIndex; + mPreviousFocusSection = Light->GetFocusSection(); + mPreviousFocusObjectType = lcObjectType::Light; } } } +void lcModelActionSelection::SaveNewFocusObject(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection) +{ + if (!FocusObject) + return; + + mNewFocusSection = FocusSection; + mNewFocusObjectType = FocusObject->GetType(); + + switch (FocusObject->GetType()) + { + case lcObjectType::Piece: + { + const std::vector>& Pieces = Model->GetPieces(); + + for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++) + { + if (Pieces[PieceIndex].get() == FocusObject) + { + mNewFocusIndex = PieceIndex; + break; + } + } + } + break; + + case lcObjectType::Camera: + { + const std::vector>& Cameras = Model->GetCameras(); + + for (size_t CameraIndex = 0; CameraIndex < Cameras.size(); CameraIndex++) + { + if (Cameras[CameraIndex].get() == FocusObject) + { + mNewFocusIndex = CameraIndex; + break; + } + } + } + break; + + case lcObjectType::Light: + { + const std::vector>& Lights = Model->GetLights(); + + for (size_t LightIndex = 0; LightIndex < Lights.size(); LightIndex++) + { + if (Lights[LightIndex].get() == FocusObject) + { + mNewFocusIndex = LightIndex; + break; + } + } + } + break; + } +} + +lcObject* lcModelActionSelection::GetNewFocusObject(const lcModel* Model) const +{ + switch (mNewFocusObjectType) + { + case lcObjectType::Piece: + { + const std::vector>& Pieces = Model->GetPieces(); + + if (mNewFocusIndex < Pieces.size()) + return Pieces[mNewFocusIndex].get(); + } + break; + + case lcObjectType::Camera: + { + const std::vector>& Cameras = Model->GetCameras(); + + if (mNewFocusIndex < Cameras.size()) + return Cameras[mNewFocusIndex].get(); + } + break; + + case lcObjectType::Light: + { + const std::vector>& Lights = Model->GetLights(); + + if (mNewFocusIndex < Lights.size()) + return Lights[mNewFocusIndex].get(); + } + break; + } + + return nullptr; +} + 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) + for (size_t PieceIndex : mPreviousSelectedPieces) if (PieceIndex < Pieces.size()) SelectedObjects.push_back(Pieces[PieceIndex].get()); - for (size_t CameraIndex : mSelectedCameras) + for (size_t CameraIndex : mPreviousSelectedCameras) if (CameraIndex < Cameras.size()) SelectedObjects.push_back(Cameras[CameraIndex].get()); - for (size_t LightIndex : mSelectedLights) + for (size_t LightIndex : mPreviousSelectedLights) if (LightIndex < Lights.size()) SelectedObjects.push_back(Lights[LightIndex].get()); - if (mFocusIndex != SIZE_MAX) + if (mPreviousFocusIndex != SIZE_MAX) { - switch (mFocusType) + switch (mPreviousFocusObjectType) { case lcObjectType::Piece: - if (mFocusIndex < Pieces.size()) - FocusObject = Pieces[mFocusIndex].get(); + if (mPreviousFocusIndex < Pieces.size()) + FocusObject = Pieces[mPreviousFocusIndex].get(); break; case lcObjectType::Camera: - if (mFocusIndex < Cameras.size()) - FocusObject = Cameras[mFocusIndex].get(); + if (mPreviousFocusIndex < Cameras.size()) + FocusObject = Cameras[mPreviousFocusIndex].get(); break; case lcObjectType::Light: - if (mFocusIndex < Lights.size()) - FocusObject = Lights[mFocusIndex].get(); + if (mPreviousFocusIndex < Lights.size()) + FocusObject = Lights[mPreviousFocusIndex].get(); break; } } - return { SelectedObjects, FocusObject, mFocusSection }; + return { SelectedObjects, FocusObject, mPreviousFocusSection }; } lcModelActionObjectEdit::lcModelActionObjectEdit(lcModelActionObjectEditMode Mode) diff --git a/common/lc_modelaction.h b/common/lc_modelaction.h index 2268d30d..d406600e 100644 --- a/common/lc_modelaction.h +++ b/common/lc_modelaction.h @@ -1,6 +1,7 @@ #pragma once enum class lcObjectType; +enum class lcSelectionMode; class lcModelAction { @@ -21,6 +22,7 @@ protected: enum class lcModelActionSelectionMode { ClearSelection, + ClearSelectionAndSetFocus, SelectAllPieces, InvertPieceSelection, Set, @@ -33,7 +35,9 @@ class lcModelActionSelection : public lcModelAction public: lcModelActionSelection(lcModelActionSelectionMode Mode, lcStep Step); virtual ~lcModelActionSelection() = default; - + + bool Initialize(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode); + lcModelActionSelectionMode GetMode() const { return mMode; @@ -44,16 +48,36 @@ public: return mStep; } - void SetSelection(const std::vector>& Pieces, const std::vector>& Cameras, const std::vector>& Lights); + lcSelectionMode GetSelectionMode() const + { + return mSelectionMode; + } + + uint32_t GetNewFocusSection() const + { + return mNewFocusSection; + } + + lcObject* GetNewFocusObject(const lcModel* Model) const; 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; + bool HasChanges(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection) const; + void SaveSelection(const lcModel* Model); + void SaveNewFocusObject(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection); + + std::vector mPreviousSelectedPieces; + std::vector mPreviousSelectedCameras; + std::vector mPreviousSelectedLights; + size_t mPreviousFocusIndex = SIZE_MAX; + uint32_t mPreviousFocusSection = 0; + lcObjectType mPreviousFocusObjectType = (lcObjectType)0; + + size_t mNewFocusIndex = SIZE_MAX; + uint32_t mNewFocusSection = 0; + lcObjectType mNewFocusObjectType = (lcObjectType)0; + lcSelectionMode mSelectionMode = (lcSelectionMode)0; + lcModelActionSelectionMode mMode; lcStep mStep; }; diff --git a/common/lc_view.cpp b/common/lc_view.cpp index bafd34bb..6789891a 100644 --- a/common/lc_view.cpp +++ b/common/lc_view.cpp @@ -2577,7 +2577,7 @@ void lcView::OnButtonDown(lcTrackButton TrackButton) else if (mMouseModifiers & Qt::ShiftModifier) ActiveModel->RemoveFromSelection(ObjectSection); else - ActiveModel->ClearSelectionAndSetFocus(ObjectSection, true); + ActiveModel->ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); StartTracking(TrackButton); } @@ -2643,7 +2643,7 @@ void lcView::OnButtonDown(lcTrackButton TrackButton) ObjectSection.Object = Focus; ObjectSection.Section = mTrackToolSection; - ActiveModel->ClearSelectionAndSetFocus(ObjectSection, true); + ActiveModel->ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); } break; @@ -2741,7 +2741,7 @@ void lcView::OnLeftButtonDoubleClick() else if (mMouseModifiers & Qt::ShiftModifier) ActiveModel->RemoveFromSelection(ObjectSection); else - ActiveModel->ClearSelectionAndSetFocus(ObjectSection, true); + ActiveModel->ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); } void lcView::OnMiddleButtonDown()