[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [sc-users] ToolsMenu and Server gui niceties



Hi

Timur Kuyanov escreveu:
Hello!

Interesting to try your tools, but i'm new to SC, can you explain steps need
to be taken to get it work?

I've put ToolsMenu folder to SCClassLibrary folder, now have this in post
window:


Don't worry about it, it's not a problem, I got millions of those.

And anyway, i don't really understand what i need to do to use it? is it
supposed to appear in menu of SC itself?

Yes, it should appear in the menu next to help. Are you placing this in your startup file ? (you can change the paths to something else off course)

ToolsMenu.add(
			[
			Platform.userAppSupportDir +/+ "startup.rtf",
			Platform.userAppSupportDir +/+ Extensions/"
			];
		);


 What code i need to put in
startup.rtf to get "black gui"?))

Server.makeWindows. altogh even if you don't put this you will get the black server guis, just not the main volume slider. If you have place the class file in your extension folder it will overide the normal server window. Are you not seeing the black gui ? Where did you put the class files (.sc) ?

Miguel


Sorry for stupid questions.

Thanx!


Miguel C. Negrão wrote:
Hi

I've made a class to add some common used functions of supercollider in
a menu using SCMenuItem.
It allows to choose soundcard for each server or all at the same time,
EQ, record window, auto sintax colorize on current document, color
picker, open quarks, Init Midi, check current midi messages, run a file
with cmd^r .
Finally it adds a menu tree with all files in predetermined folders
for easy access. When working on a project I'm always editing the same
files, closing and opening the files, and I got fed up and decided to
just put them in the menu bar for easy access.
I hope this might be useful for someone else, I think specially
newbies will appreciate being able to change the sound card (thanks for
someone who posted the code in the list) and record from a gui (thanks
wouter for ServerRecordWindow !).

http://www.friendlyvirus.org/artists/zlb/code/ToolsMenu.zip

Also included here is a nice minimal black gui for the server window I
got a from a friend and that I refined a bit. It puts all server guis as
a black strip in the bottom of the screen plus a big fader that changes
the volume of all servers. To use this addon one must call
Server.makeWindows each time a server is created and in the startup.rtf.
It uses the gui version of queryAllNodes by Scott Wilson that I added as
the method queryAllNodesGui.

I hope this is useful.
--
Miguel Negrão // ZLB
http://www.friendlyvirus.org/artists/zlb/





