commit b435ea4c39826ebc050ed68504cfae49cdd93af5
parent 55422db8d242c11cd44d1bfd5ab69654744ad261
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sat, 28 Sep 2024 20:43:57 +0200
begin control table editing via drag & drop
Diffstat:
14 files changed, 162 insertions(+), 24 deletions(-)
diff --git a/source/xtJucePlugin/CMakeLists.txt b/source/xtJucePlugin/CMakeLists.txt
@@ -21,6 +21,7 @@ set(SOURCES
weTreeItem.cpp weTreeItem.h
weTypes.h
weWaveCategoryTreeItem.cpp weWaveCategoryTreeItem.h
+ weWaveDesc.cpp weWaveDesc.h
weWaveform.cpp weWaveform.h
weWaveTree.cpp weWaveTree.h
weWaveTreeItem.cpp weWaveTreeItem.h
diff --git a/source/xtJucePlugin/weControlTree.cpp b/source/xtJucePlugin/weControlTree.cpp
@@ -10,7 +10,7 @@ namespace xtJucePlugin
m_onTableChanged.set(_editor.getData().onTableChanged, [this](const uint32_t& _index)
{
if(_index == m_table)
- onTableChanged();
+ onTableChanged(true);
});
for(uint32_t i=0; i<m_items.size(); ++i)
@@ -26,12 +26,12 @@ namespace xtJucePlugin
if(_index == m_table)
return;
m_table = _index;
- onTableChanged();
+ onTableChanged(false);
}
- void ControlTree::onTableChanged()
+ void ControlTree::onTableChanged(bool _tableHasChanged)
{
for (auto* item : m_items)
- item->setTable(m_table);
+ item->setTable(m_table, _tableHasChanged);
}
}
diff --git a/source/xtJucePlugin/weControlTree.h b/source/xtJucePlugin/weControlTree.h
@@ -16,7 +16,7 @@ namespace xtJucePlugin
void setTable(uint32_t _index);
private:
- void onTableChanged();
+ void onTableChanged(bool _tableHasChanged);
pluginLib::EventListener<uint32_t> m_onTableChanged;
uint32_t m_table = ~0;
diff --git a/source/xtJucePlugin/weControlTreeItem.cpp b/source/xtJucePlugin/weControlTreeItem.cpp
@@ -1,5 +1,6 @@
#include "weControlTreeItem.h"
+#include "weWaveDesc.h"
#include "weWaveTreeItem.h"
#include "xtWaveEditor.h"
@@ -39,14 +40,51 @@ namespace xtJucePlugin
repaintItem();
}
- void ControlTreeItem::setTable(const uint32_t _table)
+ void ControlTreeItem::setTable(const uint32_t _table, const bool _tableHasChanged)
{
- if(m_table == _table)
+ if(m_table == _table && !_tableHasChanged)
return;
m_table = _table;
setWave(m_editor.getData().getWaveIndex(_table, m_index));
}
+ juce::var ControlTreeItem::getDragSourceDescription()
+ {
+ if(m_wave == g_invalidWaveIndex)
+ return TreeViewItem::getDragSourceDescription();
+
+ auto* desc = new WaveDesc();
+ desc->waveIndex = m_wave;
+ desc->source = WaveDescSource::ControlList;
+ desc->listIndex = m_index;
+ return desc;
+ }
+
+ bool ControlTreeItem::isInterestedInDragSource(const juce::DragAndDropTarget::SourceDetails& _dragSourceDetails)
+ {
+ return WaveDesc::fromDragSource(_dragSourceDetails) != nullptr;
+ }
+
+ void ControlTreeItem::itemDropped(const juce::DragAndDropTarget::SourceDetails& _dragSourceDetails, int _insertIndex)
+ {
+ const auto* waveDesc = WaveDesc::fromDragSource(_dragSourceDetails);
+ if(!waveDesc)
+ return;
+
+ auto& data = m_editor.getData();
+
+ // if the source is the control list, we swap two entries. if the source is the wave list, we add a new wave
+ if(waveDesc->source == WaveDescSource::ControlList)
+ {
+ data.swapTableEntries(m_table, m_index, waveDesc->listIndex);
+ setSelected(true, true, juce::dontSendNotification);
+ }
+ else if(waveDesc->source == WaveDescSource::WaveList)
+ {
+ data.setTableWave(m_table, m_index, waveDesc->waveIndex);
+ }
+ }
+
void ControlTreeItem::onWaveChanged() const
{
repaintItem();
diff --git a/source/xtJucePlugin/weControlTreeItem.h b/source/xtJucePlugin/weControlTreeItem.h
@@ -1,6 +1,7 @@
#pragma once
#include "weTreeItem.h"
+#include "weTypes.h"
#include "jucePluginLib/event.h"
@@ -18,7 +19,10 @@ namespace xtJucePlugin
void paintItem(juce::Graphics& _g, int _width, int _height) override;
void setWave(uint32_t _wave);
- void setTable(uint32_t _table);
+ void setTable(uint32_t _table, bool _tableHasChanged);
+ juce::var getDragSourceDescription() override;
+ bool isInterestedInDragSource(const juce::DragAndDropTarget::SourceDetails& _dragSourceDetails) override;
+ void itemDropped(const juce::DragAndDropTarget::SourceDetails& _dragSourceDetails, int _insertIndex) override;
private:
void onWaveChanged() const;
@@ -26,8 +30,8 @@ namespace xtJucePlugin
WaveEditor& m_editor;
const uint32_t m_index;
- uint32_t m_wave = ~0;
- uint32_t m_table = ~0;
+ uint32_t m_wave = g_invalidWaveIndex;
+ uint32_t m_table = g_invalidTableIndex;
pluginLib::EventListener<uint32_t> m_onWaveChanged;
};
diff --git a/source/xtJucePlugin/weData.cpp b/source/xtJucePlugin/weData.cpp
@@ -58,7 +58,7 @@ namespace xtJucePlugin
if(m_currentWaveRequestIndex == index)
{
- m_currentWaveRequestIndex = InvalidWaveIndex;
+ m_currentWaveRequestIndex = g_invalidWaveIndex;
requestData();
}
}
@@ -78,7 +78,7 @@ namespace xtJucePlugin
if(m_currentTableRequestIndex == index)
{
- m_currentTableRequestIndex = InvalidWaveIndex;
+ m_currentTableRequestIndex = g_invalidWaveIndex;
requestData();
}
}
@@ -103,15 +103,56 @@ namespace xtJucePlugin
uint32_t WaveEditorData::getWaveIndex(uint32_t _tableIndex, uint32_t _indexInTable) const
{
if(_tableIndex >= m_tables.size())
- return InvalidWaveIndex;
+ return g_invalidWaveIndex;
if(_indexInTable >= std::tuple_size<xt::TableData>())
- return InvalidWaveIndex;
+ return g_invalidWaveIndex;
const auto table = m_tables[_tableIndex];
if(!table)
- return InvalidWaveIndex;
+ return g_invalidWaveIndex;
return (*table)[_indexInTable];
}
+ std::optional<xt::TableData> WaveEditorData::getTable(uint32_t _tableIndex) const
+ {
+ if(_tableIndex >= m_tables.size())
+ return {};
+ return m_tables[_tableIndex];
+ }
+
+ bool WaveEditorData::swapTableEntries(uint32_t _table, uint32_t _indexA, uint32_t _indexB)
+ {
+ if(_indexA == _indexB)
+ return false;
+ if(_table >= m_tables.size())
+ return false;
+ const auto& table = m_tables[_table];
+ if(!table)
+ return false;
+ auto t = *table;
+ std::swap(t[_indexA], t[_indexB]);
+ m_tables[_table] = t;
+ onTableChanged(_table);
+ return true;
+ }
+
+ bool WaveEditorData::setTableWave(uint32_t _table, uint32_t _index, uint32_t _waveIndex)
+ {
+ if(_table >= m_tables.size())
+ return false;
+ const auto& table = m_tables[_table];
+ if(!table)
+ return false;
+ auto t = *table;
+ if(_index >= t.size())
+ return false;
+ if(t[_index] == _waveIndex)
+ return false;
+ t[_index] = static_cast<uint16_t>(_waveIndex);
+ m_tables[_table] = t;
+ onTableChanged(_table);
+ return true;
+ }
+
std::optional<xt::WaveData> WaveEditorData::getWave(const uint32_t _tableIndex, const uint32_t _indexInTable) const
{
return getWave(getWaveIndex(_tableIndex, _indexInTable));
diff --git a/source/xtJucePlugin/weData.h b/source/xtJucePlugin/weData.h
@@ -19,8 +19,6 @@ namespace xtJucePlugin
class WaveEditorData
{
public:
- static constexpr uint32_t InvalidWaveIndex = std::numeric_limits<uint32_t>::max();
-
pluginLib::Event<uint32_t> onWaveChanged;
pluginLib::Event<uint32_t> onTableChanged;
@@ -28,16 +26,22 @@ namespace xtJucePlugin
void requestData();
- bool isWaitingForWave() const { return m_currentWaveRequestIndex != InvalidWaveIndex; }
- bool isWaitingForTable() const { return m_currentTableRequestIndex != InvalidWaveIndex; }
+ bool isWaitingForWave() const { return m_currentWaveRequestIndex != g_invalidWaveIndex; }
+ bool isWaitingForTable() const { return m_currentTableRequestIndex != g_invalidWaveIndex; }
bool isWaitingForData() const { return isWaitingForWave() || isWaitingForTable(); }
void onReceiveWave(const pluginLib::MidiPacket::Data& _data, const std::vector<uint8_t>& _msg);
void onReceiveTable(const pluginLib::MidiPacket::Data& _data, const std::vector<uint8_t>& _msg);
+
std::optional<xt::WaveData> getWave(uint32_t _waveIndex) const;
- uint32_t getWaveIndex(uint32_t _tableIndex, uint32_t _indexInTable) const;
std::optional<xt::WaveData> getWave(uint32_t _tableIndex, uint32_t _indexInTable) const;
+ uint32_t getWaveIndex(uint32_t _tableIndex, uint32_t _indexInTable) const;
+
+ std::optional<xt::TableData> getTable(uint32_t _tableIndex) const;
+ bool swapTableEntries(uint32_t _table, uint32_t _indexA, uint32_t _indexB);
+ bool setTableWave(uint32_t _table, uint32_t _index, uint32_t _waveIndex);
+
static uint32_t toIndex(const pluginLib::MidiPacket::Data& _data);
static bool isAlgorithmicTable(uint32_t _index);
@@ -51,8 +55,8 @@ namespace xtJucePlugin
Controller& m_controller;
- uint32_t m_currentWaveRequestIndex = InvalidWaveIndex;
- uint32_t m_currentTableRequestIndex = InvalidWaveIndex;
+ uint32_t m_currentWaveRequestIndex = g_invalidWaveIndex;
+ uint32_t m_currentTableRequestIndex = g_invalidWaveIndex;
std::array<std::optional<xt::WaveData>, xt::Wave::g_romWaveCount> m_romWaves;
std::array<std::optional<xt::WaveData>, xt::Wave::g_ramWaveCount> m_ramWaves;
diff --git a/source/xtJucePlugin/weTablesTree.cpp b/source/xtJucePlugin/weTablesTree.cpp
@@ -8,7 +8,7 @@
namespace xtJucePlugin
{
- TablesTree::TablesTree(WaveEditor& _editor): Tree(_editor)
+ TablesTree::TablesTree(WaveEditor& _editor) : Tree(_editor)
{
for(uint32_t i=0; i<xt::Wave::g_tableCount; ++i)
{
diff --git a/source/xtJucePlugin/weTablesTreeItem.cpp b/source/xtJucePlugin/weTablesTreeItem.cpp
@@ -23,7 +23,7 @@ namespace xtJucePlugin
});
}
- void TablesTreeItem::itemSelectionChanged(bool _isNowSelected)
+ void TablesTreeItem::itemSelectionChanged(const bool _isNowSelected)
{
TreeItem::itemSelectionChanged(_isNowSelected);
m_editor.setSelectedTable(m_index);
diff --git a/source/xtJucePlugin/weTypes.h b/source/xtJucePlugin/weTypes.h
@@ -16,4 +16,8 @@ namespace xtJucePlugin
};
static constexpr float g_waveEditorScale = 2.0f * 1.3f;
+
+ static constexpr uint32_t g_invalidIndex = std::numeric_limits<uint32_t>::max();
+ static constexpr uint32_t g_invalidWaveIndex = g_invalidIndex;
+ static constexpr uint32_t g_invalidTableIndex = g_invalidIndex;
}
diff --git a/source/xtJucePlugin/weWaveDesc.cpp b/source/xtJucePlugin/weWaveDesc.cpp
@@ -0,0 +1,10 @@
+#include "weWaveDesc.h"
+
+namespace xtJucePlugin
+{
+ WaveDesc* WaveDesc::fromDragSource(const juce::DragAndDropTarget::SourceDetails& _sourceDetails)
+ {
+ auto* desc = dynamic_cast<WaveDesc*>(_sourceDetails.description.getObject());
+ return desc;
+ }
+}
diff --git a/source/xtJucePlugin/weWaveDesc.h b/source/xtJucePlugin/weWaveDesc.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "weData.h"
+
+#include "juce_gui_basics/juce_gui_basics.h"
+
+namespace xtJucePlugin
+{
+ enum class WaveDescSource
+ {
+ Invalid,
+ ControlList,
+ WaveList
+ };
+
+ struct WaveDesc : juce::ReferenceCountedObject
+ {
+ uint32_t waveIndex = g_invalidWaveIndex;
+ uint32_t tableIndex = g_invalidIndex;
+ uint32_t listIndex = g_invalidIndex;
+ xt::WaveData data;
+ WaveDescSource source = WaveDescSource::Invalid;
+ static WaveDesc* fromDragSource(const juce::DragAndDropTarget::SourceDetails& _sourceDetails);
+ };
+}
diff --git a/source/xtJucePlugin/weWaveTreeItem.cpp b/source/xtJucePlugin/weWaveTreeItem.cpp
@@ -1,6 +1,7 @@
#include "weWaveTreeItem.h"
#include "weWaveCategoryTreeItem.h"
+#include "weWaveDesc.h"
#include "xtWaveEditor.h"
namespace xtJucePlugin
@@ -62,6 +63,14 @@ namespace xtJucePlugin
m_editor.setSelectedWave(m_waveIndex);
}
+ juce::var WaveTreeItem::getDragSourceDescription()
+ {
+ auto* desc = new WaveDesc();
+ desc->waveIndex = m_waveIndex;
+ desc->source = WaveDescSource::WaveList;
+ return desc;
+ }
+
void WaveTreeItem::onWaveChanged(const uint32_t _index)
{
if(_index != m_waveIndex)
diff --git a/source/xtJucePlugin/weWaveTreeItem.h b/source/xtJucePlugin/weWaveTreeItem.h
@@ -23,6 +23,8 @@ namespace xtJucePlugin
static WaveCategory getCategory(uint32_t _waveIndex);
void itemSelectionChanged(bool isNowSelected) override;
+
+ juce::var getDragSourceDescription() override;
private:
void onWaveChanged(uint32_t _index);
void onWaveChanged();