Added remaining selection actions.

This commit is contained in:
Leonardo Zide
2026-01-12 14:42:09 -08:00
parent 8342e147cf
commit 96bc1dc700
6 changed files with 229 additions and 139 deletions
+150 -128
View File
@@ -1233,7 +1233,8 @@ void lcModel::Paste(bool PasteToCurrentStep)
RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector<lcObject*>(), SelectedObjects.front(), LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
// ClearSelectionAndSetFocus(SelectedObjects[0], LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
else
SetSelectionAndFocus(SelectedObjects, nullptr, 0, false);
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, SelectedObjects, nullptr, 0, lcSelectionMode::Single);
// SetSelectionAndFocus(SelectedObjects, nullptr, 0, false);
CalculateStep(mCurrentStep);
gMainWindow->UpdateTimeline(false, false);
@@ -1310,10 +1311,12 @@ void lcModel::DuplicateSelectedPieces()
}
EndObjectEditAction(std::move(PieceIndices));
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, NewPieces, Focus, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
EndActionSequence(tr("Duplicate"));
gMainWindow->UpdateTimeline(false, false);
SetSelectionAndFocus(NewPieces, Focus, LC_PIECE_SECTION_POSITION, false);
}
void lcModel::PaintSelectedPieces()
@@ -1745,49 +1748,114 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect
{
if (!ModelActionSelection)
return;
auto LoadSelection = [this, ModelActionSelection]()
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(), Step, true);
std::vector<lcObject*> Pieces = GetSelectionModePieces(SelectionMode, Piece, Step);
SelectObjects(Pieces, Step, 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(), Step, true);
std::vector<lcObject*> Pieces = GetSelectionModePieces(SelectionMode, Piece, Step);
SelectObjects(Pieces, Step, true);
}
}
AddToSelection(Objects, SelectionMode, Step);
};
auto LoadPreviousSelection = [this, ModelActionSelection, Step, &SetSelectionAndFocus]()
{
auto [SelectedObjects, FocusObject, FocusSection] = ModelActionSelection->GetPreviousSelection(this);
SetSelectionAndFocus(SelectedObjects, FocusObject, FocusSection, false);
SetSelectionAndFocus(SelectedObjects, FocusObject, FocusSection, lcSelectionMode::Single, Step);
};
lcStep Step = ModelActionSelection->GetStep();
switch (ModelActionSelection->GetMode())
{
case lcModelActionSelectionMode::ClearSelection:
if (Apply)
DeselectAllObjects();
else
LoadSelection();
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::ClearSelectionAndSetFocus:
case lcModelActionSelectionMode::SetSelectionAndFocus:
if (Apply)
{
DeselectAllObjects();
std::vector<lcObject*> Objects = ModelActionSelection->GetNewObjects(this);
lcObject* Focus = ModelActionSelection->GetNewFocusObject(this);
uint32_t Section = ModelActionSelection->GetNewFocusSection();
lcSelectionMode SelectionMode = ModelActionSelection->GetSelectionMode();
lcObject* NewFocusObject = ModelActionSelection->GetNewFocusObject(this);
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();
if (NewFocusObject)
lcObject* PreviousFocus = GetFocusObject();
if (PreviousFocus && PreviousFocus != Focus)
PreviousFocus->SetFocused(PreviousFocus->GetFocusSection(), false);
if (Focus)
{
NewFocusObject->SetFocused(ModelActionSelection->GetNewFocusSection(), true);
const bool WasSelected = Focus->IsSelected();
if (NewFocusObject->IsPiece())
Focus->SetFocused(Section, true);
if (Focus->IsPiece() && !WasSelected)
{
lcPiece* Piece = dynamic_cast<lcPiece*>(NewFocusObject);
lcPiece* Piece = dynamic_cast<lcPiece*>(Focus);
SelectGroup(Piece->GetTopGroup(), Step, true);
std::vector<lcObject*> Pieces = GetSelectionModePieces(ModelActionSelection->GetSelectionMode(), Piece, Step);
std::vector<lcObject*> Pieces = GetSelectionModePieces(SelectionMode, Piece, Step);
SelectObjects(Pieces, Step, true);
}
}
}
}
else
LoadSelection();
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::SelectAllPieces:
@@ -1798,7 +1866,7 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect
Piece->SetSelected(true);
}
else
LoadSelection();
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::InvertPieceSelection:
@@ -1809,9 +1877,21 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect
Piece->SetSelected(!Piece->IsSelected());
}
else
LoadSelection();
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)
{
@@ -1836,21 +1916,21 @@ void lcModel::RunSelectionAction(const lcModelActionSelection* ModelActionSelect
}
}
else
LoadSelection();
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::Set:
LoadSelection();
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::Save:
if (!Apply)
LoadSelection();
LoadPreviousSelection();
break;
case lcModelActionSelectionMode::Restore:
if (Apply)
LoadSelection();
LoadPreviousSelection();
break;
}
}
@@ -3294,10 +3374,11 @@ void lcModel::InlineSelectedModels()
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("No models selected."));
return;
}
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, NewPieces, nullptr, 0, lcSelectionMode::Single);
SaveCheckpoint(tr("Inlining"));
gMainWindow->UpdateTimeline(false, false);
SetSelectionAndFocus(NewPieces, nullptr, 0, false);
}
void lcModel::RemoveCameraFromViews(lcCamera* Camera)
@@ -4470,13 +4551,39 @@ void lcModel::ClearSelection()
EndActionSequence(tr("Selection"));
}
void lcModel::ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, lcSelectionMode SelectionMode)
void lcModel::ClearSelectionAndSetFocus(lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode)
{
BeginActionSequence();
RecordSelectionAction(lcModelActionSelectionMode::ClearSelectionAndSetFocus, std::vector<lcObject*>(), Object, Section, SelectionMode);
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();
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, Objects, Focus, Section, SelectionMode);
EndActionSequence(tr("Selection"));
}
void lcModel::FocusOrDeselectObject(lcObject* Object, uint32_t Section, lcSelectionMode SelectionMode)
{
BeginActionSequence();
if (Object)
{
if (!Object->IsFocused(Section))
RecordSelectionAction(lcModelActionSelectionMode::SetFocus, std::vector<lcObject*>(), Object, Section, SelectionMode);
else
RecordSelectionAction(lcModelActionSelectionMode::SetFocus, std::vector<lcObject*>(), nullptr, 0, SelectionMode);
}
else
{
RecordSelectionAction(lcModelActionSelectionMode::SetFocus, std::vector<lcObject*>(), nullptr, 0, SelectionMode);
}
EndActionSequence(tr("Selection"));
}
void lcModel::SelectAllPieces()
{
BeginActionSequence();
@@ -4491,6 +4598,13 @@ void lcModel::InvertPieceSelection()
EndActionSequence(tr("Selection"));
}
void lcModel::AddToSelection(const std::vector<lcObject*>& Objects, lcSelectionMode SelectionMode)
{
BeginActionSequence();
RecordSelectionAction(lcModelActionSelectionMode::AddToSelection, Objects, nullptr, 0, SelectionMode);
EndActionSequence(tr("Selection"));
}
void lcModel::RemoveFromSelection(const std::vector<lcObject*>& Objects, lcSelectionMode SelectionMode)
{
BeginActionSequence();
@@ -4534,101 +4648,6 @@ void lcModel::SelectGroup(lcGroup* TopGroup, lcStep Step, bool Select)
Piece->SetSelected(Select);
}
void lcModel::FocusOrDeselectObject(const lcObjectSection& ObjectSection)
{
lcObject* FocusObject = GetFocusObject();
lcObject* Object = ObjectSection.Object;
const quint32 Section = ObjectSection.Section;
if (Object)
{
const bool WasSelected = Object->IsSelected();
if (!Object->IsFocused(Section))
{
if (FocusObject)
FocusObject->SetFocused(FocusObject->GetFocusSection(), false);
Object->SetFocused(Section, true);
}
else
Object->SetFocused(Section, false);
const bool IsSelected = Object->IsSelected();
if (Object->IsPiece() && (WasSelected != IsSelected))
{
lcPiece* Piece = (lcPiece*)Object;
if (gMainWindow->GetSelectionMode() == lcSelectionMode::Single)
SelectGroup(Piece->GetTopGroup(), mCurrentStep, IsSelected);
else
{
std::vector<lcObject*> Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), Piece, mCurrentStep);
AddToSelection(Pieces, false, false);
}
}
}
else
{
if (FocusObject)
FocusObject->SetFocused(FocusObject->GetFocusSection(), false);
}
gMainWindow->UpdateSelectedObjects(true);
UpdateAllViews();
}
void lcModel::SetSelectionAndFocus(const std::vector<lcObject*>& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode)
{
DeselectAllObjects();
if (Focus)
{
Focus->SetFocused(Section, true);
if (Focus->IsPiece())
{
SelectGroup(((lcPiece*)Focus)->GetTopGroup(), mCurrentStep, true);
if (EnableSelectionMode)
{
std::vector<lcObject*> Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), dynamic_cast<lcPiece*>(Focus), mCurrentStep);
AddToSelection(Pieces, false, false);
}
}
}
AddToSelection(Selection, EnableSelectionMode, true);
}
void lcModel::AddToSelection(const std::vector<lcObject*>& Objects, bool EnableSelectionMode, bool UpdateInterface)
{
for (lcObject* Object : Objects)
{
const bool WasSelected = Object->IsSelected();
Object->SetSelected(true);
if (Object->IsPiece())
{
if (!WasSelected)
SelectGroup(((lcPiece*)Object)->GetTopGroup(), mCurrentStep, true);
if (EnableSelectionMode)
{
std::vector<lcObject*> Pieces = GetSelectionModePieces(gMainWindow->GetSelectionMode(), dynamic_cast<lcPiece*>(Object), mCurrentStep);
AddToSelection(Pieces, false, false);
}
}
}
if (UpdateInterface)
{
gMainWindow->UpdateSelectedObjects(true);
UpdateAllViews();
}
}
void lcModel::HideSelectedPieces()
{
BeginActionSequence();
@@ -4864,7 +4883,8 @@ void lcModel::FindReplacePiece(bool SearchForward, bool FindAll, bool Replace)
}
if (FindAll)
SetSelectionAndFocus(Selection, nullptr, 0, false);
// 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);
@@ -5499,7 +5519,7 @@ void lcModel::ShowSelectByNameDialog()
if (Dialog.exec() != QDialog::Accepted)
return;
SetSelectionAndFocus(Dialog.mObjects, nullptr, 0, false);
SetSelectionAndFocus(Dialog.mObjects, nullptr, 0, lcSelectionMode::Single);
}
void lcModel::ShowArrayDialog()
@@ -5577,9 +5597,11 @@ void lcModel::ShowArrayDialog()
}
EndObjectEditAction(std::move(PieceIndices));
RecordSelectionAction(lcModelActionSelectionMode::AddToSelection, NewPieces, nullptr, 0, lcSelectionMode::Single);
EndActionSequence(tr("Piece Array"));
AddToSelection(NewPieces, false, true);
gMainWindow->UpdateTimeline(false, false);
}
@@ -5619,10 +5641,12 @@ void lcModel::ShowMinifigDialog()
Pieces.emplace_back(Piece);
}
EndObjectEditAction(std::move(PieceIndices), { mGroups.size() - 1});
EndObjectEditAction(std::move(PieceIndices), { mGroups.size() - 1});
RecordSelectionAction(lcModelActionSelectionMode::SetSelectionAndFocus, Pieces, nullptr, 0, lcSelectionMode::Single);
EndActionSequence(tr("Add Minifig"));
SetSelectionAndFocus(Pieces, nullptr, 0, false);
gMainWindow->UpdateTimeline(false, false);
}
@@ -5647,8 +5671,6 @@ void lcModel::SetMinifig(const lcMinifig& Minifig)
Pieces.emplace_back(Piece);
}
SetSelectionAndFocus(Pieces, nullptr, 0, false);
}
void lcModel::SetPreviewPieceInfo(PieceInfo* Info, int ColorIndex)
+4 -5
View File
@@ -324,14 +324,13 @@ public:
void GetSelectionInformation(int* Flags, std::vector<lcObject*>& Selection, lcObject** Focus) const;
void ClearSelection();
void ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, lcSelectionMode SelectionMode);
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);
// to update:
void FocusOrDeselectObject(const lcObjectSection& ObjectSection);
void SetSelectionAndFocus(const std::vector<lcObject*>& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode);
void AddToSelection(const std::vector<lcObject*>& Objects, bool EnableSelectionMode, bool UpdateInterface);
void HideSelectedPieces();
void HideUnselectedPieces();
+67 -1
View File
@@ -244,7 +244,34 @@ bool lcModelActionSelection::HasChanges(const lcModel* Model, const std::vector<
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:
@@ -268,6 +295,38 @@ bool lcModelActionSelection::HasChanges(const lcModel* Model, const std::vector<
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;
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;
case lcModelActionSelectionMode::SelectAllPieces:
for (const std::unique_ptr<lcPiece>& Piece : Pieces)
if (Piece->IsVisible(mStep) && !Piece->IsSelected())
@@ -282,6 +341,13 @@ bool lcModelActionSelection::HasChanges(const lcModel* Model, const std::vector<
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())
+3
View File
@@ -23,8 +23,11 @@ enum class lcModelActionSelectionMode
{
ClearSelection,
ClearSelectionAndSetFocus,
SetFocus,
SetSelectionAndFocus,
SelectAllPieces,
InvertPieceSelection,
AddToSelection,
RemoveFromSelection,
Set,
Save,
+1 -1
View File
@@ -552,7 +552,7 @@ void lcTimelineWidget::ItemSelectionChanged()
UpdateCurrentStepItem();
}
Model->SetSelectionAndFocus(Selection, CurrentPiece, LC_PIECE_SECTION_POSITION, false);
Model->SetSelectionAndFocus(Selection, CurrentPiece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single);
mIgnoreUpdates = false;
blockSignals(Blocked);
}
+4 -4
View File
@@ -2421,11 +2421,11 @@ void lcView::StopTracking(bool Accept)
std::vector<lcObject*> Objects = FindObjectsInBox(mMouseDownX, mMouseDownY, mMouseX, mMouseY);
if (mMouseModifiers & Qt::ControlModifier)
ActiveModel->AddToSelection(Objects, true, true);
ActiveModel->AddToSelection(Objects, lcSelectionMode::Single);
else if (mMouseModifiers & Qt::ShiftModifier)
ActiveModel->RemoveFromSelection(Objects, lcSelectionMode::Single);
else
ActiveModel->SetSelectionAndFocus(Objects, nullptr, 0, true);
ActiveModel->SetSelectionAndFocus(Objects, nullptr, 0, gMainWindow->GetSelectionMode());
}
break;
@@ -2573,7 +2573,7 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
lcObjectSection ObjectSection = FindObjectUnderPointer(false, false);
if (mMouseModifiers & Qt::ControlModifier)
ActiveModel->FocusOrDeselectObject(ObjectSection);
ActiveModel->FocusOrDeselectObject(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode());
else if (mMouseModifiers & Qt::ShiftModifier)
{
if (ObjectSection.Object)
@@ -2740,7 +2740,7 @@ void lcView::OnLeftButtonDoubleClick()
lcObjectSection ObjectSection = FindObjectUnderPointer(false, false);
if (mMouseModifiers & Qt::ControlModifier)
ActiveModel->FocusOrDeselectObject(ObjectSection);
ActiveModel->FocusOrDeselectObject(ObjectSection.Object, ObjectSection.Section, gMainWindow->GetSelectionMode());
else if (mMouseModifiers & Qt::ShiftModifier)
{
if (ObjectSection.Object)