--Code Change

-Add Animate Button
This commit is contained in:
Seth Troisi 2022-02-22 19:54:29 -08:00
parent 36e83c5552
commit 8ab6c920ee
7 changed files with 171 additions and 34 deletions

View File

@ -2,6 +2,8 @@
#include "FractoriumPch.h" #include "FractoriumPch.h"
template <typename T> class FractoriumEmberController;
/// <summary> /// <summary>
/// EmberTreeWidgetItem /// EmberTreeWidgetItem
/// </summary> /// </summary>
@ -14,6 +16,12 @@
class EmberTreeWidgetItemBase : public QTreeWidgetItem class EmberTreeWidgetItemBase : public QTreeWidgetItem
{ {
public: public:
friend FractoriumEmberController<float>;
#ifdef DO_DOUBLE
friend FractoriumEmberController<double>;
#endif
/// <summary> /// <summary>
/// Constructor that takes a pointer to a QTreeWidget as a parent widget. /// Constructor that takes a pointer to a QTreeWidget as a parent widget.
/// This is meant to be a root level item. /// This is meant to be a root level item.
@ -54,9 +62,15 @@ public:
setData(0, Qt::DecorationRole, m_Pixmap); setData(0, Qt::DecorationRole, m_Pixmap);
} }
void SetRendered()
{
m_Rendered = true;
}
protected: protected:
QImage m_Image; QImage m_Image;
QPixmap m_Pixmap; QPixmap m_Pixmap;
bool m_Rendered;
}; };
/// <summary> /// <summary>

View File

@ -1234,9 +1234,10 @@ void Fractorium::SetTabOrders()
w = SetTabOrder(this, w, ui.SequenceLinearCheckBox); w = SetTabOrder(this, w, ui.SequenceLinearCheckBox);
w = SetTabOrder(this, w, ui.SequenceGenerateButton); w = SetTabOrder(this, w, ui.SequenceGenerateButton);
w = SetTabOrder(this, w, ui.SequenceRenderButton); w = SetTabOrder(this, w, ui.SequenceRenderButton);
w = SetTabOrder(this, w, ui.SequenceClearButton);
w = SetTabOrder(this, w, ui.SequenceSaveButton); w = SetTabOrder(this, w, ui.SequenceSaveButton);
w = SetTabOrder(this, w, ui.SequenceOpenButton); w = SetTabOrder(this, w, ui.SequenceOpenButton);
w = SetTabOrder(this, w, ui.SequenceAnimateButton);
w = SetTabOrder(this, w, ui.SequenceClearButton);
w = SetTabOrder(this, w, ui.SequenceTree); w = SetTabOrder(this, w, ui.SequenceTree);
w = SetTabOrder(this, ui.CurrentXformCombo, ui.AddXformButton);//Xforms. w = SetTabOrder(this, ui.CurrentXformCombo, ui.AddXformButton);//Xforms.
w = SetTabOrder(this, w, ui.AddLinkedXformButton); w = SetTabOrder(this, w, ui.AddLinkedXformButton);

View File

@ -206,9 +206,10 @@ public slots:
void OnSequenceAllButtonClicked(bool checked); void OnSequenceAllButtonClicked(bool checked);
void OnSequenceGenerateButtonClicked(bool checked); void OnSequenceGenerateButtonClicked(bool checked);
void OnSequenceRenderButtonClicked(bool checked); void OnSequenceRenderButtonClicked(bool checked);
void OnSequenceClearButtonClicked(bool checked);
void OnSequenceSaveButtonClicked(bool checked); void OnSequenceSaveButtonClicked(bool checked);
void OnSequenceOpenButtonClicked(bool checked); void OnSequenceOpenButtonClicked(bool checked);
void OnSequenceAnimateButtonClicked(bool checked);
void OnSequenceClearButtonClicked(bool checked);
void OnSequenceRandomizeStaggerCheckBoxStateChanged(int state); void OnSequenceRandomizeStaggerCheckBoxStateChanged(int state);
void OnSequenceRandomizeFramesPerRotCheckBoxStateChanged(int state); void OnSequenceRandomizeFramesPerRotCheckBoxStateChanged(int state);
void OnSequenceRandomizeRotationsCheckBoxStateChanged(int state); void OnSequenceRandomizeRotationsCheckBoxStateChanged(int state);
@ -392,7 +393,7 @@ public slots:
void ShowCritical(const QString& title, const QString& text, bool invokeRequired = false); void ShowCritical(const QString& title, const QString& text, bool invokeRequired = false);
//Can't have a template function be a slot. //Can't have a template function be a slot.
void SetLibraryTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h); void SetTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h);
public: public:
//template<typename spinType, typename valType>//See below. //template<typename spinType, typename valType>//See below.

