--User changes

-Entering xaos cells will always select the entire cell to make editing easier.
 -Add radio buttons on the xaos tab to specify how pasting or duplicating xforms should preserve xaos.

--Bug fixes
 -The left header column in the xaos visualization table had somehow disappeared.

--Code changes
 -DoubleSpinBox now has a boolean which specifies whether it clears its selection on enter. Default true.
 -Make AddXformsWithXaos() be a static member of FractoriumEmberController for quicker build times.
 -Add new exmaple flames to package_linux.sh
This commit is contained in:
Person 2020-03-11 06:49:29 -07:00
parent 61dd5e6eeb
commit 18809e65aa
10 changed files with 221 additions and 83 deletions

View File

@ -10,6 +10,8 @@
namespace EmberCommon
{
enum class eXaosPasteStyle : int { NONE, ZERO_TO_ONE, ZERO_TO_VALS, ONE_TO_VALS, VALS_TO_ONE };
/// <summary>
/// Derivation of the RenderCallback class to do custom printing action
/// whenever the progress function is internally called inside of Ember
@ -869,43 +871,6 @@ static vector<const Variation<T>*> FindVarsWithout(const vector<const Variation<
return vec;
}
/// <summary>
/// Add a vector of xforms to the passed in ember, and optionally preserve the xaos based on position.
/// </summary>
/// <param name="ember">The ember to add xforms to</param>
/// <param name="xforms">The vector of xforms to add</param>
/// <param name="preserveXaos">True to preserve xaos else false.</param>
template <typename T>
static void AddXformsWithXaos(Ember<T>& ember, std::vector<std::pair<Xform<T>, size_t>>& xforms, bool preserveXaos)
{
auto origXformCount = ember.XformCount();
for (auto& it : xforms)
ember.AddXform(it.first);
for (auto i = 0; i < ember.XformCount(); i++)
{
auto xf = ember.GetXform(i);
if (i < origXformCount)
{
for (auto j = 0; j < ember.XformCount(); j++)
if (j >= origXformCount)
xf->SetXaos(j, 0);
}
else
{
for (auto j = 0; j < ember.XformCount(); j++)
if (j < origXformCount)
xf->SetXaos(j, 0);
else if (!preserveXaos)
xf->SetXaos(j, 1);
else if (i - origXformCount < xforms.size())//Should never be out of bounds, but just to be safe.
xf->SetXaos(j, xforms[i - origXformCount].first.Xaos(j - origXformCount));
}
}
}
}
/// <summary>

View File

