From 1a8928e8cebf0dcc7e45c87c7b839aaa0013eea0 Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 13 Aug 2026 14:39:56 +0200 Subject: [PATCH] Fix preset name not restored on plugin reopen The plugin saved only parameter values, so on reopening the editor reset to the default "Zero State" even though another patch was selected. Store the chosen preset name as a presetName property on the APVTS ValueTree (set on preset select, randomize, and .cfl load) so it round-trips with the saved state and the editor restores the correct name and index. Parameter tweaks made after selecting a preset are preserved since only the label is restored, not re-applied. --- Source/PluginEditor.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index a6e85ea..7aa4480 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -749,8 +749,24 @@ MainContentComponent::MainContentComponent(ChromaFlockProcessor& p) auto& presets = processorRef.presetManager.getPresets(); if (!presets.empty()) { - currentPresetIndex = 0; - patchLCD.setText(presets[currentPresetIndex].name); + // Restore the preset name from the saved state so re-opening the + // plugin shows the patch the user last selected instead of defaulting + // to "Zero State". The parameter values themselves are already + // restored by the host via setStateInformation. + currentPresetIndex = -1; + auto savedName = processorRef.apvts.state.getProperty("presetName", juce::String()).toString(); + if (savedName.isNotEmpty()) { + for (size_t i = 0; i < presets.size(); ++i) { + if (presets[i].name == savedName) { + currentPresetIndex = static_cast(i); + break; + } + } + patchLCD.setText(savedName); + } else { + currentPresetIndex = 0; + patchLCD.setText(presets[currentPresetIndex].name); + } } scaleLabel.setText("SCALE", juce::dontSendNotification); @@ -1022,6 +1038,7 @@ void MainContentComponent::loadPresetFile() { currentPresetIndex = -1; patchLCD.setText(file.getFileNameWithoutExtension()); + processorRef.apvts.state.setProperty("presetName", file.getFileNameWithoutExtension(), nullptr); setupSyncKnob(lfo1RateKnob, lfo1RateAttach, lfo1BeatAttach, "lfo1Rate", "lfo1Beat", lfo1SyncLed.isLit()); setupSyncKnob(lfo2RateKnob, lfo2RateAttach, lfo2BeatAttach, "lfo2Rate", "lfo2Beat", lfo2SyncLed.isLit()); @@ -1036,6 +1053,7 @@ void MainContentComponent::applyCurrentPreset() { processorRef.fadeOutActiveVoices(0.25f); processorRef.presetManager.applyPreset(presets[currentPresetIndex].name, processorRef.apvts); patchLCD.setText(presets[currentPresetIndex].name); + processorRef.apvts.state.setProperty("presetName", presets[currentPresetIndex].name, nullptr); // The LedToggle updates itself via its timer, so re-sync the rate/beat // knob attachments to match. @@ -1062,6 +1080,7 @@ void MainContentComponent::randomizeParameters() { } patchLCD.setText("RANDOM"); + processorRef.apvts.state.setProperty("presetName", "RANDOM", nullptr); // Re-sync the rate/beat knob attachments to match the randomized sync states. setupSyncKnob(lfo1RateKnob, lfo1RateAttach, lfo1BeatAttach, "lfo1Rate", "lfo1Beat", lfo1SyncLed.isLit());