progress integrating table with store, decoupling from fluidsynth model

This commit is contained in:
Alex Birch 2019-07-13 22:37:26 +01:00
parent e1a8df9e8f
commit 4140b3b85b
No known key found for this signature in database
GPG Key ID: 305EB1F98D44ACBA
7 changed files with 158 additions and 92 deletions

View File

@ -324,7 +324,7 @@ void FluidSynthModel::onFileNameChanged(const String &absPath, int bank, int pre
valueTree.setPropertyExcludingListener(this, "path", absPath, nullptr); valueTree.setPropertyExcludingListener(this, "path", absPath, nullptr);
// valueTree.setPropertyExcludingListener(this, "soundFontPath", absPath, nullptr); // valueTree.setPropertyExcludingListener(this, "soundFontPath", absPath, nullptr);
// sharedParams.setSoundFontPath(absPath); // sharedParams.setSoundFontPath(absPath);
eventListeners.call(&FluidSynthModel::Listener::fontChanged, this, absPath); // eventListeners.call(&FluidSynthModel::Listener::fontChanged, this, absPath);
} }
void FluidSynthModel::unloadAndLoadFont(const String &absPath) { void FluidSynthModel::unloadAndLoadFont(const String &absPath) {
@ -377,8 +377,8 @@ void FluidSynthModel::loadFont(const String &absPath) {
valueTreeState.state.getChildWithName("presets") = presets; valueTreeState.state.getChildWithName("presets") = presets;
} }
FluidSynthModel::Listener::~Listener() { // FluidSynthModel::Listener::~Listener() {
} // }
bool FluidSynthModel::shouldLoadFont(const String &absPath) { bool FluidSynthModel::shouldLoadFont(const String &absPath) {
if (absPath.isEmpty()) { if (absPath.isEmpty()) {
@ -390,23 +390,23 @@ bool FluidSynthModel::shouldLoadFont(const String &absPath) {
return true; return true;
} }
void FluidSynthModel::Listener::fontChanged(FluidSynthModel * model, const String &absPath) { // void FluidSynthModel::Listener::fontChanged(FluidSynthModel * model, const String &absPath) {
} // }
const String& FluidSynthModel::getCurrentSoundFontAbsPath() { const String& FluidSynthModel::getCurrentSoundFontAbsPath() {
return currentSoundFontAbsPath; return currentSoundFontAbsPath;
} }
//============================================================================== //==============================================================================
void FluidSynthModel::addListener (FluidSynthModel::Listener* const newListener) // void FluidSynthModel::addListener (FluidSynthModel::Listener* const newListener)
{ // {
eventListeners.add(newListener); // eventListeners.add(newListener);
} // }
void FluidSynthModel::removeListener (FluidSynthModel::Listener* const listener) // void FluidSynthModel::removeListener (FluidSynthModel::Listener* const listener)
{ // {
eventListeners.remove(listener); // eventListeners.remove(listener);
} // }
void FluidSynthModel::setSampleRate(float sampleRate) { void FluidSynthModel::setSampleRate(float sampleRate) {
currentSampleRate = sampleRate; currentSampleRate = sampleRate;

View File

@ -43,26 +43,26 @@ public:
@see Button::addListener, Button::removeListener @see Button::addListener, Button::removeListener
*/ */
class Listener // class Listener
{ // {
public: // public:
/** Destructor. */ // /** Destructor. */
virtual ~Listener(); // virtual ~Listener();
/** Called when the button is clicked. */ // /** Called when the button is clicked. */
virtual void fontChanged (FluidSynthModel*, const String &absPath); // virtual void fontChanged (FluidSynthModel*, const String &absPath);
}; // };
/** Registers a listener to receive events when this button's state changes. /** Registers a listener to receive events when this button's state changes.
If the listener is already registered, this will not register it again. If the listener is already registered, this will not register it again.
@see removeListener @see removeListener
*/ */
void addListener (Listener* newListener); // void addListener (Listener* newListener);
/** Removes a previously-registered button listener /** Removes a previously-registered button listener
@see addListener @see addListener
*/ */
void removeListener (Listener* listener); // void removeListener (Listener* listener);
void setSampleRate(float sampleRate); void setSampleRate(float sampleRate);
@ -137,7 +137,7 @@ private:
// fluid_mod_t* mod; // fluid_mod_t* mod;
ListenerList<Listener> eventListeners; // ListenerList<Listener> eventListeners;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FluidSynthModel) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FluidSynthModel)
}; };

View File

@ -7,8 +7,10 @@
// //
#include "TableComponent.h" #include "TableComponent.h"
#include "Util.h"
using namespace std; using namespace std;
using namespace Util;
//============================================================================== //==============================================================================
/** /**
@ -17,15 +19,16 @@ using namespace std;
TableComponent::TableComponent( TableComponent::TableComponent(
AudioProcessorValueTreeState& valueTreeState, AudioProcessorValueTreeState& valueTreeState,
// const vector<string> &columns, // const vector<string> &columns,
const vector<vector<string>> &rows, // const vector<TableRow> &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
) )
: font (14.0f) : valueTreeState{valueTreeState}
, columns(columns) , font{14.0f}
, rows(rows) //, columns{columns}
, onRowSelected(onRowSelected)/*, //, rows{rows}
, 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..
@ -104,26 +107,34 @@ TableComponent::~TableComponent() {
void TableComponent::valueTreePropertyChanged( void TableComponent::valueTreePropertyChanged(
ValueTree& treeWhosePropertyHasChanged, ValueTree& treeWhosePropertyHasChanged,
const Identifier& property) { const Identifier& property) {
if (treeWhosePropertyHasChanged.getType() == StringRef("soundFont")) { if (treeWhosePropertyHasChanged.getType() == StringRef("presets")) {
rows.clear();
int numChildren{treeWhosePropertyHasChanged.getNumChildren()};
for(int i{0}; i<numChildren; i++) {
ValueTree child{treeWhosePropertyHasChanged.getChild(i)};
int num{child.getProperty("num")};
String name{child.getProperty("name")};
rows.emplace_back(num, name);
}
// 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);
// } // }
} // }
} }
} }
void TableComponent::setRows(const vector<vector<string>>& rows, int initiallySelectedRow) { // void TableComponent::setRows(const vector<vector<string>>& rows, int initiallySelectedRow) {
this->rows = rows; // this->rows = rows;
table.deselectAllRows(); // table.deselectAllRows();
table.updateContent(); // table.updateContent();
table.getHeader().setSortColumnId(0, true); // table.getHeader().setSortColumnId(0, true);
table.selectRow(initiallySelectedRow); // table.selectRow(initiallySelectedRow);
table.repaint(); // table.repaint();
} // }
// This is overloaded from TableListBoxModel, and must return the total number of rows in our table // This is overloaded from TableListBoxModel, and must return the total number of rows in our table
int TableComponent::getNumRows() int TableComponent::getNumRows()
@ -160,7 +171,14 @@ void TableComponent::paintCell (
g.setColour (getLookAndFeel().findColour (ListBox::textColourId)); g.setColour (getLookAndFeel().findColour (ListBox::textColourId));
g.setFont (font); g.setFont (font);
g.drawText (rows[rowNumber][columnId-1], 2, 0, width - 4, height, Justification::centredLeft, true); TableRow& row{rows[rowNumber]};
String text;
if (columnId <= 1) {
text = String(row.preset);
} else {
text = row.name;
}
g.drawText (text, 2, 0, width - 4, height, Justification::centredLeft, true);
g.setColour (getLookAndFeel().findColour (ListBox::backgroundColourId)); g.setColour (getLookAndFeel().findColour (ListBox::backgroundColourId));
g.fillRect (width - 1, 0, 1, height); g.fillRect (width - 1, 0, 1, height);
@ -174,20 +192,25 @@ void TableComponent::sortOrderChanged (
) { ) {
if (newSortColumnId != 0) { if (newSortColumnId != 0) {
int selectedRowIx = table.getSelectedRow(); int selectedRowIx = table.getSelectedRow();
vector<string> selectedRow; // TableRow* selectedRow;
if (selectedRowIx >= 0) { // if (selectedRowIx >= 0) {
selectedRow = rows[selectedRowIx]; // selectedRow = &rows[selectedRowIx];
} // }
TableComponent::DataSorter sorter (newSortColumnId, isForwards); TableComponent::DataSorter sorter (newSortColumnId, isForwards);
sort(rows.begin(), rows.end(), sorter); sort(rows.begin(), rows.end(), sorter);
table.updateContent(); table.updateContent();
RangedAudioParameter *param {valueTreeState.getParameter("preset")};
jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
int value{castParam->get()};
if (selectedRowIx >= 0) { if (selectedRowIx >= 0) {
for (auto it = rows.begin(); it != rows.end(); ++it) { for (auto it = rows.begin(); it != rows.end(); ++it) {
if(*it == selectedRow) { if(it->preset == value) {
int index = static_cast<int>(std::distance(rows.begin(), it)); int index {static_cast<int>(std::distance(rows.begin(), it))};
table.selectRow(index); table.selectRow(index);
break; break;
} }
@ -206,8 +229,15 @@ int TableComponent::getColumnAutoSizeWidth (int columnId) {
int widest = 32; int widest = 32;
// find the widest bit of text in this column.. // find the widest bit of text in this column..
for (int i = getNumRows(); --i >= 0;) { for (int i{getNumRows()}; --i >= 0;) {
widest = jmax (widest, font.getStringWidth (rows[i][columnId-1])); TableRow& row{rows[i]};
String text;
if (columnId <= 1) {
text = String(row.preset);
} else {
text = row.name;
}
widest = jmax (widest, font.getStringWidth (text));
} }
return widest + 8; return widest + 8;
@ -226,20 +256,24 @@ TableComponent::DataSorter::DataSorter (
int columnByWhichToSort, int columnByWhichToSort,
bool forwards bool forwards
) )
: columnByWhichToSort (columnByWhichToSort), : columnByWhichToSort (columnByWhichToSort)
direction (forwards ? 1 : -1) , direction (forwards ? 1 : -1)
{} {}
bool TableComponent::DataSorter::operator ()( bool TableComponent::DataSorter::operator ()(
vector<string> first, TableRow first,
vector<string> second TableRow second
) { ) {
int result = String(first[columnByWhichToSort-1]) int result;
.compareNatural (String(second[columnByWhichToSort-1])); if (columnByWhichToSort <= 1) {
result = compare(first.preset, second.preset);
if (result == 0) } else {
result = String(first[0]) result = first.name
.compareNatural (String(second[0])); .compareNatural (second.name);
if (result == 0) {
result = compare(first.preset, second.preset);
}
}
result *= direction; result *= direction;
@ -252,7 +286,7 @@ void TableComponent::selectedRowsChanged (int row) {
} }
// onRowSelected(rowToIDMapper(rows[row])); // onRowSelected(rowToIDMapper(rows[row]));
// onRowSelected(stoi(rows[row][0])); // onRowSelected(stoi(rows[row][0]));
int newPreset{stoi(rows[row][0])}; int newPreset{rows[row].preset};
RangedAudioParameter *param {valueTreeState.getParameter("preset")}; RangedAudioParameter *param {valueTreeState.getParameter("preset")};
jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr); jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)}; AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
@ -262,3 +296,11 @@ void TableComponent::selectedRowsChanged (int row) {
bool TableComponent::keyPressed(const KeyPress &key) { bool TableComponent::keyPressed(const KeyPress &key) {
return table.keyPressed(key); return table.keyPressed(key);
} }
TableRow::TableRow(
int preset,
String name
)
: preset{preset}
: name{name}
{}

View File

@ -15,6 +15,21 @@
using namespace std; using namespace std;
class TableRow {
public:
TableRow(
int preset,
String name
);
private:
int preset;
String name;
friend class TableComponent;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableRow)
};
class TableComponent : public Component, class TableComponent : public Component,
public TableListBoxModel, public TableListBoxModel,
public ValueTree::Listener/*, public ValueTree::Listener/*,
@ -23,7 +38,7 @@ public:
TableComponent( TableComponent(
AudioProcessorValueTreeState& valueTreeState, AudioProcessorValueTreeState& valueTreeState,
// const vector<string> &columns, // const vector<string> &columns,
const vector<vector<string>> &rows, // const vector<TableRow> &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
@ -56,7 +71,7 @@ public:
void resized() override; void resized() override;
void setRows(const vector<vector<string>>& rows, int initiallySelectedRow); // void setRows(const vector<TableRow>& rows, int initiallySelectedRow);
bool keyPressed(const KeyPress &key) override; bool keyPressed(const KeyPress &key) override;
@ -79,8 +94,8 @@ private:
TableListBox table; // the table component itself TableListBox table; // the table component itself
Font font; Font font;
vector<string> columns; // vector<string> columns;
vector<vector<string>> rows; vector<TableRow> rows;
function<void (int)> onRowSelected; function<void (int)> onRowSelected;
// function<int (const vector<string>&)> rowToIDMapper; // function<int (const vector<string>&)> rowToIDMapper;
@ -94,8 +109,8 @@ private:
); );
bool operator ()( bool operator ()(
vector<string> first, TableRow first,
vector<string> second TableRow second
); );
private: private:

View File

@ -35,11 +35,12 @@ TablesComponent::TablesComponent(
}; };
presetTable = new TableComponent( presetTable = new TableComponent(
valueTreeState,
// {"#", "Name"}, // {"#", "Name"},
mapPresets( // mapPresets(
banksToPresets, // banksToPresets,
selectedBank // selectedBank
), // ),
[this](int preset){ [this](int preset){
this->onPresetSelected(preset); this->onPresetSelected(preset);
}, },
@ -169,24 +170,24 @@ bool TablesComponent::keyPressed(const KeyPress &key) {
return presetTable->keyPressed(key); return presetTable->keyPressed(key);
} }
void TablesComponent::fontChanged(FluidSynthModel *, const String &) { // void TablesComponent::fontChanged(FluidSynthModel *, const String &) {
banksToPresets = fluidSynthModel.getBanks(); // banksToPresets = fluidSynthModel.getBanks();
fluid_preset_t* currentPreset = getCurrentPreset(); // fluid_preset_t* currentPreset = getCurrentPreset();
selectedBank = fluid_preset_get_banknum(currentPreset); // selectedBank = fluid_preset_get_banknum(currentPreset);
int selectedPreset = fluid_preset_get_num(currentPreset); // int selectedPreset = fluid_preset_get_num(currentPreset);
presetTable->setRows( // presetTable->setRows(
mapPresets( // mapPresets(
banksToPresets, // banksToPresets,
selectedBank // selectedBank
), // ),
presetToIndexMapper(selectedPreset) // presetToIndexMapper(selectedPreset)
); // );
banks->setItems( // banks->setItems(
mapBanks(banksToPresets), // mapBanks(banksToPresets),
selectedBank // selectedBank
); // );
} // }

View File

@ -15,8 +15,8 @@
using namespace std; using namespace std;
class TablesComponent : public Component, class TablesComponent : public Component/*,
public FluidSynthModel::Listener public FluidSynthModel::Listener */
{ {
public: public:
TablesComponent( TablesComponent(
@ -28,7 +28,7 @@ public:
void resized() override; void resized() override;
bool keyPressed(const KeyPress &key) override; bool keyPressed(const KeyPress &key) override;
void fontChanged(FluidSynthModel *, const String &) override; // void fontChanged(FluidSynthModel *, const String &) override;
private: private:
AudioProcessorValueTreeState& valueTreeState; AudioProcessorValueTreeState& valueTreeState;

View File

@ -9,3 +9,11 @@
#define DEBUG_PRINT(str) #define DEBUG_PRINT(str)
#endif #endif
#endif #endif
namespace Util {
inline int compare(int a, int b) {
if (a > b) return 1;
if (a == b) return 0;
return -1;
}
}