From 0fc2d3107e3cd55e367367064c2eeda37f71c848 Mon Sep 17 00:00:00 2001 From: Seth Troisi Date: Sat, 12 Feb 2022 18:51:42 -0800 Subject: [PATCH 1/3] --Code Change -Change Sequence Preview to PREVIEW_SIZE (128) --- Source/Fractorium/EmberTreeWidgetItem.h | 2 +- Source/Fractorium/FractoriumEmberController.h | 2 +- Source/Fractorium/FractoriumLibrary.cpp | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/Fractorium/EmberTreeWidgetItem.h b/Source/Fractorium/EmberTreeWidgetItem.h index 1187977..0fb5996 100644 --- a/Source/Fractorium/EmberTreeWidgetItem.h +++ b/Source/Fractorium/EmberTreeWidgetItem.h @@ -47,7 +47,7 @@ public: /// The height of the image in pixels void SetImage(vector& v, uint width, uint height) { - constexpr auto size = 64; + constexpr auto size = PREVIEW_SIZE; m_Image = QImage(width, height, QImage::Format_RGBA8888); memcpy(m_Image.scanLine(0), v.data(), SizeOf(v));//Memcpy the data in. m_Pixmap = QPixmap::fromImage(m_Image).scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//Create a QPixmap out of the QImage, scaled to size. diff --git a/Source/Fractorium/FractoriumEmberController.h b/Source/Fractorium/FractoriumEmberController.h index 65c6eb4..a7d0d95 100644 --- a/Source/Fractorium/FractoriumEmberController.h +++ b/Source/Fractorium/FractoriumEmberController.h @@ -32,7 +32,7 @@ class Fractorium; template class PreviewRenderer; template class TreePreviewRenderer; -#define PREVIEW_SIZE 256 +#define PREVIEW_SIZE 128 #define UNDO_SIZE 512 /// diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp index 8616a4b..72a7f9d 100644 --- a/Source/Fractorium/FractoriumLibrary.cpp +++ b/Source/Fractorium/FractoriumLibrary.cpp @@ -176,18 +176,18 @@ void FractoriumEmberController::SyncLibrary(eLibraryUpdate update) template void FractoriumEmberController::FillLibraryTree(int selectIndex) { - uint size = 64; - uint i = 0; - const auto tree = m_Fractorium->ui.LibraryTree; + const uint size = PREVIEW_SIZE; vector v(size * size * 4); - StopAllPreviewRenderers(); + const auto tree = m_Fractorium->ui.LibraryTree; tree->clear(); + StopAllPreviewRenderers(); auto fileItem = new QTreeWidgetItem(tree); QFileInfo info(m_EmberFile.m_Filename); fileItem->setText(0, info.fileName()); fileItem->setToolTip(0, m_EmberFile.m_Filename); fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled); + uint i = 0; for (auto& it : m_EmberFile.m_Embers) { auto emberItem = new EmberTreeWidgetItem(&it, fileItem); @@ -216,7 +216,7 @@ void FractoriumEmberController::FillLibraryTree(int selectIndex) template void FractoriumEmberController::UpdateLibraryTree() { - const uint size = 64; + const uint size = PREVIEW_SIZE; vector v(size * size * 4); const auto tree = m_Fractorium->ui.LibraryTree; @@ -479,18 +479,18 @@ void FractoriumEmberController::StopAllPreviewRenderers() template void FractoriumEmberController::FillSequenceTree() { - const uint size = 64; - uint i = 0; - const auto tree = m_Fractorium->ui.SequenceTree; + const uint size = PREVIEW_SIZE; vector v(size * size * 4); - m_SequencePreviewRenderer->Stop(); + const auto tree = m_Fractorium->ui.SequenceTree; tree->clear(); + StopAllPreviewRenderers(); auto fileItem = new QTreeWidgetItem(tree); QFileInfo info(m_SequenceFile.m_Filename); fileItem->setText(0, info.fileName()); fileItem->setToolTip(0, m_SequenceFile.m_Filename); fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable); + uint i = 0; for (auto& it : m_SequenceFile.m_Embers) { auto emberItem = new EmberTreeWidgetItemBase(fileItem); From 36e83c5552e5aa97afc19cad919a06a8aeefbf96 Mon Sep 17 00:00:00 2001 From: Seth Troisi Date: Sat, 12 Feb 2022 18:47:42 -0800 Subject: [PATCH 2/3] --Code Change -Add Clear Sequence button to Sequence Panel --- Source/Fractorium/Fractorium.cpp | 1 + Source/Fractorium/Fractorium.h | 1 + Source/Fractorium/Fractorium.ui | 10 ++++++++++ Source/Fractorium/FractoriumEmberController.h | 2 ++ Source/Fractorium/FractoriumLibrary.cpp | 14 ++++++++++++++ 5 files changed, 28 insertions(+) diff --git a/Source/Fractorium/Fractorium.cpp b/Source/Fractorium/Fractorium.cpp index 09dee6b..c7efd2e 100644 --- a/Source/Fractorium/Fractorium.cpp +++ b/Source/Fractorium/Fractorium.cpp @@ -1234,6 +1234,7 @@ void Fractorium::SetTabOrders() w = SetTabOrder(this, w, ui.SequenceLinearCheckBox); w = SetTabOrder(this, w, ui.SequenceGenerateButton); w = SetTabOrder(this, w, ui.SequenceRenderButton); + w = SetTabOrder(this, w, ui.SequenceClearButton); w = SetTabOrder(this, w, ui.SequenceSaveButton); w = SetTabOrder(this, w, ui.SequenceOpenButton); w = SetTabOrder(this, w, ui.SequenceTree); diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h index 8ea9795..52dcfc0 100644 --- a/Source/Fractorium/Fractorium.h +++ b/Source/Fractorium/Fractorium.h @@ -206,6 +206,7 @@ public slots: void OnSequenceAllButtonClicked(bool checked); void OnSequenceGenerateButtonClicked(bool checked); void OnSequenceRenderButtonClicked(bool checked); + void OnSequenceClearButtonClicked(bool checked); void OnSequenceSaveButtonClicked(bool checked); void OnSequenceOpenButtonClicked(bool checked); void OnSequenceRandomizeStaggerCheckBoxStateChanged(int state); diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index ff1e9aa..6227811 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -8097,6 +8097,16 @@ + + + + <html><head/><body><p>Clear the sequence of generated thumbnails.</p></body></html> + + + Clear + + + diff --git a/Source/Fractorium/FractoriumEmberController.h b/Source/Fractorium/FractoriumEmberController.h index a7d0d95..d015c40 100644 --- a/Source/Fractorium/FractoriumEmberController.h +++ b/Source/Fractorium/FractoriumEmberController.h @@ -136,6 +136,7 @@ public: virtual void Delete(const vector>& v) { } virtual void FillSequenceTree() { } virtual void SequenceGenerateButtonClicked() { } + virtual void SequenceClearButtonClicked() { } virtual void SequenceSaveButtonClicked() { } virtual void SequenceOpenButtonClicked() { } @@ -428,6 +429,7 @@ public: void StopAllPreviewRenderers() override; void FillSequenceTree() override; void SequenceGenerateButtonClicked() override; + void SequenceClearButtonClicked() override; void SequenceSaveButtonClicked() override; void SequenceOpenButtonClicked() override; diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp index 72a7f9d..9cbb207 100644 --- a/Source/Fractorium/FractoriumLibrary.cpp +++ b/Source/Fractorium/FractoriumLibrary.cpp @@ -17,6 +17,7 @@ void Fractorium::InitLibraryUI() 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.SequenceRenderButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceRenderButtonClicked(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.SequenceOpenButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceOpenButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceRandomizeStaggerCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSequenceRandomizeStaggerCheckBoxStateChanged(int)), Qt::QueuedConnection); @@ -773,6 +774,19 @@ void Fractorium::OnSequenceRenderButtonClicked(bool checked) } } +/// +/// Clear the sequence. +/// +template +void FractoriumEmberController::SequenceClearButtonClicked() +{ + const auto tree = m_Fractorium->ui.SequenceTree; + m_SequencePreviewRenderer->Stop(); + tree->clear(); +} + +void Fractorium::OnSequenceClearButtonClicked(bool checked) { m_Controller->SequenceClearButtonClicked(); } + /// /// Save the sequence to a file. /// From 8ab6c920eedff712013a2cc64c46c25b36b398e3 Mon Sep 17 00:00:00 2001 From: Seth Troisi Date: Tue, 22 Feb 2022 19:54:29 -0800 Subject: [PATCH 3/3] --Code Change -Add Animate Button --- Source/Fractorium/EmberTreeWidgetItem.h | 14 ++ Source/Fractorium/Fractorium.cpp | 3 +- Source/Fractorium/Fractorium.h | 5 +- Source/Fractorium/Fractorium.ui | 37 ++++-- .../Fractorium/FractoriumEmberController.cpp | 12 +- Source/Fractorium/FractoriumEmberController.h | 12 +- Source/Fractorium/FractoriumLibrary.cpp | 122 +++++++++++++++--- 7 files changed, 171 insertions(+), 34 deletions(-) diff --git a/Source/Fractorium/EmberTreeWidgetItem.h b/Source/Fractorium/EmberTreeWidgetItem.h index 0fb5996..a4b38e5 100644 --- a/Source/Fractorium/EmberTreeWidgetItem.h +++ b/Source/Fractorium/EmberTreeWidgetItem.h @@ -2,6 +2,8 @@ #include "FractoriumPch.h" +template class FractoriumEmberController; + /// /// EmberTreeWidgetItem /// @@ -14,6 +16,12 @@ class EmberTreeWidgetItemBase : public QTreeWidgetItem { public: + friend FractoriumEmberController; + +#ifdef DO_DOUBLE + friend FractoriumEmberController; +#endif + /// /// Constructor that takes a pointer to a QTreeWidget as a parent widget. /// This is meant to be a root level item. @@ -54,9 +62,15 @@ public: setData(0, Qt::DecorationRole, m_Pixmap); } + void SetRendered() + { + m_Rendered = true; + } + protected: QImage m_Image; QPixmap m_Pixmap; + bool m_Rendered; }; /// diff --git a/Source/Fractorium/Fractorium.cpp b/Source/Fractorium/Fractorium.cpp index c7efd2e..a53c03f 100644 --- a/Source/Fractorium/Fractorium.cpp +++ b/Source/Fractorium/Fractorium.cpp @@ -1234,9 +1234,10 @@ void Fractorium::SetTabOrders() w = SetTabOrder(this, w, ui.SequenceLinearCheckBox); w = SetTabOrder(this, w, ui.SequenceGenerateButton); w = SetTabOrder(this, w, ui.SequenceRenderButton); - w = SetTabOrder(this, w, ui.SequenceClearButton); w = SetTabOrder(this, w, ui.SequenceSaveButton); 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, ui.CurrentXformCombo, ui.AddXformButton);//Xforms. w = SetTabOrder(this, w, ui.AddLinkedXformButton); diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h index 52dcfc0..d7ced70 100644 --- a/Source/Fractorium/Fractorium.h +++ b/Source/Fractorium/Fractorium.h @@ -206,9 +206,10 @@ public slots: void OnSequenceAllButtonClicked(bool checked); void OnSequenceGenerateButtonClicked(bool checked); void OnSequenceRenderButtonClicked(bool checked); - void OnSequenceClearButtonClicked(bool checked); void OnSequenceSaveButtonClicked(bool checked); void OnSequenceOpenButtonClicked(bool checked); + void OnSequenceAnimateButtonClicked(bool checked); + void OnSequenceClearButtonClicked(bool checked); void OnSequenceRandomizeStaggerCheckBoxStateChanged(int state); void OnSequenceRandomizeFramesPerRotCheckBoxStateChanged(int state); void OnSequenceRandomizeRotationsCheckBoxStateChanged(int state); @@ -392,7 +393,7 @@ public slots: void ShowCritical(const QString& title, const QString& text, bool invokeRequired = false); //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: //template//See below. diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index 6227811..11c9b6c 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -8097,16 +8097,6 @@ - - - - <html><head/><body><p>Clear the sequence of generated thumbnails.</p></body></html> - - - Clear - - - @@ -8128,6 +8118,33 @@ + + + + + 2 + + + + + <html><head/><body><p>Animate the sequence of generated thumbnails.</p></body></html> + + + Animate + + + + + + + <html><head/><body><p>Clear the sequence of generated thumbnails.</p></body></html> + + + Clear + + + + diff --git a/Source/Fractorium/FractoriumEmberController.cpp b/Source/Fractorium/FractoriumEmberController.cpp index 9777535..ae96c6c 100644 --- a/Source/Fractorium/FractoriumEmberController.cpp +++ b/Source/Fractorium/FractoriumEmberController.cpp @@ -18,7 +18,12 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor m_RenderTimer->setInterval(0); m_Fractorium->connect(m_RenderTimer.get(), SIGNAL(timeout()), SLOT(IdleTimer())); m_RenderRestartTimer = make_unique(m_Fractorium); + m_AnimateTimer = make_unique(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. + // XXX: why not SLOT(SequenceAnimateNextFrame())? + m_Fractorium->connect(m_AnimateTimer.get(), &QTimer::timeout, [&]() { SequenceAnimateNextFrame(); }); } /// @@ -30,6 +35,7 @@ FractoriumEmberControllerBase::~FractoriumEmberControllerBase() StopRenderTimer(true); m_RenderTimer->stop(); m_RenderRestartTimer->stop(); + m_AnimateTimer->stop(); } /// @@ -379,7 +385,8 @@ void TreePreviewRenderer::PreviewRenderFunc(uint start, uint end) 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. - 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; @@ -402,11 +409,12 @@ void TreePreviewRenderer::PreviewRenderFunc(uint start, uint end) //until the update is complete. if (m_PreviewRun) { - QMetaObject::invokeMethod(f, "SetLibraryTreeItemData", Qt::DirectConnection, + QMetaObject::invokeMethod(f, "SetTreeItemData", Qt::DirectConnection, Q_ARG(EmberTreeWidgetItemBase*, treeItem), Q_ARG(vv4F&, m_PreviewFinalImage), Q_ARG(uint, PREVIEW_SIZE), Q_ARG(uint, PREVIEW_SIZE)); + treeItem->SetRendered(); } } } diff --git a/Source/Fractorium/FractoriumEmberController.h b/Source/Fractorium/FractoriumEmberController.h index d015c40..b154d1c 100644 --- a/Source/Fractorium/FractoriumEmberController.h +++ b/Source/Fractorium/FractoriumEmberController.h @@ -135,10 +135,13 @@ public: virtual void MoveLibraryItems(const QModelIndexList& items, int destRow) { } virtual void Delete(const vector>& v) { } virtual void FillSequenceTree() { } + virtual void AddAnimationItem() { } virtual void SequenceGenerateButtonClicked() { } - virtual void SequenceClearButtonClicked() { } virtual void SequenceSaveButtonClicked() { } virtual void SequenceOpenButtonClicked() { } + virtual void SequenceAnimateButtonClicked() { } + virtual void SequenceAnimateNextFrame() { } + virtual void SequenceClearButtonClicked() { } //Params. virtual void ParamsToEmber(Ember& ember, bool imageParamsOnly = false) { }; @@ -325,8 +328,10 @@ protected: Palette m_TempPalette, m_PreviousTempPalette; std::unique_ptr m_RenderTimer; std::unique_ptr m_RenderRestartTimer; + std::unique_ptr m_AnimateTimer; shared_ptr> m_PaletteList; shared_ptr m_Info = OpenCLInfo::Instance(); + int m_AnimateFrame = 0; }; /// @@ -428,10 +433,13 @@ public: void StopSequencePreviewRender() override; void StopAllPreviewRenderers() override; void FillSequenceTree() override; + void AddAnimationItem() override; void SequenceGenerateButtonClicked() override; - void SequenceClearButtonClicked() override; void SequenceSaveButtonClicked() override; void SequenceOpenButtonClicked() override; + void SequenceAnimateButtonClicked() override; + void SequenceAnimateNextFrame() override; + void SequenceClearButtonClicked() override; //Params. void ParamsToEmber(Ember& ember, bool imageParamsOnly = false) override; diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp index 9cbb207..af2e57f 100644 --- a/Source/Fractorium/FractoriumLibrary.cpp +++ b/Source/Fractorium/FractoriumLibrary.cpp @@ -17,7 +17,8 @@ void Fractorium::InitLibraryUI() 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.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.SequenceOpenButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceOpenButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceRandomizeStaggerCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSequenceRandomizeStaggerCheckBoxStateChanged(int)), Qt::QueuedConnection); @@ -128,7 +129,7 @@ vector> Fractorium::GetCurrentEmberIndex(bool isC /// The vector holding the RGBA bitmap /// The width of the bitmap /// The height of the bitmap -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); Rgba32ToRgba8(v.data(), m_PreviewVec.data(), w, h, m_Settings->Transparency()); @@ -177,11 +178,13 @@ void FractoriumEmberController::SyncLibrary(eLibraryUpdate update) template void FractoriumEmberController::FillLibraryTree(int selectIndex) { + StopAllPreviewRenderers(); + const uint size = PREVIEW_SIZE; - vector v(size * size * 4); + vector empy_preview(size * size * 4); const auto tree = m_Fractorium->ui.LibraryTree; tree->clear(); - StopAllPreviewRenderers(); + auto fileItem = new QTreeWidgetItem(tree); QFileInfo info(m_EmberFile.m_Filename); fileItem->setText(0, info.fileName()); @@ -199,7 +202,7 @@ void FractoriumEmberController::FillLibraryTree(int selectIndex) emberItem->setText(0, it.m_Name.c_str()); emberItem->setToolTip(0, emberItem->text(0)); - emberItem->SetImage(v, size, size); + emberItem->SetImage(empy_preview, size, size); } if (selectIndex != -1) @@ -218,7 +221,7 @@ template void FractoriumEmberController::UpdateLibraryTree() { const uint size = PREVIEW_SIZE; - vector v(size * size * 4); + vector empy_preview(size * size * 4); const auto tree = m_Fractorium->ui.LibraryTree; if (auto top = tree->topLevelItem(0)) @@ -236,7 +239,7 @@ void FractoriumEmberController::UpdateLibraryTree() emberItem->setText(0, it->m_Name.c_str()); 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. @@ -429,10 +432,10 @@ template void FractoriumEmberController::RenderPreviews(QTreeWidget* tree, TreePreviewRenderer* renderer, EmberFile& file, uint start, uint end) { renderer->Stop(); - 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(); vector emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 4); @@ -472,6 +475,23 @@ void FractoriumEmberController::StopAllPreviewRenderers() StopSequencePreviewRender(); } +template +void FractoriumEmberController::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 empy_preview(size * size * 4); + emberItem->SetImage(empy_preview, size, size); +} + /// /// Fill the sequence tree with the names of the embers in the /// currently generated sequence. @@ -480,11 +500,16 @@ void FractoriumEmberController::StopAllPreviewRenderers() template void FractoriumEmberController::FillSequenceTree() { + StopAllPreviewRenderers(); + const uint size = PREVIEW_SIZE; - vector v(size * size * 4); + vector empy_preview(size * size * 4); const auto tree = m_Fractorium->ui.SequenceTree; tree->clear(); - StopAllPreviewRenderers(); + + // Add extra TreeWidget for animation at index 0 + AddAnimationItem(); + auto fileItem = new QTreeWidgetItem(tree); QFileInfo info(m_SequenceFile.m_Filename); fileItem->setText(0, info.fileName()); @@ -504,10 +529,13 @@ void FractoriumEmberController::FillSequenceTree() i++; emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); emberItem->setToolTip(0, emberItem->text(0)); - emberItem->SetImage(v, size, size); + emberItem->SetImage(empy_preview, size, size); } tree->expandAll(); + // Hide the animation item + tree->collapseItem(tree->topLevelItem(0)); + RenderSequencePreviews(0, uint(m_SequenceFile.Size())); } @@ -520,7 +548,7 @@ void FractoriumEmberController::FillSequenceTree() template void FractoriumEmberController::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); @@ -542,8 +570,13 @@ void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col) /// Ignored, render all. /// Ignored, render all. template -void FractoriumEmberController::RenderSequencePreviews(uint start, uint end) { RenderPreviews(m_Fractorium->ui.SequenceTree, m_SequencePreviewRenderer.get(), m_SequenceFile, start, end); } -void Fractorium::OnSequenceStartPreviewsButtonClicked(bool checked) { m_Controller->RenderSequencePreviews(); } +void FractoriumEmberController::RenderSequencePreviews(uint start, uint end) { + RenderPreviews(m_Fractorium->ui.SequenceTree, m_SequencePreviewRenderer.get(), m_SequenceFile, start, end); +} + +void Fractorium::OnSequenceStartPreviewsButtonClicked(bool checked) { + m_Controller->RenderSequencePreviews(); +} /// /// Stop rendering the sequence previews. @@ -731,8 +764,6 @@ void FractoriumEmberController::SequenceGenerateButtonClicked() for (frame = 0; frame < blendFrames; frame++) { - //if (frame == 43) - // cout << frame << endl; const auto seqFlag = frame == 0 || (frame == blendFrames - 1); blend = frame / double(blendFrames); result.Clear(); @@ -774,6 +805,63 @@ void Fractorium::OnSequenceRenderButtonClicked(bool checked) } } +/// +/// Animate the sequence +/// +template +void FractoriumEmberController::SequenceAnimateNextFrame() +{ + const auto tree = m_Fractorium->ui.SequenceTree; + if (const auto renders = tree->topLevelItem(1)) + { + if (renders->childCount()) + { + const auto animate = dynamic_cast(tree->topLevelItem(0)->child(0)); + const auto frame = m_AnimateFrame++ % renders->childCount(); + const auto nth = dynamic_cast(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); + } + } + } + } +} + +/// +/// Animate the sequence +/// +template +void FractoriumEmberController::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(); } + /// /// Clear the sequence. ///