--Code changes

-Convert all enums to class enum to be consistent with C++11 style.
 -Convert some if/else statements in filter classes to case statements.
 -Add overloaded stream operators to print various enums.
This commit is contained in:
mfeemster
2016-01-04 16:50:15 -08:00
parent c8e2355ec2
commit f5d0be5e5d
40 changed files with 1483 additions and 2041 deletions

View File

@ -10,7 +10,7 @@ class EllipseItem;
/// <summary>
/// Enumeration used for setting values on a specific curve.
/// </summary>
enum CurveIndex
enum class CurveIndex : et
{
ALL,
RED,
@ -82,14 +82,13 @@ public:
/// <param name="pointIndex">The point index within the curve</param>
/// <param name="viewParent">The graphics view this point is displayed on</param>
/// <param name="p">The parent widget of this item</param>
EllipseItem(const QRectF &rect, int curveIndex, int pointIndex, CurvesGraphicsView* viewParent, QGraphicsItem *parent = 0)
EllipseItem(const QRectF& rect, int curveIndex, int pointIndex, CurvesGraphicsView* viewParent, QGraphicsItem* parent = 0)
: QGraphicsEllipseItem(rect, parent)
{
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemIsMovable);
setPen(Qt::NoPen);
m_CurveIndex = curveIndex;
m_PointIndex = pointIndex;
m_ViewParent = viewParent;
@ -108,7 +107,7 @@ protected:
/// <param name="painter">Unused and just passed to QGraphicsEllipseItem::paint()</param>
/// <param name="option">Drawing options used which will have the QStyle::State_Selected flag unset</param>
/// <param name="widget">Unused and just passed to QGraphicsEllipseItem::paint()</param>
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override
{
QStyleOptionGraphicsItem myOption(*option);
myOption.state &= ~QStyle::State_Selected;
@ -122,7 +121,7 @@ protected:
/// <param name="change">Action is only taken if this value equals ItemPositionChange</param>
/// <param name="value">The new position. This will be clamped to the scene rect.</param>
/// <returns>The new position</returns>
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
virtual QVariant itemChange(GraphicsItemChange change, const QVariant& value) override
{
if (change == ItemPositionChange && scene())
{
@ -136,7 +135,7 @@ protected:
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));
}
m_ViewParent->PointChanged(m_CurveIndex, m_PointIndex, newPos);
return newPos;
}

View File