@ -12,10 +12,11 @@ QTimer DoubleSpinBox::s_Timer;
/// <param name="p">The parent widget. Default: nullptr.</param>
/// <param name="height">The height of the spin box. Default: 16.</param>
/// <param name="step">The step used to increment/decrement the spin box when using the mouse wheel. Default: 0.05.</param>
DoubleSpinBox::DoubleSpinBox(QWidget* p, int h, double step)
DoubleSpinBox::DoubleSpinBox(QWidget* p, int h, double step, bool clearSel)
: QDoubleSpinBox(p)
{
m_DoubleClick = false;
m_ClearSel = clearSel;
m_DoubleClickLowVal = 0;
m_DoubleClickNonZero = 0;
m_DoubleClickZero = 1;
@ -135,6 +136,7 @@ QLineEdit* DoubleSpinBox::lineEdit()
/// </summary>
void DoubleSpinBox::OnSpinBoxValueChanged(double)
{
if (m_ClearSel)
lineEdit()->deselect();//Gets rid of nasty "feature" that always has text selected.
}

View File

@ -19,7 +19,7 @@ class DoubleSpinBox : public QDoubleSpinBox
Q_OBJECT
public:
explicit DoubleSpinBox(QWidget* parent = nullptr, int height = 16, double step = 0.05);
explicit DoubleSpinBox(QWidget* parent = nullptr, int height = 16, double step = 0.05, bool clearsel = true);
virtual ~DoubleSpinBox() { }
void SetValueStealth(double d);
void DoubleClick(bool b);
@ -45,6 +45,7 @@ protected:
virtual void leaveEvent(QEvent* e) override;
bool m_DoubleClick;
bool m_ClearSel;
shared_ptr<FractoriumSettings> m_Settings;
private:

View File

@ -129,6 +129,9 @@ public:
bool DrawAllPost();
bool LocalPivot();
//Xaos.
eXaosPasteStyle GetXaosPasteStyleType();
//Info.
void ReorderVariations(QTreeWidgetItem* item);

View File

@ -1867,7 +1867,7 @@
<rect>
<x>550</x>
<y>0</y>
<width>252</width>
<width>310</width>
<height>881</height>
</rect>
</property>
@ -1879,8 +1879,8 @@
</property>
<property name="minimumSize">
<size>
<width>252</width>
<height>409</height>
<width>310</width>
<height>428</height>
</size>
</property>
<property name="floating">
@ -1902,9 +1902,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0,0,0">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0,0,0,0">
<property name="spacing">
<number>4</number>
<number>1</number>
</property>
<property name="leftMargin">
<number>4</number>
@ -2002,6 +2002,86 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="XaosPasteGroupBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="title">
<string>Paste Style</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QRadioButton" name="XaosPasteNoneRadio">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;All values in the new xaos rows and columns will be 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>None</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="XaosPaste0to1Radio">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;All values in the new xaos rows and columns before the bottom right square will be 0, and those in the square will be 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>0-&gt;1</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="XaosPaste0toValsRadio">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;All values in the new xaos rows and columns before the bottom right square will be 0, and those in the square will be the original xaos values starting from the top of the new xforms&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>0-&gt;Vals</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="XaosPaste1toValsRadio">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;All values in the new xaos rows and columns before the bottom right square will be 1, and those in the square will be the original xaos values starting from the top of the new xforms&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>1-&gt;Vals</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="XaosPasteValsTo1Radio">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;All values in the new xaos rows and columns before the bottom right square will be the original xaos values starting from the top of the new xforms, and those in the square will be 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Vals-&gt;1</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTableView" name="XaosTableView">
<property name="sizePolicy">
@ -2226,7 +2306,7 @@
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderCascadingSectionResizes">
<bool>false</bool>
@ -2316,7 +2396,7 @@
<widget class="QDockWidget" name="PaletteDockWidget">
<property name="geometry">
<rect>
<x>800</x>
<x>860</x>
<y>10</y>
<width>295</width>
<height>700</height>

View File

@ -489,6 +489,7 @@ public:
void FillWithXform(Xform<T>* xform);
Xform<T>* CurrentXform();
void UpdateXform(std::function<void(Xform<T>*, size_t, size_t)> func, eXformUpdate updateType = eXformUpdate::UPDATE_CURRENT, bool updateRender = true, eProcessAction action = eProcessAction::FULL_RENDER, size_t index = 0);
static void AddXformsWithXaos(Ember<T>& ember, std::vector<std::pair<Xform<T>, size_t>>& xforms, bool preserveXaos, eXaosPasteStyle pastestyle);
//Xforms Affine.
virtual void AffineSetHelper(double d, int index, bool pre) override;

View File

@ -812,7 +812,7 @@ void FractoriumEmberController<T>::PasteSelectedXforms()
{
Update([&]()
{
AddXformsWithXaos(m_Ember, m_CopiedXforms, true);
AddXformsWithXaos(m_Ember, m_CopiedXforms, true, m_Fractorium->GetXaosPasteStyleType());
if (!m_CopiedFinalXform.Empty())
m_Ember.SetFinalXform(m_CopiedFinalXform);

View File

@ -11,7 +11,7 @@ void Fractorium::InitXaosUI()
int spinHeight = 20;
ui.XaosTableView->verticalHeader()->setSectionsClickable(true);
ui.XaosTableView->horizontalHeader()->setSectionsClickable(true);
m_XaosSpinBox = new DoubleSpinBox(nullptr, spinHeight, 0.1);
m_XaosSpinBox = new DoubleSpinBox(nullptr, spinHeight, 0.1, false);
m_XaosSpinBox->DoubleClick(true);
m_XaosSpinBox->DoubleClickZero(1);
m_XaosSpinBox->DoubleClickNonZero(0);
@ -265,7 +265,7 @@ void FractoriumEmberController<T>::AddLayer(int xforms)
Update([&]
{
std::vector<std::pair<Xform<T>, size_t>> vec(xforms);
AddXformsWithXaos(m_Ember, vec, false);
AddXformsWithXaos(m_Ember, vec, false, eXaosPasteStyle::ZERO_TO_ONE);
});
FillXforms();
@ -371,6 +371,26 @@ void Fractorium::OnXaosVScrollValueChanged(int value)
ui.XaosAppliedTableView->verticalScrollBar()->setValue(value);
}
/// <summary>
/// Get an enum value corresponding to the currently selected xaos pasting mode.
/// </summary>
/// <returns>The xaos pasting mode enum</returns>
eXaosPasteStyle Fractorium::GetXaosPasteStyleType()
{
if (ui.XaosPasteNoneRadio->isChecked())
return eXaosPasteStyle::NONE;
else if (ui.XaosPaste0to1Radio->isChecked())
return eXaosPasteStyle::ZERO_TO_ONE;
else if (ui.XaosPaste0toValsRadio->isChecked())
return eXaosPasteStyle::ZERO_TO_VALS;
else if (ui.XaosPaste1toValsRadio->isChecked())
return eXaosPasteStyle::ONE_TO_VALS;
else if (ui.XaosPasteValsTo1Radio->isChecked())
return eXaosPasteStyle::VALS_TO_ONE;
else
return eXaosPasteStyle::NONE;
}
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE

View File

@ -206,6 +206,94 @@ void FractoriumEmberController<T>::AddLinkedXform()
void Fractorium::OnAddLinkedXformButtonClicked(bool checked) { m_Controller->AddLinkedXform(); }
/// <summary>
/// Add a vector of xforms to the passed in ember, and optionally preserve the xaos based on position.
/// </summary>
/// <param name="ember">The ember to add xforms to</param>
/// <param name="xforms">The vector of xforms to add</param>
/// <param name="preserveXaos">True to preserve xaos else false.</param>
/// <param name="eXaosPasteStyle">The method which governs how the copying of xaos values is handles</param>
template <typename T>
void FractoriumEmberController<T>::AddXformsWithXaos(Ember<T>& ember, std::vector<std::pair<Xform<T>, size_t>>& xforms, bool preserveXaos, eXaosPasteStyle pastestyle)
{
if (ember.XaosPresent())
{
auto oldxfcount = ember.XformCount();
for (auto& it : xforms)
{
ember.AddXform(it.first);
auto newxfcount = ember.XformCount() - 1;
auto* newxform = ember.GetXform(newxfcount);
for (size_t i = 0; i < oldxfcount; i++)
{
if (auto xform = ember.GetXform(i))
{
switch (pastestyle)
{
case EmberCommon::eXaosPasteStyle::NONE:
newxform->SetXaos(i, 1);
xform->SetXaos(newxfcount, 1);
break;
case EmberCommon::eXaosPasteStyle::ZERO_TO_ONE:
case EmberCommon::eXaosPasteStyle::ZERO_TO_VALS:
newxform->SetXaos(i, 0);
xform->SetXaos(newxfcount, 0);
break;
case EmberCommon::eXaosPasteStyle::ONE_TO_VALS:
newxform->SetXaos(i, 1);
xform->SetXaos(newxfcount, 1);
break;
case EmberCommon::eXaosPasteStyle::VALS_TO_ONE:
newxform->SetXaos(i, it.first.Xaos(i));
xform->SetXaos(newxfcount, xform->Xaos(it.second));
break;
default:
break;
}
}
}
}
for (size_t i = oldxfcount; i < ember.XformCount(); i++)
{
if (auto xform = ember.GetXform(i))
{
for (size_t j = oldxfcount; j < ember.XformCount(); j++)
{
switch (pastestyle)
{
case EmberCommon::eXaosPasteStyle::NONE:
case EmberCommon::eXaosPasteStyle::ZERO_TO_ONE:
xform->SetXaos(j, 1);
break;
case EmberCommon::eXaosPasteStyle::ZERO_TO_VALS:
case EmberCommon::eXaosPasteStyle::ONE_TO_VALS:
xform->SetXaos(j, xforms[i - oldxfcount].first.Xaos(j - oldxfcount));
break;
case EmberCommon::eXaosPasteStyle::VALS_TO_ONE:
xform->SetXaos(j, 1);
break;
default:
break;
}
}
}
}
}
else
for (auto& it : xforms)
ember.AddXform(it.first);
}
/// <summary>
/// Duplicate the specified xforms in the current ember, and set the last one as the current xform.
/// If xaos is present in the ember, the duplicated xforms will be added with xaos preserved, else they'll just be added normally.
@ -227,37 +315,7 @@ void FractoriumEmberController<T>::DuplicateXform()
}, eXformUpdate::UPDATE_SELECTED_EXCEPT_FINAL, false);
Update([&]()
{
if (m_Ember.XaosPresent())
{
if (!ctrl)
{
auto oldxfcount = m_Ember.XformCount();
for (auto& it : vec)
{
m_Ember.AddXform(it.first);
auto newxfcount = m_Ember.XformCount() - 1;
auto* newxform = m_Ember.GetXform(newxfcount);
for (size_t i = 0; i < oldxfcount; i++)
{
if (auto xform = m_Ember.GetXform(i))
{
newxform->SetXaos(i, it.first.Xaos(i));
xform->SetXaos(newxfcount, xform->Xaos(it.second));
}
}
}
}
else
{
AddXformsWithXaos(m_Ember, vec, true);
}
}
else
for (auto& it : vec)
m_Ember.AddXform(it.first);
AddXformsWithXaos(m_Ember, vec, true, m_Fractorium->GetXaosPasteStyleType());
int index = int(m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1));//Set index to the last item before final.
FillXforms(index);//Handles xaos.
});

View File

@ -123,6 +123,14 @@ tar --exclude='package-linux.sh' \
./Data/dark_linux.qss \
./Data/lightdark.qss \
./Data/uranium.qss \
./Data/examples/b33rheart_examples.flame \
./Data/examples/b33rheart_sierpinski.flame \
./Data/examples/pillemaster_hexagonal_tilings.flame \
./Data/examples/plangkye_examples.flame \
./Data/examples/tatasz_examples.flame \
./Data/examples/tatasz_substitution.flame \
./Data/examples/triptychaos_examples \
./Data/examples/tyrantwave_base_forms.flame \
.
[ $? -ne 0 ] && echo "Tar command failed." && exit 2