Skip to content

Commit

Permalink
plugin: allow renaming in preset mgr
Browse files Browse the repository at this point in the history
  • Loading branch information
JoepVanlier committed Nov 28, 2024
1 parent 3d4f9bc commit 06855dc
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 21 deletions.
62 changes: 60 additions & 2 deletions plugin/components/rpl_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "utility/functional_timer.h"
#include <juce_gui_extra/juce_gui_extra.h>
#include <algorithm>
#include "components/modal_textinputbox.h"

class BankItemsListBoxModel final : public juce::ListBox, public juce::ListBoxModel, public juce::DragAndDropTarget
{
Expand All @@ -48,8 +49,15 @@ class BankItemsListBoxModel final : public juce::ListBox, public juce::ListBoxMo
m_dblClickCallback = dblClickCallback;
}

void setRenameCallback(std::function<void(int)> renameCallback) {
m_renameCallback = renameCallback;
}

private:
std::unique_ptr<juce::AlertWindow> m_editDialog;
std::unique_ptr<juce::PopupMenu> m_itemMenu;
std::vector<juce::String> m_items;
std::function<void(int)> m_renameCallback;
std::function<void(int)> m_dblClickCallback;
std::function<void(std::vector<int>, juce::WeakReference<juce::Component>)> m_dropCallback;
std::function<void(std::vector<int>)> m_deleteCallback;
Expand Down Expand Up @@ -129,6 +137,24 @@ class BankItemsListBoxModel final : public juce::ListBox, public juce::ListBoxMo
{
m_dblClickCallback(row);
}

void listBoxItemClicked(int row, const juce::MouseEvent& evnt) override
{
if (evnt.mods.isRightButtonDown() && m_renameCallback) {
m_itemMenu.reset(new juce::PopupMenu);

juce::PopupMenu::Options presetOptions = juce::PopupMenu::Options{}
.withTargetComponent(getComponentForRowNumber(row));

m_itemMenu->addItem(1, "Rename");

m_itemMenu->showMenuAsync(presetOptions, [this, row](int index) {
if (index == 1) {
m_renameCallback(row);
}
});
}
}
};

