Two APCs with deck focus and presets lights work on each
[SugarCubes.git] / _Presets.pde
CommitLineData
e0794d3a 1interface PresetListener {
a8d1f57a
MS
2 public void onPresetLoaded(Engine.Deck deck, Preset preset);
3 public void onPresetDirty(Engine.Deck deck, Preset preset);
4 public void onPresetStored(Engine.Deck deck, Preset preset);
1f974cbc 5 public void onPresetUnloaded();
e0794d3a
MS
6}
7
c1d777c9 8class PresetManager implements LXParameter.Listener {
e0794d3a
MS
9
10 public static final int NUM_PRESETS = 8;
11 public static final String FILENAME = "data/presets.txt";
12 public static final String DELIMITER = "\t";
13
14 private final Preset[] presets = new Preset[NUM_PRESETS];
15 private final List<PresetListener> listeners = new ArrayList<PresetListener>();
16
c1d777c9
MS
17 private Preset loadedPreset = null;
18 private LXPattern loadedPattern = null;
e0794d3a
MS
19
20 PresetManager() {
21 for (int i = 0; i < presets.length; ++i) {
22 presets[i] = new Preset(this, i);
23 }
24 String[] values = loadStrings(FILENAME);
25 if (values == null) {
26 write();
27 } else {
28 int i = 0;
29 for (String serialized : values) {
30 presets[i++].load(serialized);
31 if (i >= NUM_PRESETS) {
32 break;
33 }
34 }
35 }
1f974cbc
MS
36 for (Engine.Deck deck : lx.engine.getDecks()) {
37 deck.addListener(new Engine.AbstractListener() {
38 public void patternDidChange(Engine.Deck deck, LXPattern pattern) {
39 if (midiEngine.getFocusedDeck() == deck) {
40 if (pattern != loadedPattern) {
a8d1f57a 41 onPresetDirty(deck);
1f974cbc
MS
42 }
43 }
44 }
45 });
46 }
47 }
48
49 public void setMidiEngine(MidiEngine midiEngine) {
50 midiEngine.addListener(new MidiEngineListener() {
51 public void onFocusedDeck(int deckIndex) {
52 loadedPreset = null;
53 for (PresetListener listener : listeners) {
54 listener.onPresetUnloaded();
55 }
56 }
57 });
e0794d3a
MS
58 }
59
60 public void addListener(PresetListener listener) {
61 listeners.add(listener);
62 }
a8d1f57a
MS
63
64 public Engine.Deck deckForPattern(LXPattern pattern) {
65 for (Engine.Deck deck : lx.engine.getDecks()) {
66 for (LXPattern p : deck.getPatterns()) {
67 if (p == pattern) {
68 return deck;
69 }
70 }
71 }
72 return null;
73 }
e0794d3a 74
a1396b9e 75 public void dirty(LXPattern pattern) {
a8d1f57a 76 onPresetDirty(deckForPattern(pattern));
a1396b9e
MS
77 }
78
f6394aaa
MS
79 public void select(Engine.Deck deck, int index) {
80 presets[index].select(deck);
e0794d3a
MS
81 }
82
f6394aaa 83 public void store(Engine.Deck deck, int index) {
e0794d3a 84 presets[index].store(midiEngine.getFocusedPattern());
1f974cbc 85 for (PresetListener listener : listeners) {
a8d1f57a 86 listener.onPresetStored(deck, presets[index]);
1f974cbc 87 }
f6394aaa 88 select(deck, index);
e0794d3a
MS
89 }
90
a8d1f57a 91 public void onPresetLoaded(Engine.Deck deck, Preset preset, LXPattern pattern) {
c1d777c9
MS
92 if (loadedPattern != pattern) {
93 if (loadedPattern != null) {
94 for (LXParameter p : loadedPattern.getParameters()) {
95 ((LXListenableParameter) p).removeListener(this);
96 }
97 }
98 }
e0794d3a 99 for (PresetListener listener : listeners) {
a8d1f57a 100 listener.onPresetLoaded(deck, preset);
c1d777c9
MS
101 }
102 loadedPreset = preset;
103 loadedPattern = pattern;
104 for (LXParameter p : loadedPattern.getParameters()) {
105 ((LXListenableParameter) p).addListener(this);
106 }
107 }
108
a8d1f57a 109 private void onPresetDirty(Engine.Deck deck) {
66067e53
MS
110 if (loadedPreset != null) {
111 for (PresetListener listener : listeners) {
a8d1f57a 112 listener.onPresetDirty(deck, loadedPreset);
66067e53 113 }
e0794d3a
MS
114 }
115 }
116
1f974cbc 117 public void onParameterChanged(LXParameter p) {
a8d1f57a 118 onPresetDirty(deckForPattern(loadedPattern));
1f974cbc
MS
119 }
120
e0794d3a
MS
121 public void write() {
122 String[] lines = new String[NUM_PRESETS];
123 int i = 0;
124 for (Preset preset : presets) {
125 lines[i++] = preset.serialize();
126 }
127 saveStrings(FILENAME, lines);
128 }
129}
130
131class Preset {
132
133 final PresetManager manager;
134 final int index;
135
136 String className;
137 final Map<String, Float> parameters = new HashMap<String, Float>();
138
139 Preset(PresetManager manager, int index) {
140 this.manager = manager;
141 this.index = index;
142 }
143
144 public void load(String serialized) {
145 className = null;
146 parameters.clear();
147 try {
148 String[] parts = serialized.split(PresetManager.DELIMITER);
149 className = parts[0];
150 int i = 1;
151 while (i < parts.length - 1) {
152 parameters.put(parts[i], Float.parseFloat(parts[i+1]));
153 i += 2;
154 }
155 } catch (Exception x) {
156 className = null;
157 parameters.clear();
158 }
159 }
160
161 public String serialize() {
162 if (className == null) {
163 return "null";
164 }
165 String val = className + PresetManager.DELIMITER;
166 for (String pKey : parameters.keySet()) {
167 val += pKey + PresetManager.DELIMITER + parameters.get(pKey) + PresetManager.DELIMITER;
168 }
169 return val;
170 }
171
172 public void store(LXPattern pattern) {
173 className = null;
174 parameters.clear();
175 className = pattern.getClass().getName();
176 for (LXParameter p : pattern.getParameters()) {
177 parameters.put(p.getLabel(), p.getValuef());
178 }
a1396b9e
MS
179 if (pattern instanceof DPat) {
180 DPat dpattern = (DPat) pattern;
181 for (DBool bool : dpattern.bools) {
182 parameters.put(bool.tag, bool.b ? 1.f : 0.f);
183 }
184 for (Pick pick : dpattern.picks) {
185 parameters.put(pick.tag, pick.CurRow + pick.CurCol/100.f);
186 }
187 }
e0794d3a
MS
188 manager.write();
189 }
190
f6394aaa 191 public void select(Engine.Deck deck) {
e0794d3a
MS
192 for (LXPattern pattern : deck.getPatterns()) {
193 if (pattern.getClass().getName().equals(className)) {
194 for (String pLabel : parameters.keySet()) {
195 for (LXParameter p : pattern.getParameters()) {
196 if (p.getLabel().equals(pLabel)) {
197 p.setValue(parameters.get(pLabel));
198 }
199 }
a1396b9e
MS
200 if (pattern instanceof DPat) {
201 DPat dpattern = (DPat) pattern;
202 for (DBool bool : dpattern.bools) {
203 if (bool.tag.equals(pLabel)) {
204 bool.set(bool.row, bool.col, parameters.get(pLabel) > 0);
205 }
206 }
207 for (Pick pick : dpattern.picks) {
208 if (pick.tag.equals(pLabel)) {
209 float f = parameters.get(pLabel);
210 pick.set((int) floor(f), (int) round((f%1)*100.));
211 }
212 }
213 }
e0794d3a
MS
214 }
215 deck.goPattern(pattern);
a1396b9e
MS
216 if (pattern instanceof DPat) {
217 ((DPat)pattern).updateLights();
218 }
a8d1f57a 219 manager.onPresetLoaded(deck, this, pattern);
e0794d3a
MS
220 break;
221 }
222 }
223 }
224}
225