diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h
index 86008dc..e562725 100644
--- a/Source/Ember/Ember.h
+++ b/Source/Ember/Ember.h
@@ -215,6 +215,27 @@ public:
AddXforms(xformPad - XformCount());
}
+ ///
+ /// Replace the xforms vector with the one passed in.
+ ///
+ /// The xforms to replace with
+ /// True to move, false to copy. Default: true.
+ /// True if replaced, else false.
+ bool ReplaceXforms(vector>& xforms, bool move = true)
+ {
+ if (!xforms.empty())
+ {
+ if (move)
+ m_Xforms = std::move(xforms);
+ else
+ m_Xforms = xforms;
+
+ return true;
+ }
+ else
+ return false;
+ }
+
///
/// Copy this ember with optional padding xforms added.
///
@@ -280,12 +301,13 @@ public:
/// Delete the xform at the specified index, including the final one.
///
/// The index to delete
+ /// If true, delete the final xform when its index is passed in even if one is not present. Default: false.
/// True if success, else false.
- bool DeleteTotalXform(size_t i)
+ bool DeleteTotalXform(size_t i, bool forceFinal = false)
{
if (DeleteXform(i))
{ }
- else if (i == XformCount() && UseFinalXform())
+ else if (i == XformCount() && (forceFinal || UseFinalXform()))
m_FinalXform.Clear();
else
return false;
@@ -310,13 +332,13 @@ public:
/// Get a pointer to the xform at the specified index, including the final one.
///
/// The index to get
- /// If true, return the final xform when its index is requested even if one is not present
+ /// If true, return the final xform when its index is requested even if one is not present. Default: false.
/// A pointer to the xform at the index if successful, else nullptr.
Xform* GetTotalXform(size_t i, bool forceFinal = false) const
{
if (i < XformCount())
return const_cast*>(&m_Xforms[i]);
- else if (forceFinal || (i == XformCount() && UseFinalXform()))
+ else if (i == XformCount() && (forceFinal || UseFinalXform()))
return const_cast*>(&m_FinalXform);
else
return nullptr;
@@ -342,13 +364,14 @@ public:
/// Search the xforms, including final, to find which one's address matches the address of the specified xform.
///
/// A pointer to the xform to find
+ /// If true, return the index of the final xform when its pointer is passed, even if a final is not present. Default: false.
/// The index of the matched xform if found, else -1.
- intmax_t GetTotalXformIndex(Xform* xform) const
+ intmax_t GetTotalXformIndex(Xform* xform, bool forceFinal = false) const
{
- size_t totalXformCount = TotalXformCount();
+ size_t totalXformCount = TotalXformCount(forceFinal);
for (size_t i = 0; i < totalXformCount; i++)
- if (GetTotalXform(i) == xform)
+ if (GetTotalXform(i, forceFinal) == xform)
return intmax_t(i);
return -1;
@@ -1468,7 +1491,7 @@ public:
inline const Xform* FinalXform() const { return &m_FinalXform; }
inline Xform* NonConstFinalXform() { return &m_FinalXform; }
inline bool UseFinalXform() const { return !m_FinalXform.Empty(); }
- inline size_t TotalXformCount() const { return XformCount() + (UseFinalXform() ? 1 : 0); }
+ inline size_t TotalXformCount(bool forceFinal = false) const { return XformCount() + ((forceFinal || UseFinalXform()) ? 1 : 0); }
inline int PaletteIndex() const { return m_Palette.m_Index; }
inline T BlurCoef() { return m_BlurCoef; }
inline eScaleType ScaleType() const { return m_ScaleType; }
diff --git a/Source/Fractorium/Fractorium.cpp b/Source/Fractorium/Fractorium.cpp
index 5ff533f..1cd05dd 100644
--- a/Source/Fractorium/Fractorium.cpp
+++ b/Source/Fractorium/Fractorium.cpp
@@ -264,6 +264,8 @@ void FractoriumEmberController::ApplyXmlSavingTemplate(Ember& ember)
///
/// Return whether the current ember contains a final xform and the GUI is aware of it.
+/// Note this can be true even if the final is empty, as long as they've added one and have
+/// not explicitly deleted it.
///
/// True if the current ember contains a final xform, else false.
bool Fractorium::HaveFinal()
diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h
index fe55221..3d50b8f 100644
--- a/Source/Fractorium/Fractorium.h
+++ b/Source/Fractorium/Fractorium.h
@@ -405,7 +405,7 @@ private:
//Xforms Selection.
void ClearXformsSelections();
- void ForEachXformCheckbox(std::function func);
+ void ForEachXformCheckbox(std::function func);
//Xaos.
void FillXaosTable();
diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui
index f9e97e1..6537d8f 100644
--- a/Source/Fractorium/Fractorium.ui
+++ b/Source/Fractorium/Fractorium.ui
@@ -3423,7 +3423,7 @@
<html><head/><body><p>Set all xform color speed values to random numbers between 0 and 1, inclusive</p></body></html>
- Random Color Speed
+ Random Color Speeds
diff --git a/Source/Fractorium/FractoriumEmberController.cpp b/Source/Fractorium/FractoriumEmberController.cpp
index 0b01540..54e8328 100644
--- a/Source/Fractorium/FractoriumEmberController.cpp
+++ b/Source/Fractorium/FractoriumEmberController.cpp
@@ -208,31 +208,32 @@ template
void FractoriumEmberController::UpdateXform(std::function*)> func, eXformUpdate updateType, bool updateRender, eProcessAction action, size_t index)
{
int i = 0;
- bool isCurrentFinal = m_Ember.IsFinalXform(CurrentXform());
+ auto current = CurrentXform();
+ bool forceFinal = m_Fractorium->HaveFinal();
+ bool isCurrentFinal = m_Ember.IsFinalXform(current);
bool doFinal = updateType != eXformUpdate::UPDATE_SELECTED_EXCEPT_FINAL && updateType != eXformUpdate::UPDATE_ALL_EXCEPT_FINAL;
switch (updateType)
{
case eXformUpdate::UPDATE_SPECIFIC:
{
- if (auto xform = m_Ember.GetTotalXform(index))
+ if (auto xform = m_Ember.GetTotalXform(index, forceFinal))
func(xform);
}
break;
case eXformUpdate::UPDATE_CURRENT:
{
- if (auto xform = CurrentXform())
- func(xform);
+ if (current)
+ func(current);
}
break;
case eXformUpdate::UPDATE_CURRENT_AND_SELECTED:
{
bool currentDone = false;
- auto current = CurrentXform();
- while (auto xform = m_Ember.GetTotalXform(i))
+ while (auto xform = m_Ember.GetTotalXform(i, forceFinal))
{
if (i < m_Fractorium->m_XformSelections.size())
{
@@ -261,7 +262,7 @@ void FractoriumEmberController::UpdateXform(std::function*)> fu
{
bool anyUpdated = false;
- while (auto xform = (doFinal ? m_Ember.GetTotalXform(i) : m_Ember.GetXform(i)))
+ while (auto xform = (doFinal ? m_Ember.GetTotalXform(i, forceFinal) : m_Ember.GetXform(i)))
{
if (i < m_Fractorium->m_XformSelections.size())
{
@@ -280,14 +281,14 @@ void FractoriumEmberController::UpdateXform(std::function*)> fu
if (!anyUpdated)//None were selected, so just apply to the current.
if (doFinal || !isCurrentFinal)//If do final, call func regardless. If not, only call if current is not final.
- if (auto xform = CurrentXform())
- func(xform);
+ if (current)
+ func(current);
}
break;
case eXformUpdate::UPDATE_ALL:
{
- while (auto xform = m_Ember.GetTotalXform(i++))
+ while (auto xform = m_Ember.GetTotalXform(i++, forceFinal))
func(xform);
}
break;
diff --git a/Source/Fractorium/FractoriumInfo.cpp b/Source/Fractorium/FractoriumInfo.cpp
index b66d789..b305ab3 100644
--- a/Source/Fractorium/FractoriumInfo.cpp
+++ b/Source/Fractorium/FractoriumInfo.cpp
@@ -69,7 +69,8 @@ void FractoriumEmberController::FillSummary()
int vp = 4;
int vlen = 7;
char pc = 'f';
- size_t x = 0, total = m_Ember.TotalXformCount();
+ bool forceFinal = m_Fractorium->HaveFinal();
+ size_t x = 0, total = m_Ember.TotalXformCount(forceFinal);
Xform* xform = nullptr;
QColor color;
auto table = m_Fractorium->ui.SummaryTable;
@@ -85,7 +86,7 @@ void FractoriumEmberController::FillSummary()
QSize size(table->columnWidth(0), table->rowHeight(1) + 1);
m_Fractorium->m_InfoPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- for (x = 0; x < total && (xform = m_Ember.GetTotalXform(x)); x++)
+ for (x = 0; x < total && (xform = m_Ember.GetTotalXform(x, forceFinal)); x++)
{
size_t i = 0;
QString as = "Pre";
@@ -233,5 +234,5 @@ void Fractorium::ErrorReportToQTextEdit(const vector& errors, QTextEdit*
template class FractoriumEmberController;
#ifdef DO_DOUBLE
-template class FractoriumEmberController;
+ template class FractoriumEmberController;
#endif
diff --git a/Source/Fractorium/FractoriumMenus.cpp b/Source/Fractorium/FractoriumMenus.cpp
index fe2f3c4..7144c86 100644
--- a/Source/Fractorium/FractoriumMenus.cpp
+++ b/Source/Fractorium/FractoriumMenus.cpp
@@ -428,7 +428,9 @@ void FractoriumEmberController::Undo()
{
if (m_UndoList.size() > 1 && m_UndoIndex > 0)
{
- int index = m_Ember.GetTotalXformIndex(CurrentXform());
+ bool forceFinal = m_Fractorium->HaveFinal();
+ auto current = CurrentXform();
+ int index = m_Ember.GetTotalXformIndex(current, forceFinal);
m_LastEditWasUndoRedo = true;
m_UndoIndex = std::max(0u, m_UndoIndex - 1u);
SetEmber(m_UndoList[m_UndoIndex], true, false);//Don't update pointer because it's coming from the undo list...
@@ -452,7 +454,9 @@ void FractoriumEmberController::Redo()
{
if (m_UndoList.size() > 1 && m_UndoIndex < m_UndoList.size() - 1)
{
- int index = m_Ember.GetTotalXformIndex(CurrentXform());
+ bool forceFinal = m_Fractorium->HaveFinal();
+ auto current = CurrentXform();
+ int index = m_Ember.GetTotalXformIndex(current, forceFinal);
m_LastEditWasUndoRedo = true;
m_UndoIndex = std::min(m_UndoIndex + 1, m_UndoList.size() - 1);
SetEmber(m_UndoList[m_UndoIndex], true, false);
@@ -740,10 +744,11 @@ void Fractorium::OnActionResetScale(bool checked)
template
void FractoriumEmberController::AddReflectiveSymmetry()
{
+ bool forceFinal = m_Fractorium->HaveFinal();
Update([&]()
{
m_Ember.AddSymmetry(-1, m_Rand);
- auto index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
+ auto index = m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1);//Set index to the last item before final.
FillXforms(int(index));
});
}
@@ -757,10 +762,11 @@ void Fractorium::OnActionAddReflectiveSymmetry(bool checked) { m_Controller->Add
template
void FractoriumEmberController::AddRotationalSymmetry()
{
+ bool forceFinal = m_Fractorium->HaveFinal();
Update([&]()
{
m_Ember.AddSymmetry(2, m_Rand);
- auto index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
+ auto index = m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1);//Set index to the last item before final.
FillXforms(int(index));
});
}
@@ -774,10 +780,11 @@ void Fractorium::OnActionAddRotationalSymmetry(bool checked) { m_Controller->Add
template
void FractoriumEmberController::AddBothSymmetry()
{
+ bool forceFinal = m_Fractorium->HaveFinal();
Update([&]()
{
m_Ember.AddSymmetry(-2, m_Rand);
- auto index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
+ auto index = m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1);//Set index to the last item before final.
FillXforms(int(index));
});
}
diff --git a/Source/Fractorium/FractoriumPalette.cpp b/Source/Fractorium/FractoriumPalette.cpp
index 2278b82..f816537 100644
--- a/Source/Fractorium/FractoriumPalette.cpp
+++ b/Source/Fractorium/FractoriumPalette.cpp
@@ -323,8 +323,9 @@ void FractoriumEmberController::PaletteEditorButtonClicked()
Palette prevPal = m_TempPalette;
ed->SetPalette(m_TempPalette);
map colorIndices;
+ bool forceFinal = m_Fractorium->HaveFinal();
- while (auto xform = m_Ember.GetTotalXform(i))
+ while (auto xform = m_Ember.GetTotalXform(i, forceFinal))
colorIndices[i++] = xform->m_ColorX;
ed->SetColorIndices(colorIndices);
diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp
index 0c18cc9..a54809d 100644
--- a/Source/Fractorium/FractoriumRender.cpp
+++ b/Source/Fractorium/FractoriumRender.cpp
@@ -341,10 +341,11 @@ bool FractoriumEmberController::Render()
{
size_t i = 0;
int solo = m_Fractorium->ui.CurrentXformCombo->property("soloxform").toInt();
+ bool forceFinal = m_Fractorium->HaveFinal();
if (solo != -1)
{
- m_TempOpacities.resize(m_Ember.TotalXformCount());
+ m_TempOpacities.resize(m_Ember.TotalXformCount(forceFinal));
while (auto xform = m_Ember.GetTotalXform(i))
{
@@ -357,7 +358,7 @@ bool FractoriumEmberController::Render()
m_Renderer->SetEmber(m_Ember, action);
if (solo != -1)
- while (auto xform = m_Ember.GetTotalXform(i))
+ while (auto xform = m_Ember.GetTotalXform(i, forceFinal))
xform->m_Opacity = m_TempOpacities[i++];
}
diff --git a/Source/Fractorium/FractoriumXforms.cpp b/Source/Fractorium/FractoriumXforms.cpp
index 8738750..b57bf12 100644
--- a/Source/Fractorium/FractoriumXforms.cpp
+++ b/Source/Fractorium/FractoriumXforms.cpp
@@ -46,7 +46,8 @@ void Fractorium::InitXformsUI()
template
Xform* FractoriumEmberController::CurrentXform()
{
- return m_Ember.GetTotalXform(m_Fractorium->ui.CurrentXformCombo->currentIndex());
+ bool hasFinal = m_Fractorium->HaveFinal();
+ return m_Ember.GetTotalXform(m_Fractorium->ui.CurrentXformCombo->currentIndex(), hasFinal);//Need to force final for the special case they created a final, then cleared it, but did not delete it.
}
///
@@ -67,7 +68,9 @@ void Fractorium::CurrentXform(uint i)
template
void FractoriumEmberController::CurrentXformComboChanged(int index)
{
- if (auto xform = m_Ember.GetTotalXform(index))
+ bool forceFinal = m_Fractorium->HaveFinal();
+
+ if (auto xform = m_Ember.GetTotalXform(index, forceFinal))
{
FillWithXform(xform);
m_GLController->SetSelectedXform(xform);
@@ -95,13 +98,14 @@ void Fractorium::OnCurrentXformComboChanged(int index) { m_Controller->CurrentXf
template
void FractoriumEmberController::AddXform()
{
+ bool forceFinal = m_Fractorium->HaveFinal();
Update([&]()
{
Xform newXform;
newXform.m_Weight = 0.25;
newXform.m_ColorX = m_Rand.Frand01();
m_Ember.AddXform(newXform);
- int index = int(m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1));//Set index to the last item before final.
+ int index = int(m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1));//Set index to the last item before final.
FillXforms(index);
});
}
@@ -119,6 +123,7 @@ void Fractorium::OnAddXformButtonClicked(bool checked) { m_Controller->AddXform(
template
void FractoriumEmberController::AddLinkedXform()
{
+ bool forceFinal = m_Fractorium->HaveFinal();
UpdateXform([&](Xform* xform)
{
size_t i, count = m_Ember.XformCount();
@@ -148,7 +153,7 @@ void FractoriumEmberController::AddLinkedXform()
xform->SetXaos(count - 1, 1);//Set the xaos value for the previous xform pointing to the new one to one.
xform->m_Opacity = 0;//Clear the opacity of the previous xform.
- int index = int(m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1));//Set index to the last item before final.
+ int index = int(m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1));//Set index to the last item before final.
FillXforms(index);
FillXaos();
}, eXformUpdate::UPDATE_CURRENT);
@@ -165,6 +170,7 @@ void Fractorium::OnAddLinkedXformButtonClicked(bool checked) { m_Controller->Add
template
void FractoriumEmberController::DuplicateXform()
{
+ bool forceFinal = m_Fractorium->HaveFinal();
vector> vec;
vec.reserve(m_Ember.XformCount());
UpdateXform([&] (Xform* xform)
@@ -176,7 +182,7 @@ void FractoriumEmberController::DuplicateXform()
for (auto& it : vec)
m_Ember.AddXform(it);
- int index = int(m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1));//Set index to the last item before final.
+ int index = int(m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1));//Set index to the last item before final.
FillXforms(index);//Handles xaos.
});
}
@@ -211,49 +217,60 @@ void Fractorium::OnClearXformButtonClicked(bool checked) { m_Controller->ClearXf
template
void FractoriumEmberController::DeleteXforms()
{
- int offset = 0, current = 0, checked = 0;
- bool haveFinal = false;
- size_t count;
+ bool removed = false;
+ bool haveFinal = m_Fractorium->HaveFinal();
auto combo = m_Fractorium->ui.CurrentXformCombo;
+ Xform* finalXform = nullptr;
+ vector> xforms;
+ xforms.reserve(m_Ember.TotalXformCount());
//Iterating over the checkboxes must be done instead of using UpdateXform() to iterate over xforms
//because xforms are being deleted inside the loop.
//Also manually calling UpdateRender() rather than using the usual Update() call because
//it should only be called if an xform has actually been deleted.
- m_Fractorium->ForEachXformCheckbox([&](int i, QCheckBox * w)
+ //Rather than go through and delete, it's easier to just make a list of what we want to keep.
+ m_Fractorium->ForEachXformCheckbox([&](int i, QCheckBox * w, bool isFinal)
{
- count = m_Ember.TotalXformCount();
- haveFinal = m_Ember.UseFinalXform();//Requery every time.
-
- if (w->isChecked())
- checked++;
-
- //Do not allow deleting the only remaining non-final xform.
- if (haveFinal && count <= 2 && !(i - offset))
- return;
-
- if (!haveFinal && count == 1)
- return;
-
- if (w->isChecked())
+ if (!w->isChecked())//Keep if not checked.
{
- m_Ember.DeleteTotalXform(i - offset);//Subtract offset to account for previously deleted xforms.
- offset++;
+ if (isFinal)
+ finalXform = m_Ember.NonConstFinalXform();
+ else if (auto xform = m_Ember.GetXform(i))
+ xforms.push_back(*xform);
}
});
- current = combo->currentIndex();
- count = m_Ember.TotalXformCount();
- haveFinal = m_Ember.UseFinalXform();//Requery again.
+ //They might not have selected any checkboxes, in which case just delete the current.
+ auto current = combo->currentIndex();
+ auto count = m_Ember.TotalXformCount();
+ bool anySelected = xforms.size() < m_Ember.XformCount();
+ bool finalSelected = !finalXform && haveFinal;
//Nothing was selected, so just delete current.
- if (!checked &&
- !(haveFinal && count <= 2 && current == 0) &&//Again disallow deleting the only remaining non-final xform.
- !(!haveFinal && count == 1))
+ if (!anySelected && !finalSelected)
{
- m_Ember.DeleteTotalXform(current);
- offset++;
+ //Disallow deleting the only remaining non-final xform.
+ if (!(haveFinal && count <= 2 && current == 0) &&//One non-final, one final, disallow deleting non-final.
+ !(!haveFinal && count == 1))//One non-final, no final, disallow deleting.
+ {
+ m_Ember.DeleteTotalXform(current, haveFinal);
+ removed = true;
+ }
+ }
+ else
+ {
+ if (!xforms.empty() && (xforms.size() != m_Ember.XformCount()))//Remove if they requested to do so, but ensure it's not removing all.
+ {
+ removed = true;
+ m_Ember.ReplaceXforms(xforms);
+ }
+
+ if (finalSelected)
+ {
+ removed = true;
+ m_Ember.NonConstFinalXform()->Clear();
+ }
}
- if (offset)
+ if (removed)
{
int index = int(m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1));//Set index to the last item before final. Note final is requeried one last time.
FillXforms(index);
@@ -262,7 +279,6 @@ void FractoriumEmberController::DeleteXforms()
}
void Fractorium::OnDeleteXformButtonClicked(bool checked) { m_Controller->DeleteXforms(); }
-
///
/// Add a final xform to the ember and set it as the current xform.
/// Will only take action if a final xform is not already present.
@@ -286,9 +302,7 @@ void FractoriumEmberController::AddFinalXform()
});
}
}
-
void Fractorium::OnAddFinalXformButtonClicked(bool checked) { m_Controller->AddFinalXform(); }
-
///
/// Set the weight of the selected xforms.
/// Called when weight spinner changes.
@@ -304,9 +318,7 @@ void FractoriumEmberController::XformWeightChanged(double d)
}, eXformUpdate::UPDATE_SELECTED_EXCEPT_FINAL);
SetNormalizedWeightText(CurrentXform());
}
-
void Fractorium::OnXformWeightChanged(double d) { m_Controller->XformWeightChanged(d); }
-
///
/// Equalize the weights of all xforms in the ember.
///
@@ -319,9 +331,7 @@ void FractoriumEmberController::EqualizeWeights()
m_Fractorium->m_XformWeightSpin->setValue(xform->m_Weight);//Will trigger an update, so pass false to updateRender below.
}, eXformUpdate::UPDATE_CURRENT, false);
}
-
void Fractorium::OnEqualWeightButtonClicked(bool checked) { m_Controller->EqualizeWeights(); }
-
///
/// Set the name of the current xform.
/// Update the corresponding xform checkbox text with the name.
@@ -332,17 +342,16 @@ void Fractorium::OnEqualWeightButtonClicked(bool checked) { m_Controller->Equali
template
void FractoriumEmberController::XformNameChanged(int row, int col)
{
+ bool forceFinal = m_Fractorium->HaveFinal();
UpdateXform([&] (Xform* xform)
{
- int index = m_Ember.GetTotalXformIndex(xform);
+ int index = m_Ember.GetTotalXformIndex(xform, forceFinal);
xform->m_Name = m_Fractorium->ui.XformWeightNameTable->item(row, col)->text().toStdString();
XformCheckboxAt(index, [&](QCheckBox * checkbox) { checkbox->setText(MakeXformCaption(index)); });
}, eXformUpdate::UPDATE_CURRENT, false);
FillSummary();//Manually update because this does not trigger a render, which is where this would normally be called.
}
-
void Fractorium::OnXformNameChanged(int row, int col) { m_Controller->XformNameChanged(row, col); }
-
///
/// Set the animate field of the selected xforms.
/// This has no effect on interactive rendering, it only sets a value
@@ -373,9 +382,7 @@ void FractoriumEmberController::XformAnimateChanged(int state)
}
}, false, eProcessAction::NOTHING, m_Fractorium->ApplyAll());
}
-
void Fractorium::OnXformAnimateCheckBoxStateChanged(int state) { m_Controller->XformAnimateChanged(state); }
-
///
/// Fill all GUI widgets with values from the passed in xform.
///
@@ -399,7 +406,6 @@ void FractoriumEmberController::FillWithXform(Xform* xform)//Need to see w
FillAffineWithXform(xform, true);
FillAffineWithXform(xform, false);
}
-
///
/// Set the normalized weight of the current xform as the suffix text of the weight spinner.
///
@@ -416,7 +422,6 @@ void FractoriumEmberController::SetNormalizedWeightText(Xform* xform)
m_Fractorium->m_XformWeightSpin->setSuffix(QString(" (") + QLocale::system().toString(double(m_NormalizedWeights[index]), 'g', 3) + ")");
}
}
-
///
/// Determine whether the specified xform is the final xform in the ember.
///
@@ -427,7 +432,6 @@ bool FractoriumEmberController::IsFinal(Xform* xform)
{
return (m_Fractorium->HaveFinal() && (xform == m_Ember.FinalXform()));
}
-
///
/// Fill the xforms combo box with the xforms in the current ember.
/// Select the index passed in and fill all widgets with its values.
@@ -498,9 +502,7 @@ void FractoriumEmberController::FillXforms(int index)
m_Fractorium->OnSoloXformCheckBoxStateChanged(Qt::Unchecked);
m_Fractorium->OnCurrentXformComboChanged(index);//Make sure the event gets called, because it won't if the zero index is already selected.
}
-
template class FractoriumEmberController;
-
#ifdef DO_DOUBLE
-template class FractoriumEmberController;
-#endif
+ template class FractoriumEmberController;
+#endif
\ No newline at end of file
diff --git a/Source/Fractorium/FractoriumXformsSelect.cpp b/Source/Fractorium/FractoriumXformsSelect.cpp
index 7bcc35d..cbc8174 100644
--- a/Source/Fractorium/FractoriumXformsSelect.cpp
+++ b/Source/Fractorium/FractoriumXformsSelect.cpp
@@ -16,13 +16,13 @@ void Fractorium::InitXformsSelectUI()
/// Check all of the xform selection checkboxes.
///
/// Ignored
-void Fractorium::OnXformsSelectAllButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox * w) { w->setChecked(true); }); }
+void Fractorium::OnXformsSelectAllButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox * w, bool isFinal) { w->setChecked(true); }); }
///
/// Uncheck all of the xform selection checkboxes.
///
/// Ignored
-void Fractorium::OnXformsSelectNoneButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox * w) { w->setChecked(false); }); }
+void Fractorium::OnXformsSelectNoneButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox * w, bool isFinal) { w->setChecked(false); }); }
///
/// Return whether the checkbox at the specified index is checked.
@@ -67,10 +67,11 @@ void Fractorium::ClearXformsSelections()
template
QString FractoriumEmberController::MakeXformCaption(size_t i)
{
- bool isFinal = m_Ember.FinalXform() == m_Ember.GetTotalXform(i);
+ bool forceFinal = m_Fractorium->HaveFinal();
+ bool isFinal = m_Ember.FinalXform() == m_Ember.GetTotalXform(i, forceFinal);
QString caption = isFinal ? "Final" : QString::number(i + 1);
- if (auto xform = m_Ember.GetTotalXform(i))
+ if (auto xform = m_Ember.GetTotalXform(i, forceFinal))
if (!xform->m_Name.empty())
caption += " (" + QString::fromStdString(xform->m_Name) + ")";
@@ -81,12 +82,13 @@ QString FractoriumEmberController::MakeXformCaption(size_t i)
/// Function to perform the specified operation on every dynamically created xform selection checkbox.
///
/// The operation to perform
-void Fractorium::ForEachXformCheckbox(std::function func)
+void Fractorium::ForEachXformCheckbox(std::function func)
{
int i = 0;
+ bool haveFinal = HaveFinal();
for (auto& cb : m_XformSelections)
- func(i++, cb);
+ func(i++, cb, haveFinal && cb == m_XformSelections.back());
}
///
@@ -120,7 +122,8 @@ bool FractoriumEmberController::XformCheckboxAt(int i, std::function
bool FractoriumEmberController::XformCheckboxAt(Xform* xform, std::function func)
{
- return XformCheckboxAt(m_Ember.GetTotalXformIndex(xform), func);
+ bool forceFinal = m_Fractorium->HaveFinal();
+ return XformCheckboxAt(m_Ember.GetTotalXformIndex(xform, forceFinal), func);
}
template class FractoriumEmberController;
diff --git a/Source/Fractorium/FractoriumXformsVariations.cpp b/Source/Fractorium/FractoriumXformsVariations.cpp
index 5923f45..642ce8c 100644
--- a/Source/Fractorium/FractoriumXformsVariations.cpp
+++ b/Source/Fractorium/FractoriumXformsVariations.cpp
@@ -215,7 +215,7 @@ void FractoriumEmberController::VariationSpinBoxValueChanged(double d)//Would
if (isParam)
{
//Do not take action if the xform doesn't contain the variation which this param is part of.
- if (ParametricVariation* xformParVar = dynamic_cast*>(xformVar))//The parametric cast of the xform's variation.
+ if (auto xformParVar = dynamic_cast*>(xformVar))//The parametric cast of the xform's variation.
if (xformParVar->SetParamVal(sender->ParamName().c_str(), d))
update = true;
}
diff --git a/Source/Fractorium/GLWidget.cpp b/Source/Fractorium/GLWidget.cpp
index 377a571..8b7ef51 100644
--- a/Source/Fractorium/GLWidget.cpp
+++ b/Source/Fractorium/GLWidget.cpp
@@ -290,6 +290,7 @@ void GLEmberController::DrawAffines(bool pre, bool post)
auto ember = m_FractoriumEmberController->CurrentEmber();
bool dragging = m_DragState == eDragState::DragDragging;
+ bool forceFinal = m_Fractorium->HaveFinal();
//Draw grid if control key is pressed.
if ((m_GL->hasFocus() && GetControl()) || m_Fractorium->DrawGrid())
@@ -307,7 +308,7 @@ void GLEmberController::DrawAffines(bool pre, bool post)
{
size_t i = 0;
- while (auto xform = ember->GetTotalXform(i))
+ while (auto xform = ember->GetTotalXform(i, forceFinal))
{
bool selected = m_Fractorium->IsXformSelected(i++) || (dragging ? (m_SelectedXform == xform) : (m_HoverXform == xform));
DrawAffine(xform, true, selected);
@@ -322,7 +323,7 @@ void GLEmberController::DrawAffines(bool pre, bool post)
{
size_t i = 0;
- while (auto xform = ember->GetTotalXform(i))
+ while (auto xform = ember->GetTotalXform(i, forceFinal))
{
bool selected = m_Fractorium->IsXformSelected(i++) || (dragging ? (m_SelectedXform == xform) : (m_HoverXform == xform));
DrawAffine(xform, false, selected);
@@ -1035,6 +1036,8 @@ int GLEmberController::UpdateHover(v3T& glCoords)
if (m_Fractorium->DrawXforms())//Don't bother checking anything if the user wants to see no xforms.
{
+ bool forceFinal = m_Fractorium->HaveFinal();
+
//If there's a selected/current xform, check it first so it gets precedence over the others.
if (m_SelectedXform)
{
@@ -1047,12 +1050,13 @@ int GLEmberController::UpdateHover(v3T& glCoords)
if (CheckXformHover(m_SelectedXform, glCoords, bestDist, checkSelPre, checkSelPost))
{
m_HoverXform = m_SelectedXform;
- bestIndex = int(ember->GetTotalXformIndex(m_SelectedXform));
+ bestIndex = int(ember->GetTotalXformIndex(m_SelectedXform, forceFinal));
}
}
//Check all xforms.
- while (auto xform = ember->GetTotalXform(i))
+
+ while (auto xform = ember->GetTotalXform(i, forceFinal))
{
if (preAll || (pre && m_HoverXform == xform))//Only check pre affine if they are shown.
{