decoupling achieved. compiles. doesn't immediately explode. but neither banks nor presets visible.

This commit is contained in:
Alex Birch 2019-07-14 17:22:36 +01:00
parent 58574425f3
commit 8c1be957fe
No known key found for this signature in database
GPG Key ID: 305EB1F98D44ACBA
9 changed files with 183 additions and 146 deletions

View File

@ -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)

View File

@ -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;

View File

@ -4,6 +4,7 @@
#include "Pills.h"
#include "MyColours.h"
#include <algorithm>
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<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (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<Pill>(new Pill(), [](Pill* pill) {
// pill->remo
// }));
pills.emplace_back(
this.valueTreeState,
pills.push_back(
make_unique<Pill>(
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<const int>(distance(pills.begin(), find(pills.begin(), pills.end(), selected)));
RangedAudioParameter *param {valueTreeState.getParameter("bank")};
jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
int currentlySelectedBank{castParam->get()};
ValueTree banks{valueTreeState.state.getChildWithName("banks")};
// int numChildren{banks.getNumChildren()};
vector<int> 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<const int>(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<const int>(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<int> 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<int> r2 (getLocalBounds());
r2.removeFromLeft(equalWidth * index);
r2.removeFromRight(equalWidth * (buttons.size()-index-1));
t->setBounds (r2);
r2.removeFromRight(equalWidth * (static_cast<int>(pills.size())-index-1));
pill->textButton.setBounds (r2);
index++;
}
}

View File

@ -32,8 +32,7 @@ private:
TextButton textButton;
friend class Pills;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pill)
}
};
class Pills
: public Component

View File

@ -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

View File

@ -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<string> &columns,
// const vector<TableRow> &rows,
// const function<void (int)> &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

View File

@ -29,7 +29,6 @@ private:
String name;
friend class TableComponent;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableRow)
};

View File

@ -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<string> &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);
// 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);
// },
// rowToPresetMapper,
// presetToIndexMapper(selectedPreset)
);
banks = new Pills(
"Banks",
mapBanks(banksToPresets),
[this](int bank){
this->onBankSelected(bank);
},
itemToBankMapper,
selectedBank
);
// 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<fluid_synth_t> synth {fluidSynthModel.getSynth()};
// fluid_preset_t* TablesComponent::getCurrentPreset() {
// shared_ptr<fluid_synth_t> 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<BanksToPresets::const_iterator, BanksToPresets::const_iterator> iterators = banksToPresets.equal_range(bank);
BanksToPresets::const_iterator it = iterators.first;
return it->second;
}
// Preset TablesComponent::getFirstPresetInBank(int bank) {
// pair<BanksToPresets::const_iterator, BanksToPresets::const_iterator> 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<BanksToPresets::const_iterator, BanksToPresets::const_iterator> 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<BanksToPresets::const_iterator, BanksToPresets::const_iterator> 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<string> TablesComponent::mapBanks(const BanksToPresets &banksToPresets) {
vector<string> rows;
// vector<string> TablesComponent::mapBanks(const BanksToPresets &banksToPresets) {
// vector<string> 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<vector<string>> TablesComponent::mapPresets(const BanksToPresets &banksToPresets, int bank) {
@ -156,18 +158,18 @@ vector<string> TablesComponent::mapBanks(const BanksToPresets &banksToPresets) {
void TablesComponent::resized() {
Rectangle<int> 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 &) {

View File

@ -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<vector<string>> mapPresets(const BanksToPresets &banksToPresets, int bank);
static vector<string> mapBanks(const BanksToPresets &banksToPresets);
// static vector<string> 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)
};