diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h index d311b68..874b472 100644 --- a/Source/Fractorium/Fractorium.h +++ b/Source/Fractorium/Fractorium.h @@ -145,6 +145,10 @@ public slots: void OnActionAbout(bool checked);//Help. //Toolbar. + void OnActionCpu(bool checked); + void OnActionCL(bool checked); + void OnActionSP(bool checked); + void OnActionDP(bool checked); //Library. void OnEmberTreeItemChanged(QTreeWidgetItem* item, int col); @@ -324,6 +328,9 @@ private: //Embers. bool HaveFinal(); + //Toolbar. + void SyncOptionsToToolbar(); + //Library. pair GetCurrentEmberIndex(); @@ -358,6 +365,7 @@ private: void SetTableWidgetBackgroundColor(); //Rendering/progress. + void ShutdownAndRecreateFromOptions(); bool CreateRendererFromOptions(); bool CreateControllerFromOptions(); diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index 763b6b6..5dde5b0 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -6196,9 +6196,12 @@ SpinBox - - + + + + + @@ -6541,6 +6544,50 @@ SpinBox Show variations filter window + + + true + + + CPU + + + Use CPU to render + + + + + true + + + CL + + + Use OpenCL to render + + + + + true + + + SP + + + Use single precision to render + + + + + true + + + DP + + + Use DP to render + + diff --git a/Source/Fractorium/FractoriumEmberController.cpp b/Source/Fractorium/FractoriumEmberController.cpp index a7f0e55..cd1a86e 100644 --- a/Source/Fractorium/FractoriumEmberController.cpp +++ b/Source/Fractorium/FractoriumEmberController.cpp @@ -217,7 +217,6 @@ template void FractoriumEmberController::Update(std::function func, bool updateRender, eProcessAction action) { func(); - FillSummary(); if (updateRender) UpdateRender(action); @@ -295,8 +294,6 @@ void FractoriumEmberController::UpdateXform(std::function*)> fu break; } - FillSummary(); - if (updateRender) UpdateRender(action); } @@ -339,7 +336,6 @@ void FractoriumEmberController::SetEmberPrivate(const Ember& ember, bool v m_GLController->ResetMouseState(); FillXforms();//Must do this first because the palette setup in FillParamTablesAndPalette() uses the xforms combo. FillParamTablesAndPalette(); - FillSummary(); //If a resize happened, this won't do anything because the new size is not reflected in the scroll area yet. //However, it will have been taken care of in SyncSizes() in that case, so it's ok. diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp index 592d846..c208ced 100644 --- a/Source/Fractorium/FractoriumLibrary.cpp +++ b/Source/Fractorium/FractoriumLibrary.cpp @@ -228,7 +228,6 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i } tree->blockSignals(false); - FillSummary(); } else if (auto parentItem = dynamic_cast(item)) { diff --git a/Source/Fractorium/FractoriumMenus.cpp b/Source/Fractorium/FractoriumMenus.cpp index 852d678..3458f49 100644 --- a/Source/Fractorium/FractoriumMenus.cpp +++ b/Source/Fractorium/FractoriumMenus.cpp @@ -844,10 +844,8 @@ void Fractorium::OnActionOptions(bool checked) { if (m_OptionsDialog->exec()) { - //First completely stop what the current rendering process is doing. - m_Controller->Shutdown(); - StartRenderTimer();//This will recreate the controller and/or the renderer from the options if necessary, then start the render timer. - m_Settings->sync(); + SyncOptionsToToolbar();//This won't trigger a recreate, the call below handles it. + ShutdownAndRecreateFromOptions();//This will recreate the controller and/or the renderer from the options if necessary, then start the render timer. } } diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp index 5e25da7..a8b79bc 100644 --- a/Source/Fractorium/FractoriumRender.cpp +++ b/Source/Fractorium/FractoriumRender.cpp @@ -396,7 +396,7 @@ bool FractoriumEmberController::Render() m_Fractorium->m_ProgressBar->setValue(100); - //Only certain status can be reported with OpenCL. + //Only certain stats can be reported with OpenCL. if (m_Renderer->RendererType() == OPENCL_RENDERER) { m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Total time: " + QString::fromStdString(renderTime)); @@ -438,6 +438,7 @@ bool FractoriumEmberController::Render() m_LastEditWasUndoRedo = false; m_Fractorium->UpdateHistogramBounds();//Mostly of engineering interest. + FillSummary();//Only update summary on render completion since it's not the type of thing the user needs real-time updates on. } //Update the GL window on start because the output will be forced. @@ -599,6 +600,17 @@ bool FractoriumEmberController::CreateRenderer(eRendererType renderType, uint return ok; } +/// +/// Wrapper to stop the timer, shutdown the controller and recreate, then restart the controller and renderer from the options. +/// +void Fractorium::ShutdownAndRecreateFromOptions() +{ + //First completely stop what the current rendering process is doing. + m_Controller->Shutdown(); + StartRenderTimer();//This will recreate the controller and/or the renderer from the options if necessary, then start the render timer. + m_Settings->sync(); +} + /// /// Create a new renderer from the options. /// diff --git a/Source/Fractorium/FractoriumToolbar.cpp b/Source/Fractorium/FractoriumToolbar.cpp index 8c74396..b1f94b9 100644 --- a/Source/Fractorium/FractoriumToolbar.cpp +++ b/Source/Fractorium/FractoriumToolbar.cpp @@ -6,5 +6,98 @@ /// void Fractorium::InitToolbarUI() { - //Empty for the moment, all functionality is handled in the designer. + auto clGroup = new QActionGroup(this); + clGroup->addAction(ui.ActionCpu); + clGroup->addAction(ui.ActionCL); + + auto spGroup = new QActionGroup(this); + spGroup->addAction(ui.ActionSP); + spGroup->addAction(ui.ActionDP); + + SyncOptionsToToolbar(); + connect(ui.ActionCpu, SIGNAL(triggered(bool)), this, SLOT(OnActionCpu(bool)), Qt::QueuedConnection);//Need to sync these with options dialog.//TODO + connect(ui.ActionCL, SIGNAL(triggered(bool)), this, SLOT(OnActionCL(bool)), Qt::QueuedConnection); + connect(ui.ActionSP, SIGNAL(triggered(bool)), this, SLOT(OnActionSP(bool)), Qt::QueuedConnection); + connect(ui.ActionDP, SIGNAL(triggered(bool)), this, SLOT(OnActionDP(bool)), Qt::QueuedConnection); } + +/// +/// Called when the CPU render option on the toolbar is clicked. +/// +/// Check state, action only taken if true. +void Fractorium::OnActionCpu(bool checked) +{ + if (checked && m_Settings->OpenCL()) + { + m_Settings->OpenCL(false); + ShutdownAndRecreateFromOptions(); + } +} + +/// +/// Called when the OpenCL render option on the toolbar is clicked. +/// +/// Check state, action only taken if true. +void Fractorium::OnActionCL(bool checked) +{ + if (checked && !m_Settings->OpenCL()) + { + m_Settings->OpenCL(true); + ShutdownAndRecreateFromOptions(); + } +} + +/// +/// Called when the single precision render option on the toolbar is clicked. +/// +/// Check state, action only taken if true. +void Fractorium::OnActionSP(bool checked) +{ + if (checked && m_Settings->Double()) + { + m_Settings->Double(false); + ShutdownAndRecreateFromOptions(); + } +} + +/// +/// Called when the double precision render option on the toolbar is clicked. +/// +/// Check state, action only taken if true. +void Fractorium::OnActionDP(bool checked) +{ + if (checked && !m_Settings->Double()) + { + m_Settings->Double(true); + ShutdownAndRecreateFromOptions(); + } +} + +/// +/// Sync options data to the check state of the toolbar buttons. +/// This does not trigger a clicked() event. +/// +void Fractorium::SyncOptionsToToolbar() +{ + if (m_Settings->OpenCL()) + { + ui.ActionCpu->setChecked(false); + ui.ActionCL->setChecked(true); + } + else + { + ui.ActionCpu->setChecked(true); + ui.ActionCL->setChecked(false); + } + + if (m_Settings->Double()) + { + ui.ActionSP->setChecked(false); + ui.ActionDP->setChecked(true); + } + else + { + ui.ActionSP->setChecked(true); + ui.ActionDP->setChecked(false); + } +} \ No newline at end of file diff --git a/Source/Fractorium/FractoriumXformsVariations.cpp b/Source/Fractorium/FractoriumXformsVariations.cpp index 1fddc41..93e2a68 100644 --- a/Source/Fractorium/FractoriumXformsVariations.cpp +++ b/Source/Fractorium/FractoriumXformsVariations.cpp @@ -209,7 +209,6 @@ void FractoriumEmberController::VariationSpinBoxValueChanged(double d)//Would { if (xformParVar->SetParamVal(sender->ParamName().c_str(), d)) { - FillSummary(); UpdateRender(); } } @@ -263,7 +262,6 @@ void FractoriumEmberController::VariationSpinBoxValueChanged(double d)//Would } } - FillSummary(); UpdateRender(); } } diff --git a/Source/Fractorium/OptionsDialog.cpp b/Source/Fractorium/OptionsDialog.cpp index 6a67406..4048c4c 100644 --- a/Source/Fractorium/OptionsDialog.cpp +++ b/Source/Fractorium/OptionsDialog.cpp @@ -149,6 +149,35 @@ void FractoriumOptionsDialog::OnPlatformComboCurrentIndexChanged(int index) /// Not called if cancelled or closed with the X. /// void FractoriumOptionsDialog::accept() +{ + GuiToData(); + QDialog::accept(); +} + +/// +/// Restore all GUI items to what was originally in the settings object. +/// Called when the user clicks cancel or closes with the X. +/// +void FractoriumOptionsDialog::reject() +{ + DataToGui(); + QDialog::reject(); +} + +/// +/// Copy the state of the map to the checkboxes and show the dialog. +/// +/// Event, passed to base. +void FractoriumOptionsDialog::showEvent(QShowEvent* e) +{ + DataToGui(); + QDialog::showEvent(e); +} + +/// +/// Copy the state of the Gui to the settings object. +/// +void FractoriumOptionsDialog::GuiToData() { //Interactive rendering. m_Settings->EarlyClip(EarlyClip()); @@ -176,15 +205,12 @@ void FractoriumOptionsDialog::accept() m_Settings->Id(m_IdEdit->text()); m_Settings->Url(m_UrlEdit->text()); m_Settings->Nick(m_NickEdit->text()); - - QDialog::accept(); } /// -/// Restore all GUI items to what was originally in the settings object. -/// Called when the user clicks cancel or closes with the X. +/// Copy the state of the settings object to the Gui. /// -void FractoriumOptionsDialog::reject() +void FractoriumOptionsDialog::DataToGui() { //Interactive rendering. ui.EarlyClipCheckBox->setChecked(m_Settings->EarlyClip()); @@ -212,6 +238,4 @@ void FractoriumOptionsDialog::reject() m_IdEdit->setText(m_Settings->Id()); m_UrlEdit->setText(m_Settings->Url()); m_NickEdit->setText(m_Settings->Nick()); - - QDialog::reject(); -} +} \ No newline at end of file diff --git a/Source/Fractorium/OptionsDialog.h b/Source/Fractorium/OptionsDialog.h index de74bb1..2e6eeb9 100644 --- a/Source/Fractorium/OptionsDialog.h +++ b/Source/Fractorium/OptionsDialog.h @@ -32,6 +32,9 @@ public slots: virtual void accept() override; virtual void reject() override; +protected: + virtual void showEvent(QShowEvent* e) override; + private: bool EarlyClip(); bool YAxisUp(); @@ -45,6 +48,8 @@ private: uint PlatformIndex(); uint DeviceIndex(); uint ThreadCount(); + void DataToGui(); + void GuiToData(); Ui::OptionsDialog ui; OpenCLWrapper m_Wrapper; diff --git a/Source/Fractorium/VariationsDialog.cpp b/Source/Fractorium/VariationsDialog.cpp index 5092d7c..b5c786e 100644 --- a/Source/Fractorium/VariationsDialog.cpp +++ b/Source/Fractorium/VariationsDialog.cpp @@ -26,23 +26,6 @@ FractoriumVariationsDialog::FractoriumVariationsDialog(FractoriumSettings* setti connect(ui.SelectAllButton, SIGNAL(clicked(bool)), this, SLOT(OnSelectAllButtonClicked(bool)), Qt::QueuedConnection); connect(ui.InvertSelectionButton, SIGNAL(clicked(bool)), this, SLOT(OnInvertSelectionButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SelectNoneButton, SIGNAL(clicked(bool)), this, SLOT(OnSelectNoneButtonClicked(bool)), Qt::QueuedConnection); - connect(ui.ButtonBox, SIGNAL(accepted()), this, SLOT(Accept())); -} - -/// -/// Copy the values of the checkboxes to the map. -/// -void FractoriumVariationsDialog::SyncSettings() -{ - QMap m; - - ForEachCell([&](QTableWidgetItem* cb) - { - if (!cb->text().isEmpty()) - m[cb->text()] = cb->checkState() == Qt::CheckState::Checked; - }); - - m_Settings->Variations(m); } /// @@ -85,6 +68,32 @@ void FractoriumVariationsDialog::ForEachSelectedCell(std::functionmodel()->layoutChanged(); } +/// +/// Copy the values of the checkboxes to the map. +/// +void FractoriumVariationsDialog::SyncSettings() +{ + QMap m; + + ForEachCell([&](QTableWidgetItem* cb) + { + if (!cb->text().isEmpty()) + m[cb->text()] = cb->checkState() == Qt::CheckState::Checked; + }); + + m_Settings->Variations(m); +} + +/// +/// Return a const reference to the map. +/// This will contains the state of the checkboxes after +/// the user clicks ok. +/// +const QMap& FractoriumVariationsDialog::Map() +{ + return m_Vars; +} + /// /// Check all of the checkboxes. /// @@ -172,19 +181,21 @@ void FractoriumVariationsDialog::OnVariationsTableItemChanged(QTableWidgetItem* /// Called when the user clicks ok. /// Copy the state of the checkboxes to the map. /// -void FractoriumVariationsDialog::Accept() +void FractoriumVariationsDialog::accept() { - CheckBoxesToMap(); + GuiToData(); + QDialog::accept(); } /// -/// Return a const reference to the map. -/// This will contains the state of the checkboxes after -/// the user clicks ok. +/// Called when the user clicks cancel. +/// Reset the state of the the checkboxes to what the map previously was +/// when the dialog was shown. /// -const QMap& FractoriumVariationsDialog::Map() +void FractoriumVariationsDialog::reject() { - return m_Vars; + DataToGui(); + QDialog::reject(); } /// @@ -193,10 +204,34 @@ const QMap& FractoriumVariationsDialog::Map() /// Event, passed to base. void FractoriumVariationsDialog::showEvent(QShowEvent* e) { - MapToCheckBoxes(); + DataToGui(); QDialog::showEvent(e); } +/// +/// Copy the values in the map to the state of the checkboxes. +/// +void FractoriumVariationsDialog::DataToGui() +{ + ForEachCell([&](QTableWidgetItem* cb) + { + if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) + SetCheckFromMap(cb, var); + }); +} + +/// +/// Copy the state of the checkboxes to the map. +/// +void FractoriumVariationsDialog::GuiToData() +{ + ForEachCell([&](QTableWidgetItem* cb) + { + if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) + m_Vars[cb->text()] = (cb->checkState() == Qt::Checked); + }); +} + /// /// Set the state of the passed in table item checkbox based on the boolean contained /// in the map for the passed in variation. @@ -216,27 +251,3 @@ void FractoriumVariationsDialog::SetCheckFromMap(QTableWidgetItem* cb, const Var cb->setCheckState(chk ? Qt::Checked : Qt::Unchecked); } } - -/// -/// Copy the values in the map to the state of the checkboxes. -/// -void FractoriumVariationsDialog::MapToCheckBoxes() -{ - ForEachCell([&](QTableWidgetItem* cb) - { - if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) - SetCheckFromMap(cb, var); - }); -} - -/// -/// Copy the state of the checkboxes to the map. -/// -void FractoriumVariationsDialog::CheckBoxesToMap() -{ - ForEachCell([&](QTableWidgetItem* cb) - { - if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) - m_Vars[cb->text()] = (cb->checkState() == Qt::Checked); - }); -} diff --git a/Source/Fractorium/VariationsDialog.h b/Source/Fractorium/VariationsDialog.h index cb3f337..9d58516 100644 --- a/Source/Fractorium/VariationsDialog.h +++ b/Source/Fractorium/VariationsDialog.h @@ -20,24 +20,25 @@ class FractoriumVariationsDialog : public QDialog Q_OBJECT public: FractoriumVariationsDialog(FractoriumSettings* settings, QWidget* p = nullptr, Qt::WindowFlags f = nullptr); - const QMap& Map(); void ForEachCell(std::function func); void ForEachSelectedCell(std::function func); void SyncSettings(); + const QMap& Map(); public slots: void OnSelectAllButtonClicked(bool checked); void OnInvertSelectionButtonClicked(bool checked); void OnSelectNoneButtonClicked(bool checked); - void Accept(); void OnVariationsTableItemChanged(QTableWidgetItem* item); + virtual void accept() override; + virtual void reject() override; protected: virtual void showEvent(QShowEvent* e) override; private: - void MapToCheckBoxes(); - void CheckBoxesToMap(); + void DataToGui(); + void GuiToData(); void Populate(); void SetCheckFromMap(QTableWidgetItem* cb, const Variation* var); VariationList m_VariationList;