--User changes

Add the ability to set the current xform by pressing F1 - F32.
 Add the ability to toggle an entire row or column of xaos values.

--Bug fixes
 Prevent xform index flickering whenever changing the number of xforms.

--Code changes
 Remove ForEach() wrappers and replace with range based for loops with auto.
 Replace every regular for loop with a range based one where applicable. Note this doesn't work everywhere.
 Make event filter application wide.
 Add parameter to FillXforms() to specify the index to select, default 0.
 Rename some scroll areas and layouts to names that make sense, rather than their designer defaults.
This commit is contained in:
mfeemster 2015-05-03 17:13:14 -07:00
parent cd5669d0ef
commit e005b4c20e
29 changed files with 282 additions and 212 deletions

View File

@ -543,7 +543,7 @@ public:
{ {
bool b = false; bool b = false;
ForEach(m_Xforms, [&](const Xform<T>& xform) { b |= xform.XaosPresent(); });//If at least one entry is not equal to 1, then xaos is present. for (auto& xform : m_Xforms) b |= xform.XaosPresent();//If at least one entry is not equal to 1, then xaos is present.
return b; return b;
} }
@ -553,7 +553,7 @@ public:
/// </summary> /// </summary>
void ClearXaos() void ClearXaos()
{ {
ForEach(m_Xforms, [&](Xform<T>& xform) { xform.ClearXaos(); }); for (auto& xform : m_Xforms) xform.ClearXaos();
} }
/// <summary> /// <summary>
@ -605,7 +605,7 @@ public:
{ {
T weight = T(1) / m_Xforms.size(); T weight = T(1) / m_Xforms.size();
ForEach(m_Xforms, [&](Xform<T>& xform) { xform.m_Weight = weight; }); for (auto& xform : m_Xforms) xform.m_Weight = weight;
} }
/// <summary> /// <summary>
@ -620,8 +620,8 @@ public:
if (normalizedWeights.size() != m_Xforms.size()) if (normalizedWeights.size() != m_Xforms.size())
normalizedWeights.resize(m_Xforms.size()); normalizedWeights.resize(m_Xforms.size());
ForEach(m_Xforms, [&](Xform<T>& xform) { norm += xform.m_Weight; }); for (auto& xform : m_Xforms) norm += xform.m_Weight;
ForEach(normalizedWeights, [&](T& weight) { weight = (norm == T(0) ? T(0) : m_Xforms[i].m_Weight / norm); i++; }); for (auto& weight : normalizedWeights) { weight = (norm == T(0) ? T(0) : m_Xforms[i].m_Weight / norm); i++; }
} }
/// <summary> /// <summary>
@ -635,7 +635,8 @@ public:
size_t i = 0, xformIndex = 0, totalVarCount = m_FinalXform.TotalVariationCount(); size_t i = 0, xformIndex = 0, totalVarCount = m_FinalXform.TotalVariationCount();
variations.clear(); variations.clear();
ForEach(m_Xforms, [&](const Xform<T>& xform) { totalVarCount += xform.TotalVariationCount(); }); for (auto& xform : m_Xforms) totalVarCount += xform.TotalVariationCount();
variations.reserve(totalVarCount); variations.reserve(totalVarCount);
while (Xform<T>* xform = GetTotalXform(xformIndex++)) while (Xform<T>* xform = GetTotalXform(xformIndex++))
@ -672,7 +673,7 @@ public:
{ {
bool flattened = false; bool flattened = false;
ForEach(m_Xforms, [&](Xform<T>& xform) { flattened |= xform.Flatten(names); }); for (auto& xform : m_Xforms) flattened |= xform.Flatten(names);
return flattened; return flattened;
} }
@ -685,12 +686,12 @@ public:
{ {
bool unflattened = false; bool unflattened = false;
ForEach(m_Xforms, [&](Xform<T>& xform) for (auto& xform : m_Xforms)
{ {
unflattened |= xform.DeleteVariationById(VAR_PRE_FLATTEN); unflattened |= xform.DeleteVariationById(VAR_PRE_FLATTEN);
unflattened |= xform.DeleteVariationById(VAR_FLATTEN); unflattened |= xform.DeleteVariationById(VAR_FLATTEN);
unflattened |= xform.DeleteVariationById(VAR_POST_FLATTEN); unflattened |= xform.DeleteVariationById(VAR_POST_FLATTEN);
}); }
return unflattened; return unflattened;
} }

View File

@ -83,9 +83,9 @@ public:
f.write(temp.c_str(), temp.size()); f.write(temp.c_str(), temp.size());
} }
for (size_t i = 0; i < embers.size(); i++) for (auto& ember : embers)
{ {
string s = ToString(embers[i], "", printEditDepth, doEdits, intPalette, hexPalette); string s = ToString(ember, "", printEditDepth, doEdits, intPalette, hexPalette);
f.write(s.c_str(), s.size()); f.write(s.c_str(), s.size());
} }
@ -202,7 +202,7 @@ public:
ember.GetPresentVariations(variations, false); ember.GetPresentVariations(variations, false);
if (!variations.empty()) if (!variations.empty())
ForEach(variations, [&] (Variation<T>* var) { os << var->Name() << (var != variations.back() ? " " : "\""); }); for (auto var : variations) os << var->Name() << (var != variations.back() ? " " : "\"");
else else
os << "\""; os << "\"";

View File

@ -472,8 +472,8 @@ public:
{ {
Xform<T> xform; Xform<T> xform;
for (size_t xf = 0; xf < xforms.size(); xf++) for (auto xf : xforms)
MergeXformVariations1Way(xforms[xf], &xform, false, clearWeights); MergeXformVariations1Way(xf, &xform, false, clearWeights);
return xform; return xform;
} }

View File