View File

@ -8097,16 +8097,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="SequenceClearButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Clear the sequence of generated thumbnails.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="SequenceSaveButton"> <widget class="QPushButton" name="SequenceSaveButton">
<property name="toolTip"> <property name="toolTip">
@ -8128,6 +8118,33 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</item>
<item>
<layout class="QHBoxLayout" name="SequenceAnimateButtonsHLayout" stretch="0,0,0,0">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QPushButton" name="SequenceAnimateButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Animate the sequence of generated thumbnails.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Animate</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SequenceClearButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Clear the sequence of generated thumbnails.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="LibraryTreeWidget" name="SequenceTree"> <widget class="LibraryTreeWidget" name="SequenceTree">

View File

@ -18,7 +18,12 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor
m_RenderTimer->setInterval(0); m_RenderTimer->setInterval(0);
m_Fractorium->connect(m_RenderTimer.get(), SIGNAL(timeout()), SLOT(IdleTimer())); m_Fractorium->connect(m_RenderTimer.get(), SIGNAL(timeout()), SLOT(IdleTimer()));
m_RenderRestartTimer = make_unique<QTimer>(m_Fractorium); m_RenderRestartTimer = make_unique<QTimer>(m_Fractorium);
m_AnimateTimer = make_unique<QTimer>(m_Fractorium);
m_AnimateTimer->stop();
m_Fractorium->connect(m_RenderRestartTimer.get(), &QTimer::timeout, [&]() { m_Fractorium->StartRenderTimer(false); });//It's ok to pass false for the first shot because creating the controller will start the preview renders. m_Fractorium->connect(m_RenderRestartTimer.get(), &QTimer::timeout, [&]() { m_Fractorium->StartRenderTimer(false); });//It's ok to pass false for the first shot because creating the controller will start the preview renders.
// XXX: why not SLOT(SequenceAnimateNextFrame())?
m_Fractorium->connect(m_AnimateTimer.get(), &QTimer::timeout, [&]() { SequenceAnimateNextFrame(); });
} }
/// <summary> /// <summary>
@ -30,6 +35,7 @@ FractoriumEmberControllerBase::~FractoriumEmberControllerBase()
StopRenderTimer(true); StopRenderTimer(true);
m_RenderTimer->stop(); m_RenderTimer->stop();
m_RenderRestartTimer->stop(); m_RenderRestartTimer->stop();
m_AnimateTimer->stop();
} }
/// <summary> /// <summary>
@ -379,7 +385,8 @@ void TreePreviewRenderer<T>::PreviewRenderFunc(uint start, uint end)
m_PreviewRenderer.YAxisUp(f->m_Settings->YAxisUp()); m_PreviewRenderer.YAxisUp(f->m_Settings->YAxisUp());
m_PreviewRenderer.ThreadCount(std::max(1u, Timing::ProcessorCount() - 1));//Leave one processor free so the GUI can breathe. m_PreviewRenderer.ThreadCount(std::max(1u, Timing::ProcessorCount() - 1));//Leave one processor free so the GUI can breathe.
if (const auto top = m_Tree->topLevelItem(0)) // Possible animate item at index 0
if (const auto top = m_Tree->topLevelItem(m_Tree->topLevelItemCount() - 1))
{ {
size_t i = start; size_t i = start;
@ -402,11 +409,12 @@ void TreePreviewRenderer<T>::PreviewRenderFunc(uint start, uint end)
//until the update is complete. //until the update is complete.
if (m_PreviewRun) if (m_PreviewRun)
{ {
QMetaObject::invokeMethod(f, "SetLibraryTreeItemData", Qt::DirectConnection, QMetaObject::invokeMethod(f, "SetTreeItemData", Qt::DirectConnection,
Q_ARG(EmberTreeWidgetItemBase*, treeItem), Q_ARG(EmberTreeWidgetItemBase*, treeItem),
Q_ARG(vv4F&, m_PreviewFinalImage), Q_ARG(vv4F&, m_PreviewFinalImage),
Q_ARG(uint, PREVIEW_SIZE), Q_ARG(uint, PREVIEW_SIZE),
Q_ARG(uint, PREVIEW_SIZE)); Q_ARG(uint, PREVIEW_SIZE));
treeItem->SetRendered();
} }
} }
} }