@ -82,7 +82,7 @@ bool FinalRenderEmberControllerBase::CreateRendererFromGUI()
{
bool useOpenCL = m_Info->Ok() && m_FinalRenderDialog->OpenCL();
auto v = Devices(m_FinalRenderDialog->Devices());
return CreateRenderer((useOpenCL && !v.empty()) ? OPENCL_RENDERER : CPU_RENDERER,
return CreateRenderer((useOpenCL && !v.empty()) ? eRendererType::OPENCL_RENDERER : eRendererType::CPU_RENDERER,
v,
false);//Not shared.
}
@ -583,7 +583,7 @@ bool FinalRenderEmberController<T>::SyncGuiToRenderer()
if (m_Renderer.get())
{
if (m_Renderer->RendererType() == OPENCL_RENDERER)
if (m_Renderer->RendererType() == eRendererType::OPENCL_RENDERER)
channels = 4;//Always using 4 since the GL texture is RGBA.
m_Renderer->Callback(this);
@ -598,7 +598,7 @@ bool FinalRenderEmberController<T>::SyncGuiToRenderer()
{
for (size_t i = 0; i < m_Renderers.size(); i++)
{
if (m_Renderers[i]->RendererType() == OPENCL_RENDERER)
if (m_Renderers[i]->RendererType() == eRendererType::OPENCL_RENDERER)
channels = 4;//Always using 4 since the GL texture is RGBA.
m_Renderers[i]->Callback(!i ? this : nullptr);

View File

@ -15,7 +15,7 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor
m_Shared = true;
m_FailedRenders = 0;
m_UndoIndex = 0;
m_RenderType = CPU_RENDERER;
m_RenderType = eRendererType::CPU_RENDERER;
m_OutputTexID = 0;
m_SubBatchCount = 1;//Will be ovewritten by the options on first render.
m_Fractorium = fractorium;
@ -226,7 +226,7 @@ void FractoriumEmberController<T>::Update(std::function<void (void)> func, bool
/// If no xforms are selected via the checkboxes, and the update type is UPDATE_SELECTED, then the function will be called only on the currently selected xform.
/// </summary>
/// <param name="func">The function to call</param>
/// <param name="updateType">Whether to apply this update operation on the current, all or selected xforms. Default: UPDATE_CURRENT.</param>
/// <param name="updateType">Whether to apply this update operation on the current, all or selected xforms. Default: eXformUpdate::UPDATE_CURRENT.</param>
/// <param name="updateRender">True to update renderer, else false. Default: true.</param>
/// <param name="action">The action to add to the rendering queue. Default: eProcessAction::FULL_RENDER.</param>
template <typename T>

View File

@ -11,12 +11,12 @@
/// <summary>
/// An enum representing the type of edit being done.
/// </summary>
enum eEditUndoState : uint { REGULAR_EDIT, UNDO_REDO, EDIT_UNDO };
enum class eEditUndoState : et { REGULAR_EDIT, UNDO_REDO, EDIT_UNDO };
/// <summary>
/// An enum representing which xforms an update should be applied to.
/// </summary>
enum eXformUpdate : uint { UPDATE_CURRENT, UPDATE_SELECTED, UPDATE_SELECTED_EXCEPT_FINAL, UPDATE_ALL, UPDATE_ALL_EXCEPT_FINAL };
enum class eXformUpdate : et { UPDATE_CURRENT, UPDATE_SELECTED, UPDATE_SELECTED_EXCEPT_FINAL, UPDATE_ALL, UPDATE_ALL_EXCEPT_FINAL };
/// <summary>
/// FractoriumEmberController and Fractorium need each other, but each can't include the other.

View File

@ -17,7 +17,6 @@ void Fractorium::InitMenusUI()
connect(ui.ActionSaveCurrentToOpenedFile, SIGNAL(triggered(bool)), this, SLOT(OnActionSaveCurrentToOpenedFile(bool)), Qt::QueuedConnection);
connect(ui.ActionSaveCurrentScreen, SIGNAL(triggered(bool)), this, SLOT(OnActionSaveCurrentScreen(bool)), Qt::QueuedConnection);
connect(ui.ActionExit, SIGNAL(triggered(bool)), this, SLOT(OnActionExit(bool)), Qt::QueuedConnection);
//Edit menu.
connect(ui.ActionUndo, SIGNAL(triggered(bool)), this, SLOT(OnActionUndo(bool)), Qt::QueuedConnection);
connect(ui.ActionRedo, SIGNAL(triggered(bool)), this, SLOT(OnActionRedo(bool)), Qt::QueuedConnection);
@ -28,10 +27,8 @@ void Fractorium::InitMenusUI()
connect(ui.ActionCopySelectedXforms, SIGNAL(triggered(bool)), this, SLOT(OnActionCopySelectedXforms(bool)), Qt::QueuedConnection);
connect(ui.ActionPasteSelectedXforms, SIGNAL(triggered(bool)), this, SLOT(OnActionPasteSelectedXforms(bool)), Qt::QueuedConnection);
ui.ActionPasteSelectedXforms->setEnabled(false);
//View menu.
connect(ui.ActionResetWorkspace, SIGNAL(triggered(bool)), this, SLOT(OnActionResetWorkspace(bool)), Qt::QueuedConnection);
//Tools menu.
connect(ui.ActionAddReflectiveSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddReflectiveSymmetry(bool)), Qt::QueuedConnection);
connect(ui.ActionAddRotationalSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddRotationalSymmetry(bool)), Qt::QueuedConnection);
@ -44,7 +41,6 @@ void Fractorium::InitMenusUI()
connect(ui.ActionFinalRender, SIGNAL(triggered(bool)), this, SLOT(OnActionFinalRender(bool)), Qt::QueuedConnection);
connect(m_FinalRenderDialog, SIGNAL(finished(int)), this, SLOT(OnFinalRenderClose(int)), Qt::QueuedConnection);
connect(ui.ActionOptions, SIGNAL(triggered(bool)), this, SLOT(OnActionOptions(bool)), Qt::QueuedConnection);
//Help menu.
connect(ui.ActionAbout, SIGNAL(triggered(bool)), this, SLOT(OnActionAbout(bool)), Qt::QueuedConnection);
}
@ -57,7 +53,6 @@ template <typename T>
void FractoriumEmberController<T>::NewFlock(size_t count)
{
Ember<T> ember;
StopPreviewRender();
m_EmberFile.Clear();
m_EmberFile.m_Embers.reserve(count);
@ -98,7 +93,6 @@ void FractoriumEmberController<T>::NewEmptyFlameInCurrentFile()
Ember<T> ember;
Xform<T> xform;
QDateTime local(QDateTime::currentDateTime());
StopPreviewRender();
ParamsToEmber(ember);
xform.m_Weight = T(0.25);
@ -124,7 +118,6 @@ template <typename T>
void FractoriumEmberController<T>::NewRandomFlameInCurrentFile()
{
Ember<T> ember;
StopPreviewRender();
m_SheepTools->Random(ember, m_FilteredVariations, static_cast<int>(QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand->Frand<T>(-2, 2)), 0, MAX_CL_VARS);
ParamsToEmber(ember);
@ -147,7 +140,6 @@ template <typename T>
void FractoriumEmberController<T>::CopyFlameInCurrentFile()
{
Ember<T> ember = m_Ember;
StopPreviewRender();
ember.m_Name = EmberFile<T>::DefaultEmberName(m_EmberFile.Size() + 1).toStdString();
ember.m_Index = m_EmberFile.Size();
@ -181,11 +173,10 @@ void FractoriumEmberController<T>::OpenAndPrepFiles(const QStringList& filenames
XmlToEmber<T> parser;
vector<Ember<T>> embers;
uint previousSize = append ? m_EmberFile.Size() : 0;
StopPreviewRender();
emberFile.m_Filename = filenames[0];
foreach(const QString& filename, filenames)
foreach (const QString& filename, filenames)
{
embers.clear();
@ -209,12 +200,11 @@ void FractoriumEmberController<T>::OpenAndPrepFiles(const QStringList& filenames
else
{
vector<string> errors = parser.ErrorReport();
m_Fractorium->ErrorReportToQTextEdit(errors, m_Fractorium->ui.InfoFileOpeningTextEdit);
m_Fractorium->ShowCritical("Open Failed", "Could not open file, see info tab for details.");
}
}
if (append)
{
if (m_EmberFile.m_Filename == "")
@ -273,14 +263,13 @@ void FractoriumEmberController<T>::SaveCurrentAsXml()
else
filename = m_Fractorium->SetupSaveXmlDialog(QString::fromStdString(m_Ember.m_Name));//More than one ember present, use individual ember name.
}
if (filename != "")
{
Ember<T> ember = m_Ember;
EmberToXml<T> writer;
QFileInfo fileInfo(filename);
xmlDocPtr tempEdit = ember.m_Edits;
SaveCurrentToOpenedFile();//Save the current ember back to the opened file before writing to disk.
ApplyXmlSavingTemplate(ember);
ember.m_Edits = writer.CreateNewEditdoc(&ember, nullptr, "edit", s->Nick().toStdString(), s->Url().toStdString(), s->Id().toStdString(), "", 0, 0);
@ -319,13 +308,12 @@ void FractoriumEmberController<T>::SaveEntireFileAsXml()
filename = m_LastSaveAll;
else
filename = m_Fractorium->SetupSaveXmlDialog(m_EmberFile.m_Filename);
if (filename != "")
{
EmberFile<T> emberFile;
EmberToXml<T> writer;
QFileInfo fileInfo(filename);
SaveCurrentToOpenedFile();//Save the current ember back to the opened file before writing to disk.
emberFile = m_EmberFile;
@ -384,7 +372,7 @@ void FractoriumEmberController<T>::SaveCurrentToOpenedFile()
for (i = 0; i < m_EmberFile.Size(); i++)
{
if ((m_Ember.m_Name == m_EmberFile.m_Embers[i].m_Name) &&//Check both to be extra sure.
(m_Ember.m_Index == m_EmberFile.m_Embers[i].m_Index))
(m_Ember.m_Index == m_EmberFile.m_Embers[i].m_Index))
{
m_EmberFile.m_Embers[i] = m_Ember;
fileFound = true;
@ -426,12 +414,11 @@ void FractoriumEmberController<T>::Undo()
if (m_UndoList.size() > 1 && m_UndoIndex > 0)
{
int index = m_Ember.GetTotalXformIndex(CurrentXform());
m_LastEditWasUndoRedo = true;
m_UndoIndex = std::max(0u, m_UndoIndex - 1u);
SetEmber(m_UndoList[m_UndoIndex], true);
m_EditState = UNDO_REDO;
m_EditState = eEditUndoState::UNDO_REDO;
if (index >= 0)
m_Fractorium->CurrentXform(index);
@ -451,12 +438,11 @@ void FractoriumEmberController<T>::Redo()
if (m_UndoList.size() > 1 && m_UndoIndex < m_UndoList.size() - 1)
{
int index = m_Ember.GetTotalXformIndex(CurrentXform());
m_LastEditWasUndoRedo = true;
m_UndoIndex = std::min<uint>(m_UndoIndex + 1, m_UndoList.size() - 1);
SetEmber(m_UndoList[m_UndoIndex], true);
m_EditState = UNDO_REDO;
m_EditState = eEditUndoState::UNDO_REDO;
if (index >= 0)
m_Fractorium->CurrentXform(index);
@ -477,7 +463,6 @@ void FractoriumEmberController<T>::CopyXml()
Ember<T> ember = m_Ember;
EmberToXml<T> emberToXml;
FractoriumSettings* settings = m_Fractorium->m_Settings;
ember.m_Quality = settings->XmlQuality();
ember.m_Supersample = settings->XmlSupersample();
ember.m_TemporalSamples = settings->XmlTemporalSamples();
@ -496,13 +481,11 @@ void FractoriumEmberController<T>::CopyAllXml()
ostringstream os;
EmberToXml<T> emberToXml;
FractoriumSettings* settings = m_Fractorium->m_Settings;
os << "<flames>\n";
for (auto& e : m_EmberFile.m_Embers)
{
Ember<T> ember = e;
ApplyXmlSavingTemplate(ember);
os << emberToXml.ToString(ember, "", 0, false, false, true);
}
@ -529,7 +512,6 @@ void FractoriumEmberController<T>::PasteXmlAppend()
vector<Ember<T>> embers;
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
QByteArray b = codec->fromUnicode(QApplication::clipboard()->text());
s.reserve(b.size());
for (i = 0; i < b.size(); i++)
@ -554,7 +536,7 @@ void FractoriumEmberController<T>::PasteXmlAppend()
{
embers[i].m_Index = m_EmberFile.Size();
ConstrainDimensions(embers[i]);//Do not exceed the max texture size.
//Also ensure it has a name.
if (embers[i].m_Name == "" || embers[i].m_Name == "No name")
embers[i].m_Name = ToString<qulonglong>(embers[i].m_Index).toStdString();
@ -584,9 +566,8 @@ void FractoriumEmberController<T>::PasteXmlOver()
Ember<T> backupEmber = m_EmberFile.m_Embers[0];
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
QByteArray b = codec->fromUnicode(QApplication::clipboard()->text());
s.reserve(b.size());
for (i = 0; i < b.size(); i++)
{
if (uint(b[i]) < 128u)
@ -610,7 +591,7 @@ void FractoriumEmberController<T>::PasteXmlOver()
{
m_EmberFile.m_Embers[i].m_Index = i;
ConstrainDimensions(m_EmberFile.m_Embers[i]);//Do not exceed the max texture size.
//Also ensure it has a name.
if (m_EmberFile.m_Embers[i].m_Name == "" || m_EmberFile.m_Embers[i].m_Name == "No name")
m_EmberFile.m_Embers[i].m_Name = ToString<qulonglong>(m_EmberFile.m_Embers[i].m_Index).toStdString();
@ -639,14 +620,13 @@ void FractoriumEmberController<T>::CopySelectedXforms()
{
m_CopiedXforms.clear();
m_CopiedFinalXform.Clear();
UpdateXform([&](Xform<T>* xform)
{
if (m_Ember.IsFinalXform(xform))
m_CopiedFinalXform = *xform;
else
m_CopiedXforms.push_back(*xform);
}, UPDATE_SELECTED, false);
}, eXformUpdate::UPDATE_SELECTED, false);
m_Fractorium->ui.ActionPasteSelectedXforms->setEnabled(true);
}
@ -715,7 +695,6 @@ template <typename T>
void FractoriumEmberController<T>::AddReflectiveSymmetry()
{
QComboBox* combo = m_Fractorium->ui.CurrentXformCombo;
Update([&]()
{
m_Ember.AddSymmetry(-1, m_Rand);
@ -734,7 +713,6 @@ template <typename T>
void FractoriumEmberController<T>::AddRotationalSymmetry()
{
QComboBox* combo = m_Fractorium->ui.CurrentXformCombo;
Update([&]()
{
m_Ember.AddSymmetry(2, m_Rand);
@ -753,7 +731,6 @@ template <typename T>
void FractoriumEmberController<T>::AddBothSymmetry()
{
QComboBox* combo = m_Fractorium->ui.CurrentXformCombo;
Update([&]()
{
m_Ember.AddSymmetry(-2, m_Rand);
@ -771,7 +748,7 @@ void Fractorium::OnActionAddBothSymmetry(bool checked) { m_Controller->AddBothSy
template <typename T>
void FractoriumEmberController<T>::Flatten() { UpdateXform([&] (Xform<T>* xform) { m_Ember.Flatten(XmlToEmber<T>::m_FlattenNames); FillVariationTreeWithXform(xform); }); }
void Fractorium::OnActionFlatten(bool checked) { m_Controller->Flatten(); }
/// <summary>
/// Removes pre/reg/post FlattenVariation from every xform in the current ember.
/// Resets the rendering process.
@ -875,5 +852,5 @@ void Fractorium::OnActionAbout(bool checked)
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -246,7 +246,7 @@ void FractoriumEmberController<T>::ClearUndo()
{
m_UndoIndex = 0;
m_UndoList.clear();
m_EditState = REGULAR_EDIT;
m_EditState = eEditUndoState::REGULAR_EDIT;
m_LastEditWasUndoRedo = false;
m_Fractorium->ui.ActionUndo->setEnabled(false);
m_Fractorium->ui.ActionRedo->setEnabled(false);
@ -276,7 +276,7 @@ bool FractoriumEmberController<T>::SyncSizes()
gl->Allocate();
gl->SetViewport();
if (m_Renderer->RendererType() == OPENCL_RENDERER && (rendererCL = dynamic_cast<RendererCL<T, float>*>(m_Renderer.get())))
if (m_Renderer->RendererType() == eRendererType::OPENCL_RENDERER && (rendererCL = dynamic_cast<RendererCL<T, float>*>(m_Renderer.get())))
rendererCL->SetOutputTexture(gl->OutputTexID());
m_Fractorium->CenterScrollbars();
@ -325,7 +325,7 @@ bool FractoriumEmberController<T>::Render()
action = CondenseAndClearProcessActions();//Combine with all other previously requested actions.
if (m_Renderer->RendererType() == OPENCL_RENDERER)
if (m_Renderer->RendererType() == eRendererType::OPENCL_RENDERER)
rendererCL = dynamic_cast<RendererCL<T, float>*>(m_Renderer.get());
//Force temporal samples to always be 1. Perhaps change later when animation is implemented.
@ -370,9 +370,9 @@ bool FractoriumEmberController<T>::Render()
if (iterBegin)
{
if (m_Renderer->RendererType() == CPU_RENDERER)
if (m_Renderer->RendererType() == eRendererType::CPU_RENDERER)
m_SubBatchCount = m_Fractorium->m_Settings->CpuSubBatch();
else if (m_Renderer->RendererType() == OPENCL_RENDERER)
else if (m_Renderer->RendererType() == eRendererType::OPENCL_RENDERER)
m_SubBatchCount = m_Fractorium->m_Settings->OpenCLSubBatch();
m_Fractorium->m_ProgressBar->setValue(0);
@ -387,7 +387,7 @@ bool FractoriumEmberController<T>::Render()
{
//The amount to increment sub batch while rendering proceeds is purely empirical.
//Change later if better values can be derived/observed.
if (m_Renderer->RendererType() == OPENCL_RENDERER)
if (m_Renderer->RendererType() == eRendererType::OPENCL_RENDERER)
{
if (m_SubBatchCount < (4 * m_Devices.size()))//More than 3 with OpenCL gives a sluggish UI.
m_SubBatchCount += m_Devices.size();
@ -410,7 +410,7 @@ bool FractoriumEmberController<T>::Render()
m_Fractorium->m_ProgressBar->setValue(100);
//Only certain stats can be reported with OpenCL.
if (m_Renderer->RendererType() == OPENCL_RENDERER)
if (m_Renderer->RendererType() == eRendererType::OPENCL_RENDERER)
{
m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Total time: " + QString::fromStdString(renderTime) + ".");
}
@ -424,9 +424,9 @@ bool FractoriumEmberController<T>::Render()
if (m_LastEditWasUndoRedo && (m_UndoIndex == m_UndoList.size() - 1))//Traversing through undo list, reached the end, so put back in regular edit mode.
{
m_EditState = REGULAR_EDIT;
m_EditState = eEditUndoState::REGULAR_EDIT;
}
else if (m_EditState == REGULAR_EDIT)//Regular edit, just add to the end of the undo list.
else if (m_EditState == eEditUndoState::REGULAR_EDIT)//Regular edit, just add to the end of the undo list.
{
m_UndoList.push_back(m_Ember);
m_UndoIndex = m_UndoList.size() - 1;
@ -551,7 +551,7 @@ bool FractoriumEmberController<T>::CreateRenderer(eRendererType renderType, cons
{
m_RenderType = m_Renderer->RendererType();
if (m_RenderType == OPENCL_RENDERER)
if (m_RenderType == eRendererType::OPENCL_RENDERER)
{
auto val = 30 * m_Fractorium->m_Settings->Devices().size();
m_Fractorium->m_QualitySpin->DoubleClickZero(val);
@ -628,7 +628,7 @@ bool Fractorium::CreateRendererFromOptions()
auto v = Devices(m_Settings->Devices());
//The most important option to process is what kind of renderer is desired, so do it first.
if (!m_Controller->CreateRenderer((useOpenCL && !v.empty()) ? OPENCL_RENDERER : CPU_RENDERER, v))
if (!m_Controller->CreateRenderer((useOpenCL && !v.empty()) ? eRendererType::OPENCL_RENDERER : eRendererType::CPU_RENDERER, v))
{
//If using OpenCL, will only get here if creating RendererCL failed, but creating a backup CPU Renderer succeeded.
ShowCritical("Renderer Creation Error", "Error creating renderer, most likely a GPU problem. Using CPU instead.");

View File

@ -7,14 +7,12 @@
void Fractorium::InitXformsVariationsUI()
{
auto tree = ui.VariationsTree;
tree->clear();
tree->header()->setSectionsClickable(true);
connect(tree->header(), SIGNAL(sectionClicked(int)), this, SLOT(OnTreeHeaderSectionClicked(int)));
connect(ui.VariationsFilterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnVariationsFilterLineEditTextChanged(const QString&)));
connect(ui.VariationsFilterClearButton, SIGNAL(clicked(bool)), this, SLOT(OnVariationsFilterClearButtonClicked(bool)));
connect(ui.ActionVariationsDialog, SIGNAL(triggered(bool)), this, SLOT(OnActionVariationsDialog(bool)), Qt::QueuedConnection);
//Setting dimensions in the designer with a layout is futile, so must hard code here.
tree->setColumnWidth(0, 160);
tree->setColumnWidth(1, 23);
@ -47,7 +45,6 @@ void FractoriumEmberController<T>::Filter(const QString& text)
auto& ids = m_Fractorium->m_VarDialog->Map();
auto tree = m_Fractorium->ui.VariationsTree;
auto xform = CurrentXform();
tree->setUpdatesEnabled(false);
for (int i = 0; i < tree->topLevelItemCount(); i++)
@ -55,7 +52,7 @@ void FractoriumEmberController<T>::Filter(const QString& text)
if (auto item = dynamic_cast<VariationTreeWidgetItem*>(tree->topLevelItem(i)))
{
auto varName = item->text(0);
if (xform && xform->GetVariationById(item->Id()))//If it's present then show it no matter what the filter is.
{
item->setHidden(false);
@ -84,7 +81,6 @@ template <typename T>
void FractoriumEmberController<T>::FilteredVariations()
{
auto& map = m_Fractorium->m_VarDialog->Map();
m_FilteredVariations.clear();
m_FilteredVariations.reserve(map.size());
@ -108,7 +104,6 @@ void FractoriumEmberController<T>::SetupVariationTree()
QSize hint0(75, 16);
QSize hint1(30, 16);
auto tree = m_Fractorium->ui.VariationsTree;
tree->clear();
tree->blockSignals(true);
@ -116,11 +111,9 @@ void FractoriumEmberController<T>::SetupVariationTree()
{
auto var = m_VariationList.GetVariation(i);
auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);
//First add the variation, with a spinner for its weight.
auto item = new VariationTreeWidgetItem(var->VariationId(), tree);
auto spinBox = new VariationTreeDoubleSpinBox(tree, item, var->VariationId(), "");
item->setText(0, QString::fromStdString(var->Name()));
item->setSizeHint(0, hint0);
item->setSizeHint(1, hint1);
@ -144,7 +137,6 @@ void FractoriumEmberController<T>::SetupVariationTree()
{
auto paramWidget = new VariationTreeWidgetItem(var->VariationId(), item);
auto varSpinBox = new VariationTreeDoubleSpinBox(tree, paramWidget, parVar->VariationId(), params[j].Name());
paramWidget->setText(0, params[j].Name().c_str());
paramWidget->setSizeHint(0, hint0);
paramWidget->setSizeHint(1, hint1);
@ -154,7 +146,7 @@ void FractoriumEmberController<T>::SetupVariationTree()
varSpinBox->DoubleClickZero(1);
varSpinBox->DoubleClickNonZero(0);
if (params[j].Type() == INTEGER || params[j].Type() == INTEGER_NONZERO)
if (params[j].Type() == eParamType::INTEGER || params[j].Type() == eParamType::INTEGER_NONZERO)
{
varSpinBox->setSingleStep(1);
varSpinBox->Step(1);
@ -185,7 +177,6 @@ void FractoriumEmberController<T>::ClearVariationsTree()
{
QTreeWidgetItem* item = tree->topLevelItem(i);
auto* spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(tree->itemWidget(item, 1));
spinBox->SetValueStealth(0);
for (int j = 0; j < item->childCount(); j++)//Iterate through all of the children, which will be the params.
@ -252,7 +243,6 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would
//If the item wasn't a param and the xform did not contain this variation,
//it means they went from zero to a non-zero weight, so add a new copy of this xform.
auto newVar = var->Copy();//Create a new one with default values.
newVar->m_Weight = d;
xform->AddVariation(newVar);
widgetItem->setBackgroundColor(0, QColor(200, 200, 200));//Set background to gray when a variation has non-zero weight in this xform.
@ -262,7 +252,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would
if (parVar)
{
auto newParVar = dynamic_cast<ParametricVariation<T>*>(newVar);
for (int i = 0; i < widgetItem->childCount(); i++)//Iterate through all of the children, which will be the params.
{
auto childItem = widgetItem->child(i);//Get the child.
@ -271,7 +261,6 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would
if (auto spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(itemWidget))//Cast the widget to the VariationTreeDoubleSpinBox type.
{
string s = childItem->text(0).toStdString();//Use the name of the child, and the value of the spinner widget to assign the param.
newParVar->SetParamVal(s.c_str(), spinBox->value());
}
}
@ -295,7 +284,6 @@ template <typename T>
void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
{
auto tree = m_Fractorium->ui.VariationsTree;
tree->blockSignals(true);
m_Fractorium->Filter();
@ -385,5 +373,5 @@ void Fractorium::OnVariationsFilterClearButtonClicked(bool checked)
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -13,9 +13,9 @@ GLEmberControllerBase::GLEmberControllerBase(Fractorium* fractorium, GLWidget* g
{
m_Fractorium = fractorium;
m_GL = glWidget;
m_AffineType = AffinePre;
m_HoverType = HoverNone;
m_DragState = DragNone;
m_AffineType = eAffineType::AffinePre;
m_HoverType = eHoverType::HoverNone;
m_DragState = eDragState::DragNone;
m_DragModifier = 0;
}
@ -37,7 +37,6 @@ GLEmberController<T>::GLEmberController(Fractorium* fractorium, GLWidget* glWidg
{
GridStep = T(1.0 / 8.0);
m_FractoriumEmberController = controller;
m_HoverXform = nullptr;
m_SelectedXform = nullptr;
m_CenterDownX = 0;
@ -68,7 +67,7 @@ bool GLEmberController<T>::CheckForSizeMismatch(int w, int h)
template <typename T>
void GLEmberController<T>::ResetMouseState()
{
m_HoverType = HoverNone;
m_HoverType = eHoverType::HoverNone;
m_HoverXform = nullptr;
m_SelectedXform = nullptr;
}
@ -86,10 +85,8 @@ T GLEmberController<T>::CalcScale()
v2T windowCenter(T(m_GL->width()) / T(2), T(m_GL->height()) / T(2));
v2T windowMousePosDistanceFromCenter(m_MousePos.x - windowCenter.x, m_MousePos.y - windowCenter.y);
v2T windowMouseDownDistanceFromCenter(m_MouseDownPos.x - windowCenter.x, m_MouseDownPos.y - windowCenter.y);
T lengthMousePosFromCenterInPixels = glm::length(windowMousePosDistanceFromCenter);
T lengthMouseDownFromCenterInPixels = glm::length(windowMouseDownDistanceFromCenter);
return lengthMousePosFromCenterInPixels - lengthMouseDownFromCenterInPixels;
}
@ -103,7 +100,6 @@ T GLEmberController<T>::CalcRotation()
{
T rotStart = NormalizeDeg180<T>(T(90) - (atan2(-m_MouseDownWorldPos.y, m_MouseDownWorldPos.x) * RAD_2_DEG_T));
T rot = NormalizeDeg180<T>(T(90) - (atan2(-m_MouseWorldPos.y, m_MouseWorldPos.x) * RAD_2_DEG_T));
return rotStart - rot;
}
@ -116,10 +112,8 @@ template <typename T>
typename v3T GLEmberController<T>::SnapToGrid(v3T& vec)
{
v3T ret;
ret.x = glm::round(vec.x / GridStep) * GridStep;
ret.y = glm::round(vec.y / GridStep) * GridStep;
return ret;
}
@ -135,7 +129,6 @@ typename v3T GLEmberController<T>::SnapToNormalizedAngle(v3T& vec, uint division
T rsq, theta;
T bestRsq = numeric_limits<T>::max();
v3T c, best;
best.x = 1;
best.y = 0;
@ -167,7 +160,6 @@ typename v3T GLEmberController<T>::WindowToWorld(v3T& v, bool flip)
{
v3T mouse(v.x, flip ? m_Viewport[3] - v.y : v.y, 0);//Must flip y because in OpenGL, 0,0 is bottom left, but in windows, it's top left.
v3T newCoords = glm::unProject(mouse, m_Modelview, m_Projection, m_Viewport);//Perform the calculation.
newCoords.z = 0;//For some reason, unProject() always comes back with the z coordinate as something other than 0. It should be 0 at all times.
return newCoords;
}
@ -234,7 +226,6 @@ void GLEmberController<T>::QueryMatrices(bool print)
{
double unitX = fabs(renderer->UpperRightX(false) - renderer->LowerLeftX(false)) / 2.0;
double unitY = fabs(renderer->UpperRightY(false) - renderer->LowerLeftY(false)) / 2.0;
m_GL->glMatrixMode(GL_PROJECTION);
m_GL->glPushMatrix();
m_GL->glLoadIdentity();
@ -242,9 +233,7 @@ void GLEmberController<T>::QueryMatrices(bool print)
m_GL->glMatrixMode(GL_MODELVIEW);
m_GL->glPushMatrix();
m_GL->glLoadIdentity();
QueryVMP();
m_GL->glMatrixMode(GL_PROJECTION);
m_GL->glPopMatrix();
m_GL->glMatrixMode(GL_MODELVIEW);

View File

@ -9,22 +9,22 @@
/// <summary>
/// Use/draw pre or post affine transform.
/// </summary>
enum eAffineType { AffinePre, AffinePost };
enum class eAffineType : et { AffinePre, AffinePost };
/// <summary>
/// Hovering over nothing, the x axis, the y axis or the center.
/// </summary>
enum eHoverType { HoverNone, HoverXAxis, HoverYAxis, HoverTranslation };
enum class eHoverType : et { HoverNone, HoverXAxis, HoverYAxis, HoverTranslation };
/// <summary>
/// Dragging an affine transform or panning, rotating or scaling the image.
/// </summary>
enum eDragState { DragNone, DragPanning, DragDragging, DragRotateScale };
enum class eDragState : et { DragNone, DragPanning, DragDragging, DragRotateScale };
/// <summary>
/// Dragging with no keys pressed, shift, control or alt.
/// </summary>
enum eDragModifier { DragModNone = 0x00, DragModShift = 0x01, DragModControl = 0x02, DragModAlt = 0x04 };
enum class eDragModifier : et { DragModNone = 0x00, DragModShift = 0x01, DragModControl = 0x02, DragModAlt = 0x04 };
/// <summary>
/// GLController, FractoriumEmberController, GLWidget and Fractorium need each other, but each can't all include the other.
@ -50,7 +50,15 @@ public:
void ClearDrag();
bool Allocate(bool force = false);
bool GetAlt();
bool GetShift();
bool GetControl();
void SetAlt();
void SetShift();
void SetControl();
void ClearAlt();
void ClearShift();
void ClearControl();
virtual void DrawImage() { }
virtual void DrawAffines(bool pre, bool post) { }
virtual void ClearWindow() { }
@ -129,7 +137,7 @@ private:
v3T m_DragHandlePos;
v3T m_DragHandleOffset;
v3T m_HoverHandlePos;
m4T m_Modelview;
m4T m_Projection;

View File

@ -13,18 +13,15 @@ GLWidget::GLWidget(QWidget* p)
: QOpenGLWidget(p)
{
QSurfaceFormat qsf;
m_Init = false;
m_Drawing = false;
m_TexWidth = 0;
m_TexHeight = 0;
m_OutputTexID = 0;
m_Fractorium = nullptr;
qsf.setSwapInterval(1);//Vsync.
qsf.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
qsf.setVersion(2, 0);
setFormat(qsf);
}
@ -45,11 +42,9 @@ void GLWidget::InitGL()
{
int w = m_Fractorium->ui.GLParentScrollArea->width();
int h = m_Fractorium->ui.GLParentScrollArea->height();
SetDimensions(w, h);
m_Fractorium->m_WidthSpin->setValue(w);
m_Fractorium->m_HeightSpin->setValue(h);
//Start with a flock of 10 random embers. Can't do this until now because the window wasn't maximized yet, so the sizes would have been off.
m_Fractorium->OnActionNewFlock(false);
m_Fractorium->m_Controller->DelayedStartRenderTimer();
@ -77,7 +72,7 @@ void GLWidget::DrawQuad()
if (m_OutputTexID != 0 && finalImage && !finalImage->empty())
{
glBindTexture(GL_TEXTURE_2D, m_OutputTexID);//The texture to draw to.
//Only draw if the dimensions match exactly.
if (m_TexWidth == width() && m_TexHeight == height() && ((m_TexWidth * m_TexHeight * 4) == GLint(finalImage->size())))
{
@ -90,16 +85,14 @@ void GLWidget::DrawQuad()
glLoadIdentity();
//Copy data from CPU to OpenGL if using a CPU renderer. This is not needed when using OpenCL.
if (renderer->RendererType() == CPU_RENDERER)
if (renderer->RendererType() == eRendererType::CPU_RENDERER)
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_TexWidth, m_TexHeight, GL_RGBA, GL_UNSIGNED_BYTE, finalImage->data());
glBegin(GL_QUADS);//This will need to be converted to a shader at some point in the future.
glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, 0.0);
glEnd();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
@ -120,7 +113,7 @@ void GLWidget::DrawQuad()
void GLEmberControllerBase::ClearDrag()
{
m_DragModifier = 0;
m_DragState = DragNone;
m_DragState = eDragState::DragNone;
}
/// <summary>
@ -128,6 +121,20 @@ void GLEmberControllerBase::ClearDrag()
/// </summary>
bool GLEmberControllerBase::Allocate(bool force) { return m_GL->Allocate(force); }
/// <summary>
/// Helpers to set/get/clear which keys are pressed while dragging.
/// </summary>
/// <returns>bool</returns>
bool GLEmberControllerBase::GetAlt() { return (m_DragModifier & et(eDragModifier::DragModAlt)) == et(eDragModifier::DragModAlt); }
bool GLEmberControllerBase::GetShift() { return (m_DragModifier & et(eDragModifier::DragModShift)) == et(eDragModifier::DragModShift); }
bool GLEmberControllerBase::GetControl() { return (m_DragModifier & et(eDragModifier::DragModControl)) == et(eDragModifier::DragModControl); }
void GLEmberControllerBase::SetAlt() { m_DragModifier |= et(eDragModifier::DragModAlt); }
void GLEmberControllerBase::SetShift() { m_DragModifier |= et(eDragModifier::DragModShift); }
void GLEmberControllerBase::SetControl() { m_DragModifier |= et(eDragModifier::DragModControl); }
void GLEmberControllerBase::ClearAlt() { m_DragModifier &= ~et(eDragModifier::DragModAlt); }
void GLEmberControllerBase::ClearShift() { m_DragModifier &= ~et(eDragModifier::DragModShift); }
void GLEmberControllerBase::ClearControl() { m_DragModifier &= ~et(eDragModifier::DragModControl); }
/// <summary>
/// Clear the OpenGL output window to be the background color of the current ember.
/// Both buffers must be cleared, else artifacts will show up.
@ -136,7 +143,6 @@ template <typename T>
void GLEmberController<T>::ClearWindow()
{
Ember<T>* ember = m_FractoriumEmberController->CurrentEmber();
m_GL->makeCurrent();
m_GL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GL->glClearColor(ember->m_Background.r, ember->m_Background.g, ember->m_Background.b, 1.0);
@ -191,11 +197,9 @@ void GLWidget::initializeGL()
if (!m_Init && initializeOpenGLFunctions() && m_Fractorium)
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glEnable(GL_TEXTURE_2D);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_MaxTexSize);
glDisable(GL_TEXTURE_2D);
m_Fractorium->m_WidthSpin->setMaximum(m_MaxTexSize);
m_Fractorium->m_HeightSpin->setMaximum(m_MaxTexSize);
}
@ -213,22 +217,18 @@ void GLWidget::paintGL()
if (controller && controller->Renderer() && controller->RenderTimerRunning())
{
RendererBase* renderer = controller->Renderer();
m_Drawing = true;
controller->GLController()->DrawImage();
//Affine drawing.
bool pre = m_Fractorium->ui.PreAffineGroupBox->isChecked();
bool post = m_Fractorium->ui.PostAffineGroupBox->isChecked();
float unitX = fabs(renderer->UpperRightX(false) - renderer->LowerLeftX(false)) / 2.0f;
float unitY = fabs(renderer->UpperRightY(false) - renderer->LowerLeftY(false)) / 2.0f;
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@ -236,21 +236,16 @@ void GLWidget::paintGL()
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
controller->GLController()->DrawAffines(pre, post);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_POINT_SMOOTH);
m_Drawing = false;
}
}
@ -263,23 +258,21 @@ void GLEmberController<T>::DrawImage()
{
RendererBase* renderer = m_FractoriumEmberController->Renderer();
Ember<T>* ember = m_FractoriumEmberController->CurrentEmber();
m_GL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GL->glClearColor(ember->m_Background.r, ember->m_Background.g, ember->m_Background.b, 1.0);
m_GL->glDisable(GL_DEPTH_TEST);
renderer->EnterFinalAccum();//Lock, may not be necessary, but just in case.
renderer->EnterResize();
if (SizesMatch())//Ensure all sizes are correct. If not, do nothing.
{
vector<byte>* finalImage = m_FractoriumEmberController->FinalImage();
if (renderer->RendererType() == OPENCL_RENDERER || finalImage)//Final image only matters for CPU renderer.
if (renderer->RendererType() == OPENCL_RENDERER || finalImage->size() == renderer->FinalBufferSize())
if ((renderer->RendererType() == eRendererType::OPENCL_RENDERER) || finalImage)//Final image only matters for CPU renderer.
if ((renderer->RendererType() == eRendererType::OPENCL_RENDERER) || finalImage->size() == renderer->FinalBufferSize())
m_GL->DrawQuad();//Output image is drawn here.
}
renderer->LeaveResize();//Unlock, may not be necessary.
renderer->LeaveFinalAccum();
}
@ -294,10 +287,10 @@ void GLEmberController<T>::DrawAffines(bool pre, bool post)
{
QueryVMP();//Resolves to float or double specialization function depending on T.
Ember<T>* ember = m_FractoriumEmberController->CurrentEmber();
bool dragging = m_DragState == DragDragging;
bool dragging = m_DragState == eDragState::DragDragging;
//Draw grid if control key is pressed.
if (m_GL->hasFocus() && ((m_DragModifier & DragModControl) == DragModControl))
if (m_GL->hasFocus() && GetControl())
{
m_GL->glLineWidth(1.0f);
m_GL->DrawGrid();
@ -307,7 +300,7 @@ void GLEmberController<T>::DrawAffines(bool pre, bool post)
if (!m_Fractorium->m_Settings->ShowAllXforms() && dragging)
{
if (m_SelectedXform)
DrawAffine(m_SelectedXform, m_AffineType == AffinePre, true);
DrawAffine(m_SelectedXform, m_AffineType == eAffineType::AffinePre, true);
}
else//Show all while dragging, or not dragging just hovering/mouse move.
{
@ -317,7 +310,6 @@ void GLEmberController<T>::DrawAffines(bool pre, bool post)
{
Xform<T>* xform = ember->GetTotalXform(i);
bool selected = dragging ? (m_SelectedXform == xform) : (m_HoverXform == xform);
DrawAffine(xform, true, selected);
}
}
@ -332,7 +324,6 @@ void GLEmberController<T>::DrawAffines(bool pre, bool post)
{
Xform<T>* xform = ember->GetTotalXform(i);
bool selected = dragging ? (m_SelectedXform == xform) : (m_HoverXform == xform);
DrawAffine(xform, false, selected);
}
}
@ -351,7 +342,7 @@ void GLEmberController<T>::DrawAffines(bool pre, bool post)
m_GL->glEnd();
m_GL->glPointSize(1.0f);//Restore point size.
}
else if (m_HoverType != HoverNone && m_HoverXform == m_SelectedXform)//Draw large turquoise dot on hover if they are hovering over the selected xform.
else if (m_HoverType != eHoverType::HoverNone && m_HoverXform == m_SelectedXform)//Draw large turquoise dot on hover if they are hovering over the selected xform.
{
m_GL->glPointSize(6.0f);
m_GL->glBegin(GL_POINTS);
@ -369,24 +360,26 @@ void GLEmberController<T>::DrawAffines(bool pre, bool post)
bool GLEmberControllerBase::KeyPress_(QKeyEvent* e)
{
#ifdef OLDDRAG
if (e->key() == Qt::Key_Shift)
m_DragModifier |= DragModShift;
SetShift();
else if (e->key() == Qt::Key_Control || e->key() == Qt::Key_C)
m_DragModifier |= DragModControl;
SetControl();
else if (e->key() == Qt::Key_Alt || e->key() == Qt::Key_A)
m_DragModifier |= DragModAlt;
SetAlt();
else
return false;
return true;
#else
if (e->key() == Qt::Key_Control)
{
m_DragModifier |= DragModControl;
SetControl();
return true;
}
#endif
#endif
return false;
}
@ -409,24 +402,26 @@ void GLWidget::keyPressEvent(QKeyEvent* e)
bool GLEmberControllerBase::KeyRelease_(QKeyEvent* e)
{
#ifdef OLDDRAG
if (e->key() == Qt::Key_Shift)
m_DragModifier &= ~DragModShift;
ClearShift();
else if (e->key() == Qt::Key_Control || e->key() == Qt::Key_C)
m_DragModifier &= ~DragModControl;
ClearControl();
else if (e->key() == Qt::Key_Alt || e->key() == Qt::Key_A)
m_DragModifier &= ~DragModAlt;
ClearAlt();
else
return false;
return true;
#else
if (e->key() == Qt::Key_Control)
{
m_DragModifier &= ~DragModControl;
ClearControl();
return true;
}
#endif
#endif
return false;
}
@ -435,7 +430,7 @@ bool GLEmberControllerBase::KeyRelease_(QKeyEvent* e)
/// </summary>
/// <param name="e">The event</param>
void GLWidget::keyReleaseEvent(QKeyEvent* e)
{
{
if (!GLController() || !GLController()->KeyRelease_(e))
QOpenGLWidget::keyReleaseEvent(e);
@ -466,18 +461,20 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
m_BoundsDown.x = renderer->LowerLeftY(false);
m_BoundsDown.y = renderer->UpperRightX(false);
m_BoundsDown.z = renderer->UpperRightY(false);
#ifndef OLDDRAG
Qt::KeyboardModifiers mod = e->modifiers();
if (mod.testFlag(Qt::ShiftModifier))
m_DragModifier |= DragModShift;
SetShift();
//if (mod.testFlag(Qt::ControlModifier))// || mod.testFlag(Qt::Key_C))
// m_DragModifier |= DragModControl;
if (mod.testFlag(Qt::AltModifier))// || mod.testFlag(Qt::Key_A))
m_DragModifier |= DragModAlt;
SetAlt();
#endif
if (m_DragState == DragNone)//Only take action if the user wasn't already dragging.
if (m_DragState == eDragState::DragNone)//Only take action if the user wasn't already dragging.
{
m_MouseDownWorldPos = m_MouseWorldPos;//Set the mouse down position to the current position.
@ -488,14 +485,12 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
if (m_HoverXform && xformIndex != -1)
{
m_SelectedXform = m_HoverXform;
m_DragSrcTransform = Affine2D<T>(m_AffineType == AffinePre ? m_SelectedXform->m_Affine : m_SelectedXform->m_Post);//Copy the affine of the xform that was selected.
m_DragSrcTransform = Affine2D<T>(m_AffineType == eAffineType::AffinePre ? m_SelectedXform->m_Affine : m_SelectedXform->m_Post);//Copy the affine of the xform that was selected.
m_DragHandlePos = m_HoverHandlePos;
m_DragHandleOffset = m_DragHandlePos - m_MouseWorldPos;
m_DragState = DragDragging;
m_DragState = eDragState::DragDragging;
//The user has selected an xform by clicking on it, so update the main GUI by selecting this xform in the combo box.
m_Fractorium->CurrentXform(xformIndex);
//Draw large yellow dot on select or drag.
m_GL->glPointSize(6.0f);
m_GL->glBegin(GL_POINTS);
@ -508,14 +503,14 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
else//Nothing was selected.
{
//m_SelectedXform = nullptr;
m_DragState = DragNone;
m_DragState = eDragState::DragNone;
}
}
else if (e->button() == Qt::MiddleButton)//Middle button does whole image translation.
{
m_CenterDownX = ember->m_CenterX;//Capture where the center of the image is because this value will change when panning.
m_CenterDownY = ember->m_CenterY;
m_DragState = DragPanning;
m_DragState = eDragState::DragPanning;
}
else if (e->button() == Qt::RightButton)//Right button does whole image rotation and scaling.
{
@ -525,7 +520,7 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
m_CenterDownY = ember->m_CenterY;
m_RotationDown = ember->m_Rotate;
m_ScaleDown = ember->m_PixelsPerUnit;
m_DragState = DragRotateScale;
m_DragState = eDragState::DragRotateScale;
}
}
}
@ -553,18 +548,15 @@ template <typename T>
void GLEmberController<T>::MouseRelease(QMouseEvent* e)
{
v3T mouseFlipped(e->x() * m_GL->devicePixelRatio(), m_Viewport[3] - e->y() * m_GL->devicePixelRatio(), 0);//Must flip y because in OpenGL, 0,0 is bottom left, but in windows, it's top left.
m_MouseWorldPos = WindowToWorld(mouseFlipped, false);
if (m_DragState == DragDragging && (e->button() & Qt::LeftButton))
if (m_DragState == eDragState::DragDragging && (e->button() & Qt::LeftButton))
UpdateHover(mouseFlipped);
m_DragState = DragNone;
m_DragState = eDragState::DragNone;
#ifndef OLDDRAG
m_DragModifier = 0;
#endif
m_GL->repaint();//Force immediate redraw.
}
@ -594,7 +586,7 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
glm::ivec2 mouse(e->x() * m_GL->devicePixelRatio(), e->y() * m_GL->devicePixelRatio());
v3T mouseFlipped(e->x() * m_GL->devicePixelRatio(), m_Viewport[3] - e->y() * m_GL->devicePixelRatio(), 0);//Must flip y because in OpenGL, 0,0 is bottom left, but in windows, it's top left.
Ember<T>* ember = m_FractoriumEmberController->CurrentEmber();
//First check to see if the mouse actually moved.
if (mouse == m_MousePos)
return;
@ -607,43 +599,39 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
if (m_Fractorium->m_Controller->RenderTimerRunning())
m_Fractorium->SetCoordinateStatus(e->x() * m_GL->devicePixelRatio(), e->y() * m_GL->devicePixelRatio(), m_MouseWorldPos.x, m_MouseWorldPos.y);
if (m_SelectedXform && m_DragState == DragDragging)//Dragging and affine.
if (m_SelectedXform && m_DragState == eDragState::DragDragging)//Dragging and affine.
{
bool pre = m_AffineType == AffinePre;
bool pre = m_AffineType == eAffineType::AffinePre;
Affine2D<T>* affine = pre ? &m_SelectedXform->m_Affine : &m_SelectedXform->m_Post;//Determine pre or post affine.
if (m_HoverType == HoverTranslation)
if (m_HoverType == eHoverType::HoverTranslation)
*affine = CalcDragTranslation();
else if (m_HoverType == HoverXAxis)
else if (m_HoverType == eHoverType::HoverXAxis)
*affine = CalcDragXAxis();
else if (m_HoverType == HoverYAxis)
else if (m_HoverType == eHoverType::HoverYAxis)
*affine = CalcDragYAxis();
m_FractoriumEmberController->FillAffineWithXform(m_SelectedXform, pre);//Update the spinners in the affine tab of the main window.
m_FractoriumEmberController->UpdateRender();//Restart the rendering process.
}
else if (m_DragState == DragPanning)//Translating the whole image.
else if (m_DragState == eDragState::DragPanning)//Translating the whole image.
{
T x = -(m_MouseWorldPos.x - m_MouseDownWorldPos.x);
T y = (m_MouseWorldPos.y - m_MouseDownWorldPos.y);
Affine2D<T> rotMat;
rotMat.C(m_CenterDownX);
rotMat.F(m_CenterDownY);
rotMat.Rotate(ember->m_Rotate);
v2T v1(x, y);
v2T v2 = rotMat.TransformVector(v1);
ember->m_CenterX = v2.x;
ember->m_CenterY = ember->m_RotCenterY = v2.y;
m_FractoriumEmberController->SetCenter(ember->m_CenterX, ember->m_CenterY);//Will restart the rendering process.
}
else if (m_DragState == DragRotateScale)//Rotating and scaling the whole image.
else if (m_DragState == eDragState::DragRotateScale)//Rotating and scaling the whole image.
{
T rot = CalcRotation();
T scale = CalcScale();
ember->m_Rotate = NormalizeDeg180<T>(m_RotationDown + rot);
m_Fractorium->SetRotation(ember->m_Rotate, true);
ember->m_PixelsPerUnit = m_ScaleDown + scale;
@ -660,7 +648,7 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
//In that case, nothing needs to be done.
if (UpdateHover(mouseFlipped) == -1)
draw = false;
//Xform<T>* previousHover = m_HoverXform;
//
//if (UpdateHover(mouseFlipped) == -1)
@ -669,12 +657,13 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
//if (m_HoverXform == previousHover)
// draw = false;
}
//Only update if the user was dragging or hovered over a point.
//Use repaint() to update immediately for a more responsive feel.
if ((m_DragState != DragNone) || draw)
if ((m_DragState != eDragState::DragNone) || draw)
m_GL->update();
//m_GL->repaint();
//m_GL->repaint();
}
/// <summary>
@ -684,10 +673,10 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
void GLWidget::mouseMoveEvent(QMouseEvent* e)
{
setFocus();//Must do this so that this window gets keyboard events.
if (GLEmberControllerBase* controller = GLController())
controller->MouseMove(e);
QOpenGLWidget::mouseMoveEvent(e);
}
@ -715,7 +704,7 @@ void GLWidget::wheelEvent(QWheelEvent* e)
{
if (GLEmberControllerBase* controller = GLController())
controller->Wheel(e);
//Do not call QOpenGLWidget::wheelEvent(e) because this should only affect the scale and not the position of the scroll bars.
}
@ -773,7 +762,6 @@ bool GLWidget::Allocate(bool force)
glGenTextures(1, &m_OutputTexID);
glBindTexture(GL_TEXTURE_2D, m_OutputTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//Fractron had this as GL_LINEAR_MIPMAP_LINEAR for OpenCL and Cuda.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
@ -781,7 +769,7 @@ bool GLWidget::Allocate(bool force)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TexWidth, m_TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
alloc = true;
}
if (alloc)
{
glBindTexture(GL_TEXTURE_2D, 0);
@ -835,14 +823,13 @@ template <typename T>
bool GLEmberController<T>::SizesMatch()
{
Ember<T>* ember = m_FractoriumEmberController->CurrentEmber();
return (ember &&
ember->m_FinalRasW == m_GL->width() &&
ember->m_FinalRasH == m_GL->height() &&
m_GL->width() == m_GL->m_TexWidth &&
m_GL->height() == m_GL->m_TexHeight &&
m_GL->m_TexWidth == m_GL->m_ViewWidth &&
m_GL->m_TexHeight == m_GL->m_ViewHeight);
ember->m_FinalRasW == m_GL->width() &&
ember->m_FinalRasH == m_GL->height() &&
m_GL->width() == m_GL->m_TexWidth &&
m_GL->height() == m_GL->m_TexHeight &&
m_GL->m_TexWidth == m_GL->m_ViewWidth &&
m_GL->m_TexHeight == m_GL->m_ViewHeight);
}
/// <summary>
@ -860,7 +847,6 @@ void GLWidget::DrawGrid()
float xHigh = ceil(unitX);
float yLow = floor(-unitY);
float yHigh = ceil(unitY);
glBegin(GL_LINES);
if (rad <= 8.0f)
@ -920,21 +906,19 @@ void GLWidget::DrawUnitSquare()
glLineWidth(1.0f);
glBegin(GL_LINES);
glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
glVertex2f(-1,-1);
glVertex2f( 1,-1);
glVertex2f(-1, -1);
glVertex2f( 1, -1);
glVertex2f(-1, 1);
glVertex2f( 1, 1);
glVertex2f(-1,-1);
glVertex2f(-1, -1);
glVertex2f(-1, 1);
glVertex2f( 1,-1);
glVertex2f( 1, -1);
glVertex2f( 1, 1);
glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
glVertex2f(-1, 0);
glVertex2f( 1, 0);
glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
glVertex2f( 0,-1);
glVertex2f( 0, -1);
glVertex2f( 0, 1);
glEnd();
}
@ -956,21 +940,17 @@ void GLEmberController<T>::DrawAffine(Xform<T>* xform, bool pre, bool selected)
size_t size = ember->m_Palette.m_Entries.size();
v4T color = ember->m_Palette.m_Entries[Clamp<T>(xform->m_ColorX * size, 0, size - 1)];
Affine2D<T>* affine = pre ? &xform->m_Affine : &xform->m_Post;
//For some incredibly strange reason, even though glm and OpenGL use matrices with a column-major
//data layout, nothing will work here unless they are flipped to row major order. This is how it was
//done in Fractron.
m4T mat = affine->ToMat4RowMajor();
m_GL->glPushMatrix();
m_GL->glLoadIdentity();
MultMatrix(mat);
m_GL->glLineWidth(3.0f);//One 3px wide, colored black, except green on x axis for post affine.
m_GL->DrawAffineHelper(index, selected, pre, final, true);
m_GL->glLineWidth(1.0f);//Again 1px wide, colored white, to give a white middle with black outline effect.
m_GL->DrawAffineHelper(index, selected, pre, final, false);
m_GL->glPointSize(5.0f);//Three black points, one in the center and two on the circle. Drawn big 5px first to give a black outline.
m_GL->glBegin(GL_POINTS);
m_GL->glColor4f(0.0f, 0.0f, 0.0f, selected ? 1.0f : 0.5f);
@ -978,14 +958,12 @@ void GLEmberController<T>::DrawAffine(Xform<T>* xform, bool pre, bool selected)
m_GL->glVertex2f(1.0f, 0.0f);
m_GL->glVertex2f(0.0f, 1.0f);
m_GL->glEnd();
m_GL->glLineWidth(2.0f);//Draw lines again for y axis only, without drawing the circle, using the color of the selected xform.
m_GL->glBegin(GL_LINES);
m_GL->glColor4f(color.r, color.g, color.b, 1.0f);
m_GL->glVertex2f(0.0f, 0.0f);
m_GL->glVertex2f(0.0f, 1.0f);
m_GL->glEnd();
m_GL->glPointSize(3.0f);//Draw smaller white points, to give a black outline effect.
m_GL->glBegin(GL_POINTS);
m_GL->glColor4f(1.0f, 1.0f, 1.0f, selected ? 1.0f : 0.5f);
@ -1010,7 +988,6 @@ void GLWidget::DrawAffineHelper(int index, bool selected, bool pre, bool final,
float px = 1.0f;
float py = 0.0f;
QColor col = final ? m_Fractorium->m_FinalXformComboColor : m_Fractorium->m_XformComboColors[index % XFORM_COLOR_COUNT];
glBegin(GL_LINES);
//Circle part.
@ -1030,7 +1007,6 @@ void GLWidget::DrawAffineHelper(int index, bool selected, bool pre, bool final,
float theta = float(M_PI) * 2.0f * float(i % 64) / 64.0f;
float fx = float(cos(theta));
float fy = float(sin(theta));
glVertex2f(px, py);
glVertex2f(fx, fy);
px = fx;
@ -1054,13 +1030,12 @@ void GLWidget::DrawAffineHelper(int index, bool selected, bool pre, bool final,
//The lines from the center to the circle.
glVertex2f(0.0f, 0.0f);//X axis.
glVertex2f(1.0f, 0.0f);
if (background)
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);//Y axis.
glVertex2f(0.0f, 1.0f);
glEnd();
}
@ -1080,8 +1055,7 @@ int GLEmberController<T>::UpdateHover(v3T& glCoords)
uint bestIndex = -1;
T bestDist = 10;
Ember<T>* ember = m_FractoriumEmberController->CurrentEmber();
m_HoverType = HoverNone;
m_HoverType = eHoverType::HoverNone;
//If there's a selected/current xform, check it first so it gets precedence over the others.
if (m_SelectedXform)
@ -1154,42 +1128,41 @@ bool GLEmberController<T>::CheckXformHover(Xform<T>* xform, v3T& glCoords, T& be
v3T xAxisScreen = glm::project(translation + xAxis, m_Modelview, m_Projection, m_Viewport);
v3T yAxis(xform->m_Affine.B(), xform->m_Affine.E(), 0);
v3T yAxisScreen = glm::project(translation + yAxis, m_Modelview, m_Projection, m_Viewport);
pos = translation;
dist = glm::distance(glCoords, transScreen);
if (dist < bestDist)
{
bestDist = dist;
m_HoverType = HoverTranslation;
m_HoverType = eHoverType::HoverTranslation;
m_HoverHandlePos = pos;
preFound = true;
}
pos = translation + xAxis;
dist = glm::distance(glCoords, xAxisScreen);
if (dist < bestDist)
{
bestDist = dist;
m_HoverType = HoverXAxis;
m_HoverType = eHoverType::HoverXAxis;
m_HoverHandlePos = pos;
preFound = true;
}
pos = translation + yAxis;
dist = glm::distance(glCoords, yAxisScreen);
if (dist < bestDist)
{
bestDist = dist;
m_HoverType = HoverYAxis;
m_HoverType = eHoverType::HoverYAxis;
m_HoverHandlePos = pos;
preFound = true;
}
if (preFound)
m_AffineType = AffinePre;
m_AffineType = eAffineType::AffinePre;
}
if (post)
@ -1200,42 +1173,41 @@ bool GLEmberController<T>::CheckXformHover(Xform<T>* xform, v3T& glCoords, T& be
v3T xAxisScreen = glm::project(translation + xAxis, m_Modelview, m_Projection, m_Viewport);
v3T yAxis(xform->m_Post.B(), xform->m_Post.E(), 0);
v3T yAxisScreen = glm::project(translation + yAxis, m_Modelview, m_Projection, m_Viewport);
pos = translation;
dist = glm::distance(glCoords, transScreen);
if (dist < bestDist)
{
bestDist = dist;
m_HoverType = HoverTranslation;
m_HoverType = eHoverType::HoverTranslation;
m_HoverHandlePos = pos;
postFound = true;
}
pos = translation + xAxis;
dist = glm::distance(glCoords, xAxisScreen);
if (dist < bestDist)
{
bestDist = dist;
m_HoverType = HoverXAxis;
m_HoverType = eHoverType::HoverXAxis;
m_HoverHandlePos = pos;
postFound = true;
}
pos = translation + yAxis;
dist = glm::distance(glCoords, yAxisScreen);
if (dist < bestDist)
{
bestDist = dist;
m_HoverType = HoverYAxis;
m_HoverType = eHoverType::HoverYAxis;
m_HoverHandlePos = pos;
postFound = true;
}
if (postFound)
m_AffineType = AffinePost;
m_AffineType = eAffineType::AffinePost;
}
return preFound || postFound;
@ -1264,23 +1236,21 @@ Affine2D<T> GLEmberController<T>::CalcDragXAxis()
{
v3T t3, newAxis, newPos;
Affine2D<T> result = m_DragSrcTransform;
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() &&
((m_DragModifier & DragModShift) == DragModShift) &&
((m_DragModifier & DragModAlt) == DragModAlt);
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
if (worldPivotShiftAlt)
t3 = v3T(0, 0, 0);
else
t3 = v3T(m_DragSrcTransform.O(), 0);
if ((m_DragModifier & DragModShift) == DragModShift)
if (GetShift())
{
v3T targetAxis = m_MouseWorldPos - t3;
v3T norm = glm::normalize(targetAxis);
if ((m_DragModifier & DragModControl) == DragModControl)
if (GetControl())
norm = SnapToNormalizedAngle(norm, 24);
if (worldPivotShiftAlt)
newAxis = norm * glm::length(m_DragSrcTransform.O() + m_DragSrcTransform.X());
else
@ -1288,7 +1258,7 @@ Affine2D<T> GLEmberController<T>::CalcDragXAxis()
}
else
{
if ((m_DragModifier & DragModControl) == DragModControl)
if (GetControl())
newPos = SnapToGrid(m_MouseWorldPos);
else
newPos = m_MouseWorldPos + m_DragHandleOffset;
@ -1296,7 +1266,7 @@ Affine2D<T> GLEmberController<T>::CalcDragXAxis()
newAxis = newPos - t3;
}
if ((m_DragModifier & DragModAlt) == DragModAlt)
if (GetAlt())
{
if (worldPivotShiftAlt)
result.X(v2T(newAxis) - m_DragSrcTransform.O());
@ -1309,7 +1279,6 @@ Affine2D<T> GLEmberController<T>::CalcDragXAxis()
}
m_DragHandlePos = v3T(result.O() + result.X(), 0);
return result;
}
@ -1336,21 +1305,19 @@ Affine2D<T> GLEmberController<T>::CalcDragYAxis()
{
v3T t3, newAxis, newPos;
Affine2D<T> result = m_DragSrcTransform;
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() &&
((m_DragModifier & DragModShift) == DragModShift) &&
((m_DragModifier & DragModAlt) == DragModAlt);
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
if (worldPivotShiftAlt)
t3 = v3T(0, 0, 0);
else
t3 = v3T(m_DragSrcTransform.O(), 0);
if ((m_DragModifier & DragModShift) == DragModShift)
if (GetShift())
{
v3T targetAxis = m_MouseWorldPos - t3;
v3T norm = glm::normalize(targetAxis);
if ((m_DragModifier & DragModControl) == DragModControl)
if (GetControl())
norm = SnapToNormalizedAngle(norm, 24);
if (worldPivotShiftAlt)
@ -1360,7 +1327,7 @@ Affine2D<T> GLEmberController<T>::CalcDragYAxis()
}
else
{
if ((m_DragModifier & DragModControl) == DragModControl)
if (GetControl())
newPos = SnapToGrid(m_MouseWorldPos);
else
newPos = m_MouseWorldPos + m_DragHandleOffset;
@ -1368,7 +1335,7 @@ Affine2D<T> GLEmberController<T>::CalcDragYAxis()
newAxis = newPos - t3;
}
if ((m_DragModifier & DragModAlt) == DragModAlt)
if (GetAlt())
{
if (worldPivotShiftAlt)
result.Y(v2T(newAxis) - m_DragSrcTransform.O());
@ -1381,7 +1348,6 @@ Affine2D<T> GLEmberController<T>::CalcDragYAxis()
}
m_DragHandlePos = v3T(result.O() + result.Y(), 0);
return result;
}
@ -1404,15 +1370,15 @@ Affine2D<T> GLEmberController<T>::CalcDragTranslation()
{
v3T newPos, newX, newY;
Affine2D<T> result = m_DragSrcTransform;
bool worldPivotShift = !m_Fractorium->LocalPivot() && ((m_DragModifier & DragModShift) == DragModShift);
bool worldPivotShift = !m_Fractorium->LocalPivot() && GetShift();
if ((m_DragModifier & DragModShift) == DragModShift)
if (GetShift())
{
v3T norm = glm::normalize(m_MouseWorldPos);
if ((m_DragModifier & DragModControl) == DragModControl)
if (GetControl())
norm = SnapToNormalizedAngle(norm, 12);
newPos = glm::length(m_DragSrcTransform.O()) * norm;
if (worldPivotShift)
@ -1420,13 +1386,12 @@ Affine2D<T> GLEmberController<T>::CalcDragTranslation()
T startAngle = atan2(m_DragSrcTransform.O().y, m_DragSrcTransform.O().x);
T endAngle = atan2(newPos.y, newPos.x);
T angle = startAngle - endAngle;
result.Rotate(angle * RAD_2_DEG);
}
}
else
{
if ((m_DragModifier & DragModControl) == DragModControl)
if (GetControl())
newPos = SnapToGrid(m_MouseWorldPos);
else
newPos = m_MouseWorldPos + m_DragHandleOffset;
@ -1434,7 +1399,6 @@ Affine2D<T> GLEmberController<T>::CalcDragTranslation()
result.O(v2T(newPos));
m_DragHandlePos = newPos;
return result;
}
@ -1453,5 +1417,5 @@ GLEmberControllerBase* GLWidget::GLController()
template class GLEmberController<float>;
#ifdef DO_DOUBLE
template class GLEmberController<double>;
template class GLEmberController<double>;
#endif

View File

@ -10,12 +10,10 @@
/// <param name="f">The window flags. Default: 0.</param>
FractoriumVariationsDialog::FractoriumVariationsDialog(FractoriumSettings* settings, QWidget* p, Qt::WindowFlags f)
: QDialog(p, f),
m_Settings(settings)
m_Settings(settings)
{
ui.setupUi(this);
auto table = ui.VariationsTable;
m_Vars = m_Settings->Variations();
Populate();
OnSelectAllButtonClicked(true);
@ -37,7 +35,6 @@ void FractoriumVariationsDialog::ForEachCell(std::function<void(QTableWidgetItem
auto table = ui.VariationsTable;
auto rows = table->rowCount();
auto cols = table->columnCount();
table->model()->blockSignals(true);
for (auto row = 0; row < rows; row++)
@ -57,10 +54,9 @@ void FractoriumVariationsDialog::ForEachSelectedCell(std::function<void(QTableWi
{
auto table = ui.VariationsTable;
QList<QTableWidgetItem*> selectedItems = table->selectedItems();
table->model()->blockSignals(true);
foreach(QTableWidgetItem* item, selectedItems)
foreach (QTableWidgetItem* item, selectedItems)
if (item)
func(item);
@ -74,13 +70,11 @@ void FractoriumVariationsDialog::ForEachSelectedCell(std::function<void(QTableWi
void FractoriumVariationsDialog::SyncSettings()
{
QMap<QString, QVariant> m;
ForEachCell([&](QTableWidgetItem* cb)
ForEachCell([&](QTableWidgetItem * cb)
{
if (!cb->text().isEmpty())
m[cb->text()] = cb->checkState() == Qt::CheckState::Checked;
});
m_Settings->Variations(m);
}
@ -100,7 +94,7 @@ const QMap<QString, QVariant>& FractoriumVariationsDialog::Map()
/// <param name="checked">Ignored</param>
void FractoriumVariationsDialog::OnSelectAllButtonClicked(bool checked)
{
ForEachCell([&](QTableWidgetItem* cb) { cb->setCheckState(Qt::CheckState::Checked); });
ForEachCell([&](QTableWidgetItem * cb) { cb->setCheckState(Qt::CheckState::Checked); });
}
/// <summary>
@ -109,7 +103,7 @@ void FractoriumVariationsDialog::OnSelectAllButtonClicked(bool checked)
/// <param name="checked">Ignored</param>
void FractoriumVariationsDialog::OnInvertSelectionButtonClicked(bool checked)
{
ForEachCell([&](QTableWidgetItem* cb)
ForEachCell([&](QTableWidgetItem * cb)
{
if (cb->checkState() != Qt::CheckState::Checked)
cb->setCheckState(Qt::CheckState::Checked);
@ -124,7 +118,7 @@ void FractoriumVariationsDialog::OnInvertSelectionButtonClicked(bool checked)
/// <param name="checked">Ignored</param>
void FractoriumVariationsDialog::OnSelectNoneButtonClicked(bool checked)
{
ForEachCell([&](QTableWidgetItem* cb) { cb->setCheckState(Qt::CheckState::Unchecked); });
ForEachCell([&](QTableWidgetItem * cb) { cb->setCheckState(Qt::CheckState::Unchecked); });
}
/// <summary>
@ -134,7 +128,6 @@ void FractoriumVariationsDialog::Populate()
{
auto table = ui.VariationsTable;
auto size = std::max<size_t>(std::max<size_t>(m_VariationList.RegSize(), m_VariationList.PreSize()), m_VariationList.PostSize());
table->setRowCount(size);
for (size_t i = 0; i < size; i++)
@ -152,7 +145,7 @@ void FractoriumVariationsDialog::Populate()
table->setItem(i, 1, cb);
SetCheckFromMap(cb, reg);
}
if (auto post = m_VariationList.GetVariation(i, eVariationType::VARTYPE_POST))
{
auto cb = new QTableWidgetItem(post->Name().c_str());
@ -174,7 +167,7 @@ void FractoriumVariationsDialog::OnVariationsTableItemChanged(QTableWidgetItem*
bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
if (ctrl)
ForEachSelectedCell([&](QTableWidgetItem* cb) { cb->setCheckState(item->checkState()); });
ForEachSelectedCell([&](QTableWidgetItem * cb) { cb->setCheckState(item->checkState()); });
}
/// <summary>
@ -213,7 +206,7 @@ void FractoriumVariationsDialog::showEvent(QShowEvent* e)
/// </summary>
void FractoriumVariationsDialog::DataToGui()
{
ForEachCell([&](QTableWidgetItem* cb)
ForEachCell([&](QTableWidgetItem * cb)
{
if (auto var = m_VariationList.GetVariation(cb->text().toStdString()))
SetCheckFromMap(cb, var);
@ -225,7 +218,7 @@ void FractoriumVariationsDialog::DataToGui()
/// </summary>
void FractoriumVariationsDialog::GuiToData()
{
ForEachCell([&](QTableWidgetItem* cb)
ForEachCell([&](QTableWidgetItem * cb)
{
if (auto var = m_VariationList.GetVariation(cb->text().toStdString()))
m_Vars[cb->text()] = (cb->checkState() == Qt::Checked);
@ -247,7 +240,6 @@ void FractoriumVariationsDialog::SetCheckFromMap(QTableWidgetItem* cb, const Var
else
{
bool chk = m_Vars[var->Name().c_str()].toBool();
cb->setCheckState(chk ? Qt::Checked : Qt::Unchecked);
}
}