@ -88,8 +88,8 @@ void Renderer<T, bucketT>::ComputeBounds()
//Check the size of the density estimation filter. //Check the size of the density estimation filter.
//If the radius of the density estimation filter is greater than the //If the radius of the density estimation filter is greater than the
//gutter width, have to pad with more. Otherwise, use the same value. //gutter width, have to pad with more. Otherwise, use the same value.
for (size_t i = 0; i < m_Embers.size(); i++) for (auto& ember : m_Embers)
maxDEFilterWidth = std::max<size_t>(size_t(ceil(m_Embers[i].m_MaxRadDE) * m_Ember.m_Supersample), maxDEFilterWidth); maxDEFilterWidth = std::max<size_t>(size_t(ceil(ember.m_MaxRadDE) * m_Ember.m_Supersample), maxDEFilterWidth);
//Need an extra ss = (int)floor(m_Supersample / 2.0) of pixels so that a local iteration count for DE can be determined.//SMOULDER //Need an extra ss = (int)floor(m_Supersample / 2.0) of pixels so that a local iteration count for DE can be determined.//SMOULDER
if (maxDEFilterWidth > 0) if (maxDEFilterWidth > 0)
@ -748,16 +748,16 @@ bool Renderer<T, bucketT>::Alloc()
b &= (m_Samples.size() == m_ThreadsToUse); b &= (m_Samples.size() == m_ThreadsToUse);
} }
for (size_t i = 0; i < m_Samples.size(); i++) for (auto& sample : m_Samples)
{ {
if (m_Samples[i].size() != SubBatchSize()) if (sample.size() != SubBatchSize())
{ {
m_Samples[i].resize(SubBatchSize()); sample.resize(SubBatchSize());
if (m_ReclaimOnResize) if (m_ReclaimOnResize)
m_Samples[i].shrink_to_fit(); sample.shrink_to_fit();
b &= (m_Samples[i].size() == SubBatchSize()); b &= (sample.size() == SubBatchSize());
} }
} }
@ -1214,6 +1214,9 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
#else #else
parallel_for(size_t(0), m_ThreadsToUse, [&] (size_t threadIndex) parallel_for(size_t(0), m_ThreadsToUse, [&] (size_t threadIndex)
{ {
#endif
#ifdef WIN32
//SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
#endif #endif
//Timing t; //Timing t;
IterParams<T> params; IterParams<T> params;
@ -1441,7 +1444,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
{ {
size_t histIndex, intColorIndex, histSize = m_HistBuckets.size(); size_t histIndex, intColorIndex, histSize = m_HistBuckets.size();
bucketT colorIndex, colorIndexFrac; bucketT colorIndex, colorIndexFrac;
const tvec4<bucketT, glm::defaultp>* dmap = &(palette->m_Entries[0]); auto dmap = palette->m_Entries.data();
//T oneColDiv2 = m_CarToRas.OneCol() / 2; //T oneColDiv2 = m_CarToRas.OneCol() / 2;
//T oneRowDiv2 = m_CarToRas.OneRow() / 2; //T oneRowDiv2 = m_CarToRas.OneRow() / 2;

View File

@ -21,18 +21,6 @@ static inline bool FindIf(c& container, pr pred)
return std::find_if(container.begin(), container.end(), pred) != container.end(); return std::find_if(container.begin(), container.end(), pred) != container.end();
} }
/// <summary>
/// Thin wrapper around std::for_each() to relieve the caller of having to
/// pass the implicitly obvious .begin() and .end().
/// </summary>
/// <param name="container">The container to call for_each() on</param>
/// <param name="pred">The lambda to call on each element</param>
template<class c, class fn>
static inline void ForEach(c& container, fn func)
{
std::for_each(container.begin(), container.end(), func);
}
/// <summary> /// <summary>
/// Thin wrapper around computing the total size of a vector. /// Thin wrapper around computing the total size of a vector.
/// </summary> /// </summary>
@ -149,7 +137,7 @@ public:
{ {
stringstream ss; stringstream ss;
ForEach(errorReport, [&](const string& s) { ss << s << endl; }); for (auto& s : errorReport) ss << s << endl;
return ss.str(); return ss.str();
} }

View File

@ -1678,11 +1678,14 @@ public:
{ {
bool b = false; bool b = false;
ForEach(m_Params, [&](ParamWithName<T>& param) for (auto& param : m_Params)
{ {
if (!_stricmp(param.Name().c_str(), name)) if (!_stricmp(param.Name().c_str(), name))
{
b = true; b = true;
}); break;
}
}
return b; return b;
} }
@ -1694,9 +1697,9 @@ public:
/// <returns>A pointer to the parameter value if the name matched, else false.</returns> /// <returns>A pointer to the parameter value if the name matched, else false.</returns>
T* GetParam(const char* name) T* GetParam(const char* name)
{ {
for (size_t i = 0; i < m_Params.size(); i++) for (auto& param : m_Params)
if (!_stricmp(m_Params[i].Name().c_str(), name)) if (!_stricmp(param.Name().c_str(), name))
return m_Params[i].Param(); return param.Param();
return nullptr; return nullptr;
} }
@ -1708,9 +1711,9 @@ public:
/// <returns>A parameter value if the name matched, else 0.</returns> /// <returns>A parameter value if the name matched, else 0.</returns>
T GetParamVal(const char* name) const T GetParamVal(const char* name) const
{ {
for (size_t i = 0; i < m_Params.size(); i++) for (auto& param : m_Params)
if (!_stricmp(m_Params[i].Name().c_str(), name)) if (!_stricmp(param.Name().c_str(), name))
return m_Params[i].ParamVal(); return param.ParamVal();
return 0; return 0;
} }
@ -1725,14 +1728,15 @@ public:
{ {
bool b = false; bool b = false;
ForEach(m_Params, [&](ParamWithName<T>& param) for (auto& param : m_Params)
{ {
if (!_stricmp(param.Name().c_str(), name)) if (!_stricmp(param.Name().c_str(), name))
{ {
param.Set(val); param.Set(val);
b = true; b = true;
break;
} }
}); }
if (b) if (b)
this->Precalc(); this->Precalc();
@ -1772,7 +1776,7 @@ public:
virtual void Random(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override virtual void Random(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{ {
Variation<T>::Random(rand); Variation<T>::Random(rand);
ForEach(m_Params, [&](ParamWithName<T>& param) { param.Set(rand.Frand11<T>()); }); for (auto& param : m_Params) param.Set(rand.Frand11<T>());
this->Precalc(); this->Precalc();
} }
@ -1781,7 +1785,7 @@ public:
/// </summary> /// </summary>
void Clear() void Clear()
{ {
ForEach(m_Params, [&](ParamWithName<T>& param) { *(param.Param()) = 0; }); for (auto& param : m_Params) *(param.Param()) = 0;
this->Precalc(); this->Precalc();
} }
@ -1795,11 +1799,11 @@ public:
vector<string> vec; vector<string> vec;
vec.reserve(m_Params.size()); vec.reserve(m_Params.size());
ForEach(m_Params, [&](const ParamWithName<T>& param) for (auto& param : m_Params)
{ {
if ((includePrecalcs && param.IsPrecalc()) || !param.IsPrecalc()) if ((includePrecalcs && param.IsPrecalc()) || !param.IsPrecalc())
vec.push_back(param.Name()); vec.push_back(param.Name());
}); }
return vec; return vec;
} }
@ -1813,7 +1817,7 @@ public:
ostringstream ss; ostringstream ss;
ss << Variation<T>::ToString() << endl; ss << Variation<T>::ToString() << endl;
ForEach(m_Params, [&](const ParamWithName<T>& param) { ss << param.ToString() << endl; }); for (auto& param : m_Params) ss << param.ToString() << endl;
return ss.str(); return ss.str();
} }

View File

@ -342,16 +342,16 @@ public:
ADDPREPOSTREGVAR(DCTriangle) ADDPREPOSTREGVAR(DCTriangle)
ADDPREPOSTREGVAR(DCZTransl) ADDPREPOSTREGVAR(DCZTransl)
ForEach(m_Variations, [&](Variation<T>* var) { var->Precalc(); }); for (auto var : m_Variations) var->Precalc();
std::sort(m_Variations.begin(), m_Variations.end(), [&](const Variation<T>* var1, const Variation<T>* var2) { return var1->VariationId() < var2->VariationId(); }); std::sort(m_Variations.begin(), m_Variations.end(), [&](const Variation<T>* var1, const Variation<T>* var2) { return var1->VariationId() < var2->VariationId(); });
m_RegVariations.reserve(m_Variations.size() / 3); m_RegVariations.reserve(m_Variations.size() / 3);
m_PreVariations.reserve(m_Variations.size() / 3); m_PreVariations.reserve(m_Variations.size() / 3);
m_PostVariations.reserve(m_Variations.size() / 3); m_PostVariations.reserve(m_Variations.size() / 3);
ForEach(m_Variations, [&](Variation<T>* var) { if (var->VarType() == VARTYPE_REG) m_RegVariations.push_back(var); }); for (auto var : m_Variations) if (var->VarType() == VARTYPE_REG) m_RegVariations.push_back(var);
ForEach(m_Variations, [&](Variation<T>* var) { if (var->VarType() == VARTYPE_PRE) m_PreVariations.push_back(var); }); for (auto var : m_Variations) if (var->VarType() == VARTYPE_PRE) m_PreVariations.push_back(var);
ForEach(m_Variations, [&](Variation<T>* var) { if (var->VarType() == VARTYPE_POST) m_PostVariations.push_back(var); }); for (auto var : m_Variations) if (var->VarType() == VARTYPE_POST) m_PostVariations.push_back(var);
//Keep a list of which variations derive from ParametricVariation. //Keep a list of which variations derive from ParametricVariation.
//Note that these are not new copies, rather just pointers to the original instances in m_Variations. //Note that these are not new copies, rather just pointers to the original instances in m_Variations.

View File

@ -365,11 +365,11 @@ public:
const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing) const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing)
{ {
for (size_t i = 0; i < variations.size(); i++) for (auto v : variations)
{ {
if (variations[i] != nullptr && variations[i]->VariationId() == id) if (v != nullptr && v->VariationId() == id)
{ {
var = variations[i]; var = v;
keepGoing = false; keepGoing = false;
break; break;
} }
@ -390,11 +390,11 @@ public:
const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing) const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing)
{ {
for (size_t i = 0; i < variations.size(); i++) for (auto v : variations)
{ {
if (variations[i] != nullptr && variations[i]->Name() == name) if (v != nullptr && v->Name() == name)
{ {
var = variations[i]; var = v;
keepGoing = false; keepGoing = false;
break; break;
} }
@ -593,8 +593,8 @@ public:
{ {
T norm = 0; T norm = 0;
ForEach(variations, [&](Variation<T>* var) { norm += var->m_Weight; }); for (auto var : variations) norm += var->m_Weight;
ForEach(variations, [&](Variation<T>* var) { var->m_Weight /= norm; }); for (auto var : variations) var->m_Weight /= norm;
}); });
} }
@ -839,45 +839,30 @@ public:
m_HasPreOrRegularVars = PreVariationCount() > 0 || VariationCount() > 0; m_HasPreOrRegularVars = PreVariationCount() > 0 || VariationCount() > 0;
//Only set precalcs for regular variations, they work differently for pre and post. //Only set precalcs for regular variations, they work differently for pre and post.
for (size_t i = 0; i < m_Variations.size(); i++) for (auto var : m_Variations)
{ {
if (m_Variations[i]->NeedPrecalcSumSquares()) if (var->NeedPrecalcSumSquares())
m_NeedPrecalcSumSquares = true; m_NeedPrecalcSumSquares = true;
if (m_Variations[i]->NeedPrecalcSqrtSumSquares()) if (var->NeedPrecalcSqrtSumSquares())
m_NeedPrecalcSqrtSumSquares = true; m_NeedPrecalcSqrtSumSquares = true;
if (m_Variations[i]->NeedPrecalcAngles()) if (var->NeedPrecalcAngles())
m_NeedPrecalcAngles = true; m_NeedPrecalcAngles = true;
if (m_Variations[i]->NeedPrecalcAtanXY()) if (var->NeedPrecalcAtanXY())
m_NeedPrecalcAtanXY = true; m_NeedPrecalcAtanXY = true;
if (m_Variations[i]->NeedPrecalcAtanYX()) if (var->NeedPrecalcAtanYX())
m_NeedPrecalcAtanYX = true; m_NeedPrecalcAtanYX = true;
} }
AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing) AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing)
{ {
for (size_t i = 0; i < variations.size(); i++) for (auto var : variations)
{ {
/*if (variations[i]->NeedPrecalcSumSquares()) var->ParentXform(this);
m_NeedPrecalcSumSquares = true; var->Precalc();
if (variations[i]->NeedPrecalcSqrtSumSquares())
m_NeedPrecalcSqrtSumSquares = true;
if (variations[i]->NeedPrecalcAngles())
m_NeedPrecalcAngles = true;
if (variations[i]->NeedPrecalcAtanXY())
m_NeedPrecalcAtanXY = true;
if (variations[i]->NeedPrecalcAtanYX())
m_NeedPrecalcAtanYX = true;*/
variations[i]->ParentXform(this);
variations[i]->Precalc();
} }
}); });
} }
@ -925,10 +910,9 @@ public:
{ {
AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing) AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing)
{ {
for (size_t i = 0; i < variations.size(); i++) for (auto var : variations)
//for (size_t i = 0; i < variations.size(); i++)
{ {
Variation<T>* var = variations[i];
if (var->m_Weight != 0)//This should never happen, but just to be safe. if (var->m_Weight != 0)//This should never happen, but just to be safe.
{ {
if (FindIf(names, [&] (const string& s) -> bool { return !_stricmp(s.c_str(), var->Name().c_str()); }))//If any variation is present, don't flatten. if (FindIf(names, [&] (const string& s) -> bool { return !_stricmp(s.c_str(), var->Name().c_str()); }))//If any variation is present, don't flatten.
@ -942,14 +926,15 @@ public:
//Now traverse the parameters for this variation. //Now traverse the parameters for this variation.
if (ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var))//If any parametric variation parameter is present and non-zero, don't flatten. if (ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var))//If any parametric variation parameter is present and non-zero, don't flatten.
{ {
ForEach(names, [&] (const string& s) for (auto& s : names)
{ {
if (parVar->GetParamVal(s.c_str()) != 0) if (parVar->GetParamVal(s.c_str()) != 0)
{ {
shouldFlatten = false; shouldFlatten = false;
keepGoing = false; keepGoing = false;
break;
} }
}); }
} }
} }
}); });
@ -1175,16 +1160,16 @@ public:
const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing) const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool& keepGoing)
{ {
for (size_t i = 0; i < variations.size(); i++) for (auto var : variations)
ss << variations[i]->ToString() << endl; ss << var->ToString() << endl;
ss << endl; ss << endl;
}); });
if (XaosPresent()) if (XaosPresent())
{ {
for (size_t i = 0; i < m_Xaos.size(); i++) for (auto xaos : m_Xaos)
ss << m_Xaos[i] << " "; ss << xaos << " ";
ss << endl; ss << endl;
} }