View File

@ -135,10 +135,13 @@ public:
virtual void MoveLibraryItems(const QModelIndexList& items, int destRow) { } virtual void MoveLibraryItems(const QModelIndexList& items, int destRow) { }
virtual void Delete(const vector<pair<size_t, QTreeWidgetItem*>>& v) { } virtual void Delete(const vector<pair<size_t, QTreeWidgetItem*>>& v) { }
virtual void FillSequenceTree() { } virtual void FillSequenceTree() { }
virtual void AddAnimationItem() { }
virtual void SequenceGenerateButtonClicked() { } virtual void SequenceGenerateButtonClicked() { }
virtual void SequenceClearButtonClicked() { }
virtual void SequenceSaveButtonClicked() { } virtual void SequenceSaveButtonClicked() { }
virtual void SequenceOpenButtonClicked() { } virtual void SequenceOpenButtonClicked() { }
virtual void SequenceAnimateButtonClicked() { }
virtual void SequenceAnimateNextFrame() { }
virtual void SequenceClearButtonClicked() { }
//Params. //Params.
virtual void ParamsToEmber(Ember<float>& ember, bool imageParamsOnly = false) { }; virtual void ParamsToEmber(Ember<float>& ember, bool imageParamsOnly = false) { };
@ -325,8 +328,10 @@ protected:
Palette<float> m_TempPalette, m_PreviousTempPalette; Palette<float> m_TempPalette, m_PreviousTempPalette;
std::unique_ptr<QTimer> m_RenderTimer; std::unique_ptr<QTimer> m_RenderTimer;
std::unique_ptr<QTimer> m_RenderRestartTimer; std::unique_ptr<QTimer> m_RenderRestartTimer;
std::unique_ptr<QTimer> m_AnimateTimer;
shared_ptr<PaletteList<float>> m_PaletteList; shared_ptr<PaletteList<float>> m_PaletteList;
shared_ptr<OpenCLInfo> m_Info = OpenCLInfo::Instance(); shared_ptr<OpenCLInfo> m_Info = OpenCLInfo::Instance();
int m_AnimateFrame = 0;
}; };
/// <summary> /// <summary>
@ -428,10 +433,13 @@ public:
void StopSequencePreviewRender() override; void StopSequencePreviewRender() override;
void StopAllPreviewRenderers() override; void StopAllPreviewRenderers() override;
void FillSequenceTree() override; void FillSequenceTree() override;
void AddAnimationItem() override;
void SequenceGenerateButtonClicked() override; void SequenceGenerateButtonClicked() override;
void SequenceClearButtonClicked() override;
void SequenceSaveButtonClicked() override; void SequenceSaveButtonClicked() override;
void SequenceOpenButtonClicked() override; void SequenceOpenButtonClicked() override;
void SequenceAnimateButtonClicked() override;
void SequenceAnimateNextFrame() override;
void SequenceClearButtonClicked() override;
//Params. //Params.
void ParamsToEmber(Ember<float>& ember, bool imageParamsOnly = false) override; void ParamsToEmber(Ember<float>& ember, bool imageParamsOnly = false) override;

