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

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



Hello!

I wanted to mention that big slider always at -90 at the beginning while two
other on zero...

also, is it possible to move server windows to the very bottom of the screen
if i'm not using big slider?

and it would be nice to include code changing post window appearance as
well, like on this video for example))

http://www.youtube.com/watch?v=TTzKRJ7aLZo
http://www.youtube.com/watch?v=TTzKRJ7aLZo 

Thank you!


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;
> 		    });
> 		});
> 		
> 		}
> 
> }
> 
> 
> 
> 

-- 
View this message in context: http://n2.nabble.com/ToolsMenu-and-Server-gui-niceties-tp2914037p3241230.html
Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.

_______________________________________________
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/