View File

@ -1261,11 +1261,9 @@ private:
/// <returns>The corrected name if one was found, else the passed in name.</returns> /// <returns>The corrected name if one was found, else the passed in name.</returns>
static string GetCorrectedParamName(vector<pair<string, string>>& vec, const char* name) static string GetCorrectedParamName(vector<pair<string, string>>& vec, const char* name)
{ {
for (size_t i = 0; i < vec.size(); i++) for (auto& v : vec)
{ if (!_stricmp(v.first.c_str(), name))
if (!_stricmp(vec[i].first.c_str(), name)) return v.second;
return vec[i].second;
}
return name; return name;
} }
@ -1281,21 +1279,21 @@ private:
/// <returns>The corrected name if one was found, else the passed in name.</returns> /// <returns>The corrected name if one was found, else the passed in name.</returns>
static string GetCorrectedVariationName(vector<pair<pair<string, string>, vector<string>>>& vec, xmlAttrPtr att) static string GetCorrectedVariationName(vector<pair<pair<string, string>, vector<string>>>& vec, xmlAttrPtr att)
{ {
for (size_t i = 0; i < vec.size(); i++) for (auto& v : vec)
{ {
if (!_stricmp(vec[i].first.first.c_str(), CCX(att->name)))//Do case insensitive here. if (!_stricmp(v.first.first.c_str(), CCX(att->name)))//Do case insensitive here.
{ {
if (!vec[i].second.empty()) if (!v.second.empty())
{ {
for (size_t j = 0; j < vec[i].second.size(); j++) for (size_t j = 0; j < v.second.size(); j++)
{ {
if (XmlContainsTag(att, vec[i].second[j].c_str())) if (XmlContainsTag(att, v.second[j].c_str()))
return vec[i].first.second; return v.first.second;
} }
} }
else else
{ {
return vec[i].first.second; return v.first.second;
} }
} }
} }

View File

@ -55,7 +55,7 @@ string IterOpenCLKernelCreator<T>::CreateIterKernelString(Ember<T>& ember, strin
xformFuncs << "\n" << parVarDefines << endl; xformFuncs << "\n" << parVarDefines << endl;
ember.GetPresentVariations(variations); ember.GetPresentVariations(variations);
ForEach(variations, [&](Variation<T>* var) { if (var) xformFuncs << var->OpenCLFuncsString(); }); for (auto var : variations) if (var) xformFuncs << var->OpenCLFuncsString();
for (i = 0; i < totalXformCount; i++) for (i = 0; i < totalXformCount; i++)
{ {

View File

@ -96,11 +96,11 @@ bool OpenCLWrapper::AddProgram(const string& name, const string& program, const
if (CreateSPK(name, program, entryPoint, spk, doublePrecision)) if (CreateSPK(name, program, entryPoint, spk, doublePrecision))
{ {
for (size_t i = 0; i < m_Programs.size(); i++) for (auto& program : m_Programs)
{ {
if (name == m_Programs[i].m_Name) if (name == program.m_Name)
{ {
m_Programs[i] = spk; program = spk;
return true; return true;
} }
} }

View File

@ -1483,10 +1483,10 @@ void RendererCL<T>::FillSeeds()
{ {
m_Seeds.resize(IterGridKernelCount()); m_Seeds.resize(IterGridKernelCount());
for (size_t i = 0; i < m_Seeds.size(); i++) for (auto& seed : m_Seeds)
{ {
m_Seeds[i].x = m_Rand[0].Rand(); seed.x = m_Rand[0].Rand();
m_Seeds[i].y = m_Rand[0].Rand(); seed.y = m_Rand[0].Rand();
} }
} }

View File

@ -550,11 +550,11 @@ public:
CSimpleOpt::SOption endOption = SO_END_OF_OPTIONS; CSimpleOpt::SOption endOption = SO_END_OF_OPTIONS;
entries.reserve(75); entries.reserve(75);
ForEach(m_BoolArgs, [&](Eob* entry) { if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option); }); for (auto entry : m_BoolArgs) if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option);
ForEach(m_IntArgs, [&](Eoi* entry) { if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option); }); for (auto entry : m_IntArgs) if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option);
ForEach(m_UintArgs, [&](Eou* entry) { if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option); }); for (auto entry : m_UintArgs) if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option);
ForEach(m_DoubleArgs, [&](Eod* entry) { if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option); }); for (auto entry : m_DoubleArgs) if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option);
ForEach(m_StringArgs, [&](Eos* entry) { if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option); }); for (auto entry : m_StringArgs) if (entry->m_OptionUse & optUsage) entries.push_back(entry->m_Option);
entries.push_back(endOption); entries.push_back(endOption);
return entries; return entries;
@ -569,11 +569,11 @@ public:
{ {
ostringstream os; ostringstream os;
ForEach(m_BoolArgs, [&](Eob* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl; }); for (auto entry : m_BoolArgs) if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl;
ForEach(m_IntArgs, [&](Eoi* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl; }); for (auto entry : m_IntArgs) if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl;
ForEach(m_UintArgs, [&](Eou* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl; }); for (auto entry : m_UintArgs) if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl;
ForEach(m_DoubleArgs, [&](Eod* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl; }); for (auto entry : m_DoubleArgs) if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl;
ForEach(m_StringArgs, [&](Eos* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl; }); for (auto entry : m_StringArgs) if (entry->m_OptionUse & optUsage) os << entry->m_DocString << endl;
return os.str(); return os.str();
} }
@ -588,11 +588,11 @@ public:
ostringstream os; ostringstream os;
os << std::boolalpha; os << std::boolalpha;
ForEach(m_BoolArgs, [&](Eob* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; }); for (auto entry : m_BoolArgs) if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl;
ForEach(m_IntArgs, [&](Eoi* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; }); for (auto entry : m_IntArgs) if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl;
ForEach(m_UintArgs, [&](Eou* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; }); for (auto entry : m_UintArgs) if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl;
ForEach(m_DoubleArgs, [&](Eod* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; }); for (auto entry : m_DoubleArgs) if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl;
ForEach(m_StringArgs, [&](Eos* entry) { if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; }); for (auto entry : m_StringArgs) if (entry->m_OptionUse & optUsage) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl;
return os.str(); return os.str();
} }

