Skip to content

Commit

Permalink
Move towards editor undo (surge-synthesizer#6004)
Browse files Browse the repository at this point in the history
This is a basic infrastucture which moves us towards undo
in an editor. Lots missing here all detailed in a checklist
in surge-synthesizer#694 but with this commit parameter changes, modulation changes,
osc and fx changes all push into the undo stack. Use a simple limit
of 250 gestures per instance captured.
  • Loading branch information
baconpaul authored Apr 1, 2022
1 parent cfbb183 commit 79108f2
Show file tree
Hide file tree
Showing 13 changed files with 462 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/surge-xt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ target_sources(${PROJECT_NAME} PRIVATE
gui/SurgeJUCEHelpers.h
gui/SurgeJUCELookAndFeel.cpp
gui/SurgeJUCELookAndFeel.h
gui/UndoManager.cpp
gui/overlays/AboutScreen.cpp
gui/overlays/AboutScreen.h
gui/overlays/CoveringMessageOverlay.cpp
Expand Down
7 changes: 7 additions & 0 deletions src/surge-xt/SurgeSynthProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
#include "version.h"
#include "sst/plugininfra/cpufeatures.h"

/*
* This is a bit odd but - this is an editor concept with the lifetime of the processor
*/
#include "gui/UndoManager.h"

//==============================================================================
SurgeSynthProcessor::SurgeSynthProcessor()
: juce::AudioProcessor(BusesProperties()
Expand Down Expand Up @@ -429,7 +434,9 @@ void SurgeSynthProcessor::surgeParameterUpdated(const SurgeSynthesizer::ID &id,
{
auto spar = paramsByID[id];
if (spar)
{
spar->setValueNotifyingHost(f);
}
}

void SurgeSynthProcessor::surgeMacroUpdated(const long id, float f)
Expand Down
12 changes: 12 additions & 0 deletions src/surge-xt/SurgeSynthProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
#include <execinfo.h>
#endif

namespace Surge
{
namespace GUI
{
struct UndoManager;
}
} // namespace Surge

//==============================================================================
/**
*/
Expand Down Expand Up @@ -247,5 +255,9 @@ class SurgeSynthProcessor : public juce::AudioProcessor,

int checkNamesEvery = 0;

public:
std::unique_ptr<Surge::GUI::UndoManager> undoManager;

private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SurgeSynthProcessor)
};
50 changes: 50 additions & 0 deletions src/surge-xt/gui/SurgeGUIEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,11 @@ SurgeGUIEditor::SurgeGUIEditor(SurgeSynthEditor *jEd, SurgeSynthesizer *synth)
juce::Desktop::getInstance().addFocusChangeListener(this);

setupKeymapManager();

if (!juceEditor->processor.undoManager)
juceEditor->processor.undoManager =
std::make_unique<Surge::GUI::UndoManager>(this, this->synth);
juceEditor->processor.undoManager->resetEditor(this);
}

SurgeGUIEditor::~SurgeGUIEditor()
Expand Down Expand Up @@ -2143,6 +2148,20 @@ void SurgeGUIEditor::controlBeginEdit(Surge::GUI::IComponentTagValue *control)
int ptag = tag - start_paramtags;
if (ptag >= 0 && ptag < synth->storage.getPatch().param_ptr.size())
{
if (mod_editor)
{
auto mci = dynamic_cast<Surge::Widgets::ModulatableControlInterface *>(control);
if (mci)
{
undoManager()->pushModulationChange(ptag, modsource, current_scene, modsource_index,
mci->modValue);
}
}
else
{
undoManager()->pushParameterChange(ptag,
synth->storage.getPatch().param_ptr[ptag]->val);
}
juceEditor->beginParameterEdit(synth->storage.getPatch().param_ptr[ptag]);
}
else if (tag_mod_source0 + ms_ctrl1 <= tag &&
Expand Down Expand Up @@ -2177,6 +2196,30 @@ void SurgeGUIEditor::controlEndEdit(Surge::GUI::IComponentTagValue *control)
}
}

const std::unique_ptr<Surge::GUI::UndoManager> &SurgeGUIEditor::undoManager()
{
return juceEditor->processor.undoManager;
}

void SurgeGUIEditor::setParamFromUndo(int paramId, pdata val)
{
auto p = synth->storage.getPatch().param_ptr[paramId];
auto id = synth->idForParameter(p);
juceEditor->beginParameterEdit(p);
p->val = val;
synth->sendParameterAutomation(id, synth->getParameter01(id));
juceEditor->endParameterEdit(p);
synth->refresh_editor = true;
}

void SurgeGUIEditor::setModulationFromUndo(int paramId, modsources ms, int scene, int idx,
float val)
{
auto p = synth->storage.getPatch().param_ptr[paramId];
// FIXME scene and index
synth->setModulation(p->id, ms, scene, idx, val);
synth->refresh_editor = true;
}
//------------------------------------------------------------------------------------------------