View File

@ -17,7 +17,8 @@ void Fractorium::InitLibraryUI()
connect(ui.SequenceAllButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceAllButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceAllButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceAllButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceGenerateButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceGenerateButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceGenerateButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceGenerateButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceRenderButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceRenderButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceRenderButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceRenderButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceClearButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceClearButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceAnimateButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceAnimateButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceClearButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceClearButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceSaveButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceSaveButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceSaveButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceSaveButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceOpenButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceOpenButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceOpenButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceOpenButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.SequenceRandomizeStaggerCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSequenceRandomizeStaggerCheckBoxStateChanged(int)), Qt::QueuedConnection); connect(ui.SequenceRandomizeStaggerCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSequenceRandomizeStaggerCheckBoxStateChanged(int)), Qt::QueuedConnection);
@ -128,7 +129,7 @@ vector<pair<size_t, QTreeWidgetItem*>> Fractorium::GetCurrentEmberIndex(bool isC
/// <param name="v">The vector holding the RGBA bitmap</param> /// <param name="v">The vector holding the RGBA bitmap</param>
/// <param name="w">The width of the bitmap</param> /// <param name="w">The width of the bitmap</param>
/// <param name="h">The height of the bitmap</param> /// <param name="h">The height of the bitmap</param>
void Fractorium::SetLibraryTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h) void Fractorium::SetTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h)
{ {
m_PreviewVec.resize(size_t(w) * size_t(h) * 4); m_PreviewVec.resize(size_t(w) * size_t(h) * 4);
Rgba32ToRgba8(v.data(), m_PreviewVec.data(), w, h, m_Settings->Transparency()); Rgba32ToRgba8(v.data(), m_PreviewVec.data(), w, h, m_Settings->Transparency());
@ -177,11 +178,13 @@ void FractoriumEmberController<T>::SyncLibrary(eLibraryUpdate update)
template <typename T> template <typename T>
void FractoriumEmberController<T>::FillLibraryTree(int selectIndex) void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
{ {
StopAllPreviewRenderers();
const uint size = PREVIEW_SIZE; const uint size = PREVIEW_SIZE;
vector<byte> v(size * size * 4); vector<byte> empy_preview(size * size * 4);
const auto tree = m_Fractorium->ui.LibraryTree; const auto tree = m_Fractorium->ui.LibraryTree;
tree->clear(); tree->clear();
StopAllPreviewRenderers();
auto fileItem = new QTreeWidgetItem(tree); auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_EmberFile.m_Filename); QFileInfo info(m_EmberFile.m_Filename);
fileItem->setText(0, info.fileName()); fileItem->setText(0, info.fileName());
@ -199,7 +202,7 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
emberItem->setText(0, it.m_Name.c_str()); emberItem->setText(0, it.m_Name.c_str());
emberItem->setToolTip(0, emberItem->text(0)); emberItem->setToolTip(0, emberItem->text(0));
emberItem->SetImage(v, size, size); emberItem->SetImage(empy_preview, size, size);
} }
if (selectIndex != -1) if (selectIndex != -1)
@ -218,7 +221,7 @@ template <typename T>
void FractoriumEmberController<T>::UpdateLibraryTree() void FractoriumEmberController<T>::UpdateLibraryTree()
{ {
const uint size = PREVIEW_SIZE; const uint size = PREVIEW_SIZE;
vector<byte> v(size * size * 4); vector<byte> empy_preview(size * size * 4);
const auto tree = m_Fractorium->ui.LibraryTree; const auto tree = m_Fractorium->ui.LibraryTree;
if (auto top = tree->topLevelItem(0)) if (auto top = tree->topLevelItem(0))
@ -236,7 +239,7 @@ void FractoriumEmberController<T>::UpdateLibraryTree()
emberItem->setText(0, it->m_Name.c_str()); emberItem->setText(0, it->m_Name.c_str());
emberItem->setToolTip(0, emberItem->text(0)); emberItem->setToolTip(0, emberItem->text(0));
emberItem->SetImage(v, size, size); emberItem->SetImage(empy_preview, size, size);
} }
//When adding elements, ensure all indices are sequential. //When adding elements, ensure all indices are sequential.
@ -429,10 +432,10 @@ template <typename T>
void FractoriumEmberController<T>::RenderPreviews(QTreeWidget* tree, TreePreviewRenderer<T>* renderer, EmberFile<T>& file, uint start, uint end) void FractoriumEmberController<T>::RenderPreviews(QTreeWidget* tree, TreePreviewRenderer<T>* renderer, EmberFile<T>& file, uint start, uint end)
{ {
renderer->Stop(); renderer->Stop();
if (start == UINT_MAX && end == UINT_MAX) if (start == UINT_MAX && end == UINT_MAX)
{ {
if (const auto top = tree->topLevelItem(0)) // Animated item might be at index 0, previews go in last item.
if (const auto top = tree->topLevelItem(tree->topLevelItemCount() - 1))
{ {
const auto childCount = top->childCount(); const auto childCount = top->childCount();
vector<byte> emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 4); vector<byte> emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 4);
@ -472,6 +475,23 @@ void FractoriumEmberController<T>::StopAllPreviewRenderers()
StopSequencePreviewRender(); StopSequencePreviewRender();
} }
template <typename T>
void FractoriumEmberController<T>::AddAnimationItem()
{
auto fileItem = new QTreeWidgetItem(m_Fractorium->ui.SequenceTree);
fileItem->setText(0, "Rendered Animation");
fileItem->setToolTip(0, "Rendered frames can be animated here");
fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
auto emberItem = new EmberTreeWidgetItemBase(fileItem);
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
emberItem->setToolTip(0, "Animated Frame");
const uint size = PREVIEW_SIZE;
vector<byte> empy_preview(size * size * 4);
emberItem->SetImage(empy_preview, size, size);
}
/// <summary> /// <summary>
/// Fill the sequence tree with the names of the embers in the /// Fill the sequence tree with the names of the embers in the
/// currently generated sequence. /// currently generated sequence.
@ -480,11 +500,16 @@ void FractoriumEmberController<T>::StopAllPreviewRenderers()
template <typename T> template <typename T>
void FractoriumEmberController<T>::FillSequenceTree() void FractoriumEmberController<T>::FillSequenceTree()
{ {
StopAllPreviewRenderers();
const uint size = PREVIEW_SIZE; const uint size = PREVIEW_SIZE;
vector<byte> v(size * size * 4); vector<byte> empy_preview(size * size * 4);
const auto tree = m_Fractorium->ui.SequenceTree; const auto tree = m_Fractorium->ui.SequenceTree;
tree->clear(); tree->clear();
StopAllPreviewRenderers();
// Add extra TreeWidget for animation at index 0
AddAnimationItem();
auto fileItem = new QTreeWidgetItem(tree); auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_SequenceFile.m_Filename); QFileInfo info(m_SequenceFile.m_Filename);
fileItem->setText(0, info.fileName()); fileItem->setText(0, info.fileName());
@ -504,10 +529,13 @@ void FractoriumEmberController<T>::FillSequenceTree()
i++; i++;
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
emberItem->setToolTip(0, emberItem->text(0)); emberItem->setToolTip(0, emberItem->text(0));
emberItem->SetImage(v, size, size); emberItem->SetImage(empy_preview, size, size);
} }
tree->expandAll(); tree->expandAll();
// Hide the animation item
tree->collapseItem(tree->topLevelItem(0));
RenderSequencePreviews(0, uint(m_SequenceFile.Size())); RenderSequencePreviews(0, uint(m_SequenceFile.Size()));
} }
@ -520,7 +548,7 @@ void FractoriumEmberController<T>::FillSequenceTree()
template <typename T> template <typename T>
void FractoriumEmberController<T>::SequenceTreeItemChanged(QTreeWidgetItem* item, int col) void FractoriumEmberController<T>::SequenceTreeItemChanged(QTreeWidgetItem* item, int col)
{ {
if (item == m_Fractorium->ui.SequenceTree->topLevelItem(0)) if (item == m_Fractorium->ui.SequenceTree->topLevelItem(1))
{ {
auto text = item->text(0); auto text = item->text(0);
@ -542,8 +570,13 @@ void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col)
/// <param name="start">Ignored, render all.</param> /// <param name="start">Ignored, render all.</param>
/// <param name="end">Ignored, render all.</param> /// <param name="end">Ignored, render all.</param>
template <typename T> template <typename T>
void FractoriumEmberController<T>::RenderSequencePreviews(uint start, uint end) { RenderPreviews(m_Fractorium->ui.SequenceTree, m_SequencePreviewRenderer.get(), m_SequenceFile, start, end); } void FractoriumEmberController<T>::RenderSequencePreviews(uint start, uint end) {
void Fractorium::OnSequenceStartPreviewsButtonClicked(bool checked) { m_Controller->RenderSequencePreviews(); } RenderPreviews(m_Fractorium->ui.SequenceTree, m_SequencePreviewRenderer.get(), m_SequenceFile, start, end);
}
void Fractorium::OnSequenceStartPreviewsButtonClicked(bool checked) {
m_Controller->RenderSequencePreviews();
}
/// <summary> /// <summary>
/// Stop rendering the sequence previews. /// Stop rendering the sequence previews.
@ -731,8 +764,6 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
for (frame = 0; frame < blendFrames; frame++) for (frame = 0; frame < blendFrames; frame++)
{ {
//if (frame == 43)
// cout << frame << endl;
const auto seqFlag = frame == 0 || (frame == blendFrames - 1); const auto seqFlag = frame == 0 || (frame == blendFrames - 1);
blend = frame / double(blendFrames); blend = frame / double(blendFrames);
result.Clear(); result.Clear();
@ -774,6 +805,63 @@ void Fractorium::OnSequenceRenderButtonClicked(bool checked)
} }
} }
/// <summary>
/// Animate the sequence
/// </summary>
template <typename T>
void FractoriumEmberController<T>::SequenceAnimateNextFrame()
{
const auto tree = m_Fractorium->ui.SequenceTree;
if (const auto renders = tree->topLevelItem(1))
{
if (renders->childCount())
{
const auto animate = dynamic_cast<EmberTreeWidgetItemBase*>(tree->topLevelItem(0)->child(0));
const auto frame = m_AnimateFrame++ % renders->childCount();
const auto nth = dynamic_cast<EmberTreeWidgetItemBase*>(renders->child(frame));
if (animate && nth)
{
if (!nth->m_Rendered)
{
m_AnimateFrame = 0;
}
else
{
animate->m_Pixmap = QPixmap(nth->m_Pixmap);
animate->setData(0, Qt::DecorationRole, animate->m_Pixmap);
}
}
}
}
}
/// <summary>
/// Animate the sequence
/// </summary>
template <typename T>
void FractoriumEmberController<T>::SequenceAnimateButtonClicked()
{
if (const auto animation = m_Fractorium->ui.SequenceTree->topLevelItem(0))
{
if (animation->isExpanded())
{
animation->setExpanded(false);
m_AnimateTimer->stop();
}
else
{
animation->setExpanded(true);
m_AnimateFrame = 0;
// TODO Make this a UI Parameter
const auto fps = 30;
m_AnimateTimer->start(1000 / fps);
}
}
}
void Fractorium::OnSequenceAnimateButtonClicked(bool checked) { m_Controller->SequenceAnimateButtonClicked(); }
/// <summary> /// <summary>
/// Clear the sequence. /// Clear the sequence.
/// </summary> /// </summary>