From 8c1be957fee69c987d06d77c2460604180776f21 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 14 Jul 2019 17:22:36 +0100 Subject: [PATCH] decoupling achieved. compiles. doesn't immediately explode. but neither banks nor presets visible. --- Source/FilePicker.cpp | 6 +- Source/FilePicker.h | 6 +- Source/Pills.cpp | 82 +++++++++++----- Source/Pills.h | 5 +- Source/PluginEditor.cpp | 4 +- Source/TableComponent.cpp | 9 +- Source/TableComponent.h | 1 - Source/TablesComponent.cpp | 190 +++++++++++++++++++------------------ Source/TablesComponent.h | 26 ++--- 9 files changed, 183 insertions(+), 146 deletions(-) diff --git a/Source/FilePicker.cpp b/Source/FilePicker.cpp index dbd6930..7a74eef 100644 --- a/Source/FilePicker.cpp +++ b/Source/FilePicker.cpp @@ -7,8 +7,8 @@ #include "Util.h" FilePicker::FilePicker( - AudioProcessorValueTreeState& valueTreeState, - FluidSynthModel& fluidSynthModel + AudioProcessorValueTreeState& valueTreeState + // FluidSynthModel& fluidSynthModel ) : fileChooser{ "File", @@ -20,7 +20,7 @@ FilePicker::FilePicker( String(), "Choose a Soundfont file to load into the synthesizer"} , valueTreeState{valueTreeState} -, fluidSynthModel{fluidSynthModel} +// , fluidSynthModel{fluidSynthModel} // , currentPath{} { // faster (rounded edges introduce transparency) diff --git a/Source/FilePicker.h b/Source/FilePicker.h index 1c3e39d..f590604 100644 --- a/Source/FilePicker.h +++ b/Source/FilePicker.h @@ -15,8 +15,8 @@ class FilePicker: public Component, { public: FilePicker( - AudioProcessorValueTreeState& valueTreeState, - FluidSynthModel& fluidSynthModel + AudioProcessorValueTreeState& valueTreeState + // FluidSynthModel& fluidSynthModel ); ~FilePicker(); @@ -41,7 +41,7 @@ private: FilenameComponent fileChooser; AudioProcessorValueTreeState& valueTreeState; - FluidSynthModel& fluidSynthModel; + // FluidSynthModel& fluidSynthModel; String currentPath; diff --git a/Source/Pills.cpp b/Source/Pills.cpp index 438f7a6..cb03df7 100644 --- a/Source/Pills.cpp +++ b/Source/Pills.cpp @@ -4,6 +4,7 @@ #include "Pills.h" #include "MyColours.h" +#include using namespace std; @@ -14,7 +15,8 @@ Pill::Pill( bool isLast ) // : pills{pills} -: bank{bank} +: valueTreeState{valueTreeState} +, bank{bank} , textButton{String(bank)} { textButton.setConnectedEdges ( @@ -25,16 +27,18 @@ Pill::Pill( loadToggleState(); textButton.setClickingTogglesState(true); - valueTreeState.state.addListener(this); + valueTreeState.addParameterListener("bank", this); +// valueTreeState.state.addListener(this); textButton.addListener(this); } Pill::~Pill() { - valueTreeState.state.removeListener(this); + valueTreeState.removeParameterListener("bank", this); +// valueTreeState.state.removeListener(this); textButton.removeListener(this); } -Pill::loadToggleState() { +void Pill::loadToggleState() { RangedAudioParameter *param {valueTreeState.getParameter("bank")}; jassert(dynamic_cast (param) != nullptr); AudioParameterInt* castParam {dynamic_cast (param)}; @@ -57,13 +61,13 @@ void Pill::parameterChanged(const String& parameterID, float newValue) { } } -void Pill::valueTreePropertyChanged( - ValueTree& treeWhosePropertyHasChanged, - const Identifier& property) { - if (treeWhosePropertyHasChanged.getType() == StringRef("presets")) { - loadModelFrom(treeWhosePropertyHasChanged); - } -} +// void Pill::valueTreePropertyChanged( +// ValueTree& treeWhosePropertyHasChanged, +// const Identifier& property) { +// if (treeWhosePropertyHasChanged.getType() == StringRef("presets")) { +// loadModelFrom(treeWhosePropertyHasChanged); +// } +// } Pills::Pills( AudioProcessorValueTreeState& valueTreeState @@ -83,7 +87,8 @@ Pills::Pills( setOpaque (true); // populate(initiallySelectedItem); - loadModelFrom(valueTreeState.state.getChildWithName("banks")); + ValueTree banks{valueTreeState.state.getChildWithName("banks")}; + loadModelFrom(banks); valueTreeState.state.addListener(this); } @@ -109,11 +114,12 @@ void Pills::loadModelFrom(ValueTree& banks) { // rows.push_back(unique_ptr(new Pill(), [](Pill* pill) { // pill->remo // })); - pills.emplace_back( - this.valueTreeState, + pills.push_back( + make_unique( + valueTreeState, num, i == 0, - i == numChildren - 1); + i == numChildren - 1)); } } @@ -160,21 +166,51 @@ void Pills::loadModelFrom(ValueTree& banks) { // } void Pills::cycle(bool right) { - // TODO: base this on valueTree - int currentIx = static_cast(distance(pills.begin(), find(pills.begin(), pills.end(), selected))); + RangedAudioParameter *param {valueTreeState.getParameter("bank")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + int currentlySelectedBank{castParam->get()}; + + ValueTree banks{valueTreeState.state.getChildWithName("banks")}; +// int numChildren{banks.getNumChildren()}; + + vector bankInts; + bankInts.resize(banks.getNumChildren()); + + transform(banks.begin(), banks.end(), bankInts.begin(), [](ValueTree bank) -> int { + return bank.getProperty("num"); + }); + +// int closestBank{currentlySelectedBank}; +// for(int i{0}; i < numChildren; i++) { +// ValueTree child{banks.getChild(i)}; +// int proposedBank{child.getProperty("num")}; +// if (right && proposedBank > currentlySelectedBank) { +// closestBank = jmin(closestBank, proposedBank); +// } else if (left ) +// } + + int currentIx{static_cast(distance(bankInts.begin(), find(bankInts.begin(), bankInts.end(), currentlySelectedBank)))}; currentIx += right ? 1 : pills.size()-1; - pills[currentIx % pills.size()]->textButton.triggerClick(); + // pills[currentIx % pills.size()]->textButton.triggerClick(); + *castParam = bankInts[currentIx % bankInts.size()]; + + + // TODO: base this on valueTree + // int currentIx = static_cast(distance(pills.begin(), find(pills.begin(), pills.end(), selected))); + // currentIx += right ? 1 : pills.size()-1; + // pills[currentIx % pills.size()]->textButton.triggerClick(); } void Pills::resized() { int index = 0; Rectangle r (getLocalBounds()); - const int equalWidth = r.proportionOfWidth(buttons.size() <= 0 ? 1.0 : 1.0f/buttons.size()); - for(TextButton* t : buttons) { + const int equalWidth = r.proportionOfWidth(pills.size() <= 0 ? 1.0 : 1.0f/pills.size()); + for(auto& pill : pills) { Rectangle r2 (getLocalBounds()); r2.removeFromLeft(equalWidth * index); - r2.removeFromRight(equalWidth * (buttons.size()-index-1)); - t->setBounds (r2); + r2.removeFromRight(equalWidth * (static_cast(pills.size())-index-1)); + pill->textButton.setBounds (r2); index++; } } @@ -185,4 +221,4 @@ void Pills::resized() { void Pills::paint(Graphics& g) { g.fillAll(MyColours::getUIColourIfAvailable(LookAndFeel_V4::ColourScheme::UIColour::windowBackground, Colours::lightgrey)); -} \ No newline at end of file +} diff --git a/Source/Pills.h b/Source/Pills.h index 1440ae1..c66f756 100644 --- a/Source/Pills.h +++ b/Source/Pills.h @@ -32,8 +32,7 @@ private: TextButton textButton; friend class Pills; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pill) -} +}; class Pills : public Component @@ -89,4 +88,4 @@ private: void paint(Graphics& g) override; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pills) -}; \ No newline at end of file +}; diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 6599001..b062ff3 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -21,8 +21,8 @@ JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor( , valueTreeState{valueTreeState} // sharedParams{p.getSharedParams()}, , midiKeyboard{p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard} -, tablesComponent{valueTreeState, p.getFluidSynthModel()} -, filePicker{valueTreeState, p.getFluidSynthModel()} +, tablesComponent{valueTreeState} +, filePicker{valueTreeState} , slidersComponent{valueTreeState, p.getFluidSynthModel()} { // set resize limits for this plug-in diff --git a/Source/TableComponent.cpp b/Source/TableComponent.cpp index 0023c4b..3bedb14 100644 --- a/Source/TableComponent.cpp +++ b/Source/TableComponent.cpp @@ -17,7 +17,7 @@ using namespace Util; This class shows how to implement a TableListBoxModel to show in a TableListBox. */ TableComponent::TableComponent( - AudioProcessorValueTreeState& valueTreeState, + AudioProcessorValueTreeState& valueTreeState // const vector &columns, // const vector &rows, // const function &onRowSelected, @@ -74,7 +74,8 @@ TableComponent::TableComponent( table.setWantsKeyboardFocus(false); // table.selectRow(); - loadModelFrom(valueTreeState.state.getChildWithName("presets")); + ValueTree presets{valueTreeState.state.getChildWithName("presets")}; + loadModelFrom(presets); // selectCurrentPreset(); // we could now change some initial settings.. @@ -160,9 +161,9 @@ void TableComponent::paintRowBackground ( String TableRow::getStringContents(int columnId) { if (columnId <= 1) { - return String(row.preset); + return String(preset); } - return row.name; + return name; } // This is overloaded from TableListBoxModel, and must paint any cells that aren't using custom diff --git a/Source/TableComponent.h b/Source/TableComponent.h index 8292249..41feaa3 100644 --- a/Source/TableComponent.h +++ b/Source/TableComponent.h @@ -29,7 +29,6 @@ private: String name; friend class TableComponent; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableRow) }; diff --git a/Source/TablesComponent.cpp b/Source/TablesComponent.cpp index 6549909..31284bc 100644 --- a/Source/TablesComponent.cpp +++ b/Source/TablesComponent.cpp @@ -8,105 +8,107 @@ using namespace std; using namespace placeholders; TablesComponent::TablesComponent( - AudioProcessorValueTreeState& valueTreeState, - FluidSynthModel& fluidSynthModel + AudioProcessorValueTreeState& valueTreeState + // FluidSynthModel& fluidSynthModel ) : valueTreeState{valueTreeState} -, fluidSynthModel{fluidSynthModel} -, banksToPresets{fluidSynthModel.getBanks()} -, initialised{false} +// , fluidSynthModel{fluidSynthModel} +, banks{valueTreeState} +, presetTable{valueTreeState} +// , banksToPresets{fluidSynthModel.getBanks()} +// , initialised{false} { - fluid_preset_t* currentPreset = getCurrentPreset(); - selectedBank = -1; - int selectedPreset = -1; + // fluid_preset_t* currentPreset = getCurrentPreset(); + // selectedBank = -1; + // int selectedPreset = -1; - if (currentPreset != nullptr) { - selectedBank = fluid_preset_get_banknum(currentPreset); - selectedPreset = fluid_preset_get_num(currentPreset); - } + // if (currentPreset != nullptr) { + // selectedBank = fluid_preset_get_banknum(currentPreset); + // selectedPreset = fluid_preset_get_num(currentPreset); + // } // auto rowToPresetMapper = [this](const vector &row) { // return stoi(row[0]); // }; - auto itemToBankMapper = [](const string &item) { - return stoi(item); - }; + // auto itemToBankMapper = [](const string &item) { + // return stoi(item); + // }; - presetTable = new TableComponent( - valueTreeState, - // {"#", "Name"}, - // mapPresets( - // banksToPresets, - // selectedBank - // ), - // [this](int preset){ - // this->onPresetSelected(preset); - // }, - // rowToPresetMapper, - // presetToIndexMapper(selectedPreset) - ); - banks = new Pills( - "Banks", - mapBanks(banksToPresets), - [this](int bank){ - this->onBankSelected(bank); - }, - itemToBankMapper, - selectedBank - ); + // presetTable = new TableComponent( + // valueTreeState, + // // {"#", "Name"}, + // // mapPresets( + // // banksToPresets, + // // selectedBank + // // ), + // // [this](int preset){ + // // this->onPresetSelected(preset); + // // }, + // // rowToPresetMapper, + // // presetToIndexMapper(selectedPreset) + // ); + // banks = new Pills( + // "Banks", + // mapBanks(banksToPresets), + // [this](int bank){ + // this->onBankSelected(bank); + // }, + // itemToBankMapper, + // selectedBank + // ); - presetTable->setWantsKeyboardFocus(false); + presetTable.setWantsKeyboardFocus(false); addAndMakeVisible(presetTable); addAndMakeVisible(banks); - initialised = true; + // initialised = true; - fluidSynthModel.addListener(this); + // fluidSynthModel.addListener(this); } -fluid_preset_t* TablesComponent::getCurrentPreset() { - shared_ptr synth {fluidSynthModel.getSynth()}; +// fluid_preset_t* TablesComponent::getCurrentPreset() { +// shared_ptr synth {fluidSynthModel.getSynth()}; - return fluid_synth_get_channel_preset(synth.get(), fluidSynthModel.getChannel()); -} +// return fluid_synth_get_channel_preset(synth.get(), fluidSynthModel.getChannel()); +// } -Preset TablesComponent::getFirstPresetInBank(int bank) { - pair iterators = banksToPresets.equal_range(bank); - BanksToPresets::const_iterator it = iterators.first; - return it->second; -} +// Preset TablesComponent::getFirstPresetInBank(int bank) { +// pair iterators = banksToPresets.equal_range(bank); +// BanksToPresets::const_iterator it = iterators.first; +// return it->second; +// } -void TablesComponent::onBankSelected(int bank) { - if (!initialised || bank == -1) { - return; - } - cout << "Bank " << bank << endl; - selectedBank = bank; - Preset firstPresetInBank = getFirstPresetInBank(bank); - presetTable->setRows( - mapPresets( - banksToPresets, - bank - ), - presetToIndexMapper(firstPresetInBank.getPreset()) - ); -} +// void TablesComponent::onBankSelected(int bank) { +// if (!initialised || bank == -1) { +// return; +// } +// cout << "Bank " << bank << endl; +// selectedBank = bank; +// Preset firstPresetInBank = getFirstPresetInBank(bank); +// presetTable->setRows( +// mapPresets( +// banksToPresets, +// bank +// ), +// presetToIndexMapper(firstPresetInBank.getPreset()) +// ); +// } -int TablesComponent::presetToIndexMapper(int preset) { - int ix = 0; - pair iterators = this->banksToPresets.equal_range(this->selectedBank); - for (auto it = iterators.first; it != iterators.second; ++it, ix++) { - Preset b = it->second; - if (preset == b.getPreset()) { - return ix; - } - } - return 0; -} +// int TablesComponent::presetToIndexMapper(int preset) { +// int ix = 0; +// pair iterators = this->banksToPresets.equal_range(this->selectedBank); +// for (auto it = iterators.first; it != iterators.second; ++it, ix++) { +// Preset b = it->second; +// if (preset == b.getPreset()) { +// return ix; +// } +// } +// return 0; +// } // void TablesComponent::onPresetSelected(int preset) { // if (!initialised || preset == -1) { @@ -117,25 +119,25 @@ int TablesComponent::presetToIndexMapper(int preset) { // fluidSynthModel.changePreset(selectedBank, preset); // } -TablesComponent::~TablesComponent() { - delete presetTable; - delete banks; - // fluidSynthModel.removeListener(this); -} +// TablesComponent::~TablesComponent() { +// delete presetTable; +// delete banks; +// // fluidSynthModel.removeListener(this); +// } -vector TablesComponent::mapBanks(const BanksToPresets &banksToPresets) { - vector rows; +// vector TablesComponent::mapBanks(const BanksToPresets &banksToPresets) { +// vector rows; - const auto compareKey = [](const BanksToPresets::value_type& lhs, const BanksToPresets::value_type& rhs) { - return lhs.first < rhs.first; - }; +// const auto compareKey = [](const BanksToPresets::value_type& lhs, const BanksToPresets::value_type& rhs) { +// return lhs.first < rhs.first; +// }; - for(auto i = banksToPresets.begin(); i != banksToPresets.end(); i = std::upper_bound(i, banksToPresets.end(), *i, compareKey)) { - rows.push_back(to_string(i->first)); - } +// for(auto i = banksToPresets.begin(); i != banksToPresets.end(); i = std::upper_bound(i, banksToPresets.end(), *i, compareKey)) { +// rows.push_back(to_string(i->first)); +// } - return rows; -} +// return rows; +// } // vector> TablesComponent::mapPresets(const BanksToPresets &banksToPresets, int bank) { @@ -156,18 +158,18 @@ vector TablesComponent::mapBanks(const BanksToPresets &banksToPresets) { void TablesComponent::resized() { Rectangle r (getLocalBounds()); - banks->setBounds (r.removeFromTop(27).reduced(5,0)); + banks.setBounds (r.removeFromTop(27).reduced(5,0)); - presetTable->setBounds (r); + presetTable.setBounds (r); } bool TablesComponent::keyPressed(const KeyPress &key) { if (key.getKeyCode() == KeyPress::leftKey || key.getKeyCode() == KeyPress::rightKey) { - banks->cycle(key.getKeyCode() == KeyPress::rightKey); + banks.cycle(key.getKeyCode() == KeyPress::rightKey); return true; } - return presetTable->keyPressed(key); + return presetTable.keyPressed(key); } // void TablesComponent::fontChanged(FluidSynthModel *, const String &) { diff --git a/Source/TablesComponent.h b/Source/TablesComponent.h index 69191c9..f3830cc 100644 --- a/Source/TablesComponent.h +++ b/Source/TablesComponent.h @@ -20,10 +20,10 @@ class TablesComponent : public Component/*, { public: TablesComponent( - AudioProcessorValueTreeState& valueTreeState, - FluidSynthModel& fluidSynthModel + AudioProcessorValueTreeState& valueTreeState + // FluidSynthModel& fluidSynthModel ); - ~TablesComponent(); + // ~TablesComponent(); void resized() override; @@ -32,25 +32,25 @@ public: private: AudioProcessorValueTreeState& valueTreeState; - FluidSynthModel& fluidSynthModel; - int selectedBank; + // FluidSynthModel& fluidSynthModel; + // int selectedBank; Pills banks; TableComponent presetTable; - BanksToPresets banksToPresets; + // BanksToPresets banksToPresets; // static vector> mapPresets(const BanksToPresets &banksToPresets, int bank); - static vector mapBanks(const BanksToPresets &banksToPresets); + // static vector mapBanks(const BanksToPresets &banksToPresets); - void onBankSelected(int bank); - void onPresetSelected(int preset); - int presetToIndexMapper(int preset); + // void onBankSelected(int bank); + // void onPresetSelected(int preset); + // int presetToIndexMapper(int preset); - fluid_preset_t* getCurrentPreset(); - Preset getFirstPresetInBank(int bank); + // fluid_preset_t* getCurrentPreset(); + // Preset getFirstPresetInBank(int bank); - bool initialised; + // bool initialised; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TablesComponent) };