diff --git a/Builds/MSVC/VS2015/Ember.vcxproj b/Builds/MSVC/VS2015/Ember.vcxproj
index 759bf99..57afae8 100644
--- a/Builds/MSVC/VS2015/Ember.vcxproj
+++ b/Builds/MSVC/VS2015/Ember.vcxproj
@@ -70,6 +70,7 @@
truefalseAnySuitable
+ trueWindows
@@ -99,6 +100,7 @@
falsefalsefalse
+ trueWindows
diff --git a/Builds/MSVC/VS2015/EmberAnimate.vcxproj b/Builds/MSVC/VS2015/EmberAnimate.vcxproj
index dafb3a7..c7d7152 100644
--- a/Builds/MSVC/VS2015/EmberAnimate.vcxproj
+++ b/Builds/MSVC/VS2015/EmberAnimate.vcxproj
@@ -67,6 +67,7 @@
truefalseAnySuitable
+ trueConsole
@@ -97,6 +98,7 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
truefalsefalse
+ trueConsole
diff --git a/Builds/MSVC/VS2015/EmberCL.vcxproj b/Builds/MSVC/VS2015/EmberCL.vcxproj
index 51b9935..04229f9 100644
--- a/Builds/MSVC/VS2015/EmberCL.vcxproj
+++ b/Builds/MSVC/VS2015/EmberCL.vcxproj
@@ -68,6 +68,7 @@
truefalseAnySuitable
+ trueWindows
@@ -96,6 +97,7 @@
falsetruefalse
+ trueWindows
diff --git a/Builds/MSVC/VS2015/EmberGenome.vcxproj b/Builds/MSVC/VS2015/EmberGenome.vcxproj
index cdac5fa..2959f7a 100644
--- a/Builds/MSVC/VS2015/EmberGenome.vcxproj
+++ b/Builds/MSVC/VS2015/EmberGenome.vcxproj
@@ -67,6 +67,7 @@
truefalseAnySuitable
+ trueConsole
@@ -97,6 +98,7 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
truefalsefalse
+ trueConsole
diff --git a/Builds/MSVC/VS2015/EmberRender.vcxproj b/Builds/MSVC/VS2015/EmberRender.vcxproj
index cef2440..ad01733 100644
--- a/Builds/MSVC/VS2015/EmberRender.vcxproj
+++ b/Builds/MSVC/VS2015/EmberRender.vcxproj
@@ -67,6 +67,7 @@
truefalseAnySuitable
+ trueConsole
@@ -98,6 +99,7 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
falsetruefalse
+ trueConsole
diff --git a/Builds/MSVC/VS2015/EmberTester.vcxproj b/Builds/MSVC/VS2015/EmberTester.vcxproj
index efe5eb4..7ec4eb5 100644
--- a/Builds/MSVC/VS2015/EmberTester.vcxproj
+++ b/Builds/MSVC/VS2015/EmberTester.vcxproj
@@ -67,6 +67,7 @@
truefalseAnySuitable
+ trueConsole
@@ -97,6 +98,7 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
truefalsefalse
+ trueConsole
diff --git a/Builds/MSVC/VS2015/Fractorium.vcxproj b/Builds/MSVC/VS2015/Fractorium.vcxproj
index cb1cf69..b463466 100644
--- a/Builds/MSVC/VS2015/Fractorium.vcxproj
+++ b/Builds/MSVC/VS2015/Fractorium.vcxproj
@@ -49,10 +49,10 @@
$(SolutionDir)Obj\$(TargetName)\$(Platform)\$(Configuration)\
- false
+ true
- false
+ true
@@ -74,6 +74,7 @@
falseLevel3AnySuitable
+ trueWindows
@@ -114,6 +115,7 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindowsd.dll" "$(OutDir)\platform
/bigobj -Zm150 %(AdditionalOptions)falseLevel3
+ trueWindows
diff --git a/archive/Info.plist b/Data/Info.plist
similarity index 100%
rename from archive/Info.plist
rename to Data/Info.plist
diff --git a/Source/Fractorium/EmberTreeWidgetItem.h b/Source/Fractorium/EmberTreeWidgetItem.h
index b1875a6..2076418 100644
--- a/Source/Fractorium/EmberTreeWidgetItem.h
+++ b/Source/Fractorium/EmberTreeWidgetItem.h
@@ -34,6 +34,11 @@ public:
{
}
+ //~EmberTreeWidgetItemBase()
+ //{
+ // qDebug() << "~EmberTreeWidgetItemBase()";
+ //}
+
///
/// Set the preview image for the tree widget item.
///
diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp
index c14abcc..8efe718 100644
--- a/Source/Fractorium/FractoriumLibrary.cpp
+++ b/Source/Fractorium/FractoriumLibrary.cpp
@@ -283,7 +283,11 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i
}
}
-void Fractorium::OnEmberTreeItemChanged(QTreeWidgetItem* item, int col) { m_Controller->EmberTreeItemChanged(item, col); }
+void Fractorium::OnEmberTreeItemChanged(QTreeWidgetItem* item, int col)
+{
+ if (ui.LibraryTree->topLevelItemCount())//This can sometimes be spurriously called even when the tree is empty.
+ m_Controller->EmberTreeItemChanged(item, col);
+}
///
/// Set the current ember to the selected item.
@@ -301,12 +305,17 @@ void FractoriumEmberController::EmberTreeItemDoubleClicked(QTreeWidgetItem* i
SetEmber(m_Fractorium->ui.LibraryTree->currentIndex().row(), false);
}
-void Fractorium::OnEmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col) { m_Controller->EmberTreeItemDoubleClicked(item, col); }
+void Fractorium::OnEmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col)
+{
+ if (ui.LibraryTree->topLevelItemCount())//This can sometimes be spurriously called even when the tree is empty.
+ m_Controller->EmberTreeItemDoubleClicked(item, col);
+}
///
-/// Move a library item at one index to the next index.
+/// Move a possibly disjoint selection of library items from their indices,
+/// to another index.
///
-/// The index of the source item to move
+/// The selected list of items to move
/// The destination index to move the item to
template
void FractoriumEmberController::MoveLibraryItems(const QModelIndexList& items, int destRow)
@@ -315,17 +324,16 @@ void FractoriumEmberController::MoveLibraryItems(const QModelIndexList& items
auto startRow = items[0].row();
auto tree = m_Fractorium->ui.LibraryTree;
auto top = tree->topLevelItem(0);
- list names;
+ list names;
for (auto& item : items)
if (auto temp = m_EmberFile.Get(item.row()))
- names.push_back(QString::fromStdString(temp->m_Name));
+ names.push_back(temp->m_Name);
auto b = m_EmberFile.m_Embers.begin();
auto result = Gather(b, m_EmberFile.m_Embers.end(), Advance(b, destRow), [&](const Ember& ember)
{
- auto qname = QString::fromStdString(ember.m_Name);
- auto position = std::find(names.begin(), names.end(), qname);
+ auto position = std::find(names.begin(), names.end(), ember.m_Name);
if (position != names.end())
{
@@ -335,7 +343,9 @@ void FractoriumEmberController::MoveLibraryItems(const QModelIndexList& items
return false;
});
+ tree->update();
SyncLibrary(eLibraryUpdate(eLibraryUpdate::INDEX | eLibraryUpdate::POINTER));
+ //SyncLibrary(eLibraryUpdate(eLibraryUpdate::INDEX | eLibraryUpdate::POINTER | eLibraryUpdate::NAME));
}
///
@@ -496,7 +506,11 @@ void FractoriumEmberController::SequenceTreeItemChanged(QTreeWidgetItem* item
}
}
-void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col) { m_Controller->SequenceTreeItemChanged(item, col); }
+void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col)
+{
+ if (ui.SequenceTree->topLevelItemCount())
+ m_Controller->SequenceTreeItemChanged(item, col);
+}
///
/// Wrapper around calling RenderPreviews with the appropriate values passed in for the previews in the sequence tree.
diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp
index 2949fab..84d0bc6 100644
--- a/Source/Fractorium/FractoriumRender.cpp
+++ b/Source/Fractorium/FractoriumRender.cpp
@@ -683,6 +683,7 @@ bool Fractorium::CreateControllerFromOptions()
Palette tempPalette;
#endif
QModelIndex index = ui.LibraryTree->currentIndex();
+ ui.LibraryTree->clear();//This must be here before FillLibraryTree() is called below, else a spurious EmberTreeItemChanged event will be called on a deleted object.
//First check if a controller has already been created, and if so, save its embers and gracefully shut it down.
if (m_Controller.get())
@@ -716,6 +717,12 @@ bool Fractorium::CreateControllerFromOptions()
prev->m_Palette = tempPalette;
m_Controller->SetEmberFile(efd, true);
+ //Template specific palette table and variations tree setup in controller constructor, but
+ //must manually setup the library tree here because it's after the embers were assigned.
+ //Passing row re-selects the item that was previously selected.
+ //This will eventually call FillParamTablesAndPalette(), which in addition to filling in various fields,
+ //will apply the palette adjustments.
+ m_Controller->FillLibraryTree(index.row());
m_Controller->SetEmber(current, true);
m_Controller->LockedScale(scale);
//Setting these and updating the GUI overwrites the work of clearing them done in SetEmber() above.
@@ -727,12 +734,6 @@ bool Fractorium::CreateControllerFromOptions()
m_PaletteBlurSpin->SetValueStealth(blur);
m_PaletteFrequencySpin->SetValueStealth(freq);
m_Controller->PaletteAdjust();//Applies the adjustments to temp and saves in m_Ember.m_Palette, then fills in the palette preview widget.
- //Template specific palette table and variations tree setup in controller constructor, but
- //must manually setup the library tree here because it's after the embers were assigned.
- //Passing row re-selects the item that was previously selected.
- //This will eventually call FillParamTablesAndPalette(), which in addition to filling in various fields,
- //will apply the palette adjustments.
- m_Controller->FillLibraryTree(index.row());
}
}
@@ -773,5 +774,5 @@ bool Fractorium::ControllersOk() { return m_Controller.get() && m_Controller->GL
template class FractoriumEmberController;
#ifdef DO_DOUBLE
-template class FractoriumEmberController;
+ template class FractoriumEmberController;
#endif
diff --git a/Source/Fractorium/Icons/Function-512.png b/Source/Fractorium/Icons/Function-512.png
index a46dd1a..4522c2e 100644
Binary files a/Source/Fractorium/Icons/Function-512.png and b/Source/Fractorium/Icons/Function-512.png differ
diff --git a/Source/Fractorium/Icons/grid.png b/Source/Fractorium/Icons/grid.png
index fce17c9..5169259 100644
Binary files a/Source/Fractorium/Icons/grid.png and b/Source/Fractorium/Icons/grid.png differ
diff --git a/Source/Fractorium/Icons/pic.png b/Source/Fractorium/Icons/pic.png
index a5e7bf9..f617f2a 100644
Binary files a/Source/Fractorium/Icons/pic.png and b/Source/Fractorium/Icons/pic.png differ
diff --git a/Source/Fractorium/LibraryTreeWidget.cpp b/Source/Fractorium/LibraryTreeWidget.cpp
index d081b64..af18cb0 100644
--- a/Source/Fractorium/LibraryTreeWidget.cpp
+++ b/Source/Fractorium/LibraryTreeWidget.cpp
@@ -27,14 +27,70 @@ void LibraryTreeWidget::dropEvent(QDropEvent* de)
}
else if (!items.empty())//Actually do the drop and move the item to a new location.
{
- int row = droppedIndex.row();
+ // get the list of the items that are about to be dragged
+ int i, row = droppedIndex.row();
DropIndicatorPosition dp = dropIndicatorPosition();
+ QList dragItems = selectedItems();
if (dp == QAbstractItemView::BelowItem)
row++;
+ auto itemat = this->itemFromIndex(droppedIndex);
+ QTreeWidget::dropEvent(de);//This internally changes the order of the items.
+
+ //Qt has a long standing major bug that rearranges the order of disjoint selections when
+ //The drop location is in between the disjoint regions.
+ //This is an attempt to correct for that bug by removing the dropped items, then re-inserting them
+ //in the order they were selected.
+ //This bug remains present as of Qt 5.8: https://bugreports.qt.io/browse/QTBUG-45320
+ if (auto top = topLevelItem(0))
+ {
+ if (itemat)
+ {
+ auto offsetitem = this->indexFromItem(itemat);
+
+ if (dp == QAbstractItemView::BelowItem)
+ {
+ auto itemrow = offsetitem.row() + 1;
+
+ for (i = 0; i < dragItems.size(); i++)
+ {
+ if (itemrow < top->childCount())
+ top->takeChild(itemrow);
+ }
+
+ for (i = 0; i < dragItems.size(); i++)
+ {
+ auto offset = i + itemrow;
+
+ if (offset <= top->childCount())
+ top->insertChild(offset, dragItems[i]);
+ }
+ }
+ else
+ {
+ auto itemrow = offsetitem.row();//Will be at least 1 if dropped above it.
+ auto offset = itemrow;
+
+ for (i = 0; i < dragItems.size(); i++)
+ {
+ offset--;
+
+ if (offset < top->childCount())
+ top->takeChild(offset);
+ }
+
+ for (i = 0; i < dragItems.size(); i++)
+ {
+ if (offset <= top->childCount())
+ top->insertChild(offset, dragItems[i]);
+
+ offset++;
+ }
+ }
+ }
+ }
+
QTimer::singleShot(500, [ = ]() { m_Fractorium->m_Controller->MoveLibraryItems(items, row); });//Need to fire this after this event has internally reshuffled the items.
}
-
- QTreeWidget::dropEvent(de);
}
\ No newline at end of file