long SurgeGUIEditor::applyParameterOffset(long id) { return id - start_paramtags; }
Expand Down Expand Up @@ -2422,6 +2465,8 @@ void SurgeGUIEditor::showSettingsMenu(const juce::Point<int> &where,
{
auto settingsMenu = juce::PopupMenu();

// settingsMenu.addItem("HACK DUMP", [this]() { undoManager()->dumpStack(); });

auto zoomMenu = makeZoomMenu(where, false);
settingsMenu.addSubMenu("Zoom", zoomMenu);

Expand Down Expand Up @@ -5942,6 +5987,7 @@ void SurgeGUIEditor::broadcastMSEGState()
void SurgeGUIEditor::repushAutomationFor(Parameter *p)
{
auto id = synth->idForParameter(p);

synth->sendParameterAutomation(id, synth->getParameter01(id));
}

Expand Down Expand Up @@ -6215,6 +6261,7 @@ void SurgeGUIEditor::setupKeymapManager()
Surge::GUI::keyboardActionName, [](auto a, auto b) {});

keyMapManager->clearBindings();
keyMapManager->addBinding(Surge::GUI::UNDO, {keymap_t::Modifiers::CONTROL, (int)'Z'});
keyMapManager->addBinding(Surge::GUI::OSC_1, {keymap_t::Modifiers::ALT, (int)'1'});
keyMapManager->addBinding(Surge::GUI::OSC_2, {keymap_t::Modifiers::ALT, (int)'2'});
keyMapManager->addBinding(Surge::GUI::OSC_3, {keymap_t::Modifiers::ALT, (int)'3'});
Expand Down Expand Up @@ -6312,6 +6359,9 @@ bool SurgeGUIEditor::keyPressed(const juce::KeyPress &key, juce::Component *orig

switch (action)
{
case Surge::GUI::UNDO:
undoManager()->undo();
return true;
case Surge::GUI::OSC_1:
changeSelectedOsc(0);
return true;
Expand Down
5 changes: 5 additions & 0 deletions src/surge-xt/gui/SurgeGUIEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <atomic>
#include <cstdarg>
#include <bitset>
#include "UndoManager.h"

class SurgeSynthEditor;

Expand Down Expand Up @@ -470,6 +471,10 @@ class SurgeGUIEditor : public Surge::GUI::IComponentTagValue::Listener,
bool canDropTarget(const std::string &fname); // these come as const char* from vstgui
bool onDrop(const std::string &fname);

const std::unique_ptr<Surge::GUI::UndoManager> &undoManager();
void setParamFromUndo(int paramId, pdata val);
void setModulationFromUndo(int paramId, modsources ms, int scene, int idx, float val);

private:
juce::Rectangle<int> positionForModulationGrid(modsources entry);
juce::Rectangle<int> positionForModOverview();
Expand Down
7 changes: 7 additions & 0 deletions src/surge-xt/gui/SurgeGUIEditorKeyboardActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace GUI
{
enum KeyboardActions
{
UNDO,

SAVE_PATCH,
FIND_PATCH,
FAVORITE_PATCH,
Expand Down Expand Up @@ -61,6 +63,9 @@ inline std::string keyboardActionName(KeyboardActions a)
{
switch (a)
{
case UNDO:
return "UNDO";

case OSC_1:
return "OSC_1";

Expand Down Expand Up @@ -127,6 +132,8 @@ inline std::string keyboardActionDescription(KeyboardActions a)
{
switch (a)
{
case UNDO:
return "Undo changes";
case SAVE_PATCH:
return "Open Save Patch Dialog";
case FIND_PATCH:
Expand Down
18 changes: 10 additions & 8 deletions src/surge-xt/gui/SurgeGUIEditorValueCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1498,14 +1498,15 @@ int32_t SurgeGUIEditor::controlModifierClicked(Surge::GUI::IComponentTagValue *c
addTo->addItem(displaytxt, true, isChecked, [this, p, i, tag]() {
float ef =
Parameter::intScaledToFloat(i, p->val_max.i, p->val_min.i);
undoManager()->pushParameterChange(p->id, p->val);
synth->setParameter01(synth->idForParameter(p), ef, false,
false);

if (p->ctrltype == ct_wstype)
{
updateWaveshaperOverlay();
}
repushAutomationFor(p);
broadcastPluginAutomationChangeFor(p);
synth->refresh_editor = true;
});
}
Expand All @@ -1526,13 +1527,14 @@ int32_t SurgeGUIEditor::controlModifierClicked(Surge::GUI::IComponentTagValue *c

std::string displaytxt = txt;

contextMenu.addItem(displaytxt, true, (i == p->val.i),
[this, ef, p, i]() {
synth->setParameter01(synth->idForParameter(p),
ef, false, false);
repushAutomationFor(p);
synth->refresh_editor = true;
});
contextMenu.addItem(
displaytxt, true, (i == p->val.i), [this, ef, p, i]() {
undoManager()->pushParameterChange(p->id, p->val);
synth->setParameter01(synth->idForParameter(p), ef, false,
false);
broadcastPluginAutomationChangeFor(p);
synth->refresh_editor = true;
});
}

if (isCombOnSubtype)
Expand Down
Loading

0 comments on commit 79108f2

Please sign in to comment.