#include "MacroControls.h" namespace serum { bool MacroControls::addAssignment (int macro, ModTarget target, float depth) { if (macro < 0 || macro >= kNumMacros || (int) target < 0 || (int) target >= kNumModTargets || ! std::isfinite (depth) || (int) assignments[(size_t) macro].size() >= kMaxAssignments) return false; assignments[(size_t) macro].push_back ({ target, juce::jlimit (-1.0f, 1.0f, depth) }); return true; } void MacroControls::removeAssignment (int macro, int index) { macro = juce::jlimit (0, kNumMacros - 1, macro); auto& vec = assignments[(size_t) macro]; if (index >= 0 && index < (int) vec.size()) vec.erase (vec.begin() + index); } void MacroControls::clear() { for (auto& a : assignments) a.clear(); } juce::String MacroControls::macroName (int index) { switch (index) { case 0: return "Energy"; case 1: return "Width"; case 2: return "Drive"; case 3: return "Atmosphere"; default: return {}; } } juce::ValueTree MacroControls::toValueTree() const { MacroControls validated; for (int m = 0; m < kNumMacros; ++m) for (const auto& a : assignments[(size_t) m]) { if ((int) validated.assignments[(size_t) m].size() >= kMaxAssignments) break; if (! validated.addAssignment (m, a.target, a.depth)) continue; } juce::ValueTree tree ("MACROS"); for (int m = 0; m < kNumMacros; ++m) { juce::ValueTree mac ("MACRO"); mac.setProperty ("index", m, nullptr); for (const auto& a : validated.assignments[(size_t) m]) { juce::ValueTree asg ("ASSIGN"); asg.setProperty ("target", modTargetToString (a.target), nullptr); asg.setProperty ("depth", a.depth, nullptr); mac.appendChild (asg, nullptr); } tree.appendChild (mac, nullptr); } return tree; } void MacroControls::fromValueTree (const juce::ValueTree& tree) { clear(); if (! tree.hasType ("MACROS")) return; for (const auto& mac : tree) { if (! mac.hasType ("MACRO")) continue; const double savedIndex = (double) mac.getProperty ("index", -1); if (! std::isfinite (savedIndex) || savedIndex < 0.0 || savedIndex >= kNumMacros || std::floor (savedIndex) != savedIndex) continue; const int index = (int) savedIndex; for (const auto& asg : mac) { if ((int) assignments[(size_t) index].size() >= kMaxAssignments) break; if (! asg.hasType ("ASSIGN")) continue; if (! addAssignment (index, modTargetFromString (asg.getProperty ("target").toString()), (float) asg.getProperty ("depth", 0.0))) continue; } } } } // namespace serum