progress moving table model to be managed by fluidsynth, de-generalizing and decoupling table component
This commit is contained in:
parent
e02188b7f4
commit
e1a8df9e8f
|
@ -27,12 +27,12 @@ FilePicker::FilePicker(
|
||||||
setOpaque (true);
|
setOpaque (true);
|
||||||
|
|
||||||
// setDisplayedFilePath(fluidSynthModel.getCurrentSoundFontAbsPath());
|
// setDisplayedFilePath(fluidSynthModel.getCurrentSoundFontAbsPath());
|
||||||
setDisplayedFilePath("");
|
setDisplayedFilePath(valueTreeState.state.getChildWithName("soundFont").getProperty("path", ""));
|
||||||
|
|
||||||
addAndMakeVisible (fileChooser);
|
addAndMakeVisible (fileChooser);
|
||||||
fileChooser.addListener (this);
|
fileChooser.addListener (this);
|
||||||
valueTreeState.state.addListener(this);
|
valueTreeState.state.addListener(this);
|
||||||
valueTreeState.state.getChildWithName("soundFont").sendPropertyChangeMessage("path");
|
// valueTreeState.state.getChildWithName("soundFont").sendPropertyChangeMessage("path");
|
||||||
}
|
}
|
||||||
FilePicker::~FilePicker() {
|
FilePicker::~FilePicker() {
|
||||||
fileChooser.removeListener (this);
|
fileChooser.removeListener (this);
|
||||||
|
@ -65,7 +65,7 @@ void FilePicker::valueTreePropertyChanged(ValueTree& treeWhosePropertyHasChanged
|
||||||
// if (&treeWhosePropertyHasChanged == &valueTree) {
|
// if (&treeWhosePropertyHasChanged == &valueTree) {
|
||||||
if (property == StringRef("path")) {
|
if (property == StringRef("path")) {
|
||||||
String soundFontPath{treeWhosePropertyHasChanged.getProperty("path", "")};
|
String soundFontPath{treeWhosePropertyHasChanged.getProperty("path", "")};
|
||||||
DEBUG_PRINT(soundFontPath);
|
// DEBUG_PRINT(soundFontPath);
|
||||||
// if (soundFontPath.isNotEmpty()) {
|
// if (soundFontPath.isNotEmpty()) {
|
||||||
// loadFont(soundFontPath);
|
// loadFont(soundFontPath);
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -339,6 +339,42 @@ void FluidSynthModel::loadFont(const String &absPath) {
|
||||||
currentSoundFontAbsPath = absPath;
|
currentSoundFontAbsPath = absPath;
|
||||||
sfont_id++;
|
sfont_id++;
|
||||||
fluid_synth_sfload(synth.get(), absPath.toStdString().c_str(), 1);
|
fluid_synth_sfload(synth.get(), absPath.toStdString().c_str(), 1);
|
||||||
|
fluid_sfont_t* sfont {fluid_synth_get_sfont_by_id(synth.get(), sfont_id)};
|
||||||
|
ValueTree banks{"banks"};
|
||||||
|
ValueTree presets{"presets"};
|
||||||
|
if (sfont != nullptr) {
|
||||||
|
int initialBankOffset{fluid_synth_get_bank_offset(synth.get(), sfont_id)};
|
||||||
|
banks.appendChild({ "bank", {
|
||||||
|
{ "num", initialBankOffset },
|
||||||
|
}, {} }, nullptr);
|
||||||
|
|
||||||
|
fluid_sfont_iteration_start(sfont);
|
||||||
|
|
||||||
|
for(fluid_preset_t* preset {fluid_sfont_iteration_next(sfont)};
|
||||||
|
preset != nullptr;
|
||||||
|
preset = fluid_sfont_iteration_next(sfont)) {
|
||||||
|
int bankOffset{fluid_preset_get_banknum(preset) + initialBankOffset};
|
||||||
|
// ValueTree preset{"preset"};
|
||||||
|
// banksToPresets.insert(BanksToPresets::value_type(
|
||||||
|
// fluid_preset_get_banknum(preset) + bankOffset,
|
||||||
|
// *new Preset(
|
||||||
|
// fluid_preset_get_num(preset),
|
||||||
|
// fluid_preset_get_name(preset)
|
||||||
|
// )
|
||||||
|
// ));
|
||||||
|
if (bankOffset > initialBankOffset) {
|
||||||
|
banks.appendChild({ "bank", {
|
||||||
|
{ "num", bankOffset },
|
||||||
|
}, {} }, nullptr);
|
||||||
|
}
|
||||||
|
presets.appendChild({ "preset", {
|
||||||
|
{ "num", fluid_preset_get_num(preset) },
|
||||||
|
{ "name", String{fluid_preset_get_name(preset)} }
|
||||||
|
}, {} }, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
valueTreeState.state.getChildWithName("banks") = banks;
|
||||||
|
valueTreeState.state.getChildWithName("presets") = presets;
|
||||||
}
|
}
|
||||||
|
|
||||||
FluidSynthModel::Listener::~Listener() {
|
FluidSynthModel::Listener::~Listener() {
|
||||||
|
|
|
@ -46,6 +46,10 @@ JuicySFAudioProcessor::JuicySFAudioProcessor()
|
||||||
valueTreeState.state.appendChild({ "soundFont", {
|
valueTreeState.state.appendChild({ "soundFont", {
|
||||||
{ "path", "" },
|
{ "path", "" },
|
||||||
}, {} }, nullptr);
|
}, {} }, nullptr);
|
||||||
|
// no properties, no subtrees (yet)
|
||||||
|
valueTreeState.state.appendChild({ "presets", {}, {} }, nullptr);
|
||||||
|
// no properties, no subtrees (yet)
|
||||||
|
valueTreeState.state.appendChild({ "banks", {}, {} }, nullptr);
|
||||||
// valueTreeState.state.setProperty("soundFontPath", "", nullptr);
|
// valueTreeState.state.setProperty("soundFontPath", "", nullptr);
|
||||||
// valueTreeState.state.appendChild({ "soundFontPath", {} }, nullptr);
|
// valueTreeState.state.appendChild({ "soundFontPath", {} }, nullptr);
|
||||||
|
|
||||||
|
|
|
@ -15,17 +15,18 @@ using namespace std;
|
||||||
This class shows how to implement a TableListBoxModel to show in a TableListBox.
|
This class shows how to implement a TableListBoxModel to show in a TableListBox.
|
||||||
*/
|
*/
|
||||||
TableComponent::TableComponent(
|
TableComponent::TableComponent(
|
||||||
const vector<string> &columns,
|
AudioProcessorValueTreeState& valueTreeState,
|
||||||
const vector<vector<string>> &rows,
|
// const vector<string> &columns,
|
||||||
const function<void (int)> &onRowSelected,
|
const vector<vector<string>> &rows,
|
||||||
const function<int (const vector<string>&)> &rowToIDMapper,
|
const function<void (int)> &onRowSelected,
|
||||||
int initiallySelectedRow
|
// const function<int (const vector<string>&)> &rowToIDMapper,
|
||||||
|
int initiallySelectedRow
|
||||||
)
|
)
|
||||||
: font (14.0f),
|
: font (14.0f)
|
||||||
columns(columns),
|
, columns(columns)
|
||||||
rows(rows),
|
, rows(rows)
|
||||||
onRowSelected(onRowSelected),
|
, onRowSelected(onRowSelected)/*,
|
||||||
rowToIDMapper(rowToIDMapper)
|
rowToIDMapper(rowToIDMapper)*/
|
||||||
{
|
{
|
||||||
// Create our table component and add it to this component..
|
// Create our table component and add it to this component..
|
||||||
addAndMakeVisible (table);
|
addAndMakeVisible (table);
|
||||||
|
@ -38,31 +39,81 @@ TableComponent::TableComponent(
|
||||||
int columnIx = 1;
|
int columnIx = 1;
|
||||||
|
|
||||||
// Add some columns to the table header, based on the column list in our database..
|
// Add some columns to the table header, based on the column list in our database..
|
||||||
for (auto &column : columns) // access by reference to avoid copying
|
// for (auto &column : columns) // access by reference to avoid copying
|
||||||
{
|
// {
|
||||||
const int colWidth{ columnIx == 1 ? 30 : 200 };
|
// const int colWidth{ columnIx == 1 ? 30 : 200 };
|
||||||
table.getHeader().addColumn (
|
// table.getHeader().addColumn (
|
||||||
String(column),
|
// String(column),
|
||||||
columnIx++,
|
// columnIx++,
|
||||||
colWidth, // column width
|
// colWidth, // column width
|
||||||
30, // min width
|
// 30, // min width
|
||||||
400, // max width
|
// 400, // max width
|
||||||
TableHeaderComponent::defaultFlags
|
// TableHeaderComponent::defaultFlags
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
table.getHeader().addColumn (
|
||||||
|
String("#"),
|
||||||
|
columnIx++,
|
||||||
|
30, // column width
|
||||||
|
30, // min width
|
||||||
|
400, // max width
|
||||||
|
TableHeaderComponent::defaultFlags
|
||||||
|
);
|
||||||
|
table.getHeader().addColumn (
|
||||||
|
String("Name"),
|
||||||
|
columnIx++,
|
||||||
|
200, // column width
|
||||||
|
30, // min width
|
||||||
|
400, // max width
|
||||||
|
TableHeaderComponent::defaultFlags
|
||||||
|
);
|
||||||
|
|
||||||
table.setWantsKeyboardFocus(false);
|
table.setWantsKeyboardFocus(false);
|
||||||
|
|
||||||
table.selectRow(initiallySelectedRow);
|
table.selectRow(initiallySelectedRow);
|
||||||
|
|
||||||
// we could now change some initial settings..
|
// we could now change some initial settings..
|
||||||
table.getHeader().setSortColumnId (1, false); // sort ascending by ID column
|
table.getHeader().setSortColumnId(1, false); // sort ascending by ID column
|
||||||
// table.getHeader().setColumnVisible (7, false); // hide the "length" column until the user shows it
|
// table.getHeader().setColumnVisible (7, false); // hide the "length" column until the user shows it
|
||||||
|
|
||||||
// un-comment this line to have a go of stretch-to-fit mode
|
// un-comment this line to have a go of stretch-to-fit mode
|
||||||
// table.getHeader().setStretchToFitActive (true);
|
// table.getHeader().setStretchToFitActive (true);
|
||||||
|
|
||||||
// table.setMultipleSelectionEnabled (false);
|
// table.setMultipleSelectionEnabled (false);
|
||||||
|
valueTreeState.state.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
TableComponent::~TableComponent() {
|
||||||
|
valueTreeState.state.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void TableComponent::parameterChanged(const String& parameterID, float newValue) {
|
||||||
|
// // valueTreeState.getParameter
|
||||||
|
// RangedAudioParameter *param {valueTreeState.getParameter("bank")};
|
||||||
|
// if (parameterID == "bank") {
|
||||||
|
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||||
|
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||||
|
// int value{castParam->get()};
|
||||||
|
// } else if (parameterID == "preset") {
|
||||||
|
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||||
|
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||||
|
// int value{castParam->get()};
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
void TableComponent::valueTreePropertyChanged(
|
||||||
|
ValueTree& treeWhosePropertyHasChanged,
|
||||||
|
const Identifier& property) {
|
||||||
|
if (treeWhosePropertyHasChanged.getType() == StringRef("soundFont")) {
|
||||||
|
// if (&treeWhosePropertyHasChanged == &valueTree) {
|
||||||
|
if (property == StringRef("path")) {
|
||||||
|
String soundFontPath{treeWhosePropertyHasChanged.getProperty("path", "")};
|
||||||
|
// DEBUG_PRINT(soundFontPath);
|
||||||
|
// if (soundFontPath.isNotEmpty()) {
|
||||||
|
// loadFont(soundFontPath);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableComponent::setRows(const vector<vector<string>>& rows, int initiallySelectedRow) {
|
void TableComponent::setRows(const vector<vector<string>>& rows, int initiallySelectedRow) {
|
||||||
|
@ -148,10 +199,8 @@ void TableComponent::sortOrderChanged (
|
||||||
// This is overloaded from TableListBoxModel, and should choose the best width for the specified
|
// This is overloaded from TableListBoxModel, and should choose the best width for the specified
|
||||||
// column.
|
// column.
|
||||||
int TableComponent::getColumnAutoSizeWidth (int columnId) {
|
int TableComponent::getColumnAutoSizeWidth (int columnId) {
|
||||||
// if (columnId == 5)
|
|
||||||
// return 100; // (this is the ratings column, containing a custom combobox component)
|
|
||||||
if (columnId == 1)
|
if (columnId == 1)
|
||||||
return 30; // (this is the ratings column, containing a custom combobox component)
|
return 30;
|
||||||
|
|
||||||
|
|
||||||
int widest = 32;
|
int widest = 32;
|
||||||
|
@ -201,7 +250,13 @@ void TableComponent::selectedRowsChanged (int row) {
|
||||||
if (row < 0) {
|
if (row < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onRowSelected(rowToIDMapper(rows[row]));
|
// onRowSelected(rowToIDMapper(rows[row]));
|
||||||
|
// onRowSelected(stoi(rows[row][0]));
|
||||||
|
int newPreset{stoi(rows[row][0])};
|
||||||
|
RangedAudioParameter *param {valueTreeState.getParameter("preset")};
|
||||||
|
jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||||
|
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||||
|
*castParam = newPreset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TableComponent::keyPressed(const KeyPress &key) {
|
bool TableComponent::keyPressed(const KeyPress &key) {
|
||||||
|
|
|
@ -16,15 +16,19 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class TableComponent : public Component,
|
class TableComponent : public Component,
|
||||||
public TableListBoxModel {
|
public TableListBoxModel,
|
||||||
|
public ValueTree::Listener/*,
|
||||||
|
public AudioProcessorValueTreeState::Listener */ {
|
||||||
public:
|
public:
|
||||||
TableComponent(
|
TableComponent(
|
||||||
const vector<string> &columns,
|
AudioProcessorValueTreeState& valueTreeState,
|
||||||
|
// const vector<string> &columns,
|
||||||
const vector<vector<string>> &rows,
|
const vector<vector<string>> &rows,
|
||||||
const function<void (int)> &onRowSelected,
|
const function<void (int)> &onRowSelected,
|
||||||
const function<int (const vector<string>&)> &rowToIDMapper,
|
// const function<int (const vector<string>&)> &rowToIDMapper,
|
||||||
int initiallySelectedRow
|
int initiallySelectedRow
|
||||||
);
|
);
|
||||||
|
~TableComponent();
|
||||||
|
|
||||||
int getNumRows() override;
|
int getNumRows() override;
|
||||||
|
|
||||||
|
@ -56,7 +60,22 @@ public:
|
||||||
|
|
||||||
bool keyPressed(const KeyPress &key) override;
|
bool keyPressed(const KeyPress &key) override;
|
||||||
|
|
||||||
|
// virtual void parameterChanged (const String& parameterID, float newValue) override;
|
||||||
|
|
||||||
|
virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
|
||||||
|
const Identifier& property) override;
|
||||||
|
inline virtual void valueTreeChildAdded (ValueTree& parentTree,
|
||||||
|
ValueTree& childWhichHasBeenAdded) override {};
|
||||||
|
inline virtual void valueTreeChildRemoved (ValueTree& parentTree,
|
||||||
|
ValueTree& childWhichHasBeenRemoved,
|
||||||
|
int indexFromWhichChildWasRemoved) override {};
|
||||||
|
inline virtual void valueTreeChildOrderChanged (ValueTree& parentTreeWhoseChildrenHaveMoved,
|
||||||
|
int oldIndex, int newIndex) override {};
|
||||||
|
inline virtual void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) override {};
|
||||||
|
inline virtual void valueTreeRedirected (ValueTree& treeWhichHasBeenChanged) override {};
|
||||||
private:
|
private:
|
||||||
|
AudioProcessorValueTreeState& valueTreeState;
|
||||||
|
|
||||||
TableListBox table; // the table component itself
|
TableListBox table; // the table component itself
|
||||||
Font font;
|
Font font;
|
||||||
|
|
||||||
|
@ -64,7 +83,7 @@ private:
|
||||||
vector<vector<string>> rows;
|
vector<vector<string>> rows;
|
||||||
|
|
||||||
function<void (int)> onRowSelected;
|
function<void (int)> onRowSelected;
|
||||||
function<int (const vector<string>&)> rowToIDMapper;
|
// function<int (const vector<string>&)> rowToIDMapper;
|
||||||
|
|
||||||
// A comparator used to sort our data when the user clicks a column header
|
// A comparator used to sort our data when the user clicks a column header
|
||||||
class DataSorter {
|
class DataSorter {
|
||||||
|
|
|
@ -20,20 +20,22 @@ TablesComponent::TablesComponent(
|
||||||
selectedBank = -1;
|
selectedBank = -1;
|
||||||
int selectedPreset = -1;
|
int selectedPreset = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (currentPreset != nullptr) {
|
if (currentPreset != nullptr) {
|
||||||
selectedBank = fluid_preset_get_banknum(currentPreset);
|
selectedBank = fluid_preset_get_banknum(currentPreset);
|
||||||
selectedPreset = fluid_preset_get_num(currentPreset);
|
selectedPreset = fluid_preset_get_num(currentPreset);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rowToPresetMapper = [this](const vector<string> &row) {
|
// auto rowToPresetMapper = [this](const vector<string> &row) {
|
||||||
return stoi(row[0]);
|
// return stoi(row[0]);
|
||||||
};
|
// };
|
||||||
auto itemToBankMapper = [](const string &item) {
|
auto itemToBankMapper = [](const string &item) {
|
||||||
return stoi(item);
|
return stoi(item);
|
||||||
};
|
};
|
||||||
|
|
||||||
presetTable = new TableComponent(
|
presetTable = new TableComponent(
|
||||||
{"#", "Name"},
|
// {"#", "Name"},
|
||||||
mapPresets(
|
mapPresets(
|
||||||
banksToPresets,
|
banksToPresets,
|
||||||
selectedBank
|
selectedBank
|
||||||
|
@ -41,7 +43,7 @@ TablesComponent::TablesComponent(
|
||||||
[this](int preset){
|
[this](int preset){
|
||||||
this->onPresetSelected(preset);
|
this->onPresetSelected(preset);
|
||||||
},
|
},
|
||||||
rowToPresetMapper,
|
// rowToPresetMapper,
|
||||||
presetToIndexMapper(selectedPreset)
|
presetToIndexMapper(selectedPreset)
|
||||||
);
|
);
|
||||||
banks = new Pills(
|
banks = new Pills(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user