Simplified selection history by storing the states instead of changes.

This commit is contained in:
Leonardo Zide
2026-01-31 13:38:25 -08:00
parent b7ab094635
commit ce206cffe8
5 changed files with 223 additions and 563 deletions
+135 -225
View File
@@ -1230,11 +1230,9 @@ void lcModel::Paste(bool PasteToCurrentStep)
SaveCheckpoint(tr("Pasting"));
if (SelectedObjects.size() == 1)
RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector<lcObject*>(), SelectedObjects.front(), LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
// ClearSelectionAndSetFocus(SelectedObjects[0], LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector<lcObject*>(), 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<lcObject*>& Objects, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode)
{
std::unique_ptr<lcModelActionSelection> ModelActionSelection = std::make_unique<lcModelActionSelection>(ModelActionSelectionMode, mCurrentStep);
std::unique_ptr<lcModelActionSelection> ModelActionSelection = std::make_unique<lcModelActionSelection>(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<lcPiece>& Piece : mPieces)
if (Piece->IsVisible(mCurrentStep))
Piece->SetSelected(true);
break;
case lcModelActionSelectionMode::InvertPieceSelection:
for (const std::unique_ptr<lcPiece>& 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<lcObject*>& Objects, lcSelectionMode SelectionMode, lcStep Step)
{
for (lcObject* Object : Objects)
{
if (Object->IsSelected())
continue;
Object->SetSelected(true);
if (Object->IsPiece())
{
lcPiece* Piece = dynamic_cast<lcPiece*>(Object);
SelectGroup(Piece->GetTopGroup(), true);
std::vector<lcObject*> Pieces = GetSelectionModePieces(SelectionMode, Piece, Step);
SelectObjects(Pieces, true);
}
}
};
auto SetSelectionAndFocus=[this, &AddToSelection](const std::vector<lcObject*>& Objects, lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode, lcStep Step)
{
DeselectAllObjects();
if (Focus)
{
Focus->SetFocused(Section, true);
if (Focus->IsPiece())
{
lcPiece* Piece = dynamic_cast<lcPiece*>(Focus);
SelectGroup(Piece->GetTopGroup(), true);
std::vector<lcObject*> 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<lcObject*> 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<lcPiece*>(Focus);
SelectGroup(Piece->GetTopGroup(), true);
std::vector<lcObject*> Pieces = GetSelectionModePieces(SelectionMode, Piece, Step);
SelectObjects(Pieces, true);
}
}
}
else
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::SelectAllPieces:
if (Apply)
{
for (const std::unique_ptr<lcPiece>& Piece : mPieces)
if (Piece->IsVisible(Step))
Piece->SetSelected(true);
}
else
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::InvertPieceSelection:
if (Apply)
{
for (const std::unique_ptr<lcPiece>& Piece : mPieces)
if (Piece->IsSelected() || Piece->IsVisible(Step))
Piece->SetSelected(!Piece->IsSelected());
}
else
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::AddToSelection:
if (Apply)
{
std::vector<lcObject*> Objects = ModelActionSelection->GetNewObjects(this);
lcSelectionMode SelectionMode = ModelActionSelection->GetSelectionMode();
AddToSelection(Objects, SelectionMode, Step);
}
else
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::RemoveFromSelection:
if (Apply)
{
std::vector<lcObject*> Objects = ModelActionSelection->GetNewObjects(this);
for (lcObject* Object : Objects)
{
if (!Object->IsSelected())
continue;
Object->SetSelected(false);
if (Object->IsPiece())
{
lcPiece* Piece = dynamic_cast<lcPiece*>(Object);
SelectGroup(Piece->GetTopGroup(), false);
std::vector<lcObject*> 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<lcModelHistoryEntry> ModelHistoryEntry = std::make_unique<lcModelHistoryEntry>(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<lcObject*>(), Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
// ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector<lcObject*>(), 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<lcObject*>(), ModelPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector<lcObject*>(), ModelPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
}
void lcModel::InlineSelectedModels()
@@ -4470,39 +4360,6 @@ void lcModel::GetSelectionInformation(int* Flags, std::vector<lcObject*>& Select
}
}
std::vector<lcObject*> lcModel::GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece, lcStep Step) const
{
const PieceInfo* Info = SelectedPiece->mPieceInfo;
const int ColorIndex = SelectedPiece->GetColorIndex();
std::vector<lcObject*> Pieces;
switch (SelectionMode)
{
case lcSelectionMode::Single:
break;
case lcSelectionMode::Piece:
for (const std::unique_ptr<lcPiece>& 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<lcPiece>& 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<lcPiece>& 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<lcObject*>(), Focus, Section, SelectionMode);
EndActionSequence(tr("Selection"));
}
void lcModel::SetSelectionAndFocus(const std::vector<lcObject*>& Objects, lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode)
{
BeginActionSequence();
@@ -4557,20 +4407,53 @@ void lcModel::InvertPieceSelection()
EndActionSequence(tr("Selection"));
}
void lcModel::AddToSelection(const std::vector<lcObject*>& Objects, lcSelectionMode SelectionMode)
void lcModel::AddToSelection(const std::vector<lcObject*>& 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<lcObject*>& Objects, lcSelectionMode SelectionMode)
void lcModel::RemoveFromSelection(const std::vector<lcObject*>& Objects)
{
BeginActionSequence();
RecordSelectionAction(lcModelActionSelectionMode::RemoveFromSelection, Objects, nullptr, 0, SelectionMode);
RecordSelectionAction(lcModelActionSelectionMode::RemoveFromSelection, Objects, nullptr, 0, lcSelectionMode::Single);
EndActionSequence(tr("Selection"));
}
std::vector<lcObject*> lcModel::GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece) const
{
const PieceInfo* Info = SelectedPiece->mPieceInfo;
const int ColorIndex = SelectedPiece->GetColorIndex();
std::vector<lcObject*> Pieces;
switch (SelectionMode)
{
case lcSelectionMode::Single:
break;
case lcSelectionMode::Piece:
for (const std::unique_ptr<lcPiece>& 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<lcPiece>& 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<lcPiece>& 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<lcPiece>& Piece : mPieces)
@@ -4583,17 +4466,46 @@ void lcModel::DeselectAllObjects()
Light->SetSelected(false);
}
void lcModel::SelectObjects(const std::vector<lcObject*>& 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<lcPiece*>(FocusObject);
if (Piece)
{
if (!Piece->IsSelected())
SetObjectsSelected({ Piece }, true);
std::vector<lcObject*> Pieces = GetSelectionModePieces(SelectionMode, Piece);
SetObjectsSelected(Pieces, true);
}
FocusObject->SetFocused(FocusSection, true);
}
}
void lcModel::SetObjectsSelected(const std::vector<lcObject*>& 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<lcPiece*>(Object)->GetTopGroup(), Select);
{
lcPiece* Piece = dynamic_cast<lcPiece*>(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<lcObject*>(), Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector<lcObject*>(), Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
if (ReplacedCount)
{
@@ -5035,7 +4945,7 @@ void lcModel::InsertPieceToolClicked(const std::vector<lcInsertPieceInfo>& Piece
EndObjectEditAction(std::move(PieceIndices));
RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector<lcObject*>(), Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector<lcObject*>(), 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<lcObject*>(), Camera, LC_CAMERA_SECTION_POSITION, lcSelectionMode::Single);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector<lcObject*>(), 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<lcObject*>(), Light, LC_LIGHT_SECTION_POSITION, lcSelectionMode::Single);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, std::vector<lcObject*>(), Light, LC_LIGHT_SECTION_POSITION, lcSelectionMode::Single);
EndActionSequence(ActionName);
}
+5 -5
View File
@@ -324,13 +324,12 @@ public:
void GetSelectionInformation(int* Flags, std::vector<lcObject*>& Selection, lcObject** Focus) const;
void ClearSelection();
void ClearSelectionAndSetFocus(lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode);
void SetSelectionAndFocus(const std::vector<lcObject*>& 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<lcObject*>& Objects, lcSelectionMode SelectionMode);
void RemoveFromSelection(const std::vector<lcObject*>& Objects, lcSelectionMode SelectionMode);
void AddToSelection(const std::vector<lcObject*>& Objects);
void RemoveFromSelection(const std::vector<lcObject*>& Objects);
void HideSelectedPieces();
void HideUnselectedPieces();
@@ -426,9 +425,10 @@ protected:
bool RemoveSelectedObjects();
void RemoveCameraFromViews(lcCamera* Camera);
std::vector<lcObject*> GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece, lcStep Step) const;
std::vector<lcObject*> GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece) const;
void DeselectAllObjects();
void SelectObjects(const std::vector<lcObject*>& Objects, bool Select);
void SetFocusedObject(lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode);
void SetObjectsSelected(const std::vector<lcObject*>& Objects, bool Selected);
void SelectGroup(lcGroup* TopGroup, bool Select);
size_t AddPiece(lcPiece* Piece);
+57 -288
View File
@@ -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<lcObject*>& 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<std::unique_ptr<lcPiece>>& 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<std::unique_ptr<lcCamera>>& 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<std::unique_ptr<lcLight>>& 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<lcObject*>& Objects, lcObject* FocusObject, uint32_t FocusSection) const
void lcModelActionSelection::LoadStartState(lcModel* Model) const
{
const std::vector<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
const std::vector<std::unique_ptr<lcLight>>& 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<lcPiece>& Piece : Pieces)
if (Piece->IsSelected() && Piece.get() != FocusObject)
return true;
for (const std::unique_ptr<lcCamera>& Camera : Cameras)
if (Camera->IsSelected() && Camera.get() != FocusObject)
return true;
for (const std::unique_ptr<lcLight>& 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<lcPiece>& Piece : Pieces)
if (HasSelectionChanges(Piece.get()))
return true;
for (const std::unique_ptr<lcCamera>& Camera : Cameras)
if (HasSelectionChanges(Camera.get()))
return true;
for (const std::unique_ptr<lcLight>& 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<lcPiece>& Piece : Pieces)
if (Piece->IsVisible(mStep) && !Piece->IsSelected())
return true;
return false;
case lcModelActionSelectionMode::InvertPieceSelection:
for (const std::unique_ptr<lcPiece>& 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<std::unique_ptr<lcPiece>>& 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<std::unique_ptr<lcCamera>>& 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<std::unique_ptr<lcLight>>& 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<lcObject*>& 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<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
const std::vector<std::unique_ptr<lcLight>>& 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<lcObject*> lcModelActionSelection::GetNewObjects(const lcModel* Model) const
{
const std::vector<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
const std::vector<std::unique_ptr<lcLight>>& Lights = Model->GetLights();
std::vector<lcObject*> 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<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
if (mNewFocusIndex < Pieces.size())
return Pieces[mNewFocusIndex].get();
}
break;
case lcObjectType::Camera:
{
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
if (mNewFocusIndex < Cameras.size())
return Cameras[mNewFocusIndex].get();
}
break;
case lcObjectType::Light:
{
const std::vector<std::unique_ptr<lcLight>>& Lights = Model->GetLights();
if (mNewFocusIndex < Lights.size())
return Lights[mNewFocusIndex].get();
}
break;
}
return nullptr;
}
std::tuple<std::vector<lcObject*>, lcObject*, uint32_t> lcModelActionSelection::GetPreviousSelection(const lcModel* Model) const
{
const std::vector<std::unique_ptr<lcPiece>>& Pieces = Model->GetPieces();
const std::vector<std::unique_ptr<lcCamera>>& Cameras = Model->GetCameras();
const std::vector<std::unique_ptr<lcLight>>& Lights = Model->GetLights();
std::vector<lcObject*> 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)
+19 -38
View File
@@ -22,7 +22,6 @@ protected:
enum class lcModelActionSelectionMode
{
ClearSelection,
ClearSelectionAndSetFocus,
SetFocus,
SetSelectionAndFocus,
SelectAllPieces,
@@ -36,63 +35,45 @@ enum class lcModelActionSelectionMode
struct lcModelActionSelectionState
{
std::vector<bool> SelectedPieces;
std::vector<bool> SelectedCameras;
std::vector<bool> SelectedLights;
std::vector<bool> PieceSelection;
std::vector<bool> CameraSelection;
std::vector<bool> LightSelection;
size_t FocusIndex = SIZE_MAX;
uint32_t FocusSection = 0;
lcObjectType FocusObjectType = static_cast<lcObjectType>(~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<lcObject*>& 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<lcObject*> GetNewObjects(const lcModel* Model) const;
lcObject* GetNewFocusObject(const lcModel* Model) const;
std::tuple<std::vector<lcObject*>, 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<lcObject*>& Objects, lcObject* FocusObject, uint32_t FocusSection) const;
void SaveNewObjects(const std::vector<lcObject*>& 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<std::pair<size_t, lcObjectType>> 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
+7 -7
View File
@@ -2421,9 +2421,9 @@ void lcView::StopTracking(bool Accept)
std::vector<lcObject*> 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<lcObject*>(), 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<lcObject*>(), 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<lcObject*>(), ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode());
}
void lcView::OnMiddleButtonDown()