gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

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:
Msource/xtJucePlugin/CMakeLists.txt | 1+
Msource/xtJucePlugin/weControlTree.cpp | 8++++----
Msource/xtJucePlugin/weControlTree.h | 2+-
Msource/xtJucePlugin/weControlTreeItem.cpp | 42++++++++++++++++++++++++++++++++++++++++--
Msource/xtJucePlugin/weControlTreeItem.h | 10+++++++---
Msource/xtJucePlugin/weData.cpp | 51++++++++++++++++++++++++++++++++++++++++++++++-----
Msource/xtJucePlugin/weData.h | 18+++++++++++-------
Msource/xtJucePlugin/weTablesTree.cpp | 2+-
Msource/xtJucePlugin/weTablesTreeItem.cpp | 2+-
Msource/xtJucePlugin/weTypes.h | 4++++
Asource/xtJucePlugin/weWaveDesc.cpp | 10++++++++++
Asource/xtJucePlugin/weWaveDesc.h | 25+++++++++++++++++++++++++
Msource/xtJucePlugin/weWaveTreeItem.cpp | 9+++++++++
Msource/xtJucePlugin/weWaveTreeItem.h | 2++
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();