+ Server {

	// shortcut server record
	rek {|chans=1, filename="test.aif", format="int24"|
		var path, sched;
		path = "~/Desktop/".standardizePath ++ filename;
		this.recChannels = chans;
		this.recSampleFormat = format;
this.prepareForRecord( path ); AppClock.sched(1.0, { this.record; nil });
	}
	
	stoprek { this.stopRecording }
	
	*makeWindows{
		var window,w;
		var bgColor= Color.grey(0.0, 0.9);
		var stringColor= Color.grey(0.8);
		var runningColor= Color.magenta;
		var bootingColor= Color.yellow(0.9);
		var bundlingColor= Color.new255(237, 157, 196);
		var width, font;

Server.set.do({|se| if(se.window != nil) {
				Routine({
					se.window.close;
					0.1.wait;
			 		se.makeWindow;
			 		}).play(AppClock)
			 }{
			 	se.makeWindow
			 }});
width = SCWindow.screenBounds.width - 2;
		w = window = Window( "Main Volume",
						Rect(1, 1, width, 19),
						resizable: false, border: false);
						w.view.background_(bgColor);
			w.view.decorator = FlowLayout(w.view.bounds);
			w.front;
		Slider.new(w,Rect(0, 0, width-2, 16))
.action_{|v| Server.set.do{ |server| server.volume.volume_([server.volume.min,server.volume.max,
\db].asSpec.map(v.value))
					}
				}
				.canFocus_(false);
		
	}
	// server window customize	
	makeWindow { arg w;
		var active, booter, killer, makeDefault, running, booting, stopped,
bundling;
		var scoper;
		var countsViews, ctlr;
		var dumping=false, label, gui, volumeNum;
		
		var bgColor= Color.grey(0.0, 0.9);
		var stringColor= Color.grey(0.8);
		var runningColor= Color.magenta;
		var bootingColor= Color.yellow(0.9);
		var bundlingColor= Color.new255(237, 157, 196);
		var hideLocal= false;
		var hideInternal= false;
		var hideButt;
		var width, font;
		
		gui = GUI.current;
		
		if (window.notNil, { ^window.front });
		
		width = SCWindow.screenBounds.width - 2;
		font = Font("Monaco", 9);
		
		if(w.isNil) {
			label = name.asString + "server";
			w = window = Window( label,
						Rect(1, ((named.values.size-1)-named.values.indexOf(this)+1)*20+1,
width, 19),
						resizable: false, border: false);
						w.view.background_(bgColor);
			w.view.decorator = FlowLayout(w.view.bounds);
		} { label = w.name };
		
		active = StaticText(w, Rect(0, 0, 78, 24));
		active.string = this.name.asString;
		active.align = \center;
		active.font = font;
		active.background = Color.clear;
		if(serverRunning,running,stopped);
		
		hideButt= Button(w, Rect(0, 0, 19, 19));
		hideButt.states= [["x", stringColor, Color.clear], ["", stringColor,
Color.clear]];
		hideButt.action_({|view|
			if(view.value==1, {
				w.bounds_(Rect(1,
((named.values.size-1)-named.values.indexOf(this)+1)*20+1, 108, 19));
				w.view.children.do{|x|
					if([active, hideButt].includes(x).not, {
						x.visible= false;
					});
				};
			}, {
				w.bounds_(Rect(1,
((named.values.size-1)-named.values.indexOf(this)+1)*20+1, width, 19));
				w.view.children.do{|x| x.visible= true};
			});
		});
		if(isLocal&&hideLocal, { hideButt.valueAction_(1) });
		if(this.name==\internal&&hideInternal, { hideButt.valueAction_(1) });
		
		
		if(isLocal,{
			booter = Button(w, Rect(0, 0, 48, 24));
			booter.states = [["Boot", stringColor, Color.clear],
						   ["Quit", stringColor, Color.clear]];
			
booter.action = { arg view; if(view.value == 1, {
					booting.value;
					this.boot;
				});
				if(view.value == 0,{
					this.quit;
				});
			};
			booter.setProperty(\value,serverRunning.binaryValue);
			
			killer = Button(w, Rect(0,0, 24, 24));
			killer.states = [["K", stringColor, Color.clear]];
			
			killer.action = { Server.killAll };	
		});
		
		
		makeDefault = Button(w, Rect(0, 0, 80, 24));
		makeDefault.states = [["-> default", stringColor, Color.clear]];
		makeDefault.action = {
			thisProcess.interpreter.s = this;
			Server.default = this;
		};
		
		w.view.keyDownAction = { arg ascii, char;
			var startDump, stopDump, stillRunning;
			
case {char === $n} { this.queryAllNodesGui }
			{char === $l} { this.meter }
			{char === $N} { this.queryAllNodes(true) }
			{char === $ } { if(serverRunning.not) { this.boot } }
			{char === $s and: { Stethoscope.isValidServer( this )}} { this.scope }
			{char == $d} {
				if(this.isLocal or: { this.inProcess }) {
					stillRunning = {
						SystemClock.sched(0.2, { this.stopAliveThread });
					};
startDump = { this.dumpOSC(1);
						this.stopAliveThread;
						dumping = true;
						w.name = "dumping osc: " ++ name.asString;
						CmdPeriod.add(stillRunning);
					};
					stopDump = {
						this.dumpOSC(0);
						this.startAliveThread;
						dumping = false;
						w.name = label;
						CmdPeriod.remove(stillRunning);
					};
					if(dumping, stopDump, startDump)
				} {
					"cannot dump a remote server's messages".inform
				}
			
			};
		};
		
		if (isLocal, {
			
			running = {
				active.stringColor_(runningColor);
				booter.setProperty(\value,1);
			};
			stopped = {
				active.stringColor_(stringColor);
				booter.setProperty(\value,0);
			};
			booting = {
				active.stringColor_(bootingColor);	
			};
			bundling = {
				active.stringColor_(bundlingColor);	
				booter.setProperty(\value,1);
			};
			
			w.onClose = {
				window = nil;
				ctlr.remove;
			};
		},{	
			running = {
				active.stringColor = runningColor;	
				active.background = Color.red;
			};
			stopped = {
				active.stringColor = stringColor;	
				active.background = Color.black;
			};
			booting = {
				active.stringColor = bootingColor;	
				active.background = Color.yellow;
			};
			
			bundling = {
				active.stringColor = bundlingColor;	
				active.background = Color.red(0.5);
				booter.setProperty(\value,1);
			};
			
			w.onClose = {
				// but do not remove other responders
				this.stopAliveThread;
				ctlr.remove;
			};
		});
		if(serverRunning,running,stopped);
		

countsViews = #[ "Avg CPU :", "Peak CPU :", "UGens :", "Synths :", "Groups :", "SynthDefs :"
		].collect({ arg name, i;
			var label,numView, pctView;
			label = StaticText(w, Rect(0,0, 80, 14));
			label.stringColor_(stringColor);			
			label.string = name;
			label.align = \right;
		
if (i < 2, { numView = StaticText(w, Rect(0,0, 38, 14));
				numView.stringColor_(stringColor);	
				numView.string = "?";
				numView.align = \left;
			
				pctView = StaticText(w, Rect(0,0, 12, 14));
				pctView.stringColor_(stringColor);	
				pctView.string = "%";
				pctView.align = \left;
			},{
				numView = StaticText(w, Rect(0,0, 50, 14));
				numView.stringColor_(stringColor);
				numView.string = "?";
				numView.align = \left;
			});
			numView
		});
		
		if(isLocal or: { options.remoteControlVolume }) {
		{
			var volSpec, cpVol;
			var volumeSlider, muteButton, muteActions, volController;
			muteActions = [{this.unmute}, {this.mute}];
			volSpec = [volume.min, volume.max, \db].asSpec;
			
			StaticText.new(w, Rect(0,0, 44, 18))
				.font_(font)
				.stringColor_(stringColor)
				.string_(" volume :");

			muteButton = gui.button.new(w, Rect(0, 0, 20, 16))
				.font_(font)
				.canFocus_(false)
				.states_([
					["M", stringColor, Color.clear],
					["M", Color.black, Color.red.alpha_(0.3)]
					])
				.action_({arg me;
					this.serverRunning.if({
						muteActions[me.value].value;
						}, {
						"The server must be booted to mute it".warn;
						me.value_(0);
						})
					});
					
			volumeNum = gui.numberBox.new(w, Rect(0, 0, 28, 15))
				.font_(font)
				.value_(0.0)
				.align_(\center)
				.stringColor_(stringColor)
				.action_({arg me;
					var newdb;
					newdb = me.value.clip(-90, 6);
					this.volume_(newdb);
					volumeSlider.value_(volSpec.unmap(newdb));
					});
			
			volumeSlider = gui.slider.new(w, Rect(0, 0, 172, 16))
				.value_(volSpec.unmap(0))
				.onClose_{volController.remove}
.action_({arg me; var newdb;
					newdb = volSpec.map(me.value).round(0.1);
					this.volume_(newdb);
					volumeNum.value_(newdb);
					})
				.keyDownAction_({arg slider, char, modifiers, unicode, keycode;
					if (char == $], { slider.increment; });
					if (char == $[, { slider.decrement; });
					if (unicode == 16rF700, { slider.increment; });
					if (unicode == 16rF703, { slider.increment; });
					if (unicode == 16rF701, { slider.decrement; });
					if (unicode == 16rF702, { slider.decrement; });					nil;
					});
			volController = SimpleController(volume)
				.put(\amp, {|changer, what, vol|
					{
						volumeNum.value_(vol.round(0.01));
						volumeSlider.value_(volSpec.unmap(vol));
					}.defer		
				})
				.put(\mute, {|changer, what, flag|
					{
						muteButton.value_(flag.binaryValue);
					}.defer		
				})
				.put(\ampRange, {|changer, what, min, max|
					volSpec = [min, max, \db].asSpec;
					volumeSlider.value_(volSpec.unmap(volume.volume));
				})			
			}.value;
		};
		

		w.front;

		ctlr = SimpleController(this)
			.put(\serverRunning, {	if(serverRunning,running,stopped) })
			.put(\counts,{
				countsViews.at(0).string = avgCPU.round(0.1);
				countsViews.at(1).string = peakCPU.round(0.1);
				countsViews.at(2).string = numUGens;
				countsViews.at(3).string = numSynths;
				countsViews.at(4).string = numGroups;
				countsViews.at(5).string = numSynthDefs;
			})
			.put(\bundling, bundling);
		this.startAliveThread;
		
		w.view.children.do{|view|
			view.bounds_(Rect(view.bounds.left, view.bounds.top, view.bounds.width,
14));
			if(view.respondsTo(\font)) { view.font_(font) };
			view.canFocus_(false);
		};
	}
	
	queryAllNodesGui {
		var resp, done = false;
		
		// msg[1] controls included
		// msg[2] nodeID of queried group
		// initial number of children
		resp = OSCresponderNode(this.addr, '/g_queryTree.reply', { arg time,
responder, msg;
//var finalEvent;
		    var i = 2, j, controls, printControls = false, dumpFunc;
		    if(msg[1] != 0, {printControls = true});
		    dumpFunc = {|numChildren|
		        var event, children;
		        event = ().group;
		        event.id = msg[i];
		        event.instrument = nil; // need to know it's a group
		        i = i + 2;
		        children = Array.fill(numChildren, {
		            var id, child;
		            // i = id
		            // i + 1 = numChildren
		            // i + 2 = def (if synth)
		            id = msg[i];
		            if(msg[i+1] >=0, {
		                child = dumpFunc.value(msg[i+1]);
		            }, {
		                j = 4;
		                child = ().synth.instrument_(msg[i+2]);
		                if(printControls, {
controls = ();
		                    msg[i+3].do({
		                        controls[msg[i + j]] = msg[i + j + 1];
		                        j = j + 2;
		                    });
		                    child.controls = controls;
		                    i = i + 4 + (2 * controls.size);
		                }, {i = i + 3 });
		            });
		            child.id = id;
		        });
		        event.children = children;
		        event;
		    };
		    ~finalEvent = dumpFunc.value(msg[3]);
done = true;
		    {
		        var collectChildren, levels, countSize;
		        var window, view, bounds;
		        var tabSize = 25;
		        collectChildren = {|group|
		            group.children.collect({|child|
		                if(child.children.notNil,{
		                    child.id -> collectChildren.value(child);
		                }, {
		                    child.id -> child.instrument;
		                });
		            });
		        };
		        levels = collectChildren.value(~finalEvent);
countSize = {|array|
		            var size = 0;
		            array.do({|elem|
		                if(elem.value.isArray, { size = size +
countSize.value(elem.value) + 2}, {size = size + 1;});
		            });
		            size
		        };
		        //countSize.value(levels);
window = Window.new(this.asString,scroll:true).front; window.view.hasHorizontalScroller_(false).background_(Color.black); bounds = Rect(0, 0, 400, tabSize * (countSize.value(levels) +
2));
		        view = UserView.new(window, bounds);
view.drawFunc = {
		            var xtabs = 0, ytabs = 0, drawFunc;
drawFunc = {|group|
		                var thisSize, rect, endYTabs;
		                xtabs = xtabs + 1;
		                ytabs = ytabs + 1;
		                group.do({|node|
		                    if(node.value.isArray, {
thisSize = countSize.value(node);
		                        endYTabs = ytabs + thisSize + 0.2;
		                        rect = Rect(xtabs * tabSize,
		                            ytabs * tabSize,
		                            window.view.bounds.width - (xtabs * tabSize
* 2),
		                            thisSize * tabSize;
		                        );
		                        Pen.fillColor = Color.green.alpha_(0.5);
		                        Pen.fillRect(rect);
		                        Pen.strokeRect(rect);
		                        (" Group" + node.key.asString + (node.key ==
1).if("- default group", "")).drawInRect(rect,
		                            Font("Helvetica", 11),
		                            Color.black);
		                        drawFunc.value(node.value);
		                        ytabs = endYTabs;
		                        //ytabs.postln;
		                    },{
		                        rect = Rect(xtabs * tabSize,
		                            ytabs * tabSize,
		                            7 * tabSize,
		                            0.8 * tabSize
		                        );
		                        //rect.postln;
		                        Pen.fillColor = Color.red;
		                        Pen.fillRect(rect);
		                        Pen.strokeRect(rect);
		                        (" " ++ node.key.asString +
node.value.asString).drawInRect(rect, Font("Helvetica", 11), Color.black);
		                        ytabs = ytabs + 1;
		                    });
		                });
		                xtabs = xtabs - 1;
		            };
		            drawFunc.value(levels);
		        };
		    }.defer
		}).add.removeWhenDone;
		this.sendMsg("/g_queryTree", 0, 0);
		SystemClock.sched(3, {
		    done.not.if({
		        resp.remove;
		        "Server failed to respond to Group:queryTree!".warn;
		    });
		});
		
		}

}







--
Miguel Negrão // ZLB
http://www.friendlyvirus.org/artists/zlb/

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: https://listarc.bham.ac.uk/marchives/sc-users/
search: https://listarc.bham.ac.uk/lists/sc-users/search/