Hi,
I’m using a ListBox in my plugin preset browser to show the list of presets. The presets are organized in two groups: factory and user. When switching between the user and factory group, updateContent() is called and the ListBoxModel pulls the relevant list of presets. This normally triggers a repaint, but if both factory and user lists are the same size, I have to call repaint() manually for it to refresh. Is it a bug or a feature? Now I can compare the sizes and do a manual repaint() for this special case, but this does sound like a workaround…
Here’s a relevant bit of code:
class ListBoxModelBase : public ListBoxModel {
public:
virtual String getTextForRowNumber(int rowNumber) = 0;
void paintListBoxItem(int rowNumber,
Graphics& g,
int width, int height,
bool rowIsSelected) final override {
// Background
g.setColour(rowIsSelected ? Theme::Colours::accent : Theme::Colours::comboBoxBackground);
g.fillRect(g.getClipBounds().withTrimmedBottom(1));
// Text
g.setFont(Theme::listBoxFontHeight);
g.setColour(Theme::Colours::normalLight);
g.drawText(getTextForRowNumber(rowNumber), 5, 0, width, height, Justification::centredLeft, true);
};
std::function<void(int lastRowSelected)> onSelectedRowsChanged = nullptr;
};
#pragma mark -
class SourcesListBoxModel : public ListBoxModelBase {
public:
SourcesListBoxModel(PresetManager& presetManager) : presetManager(presetManager) {}
int getNumRows() final override {
return static_cast<decltype(getNumRows())>(presetManager.presetSourceNames.size());
}
String getTextForRowNumber(int rowNumber) final override {
return presetManager.presetSourceNames[rowNumber];
}
void selectedRowsChanged(int lastRowSelected) final override {
if (lastRowSelected < PresetManager::Source::Factory
|| lastRowSelected > PresetManager::Source::User) {
return;
}
if (onSelectedRowsChanged) {
onSelectedRowsChanged(lastRowSelected);
}
}
PresetManager& presetManager;
};
#pragma mark -
class PresetsListBoxModel : public ListBoxModelBase {
public:
PresetsListBoxModel(PresetManager& presetManager) : presetManager(presetManager) {}
int getNumRows() final override {
currentPresets = presetManager.getCurrentPresets();
return static_cast<decltype(getNumRows())>(currentPresets.size());
};
String getTextForRowNumber(int rowNumber) final override {
return currentPresets[rowNumber].getName();
}
void selectedRowsChanged(int lastRowSelected) final override {
if (lastRowSelected > 0) {
presetManager.loadPreset(currentPresets[lastRowSelected]);
}
}
PresetManager& presetManager;
std::vector<Preset> currentPresets;
};
#pragma mark -
class PresetBrowser : public Component {
public:
PresetBrowser(PresetManager& presetManager)
: Component()
, presetManager(presetManager)
, sourcesListBoxModel(presetManager)
, presetsListBoxModel(presetManager)
{
sourcesListBoxModel.onSelectedRowsChanged = [&] (int lastRowSelected) {
presetManager.setCurrentSource(static_cast<PresetManager::Source>(lastRowSelected));
presetsListBox.updateContent();
};
sourcesListBox.setModel(&sourcesListBoxModel);
sourcesListBox.setRowHeight(Theme::listBoxRowHeight);
addAndMakeVisible(sourcesListBox);
presetsListBox.setModel(&presetsListBoxModel);
presetsListBox.setRowHeight(Theme::listBoxRowHeight);
addAndMakeVisible(presetsListBox);
addAndMakeVisible(deleteButton);
addAndMakeVisible(saveButton);
}
void paint(Graphics& g) final override {
/// ...
}
void resized() final override {
/// ...
}
private:
PresetManager& presetManager;
SourcesListBoxModel sourcesListBoxModel;
ListBox sourcesListBox;
PresetsListBoxModel presetsListBoxModel;
ListBox presetsListBox;
TextButton deleteButton { "Delete" };
TextButton saveButton { "Save" };
};