class LoadedBank : public juce::Component, public juce::DragAndDropContainer {
Expand All @@ -137,6 +163,7 @@ class LoadedBank : public juce::Component, public juce::DragAndDropContainer {
juce::File m_file;
ysfx_bank_shared m_bank;

std::unique_ptr<juce::AlertWindow> m_editDialog;
std::unique_ptr<BankItemsListBoxModel> m_listBox;
std::unique_ptr<juce::Label> m_label;
std::unique_ptr<juce::TextButton> m_btnLoadFile;
Expand Down Expand Up @@ -255,6 +282,35 @@ class LoadedBank : public juce::Component, public juce::DragAndDropContainer {
);
}

void renamePreset(int row) {
if (!m_bank) return;
if (row > static_cast<int>(m_bank->preset_count)) return;

std::string currentPreset{m_bank->presets[row].name};

m_editDialog.reset(
show_async_text_input(
"Enter new name",
"",
[this, currentPreset](juce::String presetName, bool wantRename) {
if (wantRename) {
m_bank.reset(ysfx_rename_preset_from_bank(m_bank.get(), currentPreset.c_str(), presetName.toStdString().c_str()));
this->m_listBox->deselectAllRows();
save_bank(m_file.getFullPathName().toStdString().c_str(), m_bank.get());
if (m_bankUpdatedCallback) m_bankUpdatedCallback();
}
},
[this](juce::String presetName) {
if (ysfx_preset_exists(m_bank.get(), presetName.toStdString().c_str())) {
return juce::String("Preset with that name already exists.\nChoose a different name or click cancel.");
} else {
return juce::String("");
}
}
)
);
}

void createUI(bool withLoad)
{
m_listBox.reset(new BankItemsListBoxModel());
Expand All @@ -268,6 +324,7 @@ class LoadedBank : public juce::Component, public juce::DragAndDropContainer {
m_listBox->setOutlineThickness(1);
m_listBox->setDropCallback([this](std::vector<int> indices, juce::WeakReference<juce::Component> ref) { this->transferPresets(indices, ref); });
m_listBox->setDeleteCallback([this](std::vector<int> indices) { this->deletePresets(indices); });
m_listBox->setRenameCallback([this](int row) { this->renamePreset(row); });
m_listBox->setDoubleClickCallback([this](int idx) { if (m_loadPresetCallback) m_loadPresetCallback(std::string{m_bank->presets[idx].name}); });
addAndMakeVisible(*m_listBox);
addAndMakeVisible(*m_label);
Expand All @@ -283,6 +340,7 @@ class LoadedBank : public juce::Component, public juce::DragAndDropContainer {
if (m_file == juce::File{}) {
m_listBox->setItems({});
m_listBox->updateContent();
repaint();
return;
}

Expand All @@ -303,9 +361,9 @@ class LoadedBank : public juce::Component, public juce::DragAndDropContainer {
names.push_back(juce::String::fromUTF8(m_bank->presets[i].name));
}
m_listBox->setItems(names);
m_listBox->updateContent();

m_listBox->updateContent();
m_label->setText(m_file.getFileName() + juce::String(" (") + juce::String(bank->name) + juce::String(")"), juce::dontSendNotification);
repaint();
}

void setFile(juce::File file)
Expand Down
4 changes: 2 additions & 2 deletions plugin/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ void YsfxEditor::Impl::updateInfo()

auto index = ysfx_preset_exists(bank.get(), preset.c_str());
if (index > 0) {
m_proc->loadJsfxPreset(info, bank, (uint32_t)(index - 1), true, true);
m_proc->loadJsfxPreset(info, bank, (uint32_t)(index - 1), PresetLoadMode::load, true);
}
}
);
Expand Down Expand Up @@ -759,7 +759,7 @@ void YsfxEditor::Impl::popupPresets()

showPopupMenuWithQuickSearch(*m_presetsPopup, quickSearchOptions, [this, info, bank](int index) {
if ((index > 0) && (index < 32767)) {
m_proc->loadJsfxPreset(info, bank, (uint32_t)(index - 1), true, true);
m_proc->loadJsfxPreset(info, bank, (uint32_t)(index - 1), PresetLoadMode::load, true);
}
}
);
Expand Down
36 changes: 21 additions & 15 deletions plugin/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct YsfxProcessor::Impl : public juce::AudioProcessorListener {
YsfxInfo::Ptr info;
ysfx_bank_shared bank;
uint32_t index = 0;
bool load = false;
PresetLoadMode load = noLoad;
volatile bool completion = false;
std::mutex completionMutex;
std::condition_variable completionVariable;
Expand Down Expand Up @@ -231,7 +231,7 @@ void YsfxProcessor::loadJsfxFile(const juce::String &filePath, ysfx_state_t *ini
}
}

void YsfxProcessor::loadJsfxPreset(YsfxInfo::Ptr info, ysfx_bank_shared bank, uint32_t index, bool load, bool async)
void YsfxProcessor::loadJsfxPreset(YsfxInfo::Ptr info, ysfx_bank_shared bank, uint32_t index, PresetLoadMode load, bool async)
{
Impl::PresetRequest::Ptr presetRequest{new Impl::PresetRequest};
presetRequest->info = info;
Expand Down Expand Up @@ -264,10 +264,10 @@ void YsfxProcessor::reloadBank()
return;

ysfx_bank_shared bank = m_impl->loadDefaultBank(m_impl->m_info);
loadJsfxPreset(m_impl->m_info, bank, false, false, true);
loadJsfxPreset(m_impl->m_info, bank, false, PresetLoadMode::noLoad, true);
}

void YsfxProcessor::savePreset(const char* preset_name, ysfx_state_t* preset, bool load)
void YsfxProcessor::savePreset(const char* preset_name, ysfx_state_t* preset)
{
ysfx_t *fx = m_impl->m_fx.get();
if (!fx) return;
Expand All @@ -287,35 +287,41 @@ void YsfxProcessor::savePreset(const char* preset_name, ysfx_state_t* preset, bo
}

save_bank(bankLocation.getFullPathName().toStdString().c_str(), newBank.get());
loadJsfxPreset(m_impl->m_info, newBank, ysfx_preset_exists(newBank.get(), preset_name) - 1, load, true);
loadJsfxPreset(m_impl->m_info, newBank, ysfx_preset_exists(newBank.get(), preset_name) - 1, PresetLoadMode::load, true);
}

void YsfxProcessor::saveCurrentPreset(const char* preset_name)
{
ysfx_t *fx = m_impl->m_fx.get();
if (!fx) return;

savePreset(preset_name, ysfx_save_state(fx), true);
savePreset(preset_name, ysfx_save_state(fx));
}

void YsfxProcessor::renameCurrentPreset(const char* new_preset_name)
{
ysfx_t *fx = m_impl->m_fx.get();
if (!fx) return;

// Make a backup copy before we write in case there's trouble
juce::File bankLocation = getCustomBankLocation(fx);
backupPresetFile(bankLocation);

ysfx_bank_shared bank = m_impl->m_bank; // Make sure we keep it alive while we are operating on it
if (!bank) return;

auto currentPreset = m_impl->m_currentPresetInfo->m_lastChosenPreset;
if (currentPreset.isEmpty()) return;

// It doesn't exist => Save instead!
if (ysfx_preset_exists(bank.get(), currentPreset.toStdString().c_str()) == 0) {
saveCurrentPreset(new_preset_name);
return;
}

// Make a backup copy before we write in case there's trouble
juce::File bankLocation = getCustomBankLocation(fx);
backupPresetFile(bankLocation);

ysfx_bank_shared newBank = make_ysfx_bank_shared(ysfx_rename_preset_from_bank(bank.get(), currentPreset.toStdString().c_str(), new_preset_name));
save_bank(bankLocation.getFullPathName().toStdString().c_str(), newBank.get());
loadJsfxPreset(m_impl->m_info, newBank, ysfx_preset_exists(newBank.get(), new_preset_name) - 1, true, true);
loadJsfxPreset(m_impl->m_info, newBank, ysfx_preset_exists(newBank.get(), new_preset_name) - 1, PresetLoadMode::load, true);
}

void YsfxProcessor::deleteCurrentPreset()
Expand All @@ -335,7 +341,7 @@ void YsfxProcessor::deleteCurrentPreset()

ysfx_bank_shared newBank = make_ysfx_bank_shared(ysfx_delete_preset_from_bank(bank.get(), currentPreset.toStdString().c_str()));
save_bank(bankLocation.getFullPathName().toStdString().c_str(), newBank.get());
loadJsfxPreset(m_impl->m_info, newBank, 0, false, true);
loadJsfxPreset(m_impl->m_info, newBank, 0, PresetLoadMode::deleteName, true);
}

