HelpBrowser: path box becomes a more conventional search box
[supercollider.git] / SCClassLibrary / JITLib / GUI / ProxyMixerOld.sc
blobbc7011106001f153e6de5e396b95ac27818f23de
1 // idea by adc, mods by /f0, jrh, mc, ...
3 ProxyMixerOld {
4                 // proxymixer need not be built into a supplied window,
5                 // so just call the parent window.
6         var <window, <zone, <proxyspace, <>nProxies;
7         var <activeNodes;
8         var <title;
10         var <editZoneBtn, <pxMons, <editBtnsAr, <editBtnsKr, <buttonLinesKr;
11         var <compArZone, <compKrZone;
13         var origBounds, fullBounds, editZoneOpen=false, <selectMethod=\existingProxies;
14         var <skippy, <editor, <recorder;
15         var <skin, <font;
16         var <prevKrNames, <prevArNames;
17         var <scrollyAr, <keysRotationAr=0;
18         var <scrollyKr, <keysRotationKr=0;
20         *initClass {
21                 GUI.skins.put(\jitSmall, (
22                                 fontSpecs:      ["Helvetica", 10],
23                                 fontColor:      Color.black,
24                                 background:     Color(0.8, 0.85, 0.7, 0.5),
25                                 foreground:     Color.grey(0.95),
26                                 onColor:                Color(0.5, 1, 0.5),
27                                 offColor:               Color.clear,
28                                 gap:                    0 @ 0,
29                                 margin:                 2@2,
30                                 buttonHeight:   16
31                         )
32                 );
33         }
35         w {
36                 warn("" ++ this.class ++ ":w is deprecated. use .window instead.")
37                 ^window
38         }
40         *new { arg proxyspace, nProxies = 16, title, where;
41                 ^super.new.init(proxyspace, nProxies,
42                         title ?? { format("proxyspace: %", proxyspace.tryPerform(\name) ? "") }, where
43                 );
44         }
46         init { arg space, nPxs = 16, argTitle, where;
48                 var winHeight, height, color, bounds;
49                 skin = GUI.skins[\jitSmall];
50                 font = GUI.font.new(*skin.fontSpecs);
52                 title = argTitle;
53                 bounds = ((where ? (10@250)).asArray ++ [0,0]).asRect;
55                 proxyspace = space ? currentEnvironment;
56                 if(proxyspace.isKindOf(ProxySpace).not) { Error("no proxy space present!").throw };
57                 nProxies = nPxs;
59                 height = nProxies + 1 * (skin.buttonHeight) + 16;
61                 // global layout:
63                 origBounds = bounds.resizeTo(612, height + 10);
64                 fullBounds = origBounds.resizeBy(345, 0);
65                 this.makeWindow;
67                 zone = CompositeView(window, fullBounds.moveTo(0,0));
68                 zone.decorator =  FlowLayout(zone.bounds); //.gap_(6@6);
70                 compArZone = CompositeView.new(zone, Rect(0, 0, 400, height))
71                         .background_(skin.foreground);
72                 compKrZone = CompositeView.new(zone, Rect(0, 0, 200, height))
73                         .background_(skin.foreground);
75                 compArZone.decorator = FlowLayout(compArZone.bounds).gap_(skin.gap);
76                 compKrZone.decorator = FlowLayout(compKrZone.bounds).gap_(skin.gap);
78                 this.makeArZone;
79                 this.makeKrZone;
80                 this.makeEditZone;
82                 window.front;
84                 this.makeSkipJack;
85                 window.onClose_({ this.stopUpdate });
86                 this.runUpdate;
88         }
90         runUpdate { editor.runUpdate; skippy.start; }
91         stopUpdate { editor.stopUpdate; skippy.stop }
93         makeWindow {
94                 window = Window(this.title, origBounds);
95                 window.view.background = skin.background;
97         }
98         makeSkipJack {
99                 skippy = SkipJack({ this.updateZones }, 0.2, { window.isClosed }, title);
100         }
102         makeEditZone {
103                 editor = NodeProxyEditor(nil, nProxies - 1, zone);
104         }
106         openEditZone { arg flag;
107                         if(flag == 1 or: {editZoneOpen.not}) {
108                                 if(editZoneOpen.not) {
109                                         origBounds = window.bounds;
110                                         window.bounds = window.bounds.setExtent(fullBounds.width, fullBounds.height);
111                                         editZoneOpen = true;
112                                         editZoneBtn.value = 1;
113                                         this.update;
114                                 }
115                         }{
116                                 window.bounds = window.bounds.setExtent(origBounds.width, origBounds.height);
117                                 editZoneOpen = false;
118                                 editZoneBtn.value = 0;
119                         };
120         }
123         makeArZoneHead {
125                 GUI.popUpMenu.new(compArZone, Rect(10, 10, 110, skin.buttonHeight+2))
126                                 .items_([\existingProxies, \activeProxies, \playingProxies])
127                                 .action_({ arg view; selectMethod = view.items[view.value] })
128                                 .font_(font);
130                 GUI.button.new(compArZone, Rect(10, 10, 50, skin.buttonHeight+2))
131                                 .states_(
132                                         [["reduce", skin.fontcolor, Color.clear]]                               )
133                                 .action_({ proxyspace.reduce }).font_(font);
134                 GUI.button.new(compArZone, Rect(10, 10, 30, skin.buttonHeight+2))
135                                 .states_(
136                                         [["doc", skin.fontcolor, Color.clear]]                          )
137                                 .action_({ proxyspace.document }).font_(font);
138                 GUI.button.new(compArZone, Rect(10, 10, 30, skin.buttonHeight+2))
139                                 .states_(
140                                         [["docc", skin.fontcolor, Color.clear]]                         )
141                                 .action_({
142                                         proxyspace.document(this.selectedKeys)
143                                 }).font_(font);
144                 /*
145                 GUI.button.new.new(compArZone, Rect(10, 10, 20, skin.buttonHeight+2)).states_([
146                                 ["#",  skin.fontcolor, Color.clear ]
147                         ])
148                         .action_({ editor.pxKey !? { proxyspace.storeOn(Post, [editor.pxKey]) } })
149                         .font_(font);
150                 */
151                 editZoneBtn = GUI.button.new(compArZone, Rect(10, 10, 60, skin.buttonHeight+2))
152                                 .font_(font)
153                                 .states_(
154                                         [       ["openEdit", skin.fontcolor, Color.clear],
155                                                 ["closeEdit", skin.fontcolor, Color.clear]
156                                         ]                               )
157                                 .action_({ |b| this.openEditZone(b.value) });
159                 GUI.button.new(compArZone, Rect(10, 10, 20, skin.buttonHeight+2))
160                                 .font_(font)
161                                 .states_(
162                                         [       ["R", Color.red, Color.clear]                                   ])
163                                 .action_({  RecordProxyMixer(this, origBounds.resizeTo(472, 100)) });
165         }
167         makeArZone {
168                 var arLayout = compArZone.decorator;
169                 this.makeArZoneHead;
171                 arLayout.nextLine;
172                 arLayout.shift(0,4);
174                 #pxMons, editBtnsAr = Array.fill(nProxies, { arg i;
175                         var pxmon, edbut;
176                         pxmon = ProxyMonitorGui(nil, compArZone, 360@skin.buttonHeight, makeWatcher: false);                    pxmon.zone.visible_(false);
178                 //      arLayout.shift(4);
180                         edbut = GUI.button.new(compArZone, Rect(0,0, 16, 16))
181                                 .font_(font)
182                                 .visible_(false)
183                                 .states_([
184                                         ["ed", Color.black, Color.grey(0.75)],
185                                         ["ed", Color.black, Color.white]])
186                                 .action_({ arg btn, mod;
187                                         if (mod.notNil and: { mod.isAlt }) {
188                                                 NodeProxyEditor(pxmon.proxy);                                   } {
189                                                 editor.proxy_(pxmon.proxy);
190                                                 this.openEditZone(1);
191                                                 editBtnsAr.do { |b| b.value_(0) };
192                                                 editBtnsKr.do { |b| b.value_(0) };
193                                                 btn.value_(1);
194                                         };
195                                 });
196                         arLayout.nextLine;
197                         [pxmon, edbut]
198                 }).flop;
200                 scrollyAr = EZScroller.new(window,
201                         Rect(compArZone.bounds.right - 16, 30, 12, nProxies * skin.buttonHeight),
202                         nProxies, nProxies,
203                         { |sc| keysRotationAr = sc.value.asInteger.max(0); }
204                 ).value_(0).visible_(true);
206         }
208         makeKrZone {
209                 var layout = compKrZone.decorator;
210                 var emergencySynth;
212                 GUI.staticText.new(compKrZone, Rect(0, 0, 180, 18))
213                         .font_(font).align_(\center)
214                         .string_("kr proxies");
216                 layout.nextLine;
217                 layout.shift(0,4);
219                 /*
220                 GUI.button.new(compKrZone, Rect(0,0,20, skin.buttonHeight))
221                 .font_(Font("Helvetica-Bold", 12))
222                 .states_([["+", Color.red, Color.white]])
223                 .action_({
224                         if(emergencySynth.isPlaying.not) {
225                                 emergencySynth = Synth.tail(0, "proxymixer_emergency");
226                                 NodeWatcher.register(emergencySynth);
227                         } {
228                                 emergencySynth.release
229                         }
230                 });
231                 */
232                 layout.nextLine;
233                 layout.nextLine;
235                 buttonLinesKr = Array.fill(nProxies, { arg i;
236                         var nameBtn, pausBtn, sendBtn, editBtn, pollBtn;
238                         nameBtn = GUI.dragSource.new(compKrZone, Rect(0,0,72, skin.buttonHeight))
239                         .font_(font)
240                         .align_(\center);
241                         pausBtn = GUI.button.new(compKrZone, Rect(0,0, 30, skin.buttonHeight))
242                                 .font_(font).states_([["paus", Color.black, skin.onColor],
243                                 ["rsum", Color.black, Color.clear]])
244                                 .action_({ |btn|
245                                         var editName = nameBtn.string.asSymbol;
246                                         var px = proxyspace.envir[editName];
247                                         if (px.notNil) {
248                                                 if (px.paused) { px.resume } { px.pause };
249                                         };
250                                 });
251                         sendBtn = GUI.button.new(compKrZone, Rect(0,0, 30, skin.buttonHeight))
252                                 .font_(font).states_([["send", Color.black, skin.onColor]])
253                                 .action_({ |btn|
254                                         var editName = nameBtn.string.asSymbol;
255                                         var px = proxyspace.envir[editName];
256                                         if (px.notNil) { px.send };
257                                 });
259                         pollBtn = GUI.button.new(compKrZone, Rect(0,0, 24, skin.buttonHeight))
260                                 .font_(font).states_([["poll", Color.black, skin.foreground]])
261                                 .action_({
262                                         var editName = nameBtn.string.asSymbol;
263                                         var px = proxyspace.envir[editName];
264                                         if (px.notNil) {
265                                                 px.bus.getn(px.numChannels, { |arr| [editName, arr.unbubble].postln });
266                                         };
267                                 });
268                         editBtn = GUI.button.new(compKrZone, Rect(0,0,20, skin.buttonHeight)).states_([
269                                 ["ed", skin.fontcolor, Color.new(0.7,0.7,0.7,1)],
270                                 ["ed", skin.fontcolor, Color.white]])
271                                 .action_({ arg btn;
272                                         var editName = nameBtn.string.asSymbol;
273                                         editor.proxy_(proxyspace.envir[editName]);
274                                         this.update;
275                                         this.openEditZone(1);
276                                         editBtnsAr.do { |b| b.value_(0) };
277                                         editBtnsKr.do { |b| b.value_(0) };
278                                         btn.value_(1);
279                                 }).font_(font);
282                         [ nameBtn, pausBtn, sendBtn, editBtn, pollBtn].do({ arg v; v.visible_(false) });
283                 });
284                 editBtnsKr = buttonLinesKr.collect(_[1]);
285                 layout.nextLine;
287                 scrollyKr = EZScroller.new(window,
288                         Rect(compKrZone.bounds.right - 16, 30, 12, nProxies * skin.buttonHeight),
289                         nProxies, nProxies,
290                         { |sc| keysRotationKr = sc.value.asInteger.max(0); }
291                 ).value_(0).visible_(true);
293         }
295         updateZones {
296                 this.updateArSlots;
297                 this.updateKrSlots;
298         }
300         highlightSlots { |parOffset, num|
301                 var onCol = Color(1, 0.5, 0.5);
302                 var offCol = Color.clear;
303                 { pxMons.do { |moni, i|
304                         var col = if (i >= parOffset and: (i < (parOffset + num).max(0)), onCol, offCol);
305                         moni.nameView.background_(col.green_([0.5, 0.7].wrapAt(i - parOffset div: 2)));
306                 } }.defer;
307         }
309         updateKrSlots {
310                 var krProxyNames;
311                 krProxyNames = proxyspace.krProxyNames;
313                 if (krProxyNames.size > nProxies) {
315                         scrollyKr.visible_(true)
316                                 .numItems_(krProxyNames.size)
317                                 .value_(keysRotationKr ? (krProxyNames.size - nProxies));
319                         krProxyNames = krProxyNames.drop(keysRotationKr).keep(nProxies);
320                 } {
321                         scrollyKr.visible_(false);
322                 };
324                 if (krProxyNames != prevKrNames) {
325                         nProxies.do { arg i;
326                                 var butLine, nameSink, key, px, showLine;
327                                 key = krProxyNames[i];
328                                 px = proxyspace.envir[ key ];
330                                 butLine = buttonLinesKr[i];
331                                 nameSink = butLine[0];
332                                 nameSink.object_(px).string_(key ? "");
334                                 showLine = key.notNil and: px.notNil;
335                                 butLine.do(_.visible_(showLine));
336                         }
337                 };
338                 prevKrNames = krProxyNames;
339         }
341         existingProxies { ^proxyspace.arProxyNames }
342         activeProxies { ^proxyspace.arProxyNames({ |px, key| px.isPlaying }) }
343         playingProxies { ^proxyspace.arProxyNames({ |px, key| px.monitor.isPlaying }) }
345         selectedKeys { ^this.perform(selectMethod) }
347         updateArSlots {
348                 var arPxNames, pxKey, px, pxMon;
349                 arPxNames = this.selectedKeys;
351                 if (arPxNames.size > nProxies) {
352                         scrollyAr.visible_(true)
353                                 .numItems_(arPxNames.size)
354                                 .value_(keysRotationAr ? (arPxNames.size - nProxies));
356                         arPxNames = arPxNames.drop(keysRotationAr).keep(nProxies);
357                 } {
358                         scrollyAr.visible_(false);
359                 };
361                 if (arPxNames != prevArNames) {
362                         nProxies.do { arg i;
363                                 pxMon = pxMons[i];
364                                 pxKey = arPxNames[i];
366                                 px = proxyspace.envir.at(pxKey);
367                                 if(px.notNil) {
368                                         pxMon.zone.visible_(true);
369                                         editBtnsAr[i].visible_(true);
370                                         pxMon.proxy_(px);
371                                 }{
372                                         pxMon.zone.visible_(false);
373                                         editBtnsAr[i].visible_(false);
374                                 }
375                         }
376                 };
377                 arPxNames.do { |name, i| pxMons[i].updateAll };
379                 prevArNames = arPxNames;
380         }
382         adjustWindowSize { arg n;
383                 n = n ? nProxies;
384                 window.bounds = if(editZoneOpen)
385                         { origBounds.resizeBy(0, 330) }
386                         { origBounds.copy.height_(n  * 18 + 80) };
387         }
391 NdefMixerOld : ProxyMixerOld {
393         *new { |server, nProxies = 16, title, bounds|
394                 var space;
395                 if (server.isKindOf(Symbol)) {
396                         server = Server.named.at(server);
397                         if (server.isNil) { Error("NdefMixer: no server named %.".format(server)).throw };
398                 } {
399                         server = server ? Ndef.defaultServer ? Server.default;
400                 };
402                 space = Ndef.dictFor(server);
404                 title = title ? ("Ndef:" + server.name);
405                 ^super.new(space, nProxies, title, bounds);
406         }