diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 696b1bf9..4ae92658 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -1230,11 +1230,9 @@ void lcModel::Paste(bool PasteToCurrentStep) SaveCheckpoint(tr("Pasting")); if (SelectedObjects.size() == 1) - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), SelectedObjects.front(), LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); -// ClearSelectionAndSetFocus(SelectedObjects[0], LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector(), SelectedObjects.front(), LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); else RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, SelectedObjects, nullptr, 0, lcSelectionMode::Single); -// SetSelectionAndFocus(SelectedObjects, nullptr, 0, false); CalculateStep(mCurrentStep); gMainWindow->UpdateTimeline(false, false); @@ -1738,9 +1736,57 @@ void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::v void lcModel::RecordSelectionAction(lcModelActionSelectionMode ModelActionSelectionMode, const std::vector& Objects, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode) { - std::unique_ptr ModelActionSelection = std::make_unique(ModelActionSelectionMode, mCurrentStep); + std::unique_ptr ModelActionSelection = std::make_unique(ModelActionSelectionMode); + bool ForceAdd = false; - if (ModelActionSelection->Initialize(this, Objects, FocusObject, FocusSection, SelectionMode)) + ModelActionSelection->SaveStartState(this); + + switch (ModelActionSelectionMode) + { + case lcModelActionSelectionMode::ClearSelection: + DeselectAllObjects(); + break; + + case lcModelActionSelectionMode::SetSelectionAndFocus: + DeselectAllObjects(); + SetObjectsSelected(Objects, true); + SetFocusedObject(FocusObject, FocusSection, SelectionMode); + break; + + case lcModelActionSelectionMode::SetFocus: + SetFocusedObject(FocusObject, FocusSection, SelectionMode); + break; + + case lcModelActionSelectionMode::SelectAllPieces: + for (const std::unique_ptr& Piece : mPieces) + if (Piece->IsVisible(mCurrentStep)) + Piece->SetSelected(true); + break; + + case lcModelActionSelectionMode::InvertPieceSelection: + for (const std::unique_ptr& Piece : mPieces) + if (Piece->IsSelected() || Piece->IsVisible(mCurrentStep)) + Piece->SetSelected(!Piece->IsSelected()); + break; + + case lcModelActionSelectionMode::AddToSelection: + SetObjectsSelected(Objects, true); + break; + + case lcModelActionSelectionMode::RemoveFromSelection: + SetObjectsSelected(Objects, false); + break; + + case lcModelActionSelectionMode::Set: + case lcModelActionSelectionMode::Save: + case lcModelActionSelectionMode::Restore: + ForceAdd = true; + break; + } + + ModelActionSelection->SaveEndState(this); + + if (ForceAdd || ModelActionSelection->StateChanged()) mActionSequence.emplace_back(std::move(ModelActionSelection)); } @@ -1749,188 +1795,33 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect if (!ModelActionSelection) return; - lcStep Step = ModelActionSelection->GetStep(); - - auto AddToSelection=[this](const std::vector& Objects, lcSelectionMode SelectionMode, lcStep Step) - { - for (lcObject* Object : Objects) - { - if (Object->IsSelected()) - continue; - - Object->SetSelected(true); - - if (Object->IsPiece()) - { - lcPiece* Piece = dynamic_cast(Object); - - SelectGroup(Piece->GetTopGroup(), true); - - std::vector Pieces = GetSelectionModePieces(SelectionMode, Piece, Step); - SelectObjects(Pieces, true); - } - } - }; - - auto SetSelectionAndFocus=[this, &AddToSelection](const std::vector& Objects, lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode, lcStep Step) - { - DeselectAllObjects(); - - if (Focus) - { - Focus->SetFocused(Section, true); - - if (Focus->IsPiece()) - { - lcPiece* Piece = dynamic_cast(Focus); - - SelectGroup(Piece->GetTopGroup(), true); - - std::vector Pieces = GetSelectionModePieces(SelectionMode, Piece, Step); - SelectObjects(Pieces, true); - } - } - - AddToSelection(Objects, SelectionMode, Step); - }; - - auto LoadPreviousSelection = [this, ModelActionSelection, Step, &SetSelectionAndFocus]() - { - auto [SelectedObjects, FocusObject, FocusSection] = ModelActionSelection->GetPreviousSelection(this); - - SetSelectionAndFocus(SelectedObjects, FocusObject, FocusSection, lcSelectionMode::Single, Step); - }; - switch (ModelActionSelection->GetMode()) { case lcModelActionSelectionMode::ClearSelection: - if (Apply) - DeselectAllObjects(); - else - LoadPreviousSelection(); - break; - - case lcModelActionSelectionMode::ClearSelectionAndSetFocus: case lcModelActionSelectionMode::SetSelectionAndFocus: - if (Apply) - { - std::vector Objects = ModelActionSelection->GetNewObjects(this); - lcObject* Focus = ModelActionSelection->GetNewFocusObject(this); - uint32_t Section = ModelActionSelection->GetNewFocusSection(); - lcSelectionMode SelectionMode = ModelActionSelection->GetSelectionMode(); - - SetSelectionAndFocus(Objects, Focus, Section, SelectionMode, Step); - } - else - LoadPreviousSelection(); - break; - case lcModelActionSelectionMode::SetFocus: - if (Apply) - { - lcObject* Focus = ModelActionSelection->GetNewFocusObject(this); - uint32_t Section = ModelActionSelection->GetNewFocusSection(); - lcSelectionMode SelectionMode = ModelActionSelection->GetSelectionMode(); - - lcObject* PreviousFocus = GetFocusObject(); - - if (PreviousFocus && PreviousFocus != Focus) - PreviousFocus->SetFocused(PreviousFocus->GetFocusSection(), false); - - if (Focus) - { - const bool WasSelected = Focus->IsSelected(); - - Focus->SetFocused(Section, true); - - if (Focus->IsPiece() && !WasSelected) - { - lcPiece* Piece = dynamic_cast(Focus); - - SelectGroup(Piece->GetTopGroup(), true); - - std::vector Pieces = GetSelectionModePieces(SelectionMode, Piece, Step); - SelectObjects(Pieces, true); - } - } - } - else - LoadPreviousSelection(); - break; - case lcModelActionSelectionMode::SelectAllPieces: - if (Apply) - { - for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsVisible(Step)) - Piece->SetSelected(true); - } - else - LoadPreviousSelection(); - break; - case lcModelActionSelectionMode::InvertPieceSelection: - if (Apply) - { - for (const std::unique_ptr& Piece : mPieces) - if (Piece->IsSelected() || Piece->IsVisible(Step)) - Piece->SetSelected(!Piece->IsSelected()); - } - else - LoadPreviousSelection(); - break; - case lcModelActionSelectionMode::AddToSelection: - if (Apply) - { - std::vector Objects = ModelActionSelection->GetNewObjects(this); - lcSelectionMode SelectionMode = ModelActionSelection->GetSelectionMode(); - - AddToSelection(Objects, SelectionMode, Step); - } - else - LoadPreviousSelection(); - break; - case lcModelActionSelectionMode::RemoveFromSelection: if (Apply) - { - std::vector Objects = ModelActionSelection->GetNewObjects(this); - - for (lcObject* Object : Objects) - { - if (!Object->IsSelected()) - continue; - - Object->SetSelected(false); - - if (Object->IsPiece()) - { - lcPiece* Piece = dynamic_cast(Object); - - SelectGroup(Piece->GetTopGroup(), false); - - std::vector Pieces = GetSelectionModePieces(ModelActionSelection->GetSelectionMode(), Piece, Step); - SelectObjects(Pieces, false); - } - } - } + ModelActionSelection->LoadEndState(this); else - LoadPreviousSelection(); + ModelActionSelection->LoadStartState(this); break; case lcModelActionSelectionMode::Set: - LoadPreviousSelection(); + ModelActionSelection->LoadStartState(this); break; case lcModelActionSelectionMode::Save: if (!Apply) - LoadPreviousSelection(); + ModelActionSelection->LoadStartState(this); break; case lcModelActionSelectionMode::Restore: if (Apply) - LoadPreviousSelection(); + ModelActionSelection->LoadStartState(this); break; } } @@ -2099,8 +1990,6 @@ void lcModel::EndActionSequence(const QString& Description) if (mActionSequence.empty()) return; - RunActionSequence(mActionSequence, true); - std::unique_ptr ModelHistoryEntry = std::make_unique(lcModelHistoryEntry()); ModelHistoryEntry->Description = Description; @@ -2111,6 +2000,8 @@ void lcModel::EndActionSequence(const QString& Description) gMainWindow->UpdateModified(IsModified()); gMainWindow->UpdateUndoRedo(!mUndoHistory.empty() ? mUndoHistory.front()->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory.front()->Description : nullptr); + + UpdateAllViews(); } void lcModel::DiscardActionSequence() @@ -2743,8 +2634,7 @@ lcPiece* lcModel::AddPiece(PieceInfo* Info, quint32 Section) } gMainWindow->UpdateTimeline(false, false); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); -// ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector(), Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); SaveCheckpoint(tr("Adding Piece")); @@ -3295,8 +3185,8 @@ void lcModel::MoveSelectionToModel(lcModel* Model) SaveCheckpoint(tr("New Model")); gMainWindow->UpdateTimeline(false, false); -// ClearSelectionAndSetFocus(ModelPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), ModelPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + + RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector(), ModelPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); } void lcModel::InlineSelectedModels() @@ -4470,39 +4360,6 @@ void lcModel::GetSelectionInformation(int* Flags, std::vector& Select } } -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 (SelectionMode) - { - case lcSelectionMode::Single: - break; - - case lcSelectionMode::Piece: - for (const std::unique_ptr& Piece : mPieces) - 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(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(Step) && Piece->mPieceInfo == Info && Piece->GetColorIndex() == ColorIndex && Piece.get() != SelectedPiece) - Pieces.emplace_back(Piece.get()); - break; - } - - return Pieces; -} - void lcModel::ClearSelection() { BeginActionSequence(); @@ -4510,13 +4367,6 @@ void lcModel::ClearSelection() EndActionSequence(tr("Selection")); } -void lcModel::ClearSelectionAndSetFocus(lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode) -{ - BeginActionSequence(); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), Focus, Section, SelectionMode); - EndActionSequence(tr("Selection")); -} - void lcModel::SetSelectionAndFocus(const std::vector& Objects, lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode) { BeginActionSequence(); @@ -4557,20 +4407,53 @@ void lcModel::InvertPieceSelection() EndActionSequence(tr("Selection")); } -void lcModel::AddToSelection(const std::vector& Objects, lcSelectionMode SelectionMode) +void lcModel::AddToSelection(const std::vector& Objects) { BeginActionSequence(); - RecordSelectionAction(lcModelActionSelectionMode::AddToSelection, Objects, nullptr, 0, SelectionMode); + RecordSelectionAction(lcModelActionSelectionMode::AddToSelection, Objects, nullptr, 0, lcSelectionMode::Single); EndActionSequence(tr("Selection")); } -void lcModel::RemoveFromSelection(const std::vector& Objects, lcSelectionMode SelectionMode) +void lcModel::RemoveFromSelection(const std::vector& Objects) { BeginActionSequence(); - RecordSelectionAction(lcModelActionSelectionMode::RemoveFromSelection, Objects, nullptr, 0, SelectionMode); + RecordSelectionAction(lcModelActionSelectionMode::RemoveFromSelection, Objects, nullptr, 0, lcSelectionMode::Single); EndActionSequence(tr("Selection")); } +std::vector lcModel::GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece) const +{ + const PieceInfo* Info = SelectedPiece->mPieceInfo; + const int ColorIndex = SelectedPiece->GetColorIndex(); + std::vector Pieces; + + 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) + 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) + 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) + Pieces.emplace_back(Piece.get()); + break; + } + + return Pieces; +} + void lcModel::DeselectAllObjects() { for (const std::unique_ptr& Piece : mPieces) @@ -4583,17 +4466,46 @@ void lcModel::DeselectAllObjects() Light->SetSelected(false); } -void lcModel::SelectObjects(const std::vector& Objects, bool Select) +void lcModel::SetFocusedObject(lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode) +{ + lcObject* PreviousFocus = GetFocusObject(); + + if (PreviousFocus) + PreviousFocus->SetFocused(PreviousFocus->GetFocusSection(), false); + + if (FocusObject) + { + lcPiece* Piece = dynamic_cast(FocusObject); + + if (Piece) + { + if (!Piece->IsSelected()) + SetObjectsSelected({ Piece }, true); + + std::vector Pieces = GetSelectionModePieces(SelectionMode, Piece); + + SetObjectsSelected(Pieces, true); + } + + FocusObject->SetFocused(FocusSection, true); + } +} + +void lcModel::SetObjectsSelected(const std::vector& Objects, bool Selected) { for (lcObject* Object : Objects) { - if (Object->IsSelected() == Select) + if (Object->IsSelected() == Selected) continue; - Object->SetSelected(Select); + Object->SetSelected(Selected); if (Object->IsPiece()) - SelectGroup(dynamic_cast(Object)->GetTopGroup(), Select); + { + lcPiece* Piece = dynamic_cast(Object); + + SelectGroup(Piece->GetTopGroup(), Selected); + } } } @@ -4842,11 +4754,9 @@ void lcModel::FindReplacePiece(bool SearchForward, bool FindAll, bool Replace) } if (FindAll) -// SetSelectionAndFocus(Selection, nullptr, 0, false); RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, Selection, nullptr, 0, lcSelectionMode::Single); else -// ClearSelectionAndSetFocus(Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector(), Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); if (ReplacedCount) { @@ -5035,7 +4945,7 @@ void lcModel::InsertPieceToolClicked(const std::vector& Piece EndObjectEditAction(std::move(PieceIndices)); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector(), Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); EndActionSequence(tr("Add Piece")); @@ -5057,7 +4967,7 @@ void lcModel::InsertCameraToolClicked(const lcVector3& Position) EndObjectEditAction({ mCameras.size() - 1 }); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), Camera, LC_CAMERA_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector(), Camera, LC_CAMERA_SECTION_POSITION, lcSelectionMode::Single); EndActionSequence(tr("Add Camera")); } @@ -5098,7 +5008,7 @@ void lcModel::InsertLightToolClicked(const lcVector3& Position, lcLightType Ligh EndObjectEditAction({ mLights.size() - 1 }); - RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector(), Light, LC_LIGHT_SECTION_POSITION, lcSelectionMode::Single); + RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector(), Light, LC_LIGHT_SECTION_POSITION, lcSelectionMode::Single); EndActionSequence(ActionName); } diff --git a/common/lc_model.h b/common/lc_model.h index ec699dff..98482d7a 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -324,13 +324,12 @@ public: void GetSelectionInformation(int* Flags, std::vector& Selection, lcObject** Focus) const; void ClearSelection(); - void ClearSelectionAndSetFocus(lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode); void SetSelectionAndFocus(const std::vector& Selection, lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode); void FocusOrDeselectObject(lcObject* Object, uint32_t Section, lcSelectionMode SelectionMode); void SelectAllPieces(); void InvertPieceSelection(); - void AddToSelection(const std::vector& Objects, lcSelectionMode SelectionMode); - void RemoveFromSelection(const std::vector& Objects, lcSelectionMode SelectionMode); + void AddToSelection(const std::vector& Objects); + void RemoveFromSelection(const std::vector& Objects); void HideSelectedPieces(); void HideUnselectedPieces(); @@ -426,9 +425,10 @@ protected: bool RemoveSelectedObjects(); void RemoveCameraFromViews(lcCamera* Camera); - std::vector GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece, lcStep Step) const; + std::vector GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece) const; void DeselectAllObjects(); - void SelectObjects(const std::vector& Objects, bool Select); + void SetFocusedObject(lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode); + void SetObjectsSelected(const std::vector& Objects, bool Selected); void SelectGroup(lcGroup* TopGroup, bool Select); size_t AddPiece(lcPiece* Piece); diff --git a/common/lc_modelaction.cpp b/common/lc_modelaction.cpp index e8a0a647..db3e66d5 100644 --- a/common/lc_modelaction.cpp +++ b/common/lc_modelaction.cpp @@ -182,186 +182,34 @@ bool lcModelAction::LoadHistoryBuffer(const QByteArray& Buffer, lcModel* Model, return true; } -lcModelActionSelection::lcModelActionSelection(lcModelActionSelectionMode Mode, lcStep Step) - : mMode(Mode), mStep(Step) +lcModelActionSelection::lcModelActionSelection(lcModelActionSelectionMode Mode) + : mMode(Mode) { } -bool lcModelActionSelection::Initialize(const lcModel* Model, const std::vector& Objects, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode) +void lcModelActionSelection::SaveStartState(const lcModel* Model) { - if (!HasChanges(Model, Objects, FocusObject, FocusSection)) - return false; - - mSelectionMode = SelectionMode; - SaveState(mStartState, Model); - SaveNewObjects(Objects, Model); - SaveNewFocusObject(Model, FocusObject, FocusSection); - - return true; } -size_t lcModelActionSelection::GetObjectIndex(const lcObject* Object, const lcModel* Model) +void lcModelActionSelection::SaveEndState(const lcModel* Model) { - switch (Object->GetType()) - { - case lcObjectType::Piece: - { - const std::vector>& Pieces = Model->GetPieces(); - - for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++) - if (Pieces[PieceIndex].get() == Object) - return PieceIndex; - } - break; - - case lcObjectType::Camera: - { - const std::vector>& Cameras = Model->GetCameras(); - - for (size_t CameraIndex = 0; CameraIndex < Cameras.size(); CameraIndex++) - if (Cameras[CameraIndex].get() == Object) - return CameraIndex; - } - break; - - case lcObjectType::Light: - { - const std::vector>& Lights = Model->GetLights(); - - for (size_t LightIndex = 0; LightIndex < Lights.size(); LightIndex++) - if (Lights[LightIndex].get() == Object) - return LightIndex; - } - break; - } - - return SIZE_MAX; + SaveState(mEndState, Model); } -bool lcModelActionSelection::HasChanges(const lcModel* Model, const std::vector& Objects, lcObject* FocusObject, uint32_t FocusSection) const +void lcModelActionSelection::LoadStartState(lcModel* Model) const { - const std::vector>& Pieces = Model->GetPieces(); - const std::vector>& Cameras = Model->GetCameras(); - const std::vector>& Lights = Model->GetLights(); - - auto HasSelectionChanges=[&Objects, FocusObject, FocusSection](lcObject* CheckObject) - { - if (CheckObject->IsFocused()) - { - if (CheckObject != FocusObject || CheckObject->GetFocusSection() != FocusSection) - return true; - } - else - { - if (CheckObject == FocusObject) - return true; - } - - if (CheckObject == FocusObject || std::find(Objects.begin(), Objects.end(), CheckObject) != Objects.end()) - { - if (!CheckObject->IsSelected()) - return true; - } - else - { - if (CheckObject->IsSelected()) - return true; - } - - return false; - }; - - 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::SetFocus: - if (FocusObject) - { - if (!FocusObject->IsFocused(FocusSection)) - return true; - } - else - { - if (Model->GetFocusObject()) - return true; - } - - return false; - - case lcModelActionSelectionMode::SetSelectionAndFocus: - if (FocusObject && !FocusObject->IsFocused(FocusSection)) - return true; + LoadState(mStartState, Model); +} - for (const std::unique_ptr& Piece : Pieces) - if (HasSelectionChanges(Piece.get())) - return true; - - for (const std::unique_ptr& Camera : Cameras) - if (HasSelectionChanges(Camera.get())) - return true; - - for (const std::unique_ptr& Light : Lights) - if (HasSelectionChanges(Light.get())) - return true; - - return false; +void lcModelActionSelection::LoadEndState(lcModel* Model) const +{ + LoadState(mEndState, Model); +} - 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::AddToSelection: - for (lcObject* Object : Objects) - if (!Object->IsSelected()) - return true; - - return false; - - case lcModelActionSelectionMode::RemoveFromSelection: - for (lcObject* Object : Objects) - if (Object->IsSelected()) - return true; - - return false; - - case lcModelActionSelectionMode::Set: - case lcModelActionSelectionMode::Save: - case lcModelActionSelectionMode::Restore: - break; - } - - return true; +bool lcModelActionSelection::StateChanged() const +{ + return mStartState != mEndState; } void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const lcModel* Model) @@ -369,7 +217,7 @@ void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const State = lcModelActionSelectionState(); const std::vector>& Pieces = Model->GetPieces(); - State.SelectedPieces.resize(Pieces.size(), false); + State.PieceSelection.resize(Pieces.size(), false); for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++) { @@ -378,7 +226,7 @@ void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const if (!Piece->IsSelected()) continue; - State.SelectedPieces[PieceIndex] = true; + State.PieceSelection[PieceIndex] = true; if (Piece->IsFocused()) { @@ -389,7 +237,7 @@ void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const } const std::vector>& Cameras = Model->GetCameras(); - State.SelectedCameras.resize(Cameras.size(), false); + State.CameraSelection.resize(Cameras.size(), false); for (size_t CameraIndex = 0; CameraIndex < Cameras.size(); CameraIndex++) { @@ -398,7 +246,7 @@ void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const if (!Camera->IsSelected()) continue; - State.SelectedCameras[CameraIndex] = true; + State.CameraSelection[CameraIndex] = true; if (Camera->IsFocused()) { @@ -409,7 +257,7 @@ void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const } const std::vector>& Lights = Model->GetLights(); - State.SelectedLights.resize(Lights.size(), false); + State.LightSelection.resize(Lights.size(), false); for (size_t LightIndex = 0; LightIndex < Lights.size(); LightIndex++) { @@ -418,7 +266,7 @@ void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const if (!Light->IsSelected()) continue; - State.SelectedLights[LightIndex] = true; + State.LightSelection[LightIndex] = true; if (Light->IsFocused()) { @@ -429,129 +277,50 @@ void lcModelActionSelection::SaveState(lcModelActionSelectionState& State, const } } -void lcModelActionSelection::SaveNewObjects(const std::vector& Objects, const lcModel* Model) +void lcModelActionSelection::LoadState(const lcModelActionSelectionState& State, lcModel* Model) { - mNewObjects.clear(); - mNewObjects.reserve(Objects.size()); - - for (lcObject* Object : Objects) - mNewObjects.emplace_back(GetObjectIndex(Object, Model), Object->GetType()); -} + const std::vector>& Pieces = Model->GetPieces(); + const std::vector>& Cameras = Model->GetCameras(); + const std::vector>& Lights = Model->GetLights(); -void lcModelActionSelection::SaveNewFocusObject(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection) -{ - if (!FocusObject) + if (Pieces.size() != State.PieceSelection.size() || Cameras.size() != State.CameraSelection.size() || Lights.size() != State.LightSelection.size()) return; - mNewFocusSection = FocusSection; - mNewFocusObjectType = FocusObject->GetType(); - mNewFocusIndex = GetObjectIndex(FocusObject, Model); -} - -std::vector lcModelActionSelection::GetNewObjects(const lcModel* Model) const -{ - const std::vector>& Pieces = Model->GetPieces(); - const std::vector>& Cameras = Model->GetCameras(); - const std::vector>& Lights = Model->GetLights(); - std::vector Objects; - - for (auto [ObjectIndex, ObjectType] : mNewObjects) + for (size_t PieceIndex = 0; PieceIndex < Pieces.size(); PieceIndex++) { - switch (ObjectType) - { - case lcObjectType::Piece: - if (ObjectIndex < Pieces.size()) - Objects.push_back(Pieces[ObjectIndex].get()); - break; - - case lcObjectType::Camera: - if (ObjectIndex < Cameras.size()) - Objects.push_back(Cameras[ObjectIndex].get()); - break; - - case lcObjectType::Light: - if (ObjectIndex < Lights.size()) - Objects.push_back(Lights[ObjectIndex].get()); - break; - } - } + lcPiece* Piece = Pieces[PieceIndex].get(); + + Piece->SetSelected(State.PieceSelection[PieceIndex]); - return Objects; -} - -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::GetPreviousSelection(const lcModel* Model) const -{ - const std::vector>& Pieces = Model->GetPieces(); - const std::vector>& Cameras = Model->GetCameras(); - const std::vector>& Lights = Model->GetLights(); - - std::vector SelectedObjects; - lcObject* FocusObject = nullptr; - - for (size_t PieceIndex = 0; PieceIndex < mStartState.SelectedPieces.size(); PieceIndex++) - if (mStartState.SelectedPieces[PieceIndex] && PieceIndex < Pieces.size()) - SelectedObjects.push_back(Pieces[PieceIndex].get()); - - for (size_t CameraIndex = 0; CameraIndex < mStartState.SelectedCameras.size(); CameraIndex++) - if (mStartState.SelectedCameras[CameraIndex] && CameraIndex < Cameras.size()) - SelectedObjects.push_back(Cameras[CameraIndex].get()); - - for (size_t LightIndex = 0; LightIndex < mStartState.SelectedLights.size(); LightIndex++) - if (mStartState.SelectedLights[LightIndex] && LightIndex < Lights.size()) - SelectedObjects.push_back(Lights[LightIndex].get()); - - switch (mStartState.FocusObjectType) - { - case lcObjectType::Piece: - if (mStartState.FocusIndex < Pieces.size()) - FocusObject = Pieces[mStartState.FocusIndex].get(); - break; - case lcObjectType::Camera: - if (mStartState.FocusIndex < Cameras.size()) - FocusObject = Cameras[mStartState.FocusIndex].get(); - break; - case lcObjectType::Light: - if (mStartState.FocusIndex < Lights.size()) - FocusObject = Lights[mStartState.FocusIndex].get(); - break; + if (State.FocusObjectType == lcObjectType::Piece && State.FocusIndex == PieceIndex) + Piece->SetFocused(State.FocusSection, true); + else + Piece->SetFocused(State.FocusSection, false); } - return { SelectedObjects, FocusObject, mStartState.FocusSection }; + for (size_t CameraIndex = 0; CameraIndex < Cameras.size(); CameraIndex++) + { + lcCamera* Camera = Cameras[CameraIndex].get(); + + Camera->SetSelected(State.CameraSelection[CameraIndex]); + + if (State.FocusObjectType == lcObjectType::Camera && State.FocusIndex == CameraIndex) + Camera->SetFocused(State.FocusSection, true); + else + Camera->SetFocused(State.FocusSection, false); + } + + for (size_t LightIndex = 0; LightIndex < Lights.size(); LightIndex++) + { + lcLight* Light = Lights[LightIndex].get(); + + Light->SetSelected(State.LightSelection[LightIndex]); + + if (State.FocusObjectType == lcObjectType::Light && State.FocusIndex == LightIndex) + Light->SetFocused(State.FocusSection, true); + else + Light->SetFocused(State.FocusSection, false); + } } lcModelActionObjectEdit::lcModelActionObjectEdit(lcModelActionObjectEditMode Mode) diff --git a/common/lc_modelaction.h b/common/lc_modelaction.h index b68868b3..7266abcf 100644 --- a/common/lc_modelaction.h +++ b/common/lc_modelaction.h @@ -22,7 +22,6 @@ protected: enum class lcModelActionSelectionMode { ClearSelection, - ClearSelectionAndSetFocus, SetFocus, SetSelectionAndFocus, SelectAllPieces, @@ -36,63 +35,45 @@ enum class lcModelActionSelectionMode struct lcModelActionSelectionState { - std::vector SelectedPieces; - std::vector SelectedCameras; - std::vector SelectedLights; + std::vector PieceSelection; + std::vector CameraSelection; + std::vector LightSelection; size_t FocusIndex = SIZE_MAX; uint32_t FocusSection = 0; lcObjectType FocusObjectType = static_cast(~0); + + bool operator!=(const lcModelActionSelectionState& Other) const + { + return PieceSelection != Other.PieceSelection || CameraSelection != Other.CameraSelection || LightSelection != Other.LightSelection || + FocusIndex != Other.FocusIndex || FocusSection != Other.FocusSection || FocusObjectType != Other.FocusObjectType; + } }; class lcModelActionSelection : public lcModelAction { public: - lcModelActionSelection(lcModelActionSelectionMode Mode, lcStep Step); + lcModelActionSelection(lcModelActionSelectionMode Mode); virtual ~lcModelActionSelection() = default; - - bool Initialize(const lcModel* Model, const std::vector& Objects, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode); - + lcModelActionSelectionMode GetMode() const { return mMode; } - lcStep GetStep() const - { - return mStep; - } - - lcSelectionMode GetSelectionMode() const - { - return mSelectionMode; - } - - uint32_t GetNewFocusSection() const - { - return mNewFocusSection; - } - - std::vector GetNewObjects(const lcModel* Model) const; - lcObject* GetNewFocusObject(const lcModel* Model) const; - std::tuple, lcObject*, uint32_t> GetPreviousSelection(const lcModel* Model) const; + void SaveStartState(const lcModel* Model); + void SaveEndState(const lcModel* Model); + void LoadStartState(lcModel* Model) const; + void LoadEndState(lcModel* Model) const; + + bool StateChanged() const; protected: static void SaveState(lcModelActionSelectionState& State, const lcModel* Model); - static size_t GetObjectIndex(const lcObject* Object, const lcModel* Model); - bool HasChanges(const lcModel* Model, const std::vector& Objects, lcObject* FocusObject, uint32_t FocusSection) const; - void SaveNewObjects(const std::vector& Objects, const lcModel* Model); - void SaveNewFocusObject(const lcModel* Model, lcObject* FocusObject, uint32_t FocusSection); + static void LoadState(const lcModelActionSelectionState& State, lcModel* Model); lcModelActionSelectionState mStartState; - - std::vector> mNewObjects; - size_t mNewFocusIndex = SIZE_MAX; - uint32_t mNewFocusSection = 0; - lcObjectType mNewFocusObjectType = (lcObjectType)0; - lcSelectionMode mSelectionMode = (lcSelectionMode)0; - + lcModelActionSelectionState mEndState; lcModelActionSelectionMode mMode; - lcStep mStep; }; enum class lcModelActionObjectEditMode diff --git a/common/lc_view.cpp b/common/lc_view.cpp index 9990278c..eeee97ac 100644 --- a/common/lc_view.cpp +++ b/common/lc_view.cpp @@ -2421,9 +2421,9 @@ void lcView::StopTracking(bool Accept) std::vector Objects = FindObjectsInBox(mMouseDownX, mMouseDownY, mMouseX, mMouseY); if (mMouseModifiers & Qt::ControlModifier) - ActiveModel->AddToSelection(Objects, lcSelectionMode::Single); + ActiveModel->AddToSelection(Objects); else if (mMouseModifiers & Qt::ShiftModifier) - ActiveModel->RemoveFromSelection(Objects, lcSelectionMode::Single); + ActiveModel->RemoveFromSelection(Objects); else ActiveModel->SetSelectionAndFocus(Objects, nullptr, 0, gMainWindow->GetSelectionMode()); } @@ -2577,10 +2577,10 @@ void lcView::OnButtonDown(lcTrackButton TrackButton) else if (mMouseModifiers & Qt::ShiftModifier) { if (ObjectSection.Object) - ActiveModel->RemoveFromSelection({ ObjectSection.Object }, gMainWindow->GetSelectionMode()); + ActiveModel->RemoveFromSelection({ ObjectSection.Object }); } else - ActiveModel->ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); + ActiveModel->SetSelectionAndFocus(std::vector(), ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); StartTracking(TrackButton); } @@ -2646,7 +2646,7 @@ void lcView::OnButtonDown(lcTrackButton TrackButton) ObjectSection.Object = Focus; ObjectSection.Section = mTrackToolSection; - ActiveModel->ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); + ActiveModel->SetSelectionAndFocus(std::vector(), ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); } break; @@ -2744,10 +2744,10 @@ void lcView::OnLeftButtonDoubleClick() else if (mMouseModifiers & Qt::ShiftModifier) { if (ObjectSection.Object) - ActiveModel->RemoveFromSelection({ ObjectSection.Object }, gMainWindow->GetSelectionMode()); + ActiveModel->RemoveFromSelection({ ObjectSection.Object }); } else - ActiveModel->ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); + ActiveModel->SetSelectionAndFocus(std::vector(), ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode()); } void lcView::OnMiddleButtonDown()