void YsfxProcessor::cyclePreset(int direction)
Expand Down Expand Up @@ -366,7 +372,7 @@ void YsfxProcessor::cyclePreset(int direction)
next_preset = 0;
}

loadJsfxPreset(m_impl->m_info, m_impl->m_bank, next_preset, true, true);
loadJsfxPreset(m_impl->m_info, m_impl->m_bank, next_preset, PresetLoadMode::load, true);
}

YsfxInfo::Ptr YsfxProcessor::getCurrentInfo()
Expand Down Expand Up @@ -1025,13 +1031,13 @@ void YsfxProcessor::Impl::Background::processPresetRequest(PresetRequest &req)

ysfx_bank_t *bank = req.bank.get();

if (req.load) {
if (req.load == PresetLoadMode::load) {
if (!bank || req.index >= bank->preset_count)
return;

const ysfx_preset_t &preset = bank->presets[req.index];
m_impl->loadNewPreset(preset);
} else {
} else if (req.load == PresetLoadMode::deleteName) {
m_impl->resetPresetInfo();
}

Expand Down
5 changes: 3 additions & 2 deletions plugin/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ using ysfx_t = struct ysfx_s;
using ysfx_state_t = struct ysfx_state_s;

enum RetryState {ok, mustRetry, retrying};
enum PresetLoadMode {load, noLoad, deleteName};

class YsfxProcessor : public juce::AudioProcessor {
public:
Expand All @@ -32,10 +33,10 @@ class YsfxProcessor : public juce::AudioProcessor {

YsfxParameter *getYsfxParameter(int sliderIndex);
void loadJsfxFile(const juce::String &filePath, ysfx_state_t *initialState, bool async);
void loadJsfxPreset(YsfxInfo::Ptr info, ysfx_bank_shared bank, uint32_t index, bool load, bool async);
void loadJsfxPreset(YsfxInfo::Ptr info, ysfx_bank_shared bank, uint32_t index, PresetLoadMode load, bool async);
bool presetExists(const char *preset_name);
void reloadBank();
void savePreset(const char* preset_name, ysfx_state_t *preset, bool load);
void savePreset(const char* preset_name, ysfx_state_t *preset);
void cyclePreset(int direction);
void saveCurrentPreset(const char* preset_name);
void renameCurrentPreset(const char *new_preset_name);
Expand Down

0 comments on commit 06855dc

Please sign in to comment.