View File

@ -1317,7 +1317,7 @@ void TestVarTime()
} }
std::sort(times.begin(), times.end(), &SortPairByTime); std::sort(times.begin(), times.end(), &SortPairByTime);
//ForEach(times, [&](pair<string, double>& p) { cout << p.first << "\t" << p.second << "" << endl; }); //forr (auto& p : times) cout << p.first << "\t" << p.second << "" << endl;
} }
void TestCasting() void TestCasting()

View File

@ -385,8 +385,8 @@ void FractoriumFinalRenderDialog::OnPlatformComboCurrentIndexChanged(int index)
ui.FinalRenderDeviceCombo->clear(); ui.FinalRenderDeviceCombo->clear();
for (size_t i = 0; i < devices.size(); i++) for (auto& device : devices)
ui.FinalRenderDeviceCombo->addItem(QString::fromStdString(devices[i])); ui.FinalRenderDeviceCombo->addItem(QString::fromStdString(device));
} }
/// <summary> /// <summary>

View File

@ -522,8 +522,8 @@ void FinalRenderEmberController<T>::SyncGuiToEmbers(size_t widthOverride, size_t
{ {
if (m_FinalRenderDialog->ApplyToAll()) if (m_FinalRenderDialog->ApplyToAll())
{ {
for (size_t i = 0; i < m_EmberFile.Size(); i++) for (auto& ember : m_EmberFile.m_Embers)
SyncGuiToEmber(m_EmberFile.m_Embers[i], widthOverride, heightOverride); SyncGuiToEmber(ember, widthOverride, heightOverride);
} }
else else
{ {

View File

@ -139,7 +139,7 @@ Fractorium::Fractorium(QWidget* p)
ui.GeometryTable->setStyleSheet("QTableWidget::item { padding: 1px; }"); ui.GeometryTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
ui.FilterTable->setStyleSheet("QTableWidget::item { padding: 1px; }"); ui.FilterTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
ui.IterationTable->setStyleSheet("QTableWidget::item { padding: 1px; }"); ui.IterationTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
ui.AffineTab->setStyleSheet("QTableWidget::item { padding: 1px; }"); ui.XformAffineTab->setStyleSheet("QTableWidget::item { padding: 1px; }");
ui.XformWeightNameTable->setStyleSheet("QTableWidget::item { padding: 0px; }"); ui.XformWeightNameTable->setStyleSheet("QTableWidget::item { padding: 0px; }");
ui.XformColorIndexTable->setStyleSheet("QTableWidget::item { padding: 1px; }"); ui.XformColorIndexTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
ui.XformColorValuesTable->setStyleSheet("QTableWidget::item { padding: 1px; }"); ui.XformColorValuesTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
@ -153,8 +153,6 @@ Fractorium::Fractorium(QWidget* p)
SetCoordinateStatus(0, 0, 0, 0); SetCoordinateStatus(0, 0, 0, 0);
SetTabOrders(); SetTabOrders();
ui.GLParentScrollArea->installEventFilter(this);
//At this point, everything has been setup except the renderer. Shortly after //At this point, everything has been setup except the renderer. Shortly after
//this constructor exits, GLWidget::InitGL() will create the initial flock and start the rendering timer //this constructor exits, GLWidget::InitGL() will create the initial flock and start the rendering timer
//which executes whenever the program is idle. Upon starting the timer, the renderer //which executes whenever the program is idle. Upon starting the timer, the renderer
@ -278,11 +276,17 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
{ {
m_WidthSpin->DoubleClickNonZero(ui.GLParentScrollArea->width()); m_WidthSpin->DoubleClickNonZero(ui.GLParentScrollArea->width());
m_HeightSpin->DoubleClickNonZero(ui.GLParentScrollArea->height()); m_HeightSpin->DoubleClickNonZero(ui.GLParentScrollArea->height());
//qDebug() << "scroll area resized";
} }
else if (o == ui.LibraryTree) else if (QKeyEvent* ke = dynamic_cast<QKeyEvent*>(e))
{ {
if (QKeyEvent* ke = dynamic_cast<QKeyEvent*>(e)) if (ke->key() >= Qt::Key_F1 && ke->key() <= Qt::Key_F32)
{
int val = ke->key() - (int)Qt::Key_F1;
if (val < ui.CurrentXformCombo->count())
ui.CurrentXformCombo->setCurrentIndex(val);
}
else if (o == ui.LibraryTree)
{ {
if (ke->key() == Qt::Key_Delete && e->type() == QEvent::KeyRelease) if (ke->key() == Qt::Key_Delete && e->type() == QEvent::KeyRelease)
{ {
@ -401,10 +405,10 @@ void Fractorium::dropEvent(QDropEvent* e)
/// <param name="signal">The signal the combo box emits</param> /// <param name="signal">The signal the combo box emits</param>
/// <param name="slot">The slot to receive the signal</param> /// <param name="slot">The slot to receive the signal</param>
/// <param name="connectionType">Type of the connection. Default: Qt::QueuedConnection.</param> /// <param name="connectionType">Type of the connection. Default: Qt::QueuedConnection.</param>
void Fractorium::SetupCombo(QTableWidget* table, const QObject* receiver, int& row, int col, StealthComboBox*& comboBox, vector<string>& vals, const char* signal, const char* slot, Qt::ConnectionType connectionType) void Fractorium::SetupCombo(QTableWidget* table, const QObject* receiver, int& row, int col, StealthComboBox*& comboBox, const vector<string>& vals, const char* signal, const char* slot, Qt::ConnectionType connectionType)
{ {
comboBox = new StealthComboBox(table); comboBox = new StealthComboBox(table);
ForEach(vals, [&](const string& s) { comboBox->addItem(s.c_str()); }); for (auto& s : vals) comboBox->addItem(s.c_str());
table->setCellWidget(row, col, comboBox); table->setCellWidget(row, col, comboBox);
connect(comboBox, signal, receiver, slot, connectionType); connect(comboBox, signal, receiver, slot, connectionType);
row++; row++;

View File

@ -249,6 +249,8 @@ public slots:
void OnXaosChanged(double d); void OnXaosChanged(double d);
void OnClearXaosButtonClicked(bool checked); void OnClearXaosButtonClicked(bool checked);
void OnRandomXaosButtonClicked(bool checked); void OnRandomXaosButtonClicked(bool checked);
void OnXaosRowDoubleClicked(int logicalIndex);
void OnXaosColDoubleClicked(int logicalIndex);
//Palette. //Palette.
void OnPaletteFilenameComboChanged(const QString& text); void OnPaletteFilenameComboChanged(const QString& text);
@ -271,7 +273,7 @@ public:
//template<typename spinType, typename valType>//See below. //template<typename spinType, typename valType>//See below.
//static void SetupSpinner(QTableWidget* table, const QObject* receiver, int& row, int col, spinType*& spinBox, int height, valType min, valType max, valType step, const char* signal, const char* slot, bool incRow = true, valType val = 0, valType doubleClickZero = -999, valType doubleClickNonZero = -999); //static void SetupSpinner(QTableWidget* table, const QObject* receiver, int& row, int col, spinType*& spinBox, int height, valType min, valType max, valType step, const char* signal, const char* slot, bool incRow = true, valType val = 0, valType doubleClickZero = -999, valType doubleClickNonZero = -999);
static void SetupAffineSpinner(QTableWidget* table, const QObject* receiver, int row, int col, DoubleSpinBox*& spinBox, int height, double min, double max, double step, double prec, const char* signal, const char* slot); static void SetupAffineSpinner(QTableWidget* table, const QObject* receiver, int row, int col, DoubleSpinBox*& spinBox, int height, double min, double max, double step, double prec, const char* signal, const char* slot);
static void SetupCombo(QTableWidget* table, const QObject* receiver, int& row, int col, StealthComboBox*& comboBox, vector<string>& vals, const char* signal, const char* slot, Qt::ConnectionType connectionType = Qt::QueuedConnection); static void SetupCombo(QTableWidget* table, const QObject* receiver, int& row, int col, StealthComboBox*& comboBox, const vector<string>& vals, const char* signal, const char* slot, Qt::ConnectionType connectionType = Qt::QueuedConnection);
static void SetFixedTableHeader(QHeaderView* header, QHeaderView::ResizeMode mode = QHeaderView::Fixed); static void SetFixedTableHeader(QHeaderView* header, QHeaderView::ResizeMode mode = QHeaderView::Fixed);
static int FlipDet(Affine2D<float>& affine); static int FlipDet(Affine2D<float>& affine);

View File

@ -239,7 +239,7 @@
<number>6</number> <number>6</number>
</property> </property>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_6"> <layout class="QHBoxLayout" name="DockWidgetHLayout">
<property name="spacing"> <property name="spacing">
<number>4</number> <number>4</number>
</property> </property>
@ -379,7 +379,7 @@
<number>4</number> <number>4</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QScrollArea" name="scrollArea_4"> <widget class="QScrollArea" name="LibraryTabScrollArea">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
@ -392,7 +392,7 @@
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<widget class="QWidget" name="scrollAreaWidgetContents_5"> <widget class="QWidget" name="LibraryTabScrollWidgetContents">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -489,7 +489,7 @@
<number>4</number> <number>4</number>
</property> </property>
<item> <item>
<widget class="QScrollArea" name="scrollArea"> <widget class="QScrollArea" name="FlameTabScrollArea">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
@ -499,7 +499,7 @@
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<widget class="QWidget" name="scrollAreaWidgetContents"> <widget class="QWidget" name="FlameTabScrollWidgetContents">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -1509,7 +1509,7 @@
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<spacer name="verticalSpacer"> <spacer name="FlameTabVerticalSpacer1">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -1525,7 +1525,7 @@
</spacer> </spacer>
</item> </item>
<item row="5" column="0"> <item row="5" column="0">
<spacer name="verticalSpacer_2"> <spacer name="FlameTabVerticalSpacer2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -1831,7 +1831,7 @@
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="8" column="0">
<spacer name="verticalSpacer_3"> <spacer name="FlameTabVerticalSpacer3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -1847,7 +1847,7 @@
</spacer> </spacer>
</item> </item>
<item row="11" column="0"> <item row="11" column="0">
<spacer name="verticalSpacer_8"> <spacer name="FlameTabVerticalSpacer4">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -1954,7 +1954,7 @@ SpinBox
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>2</number>
</property> </property>
<widget class="QWidget" name="ColorTab"> <widget class="QWidget" name="XformColorTab">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -2509,7 +2509,7 @@ SpinBox
</widget> </widget>
</item> </item>
<item row="6" column="0" colspan="2"> <item row="6" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="CurvesGroupBox">
<property name="title"> <property name="title">
<string>Curve</string> <string>Curve</string>
</property> </property>
@ -2575,7 +2575,7 @@ SpinBox
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="AffineTab"> <widget class="QWidget" name="XformAffineTab">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -2608,7 +2608,7 @@ SpinBox
<number>5</number> <number>5</number>
</property> </property>
<item> <item>
<widget class="QScrollArea" name="scrollArea_3"> <widget class="QScrollArea" name="AffineTabScrollArea">
<property name="autoFillBackground"> <property name="autoFillBackground">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -2621,7 +2621,7 @@ SpinBox
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<widget class="QWidget" name="scrollAreaWidgetContents_3"> <widget class="QWidget" name="AffineTabScrollWidgetContents">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -3921,7 +3921,7 @@ SpinBox
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_10"> <spacer name="AffineTabVerticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -3942,7 +3942,7 @@ SpinBox
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="VariationsTab"> <widget class="QWidget" name="XformVariationsTab">
<property name="toolTip"> <property name="toolTip">
<string>Full list of available variations and their weights for the currently selected xform.</string> <string>Full list of available variations and their weights for the currently selected xform.</string>
</property> </property>
@ -3963,7 +3963,7 @@ SpinBox
<number>6</number> <number>6</number>
</property> </property>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_11" stretch="0,0"> <layout class="QHBoxLayout" name="VariationsTabHLayout" stretch="0,0">
<property name="spacing"> <property name="spacing">
<number>5</number> <number>5</number>
</property> </property>
@ -4015,7 +4015,7 @@ SpinBox
</sizepolicy> </sizepolicy>
</property> </property>
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::StrongFocus</enum> <enum>Qt::WheelFocus</enum>
</property> </property>
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum> <enum>Qt::DefaultContextMenu</enum>
@ -4173,10 +4173,13 @@ SpinBox
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="XformsSelectTab"> <widget class="QWidget" name="XformSelectTab">
<property name="toolTip"> <property name="toolTip">
<string>Select multiple xforms to apply operations to.</string> <string>Select multiple xforms to apply operations to.</string>
</property> </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="title"> <attribute name="title">
<string>Select</string> <string>Select</string>
</attribute> </attribute>
@ -4218,6 +4221,9 @@ SpinBox
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="title"> <property name="title">
<string>Select Xforms</string> <string>Select Xforms</string>
</property> </property>
@ -4248,6 +4254,9 @@ SpinBox
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
@ -4320,7 +4329,7 @@ SpinBox
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_13"> <layout class="QHBoxLayout" name="XformTabHLayout">
<property name="spacing"> <property name="spacing">
<number>2</number> <number>2</number>
</property> </property>
@ -4845,7 +4854,7 @@ SpinBox
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="XaosTabHLayout">
<item> <item>
<widget class="QPushButton" name="ClearXaosButton"> <widget class="QPushButton" name="ClearXaosButton">
<property name="toolTip"> <property name="toolTip">
@ -5186,7 +5195,7 @@ SpinBox
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="PaletteTabHLayout">
<property name="spacing"> <property name="spacing">
<number>4</number> <number>4</number>
</property> </property>
@ -5280,7 +5289,7 @@ SpinBox
<number>4</number> <number>4</number>
</property> </property>
<item> <item>
<widget class="QScrollArea" name="scrollArea_5"> <widget class="QScrollArea" name="InfoTabScrollArea">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding"> <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -5302,7 +5311,7 @@ SpinBox
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<widget class="QWidget" name="scrollAreaWidgetContents_6"> <widget class="QWidget" name="InfoTabScrollWidgetContents">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -6127,7 +6136,7 @@ SpinBox
<tabstop>SaveCurrentToOpenedFileButton</tabstop> <tabstop>SaveCurrentToOpenedFileButton</tabstop>
<tabstop>ParamsTabWidget</tabstop> <tabstop>ParamsTabWidget</tabstop>
<tabstop>LibraryTree</tabstop> <tabstop>LibraryTree</tabstop>
<tabstop>scrollArea</tabstop> <tabstop>FlameTabScrollArea</tabstop>
<tabstop>CurrentXformCombo</tabstop> <tabstop>CurrentXformCombo</tabstop>
<tabstop>AddXformButton</tabstop> <tabstop>AddXformButton</tabstop>
<tabstop>DuplicateXformButton</tabstop> <tabstop>DuplicateXformButton</tabstop>
@ -6140,7 +6149,7 @@ SpinBox
<tabstop>XformColorScroll</tabstop> <tabstop>XformColorScroll</tabstop>
<tabstop>XformColorValuesTable</tabstop> <tabstop>XformColorValuesTable</tabstop>
<tabstop>SoloXformCheckBox</tabstop> <tabstop>SoloXformCheckBox</tabstop>
<tabstop>scrollArea_3</tabstop> <tabstop>AffineTabScrollArea</tabstop>
<tabstop>PreAffineTable</tabstop> <tabstop>PreAffineTable</tabstop>
<tabstop>PreFlipVerticalButton</tabstop> <tabstop>PreFlipVerticalButton</tabstop>
<tabstop>PreResetButton</tabstop> <tabstop>PreResetButton</tabstop>
@ -6186,13 +6195,13 @@ SpinBox
<tabstop>VariationsTree</tabstop> <tabstop>VariationsTree</tabstop>
<tabstop>PaletteAdjustTable</tabstop> <tabstop>PaletteAdjustTable</tabstop>
<tabstop>PaletteListTable</tabstop> <tabstop>PaletteListTable</tabstop>
<tabstop>scrollArea_5</tabstop> <tabstop>InfoTabScrollArea</tabstop>
<tabstop>InfoFileOpeningGroupBox</tabstop> <tabstop>InfoFileOpeningGroupBox</tabstop>
<tabstop>InfoFileOpeningTextEdit</tabstop> <tabstop>InfoFileOpeningTextEdit</tabstop>
<tabstop>InfoRenderingGroupBox</tabstop> <tabstop>InfoRenderingGroupBox</tabstop>
<tabstop>InfoRenderingTextEdit</tabstop> <tabstop>InfoRenderingTextEdit</tabstop>
<tabstop>PreAffineGroupBox</tabstop> <tabstop>PreAffineGroupBox</tabstop>
<tabstop>scrollArea_4</tabstop> <tabstop>LibraryTabScrollArea</tabstop>
<tabstop>InfoBoundsGroupBox</tabstop> <tabstop>InfoBoundsGroupBox</tabstop>
</tabstops> </tabstops>
<resources> <resources>

View File

@ -158,7 +158,7 @@ public:
virtual void XformWeightChanged(double d) { } virtual void XformWeightChanged(double d) { }
virtual void EqualizeWeights() { } virtual void EqualizeWeights() { }
virtual void XformNameChanged(int row, int col) { } virtual void XformNameChanged(int row, int col) { }
virtual void FillXforms() { } virtual void FillXforms(int index = 0) { }
//Xforms Affine. //Xforms Affine.
virtual void AffineSetHelper(double d, int index, bool pre) { } virtual void AffineSetHelper(double d, int index, bool pre) { }
@ -387,7 +387,7 @@ public:
virtual void XformWeightChanged(double d) override; virtual void XformWeightChanged(double d) override;
virtual void EqualizeWeights() override; virtual void EqualizeWeights() override;
virtual void XformNameChanged(int row, int col) override; virtual void XformNameChanged(int row, int col) override;
virtual void FillXforms() override; virtual void FillXforms(int index = 0) override;
void FillWithXform(Xform<T>* xform); void FillWithXform(Xform<T>* xform);
Xform<T>* CurrentXform(); Xform<T>* CurrentXform();
@ -421,7 +421,7 @@ public:
virtual void XaosChanged(DoubleSpinBox* sender) override; virtual void XaosChanged(DoubleSpinBox* sender) override;
virtual void ClearXaos() override; virtual void ClearXaos() override;
virtual void RandomXaos() override; virtual void RandomXaos() override;
//Palette. //Palette.
virtual int InitPaletteList(const string& s) override; virtual int InitPaletteList(const string& s) override;
virtual bool FillPaletteTable(const string& s) override; virtual bool FillPaletteTable(const string& s) override;

View File

@ -51,6 +51,6 @@ void Fractorium::ErrorReportToQTextEdit(const vector<string>& errors, QTextEdit*
if (clear) if (clear)
QMetaObject::invokeMethod(textEdit, "clear", Qt::QueuedConnection); QMetaObject::invokeMethod(textEdit, "clear", Qt::QueuedConnection);
for (size_t i = 0; i < errors.size(); i++) for (auto& error : errors)
QMetaObject::invokeMethod(textEdit, "append", Qt::QueuedConnection, Q_ARG(const QString&, QString::fromStdString(errors[i]) + "\n")); QMetaObject::invokeMethod(textEdit, "append", Qt::QueuedConnection, Q_ARG(const QString&, QString::fromStdString(error) + "\n"));
} }

View File

@ -9,7 +9,6 @@ void Fractorium::InitLibraryUI()
connect(ui.LibraryTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemChanged(QTreeWidgetItem*, int)), Qt::QueuedConnection); connect(ui.LibraryTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemChanged(QTreeWidgetItem*, int)), Qt::QueuedConnection);
connect(ui.LibraryTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection); connect(ui.LibraryTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection);
connect(ui.LibraryTree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection); connect(ui.LibraryTree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection);
ui.LibraryTree->installEventFilter(this);//Needed for keypress events other than enter.
} }

View File

@ -323,8 +323,8 @@ void FractoriumEmberController<T>::SaveEntireFileAsXml()
SaveCurrentToOpenedFile();//Save the current ember back to the opened file before writing to disk. SaveCurrentToOpenedFile();//Save the current ember back to the opened file before writing to disk.
emberFile = m_EmberFile; emberFile = m_EmberFile;
for (size_t i = 0; i < emberFile.Size(); i++) for (auto& ember : emberFile.m_Embers)
ApplyXmlSavingTemplate(emberFile.m_Embers[i]); ApplyXmlSavingTemplate(ember);
if (writer.Save(filename.toStdString().c_str(), emberFile.m_Embers, 0, true, false, true)) if (writer.Save(filename.toStdString().c_str(), emberFile.m_Embers, 0, true, false, true))
{ {
@ -479,9 +479,9 @@ void FractoriumEmberController<T>::CopyAllXml()
os << "<flames>\n"; os << "<flames>\n";
for (size_t i = 0; i < m_EmberFile.Size(); i++) for (auto& e : m_EmberFile.m_Embers)
{ {
Ember<T> ember = m_EmberFile.m_Embers[i]; Ember<T> ember = e;
ApplyXmlSavingTemplate(ember); ApplyXmlSavingTemplate(ember);
os << emberToXml.ToString(ember, "", 0, false, false, true); os << emberToXml.ToString(ember, "", 0, false, false, true);
@ -621,8 +621,8 @@ void FractoriumEmberController<T>::AddReflectiveSymmetry()
Update([&]() Update([&]()
{ {
m_Ember.AddSymmetry(-1, m_Rand); m_Ember.AddSymmetry(-1, m_Rand);
FillXforms(); int index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
combo->setCurrentIndex(combo->count() - (m_Fractorium->HaveFinal() ? 2 : 1));//Set index to the last item before final. FillXforms(index);
}); });
} }
@ -640,8 +640,8 @@ void FractoriumEmberController<T>::AddRotationalSymmetry()
Update([&]() Update([&]()
{ {
m_Ember.AddSymmetry(2, m_Rand); m_Ember.AddSymmetry(2, m_Rand);
FillXforms(); int index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
combo->setCurrentIndex(combo->count() - (m_Fractorium->HaveFinal() ? 2 : 1));//Set index to the last item before final. FillXforms(index);
}); });
} }
@ -659,8 +659,8 @@ void FractoriumEmberController<T>::AddBothSymmetry()
Update([&]() Update([&]()
{ {
m_Ember.AddSymmetry(-2, m_Rand); m_Ember.AddSymmetry(-2, m_Rand);
FillXforms(); int index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
combo->setCurrentIndex(combo->count() - (m_Fractorium->HaveFinal() ? 2 : 1));//Set index to the last item before final. FillXforms(index);
}); });
} }
@ -705,7 +705,6 @@ void FractoriumEmberController<T>::ClearFlame()
} }
FillXforms(); FillXforms();
m_Fractorium->ui.CurrentXformCombo->setCurrentIndex(0);
}); });
} }

