--User changes

-Allow locking of the scale at which affine circles are displayed.
 -Allow user to toggle whether xform will be animated when generating sequences. Also show the animate value when loading.

--Code changes
 -More conversion to C++11 style code.
 -Add another value to the eXformUpdate enum called UPDATE_CURRENT_AND_SELECTED in anticipation of future work.
 -Remove some old #defines.
This commit is contained in:
mfeemster
2016-02-02 17:51:58 -08:00
parent 96d53113a0
commit f10e4e610a
24 changed files with 424 additions and 358 deletions

View File

@ -7,7 +7,6 @@
void Fractorium::InitXformsUI()
{
int spinHeight = 20, row = 0;
connect(ui.AddXformButton, SIGNAL(clicked(bool)), this, SLOT(OnAddXformButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.AddLinkedXformButton, SIGNAL(clicked(bool)), this, SLOT(OnAddLinkedXformButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.DuplicateXformButton, SIGNAL(clicked(bool)), this, SLOT(OnDuplicateXformButtonClicked(bool)), Qt::QueuedConnection);
@ -15,7 +14,7 @@ void Fractorium::InitXformsUI()
connect(ui.DeleteXformButton, SIGNAL(clicked(bool)), this, SLOT(OnDeleteXformButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.AddFinalXformButton, SIGNAL(clicked(bool)), this, SLOT(OnAddFinalXformButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.CurrentXformCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnCurrentXformComboChanged(int)), Qt::QueuedConnection);
connect(ui.AnimateXformCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnXformAnimateCheckBoxStateChanged(int)), Qt::QueuedConnection);
SetFixedTableHeader(ui.XformWeightNameTable->horizontalHeader());
//Use SetupSpinner() just to create the spinner, but use col of -1 to prevent it from being added to the table.
SetupSpinner<DoubleSpinBox, double>(ui.XformWeightNameTable, this, row, -1, m_XformWeightSpin, spinHeight, 0, 1000, 0.05, SIGNAL(valueChanged(double)), SLOT(OnXformWeightChanged(double)), false, 0, 1, 0);
@ -25,13 +24,11 @@ void Fractorium::InitXformsUI()
m_XformWeightSpinnerButtonWidget->m_Button->setToolTip("Equalize weights");
m_XformWeightSpinnerButtonWidget->m_Button->setStyleSheet("text-align: center center");
connect(m_XformWeightSpinnerButtonWidget->m_Button, SIGNAL(clicked(bool)), this, SLOT(OnEqualWeightButtonClicked(bool)), Qt::QueuedConnection);
ui.XformWeightNameTable->setCellWidget(0, 0, m_XformWeightSpinnerButtonWidget);
ui.XformWeightNameTable->setItem(0, 1, new QTableWidgetItem());
connect(ui.XformWeightNameTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnXformNameChanged(int, int)), Qt::QueuedConnection);
ui.CurrentXformCombo->setProperty("soloxform", -1);
#ifndef WIN32
#ifndef WIN32
//For some reason linux makes these 24x24, even though the designer explicitly says 16x16.
ui.AddXformButton->setIconSize(QSize(16, 16));
ui.DuplicateXformButton->setIconSize(QSize(16, 16));
@ -70,19 +67,15 @@ void Fractorium::CurrentXform(uint i)
template <typename T>
void FractoriumEmberController<T>::CurrentXformComboChanged(int index)
{
if (Xform<T>* xform = m_Ember.GetTotalXform(index))
if (auto xform = m_Ember.GetTotalXform(index))
{
FillWithXform(xform);
m_GLController->SetSelectedXform(xform);
int solo = m_Fractorium->ui.CurrentXformCombo->property("soloxform").toInt();
m_Fractorium->ui.SoloXformCheckBox->blockSignals(true);
m_Fractorium->ui.SoloXformCheckBox->setChecked(solo == index);
m_Fractorium->ui.SoloXformCheckBox->blockSignals(false);
bool enable = !IsFinal(CurrentXform());
m_Fractorium->ui.DuplicateXformButton->setEnabled(enable);
m_Fractorium->m_XformWeightSpin->setEnabled(enable);
m_Fractorium->ui.SoloXformCheckBox->setEnabled(enable);
@ -105,7 +98,6 @@ void FractoriumEmberController<T>::AddXform()
Update([&]()
{
Xform<T> newXform;
newXform.m_Weight = 0.25;
newXform.m_ColorX = m_Rand.Frand01<T>();
m_Ember.AddXform(newXform);
@ -131,7 +123,6 @@ void FractoriumEmberController<T>::AddLinkedXform()
{
size_t i, count = m_Ember.XformCount();
Xform<T> newXform;
newXform.m_Weight = 0.5;
newXform.m_Opacity = 1;
newXform.m_ColorSpeed = 1;
@ -175,21 +166,18 @@ template <typename T>
void FractoriumEmberController<T>::DuplicateXform()
{
vector<Xform<T>> vec;
vec.reserve(m_Ember.XformCount());
UpdateXform([&] (Xform<T>* xform)
{
vec.push_back(*xform);
}, eXformUpdate::UPDATE_SELECTED_EXCEPT_FINAL, false);
Update([&]()
{
QComboBox* combo = m_Fractorium->ui.CurrentXformCombo;
auto combo = m_Fractorium->ui.CurrentXformCombo;
for (auto& it : vec)
m_Ember.AddXform(it);
int index = m_Ember.TotalXformCount() - (m_Ember.UseFinalXform() ? 2 : 1);//Set index to the last item before final.
FillXforms(index);//Handles xaos.
});
@ -210,7 +198,6 @@ void FractoriumEmberController<T>::ClearXform()
{
xform->ClearAndDeleteVariations();//Note xaos is left alone.
}, eXformUpdate::UPDATE_SELECTED);
FillVariationTreeWithXform(CurrentXform());
}
@ -229,17 +216,16 @@ void FractoriumEmberController<T>::DeleteXforms()
int i = 0, offset = 0, current = 0, checked = 0;
bool haveFinal = false;
size_t count;
QComboBox* combo = m_Fractorium->ui.CurrentXformCombo;
auto combo = m_Fractorium->ui.CurrentXformCombo;
//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)
m_Fractorium->ForEachXformCheckbox([&](int i, QCheckBox * w)
{
count = m_Ember.TotalXformCount();
haveFinal = m_Ember.UseFinalXform();//Requery every time.
if (w->isChecked())
checked++;
@ -252,20 +238,18 @@ void FractoriumEmberController<T>::DeleteXforms()
if (w->isChecked())
{
//qDebug() << "Deleting " << w->text();
m_Ember.DeleteTotalXform(i - offset);//Subtract offset to account for previously deleted xforms.
offset++;
}
});
current = combo->currentIndex();
count = m_Ember.TotalXformCount();
haveFinal = m_Ember.UseFinalXform();//Requery again.
//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))
!(haveFinal && count <= 2 && current == 0) &&//Again disallow deleting the only remaining non-final xform.
!(!haveFinal && count == 1))
{
m_Ember.DeleteTotalXform(current);
offset++;
@ -298,7 +282,6 @@ void FractoriumEmberController<T>::AddFinalXform()
{
Xform<T> final;
auto combo = m_Fractorium->ui.CurrentXformCombo;
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);
int index = m_Ember.TotalXformCount() - 1;//Set index to the last item.
@ -322,7 +305,6 @@ void FractoriumEmberController<T>::XformWeightChanged(double d)
{
xform->m_Weight = d;
}, eXformUpdate::UPDATE_SELECTED_EXCEPT_FINAL);
SetNormalizedWeightText(CurrentXform());
}
@ -356,19 +338,32 @@ void FractoriumEmberController<T>::XformNameChanged(int row, int col)
UpdateXform([&] (Xform<T>* xform)
{
int index = m_Ember.GetTotalXformIndex(xform);
xform->m_Name = m_Fractorium->ui.XformWeightNameTable->item(row, col)->text().toStdString();
XformCheckboxAt(index, [&](QCheckBox* checkbox) { checkbox->setText(MakeXformCaption(index)); });
//if (index != -1)
//{
// if (QTableWidgetItem* xformNameItem = m_Fractorium->ui.XaosTable->item(index, 0))
// xformNameItem->setText(MakeXaosNameString(index));
//}
XformCheckboxAt(index, [&](QCheckBox * checkbox) { checkbox->setText(MakeXformCaption(index)); });
}, eXformUpdate::UPDATE_CURRENT, false);
}
void Fractorium::OnXformNameChanged(int row, int col) { m_Controller->XformNameChanged(row, col); }
/// <summary>
/// Set the animate field of the selected xforms.
/// This has no effect on interactive rendering, it only sets a value
/// that will later be saved to Xml when the user saves.
/// This value is observed when creating sequences for animation.
/// Called when the user toggles the animate xform checkbox.
/// </summary>
/// <param name="state">1 for checked, else false</param>
template <typename T>
void FractoriumEmberController<T>::XformAnimateChanged(int state)
{
UpdateXform([&](Xform<T>* xform)
{
xform->m_Animate = state > 0 ? 1 : 0;
}, eXformUpdate::UPDATE_SELECTED, false);
}
void Fractorium::OnXformAnimateCheckBoxStateChanged(int state) { m_Controller->XformAnimateChanged(state); }
/// <summary>
/// Fill all GUI widgets with values from the passed in xform.
/// </summary>
@ -378,8 +373,9 @@ void FractoriumEmberController<T>::FillWithXform(Xform<T>* xform)//Need to see w
{
m_Fractorium->m_XformWeightSpin->SetValueStealth(xform->m_Weight);
SetNormalizedWeightText(xform);
m_Fractorium->ui.AnimateXformCheckBox->setChecked(xform->m_Animate > 0 ? true : false);//Make a signal/slot to handle checking this.
if (QTableWidgetItem* item = m_Fractorium->ui.XformWeightNameTable->item(0, 1))
if (auto item = m_Fractorium->ui.XformWeightNameTable->item(0, 1))
{
m_Fractorium->ui.XformWeightNameTable->blockSignals(true);
item->setText(QString::fromStdString(xform->m_Name));
@ -402,7 +398,6 @@ void FractoriumEmberController<T>::SetNormalizedWeightText(Xform<T>* xform)
if (xform)
{
int index = m_Ember.GetXformIndex(xform);
m_Ember.CalcNormalizedWeights(m_NormalizedWeights);
if (index != -1 && index < m_NormalizedWeights.size())
@ -433,29 +428,27 @@ void FractoriumEmberController<T>::FillXforms(int index)
{
int i = 0, count = int(XformCount());
auto combo = m_Fractorium->ui.CurrentXformCombo;
combo->blockSignals(true);
combo->clear();
//First clear all dynamically created checkboxes.
m_Fractorium->ClearXformsSelections();
m_Fractorium->m_XformsSelectionLayout->blockSignals(true);
//Fill combo box and create new checkboxes.
for (i = 0; i < count; i++)
{
combo->addItem(ToString(i + 1));
combo->setItemIcon(i, m_Fractorium->m_XformComboIcons[i % XFORM_COLOR_COUNT]);
}
i = 0;
while (i < count)
{
if (i < count - 1)
{
auto cb1 = new QCheckBox(MakeXformCaption(i), m_Fractorium);
auto cb2 = new QCheckBox(MakeXformCaption(i + 1), m_Fractorium);
m_Fractorium->m_XformSelections.push_back(cb1);
m_Fractorium->m_XformSelections.push_back(cb2);
m_Fractorium->m_XformsSelectionLayout->addRow(cb1, cb2);
@ -464,31 +457,28 @@ void FractoriumEmberController<T>::FillXforms(int index)
else if (i < count)
{
auto cb = new QCheckBox(MakeXformCaption(i), m_Fractorium);
m_Fractorium->m_XformSelections.push_back(cb);
m_Fractorium->m_XformsSelectionLayout->addRow(cb, new QWidget(m_Fractorium));
i++;
}
}
//Special case for final xform.
if (UseFinalXform())
{
auto cb = new QCheckBox(MakeXformCaption(i), m_Fractorium);
m_Fractorium->m_XformSelections.push_back(cb);
m_Fractorium->m_XformsSelectionLayout->addRow(cb, new QWidget(m_Fractorium));
combo->addItem("Final");
combo->setItemIcon(i, m_Fractorium->m_FinalXformComboIcon);
}
m_Fractorium->m_XformsSelectionLayout->blockSignals(false);
combo->blockSignals(false);
if (index < combo->count())
combo->setCurrentIndex(index);
m_Fractorium->FillXaosTable();
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.
@ -497,5 +487,5 @@ void FractoriumEmberController<T>::FillXforms(int index)
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif