diff --git a/Builds/MSVC/VS2013/Fractorium.vcxproj b/Builds/MSVC/VS2013/Fractorium.vcxproj
index d4c16dc..5a78d0e 100644
--- a/Builds/MSVC/VS2013/Fractorium.vcxproj
+++ b/Builds/MSVC/VS2013/Fractorium.vcxproj
@@ -361,6 +361,12 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -447,6 +453,12 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -519,6 +531,12 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -776,6 +794,32 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/CurvesGraphicsView.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing DoubleSpinBoxTableItemDelegate.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing DoubleSpinBoxTableItemDelegate.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing DoubleSpinBoxTableItemDelegate.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing DoubleSpinBoxTableItemDelegate.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing DoubleSpinBoxTableItemDelegate.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing DoubleSpinBoxTableItemDelegate.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+
diff --git a/Builds/MSVC/VS2013/Fractorium.vcxproj.filters b/Builds/MSVC/VS2013/Fractorium.vcxproj.filters
index 853fb83..bb3dac8 100644
--- a/Builds/MSVC/VS2013/Fractorium.vcxproj.filters
+++ b/Builds/MSVC/VS2013/Fractorium.vcxproj.filters
@@ -247,6 +247,15 @@
MainWindows
+
+ Generated Files\Debug
+
+
+ Generated Files\Release
+
+
+ Generated Files\ReleaseNvidia
+
@@ -347,6 +356,9 @@
Widgets
+
+ Widgets
+
diff --git a/Builds/QtCreator/Fractorium/Fractorium.pro b/Builds/QtCreator/Fractorium/Fractorium.pro
index 813a15c..3e0a3be 100644
--- a/Builds/QtCreator/Fractorium/Fractorium.pro
+++ b/Builds/QtCreator/Fractorium/Fractorium.pro
@@ -73,7 +73,8 @@ HEADERS += \
../../../Source/EmberCommon/EmberCommon.h \
../../../Source/EmberCommon/JpegUtils.h \
../../../Source/EmberCommon/EmberCommonPch.h \
- ../../../Source/Fractorium/FractoriumCommon.h
+ ../../../Source/Fractorium/FractoriumCommon.h \
+ ../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h
FORMS += \
../../../Source/Fractorium/AboutDialog.ui \
diff --git a/Source/Fractorium/DoubleSpinBox.cpp b/Source/Fractorium/DoubleSpinBox.cpp
index 17115b5..d9fe1f1 100644
--- a/Source/Fractorium/DoubleSpinBox.cpp
+++ b/Source/Fractorium/DoubleSpinBox.cpp
@@ -23,7 +23,6 @@ DoubleSpinBox::DoubleSpinBox(QWidget* p, int h, double step)
m_SmallStep = step / 10.0;
setSingleStep(step);
setFrame(false);
- //setAttribute(Qt::WA_PaintOnScreen);
setButtonSymbols(QAbstractSpinBox::NoButtons);
setFocusPolicy(Qt::StrongFocus);
setMinimumHeight(h);//setGeometry() has no effect, so must set both of these instead.
diff --git a/Source/Fractorium/DoubleSpinBoxTableItemDelegate.h b/Source/Fractorium/DoubleSpinBoxTableItemDelegate.h
new file mode 100644
index 0000000..5830b6c
--- /dev/null
+++ b/Source/Fractorium/DoubleSpinBoxTableItemDelegate.h
@@ -0,0 +1,91 @@
+#pragma once
+
+#include "FractoriumPch.h"
+#include "DoubleSpinBox.h"
+
+///
+/// DoubleSpinBoxTableItemDelegate class.
+///
+
+///
+/// Used for showing a DoubleSpinBox on the cell of a QTableView when the user enters the cell to edit it.
+///
+class DoubleSpinBoxTableItemDelegate
+ : public QItemDelegate
+{
+ Q_OBJECT
+public:
+ ///
+ /// Constructor that assigns a DoubleSpinBox.
+ ///
+ /// The DoubleSpinBox to use throughought the life of the object
+ /// The parent widget. Default: nullptr.
+ explicit DoubleSpinBoxTableItemDelegate(DoubleSpinBox* spinBox, QObject* parent = nullptr)
+ : QItemDelegate(parent),
+ m_SpinBox(spinBox)
+ {
+ }
+
+ ///
+ /// Re-parent and return the DoubleSpinBox to display when the user clicks on a cell and it enters edit mode.
+ /// The re-parenting is done so that the DoubleSpinBox appears directly on top of the cell.
+ ///
+ /// The parent cell
+ /// Unused
+ /// unused
+ /// The DoubleSpinBox member
+ QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
+ {
+ m_SpinBox->setParent(parent);
+
+ return m_SpinBox;
+ }
+
+ ///
+ /// Prevent DoubleSpinBox control from being destroyed when the cell loses focus.
+ ///
+ /// Unused
+ /// Unused
+ void destroyEditor(QWidget* editor, const QModelIndex& index) const override
+ {
+ }
+
+ ///
+ /// Set the value of the DoubleSpinBox as well as its tableindex property.
+ ///
+ /// Unused
+ /// Unused
+ void setEditorData(QWidget* editor, const QModelIndex& index) const override
+ {
+ QPoint p(index.row(), index.column());
+ auto value = index.model()->data(index, Qt::EditRole).toDouble();
+
+ m_SpinBox->setProperty("tableindex", p);
+ m_SpinBox->setValue(value);
+ }
+
+ ///
+ /// Set the cell in the model to the value of the DoubleSpinBox.
+ ///
+ /// Unused
+ /// The model whose value will be set
+ /// The cell index of the model
+ void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override
+ {
+ model->setData(index, m_SpinBox->value(), Qt::EditRole);
+ }
+
+ ///
+ /// Set the geometry of the DoubleSpinBox to match the cell being edited.
+ ///
+ /// The DoubleSpinBox member
+ /// Contains the rectangle to be used for the geometry of the DoubleSpinBox
+ /// Unused
+ void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override
+ {
+ editor->setGeometry(option.rect);
+ }
+
+private:
+ DoubleSpinBox* m_SpinBox;
+};
\ No newline at end of file
diff --git a/Source/Fractorium/Fractorium.cpp b/Source/Fractorium/Fractorium.cpp
index 43ed366..9cf142a 100644
--- a/Source/Fractorium/Fractorium.cpp
+++ b/Source/Fractorium/Fractorium.cpp
@@ -1,6 +1,11 @@
#include "FractoriumPch.h"
#include "Fractorium.h"
+// X11 headers on Linux define this, causing build errors.
+#ifdef KeyRelease
+ #undef KeyRelease
+#endif
+
///
/// Constructor that initializes the entire program.
/// The setup process is very lengthy because it requires many custom modifications
@@ -584,16 +589,15 @@ QString Fractorium::SetupSaveFolderDialog()
///
/// Thin wrapper around QMessageBox::critical() to allow it to be invoked from another thread.
///
+/// The title of the message box
+/// The text displayed on the message box
+/// True if running on another thread, else false. Default: false.
void Fractorium::ShowCritical(const QString& title, const QString& text, bool invokeRequired)
{
if (!invokeRequired)
- {
QMessageBox::critical(this, title, text);
- }
else
- {
QMetaObject::invokeMethod(this, "ShowCritical", Qt::QueuedConnection, Q_ARG(const QString&, title), Q_ARG(const QString&, text), Q_ARG(bool, false));
- }
}
///
@@ -730,33 +734,58 @@ void Fractorium::SetTabOrders()
/// If shift is held down, reverse the logic.
/// Resets the rendering process.
///
+/// The QTableWidget or QTableView whose row will be toggled
/// The index of the row that was double clicked
-void Fractorium::ToggleTableRow(TableWidget* table, int logicalIndex)
+void Fractorium::ToggleTableRow(QTableView* table, int logicalIndex)
{
bool allZero = true;
- int cols = table->columnCount();
+ auto model = table->model();
+ int cols = model->columnCount();
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
+ auto tableWidget = dynamic_cast(table);
- for (int i = 0; i < cols; i++)
+ if (tableWidget)
{
- if (auto* spinBox = dynamic_cast(table->cellWidget(logicalIndex, i)))
+ for (int i = 0; i < cols; i++)
{
- if (!IsNearZero(spinBox->value()))
+ if (auto* spinBox = dynamic_cast(tableWidget->cellWidget(logicalIndex, i)))
+ {
+ if (!IsNearZero(spinBox->value()))
+ {
+ allZero = false;
+ break;
+ }
+ }
+ }
+
+ if (shift)
+ allZero = !allZero;
+
+ double val = allZero ? 1.0 : 0.0;
+
+ for (int i = 0; i < cols; i++)
+ if (auto* spinBox = dynamic_cast(tableWidget->cellWidget(logicalIndex, i)))
+ spinBox->setValue(val);
+ }
+ else
+ {
+ for (int i = 0; i < cols; i++)
+ {
+ if (!IsNearZero(model->data(model->index(logicalIndex, i, QModelIndex())).toDouble()))
{
allZero = false;
break;
}
}
+
+ if (shift)
+ allZero = !allZero;
+
+ double val = allZero ? 1.0 : 0.0;
+
+ for (int i = 0; i < cols; i++)
+ model->setData(model->index(logicalIndex, i), val, Qt::EditRole);
}
-
- if (shift)
- allZero = !allZero;
-
- double val = allZero ? 1.0 : 0.0;
-
- for (int i = 0; i < cols; i++)
- if (auto* spinBox = dynamic_cast(table->cellWidget(logicalIndex, i)))
- spinBox->setValue(val);
}
///
@@ -766,82 +795,61 @@ void Fractorium::ToggleTableRow(TableWidget* table, int logicalIndex)
/// If shift is held down, reverse the logic.
/// Resets the rendering process.
///
+/// The QTableWidget or QTableView whose column will be toggled
/// The index of the column that was double clicked
-void Fractorium::ToggleTableCol(TableWidget* table, int logicalIndex)
+void Fractorium::ToggleTableCol(QTableView* table, int logicalIndex)
{
bool allZero = true;
- int rows = table->rowCount();
+ auto model = table->model();
+ int rows = model->rowCount();
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
+
+ auto tableWidget = dynamic_cast(table);
- for (int i = 0; i < rows; i++)
+ if (tableWidget)
{
- if (auto* spinBox = dynamic_cast(table->cellWidget(i, logicalIndex)))
+ for (int i = 0; i < rows; i++)
{
- if (!IsNearZero(spinBox->value()))
+ if (auto* spinBox = dynamic_cast(tableWidget->cellWidget(i, logicalIndex)))
+ {
+ if (!IsNearZero(spinBox->value()))
+ {
+ allZero = false;
+ break;
+ }
+ }
+ }
+
+ if (shift)
+ allZero = !allZero;
+
+ double val = allZero ? 1.0 : 0.0;
+
+ for (int i = 0; i < rows; i++)
+ if (auto* spinBox = dynamic_cast(tableWidget->cellWidget(i, logicalIndex)))
+ spinBox->setValue(val);
+ }
+ else
+ {
+ for (int i = 0; i < rows; i++)
+ {
+ if (!IsNearZero(model->data(model->index(i, logicalIndex, QModelIndex())).toDouble()))
{
allZero = false;
break;
}
}
+
+ if (shift)
+ allZero = !allZero;
+
+ double val = allZero ? 1.0 : 0.0;
+
+ for (int i = 0; i < rows; i++)
+ model->setData(model->index(i, logicalIndex), val, Qt::EditRole);
}
-
- if (shift)
- allZero = !allZero;
-
- double val = allZero ? 1.0 : 0.0;
-
- for (int i = 0; i < rows; i++)
- if (auto* spinBox = dynamic_cast(table->cellWidget(i, logicalIndex)))
- spinBox->setValue(val);
}
-///
-/// This is no longer needed and was used to compensate for a different bug
-/// however the code is interesting, so keep it around for possible future use.
-/// This was used to correct a rotation bug where matrix rotation comes out in the wrong direction
-/// if x1, y1 (a & d) are on the left side of the line from 0,0 to
-/// x2, y2 (b, e). In that case, the angle must be flipped. In order
-/// to determine which side of the line it's on, create a mat2
-/// and find its determinant. Values > 0 are on the left side of the line.
-///
-/// The affine.
-///
-int Fractorium::FlipDet(Affine2D& affine)
-{
- float x1 = affine.A();
- float y1 = affine.D();
- float x2 = affine.B();
- float y2 = affine.E();
-
- //Just make the other end of the line be the center of the circle.
- glm::mat2 mat( 0 - x1, 0 - y1,//Col 0.
- x2 - x1, y2 - y1);//Col 1.
-
- return (glm::determinant(mat) > 0) ? -1 : 1;
-}
-
-//template//See note at the end of Fractorium.h
-//void Fractorium::SetupSpinner(QTableWidget* table, const QObject* receiver, int& row, int col, spinType*& spinBox, int height, valType min, valType max, valType step, const char* signal, const char* slot, bool incRow, valType val, valType doubleClickZero, valType doubleClickNonZero)
-//{
-// spinBox = new spinType(table, height, step);
-// spinBox->setRange(min, max);
-// spinBox->setValue(val);
-// table->setCellWidget(row, col, spinBox);
-//
-// if (string(signal) != "" && string(slot) != "")
-// connect(spinBox, signal, receiver, slot, connectionType);
-//
-// if (doubleClickNonZero != -999 && doubleClickZero != -999)
-// {
-// spinBox->DoubleClick(true);
-// spinBox->DoubleClickZero((valType)doubleClickZero);
-// spinBox->DoubleClickNonZero((valType)doubleClickNonZero);
-// }
-//
-// if (incRow)
-// row++;
-//}
-
template class FractoriumEmberController;
#ifdef DO_DOUBLE
diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h
index f4d8d51..93465d9 100644
--- a/Source/Fractorium/Fractorium.h
+++ b/Source/Fractorium/Fractorium.h
@@ -11,6 +11,7 @@
#include "OptionsDialog.h"
#include "AboutDialog.h"
#include "CurvesGraphicsView.h"
+#include "DoubleSpinBoxTableItemDelegate.h"
///
/// Fractorium class.
@@ -258,6 +259,7 @@ public slots:
void OnRandomXaosButtonClicked(bool checked);
void OnXaosRowDoubleClicked(int logicalIndex);
void OnXaosColDoubleClicked(int logicalIndex);
+ void OnXaosTableModelDataChanged(const QModelIndex& indexA, const QModelIndex& indexB);
//Palette.
void OnPaletteFilenameComboChanged(const QString& text);
@@ -282,7 +284,6 @@ public:
static void SetupAffineSpinner(QTableWidget* table, const QObject* receiver, int row, int col, DoubleSpinBox*& spinBox, int height, double min, double max, double step, double prec, const char* signal, const char* slot);
static void SetupCombo(QTableWidget* table, const QObject* receiver, int& row, int col, StealthComboBox*& comboBox, const vector& vals, const char* signal, const char* slot, Qt::ConnectionType connectionType = Qt::QueuedConnection);
static void SetFixedTableHeader(QHeaderView* header, QHeaderView::ResizeMode mode = QHeaderView::Fixed);
- static int FlipDet(Affine2D& affine);
protected:
virtual bool eventFilter(QObject* o, QEvent* e) override;
@@ -306,8 +307,8 @@ private:
void InitLibraryUI();
void SetTabOrders();
- void ToggleTableRow(TableWidget* table, int logicalIndex);
- void ToggleTableCol(TableWidget* table, int logicalIndex);
+ void ToggleTableRow(QTableView* table, int logicalIndex);
+ void ToggleTableCol(QTableView* table, int logicalIndex);
//Embers.
bool HaveFinal();
@@ -421,6 +422,11 @@ private:
DoubleSpinBox* m_PreSpins[6];
DoubleSpinBox* m_PostSpins[6];
+ //Xaos.
+ DoubleSpinBox* m_XaosSpinBox;
+ QStandardItemModel* m_XaosTableModel;
+ DoubleSpinBoxTableItemDelegate* m_XaosTableItemDelegate;
+
//Palette.
SpinBox* m_PaletteHueSpin;
SpinBox* m_PaletteSaturationSpin;
@@ -457,6 +463,3 @@ private:
unique_ptr m_Controller;
Ui::FractoriumClass ui;
};
-
-//template void Fractorium::SetupSpinner (QTableWidget* table, const QObject* receiver, int& row, int col, SpinBox*& spinBox, int height, int min, int max, int step, const char* signal, const char* slot, bool incRow, int val, int doubleClickZero, int doubleClickNonZero);
-//template void Fractorium::SetupSpinner(QTableWidget* table, const QObject* receiver, int& row, int col, DoubleSpinBox*& spinBox, int height, double min, double max, double step, const char* signal, const char* slot, bool incRow, double val, double doubleClickZero, double doubleClickNonZero);
diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui
index 12e5630..84d12aa 100644
--- a/Source/Fractorium/Fractorium.ui
+++ b/Source/Fractorium/Fractorium.ui
@@ -2644,8 +2644,8 @@ SpinBox
0
0
- 245
- 747
+ 118
+ 618
@@ -4301,8 +4301,8 @@ SpinBox
0
0
- 245
- 682
+ 133
+ 52
@@ -4717,7 +4717,7 @@ SpinBox
4
-
-
+
0
@@ -4766,13 +4766,13 @@ SpinBox
QAbstractScrollArea::AdjustToContents
- false
+ true
- QAbstractItemView::NoEditTriggers
+ QAbstractItemView::CurrentChanged|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked
- false
+ true
false
@@ -4784,7 +4784,7 @@ SpinBox
false
- QAbstractItemView::NoSelection
+ QAbstractItemView::SingleSelection
QAbstractItemView::ScrollPerPixel
@@ -4804,14 +4804,8 @@ SpinBox
false
-
- 3
-
-
- false
-
- true
+ false
35
@@ -4822,14 +4816,8 @@ SpinBox
35
-
- false
-
-
- false
-
- true
+ false
22
@@ -4840,44 +4828,6 @@ SpinBox
22
-
- false
-
-
-
-
-
-
-
-
- F1
-
-
-
-
- F2
-
-
-
-
- F3
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
-
@@ -6181,7 +6131,7 @@ SpinBox
CurvesGraphicsView
QGraphicsView
-
+
diff --git a/Source/Fractorium/FractoriumEmberController.h b/Source/Fractorium/FractoriumEmberController.h
index 5ac75de..25cce67 100644
--- a/Source/Fractorium/FractoriumEmberController.h
+++ b/Source/Fractorium/FractoriumEmberController.h
@@ -189,7 +189,7 @@ public:
//Xaos.
virtual void FillXaos() { }
virtual QString MakeXaosNameString(uint i) { return ""; }
- virtual void XaosChanged(DoubleSpinBox* sender) { }
+ virtual void XaosChanged(int x, int y, double val) { }
virtual void ClearXaos() { }
virtual void RandomXaos() { }
@@ -422,7 +422,7 @@ public:
//Xforms Xaos.
virtual void FillXaos() override;
virtual QString MakeXaosNameString(uint i) override;
- virtual void XaosChanged(DoubleSpinBox* sender) override;
+ virtual void XaosChanged(int x, int y, double val) override;
virtual void ClearXaos() override;
virtual void RandomXaos() override;
diff --git a/Source/Fractorium/FractoriumPch.h b/Source/Fractorium/FractoriumPch.h
index bfb9f72..c9fba54 100644
--- a/Source/Fractorium/FractoriumPch.h
+++ b/Source/Fractorium/FractoriumPch.h
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
diff --git a/Source/Fractorium/FractoriumXaos.cpp b/Source/Fractorium/FractoriumXaos.cpp
index df3efce..3235056 100644
--- a/Source/Fractorium/FractoriumXaos.cpp
+++ b/Source/Fractorium/FractoriumXaos.cpp
@@ -6,15 +6,25 @@
///
void Fractorium::InitXaosUI()
{
- ui.XaosTable->verticalHeader()->setVisible(true);
- ui.XaosTable->horizontalHeader()->setVisible(true);
- ui.XaosTable->verticalHeader()->setSectionsClickable(true);
- ui.XaosTable->horizontalHeader()->setSectionsClickable(true);
+ int spinHeight = 20;
+ ui.XaosTableView->verticalHeader()->setSectionsClickable(true);
+ ui.XaosTableView->horizontalHeader()->setSectionsClickable(true);
+
+ m_XaosSpinBox = new DoubleSpinBox(nullptr, spinHeight, 0.1);
+ m_XaosSpinBox->setFixedWidth(35);
+ m_XaosSpinBox->DoubleClick(true);
+ m_XaosSpinBox->DoubleClickZero(1);
+ m_XaosSpinBox->DoubleClickNonZero(0);
+
+ m_XaosTableModel = nullptr;
+ m_XaosTableItemDelegate = new DoubleSpinBoxTableItemDelegate(m_XaosSpinBox, this);
+
+ connect(m_XaosSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnXaosChanged(double)), Qt::QueuedConnection);
connect(ui.ClearXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnClearXaosButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.RandomXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnRandomXaosButtonClicked(bool)), Qt::QueuedConnection);
- connect(ui.XaosTable->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosRowDoubleClicked(int)), Qt::QueuedConnection);
- connect(ui.XaosTable->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosColDoubleClicked(int)), Qt::QueuedConnection);
+ connect(ui.XaosTableView->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosRowDoubleClicked(int)), Qt::QueuedConnection);
+ connect(ui.XaosTableView->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosColDoubleClicked(int)), Qt::QueuedConnection);
}
///
@@ -25,11 +35,14 @@ void FractoriumEmberController::FillXaos()
{
for (int i = 0, count = int(XformCount()); i < count; i++)
{
- auto* xform = m_Ember.GetXform(i);
-
- for (int j = 0; j < count; j++)
- if (auto* spinBox = dynamic_cast(m_Fractorium->ui.XaosTable->cellWidget(i, j)))
- spinBox->SetValueStealth(xform->Xaos(j));
+ if (auto xform = m_Ember.GetXform(i))
+ {
+ for (int j = 0; j < count; j++)
+ {
+ QModelIndex index = m_Fractorium->m_XaosTableModel->index(i, j, QModelIndex());
+ m_Fractorium->m_XaosTableModel->setData(index, xform->Xaos(j));
+ }
+ }
}
}
@@ -67,22 +80,34 @@ QString FractoriumEmberController::MakeXaosNameString(uint i)
///
/// Set the xaos value.
/// Called when any xaos spinner is changed.
+/// It actually gets called multiple times as the user clicks around the
+/// xaos table due to how QTableView passes events to and from its model.
+/// To filter out spurrious events, the value is checked against the existing
+/// xaos value.
/// Resets the rendering process.
///
/// The DoubleSpinBox that triggered this event
template
-void FractoriumEmberController::XaosChanged(DoubleSpinBox* sender)
+void FractoriumEmberController::XaosChanged(int x, int y, double val)
{
- auto p = sender->property("tableindex").toPoint();
-
- if (auto* xform = m_Ember.GetXform(p.x()))
- Update([&] { xform->SetXaos(p.y(), sender->value()); });
+ if (Xform* xform = m_Ember.GetXform(x))
+ if (!IsClose(val, xform->Xaos(y), 1e-10))//Ensure it actually changed.
+ Update([&] { xform->SetXaos(y, val); });
}
void Fractorium::OnXaosChanged(double d)
{
if (auto* senderSpinBox = dynamic_cast(this->sender()))
- m_Controller->XaosChanged(senderSpinBox);
+ {
+ auto p = senderSpinBox->property("tableindex").toPoint();
+
+ m_Controller->XaosChanged(p.x(), p.y(), d);
+ }
+}
+
+void Fractorium::OnXaosTableModelDataChanged(const QModelIndex& indexA, const QModelIndex& indexB)
+{
+ m_Controller->XaosChanged(indexA.row(), indexA.column(), indexA.data().toDouble());
}
///
@@ -90,57 +115,37 @@ void Fractorium::OnXaosChanged(double d)
///
void Fractorium::FillXaosTable()
{
- int spinHeight = 20;
int count = int(m_Controller->XformCount());
- QWidget* w = nullptr;
- QString lbl("lbl");
+ QStringList hl, vl;
+ auto oldModel = m_XaosTableModel;
- ui.XaosTable->blockSignals(true);
- ui.XaosTable->setRowCount(count);//This will grow or shrink the number of rows and call the destructor for previous DoubleSpinBoxes.
- ui.XaosTable->setColumnCount(count);
+ hl.reserve(count);
+ vl.reserve(count);
+ m_XaosTableModel = new QStandardItemModel(count, count, this);
+ connect(m_XaosTableModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), SLOT(OnXaosTableModelDataChanged(QModelIndex, QModelIndex)));
+ ui.XaosTableView->blockSignals(true);
for (int i = 0; i < count; i++)
{
- for (int j = 0; j < count; j++)
- {
- QPoint p(i, j);
- DoubleSpinBox* spinBox = new DoubleSpinBox(ui.XaosTable, spinHeight, 0.1);
+ auto s = QString::number(i + 1);
- spinBox->setFixedWidth(35);
- spinBox->DoubleClick(true);
- spinBox->DoubleClickZero(1);
- spinBox->DoubleClickNonZero(0);
- spinBox->setProperty("tableindex", p);
- ui.XaosTable->setCellWidget(i, j, spinBox);
-
- auto wp = ui.XaosTable->item(i, j);
-
- if (wp)
- wp->setTextAlignment(Qt::AlignCenter);
-
- connect(spinBox, SIGNAL(valueChanged(double)), this, SLOT(OnXaosChanged(double)), Qt::QueuedConnection);
-
- if (i == 0 && j == 0)
- w = spinBox;
- else
- w = SetTabOrder(this, w, spinBox);
- }
+ hl.push_back("F" + s);
+ vl.push_back("T" + s);
}
+
+ m_XaosTableModel->setHorizontalHeaderLabels(hl);
+ m_XaosTableModel->setVerticalHeaderLabels(vl);
+
+ ui.XaosTableView->setModel(m_XaosTableModel);
+ ui.XaosTableView->setItemDelegate(m_XaosTableItemDelegate);
+ ui.XaosTableView->resizeRowsToContents();
+ ui.XaosTableView->resizeColumnsToContents();
+
+ SetTabOrder(this, ui.ClearXaosButton, ui.RandomXaosButton);
+ ui.XaosTableView->blockSignals(false);
- for (int i = 0; i < count; i++)
- {
- ui.XaosTable->setHorizontalHeaderItem(i, new QTableWidgetItem("F" + QString::number(i + 1)));
- ui.XaosTable->setVerticalHeaderItem(i, new QTableWidgetItem("T" + QString::number(i + 1)));
- ui.XaosTable->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- ui.XaosTable->verticalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
-
- ui.XaosTable->resizeRowsToContents();
- ui.XaosTable->resizeColumnsToContents();
-
- w = SetTabOrder(this, w, ui.ClearXaosButton);
- w = SetTabOrder(this, w, ui.RandomXaosButton);
- ui.XaosTable->blockSignals(false);
+ if (oldModel)
+ delete oldModel;
}
///
@@ -193,7 +198,7 @@ void Fractorium::OnRandomXaosButtonClicked(bool checked) { m_Controller->RandomX
/// The index of the row that was double clicked
void Fractorium::OnXaosRowDoubleClicked(int logicalIndex)
{
- ToggleTableRow(ui.XaosTable, logicalIndex);
+ ToggleTableRow(ui.XaosTableView, logicalIndex);
}
///
@@ -203,7 +208,7 @@ void Fractorium::OnXaosRowDoubleClicked(int logicalIndex)
/// The index of the column that was double clicked
void Fractorium::OnXaosColDoubleClicked(int logicalIndex)
{
- ToggleTableCol(ui.XaosTable, logicalIndex);
+ ToggleTableCol(ui.XaosTableView, logicalIndex);
}
template class FractoriumEmberController;