View File

@ -212,9 +212,9 @@ eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions()
m_Cs.Enter(); m_Cs.Enter();
eProcessAction action = NOTHING; eProcessAction action = NOTHING;
for (size_t i = 0; i < m_ProcessActions.size(); i++) for (auto a : m_ProcessActions)
if (m_ProcessActions[i] > action) if (a > action)
action = m_ProcessActions[i]; action = a;
m_ProcessActions.clear(); m_ProcessActions.clear();
m_Cs.Leave(); m_Cs.Leave();
@ -492,6 +492,7 @@ bool FractoriumEmberController<T>::Render()
//Upon finishing, or having nothing to do, rest. //Upon finishing, or having nothing to do, rest.
if (ProcessState() == ACCUM_DONE) if (ProcessState() == ACCUM_DONE)
QThread::msleep(1); QThread::msleep(1);
//QApplication::processEvents();
m_Rendering = false; m_Rendering = false;
return success; return success;

View File

@ -6,8 +6,15 @@
/// </summary> /// </summary>
void Fractorium::InitXaosUI() void Fractorium::InitXaosUI()
{ {
ui.XaosTable->verticalHeader()->setVisible(true);
ui.XaosTable->horizontalHeader()->setVisible(true);
ui.XaosTable->verticalHeader()->setSectionsClickable(true);
ui.XaosTable->horizontalHeader()->setSectionsClickable(true);
connect(ui.ClearXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnClearXaosButtonClicked(bool)), Qt::QueuedConnection); connect(ui.ClearXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnClearXaosButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.RandomXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnRandomXaosButtonClicked(bool)), Qt::QueuedConnection); connect(ui.RandomXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnRandomXaosButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.XaosTable->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosRowDoubleClicked(int)), Qt::QueuedConnection);
connect(ui.XaosTable->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosColDoubleClicked(int)), Qt::QueuedConnection);
} }
/// <summary> /// <summary>
@ -92,11 +99,6 @@ void Fractorium::FillXaosTable()
ui.XaosTable->setRowCount(count);//This will grow or shrink the number of rows and call the destructor for previous DoubleSpinBoxes. ui.XaosTable->setRowCount(count);//This will grow or shrink the number of rows and call the destructor for previous DoubleSpinBoxes.
ui.XaosTable->setColumnCount(count); ui.XaosTable->setColumnCount(count);
ui.XaosTable->verticalHeader()->setVisible(true);
ui.XaosTable->horizontalHeader()->setVisible(true);
ui.XaosTable->verticalHeader()->setSectionsClickable(false);
ui.XaosTable->horizontalHeader()->setSectionsClickable(false);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
for (int j = 0; j < count; j++) for (int j = 0; j < count; j++)
@ -159,7 +161,6 @@ void Fractorium::OnClearXaosButtonClicked(bool checked) { m_Controller->ClearXao
/// 50% that they're 0-3. /// 50% that they're 0-3.
/// Resets the rendering process. /// Resets the rendering process.
/// </summary> /// </summary>
/// <param name="checked">Ignored</param>
template <typename T> template <typename T>
void FractoriumEmberController<T>::RandomXaos() void FractoriumEmberController<T>::RandomXaos()
{ {
@ -185,6 +186,78 @@ void FractoriumEmberController<T>::RandomXaos()
void Fractorium::OnRandomXaosButtonClicked(bool checked) { m_Controller->RandomXaos(); } void Fractorium::OnRandomXaosButtonClicked(bool checked) { m_Controller->RandomXaos(); }
/// <summary>
/// Toggle all xaos values in one row.
/// The logic is:
/// If any cell in the row is non zero, set all cells to zero, else 1.
/// If shift is held down, reverse the logic.
/// Resets the rendering process.
/// </summary>
/// <param name="logicalIndex">The index of the row that was double clicked</param>
void Fractorium::OnXaosRowDoubleClicked(int logicalIndex)
{
bool allZero = true;
int cols = ui.XaosTable->columnCount();
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
for (int i = 0; i < cols; i++)
{
if (auto* spinBox = dynamic_cast<DoubleSpinBox*>(ui.XaosTable->cellWidget(logicalIndex, i)))
{
if (!IsNearZero(spinBox->value()))
{
allZero = false;
break;
}
}
}
if (shift)
allZero = !allZero;
double val = allZero ? 1.0 : 0.0;
for (int i = 0; i < cols; i++)
if (auto* spinBox = dynamic_cast<DoubleSpinBox*>(ui.XaosTable->cellWidget(logicalIndex, i)))
spinBox->setValue(val);
}
/// <summary>
/// Toggle all xaos values in one column.
/// The logic is:
/// If any cell in the column is non zero, set all cells to zero, else 1.
/// If shift is held down, reverse the logic.
/// Resets the rendering process.
/// </summary>
/// <param name="logicalIndex">The index of the column that was double clicked</param>
void Fractorium::OnXaosColDoubleClicked(int logicalIndex)
{
bool allZero = true;
int rows = ui.XaosTable->rowCount();
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
for (int i = 0; i < rows; i++)
{
if (auto* spinBox = dynamic_cast<DoubleSpinBox*>(ui.XaosTable->cellWidget(i, logicalIndex)))
{
if (!IsNearZero(spinBox->value()))
{
allZero = false;
break;
}
}
}
if (shift)
allZero = !allZero;
double val = allZero ? 1.0 : 0.0;
for (int i = 0; i < rows; i++)
if (auto* spinBox = dynamic_cast<DoubleSpinBox*>(ui.XaosTable->cellWidget(i, logicalIndex)))
spinBox->setValue(val);
}
template class FractoriumEmberController<float>; template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE #ifdef DO_DOUBLE

View File

@ -109,8 +109,8 @@ void FractoriumEmberController<T>::AddXform()
newXform.m_Weight = 0.25; newXform.m_Weight = 0.25;
newXform.m_ColorX = m_Rand.Frand01<T>(); newXform.m_ColorX = m_Rand.Frand01<T>();
m_Ember.AddXform(newXform); m_Ember.AddXform(newXform);
FillXforms(); int index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
combo->setCurrentIndex(combo->count() - (m_Fractorium->HaveFinal() ? 2 : 1));//Set index to the last item before final. FillXforms(index);
}); });
} }
@ -141,8 +141,8 @@ void FractoriumEmberController<T>::DuplicateXform()
for (auto& it : vec) for (auto& it : vec)
m_Ember.AddXform(it); m_Ember.AddXform(it);
FillXforms();//Handles xaos. int index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
combo->setCurrentIndex(combo->count() - (m_Fractorium->HaveFinal() ? 2 : 1));//Set index to the last item before final. FillXforms(index);//Handles xaos.
}); });
} }
@ -224,8 +224,8 @@ void FractoriumEmberController<T>::DeleteXforms()
if (offset) if (offset)
{ {
FillXforms(); int index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final. Note final is requeried one last time.
combo->setCurrentIndex(combo->count() - (m_Ember.UseFinalXform() ? 2 : 1));//Set index to the last item before final. Note final is requeried one last time. FillXforms(index);
UpdateRender(); UpdateRender();
} }
} }
@ -252,8 +252,8 @@ void FractoriumEmberController<T>::AddFinalXform()
final.AddVariation(new LinearVariation<T>());//Just a placeholder so other parts of the code don't see it as being empty. final.AddVariation(new LinearVariation<T>());//Just a placeholder so other parts of the code don't see it as being empty.
m_Ember.SetFinalXform(final); m_Ember.SetFinalXform(final);
FillXforms(); int index = m_Ember.TotalXformCount() - 1;//Set index to the last item.
combo->setCurrentIndex(combo->count() - 1);//Set index to the last item. FillXforms(index);
}); });
} }
} }
@ -374,12 +374,13 @@ bool FractoriumEmberController<T>::IsFinal(Xform<T>* xform)
/// <summary> /// <summary>
/// Fill the xforms combo box with the xforms in the current ember. /// Fill the xforms combo box with the xforms in the current ember.
/// Select the first one and fill all widgets with its values. /// Select the index passed in and fill all widgets with its values.
/// Also dynamically generate a checkbox for each xform which will allow the user /// Also dynamically generate a checkbox for each xform which will allow the user
/// to select which xforms to apply operations to. /// to select which xforms to apply operations to.
/// </summary> /// </summary>
/// <param name="index">The index to select after populating, default 0.</param>
template <typename T> template <typename T>
void FractoriumEmberController<T>::FillXforms() void FractoriumEmberController<T>::FillXforms(int index)
{ {
int i = 0, count = int(XformCount()); int i = 0, count = int(XformCount());
auto combo = m_Fractorium->ui.CurrentXformCombo; auto combo = m_Fractorium->ui.CurrentXformCombo;
@ -435,11 +436,13 @@ void FractoriumEmberController<T>::FillXforms()
m_Fractorium->m_XformsSelectionLayout->blockSignals(false); m_Fractorium->m_XformsSelectionLayout->blockSignals(false);
combo->blockSignals(false); combo->blockSignals(false);
combo->setCurrentIndex(0);
if (index < combo->count())
combo->setCurrentIndex(index);
m_Fractorium->FillXaosTable(); m_Fractorium->FillXaosTable();
m_Fractorium->OnSoloXformCheckBoxStateChanged(Qt::Unchecked); m_Fractorium->OnSoloXformCheckBoxStateChanged(Qt::Unchecked);
m_Fractorium->OnCurrentXformComboChanged(0);//Make sure the event gets called, because it won't if the zero index is already selected. m_Fractorium->OnCurrentXformComboChanged(index);//Make sure the event gets called, because it won't if the zero index is already selected.
} }
template class FractoriumEmberController<float>; template class FractoriumEmberController<float>;

View File

@ -64,7 +64,7 @@ void FractoriumEmberController<T>::SetupVariationTree()
{ {
ParamWithName<T>* params = parVar->Params(); ParamWithName<T>* params = parVar->Params();
for (size_t j = 0; j< parVar->ParamCount(); j++) for (size_t j = 0; j < parVar->ParamCount(); j++)
{ {
if (!params[j].IsPrecalc()) if (!params[j].IsPrecalc())
{ {

View File

@ -46,6 +46,7 @@ int main(int argc, char *argv[])
Fractorium w; Fractorium w;
w.show(); w.show();
a.installEventFilter(&w);
return a.exec(); return a.exec();
} }

View File

@ -134,8 +134,8 @@ void FractoriumOptionsDialog::OnPlatformComboCurrentIndexChanged(int index)
ui.DeviceCombo->clear(); ui.DeviceCombo->clear();
for (size_t i = 0; i < devices.size(); i++) for (auto& device : devices)
ui.DeviceCombo->addItem(QString::fromStdString(devices[i])); ui.DeviceCombo->addItem(QString::fromStdString(device));
if (ui.PlatformCombo->currentIndex() == m_Settings->PlatformIndex()) if (ui.PlatformCombo->currentIndex() == m_Settings->PlatformIndex())
ui.DeviceCombo->setCurrentIndex(m_Settings->DeviceIndex()); ui.DeviceCombo->setCurrentIndex(m_Settings->DeviceIndex());