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

[sc-dev] SF.net SVN: quarks:[2833] wslib



Revision: 2833
          http://sourceforge.net/p/quarks/code/2833
Author:   wsnoei
Date:     2021-01-18 15:48:15 +0000 (Mon, 18 Jan 2021)
Log Message:
-----------
replace asInt by asInteger

Modified Paths:
--------------
    wslib/wslib-classes/Experimental/MultiServer.sc
    wslib/wslib-classes/Extensions/String/asStringWithFrac.sc
    wslib/wslib-classes/Extensions/String/extString-boundsM9.sc
    wslib/wslib-classes/Extensions/UGens/extArray-Rotation.sc
    wslib/wslib-classes/Extensions/Various/extBuffer-checkFree.sc
    wslib/wslib-classes/Extensions/Various/extPoint-variousOps.sc
    wslib/wslib-classes/GUI/Extensions/extColor-web.sc
    wslib/wslib-classes/GUI/Full windows/ServerRecordWindow.sc
    wslib/wslib-classes/GUI/MIDI/MIDISliderWindow.sc
    wslib/wslib-classes/GUI/ModKey.sc
    wslib/wslib-classes/GUI/ScaledUserView/ScaledUserViewWindow.sc
    wslib/wslib-classes/GUI/Views/RoundButton.sc
    wslib/wslib-classes/GUI/Views/RoundView.sc
    wslib/wslib-classes/GUI/Views/ViewHolder2.sc
    wslib/wslib-classes/Main Features/EQ/BHiCut.sc
    wslib/wslib-classes/Main Features/Note/extVarious-midiname.sc
    wslib/wslib-classes/Main Features/SMPTE/SMPTEView.sc
    wslib/wslib-classes/Main Features/SimpleMIDIFile/SimpleMIDIFile.sc
    wslib/wslib-classes/Main Features/SimpleMIDIFile/extSimpleMIDIFile-patterns.sc
    wslib/wslib-classes/Main Features/SimpleMIDIFile/extSimpleMIDIFile-plot.sc
    wslib/wslib-help/interpolate.html

Modified: wslib/wslib-classes/Experimental/MultiServer.sc
===================================================================
--- wslib/wslib-classes/Experimental/MultiServer.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Experimental/MultiServer.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,124 +1,132 @@
-MultiServer {
-	classvar <>default;
-	
-	var <>servers, <window, <>pointer = 0, <>hostName, synthDefDir;
-	
-	*new { |names, adresses, options, hostName, synthDefDir, clientID = 0 |
-			// options and clientID are the same for every server
-		^super.new.init( names ? [], adresses ? [], options, clientID, hostName, synthDefDir );
-		}
-		
-	*row { |n = 1, startName = "server", startAddr, options, hostName, synthDefDir, clientID = 0|
-		var names, adresses;
-		startAddr = startAddr ? NetAddr( "127.0.0.1", 58000 );
-		
-		options = options ? Server.default.options;
-		names = { |i| startName ++ (i+1); } ! n;
-		adresses = { |i| NetAddr( startAddr.hostname, startAddr.port + i ); } ! n;
-		
-		^this.new( names, adresses, options, hostName, synthDefDir, clientID );
-		
-		}
-		
-	*rowFindHost { |hostName, n = 1, startName = "server", startPort = 58000, options, 
-			synthDefDir, clientID = 0|
-		var addr;
-		options = options ? Server.default.options;
-		if( hostName.isNil )
-			{ addr = NetAddr( "127.0.0.1", startPort ); }
-			{ addr = NetAddr( hostName.findReplaceAll( " ", "-" )
-			.replaceExtension( "local" ), startPort );  };
-		^this.row( n, startName, addr, options, hostName, synthDefDir, clientID );
-		}
-		
-	makeDefault { default = this }
-		
-	init { |argNames, argAddr, argOptions, argClientID, argHostName, argSynthDefDir|
-		
-		servers = argNames.collect({ |name, i|
-			Server( name, argAddr.wrapAt(i), argOptions, argClientID);
-			});
-		
-		hostName = argHostName ? "";
-		synthDefDir = argSynthDefDir ?? { SynthDef.synthDefDir; };
-		
-		}
-	
-	synthDefDir { ^"/Volumes/" ++ hostName ++ "/" ++ synthDefDir; }
-	
+{\rtf1\ansi\ansicpg1252\cocoartf1561\cocoasubrtf600
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue191;\red0\green0\blue0;\red0\green0\blue255;
+\red191\green0\blue0;\red102\green102\blue191;\red96\green96\blue96;\red0\green115\blue0;}
+{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c75000;\csgenericrgb\c0\c0\c0;\csgenericrgb\c0\c0\c100000;
+\csgenericrgb\c75000\c0\c0;\csgenericrgb\c40000\c40000\c75000;\csgenericrgb\c37500\c37500\c37500;\csgenericrgb\c0\c45000\c0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
 
-	openHost { |login, password, serverName|
-		if( ( "/Volumes/" ++ (serverName ? hostName) ).pathMatch.size == 0 )
-			{ (serverName ? hostName).openServer( login, password, hostName ); }
-			{ ("/Volumes/" ++ (serverName ? hostName) ++ "/").openInFinder; } 
-		}
-		
-	sendMsg { arg ... msg;
-		servers.do( _.sendMsg(*msg) );
-	}
-	
-	sendBundle { arg time ... msgs;
-		servers.do( _.sendBundle(time, *msgs) );
-	}
-	
-	listSendMsg { arg msg;
-		servers.do( _.sendMsg(*msg) );
-	}
-	
- 	listSendBundle { arg time, msgs;
-		servers.do( _.sendBundle(time, *msgs) );
-	}
-	
-	makeWindow {
-	
-		//var window;
-		if( window.notNil && { window.dataptr.notNil }) { window.front; ^this };
-		
-		window = SCWindow("MultiServer", Rect(10, 10, 400, 3 + ( servers.size * 29))).front;
-		window.view.decorator = FlowLayout(window.view.bounds);
-		servers.do({ |server| server.makeView( window ); });
-		
-		}
-		
-	add { |server|	
-		servers = servers.add( server );
-		}
-		
-	++ { |aMultiServer|
-		case { aMultiServer.class == Server }
-			{ this.add( aMultiServer )  }
-			{ aMultiServer.class == MultiServer }
-			{ servers = servers ++ aMultiServer.servers };
-		}
-		
-	at { |index| ^servers.wrapAt( index ); }
-		
-	boot { |delay = 0|
-		if( servers[0].addr.ip.asSymbol == '127.0.0.1' ) {
-			if(delay>0){ 
-				Routine({
-					servers.do{ |server| 
-						server.boot;
-						delay.wait;
-					}
-				}).play
-			}{
-				servers.do(_.boot)
-			}
- 		}
-	}
-	
-	quit {
-		if( servers[0].addr.ip.asSymbol == '127.0.0.1' )
-			{ servers.do( _.quit ) };
-		}
-	
-	current { ^servers.wrapAt( pointer ); }
-	next { pointer = (pointer + 1) % servers.size; ^this.current }
-		
-	}
-		
-	
-			
-		
-		
\ No newline at end of file
+\f0\fs20 \cf2 MultiServer\cf3  \{\
+	\cf4 classvar\cf3  <>default;\
+	\
+	\cf4 var\cf3  <>servers, <window, <>pointer = 0, <>hostName, synthDefDir;\
+	\
+	*new \{ \cf4 |names, adresses, options, hostName, synthDefDir, clientID = 0 |\cf3 \
+			\cf5 // options and clientID are the same for every server\cf3 \
+		^\cf6 super\cf3 .new.init( names ? [], adresses ? [], options, clientID, hostName, synthDefDir );\
+		\}\
+		\
+	*row \{ \cf4 |n = 1, startName = "server", startAddr, options, hostName, synthDefDir, clientID = 0|\cf3 \
+		\cf4 var\cf3  names, adresses;\
+		startAddr = startAddr ? \cf2 NetAddr\cf3 ( \cf7 "127.0.0.1"\cf3 , 58000 );\
+		\
+		options = options ? \cf2 Server\cf3 .default.options;\
+		names = \{ \cf4 |i|\cf3  startName ++ (i+1); \} ! n;\
+		adresses = \{ \cf4 |i|\cf3  \cf2 NetAddr\cf3 ( startAddr.hostname, startAddr.port + i ); \} ! n;\
+		\
+		^\cf6 this\cf3 .new( names, adresses, options, hostName, synthDefDir, clientID );\
+		\
+		\}\
+		\
+	*rowFindHost \{ \cf4 |hostName, n = 1, startName = "server", startPort = 58000, options, \
+			synthDefDir, clientID = 0|\cf3 \
+		\cf4 var\cf3  addr;\
+		options = options ? \cf2 Server\cf3 .default.options;\
+		if( hostName.isNil )\
+			\{ addr = \cf2 NetAddr\cf3 ( \cf7 "127.0.0.1"\cf3 , startPort ); \}\
+			\{ addr = \cf2 NetAddr\cf3 ( hostName.findReplaceAll( \cf7 " "\cf3 , \cf7 "-"\cf3  )\
+			.replaceExtension( \cf7 "local"\cf3  ), startPort );  \};\
+		^\cf6 this\cf3 .row( n, startName, addr, options, hostName, synthDefDir, clientID );\
+		\}\
+		\
+	makeDefault \{ default = \cf6 this\cf3  \}\
+		\
+	init \{ \cf4 |argNames, argAddr, argOptions, argClientID, argHostName, argSynthDefDir|\cf3 \
+		\
+		servers = argNames.collect(\{ \cf4 |name, i|\cf3 \
+			\cf2 Server\cf3 ( name, argAddr.wrapAt(i), argOptions, argClientID);\
+			\});\
+		\
+		hostName = argHostName ? \cf7 ""\cf3 ;\
+		synthDefDir = argSynthDefDir ?? \{ \cf2 SynthDef\cf3 .synthDefDir; \};\
+		\
+		\}\
+	\
+	synthDefDir \{ ^\cf7 "/Volumes/"\cf3  ++ hostName ++ \cf7 "/"\cf3  ++ synthDefDir; \}\
+	\
+\
+	openHost \{ \cf4 |login, password, serverName|\cf3 \
+		if( ( \cf7 "/Volumes/"\cf3  ++ (serverName ? hostName) ).pathMatch.size == 0 )\
+			\{ (serverName ? hostName).openServer( login, password, hostName ); \}\
+			\{ (\cf7 "/Volumes/"\cf3  ++ (serverName ? hostName) ++ \cf7 "/"\cf3 ).openInFinder; \} \
+		\}\
+		\
+	sendMsg \{ \cf4 arg\cf3  ... msg;\
+		servers.do( \cf2 _\cf3 .sendMsg(*msg) );\
+	\}\
+	\
+	sendBundle \{ \cf4 arg\cf3  time ... msgs;\
+		servers.do( \cf2 _\cf3 .sendBundle(time, *msgs) );\
+	\}\
+	\
+	listSendMsg \{ \cf4 arg\cf3  msg;\
+		servers.do( \cf2 _\cf3 .sendMsg(*msg) );\
+	\}\
+	\
+ 	listSendBundle \{ \cf4 arg\cf3  time, msgs;\
+		servers.do( \cf2 _\cf3 .sendBundle(time, *msgs) );\
+	\}\
+	\
+	makeWindow \{\
+	\
+		\cf5 //var window;\cf3 \
+		if( window.notNil && \{ window.dataptr.notNil \}) \{ window.front; ^\cf6 this\cf3  \};\
+		\
+		window = \cf2 SCWindow\cf3 (\cf7 "MultiServer"\cf3 , \cf2 Rect\cf3 (10, 10, 400, 3 + ( servers.size * 29))).front;\
+		window.view.decorator = \cf2 FlowLayout\cf3 (window.view.bounds);\
+		servers.do(\{ \cf4 |server|\cf3  server.makeView( window ); \});\
+		\
+		\}\
+		\
+	add \{ \cf4 |server|\cf3 	\
+		servers = servers.add( server );\
+		\}\
+		\
+	++ \{ \cf4 |aMultiServer|\cf3 \
+		case \{ aMultiServer.class == \cf2 Server\cf3  \}\
+			\{ \cf6 this\cf3 .add( aMultiServer )  \}\
+			\{ aMultiServer.class == \cf2 MultiServer\cf3  \}\
+			\{ servers = servers ++ aMultiServer.servers \};\
+		\}\
+		\
+	at \{ \cf4 |index|\cf3  ^servers.wrapAt( index ); \}\
+		\
+	boot \{ \cf4 |delay = 0|\cf3 \
+		if( servers[0].addr.ip.asSymbol == \cf8 '127.0.0.1'\cf3  ) \{\
+			if(delay>0)\{ \
+				\cf2 Routine\cf3 (\{\
+					servers.do\{ \cf4 |server|\cf3  \
+						delay.wait;\
+						server.boot;\
+					\}\
+				\}).play\
+			\}\{\
+				servers.do(\cf2 _\cf3 .boot)\
+			\}\
+ 		\}\
+	\}\
+	\
+	quit \{\
+		if( servers[0].addr.ip.asSymbol == \cf8 '127.0.0.1'\cf3  )\
+			\{ servers.do( \cf2 _\cf3 .quit ) \};\
+		\}\
+	\
+	current \{ ^servers.wrapAt( pointer ); \}\
+	next \{ pointer = (pointer + 1) % servers.size; ^\cf6 this\cf3 .current \}\
+		\
+	\}\
+		\
+	\
+			\
+		\
+		}
\ No newline at end of file

Modified: wslib/wslib-classes/Extensions/String/asStringWithFrac.sc
===================================================================
--- wslib/wslib-classes/Extensions/String/asStringWithFrac.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Extensions/String/asStringWithFrac.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,25 +1,33 @@
-+ Integer {
-	asStringWithFrac { |fracSize = 3|
-		^(this.asString ++ ".".extend( fracSize+1, $0 ));
-		}
-	}
-	
-+ Float {
-	asStringWithFrac { |fracSize = 3|
-		var val;
-		val = this.round( 10 ** (fracSize.neg) );
-		^(val.asInt.asString ++ "." ++ 
-			( val.abs.frac* (10**fracSize) ).round(1).asInt.asStringToBase(10,fracSize));
-		}
-	}
-	
-+ ArrayedCollection {
-	preExtend { |size, item| 
-		var arraySize;
-		case { (arraySize = this.size) > size } {
-			^this[ arraySize - size .. ];
-		} { arraySize < size } {
-			^(item!(size-arraySize)).as(this.class) ++ this;
-		} { ^this };
-	}
-}
\ No newline at end of file
+{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue191;\red0\green0\blue255;
+\red102\green102\blue191;\red96\green96\blue96;}
+{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;\csgenericrgb\c0\c0\c75000;\csgenericrgb\c0\c0\c100000;
+\csgenericrgb\c40000\c40000\c75000;\csgenericrgb\c37500\c37500\c37500;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+
+\f0\fs20 \cf2 + \cf3 Integer\cf2  \{\
+	asStringWithFrac \{ \cf4 |fracSize = 3|\cf2 \
+		^(\cf5 this\cf2 .asString ++ \cf6 "."\cf2 .extend( fracSize+1, $0 ));\
+		\}\
+	\}\
+	\
++ \cf3 Float\cf2  \{\
+	asStringWithFrac \{ \cf4 |fracSize = 3|\cf2 \
+		\cf4 var\cf2  val;\
+		val = \cf5 this\cf2 .round( 10 ** (fracSize.neg) );\
+		^(val.asInteger.asString ++ \cf6 "."\cf2  ++ \
+			( val.abs.frac* (10**fracSize) ).round(1).asInteger.asStringToBase(10,fracSize));\
+		\}\
+	\}\
+	\
++ \cf3 ArrayedCollection\cf2  \{\
+	preExtend \{ \cf4 |size, item|\cf2  \
+		\cf4 var\cf2  arraySize;\
+		case \{ (arraySize = \cf5 this\cf2 .size) > size \} \{\
+			^\cf5 this\cf2 [ arraySize - size .. ];\
+		\} \{ arraySize < size \} \{\
+			^(item!(size-arraySize)).as(\cf5 this\cf2 .class) ++ \cf5 this\cf2 ;\
+		\} \{ ^\cf5 this\cf2  \};\
+	\}\
+\}}
\ No newline at end of file

Modified: wslib/wslib-classes/Extensions/String/extString-boundsM9.sc
===================================================================
--- wslib/wslib-classes/Extensions/String/extString-boundsM9.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Extensions/String/extString-boundsM9.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -30,10 +30,10 @@
 		lines = this.split( $\n );
 		maxSizeH = ( ( rect.width + allowWidth ) / this.class.widthM9 );
 		lines = lines.copyRange(0, 
-			(( ( rect.height + allowHeight) / this.class.heightM9 ).floor.asInt - 1) );
+			(( ( rect.height + allowHeight) / this.class.heightM9 ).floor.asInteger - 1) );
 		lines = lines.collect({ |line|
 			if( line.size > maxSizeH  )
-				{ line = line.copyRange(0, maxSizeH.asInt - (clipSign.size + 1) ) ++ clipSign }
+				{ line = line.copyRange(0, maxSizeH.asInteger - (clipSign.size + 1) ) ++ clipSign }
 				{ line };
 			});
 		^lines.join( $\n )

Modified: wslib/wslib-classes/Extensions/UGens/extArray-Rotation.sc
===================================================================
--- wslib/wslib-classes/Extensions/UGens/extArray-Rotation.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Extensions/UGens/extArray-Rotation.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -16,8 +16,8 @@
 		
 	rotateL { |n = 0|  // linear interpolation
 		^case {n.rate == 'scalar'}
-				{ (this.rotate(n.floor.asInt) * (1-n.frac))
-				+ (this.rotate(((n.floor+1)%this.size).asInt) * n.frac) }
+				{ (this.rotate(n.floor.asInteger) * (1-n.frac))
+				+ (this.rotate(((n.floor+1)%this.size).asInteger) * n.frac) }
 			{this.rate == 'audio'}
 				{ RotateL.ar(n, this) }
 			{this.rate == 'control'}
@@ -33,8 +33,8 @@
 		// sinusoid interpolation
 		// only for scalars for now
 		var sinEnv = Env([0,1],[1],\sine);
-		^(this.rotate(n.floor.asInt) * sinEnv[(1-n.frac)])
-				+ (this.rotate(((n.floor+1)%this.size).asInt) * sinEnv[(n.frac)]) ;
+		^(this.rotate(n.floor.asInteger) * sinEnv[(1-n.frac)])
+				+ (this.rotate(((n.floor+1)%this.size).asInteger) * sinEnv[(n.frac)]) ;
 	}
 	
 }
\ No newline at end of file

Modified: wslib/wslib-classes/Extensions/Various/extBuffer-checkFree.sc
===================================================================
--- wslib/wslib-classes/Extensions/Various/extBuffer-checkFree.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Extensions/Various/extBuffer-checkFree.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,102 +1,80 @@
-+ Buffer {
-		
-	// wslib 2008
-	// free a buffer and check if it is really freed.
-	// Use this remote servers in high traffic situations to prevent new
-	// buffers to be allocated when a "/b_free" message is still on the way
-	
-	checkFree { |action| 
-		
-		if( 1.respondsTo( \factorial ) ) // *very* dirty check to see if this is > rev8139
-			{ 
-			// post rev8193 : less traffic
-			OSCpathResponder( server.addr, [ '/done', '/b_free', bufnum ], { |time,resp,msg|
-				this.uncache;
-				server.bufferAllocator.free(bufnum);
-				action.value( this );
-				resp.remove;
-			 	}).add;
-			
-			server.addr.sendMsg( "/b_free", bufnum );
-			}
-			
-			{ 
-			// pre rev8193
-			OSCpathResponder( server.addr, [ '/b_info', bufnum, 0 ], { |time,resp,msg|
-				this.uncache;
-				server.bufferAllocator.free(bufnum);
-				action.value( this );
-				resp.remove;
-			 	}).add;
-			
-			server.addr.sendMsg( "/b_free", bufnum, ["/b_query", bufnum] );
-			};
-		
-		}
-		
-	*checkFreeMulti { |buffers, action| 
-		
-		if( 1.respondsTo( \factorial ) ) // *very* dirty check to see if this is > rev8139
-			{ 
-			// post rev8193 : less traffic
-			
-				OSCpathResponder( buffers[0].server.addr, [ '/done', '/b_free' ], { 
-					|time,resp,msg|
-						var buf = buffers[msg[2]];
-						buf.uncache;
-						buf.server.bufferAllocator.free(buf.bufnum);
-						action.value( buf );
-						//resp.remove;
-				 	}).add;
-	
-			
-			buffers[0].server.addr.sendBundle( nil,
-				*buffers.collect({ |buf| ["/b_free", buf.bufnum] }) 
-				);
-			};
-			/*
-			{ 
-			// pre rev8193
-			OSCpathResponder( server.addr, [ '/b_info', bufnum, 0 ], { |time,resp,msg|
-				this.uncache;
-				server.bufferAllocator.free(bufnum);
-				action.value( this );
-				resp.remove;
-			 	}).add;
-			
-			server.addr.sendMsg( "/b_free", bufnum, ["/b_query", bufnum] );
-			};
-			*/
-		
-		}
-		
-		
-	checkCloseFree { |action|
-		if( 1.respondsTo( \factorial ) ) // *very* dirty check to see if this is > rev8139
-			{ 
-			// post rev8193 : less traffic
-			OSCpathResponder( server.addr, [ '/done', '/b_free', bufnum ], { |time,resp,msg|
-				this.uncache;
-				server.bufferAllocator.free(bufnum);
-				action.value( this );
-				resp.remove;
-			 	}).add;
-		
-			server.addr.sendMsg( "b_close", bufnum, ["/b_free", bufnum ] );
-			}
-			
-			{ 
-			// pre rev8193
-			OSCpathResponder( server.addr, [ '/b_info', bufnum, 0 ], { |time,resp,msg|
-				this.uncache;
-				server.bufferAllocator.free(bufnum);
-				action.value( this );
-				resp.remove;
-			 	}).add;
-			
-			server.addr.sendMsg( "b_close", bufnum, 
-				["/b_free", bufnum, ["/b_query", bufnum] ] );
-			};
-		
-		}
-	}
\ No newline at end of file
+{\rtf1\ansi\ansicpg1252\cocoartf1561\cocoasubrtf600
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue191;\red191\green0\blue0;
+\red0\green0\blue255;\red102\green102\blue191;\red0\green115\blue0;\red51\green51\blue191;\red96\green96\blue96;
+}
+{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;\csgenericrgb\c0\c0\c75000;\csgenericrgb\c75000\c0\c0;
+\csgenericrgb\c0\c0\c100000;\csgenericrgb\c40000\c40000\c75000;\csgenericrgb\c0\c45000\c0;\csgenericrgb\c20000\c20000\c75000;\csgenericrgb\c37500\c37500\c37500;
+}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+
+\f0\fs20 \cf2 + \cf3 Buffer\cf2  \{\
+		\
+	\cf4 // wslib 2008 / 2018\cf2 \
+	\cf4 // free a buffer and check if it is really freed.\cf2 \
+	\cf4 // Use this remote servers in high traffic situations to prevent new\cf2 \
+	\cf4 // buffers to be allocated when a "/b_free" message is still on the way\cf2 \
+	\
+	checkFree \{ \cf5 |action|\cf2  \
+		\
+		\cf3 OSCFunc\cf2 (\{  \cf5 |msg, time, addr, recvPort|\cf2 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+\cf2 				\cf6 this\cf2 .freeMsg; \cf4 // cleans up internally\cf2 \
+				action.value( \cf6 this\cf2  );\
+		\},  \cf7 '/done'\cf2 , server.addr, \cf8 nil\cf2 , [\cf7 '/b_free'\cf2 , bufnum ] ).oneShot;\
+		\
+		server.addr.sendMsg( \cf9 "/b_free"\cf2 , bufnum );\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+\cf2 	\}\
+	\
+	checkCloseFree \{ \cf5 |action|\cf2 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+\cf2 		\
+		\cf3 OSCFunc\cf2 (\{  \cf5 |msg, time, addr, recvPort|\cf2 \
+				\cf6 this\cf2 .freeMsg; \cf4 // cleans up internally\cf2 \
+				action.value( \cf6 this\cf2  );\
+		\},  \cf7 '/done'\cf2 , server.addr, \cf8 nil\cf2 , [\cf7 '/b_free'\cf2 , bufnum ] ).oneShot;\
+		\
+		server.addr.sendMsg( \cf9 "b_close"\cf2 , bufnum, [\cf9 "/b_free"\cf2 , bufnum ] );\
+	\}\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+\cf2 		\
+	\cf4 /* // this method has flaws, I don't think it is used anywhere anyway.\
+	\
+	*checkFreeMulti \{ |buffers, action| \
+		\
+		if( 1.respondsTo( \\factorial ) ) // *very* dirty check to see if this is > rev8139\
+			\{ \
+			// post rev8193 : less traffic\
+			\
+				OSCpathResponder( buffers[0].server.addr, [ '/done', '/b_free' ], \{ \
+					|time,resp,msg|\
+						var buf = buffers[msg[2]];\
+						buf.uncache;\
+						buf.server.bufferAllocator.free(buf.bufnum);\
+						action.value( buf );\
+						//resp.remove;\
+				 	\}).add;\
+	\
+			\
+			buffers[0].server.addr.sendBundle( nil,\
+				*buffers.collect(\{ |buf| ["/b_free", buf.bufnum] \}) \
+				);\
+			\};\
+			/*\
+			\{ \
+			// pre rev8193\
+			OSCpathResponder( server.addr, [ '/b_info', bufnum, 0 ], \{ |time,resp,msg|\
+				this.uncache;\
+				server.bufferAllocator.free(bufnum);\
+				action.value( this );\
+				resp.remove;\
+			 	\}).add;\
+			\
+			server.addr.sendMsg( "/b_free", bufnum, ["/b_query", bufnum] );\
+			\};\
+			*/\
+		\
+		\}\
+		*/\cf2 \
+\}}
\ No newline at end of file

Modified: wslib/wslib-classes/Extensions/Various/extPoint-variousOps.sc
===================================================================
--- wslib/wslib-classes/Extensions/Various/extPoint-variousOps.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Extensions/Various/extPoint-variousOps.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -52,7 +52,7 @@
 	
 	// conversion to float/int
 	asFloat { ^x.asFloat }
-	asInt { ^x.asInt }
+	asInteger { ^x.asInteger }
 	
 	// unary ops
 	neg { ^this.performOnEach( thisMethod.name ) }

Modified: wslib/wslib-classes/GUI/Extensions/extColor-web.sc
===================================================================
--- wslib/wslib-classes/GUI/Extensions/extColor-web.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/Extensions/extColor-web.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -19,9 +19,9 @@
 		}
 		
 	hex { ^(
-		(red * 255).asInt.asHexString(2) ++ 
-		(green * 255).asInt.asHexString(2) ++ 
-		(blue  * 255).asInt.asHexString(2)); }
+		(red * 255).asInteger.asHexString(2) ++ 
+		(green * 255).asInteger.asHexString(2) ++ 
+		(blue  * 255).asInteger.asHexString(2)); }
 	
 	webHex { ^"#" ++ this.hex; }
 	
@@ -35,9 +35,9 @@
 		}
 		
 	hexValue { ^("16x" ++ (
-		(red * 255).asInt.asHexString(2) ++ 
-		(green * 255).asInt.asHexString(2) ++ 
-		(blue  * 255).asInt.asHexString(2))).interpret; }
+		(red * 255).asInteger.asHexString(2) ++ 
+		(green * 255).asInteger.asHexString(2) ++ 
+		(blue  * 255).asInteger.asHexString(2))).interpret; }
 	
 	*newName { arg name, table, includeXWindows = false;
 		// test all possible inputs..

Modified: wslib/wslib-classes/GUI/Full windows/ServerRecordWindow.sc
===================================================================
--- wslib/wslib-classes/GUI/Full windows/ServerRecordWindow.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/Full windows/ServerRecordWindow.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -56,7 +56,7 @@
 		StaticText( w, 60@20 ).string_( "#channels" ).align_( \right );
 		nCha = NumberBox( w, 40@20 ).value_( server.recChannels )
 			.clipLo_( 1 )
-			.action_({ |v| server.recChannels = v.value.asInt });
+			.action_({ |v| server.recChannels = v.value.asInteger });
 			
 		//w.view.decorator.nextLine;
 		StaticText( w, 60@20 ).string_( "format" ).align_( \right );
@@ -132,7 +132,7 @@
 							 
 						server.recSampleFormat = sFormat.items[ sFormat.value ].asString;
 						server.recHeaderFormat = hFormat.items[ hFormat.value ].asString; 
-						server.recChannels = nCha.value.asInt;
+						server.recChannels = nCha.value.asInteger;
 						server.prepareForRecord( inFileName );
 						controls[ \prepare ].enabled_( false );
 						controls[ \record ].value = 1;

Modified: wslib/wslib-classes/GUI/MIDI/MIDISliderWindow.sc
===================================================================
--- wslib/wslib-classes/GUI/MIDI/MIDISliderWindow.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/MIDI/MIDISliderWindow.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -644,7 +644,7 @@
 var busMessage = { |chan, val| Server.default.sendMsg("/c_set", chan + busOffset, val) };
 var routine, routineButton;
 var values;
-if(channels.size == 0) { channels = (_.asInt)!channels };
+if(channels.size == 0) { channels = (_.asInteger)!channels };
 values = channels.collect({0.0});
 MIDIWindow.new;
 

Modified: wslib/wslib-classes/GUI/ModKey.sc
===================================================================
--- wslib/wslib-classes/GUI/ModKey.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/ModKey.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -44,7 +44,7 @@
 			.collect({ |item| numberDict.findKeyForValue( item ) })
 			.select( _.notNil ) ++ extra;
 		string = String.fill(24, { |i| if( indices.includes( i ) ) { $1 } { $0 } } );
-		^( "2r" ++ string ).interpret.asInt;
+		^( "2r" ++ string ).interpret.asInteger;
 		}
 	
 	init { |args|

Modified: wslib/wslib-classes/GUI/ScaledUserView/ScaledUserViewWindow.sc
===================================================================
--- wslib/wslib-classes/GUI/ScaledUserView/ScaledUserViewWindow.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/ScaledUserView/ScaledUserViewWindow.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,543 +1,551 @@
-// wslib 2006
-// scaled SCUserView
+{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf830
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;\red191\green0\blue0;\red0\green0\blue0;\red0\green0\blue191;
+\red0\green0\blue255;\red51\green51\blue191;\red102\green102\blue191;\red96\green96\blue96;}
+{\*\expandedcolortbl;;\csgenericrgb\c75000\c0\c0;\csgenericrgb\c0\c0\c0;\csgenericrgb\c0\c0\c75000;
+\csgenericrgb\c0\c0\c100000;\csgenericrgb\c20000\c20000\c75000;\csgenericrgb\c40000\c40000\c75000;\csgenericrgb\c37500\c37500\c37500;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
 
-// wslib 2009
-// scaled SCUserViewContainer
-// replacement for ScaledUserViewWindow
-// can both be a separate window and a compositeview in an existing window
-
-ScaledUserViewContainer {
-	
-	classvar <>defaultBounds, <>defaultFromBounds;
-	
-	var <composite, <userView, <scaleSliders, <moveSliders;
-	var <viewOffset;
-	var <>maxZoom = 8, <>minZoom = 1;
-	var <>zoomCurve = 0;
-	var resize = 1;
-	var window;
-	var currentBounds;
-	var <sliderKnobColor, <sliderBackColor;
-
-	var <sliderWidth = 12, <sliderSpacing = 2, <scaleSliderLength = 52; // defaults
-	
-	// these defaults should not be changed until after creation
-	var <scaleHEnabled = true, <scaleVEnabled = true;
-	var <moveHEnabled = true, <moveVEnabled = true;
-	
-	*initClass { 
-		defaultBounds = Rect( 0, 0, 400, 400 );
-		defaultFromBounds = Rect(0,0,1,1); // different from ScaledUserView
-		}
-		
-	doesNotUnderstand { arg selector ... args;
-		var res;
-		res = userView.perform(selector, *args);
-		if (res.class == ScaledUserView )
-			{ ^this }
-			{ ^res }
-		}
-	
-	*new { |parent, bounds, fromBounds, viewOffset|
-		var resize;
-		
-		viewOffset = viewOffset ? [1,1];
-		case { viewOffset.class == Point }
-			{ viewOffset = [ viewOffset.x, viewOffset.y ]; }
-			{ viewOffset.size == 0 }
-			{ viewOffset = [ viewOffset, viewOffset ]; }
-			{ viewOffset.size == 1 }
-			{ viewOffset = viewOffset ++ viewOffset; };
-		
-		if( parent.isNil or: {parent.isString} )
-		 	{ 
-			parent = Window(parent ? "ScaledUserView", bounds).front;
-			resize = 5;
-			bounds = (bounds ? defaultBounds).asRect;
-			bounds !? { bounds = bounds
-					.moveTo(*viewOffset)
-					.resizeBy(*viewOffset.neg)
-					.resizeBy(-2,-2) };
-			};
-			
-		bounds = (bounds ? defaultBounds).asRect;
-		fromBounds = (fromBounds ? defaultFromBounds).asRect;
-		^super.new.init( parent, bounds, fromBounds, resize);
-		}
-		
-	front { composite.front }
-	
-	init { | inParent, inBounds, inFromBounds, inResize|
-		resize = inResize ? resize;
-		
-		sliderKnobColor = sliderKnobColor ?? { Color.gray(0.2); };
-		sliderBackColor = sliderBackColor ?? { Color.black.alpha_(0.33); };
-		composite = CompositeView( inParent, inBounds );
-		composite.resize_( resize );
-		// composite.background = Color.gray(0.8);
-		// composite.onClose = { onClose.value( this, composite ) };
-		
-		userView = ScaledUserView( composite, Rect(0,0, 
-			composite.bounds.width - (sliderWidth + sliderSpacing),
-			composite.bounds.height - (sliderWidth + sliderSpacing)), inFromBounds );
-			
-		userView.view.resize_(5);
-		userView.view.focusColor = Color.clear;
-		userView.background = Color.white.alpha_(0.5);
-		
-		scaleSliders = [ 
-			SmoothSlider( composite, Rect( 
-					composite.bounds.width - 
-						(scaleSliderLength + sliderWidth + sliderSpacing),  
-		 			composite.bounds.height - sliderWidth, 
-		 			scaleSliderLength, sliderWidth )  )
-				.value_(0).action_({ |v| 
-					userView.scaleH = 
-						v.value.lincurve(0,1,minZoom.asPoint.x, maxZoom.asPoint.x, zoomCurve);
-						//1 + (v.value * maxZoom.asPoint.x);
-					this.setMoveSliderWidths( composite.bounds );
-					})
-				.knobColor_( sliderKnobColor )
-		 		.hilightColor_( nil )
-		 		.background_(sliderBackColor)
-		 		.knobSize_( 1 )
-		 		.canFocus_( false )
-				.resize_(9),
-			SmoothSlider( composite,  Rect( 
-		 			composite.bounds.width - sliderWidth,  
-		 			composite.bounds.height - 
-		 				(scaleSliderLength + sliderWidth + sliderSpacing), 
-		 				sliderWidth, scaleSliderLength ) )
-				.value_(1).action_({ |v| 
-					userView.scaleV = 
-						(1-v.value).lincurve(0,1,minZoom.asPoint.y, maxZoom.asPoint.y, zoomCurve);
-						//1 + ((1 - v.value) * maxZoom.asPoint.y);
-					this.setMoveSliderWidths( composite.bounds );
-					})
-				.knobColor_( sliderKnobColor )
-				.hilightColor_( nil )
-				.background_(sliderBackColor)
-				.knobSize_( 1 )
-		 		.canFocus_( false )
-				.resize_(9) ];
-		 
-		moveSliders = [ 
-			SmoothSlider( composite,  Rect( 0, 
-					composite.bounds.height - sliderWidth, 
-					composite.bounds.width - 
-						(scaleSliderLength + sliderWidth + (2 * sliderSpacing)), 
-					sliderWidth ) )
-				 .value_(0.5).action_({ |v| userView.moveH = v.value; })
-				 .knobColor_( sliderKnobColor)
-				 .hilightColor_( nil )
-				 .background_(sliderBackColor)
-				 .resize_(8)
-		 		.canFocus_( false ),
-			SmoothSlider( composite,  Rect( 
-					composite.bounds.width - sliderWidth,  
-					0, sliderWidth, 
-					(composite.bounds.height - 
-						(scaleSliderLength + sliderWidth + (2 * sliderSpacing))) ) )
-				 .value_(0.5).action_({ |v| userView.moveV = 1 - (v.value); })
-				 .knobColor_( sliderKnobColor )
-				 .hilightColor_( nil )
-				 .background_(sliderBackColor)
-				 .resize_(6)
-		 		.canFocus_( false ) ];
-		
-		this.setMoveSliderWidths;
-		
-		currentBounds = userView.bounds;
-		
-		userView.refreshAction = { |vw|
-			if( currentBounds != vw.bounds )
-				{ this.setMoveSliderWidths; currentBounds = vw.bounds; }
-			};
-		}
-		
-	updateSliders { |scaleFlag = true, moveFlag = true|
-		if( scaleFlag )
-			{ scaleSliders[0].value = 
-				userView.scaleH.curvelin(minZoom.asPoint.x, maxZoom.asPoint.x, 0, 1, zoomCurve );
-				//(userView.scaleH - 1) / maxZoom.asPoint.x;
-			scaleSliders[1].value = 1 - 
-				userView.scaleV.linlin(minZoom.asPoint.y, maxZoom.asPoint.y, 0, 1, zoomCurve );
-				//((userView.scaleV - 1) / maxZoom.asPoint.y );
-			this.setMoveSliderWidths;
-			};
-		if( moveFlag )
-			{
-			moveSliders[0].value = userView.moveH;
-			moveSliders[1].value = 1 - userView.moveV;
-			};
-		}
-		
-	updateSliderBounds {
-	
-		var hasH, hasV;
-		var scaleVReallyEnabled;
-		
-		scaleVReallyEnabled = scaleVEnabled and: (userView.keepRatio.not);
-		
-		// show/hide sliders
-		[scaleHEnabled, scaleVReallyEnabled, moveHEnabled, moveVEnabled].do({ |enabled, i|
-			[ scaleSliders[0], scaleSliders[1], moveSliders[0], moveSliders[1] ][i]
-				.visible = enabled;
-			});
-					
-		hasH =  (moveHEnabled or: scaleHEnabled).binaryValue;
-		hasV =  (moveVEnabled or: scaleVReallyEnabled).binaryValue;
-		
-		#hasH, hasV = [ hasH, hasV ] * (sliderWidth + sliderSpacing);
-				
-		// set bounds		
-		if( moveHEnabled )
-			{ moveSliders[0].bounds = Rect( 
-				0, 
-				composite.bounds.height - sliderWidth, 
-				composite.bounds.width - ( hasV +
-					((scaleSliderLength + sliderSpacing) * scaleHEnabled.binaryValue )
-					), 
-				sliderWidth );
-			};
-				
-		if( moveVEnabled )
-			{ moveSliders[1].bounds = Rect( 
-				composite.bounds.width - sliderWidth,  
-				0, 
-				sliderWidth, 
-				composite.bounds.height - (hasH +
-					((scaleSliderLength + sliderSpacing) * scaleVReallyEnabled.binaryValue ) 
-					)
-					
-				);
-			};
-			
-		if( scaleHEnabled )
-			{ scaleSliders[0].bounds = Rect(
-				composite.bounds.width - (scaleSliderLength + hasV),  
-		 		composite.bounds.height - sliderWidth, 
-		 		scaleSliderLength, 
-		 		sliderWidth );
-			};
-			
-		if( scaleVReallyEnabled )
-			{ scaleSliders[1].bounds = Rect( 
-				composite.bounds.width - sliderWidth,  
-	 			composite.bounds.height - (scaleSliderLength + hasH), 
-	 			sliderWidth, 
-	 			scaleSliderLength );
-			};
-			
-		userView.bounds = Rect(0,0, 
-			composite.bounds.width - hasV,
-			composite.bounds.height - hasH
-			);
-		}
-		
-	bounds { ^composite.bounds }
-	bounds_ { |newBounds| composite.bounds = newBounds; }
-		
-	scaleHEnabled_ { |bool| scaleHEnabled = bool; this.updateSliderBounds; }
-	scaleVEnabled_ { |bool| scaleVEnabled = bool; this.updateSliderBounds; }
-	
-	moveHEnabled_ { |bool| moveHEnabled = bool; this.updateSliderBounds; }
-	moveVEnabled_ { |bool| moveVEnabled = bool; this.updateSliderBounds; }
-	
-	sliderWidth_ { |width = 12| sliderWidth = width; this.updateSliderBounds; }
-	sliderSpacing_ { |spacing = 2| sliderSpacing = spacing; this.updateSliderBounds; }
-	scaleSliderLength_ { |length = 52| scaleSliderLength = length;  this.updateSliderBounds; }
-		
-	sliderKnobColor_ { |color|
-		(scaleSliders ++ moveSliders).do(_.knobColor_(color));
-		}
-		
-	sliderBackColor_ { |color|
-		(scaleSliders ++ moveSliders).do(_.background_(color));
-		}
-		
-	setMoveSliderWidths { // |rect| // not used anymore
-		moveSliders[0].relThumbSize = (1 / userView.scaleH).min( userView.scaleH );
-		moveSliders[1].relThumbSize = (1 / userView.scaleV).min( userView.scaleV );
-			}
-
-
-	scaleH_ { |newScaleH, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.scaleH_( newScaleH, refreshFlag );
-		this.updateSliders( updateFlag, false );
-		 }
-		 
-	scaleV_ { |newScaleV, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.scaleV_( newScaleV, refreshFlag );
-		this.updateSliders( updateFlag, false );
-		 }
-		 
-	scale_ { |newScaleArray, refreshFlag, updateFlag| // can be single value, array or point
-		updateFlag = updateFlag ? true;
-		userView.scale_( newScaleArray, refreshFlag );
-		this.updateSliders( updateFlag, false );
-		}
-		
-		
-	moveH_ { |newMoveH, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.moveH_( newMoveH, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		 }
-		 
-	moveV_ { |newMoveV, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.moveV_( newMoveV, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		 }
-		 
-	move_ { |newMoveArray, refreshFlag, updateFlag| // can be single value, array or point
-		updateFlag = updateFlag ? true;
-		userView.move_( newMoveArray, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		}
-		
-	movePixels_ {  |newPixelsArray, limit, refreshFlag, updateFlag| 
-		updateFlag = updateFlag ? true;
-		userView.movePixels_( newPixelsArray, limit, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		}
-		
-	viewRect_ { |rect, refreshFlag, updateFlag| // can be single value, array or point
-		updateFlag = updateFlag ? true;
-		userView.viewRect_( rect, refreshFlag );
-		this.updateSliders( updateFlag, updateFlag );
-		}
-	
-		
-	keepRatio_ { |bool = false|
-		userView.keepRatio = bool;
-		this.updateSliderBounds;
-		/*
-		scaleSliders[1].visible = bool.not;
-		
-		moveSliders[1].bounds = moveSliders[1].bounds
-			.height_( composite.bounds.height -
-				[ scaleSliderLength + sliderWidth + (2 * sliderSpacing),
-				  sliderWidth + sliderSpacing][ bool.binaryValue ] );
-		*/
-		this.scaleH = this.scaleH; 
-		 }
-		
-	refresh { //this.setMoveSliderWidths;
-		 ^composite.refresh }
-		 
-	resize { ^resize }
-	resize_ { |val| resize = val; composite.resize_( val ) }
-	
-	window { ^window ?? { window = composite.getParents.last.findWindow; } }
-	
-	drawHook { ^this.window.drawHook }
-	drawHook_ { |func| this.window.drawHook = func; }
-	
-	onClose { ^this.window.onClose }
-	onClose_ { |func| this.window.onClose = func; }
-	
-	remove { composite.remove; }
-		
-	} 
-	
-//// Soon to be replaced by above
-
-ScaledUserViewWindow {
-	
-	classvar <>defaultBounds, <>defaultFromBounds;
-	
-	var <window, <userView, <scaleSliders, <moveSliders, <>drawHook; 
-	var <viewOffset;
-	var <>maxZoom = 8;
-	var <>onClose;
-	
-	*initClass { 
-		defaultBounds = Rect( 350, 128, 400, 400 );
-		defaultFromBounds = Rect(0,0,1,1); // different from ScaledUserView
-		}
-		
-	doesNotUnderstand { arg selector ... args;
-		var res;
-		res = userView.perform(selector, *args);
-		if (res.class == ScaledUserView )
-			{ ^this }
-			{ ^res }
-		}
-		
-	*new { |name, bounds, fromBounds, viewOffset|
-		name = name ? "ScaledUserViewWindow";
-		bounds = (bounds ? defaultBounds).asRect;
-		fromBounds = (fromBounds ? defaultFromBounds).asRect;
-		viewOffset = viewOffset ? [1,1];
-		^super.new.init( name, bounds, fromBounds, viewOffset);
-		}
-		
-	front { window.front }
-	
-	init { | inName, inBounds, inFromBounds, inViewOffset|
-		var sliderKnobColor, sliderBackColor;
-		sliderKnobColor = Color.gray(0.2);
-		sliderBackColor = Color.black.alpha_(0.33);
-		window = Window( inName, inBounds );
-		//window.view.background = Color.gray(0.8);
-		case { inViewOffset.class == Point }
-			{ viewOffset = [ inViewOffset.x, inViewOffset.y ]; }
-			{ inViewOffset.size == 0 }
-			{ viewOffset = [ inViewOffset, inViewOffset ]; }
-			{ inViewOffset.size == 1 }
-			{ viewOffset = inViewOffset ++ inViewOffset; }
-			{ true }
-			{ viewOffset = inViewOffset; };
-		
-		window.onClose = { onClose.value( this, window ) };
-			
-		userView = ScaledUserView( window, (window.asView.bounds + 
-			Rect(0,0,-19,-19)).insetAll( *(viewOffset ++ [0,0]) ), inFromBounds );
-			
-		userView.view.resize_(5);
-		userView.background = Color.white.alpha_(0.5);
-		
-		scaleSliders = [ 
-			SmoothSlider( window,  Rect( 
-		 			window.asView.bounds.width - 75,  
-		 			window.asView.bounds.height - 16, 48, 13 )  )
-				.value_(0).action_({ |v| 
-					userView.scaleH = 1 + (v.value * maxZoom.asPoint.x);
-					this.setMoveSliderWidths( window.asView.bounds );
-					/*
-					if( userView.keepRatio )
-						{ scaleSliders[1].valueAction = (1 - v.value); };
-					*/
-					})
-				.knobColor_( sliderKnobColor )
-		 		.hilightColor_( nil )
-		 		.background_(sliderBackColor)
-		 		.knobSize_( 1 )
-		 		.canFocus_( false )
-				.resize_(9),
-			SmoothSlider( window,  Rect( 
-		 			window.asView.bounds.width - 16,  
-		 			window.asView.bounds.height - 75, 13, 48 ) )
-				.value_(1).action_({ |v| 
-					userView.scaleV = 1 + ((1 - v.value) * maxZoom.asPoint.y);
-					this.setMoveSliderWidths( window.asView.bounds );
-					/*
-					if( userView.keepRatio )
-						{ scaleSliders[0].valueAction = (1 - v.value); };
-					*/
-					})
-				.knobColor_( sliderKnobColor )
-				.hilightColor_( nil )
-				.background_(sliderBackColor)
-				.knobSize_( 1 )
-		 		.canFocus_( false )
-				.resize_(9) ];
-		 
-		moveSliders = [ 
-			SmoothSlider( window,  Rect( viewOffset[0],  
-				 	window.asView.bounds.height - 16, 
-				 	(window.asView.bounds.width - 78) - viewOffset[0], 13 )  )
-				 .value_(0.5).action_({ |v| userView.moveH = v.value; })
-				 .knobColor_( sliderKnobColor)
-				 .hilightColor_( nil )
-				 .background_(sliderBackColor)
-				 .resize_(8)
-		 		.canFocus_( false ),
-			SmoothSlider( window,  Rect( 
-					window.asView.bounds.width - 16,  viewOffset[1], 13, 
-					(window.asView.bounds.height - 78) - viewOffset[1] )  )
-				 .value_(0.5).action_({ |v| userView.moveV = 1 - (v.value); })
-				 .knobColor_( sliderKnobColor )
-				 .hilightColor_( nil )
-				 .background_(sliderBackColor)
-				 .resize_(6)
-		 		.canFocus_( false ) ];
-		
-		this.setMoveSliderWidths;
-		
-		
-		
-		
-		window.drawHook = { |w|
-			this.setMoveSliderWidths;
-			drawHook.value( window );
-			};
-			
-		window.front;
-		}
-		
-	updateSliders { |scaleFlag = true, moveFlag = true|
-		if( scaleFlag )
-			{ scaleSliders[0].value = (userView.scaleH - 1) / maxZoom.asPoint.x;
-			scaleSliders[1].value = 1 - ((userView.scaleV - 1) / maxZoom.asPoint.y );
-			this.setMoveSliderWidths;
-			};
-		if( moveFlag )
-			{
-			moveSliders[0].value = userView.moveH;
-			moveSliders[1].value = 1 - userView.moveV;
-			};
-		}
-		
-	setMoveSliderWidths { // |rect| // not used anymore
-		moveSliders[0].relThumbSize = (1 / userView.scaleH).min(1);
-		moveSliders[1].relThumbSize = (1 / userView.scaleV).min(1);
-			}
-
-
-	scaleH_ { |newScaleH, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.scaleH_( newScaleH, refreshFlag );
-		this.updateSliders( updateFlag, false );
-		 }
-		 
-	scaleV_ { |newScaleV, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.scaleV_( newScaleV, refreshFlag );
-		this.updateSliders( updateFlag, false );
-		 }
-		 
-	scale_ { |newScaleArray, refreshFlag, updateFlag| // can be single value, array or point
-		updateFlag = updateFlag ? true;
-		userView.scale_( newScaleArray, refreshFlag );
-		this.updateSliders( updateFlag, false );
-		}
-		
-		
-	moveH_ { |newMoveH, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.moveH_( newMoveH, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		 }
-		 
-	moveV_ { |newMoveV, refreshFlag, updateFlag|
-		updateFlag = updateFlag ? true;
-		userView.moveV_( newMoveV, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		 }
-		 
-	move_ { |newMoveArray, refreshFlag, updateFlag| // can be single value, array or point
-		updateFlag = updateFlag ? true;
-		userView.move_( newMoveArray, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		}
-		
-	movePixels_ {  |newPixelsArray, limit, refreshFlag, updateFlag| 
-		updateFlag = updateFlag ? true;
-		userView.movePixels_( newPixelsArray, limit, refreshFlag );
-		this.updateSliders( false, updateFlag );
-		}
-		
-	keepRatio_ { |bool = false|
-		userView.keepRatio = bool;
-		scaleSliders[1].visible = bool.not;
-		this.scaleH = this.scaleH; 
-		 }
-		
-	refresh { ^window.refresh }
-		
-	} 
\ No newline at end of file
+\f0\fs20 \cf2 // wslib 2006\cf3 \
+\cf2 // scaled SCUserView\cf3 \
+\
+\cf2 // wslib 2009\cf3 \
+\cf2 // scaled SCUserViewContainer\cf3 \
+\cf2 // replacement for ScaledUserViewWindow\cf3 \
+\cf2 // can both be a separate window and a compositeview in an existing window\cf3 \
+\
+\cf4 ScaledUserViewContainer\cf3  \{\
+	\
+	\cf5 classvar\cf3  <>defaultBounds, <>defaultFromBounds;\
+	\
+	\cf5 var\cf3  <composite, <userView, <scaleSliders, <moveSliders;\
+	\cf5 var\cf3  <viewOffset;\
+	\cf5 var\cf3  <>maxZoom = 8, <>minZoom = 1;\
+	\cf5 var\cf3  <>zoomCurve = 0;\
+	\cf5 var\cf3  resize = 1;\
+	\cf5 var\cf3  window;\
+	\cf5 var\cf3  currentBounds;\
+	\cf5 var\cf3  <sliderKnobColor, <sliderBackColor;\
+\
+	\cf5 var\cf3  <sliderWidth = 12, <sliderSpacing = 2, <scaleSliderLength = 52; \cf2 // defaults\cf3 \
+	\
+	\cf2 // these defaults should not be changed until after creation\cf3 \
+	\cf5 var\cf3  <scaleHEnabled = \cf6 true\cf3 , <scaleVEnabled = \cf6 true\cf3 ;\
+	\cf5 var\cf3  <moveHEnabled = \cf6 true\cf3 , <moveVEnabled = \cf6 true\cf3 ;\
+	\
+	*initClass \{ \
+		defaultBounds = \cf4 Rect\cf3 ( 0, 0, 400, 400 );\
+		defaultFromBounds = \cf4 Rect\cf3 (0,0,1,1); \cf2 // different from ScaledUserView\cf3 \
+		\}\
+		\
+	doesNotUnderstand \{ \cf5 arg\cf3  selector ... args;\
+		\cf5 var\cf3  res;\
+		res = userView.perform(selector, *args);\
+		if (res.class == \cf4 ScaledUserView\cf3  )\
+			\{ ^\cf7 this\cf3  \}\
+			\{ ^res \}\
+		\}\
+	\
+	*new \{ \cf5 |parent, bounds, fromBounds, viewOffset|\cf3 \
+		\cf5 var\cf3  resize;\
+		\
+		viewOffset = viewOffset ? [1,1];\
+		case \{ viewOffset.class == \cf4 Point\cf3  \}\
+			\{ viewOffset = [ viewOffset.x, viewOffset.y ]; \}\
+			\{ viewOffset.size == 0 \}\
+			\{ viewOffset = [ viewOffset, viewOffset ]; \}\
+			\{ viewOffset.size == 1 \}\
+			\{ viewOffset = viewOffset ++ viewOffset; \};\
+		\
+		if( parent.isNil or: \{parent.isString\} )\
+		 	\{ \
+			parent = \cf4 Window\cf3 (parent ? \cf8 "ScaledUserView"\cf3 , bounds).front;\
+			resize = 5;\
+			bounds = (bounds ? defaultBounds).asRect;\
+			bounds !? \{ bounds = bounds\
+					.moveTo(*viewOffset)\
+					.resizeBy(*viewOffset.neg)\
+					.resizeBy(-2,-2) \};\
+			\};\
+			\
+		bounds = (bounds ? defaultBounds).asRect;\
+		fromBounds = (fromBounds ? defaultFromBounds).asRect;\
+		^\cf7 super\cf3 .new.init( parent, bounds, fromBounds, resize);\
+		\}\
+		\
+	front \{ composite.front \}\
+	\
+	init \{ \cf5 | inParent, inBounds, inFromBounds, inResize|\cf3 \
+		resize = inResize ? resize;\
+		\
+		sliderKnobColor = sliderKnobColor ?? \{ \cf4 Color\cf3 .gray(0.2); \};\
+		sliderBackColor = sliderBackColor ?? \{ \cf4 Color\cf3 .black.alpha_(0.33); \};\
+		composite = \cf4 CompositeView\cf3 ( inParent, inBounds );\
+		composite.resize_( resize );\
+		\cf2 // composite.background = Color.gray(0.8);\cf3 \
+		\cf2 // composite.onClose = \{ onClose.value( this, composite ) \};\cf3 \
+		\
+		userView = \cf4 ScaledUserView\cf3 ( composite, \cf4 Rect\cf3 (0,0, \
+			composite.bounds.width - (sliderWidth + sliderSpacing),\
+			composite.bounds.height - (sliderWidth + sliderSpacing)), inFromBounds );\
+			\
+		userView.view.resize_(5);\
+		userView.view.focusColor = \cf4 Color\cf3 .clear;\
+		userView.background = \cf4 Color\cf3 .white.alpha_(0.5);\
+		\
+		scaleSliders = [ \
+			\cf4 SmoothSlider\cf3 ( composite, \cf4 Rect\cf3 ( \
+					composite.bounds.width - \
+						(scaleSliderLength + sliderWidth + sliderSpacing),  \
+		 			composite.bounds.height - sliderWidth, \
+		 			scaleSliderLength, sliderWidth )  )\
+				.value_(0).action_(\{ \cf5 |v|\cf3  \
+					userView.scaleH = \
+						v.value.lincurve(0,1,minZoom.asPoint.x, maxZoom.asPoint.x, zoomCurve);\
+						\cf2 //1 + (v.value * maxZoom.asPoint.x);\cf3 \
+					\cf7 this\cf3 .setMoveSliderWidths( composite.bounds );\
+					\})\
+				.knobColor_( sliderKnobColor )\
+		 		.hilightColor_( \cf6 nil\cf3  )\
+		 		.background_(sliderBackColor)\
+		 		.knobSize_( 1 )\
+		 		.canFocus_( \cf6 false\cf3  )\
+				.resize_(9),\
+			\cf4 SmoothSlider\cf3 ( composite,  \cf4 Rect\cf3 ( \
+		 			composite.bounds.width - sliderWidth,  \
+		 			composite.bounds.height - \
+		 				(scaleSliderLength + sliderWidth + sliderSpacing), \
+		 				sliderWidth, scaleSliderLength ) )\
+				.value_(1).action_(\{ \cf5 |v|\cf3  \
+					userView.scaleV = \
+						(1-v.value).lincurve(0,1,minZoom.asPoint.y, maxZoom.asPoint.y, zoomCurve);\
+						\cf2 //1 + ((1 - v.value) * maxZoom.asPoint.y);\cf3 \
+					\cf7 this\cf3 .setMoveSliderWidths( composite.bounds );\
+					\})\
+				.knobColor_( sliderKnobColor )\
+				.hilightColor_( \cf6 nil\cf3  )\
+				.background_(sliderBackColor)\
+				.knobSize_( 1 )\
+		 		.canFocus_( \cf6 false\cf3  )\
+				.resize_(9) ];\
+		 \
+		moveSliders = [ \
+			\cf4 SmoothSlider\cf3 ( composite,  \cf4 Rect\cf3 ( 0, \
+					composite.bounds.height - sliderWidth, \
+					composite.bounds.width - \
+						(scaleSliderLength + sliderWidth + (2 * sliderSpacing)), \
+					sliderWidth ) )\
+				 .value_(0.5).action_(\{ \cf5 |v|\cf3  userView.moveH = v.value; \})\
+				 .knobColor_( sliderKnobColor)\
+				 .hilightColor_( \cf6 nil\cf3  )\
+				 .background_(sliderBackColor)\
+				 .resize_(8)\
+		 		.canFocus_( \cf6 false\cf3  ),\
+			\cf4 SmoothSlider\cf3 ( composite,  \cf4 Rect\cf3 ( \
+					composite.bounds.width - sliderWidth,  \
+					0, sliderWidth, \
+					(composite.bounds.height - \
+						(scaleSliderLength + sliderWidth + (2 * sliderSpacing))) ) )\
+				 .value_(0.5).action_(\{ \cf5 |v|\cf3  userView.moveV = 1 - (v.value); \})\
+				 .knobColor_( sliderKnobColor )\
+				 .hilightColor_( \cf6 nil\cf3  )\
+				 .background_(sliderBackColor)\
+				 .resize_(6)\
+		 		.canFocus_( \cf6 false\cf3  ) ];\
+		\
+		\cf7 this\cf3 .setMoveSliderWidths;\
+		\
+		currentBounds = userView.bounds;\
+		\
+		userView.refreshAction = \{ \cf5 |vw|\cf3 \
+			if( currentBounds != vw.bounds )\
+				\{ \cf7 this\cf3 .setMoveSliderWidths; currentBounds = vw.bounds; \}\
+			\};\
+		\}\
+		\
+	updateSliders \{ \cf5 |scaleFlag = true, moveFlag = true|\cf3 \
+		if( scaleFlag )\
+			\{ scaleSliders[0].value = \
+				userView.scaleH.curvelin(minZoom.asPoint.x, maxZoom.asPoint.x, 0, 1, zoomCurve );\
+				\cf2 //(userView.scaleH - 1) / maxZoom.asPoint.x;\cf3 \
+			scaleSliders[1].value = 1 - \
+				userView.scaleV.linlin(minZoom.asPoint.y, maxZoom.asPoint.y, 0, 1, zoomCurve );\
+				\cf2 //((userView.scaleV - 1) / maxZoom.asPoint.y );\cf3 \
+			\cf7 this\cf3 .setMoveSliderWidths;\
+			\};\
+		if( moveFlag )\
+			\{\
+			moveSliders[0].value = userView.moveH;\
+			moveSliders[1].value = 1 - userView.moveV;\
+			\};\
+		\}\
+		\
+	updateSliderBounds \{\
+	\
+		\cf5 var\cf3  hasH, hasV;\
+		\cf5 var\cf3  scaleVReallyEnabled;\
+		\
+		scaleVReallyEnabled = scaleVEnabled and: (userView.keepRatio.not);\
+		\
+		\cf2 // show/hide sliders\cf3 \
+		[scaleHEnabled, scaleVReallyEnabled, moveHEnabled, moveVEnabled].do(\{ \cf5 |enabled, i|\cf3 \
+			[ scaleSliders[0], scaleSliders[1], moveSliders[0], moveSliders[1] ][i]\
+				.visible = enabled;\
+			\});\
+					\
+		hasH =  (moveHEnabled or: scaleHEnabled).binaryValue;\
+		hasV =  (moveVEnabled or: scaleVReallyEnabled).binaryValue;\
+		\
+		#hasH, hasV = [ hasH, hasV ] * (sliderWidth + sliderSpacing);\
+				\
+		\cf2 // set bounds		\cf3 \
+		if( moveHEnabled )\
+			\{ moveSliders[0].bounds = \cf4 Rect\cf3 ( \
+				0, \
+				composite.bounds.height - sliderWidth, \
+				composite.bounds.width - ( hasV +\
+					((scaleSliderLength + sliderSpacing) * scaleHEnabled.binaryValue )\
+					), \
+				sliderWidth );\
+			\};\
+				\
+		if( moveVEnabled )\
+			\{ moveSliders[1].bounds = \cf4 Rect\cf3 ( \
+				composite.bounds.width - sliderWidth,  \
+				0, \
+				sliderWidth, \
+				composite.bounds.height - (hasH +\
+					((scaleSliderLength + sliderSpacing) * scaleVReallyEnabled.binaryValue ) \
+					)\
+					\
+				);\
+			\};\
+			\
+		if( scaleHEnabled )\
+			\{ scaleSliders[0].bounds = \cf4 Rect\cf3 (\
+				composite.bounds.width - (scaleSliderLength + hasV),  \
+		 		composite.bounds.height - sliderWidth, \
+		 		scaleSliderLength, \
+		 		sliderWidth );\
+			\};\
+			\
+		if( scaleVReallyEnabled )\
+			\{ scaleSliders[1].bounds = \cf4 Rect\cf3 ( \
+				composite.bounds.width - sliderWidth,  \
+	 			composite.bounds.height - (scaleSliderLength + hasH), \
+	 			sliderWidth, \
+	 			scaleSliderLength );\
+			\};\
+			\
+		userView.bounds = \cf4 Rect\cf3 (0,0, \
+			composite.bounds.width - hasV,\
+			composite.bounds.height - hasH\
+			);\
+		\}\
+		\
+	bounds \{ ^composite.bounds \}\
+	bounds_ \{ \cf5 |newBounds|\cf3  composite.bounds = newBounds; \}\
+		\
+	scaleHEnabled_ \{ \cf5 |bool|\cf3  scaleHEnabled = bool; \cf7 this\cf3 .updateSliderBounds; \}\
+	scaleVEnabled_ \{ \cf5 |bool|\cf3  scaleVEnabled = bool; \cf7 this\cf3 .updateSliderBounds; \}\
+	\
+	moveHEnabled_ \{ \cf5 |bool|\cf3  moveHEnabled = bool; \cf7 this\cf3 .updateSliderBounds; \}\
+	moveVEnabled_ \{ \cf5 |bool|\cf3  moveVEnabled = bool; \cf7 this\cf3 .updateSliderBounds; \}\
+	\
+	sliderWidth_ \{ \cf5 |width = 12|\cf3  sliderWidth = width; \cf7 this\cf3 .updateSliderBounds; \}\
+	sliderSpacing_ \{ \cf5 |spacing = 2|\cf3  sliderSpacing = spacing; \cf7 this\cf3 .updateSliderBounds; \}\
+	scaleSliderLength_ \{ \cf5 |length = 52|\cf3  scaleSliderLength = length;  \cf7 this\cf3 .updateSliderBounds; \}\
+		\
+	sliderKnobColor_ \{ \cf5 |color|\cf3 \
+		(scaleSliders ++ moveSliders).do(\cf4 _\cf3 .knobColor_(color));\
+		\}\
+		\
+	sliderBackColor_ \{ \cf5 |color|\cf3 \
+		(scaleSliders ++ moveSliders).do(\cf4 _\cf3 .background_(color));\
+		\}\
+		\
+	setMoveSliderWidths \{ \cf2 // |rect| // not used anymore\cf3 \
+		moveSliders[0].relThumbSize = (1 / userView.scaleH).min( userView.scaleH );\
+		moveSliders[1].relThumbSize = (1 / userView.scaleV).min( userView.scaleV );\
+			\}\
+\
+\
+	scaleH_ \{ \cf5 |newScaleH, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.scaleH_( newScaleH, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( updateFlag, \cf6 false\cf3  );\
+		 \}\
+		 \
+	scaleV_ \{ \cf5 |newScaleV, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.scaleV_( newScaleV, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( updateFlag, \cf6 false\cf3  );\
+		 \}\
+		 \
+	scale_ \{ \cf5 |newScaleArray, refreshFlag, updateFlag|\cf3  \cf2 // can be single value, array or point\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.scale_( newScaleArray, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( updateFlag, \cf6 false\cf3  );\
+		\}\
+		\
+		\
+	moveH_ \{ \cf5 |newMoveH, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.moveH_( newMoveH, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		 \}\
+		 \
+	moveV_ \{ \cf5 |newMoveV, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.moveV_( newMoveV, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		 \}\
+		 \
+	move_ \{ \cf5 |newMoveArray, refreshFlag, updateFlag|\cf3  \cf2 // can be single value, array or point\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.move_( newMoveArray, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		\}\
+		\
+	movePixels_ \{  \cf5 |newPixelsArray, limit, refreshFlag, updateFlag|\cf3  \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.movePixels_( newPixelsArray, limit, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		\}\
+		\
+	viewRect_ \{ \cf5 |rect, refreshFlag, updateFlag|\cf3  \cf2 // can be single value, array or point\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.viewRect_( rect, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( updateFlag, updateFlag );\
+		\}\
+	\
+		\
+	keepRatio_ \{ \cf5 |bool = false|\cf3 \
+		userView.keepRatio = bool;\
+		\cf7 this\cf3 .updateSliderBounds;\
+		\cf2 /*\
+		scaleSliders[1].visible = bool.not;\
+		\
+		moveSliders[1].bounds = moveSliders[1].bounds\
+			.height_( composite.bounds.height -\
+				[ scaleSliderLength + sliderWidth + (2 * sliderSpacing),\
+				  sliderWidth + sliderSpacing][ bool.binaryValue ] );\
+		*/\cf3 \
+		\cf7 this\cf3 .scaleH = \cf7 this\cf3 .scaleH; \
+		 \}\
+		\
+	refresh \{ \cf2 //this.setMoveSliderWidths;\cf3 \
+		 ^composite.refresh \}\
+		 \
+	resize \{ ^resize \}\
+	resize_ \{ \cf5 |val|\cf3  resize = val; composite.resize_( val ) \}\
+	\
+	window \{ ^window ?? \{ window = composite.getParents.last.findWindow; \} \}\
+	\
+	drawHook \{ ^\cf7 this\cf3 .window.drawHook \}\
+	drawHook_ \{ \cf5 |func|\cf3  \cf7 this\cf3 .window.drawHook = func; \}\
+	\
+	onClose \{ ^\cf7 this\cf3 .window.onClose \}\
+	onClose_ \{ \cf5 |func|\cf3  \cf7 this\cf3 .window.onClose = func; \}\
+	\
+	remove \{ composite.remove; \}\
+		\
+	\} \
+	\
+\cf2 //// Soon to be replaced by above\cf3 \
+\
+\cf4 ScaledUserViewWindow\cf3  \{\
+	\
+	\cf5 classvar\cf3  <>defaultBounds, <>defaultFromBounds;\
+	\
+	\cf5 var\cf3  <window, <userView, <scaleSliders, <moveSliders, <>drawHook; \
+	\cf5 var\cf3  <viewOffset;\
+	\cf5 var\cf3  <>maxZoom = 8;\
+	\cf5 var\cf3  <>onClose;\
+	\
+	*initClass \{ \
+		defaultBounds = \cf4 Rect\cf3 ( 350, 128, 400, 400 );\
+		defaultFromBounds = \cf4 Rect\cf3 (0,0,1,1); \cf2 // different from ScaledUserView\cf3 \
+		\}\
+		\
+	doesNotUnderstand \{ \cf5 arg\cf3  selector ... args;\
+		\cf5 var\cf3  res;\
+		res = userView.perform(selector, *args);\
+		if (res.class == \cf4 ScaledUserView\cf3  )\
+			\{ ^\cf7 this\cf3  \}\
+			\{ ^res \}\
+		\}\
+		\
+	*new \{ \cf5 |name, bounds, fromBounds, viewOffset|\cf3 \
+		name = name ? \cf8 "ScaledUserViewWindow"\cf3 ;\
+		bounds = (bounds ? defaultBounds).asRect;\
+		fromBounds = (fromBounds ? defaultFromBounds).asRect;\
+		viewOffset = viewOffset ? [1,1];\
+		^\cf7 super\cf3 .new.init( name, bounds, fromBounds, viewOffset);\
+		\}\
+		\
+	front \{ window.front \}\
+	\
+	init \{ \cf5 | inName, inBounds, inFromBounds, inViewOffset|\cf3 \
+		\cf5 var\cf3  sliderKnobColor, sliderBackColor;\
+		sliderKnobColor = \cf4 Color\cf3 .gray(0.2);\
+		sliderBackColor = \cf4 Color\cf3 .black.alpha_(0.33);\
+		window = \cf4 Window\cf3 ( inName, inBounds );\
+		\cf2 //window.view.background = Color.gray(0.8);\cf3 \
+		case \{ inViewOffset.class == \cf4 Point\cf3  \}\
+			\{ viewOffset = [ inViewOffset.x, inViewOffset.y ]; \}\
+			\{ inViewOffset.size == 0 \}\
+			\{ viewOffset = [ inViewOffset, inViewOffset ]; \}\
+			\{ inViewOffset.size == 1 \}\
+			\{ viewOffset = inViewOffset ++ inViewOffset; \}\
+			\{ \cf6 true\cf3  \}\
+			\{ viewOffset = inViewOffset; \};\
+		\
+		window.onClose = \{ onClose.value( \cf7 this\cf3 , window ) \};\
+			\
+		userView = \cf4 ScaledUserView\cf3 ( window, (window.asView.bounds + \
+			\cf4 Rect\cf3 (0,0,-19,-19)).insetAll( *(viewOffset ++ [0,0]) ), inFromBounds );\
+			\
+		userView.view.resize_(5);\
+		userView.background = \cf4 Color\cf3 .white.alpha_(0.5);\
+		\
+		scaleSliders = [ \
+			\cf4 SmoothSlider\cf3 ( window,  \cf4 Rect\cf3 ( \
+		 			window.asView.bounds.width - 75,  \
+		 			window.asView.bounds.height - 16, 48, 13 )  )\
+				.value_(0).action_(\{ \cf5 |v|\cf3  \
+					userView.scaleH = 1 + (v.value * maxZoom.asPoint.x);\
+					\cf7 this\cf3 .setMoveSliderWidths( window.asView.bounds );\
+					\cf2 /*\
+					if( userView.keepRatio )\
+						\{ scaleSliders[1].valueAction = (1 - v.value); \};\
+					*/\cf3 \
+					\})\
+				.knobColor_( sliderKnobColor )\
+		 		.hilightColor_( \cf6 nil\cf3  )\
+		 		.background_(sliderBackColor)\
+		 		.knobSize_( 1 )\
+		 		.canFocus_( \cf6 false\cf3  )\
+				.resize_(9),\
+			\cf4 SmoothSlider\cf3 ( window,  \cf4 Rect\cf3 ( \
+		 			window.asView.bounds.width - 16,  \
+		 			window.asView.bounds.height - 75, 13, 48 ) )\
+				.value_(1).action_(\{ \cf5 |v|\cf3  \
+					userView.scaleV = 1 + ((1 - v.value) * maxZoom.asPoint.y);\
+					\cf7 this\cf3 .setMoveSliderWidths( window.asView.bounds );\
+					\cf2 /*\
+					if( userView.keepRatio )\
+						\{ scaleSliders[0].valueAction = (1 - v.value); \};\
+					*/\cf3 \
+					\})\
+				.knobColor_( sliderKnobColor )\
+				.hilightColor_( \cf6 nil\cf3  )\
+				.background_(sliderBackColor)\
+				.knobSize_( 1 )\
+		 		.canFocus_( \cf6 false\cf3  )\
+				.resize_(9) ];\
+		 \
+		moveSliders = [ \
+			\cf4 SmoothSlider\cf3 ( window,  \cf4 Rect\cf3 ( viewOffset[0],  \
+				 	window.asView.bounds.height - 16, \
+				 	(window.asView.bounds.width - 78) - viewOffset[0], 13 )  )\
+				 .value_(0.5).action_(\{ \cf5 |v|\cf3  userView.moveH = v.value; \})\
+				 .knobColor_( sliderKnobColor)\
+				 .hilightColor_( \cf6 nil\cf3  )\
+				 .background_(sliderBackColor)\
+				 .resize_(8)\
+		 		.canFocus_( \cf6 false\cf3  ),\
+			\cf4 SmoothSlider\cf3 ( window,  \cf4 Rect\cf3 ( \
+					window.asView.bounds.width - 16,  viewOffset[1], 13, \
+					(window.asView.bounds.height - 78) - viewOffset[1] )  )\
+				 .value_(0.5).action_(\{ \cf5 |v|\cf3  userView.moveV = 1 - (v.value); \})\
+				 .knobColor_( sliderKnobColor )\
+				 .hilightColor_( \cf6 nil\cf3  )\
+				 .background_(sliderBackColor)\
+				 .resize_(6)\
+		 		.canFocus_( \cf6 false\cf3  ) ];\
+		\
+		\cf7 this\cf3 .setMoveSliderWidths;\
+		\
+		\
+		\
+		\
+		window.drawHook = \{ \cf5 |w|\cf3 \
+			\cf7 this\cf3 .setMoveSliderWidths;\
+			drawHook.value( window );\
+			\};\
+			\
+		window.front;\
+		\}\
+		\
+	updateSliders \{ \cf5 |scaleFlag = true, moveFlag = true|\cf3 \
+		if( scaleFlag )\
+			\{ scaleSliders[0].value = (userView.scaleH - 1) / maxZoom.asPoint.x;\
+			scaleSliders[1].value = 1 - ((userView.scaleV - 1) / maxZoom.asPoint.y );\
+			\cf7 this\cf3 .setMoveSliderWidths;\
+			\};\
+		if( moveFlag )\
+			\{\
+			moveSliders[0].value = userView.moveH;\
+			moveSliders[1].value = 1 - userView.moveV;\
+			\};\
+		\}\
+		\
+	setMoveSliderWidths \{ \cf2 // |rect| // not used anymore\cf3 \
+		moveSliders[0].relThumbSize = (1 / userView.scaleH).min(1);\
+		moveSliders[1].relThumbSize = (1 / userView.scaleV).min(1);\
+			\}\
+\
+\
+	scaleH_ \{ \cf5 |newScaleH, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.scaleH_( newScaleH, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( updateFlag, \cf6 false\cf3  );\
+		 \}\
+		 \
+	scaleV_ \{ \cf5 |newScaleV, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.scaleV_( newScaleV, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( updateFlag, \cf6 false\cf3  );\
+		 \}\
+		 \
+	scale_ \{ \cf5 |newScaleArray, refreshFlag, updateFlag|\cf3  \cf2 // can be single value, array or point\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.scale_( newScaleArray, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( updateFlag, \cf6 false\cf3  );\
+		\}\
+		\
+		\
+	moveH_ \{ \cf5 |newMoveH, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.moveH_( newMoveH, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		 \}\
+		 \
+	moveV_ \{ \cf5 |newMoveV, refreshFlag, updateFlag|\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.moveV_( newMoveV, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		 \}\
+		 \
+	move_ \{ \cf5 |newMoveArray, refreshFlag, updateFlag|\cf3  \cf2 // can be single value, array or point\cf3 \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.move_( newMoveArray, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		\}\
+		\
+	movePixels_ \{  \cf5 |newPixelsArray, limit, refreshFlag, updateFlag|\cf3  \
+		updateFlag = updateFlag ? \cf6 true\cf3 ;\
+		userView.movePixels_( newPixelsArray, limit, refreshFlag );\
+		\cf7 this\cf3 .updateSliders( \cf6 false\cf3 , updateFlag );\
+		\}\
+		\
+	keepRatio_ \{ \cf5 |bool = false|\cf3 \
+		userView.keepRatio = bool;\
+		scaleSliders[1].visible = bool.not;\
+		\cf7 this\cf3 .scaleH = \cf7 this\cf3 .scaleH; \
+		 \}\
+		\
+	refresh \{ ^window.refresh \}\
+		\
+	\} }
\ No newline at end of file

Modified: wslib/wslib-classes/GUI/Views/RoundButton.sc
===================================================================
--- wslib/wslib-classes/GUI/Views/RoundButton.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/Views/RoundButton.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -116,7 +116,7 @@
 			
 			Pen.use {
 				
-				if( hiliteColor.notNil && { (value.asInt == 1) && { states[1][2].isNil } } ) {
+				if( hiliteColor.notNil && { (value.asInteger == 1) && { states[1][2].isNil } } ) {
 					Pen.roundedRect( rect, radius );
 					hiliteColor.penFill( rect ); // requires Gradient:fill method
 				};
@@ -229,7 +229,7 @@
 	
 	doAction {
 		if( action.size > 0 ) // if action is in fact an array; couple states to actions
-			{ action.wrapAt( this.value.asInt - 1 ).value( this ); }
+			{ action.wrapAt( this.value.asInteger - 1 ).value( this ); }
 			{ action.value( this ); };
 	}
 	

Modified: wslib/wslib-classes/GUI/Views/RoundView.sc
===================================================================
--- wslib/wslib-classes/GUI/Views/RoundView.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/Views/RoundView.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -153,7 +153,7 @@
 		// use like this:
 		// unicode.getArrowKey ? key.getArrowKey;
 		^if( GUI.id == \qt ) {
-			switch( this.asInt,
+			switch( this.asInteger,
 				16r1000012, \left,
 				16r1000013, \up,
 				16r1000014, \right,
@@ -160,7 +160,7 @@
 				16r1000015, \down
 			);		
 		} {
-			switch( this.asInt,
+			switch( this.asInteger,
 				16rF700, \up,
 				16rF701, \down,
 				16rF702, \left,

Modified: wslib/wslib-classes/GUI/Views/ViewHolder2.sc
===================================================================
--- wslib/wslib-classes/GUI/Views/ViewHolder2.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/GUI/Views/ViewHolder2.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,159 +1,168 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf830
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red191\green0\blue0;\red0\green0\blue191;
+\red0\green0\blue255;\red51\green51\blue191;\red102\green102\blue191;\red0\green115\blue0;}
+{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;\csgenericrgb\c75000\c0\c0;\csgenericrgb\c0\c0\c75000;
+\csgenericrgb\c0\c0\c100000;\csgenericrgb\c20000\c20000\c75000;\csgenericrgb\c40000\c40000\c75000;\csgenericrgb\c0\c45000\c0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
 
-// SCViewHolder makes it possible to add more capabilities by holding an SCView, not subclassing it
-
-// Based on Sciss SCViewHolder
-// as long as that isn't in the main distro, this copy will be used
-
-ViewHolder2 {
-	classvar <>consumeKeyDowns = false;	// should the view by default consume keydowns
-	classvar <>dontRefresh = false;
-
-	// redirected hooks ((J)SCView)
-	var <>action, <>mouseDownAction, <>mouseUpAction, <>mouseOverAction, <>mouseMoveAction;
-	var <keyDownAction, <keyUpAction, <keyModifiersChangedAction;
-	var <beginDragAction,<canReceiveDragHandler,<receiveDragHandler;
-	var <>onClose;
-	var <>focusGainedAction, <>focusLostAction;
-	
-	// the user view, the GUI scheme
-	var <view;
-	
-	view_ { arg v;
-		// subclasses need to ALWAYS use this method to set the view
-		view = v;
-		if( view.isNil, { ^this });
-
-		view	// install double behaviour
-			.action_({          arg view ... rest; action.( this, *rest )})
-			.mouseDownAction_({ arg view ... rest; this.mouseDown( *rest ); })
-			.mouseUpAction_({   arg view ... rest; this.mouseUp( *rest ); })
-			.mouseOverAction_({ arg view ... rest; this.mouseOver( *rest ); })
-			.mouseMoveAction_({ arg view ... rest; this.mouseMove( *rest ); })
-			.onClose_({         arg view ... rest; this.viewDidClose; protect { onClose.( this, *rest )} { this.view = nil }})
-			;
-		if( view.respondsTo( 'focusGainedAction_' ), {    // currently no support in cocoa
-			view.focusGainedAction = { arg view ... rest; this.focusGained( *rest ); focusGainedAction.( this, *rest )};
-		});
-		if( view.respondsTo( 'focusLostAction_' ), {      // currently no support in cocoa
-			view.focusLostAction   = { arg view ... rest; this.focusLost( *rest );   focusLostAction.( this, *rest )};
-		});
-		this	// install default hooks
-			.keyDownAction_( nil )
-			.keyUpAction_( nil )
-			.keyModifiersChangedAction_( nil )
-			.beginDragAction_( nil )
-			.canReceiveDragHandler_( nil )
-			.receiveDragHandler_( nil )
-			;
-	}
-		
-	keyDownResponder { ^nil }
-	enableKeyDowns { this.keyDownAction = this.keyDownResponder }
-	asView { ^view }
-
-	isClosed { ^(view.isNil or: {view.isClosed}) }
-	
-	// ---- smart hook registration ----
-	
-	keyDownAction_ { arg func;
-		keyDownAction = func;
-		if( func.notNil, {
-			view.keyDownAction = { arg view ... rest; keyDownAction.( this, *rest )};
-		}, {
-			view.keyDownAction = { arg view ... rest; this.keyDown( *rest )};
-		});
-	}
-
-	keyUpAction_ { arg func;
-		keyUpAction = func;
-		if( func.notNil, {
-			view.keyUpAction = { arg view ... rest; keyUpAction.( this, *rest )};
-		}, {
-			view.keyUpAction = { arg view ... rest; this.keyUp( *rest )};
-		});
-	}
-
-	keyModifiersChangedAction_ { arg func;
-		keyModifiersChangedAction = func;
-		if( func.notNil, {
-			view.keyUpAction = { arg view ... rest; keyModifiersChangedAction.( this, *rest )};
-		}, {
-			view.keyUpAction = { arg view ... rest; this.keyModifiersChanged( *rest )};
-		});
-	}
-
-	beginDragAction_ { arg func;
-		beginDragAction = func;
-		if( func.notNil, {
-			view.beginDragAction = { arg view ... rest; beginDragAction.( this, *rest )};
-		}, {
-			view.beginDragAction = { arg view ... rest; this.getDrag( *rest ) };
-			//iew.beginDragAction = nil;
-		});
-	}
-
-	canReceiveDragHandler_ { arg func;
-		canReceiveDragHandler = func;
-		if( func.notNil, {
-			view.canReceiveDragHandler = { arg view ... rest; canReceiveDragHandler.( this, *rest )};
-		}, {
-			view.canReceiveDragHandler = { arg view ... rest; this.canReceiveDrag( *rest )};
-		});
-	}
-
-	receiveDragHandler_ { arg func;
-		receiveDragHandler = func;
-		if( func.notNil, {
-			view.receiveDragHandler = { arg view ... rest; receiveDragHandler.( this, *rest )};
-		}, {
-			view.receiveDragHandler = { arg view ... rest; this.receiveDrag( *rest )};
-		});
-	}
-
-	// ------- utility methods for subclasses -------
-	
-	currentDrag { ^view.scheme.view.currentDrag }
-	currentDragString { ^view.scheme.view.currentDragString }
-	
-	// ------- methods that can be overridden by subclasses if necessary -------
-	
-	init { } // this is called after instantiation; put any initialization code here
-	
-	// mouse control. these methods get called before user registered actions
-	mouseDown { |...rest| mouseDownAction.( this, *rest ) }
-	mouseUp { |...rest| mouseUpAction.( this, *rest ) }
-	mouseOver { |...rest| mouseOverAction.( this, *rest ) }
-	mouseMove { |...rest| mouseMoveAction.( this, *rest ) }
-	
-	// for the three key methods, returning nil will bubble up events
-	keyDown { ^nil }				// corresponds to defaultKeyDownAction
-	keyUp { ^nil }				// corresponds to defaultKeyUpAction
-	keyModifiersChanged { ^nil }	// like a defaultKeyModifiersChangedAction
-
-	// note: currently these are not called in cocoa
-	focusGained { }
-	focusLost { }
-	
-	// to access (J)SCView.currentDrag and currentDragString,
-	// please call this.currentDrag and this.currentDragString
-	// since they will automatically use the right GUI scheme!
-	getDrag { ^nil }				// corresponds to defaultGetDrag
-	canReceiveDrag { ^false }		// corresponds to defaultCanReceiveDrag
-	receiveDrag { } 				// corresponds to defaultReceiveDrag
-	
-	viewDidClose { }				// corresponds to onClose
-	
-	// ---- method forwarding ----
-	
-	refresh { if( dontRefresh !== true ) { view.refresh } }
-
-	// forwards any unknown calls to the view
-	doesNotUnderstand { arg ... args;
-		var result = view.perform( *args );
-		^if( result === view, { this }, { result }); // be sure to replace view with base
-	}
-	
-	respondsTo { arg ... args;
-		^if( super.respondsTo( *args ), true, { view.respondsTo( *args )});
-	}
-}
+\f0\fs20 \cf2 \
+\cf3 // SCViewHolder makes it possible to add more capabilities by holding an SCView, not subclassing it\cf2 \
+\
+\cf3 // Based on Sciss SCViewHolder\cf2 \
+\cf3 // as long as that isn't in the main distro, this copy will be used\cf2 \
+\
+\cf4 ViewHolder2\cf2  \{\
+	\cf5 classvar\cf2  <>consumeKeyDowns = \cf6 false\cf2 ;	\cf3 // should the view by default consume keydowns\cf2 \
+	\cf5 classvar\cf2  <>dontRefresh = \cf6 false\cf2 ;\
+\
+	\cf3 // redirected hooks ((J)SCView)\cf2 \
+	\cf5 var\cf2  <>action, <>mouseDownAction, <>mouseUpAction, <>mouseOverAction, <>mouseMoveAction;\
+	\cf5 var\cf2  <keyDownAction, <keyUpAction, <keyModifiersChangedAction;\
+	\cf5 var\cf2  <beginDragAction,<canReceiveDragHandler,<receiveDragHandler;\
+	\cf5 var\cf2  <>onClose;\
+	\cf5 var\cf2  <>focusGainedAction, <>focusLostAction;\
+	\
+	\cf3 // the user view, the GUI scheme\cf2 \
+	\cf5 var\cf2  <view;\
+	\
+	view_ \{ \cf5 arg\cf2  v;\
+		\cf3 // subclasses need to ALWAYS use this method to set the view\cf2 \
+		view = v;\
+		if( view.isNil, \{ ^\cf7 this\cf2  \});\
+\
+		view	\cf3 // install double behaviour\cf2 \
+			.action_(\{          \cf5 arg\cf2  view ... rest; action.( \cf7 this\cf2 , *rest )\})\
+			.mouseDownAction_(\{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .mouseDown( *rest ); \})\
+			.mouseUpAction_(\{   \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .mouseUp( *rest ); \})\
+			.mouseOverAction_(\{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .mouseOver( *rest ); \})\
+			.mouseMoveAction_(\{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .mouseMove( *rest ); \})\
+			.onClose_(\{         \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .viewDidClose; protect \{ onClose.( \cf7 this\cf2 , *rest )\} \{ \cf7 this\cf2 .view = \cf6 nil\cf2  \}\})\
+			;\
+		if( view.respondsTo( \cf8 'focusGainedAction_'\cf2  ), \{    \cf3 // currently no support in cocoa\cf2 \
+			view.focusGainedAction = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .focusGained( *rest ); focusGainedAction.( \cf7 this\cf2 , *rest )\};\
+		\});\
+		if( view.respondsTo( \cf8 'focusLostAction_'\cf2  ), \{      \cf3 // currently no support in cocoa\cf2 \
+			view.focusLostAction   = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .focusLost( *rest );   focusLostAction.( \cf7 this\cf2 , *rest )\};\
+		\});\
+		\cf7 this\cf2 	\cf3 // install default hooks\cf2 \
+			.keyDownAction_( \cf6 nil\cf2  )\
+			.keyUpAction_( \cf6 nil\cf2  )\
+			.keyModifiersChangedAction_( \cf6 nil\cf2  )\
+			.beginDragAction_( \cf6 nil\cf2  )\
+			.canReceiveDragHandler_( \cf6 nil\cf2  )\
+			.receiveDragHandler_( \cf6 nil\cf2  )\
+			;\
+	\}\
+		\
+	keyDownResponder \{ ^\cf6 nil\cf2  \}\
+	enableKeyDowns \{ \cf7 this\cf2 .keyDownAction = \cf7 this\cf2 .keyDownResponder \}\
+	asView \{ ^view \}\
+\
+	isClosed \{ ^(view.isNil or: \{view.isClosed\}) \}\
+	\
+	\cf3 // ---- smart hook registration ----\cf2 \
+	\
+	keyDownAction_ \{ \cf5 arg\cf2  func;\
+		keyDownAction = func;\
+		if( func.notNil, \{\
+			view.keyDownAction = \{ \cf5 arg\cf2  view ... rest; keyDownAction.( \cf7 this\cf2 , *rest )\};\
+		\}, \{\
+			view.keyDownAction = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .keyDown( *rest )\};\
+		\});\
+	\}\
+\
+	keyUpAction_ \{ \cf5 arg\cf2  func;\
+		keyUpAction = func;\
+		if( func.notNil, \{\
+			view.keyUpAction = \{ \cf5 arg\cf2  view ... rest; keyUpAction.( \cf7 this\cf2 , *rest )\};\
+		\}, \{\
+			view.keyUpAction = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .keyUp( *rest )\};\
+		\});\
+	\}\
+\
+	keyModifiersChangedAction_ \{ \cf5 arg\cf2  func;\
+		keyModifiersChangedAction = func;\
+		if( func.notNil, \{\
+			view.keyUpAction = \{ \cf5 arg\cf2  view ... rest; keyModifiersChangedAction.( \cf7 this\cf2 , *rest )\};\
+		\}, \{\
+			view.keyUpAction = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .keyModifiersChanged( *rest )\};\
+		\});\
+	\}\
+\
+	beginDragAction_ \{ \cf5 arg\cf2  func;\
+		beginDragAction = func;\
+		if( func.notNil, \{\
+			view.beginDragAction = \{ \cf5 arg\cf2  view ... rest; beginDragAction.( \cf7 this\cf2 , *rest )\};\
+		\}, \{\
+			view.beginDragAction = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .getDrag( *rest ) \};\
+			\cf3 //iew.beginDragAction = nil;\cf2 \
+		\});\
+	\}\
+\
+	canReceiveDragHandler_ \{ \cf5 arg\cf2  func;\
+		canReceiveDragHandler = func;\
+		if( func.notNil, \{\
+			view.canReceiveDragHandler = \{ \cf5 arg\cf2  view ... rest; canReceiveDragHandler.( \cf7 this\cf2 , *rest )\};\
+		\}, \{\
+			view.canReceiveDragHandler = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .canReceiveDrag( *rest )\};\
+		\});\
+	\}\
+\
+	receiveDragHandler_ \{ \cf5 arg\cf2  func;\
+		receiveDragHandler = func;\
+		if( func.notNil, \{\
+			view.receiveDragHandler = \{ \cf5 arg\cf2  view ... rest; receiveDragHandler.( \cf7 this\cf2 , *rest )\};\
+		\}, \{\
+			view.receiveDragHandler = \{ \cf5 arg\cf2  view ... rest; \cf7 this\cf2 .receiveDrag( *rest )\};\
+		\});\
+	\}\
+\
+	\cf3 // ------- utility methods for subclasses -------\cf2 \
+	\
+	currentDrag \{ ^view.scheme.view.currentDrag \}\
+	currentDragString \{ ^view.scheme.view.currentDragString \}\
+	\
+	\cf3 // ------- methods that can be overridden by subclasses if necessary -------\cf2 \
+	\
+	init \{ \} \cf3 // this is called after instantiation; put any initialization code here\cf2 \
+	\
+	\cf3 // mouse control. these methods get called before user registered actions\cf2 \
+	mouseDown \{ \cf5 |...rest|\cf2  mouseDownAction.( \cf7 this\cf2 , *rest ) \}\
+	mouseUp \{ \cf5 |...rest|\cf2  mouseUpAction.( \cf7 this\cf2 , *rest ) \}\
+	mouseOver \{ \cf5 |...rest|\cf2  mouseOverAction.( \cf7 this\cf2 , *rest ) \}\
+	mouseMove \{ \cf5 |...rest|\cf2  mouseMoveAction.( \cf7 this\cf2 , *rest ) \}\
+	\
+	\cf3 // for the three key methods, returning nil will bubble up events\cf2 \
+	keyDown \{ ^\cf6 nil\cf2  \}				\cf3 // corresponds to defaultKeyDownAction\cf2 \
+	keyUp \{ ^\cf6 nil\cf2  \}				\cf3 // corresponds to defaultKeyUpAction\cf2 \
+	keyModifiersChanged \{ ^\cf6 nil\cf2  \}	\cf3 // like a defaultKeyModifiersChangedAction\cf2 \
+\
+	\cf3 // note: currently these are not called in cocoa\cf2 \
+	focusGained \{ \}\
+	focusLost \{ \}\
+	\
+	\cf3 // to access (J)SCView.currentDrag and currentDragString,\cf2 \
+	\cf3 // please call this.currentDrag and this.currentDragString\cf2 \
+	\cf3 // since they will automatically use the right GUI scheme!\cf2 \
+	getDrag \{ ^\cf6 nil\cf2  \}				\cf3 // corresponds to defaultGetDrag\cf2 \
+	canReceiveDrag \{ ^\cf6 false\cf2  \}		\cf3 // corresponds to defaultCanReceiveDrag\cf2 \
+	receiveDrag \{ \} 				\cf3 // corresponds to defaultReceiveDrag\cf2 \
+	\
+	viewDidClose \{ \}				\cf3 // corresponds to onClose\cf2 \
+	\
+	\cf3 // ---- method forwarding ----\cf2 \
+	\
+	refresh \{ if( dontRefresh !== \cf6 true\cf2  ) \{ view !? _.refresh \} \}\
+\
+	\cf3 // forwards any unknown calls to the view\cf2 \
+	doesNotUnderstand \{ \cf5 arg\cf2  ... args;\
+		\cf5 var\cf2  result = view.perform( *args );\
+		^if( result === view, \{ \cf7 this\cf2  \}, \{ result \}); \cf3 // be sure to replace view with base\cf2 \
+	\}\
+	\
+	respondsTo \{ \cf5 arg\cf2  ... args;\
+		^if( \cf7 super\cf2 .respondsTo( *args ), \cf6 true\cf2 , \{ view.respondsTo( *args )\});\
+	\}\
+\}\
+}
\ No newline at end of file

Modified: wslib/wslib-classes/Main Features/EQ/BHiCut.sc
===================================================================
--- wslib/wslib-classes/Main Features/EQ/BHiCut.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Main Features/EQ/BHiCut.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,126 +1,134 @@
-// wslib 2010-2011
-// cascaded butterworth filters
-// these filters provide linear slope of -12 to -60 dB per octave
-/*
+{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf820
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;\red191\green0\blue0;\red0\green0\blue0;\red0\green0\blue191;
+\red0\green0\blue255;\red102\green102\blue191;\red0\green115\blue0;}
+{\*\expandedcolortbl;;\csgenericrgb\c75000\c0\c0;\csgenericrgb\c0\c0\c0;\csgenericrgb\c0\c0\c75000;
+\csgenericrgb\c0\c0\c100000;\csgenericrgb\c40000\c40000\c75000;\csgenericrgb\c0\c45000\c0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
 
-(
-6.collect({ |i| // order: 0-5
-	BLowCut.magResponse( 1000, 44100, 1000, i ).ampdb
-}).plot2( minval: -350, maxval: 10 ).superpose_(true);
-)
-
-*/
-
-BHiCut : BEQSuite {
-	
-	classvar <allRQs;
-	
-	*initClass { 
-		
-		/*
-		allRQs = [ 	// Tietze/Schenk, 1999 issue page 856, pdf page #882.
-			[],
-			[ 2.sqrt ],					 // 2nd order - 12dB per octave
-			[1.8478, 0.7654 ],						// 4 - 24dB
-			[1.9319, 1.4142, 0.5176 ],				// 6 - 36dB
-			[1.9616, 1.6629, 1.1111, 0.3902 ],   		// 8 - 48dB
-			[1.9754, 1.7820, 1.4142, 0.9080, 0.3129 ]	// 10 - 60dB
-		];
-		*/
-		
-		allRQs = [ 	// Tietze/Schenk, 1999 issue page 856, pdf page #882.
-			[],									// 0: bypass
-			[ 2 ].sqrt,					 		// 1: 2nd order - 12dB per octave
-			[ 2 + 2.sqrt, 2 - 2.sqrt ].sqrt,	 		// 2: 4th order - 24dB
-			[ 2 + 3.sqrt, 2, 2 - 3.sqrt ].sqrt,		// 3: 6th order - 36dB
-			[ 2 + (2 + 2.sqrt).sqrt, 
-			  2 + (2 - 2.sqrt).sqrt, 
-			  2 - (2 - 2.sqrt).sqrt, 
-			  2 - (2 + 2.sqrt).sqrt ].sqrt,           // 4: 8th order - 48dB
-			[1.9754, 1.7820, 2.sqrt, 0.9080, 0.3129 ]	// 5: 10th order - 60dB
-		];
-		
-		
-	}
-	
-	*filterClass { ^BLowPass }
-	
-	*coeffs { |sr, freq = 1200, order = 2|
-		^[]; // not us ed, only here for EQdef to know the args
-	}
-	
-	*new1 { |rate = 'audio', in, freq, order=2, maxOrder=5| 
-		if( order.isNumber ) {
-			// fixed order: less cpu
-			^this.newFixed( rate, in, freq, order );
-		} { 	// variable order
-			// assume control input
-			// use lower maxOrder for less cpu use
-			^this.newVari( rate, in, freq, order, maxOrder );
-		};
-	}
-	
-	*newFixed { |rate = 'audio', in, freq, order=2| // maxOrder doesn't apply here
-		var rqs, selector; 
-		rqs = allRQs.clipAt(order);
-		selector = this.methodSelectorForRate( rate );
-		rqs.do {\xCA|rq|\xCAin = this.filterClass.perform( selector, in, freq, rq ) };
-		^in;
-	}
-	
-	*newVari { |rate = 'audio', in, freq, order=2, maxOrder=5|
-		var rqs, selector;
-		rqs = Select.kr(
-			order.clip(0, maxOrder), 
-			allRQs.collect(_.extend(maxOrder, 2.sqrt) ) 
-		);
-		selector = this.methodSelectorForRate( rate );
-		rqs.do { |rq, i| 
-			in = Select.ar( order > i, [ 
-				in, 
-				this.filterClass.perform( selector, in, freq, rq ) 
-			]);
-		};
-		^in;	
-	}
-
-	*ar { |in, freq, order=2, maxOrder = 5|\xCA
-		^this.new1( 'audio', in, freq, order, maxOrder );
-	}
-	
-	*kr { |in, freq, order=2, maxOrder = 5|\xCA
-		^this.new1( 'control', in, freq, order, maxOrder );
-	}
-
-}
-
-BLowCut : BHiCut {
-	*filterClass { ^BHiPass }
-}
-
-LRLowCut : BLowCut { // dual cascaded butterworth - use for crossovers
-	
-	*ar { |in, freq, order=2, maxOrder=5|
-		in = this.new1( 'audio', in, freq, order, maxOrder );
-		^this.new1( 'audio', in, freq, order, maxOrder );
-	}
-	
-	*kr { |in, freq, order=2, maxOrder=5|
-		in = this.new1( 'control', in, freq, order, maxOrder );
-		^this.new1( 'control', in, freq, order, maxOrder );
-	}
-	
-}
-
-LRHiCut : BHiCut {
-	
-	*ar { |in, freq, order=2, maxOrder=5|
-		in = this.new1( 'audio', in, freq, order, maxOrder );
-		^this.new1( 'audio', in, freq, order, maxOrder );
-	}
-	
-	*kr { |in, freq, order=2, maxOrder=5|
-		in = this.new1( 'control', in, freq, order, maxOrder );
-		^this.new1( 'control', in, freq, order, maxOrder );
-	}
-}
\ No newline at end of file
+\f0\fs20 \cf2 // wslib 2010-2011\cf3 \
+\cf2 // cascaded butterworth filters\cf3 \
+\cf2 // these filters provide linear slope of -12 to -60 dB per octave\cf3 \
+\cf2 /*\
+\
+(\
+6.collect(\{ |i| // order: 0-5\
+	BLowCut.magResponse( 1000, 44100, 1000, i ).ampdb\
+\}).plot2( minval: -350, maxval: 10 ).superpose_(true);\
+)\
+\
+*/\cf3 \
+\
+\cf4 BHiCut\cf3  : \cf4 BEQSuite\cf3  \{\
+	\
+	\cf5 classvar\cf3  <allRQs;\
+	\
+	*initClass \{ \
+		\
+		\cf2 /*\
+		allRQs = [ 	// Tietze/Schenk, 1999 issue page 856, pdf page #882.\
+			[],\
+			[ 2.sqrt ],					 // 2nd order - 12dB per octave\
+			[1.8478, 0.7654 ],						// 4 - 24dB\
+			[1.9319, 1.4142, 0.5176 ],				// 6 - 36dB\
+			[1.9616, 1.6629, 1.1111, 0.3902 ],   		// 8 - 48dB\
+			[1.9754, 1.7820, 1.4142, 0.9080, 0.3129 ]	// 10 - 60dB\
+		];\
+		*/\cf3 \
+		\
+		allRQs = [ 	\cf2 // Tietze/Schenk, 1999 issue page 856, pdf page #882.\cf3 \
+			[],									\cf2 // 0: bypass\cf3 \
+			[ 2 ].sqrt,					 		\cf2 // 1: 2nd order - 12dB per octave\cf3 \
+			[ 2 + 2.sqrt, 2 - 2.sqrt ].sqrt,	 		\cf2 // 2: 4th order - 24dB\cf3 \
+			[ 2 + 3.sqrt, 2, 2 - 3.sqrt ].sqrt,		\cf2 // 3: 6th order - 36dB\cf3 \
+			[ 2 + (2 + 2.sqrt).sqrt, \
+			  2 + (2 - 2.sqrt).sqrt, \
+			  2 - (2 - 2.sqrt).sqrt, \
+			  2 - (2 + 2.sqrt).sqrt ].sqrt,           \cf2 // 4: 8th order - 48dB\cf3 \
+			[1.9754, 1.7820, 2.sqrt, 0.9080, 0.3129 ]	\cf2 // 5: 10th order - 60dB\cf3 \
+		];\
+		\
+		\
+	\}\
+	\
+	*filterClass \{ ^\cf4 BLowPass\cf3  \}\
+	\
+	*coeffs \{ \cf5 |sr, freq = 1200, order = 2|\cf3 \
+		^[]; \cf2 // not us ed, only here for EQdef to know the args\cf3 \
+	\}\
+	\
+	*new1 \{ \cf5 |rate = 'audio', in, freq, order=2, maxOrder=5|\cf3  \
+		if( order.isNumber ) \{\
+			\cf2 // fixed order: less cpu\cf3 \
+			^\cf6 this\cf3 .newFixed( rate, in, freq, order );\
+		\} \{ 	\cf2 // variable order\cf3 \
+			\cf2 // assume control input\cf3 \
+			\cf2 // use lower maxOrder for less cpu use\cf3 \
+			^\cf6 this\cf3 .newVari( rate, in, freq, order, maxOrder );\
+		\};\
+	\}\
+	\
+	*newFixed \{ \cf5 |rate = 'audio', in, freq, order=2|\cf3  \cf2 // maxOrder doesn't apply here\cf3 \
+		\cf5 var\cf3  rqs, selector; \
+		rqs = allRQs.clipAt(order);\
+		selector = \cf6 this\cf3 .methodSelectorForRate( rate );\
+		rqs.do \{\'a0|rq|\'a0in = \cf6 this\cf3 .filterClass.perform( selector, in, freq, rq ) \};\
+		^in;\
+	\}\
+	\
+	*newVari \{ \cf5 |rate = 'audio', in, freq, order=2, maxOrder=5|\cf3 \
+		\cf5 var\cf3  rqs, selector;\
+		rqs = \cf4 Select\cf3 .kr(\
+			order.clip(0, maxOrder), \
+			allRQs.collect(\{ \cf5 |item|\cf3  item.copy.extend(maxOrder, 2.sqrt) \}) \
+		);\
+		selector = \cf6 this\cf3 .methodSelectorForRate( rate );\
+		rqs.do \{ \cf5 |rq, i|\cf3  \
+			in = \cf4 Select\cf3 .ar( order > i, [ \
+				in, \
+				\cf6 this\cf3 .filterClass.perform( selector, in, freq, rq ) \
+			]);\
+		\};\
+		^in;	\
+	\}\
+\
+	*ar \{ \cf5 |in, freq, order=2, maxOrder = 5|\cf3 \'a0\
+		^\cf6 this\cf3 .new1( \cf7 'audio'\cf3 , in, freq, order, maxOrder );\
+	\}\
+	\
+	*kr \{ \cf5 |in, freq, order=2, maxOrder = 5|\cf3 \'a0\
+		^\cf6 this\cf3 .new1( \cf7 'control'\cf3 , in, freq, order, maxOrder );\
+	\}\
+\
+\}\
+\
+\cf4 BLowCut\cf3  : \cf4 BHiCut\cf3  \{\
+	*filterClass \{ ^\cf4 BHiPass\cf3  \}\
+\}\
+\
+\cf4 LRLowCut\cf3  : \cf4 BLowCut\cf3  \{ \cf2 // dual cascaded butterworth - use for crossovers\cf3 \
+	\
+	*ar \{ \cf5 |in, freq, order=2, maxOrder=5|\cf3 \
+		in = \cf6 this\cf3 .new1( \cf7 'audio'\cf3 , in, freq, order, maxOrder );\
+		^\cf6 this\cf3 .new1( \cf7 'audio'\cf3 , in, freq, order, maxOrder );\
+	\}\
+	\
+	*kr \{ \cf5 |in, freq, order=2, maxOrder=5|\cf3 \
+		in = \cf6 this\cf3 .new1( \cf7 'control'\cf3 , in, freq, order, maxOrder );\
+		^\cf6 this\cf3 .new1( \cf7 'control'\cf3 , in, freq, order, maxOrder );\
+	\}\
+	\
+\}\
+\
+\cf4 LRHiCut\cf3  : \cf4 BHiCut\cf3  \{\
+	\
+	*ar \{ \cf5 |in, freq, order=2, maxOrder=5|\cf3 \
+		in = \cf6 this\cf3 .new1( \cf7 'audio'\cf3 , in, freq, order, maxOrder );\
+		^\cf6 this\cf3 .new1( \cf7 'audio'\cf3 , in, freq, order, maxOrder );\
+	\}\
+	\
+	*kr \{ \cf5 |in, freq, order=2, maxOrder=5|\cf3 \
+		in = \cf6 this\cf3 .new1( \cf7 'control'\cf3 , in, freq, order, maxOrder );\
+		^\cf6 this\cf3 .new1( \cf7 'control'\cf3 , in, freq, order, maxOrder );\
+	\}\
+\}}
\ No newline at end of file

Modified: wslib/wslib-classes/Main Features/Note/extVarious-midiname.sc
===================================================================
--- wslib/wslib-classes/Main Features/Note/extVarious-midiname.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Main Features/Note/extVarious-midiname.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -60,7 +60,7 @@
 		$# -> ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"],
 		$b -> ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"],
 		$n -> ["C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B"]
-		].at(sign)[this.round(1.0) % 12] ++ ((this.round(1.0) / 12).floor - 2).asInt;
+		].at(sign)[this.round(1.0) % 12] ++ ((this.round(1.0) / 12).floor - 2).asInteger;
 		out.addUniqueMethod('cents', { ((this - this.round(1.0)) * 100).round(10e-8) });
 		out.addUniqueMethod('alt', { IdentityDictionary[$# -> 1, $b -> -1].at(out[1]) ? 0 })
 		//out.cents_( ((this - this.round(1.0)) * 100).round(10e-8)  );
@@ -238,7 +238,7 @@
 		alt.abs.do({ altString = altString ++ 
 			(if(alt.isPositive) {"#"} {"b"}); });
 		if(alt==2) {altString="x"};
-		out = name.asString ++ altString ++ octave.round(1).asInt;
+		out = name.asString ++ altString ++ octave.round(1).asInteger;
 		out.addUniqueMethod('cents', { cents });
 		out.addUniqueMethod('alt', { alt });
 		^out;

Modified: wslib/wslib-classes/Main Features/SMPTE/SMPTEView.sc
===================================================================
--- wslib/wslib-classes/Main Features/SMPTE/SMPTEView.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Main Features/SMPTE/SMPTEView.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,157 +1,165 @@
-SMPTEView { // fps = 1000
-	var <>parent, <view, <pos = 0, <selected = -1, <fontSize = 20;
-	var <fontName, <fontColor, <background;
-	var <>keyDownAction, <>keyUpAction, <>mouseDownAction, <>mouseMoveAction, <>mouseUpAction;
-	var <>action;
-	var <>minTime = 0, <>maxTime = 62330.591114739;
-	
-	*new { |parent, bnds, fontSize = 20| // bounds can be point; only top and left are used anyway
-		this.deprecated( thisMethod );
-		^super.newCopyArgs( parent ).init( bnds ? (0@0), fontSize );
-		}
-	
-	init { |inBounds, inFontSize = 20|
-		var counterDragStart;
-		if( inBounds.class == Point ) 
-			{ inBounds = Rect( inBounds.x, inBounds.y, 0,0 ); };
-		
-		fontColor = fontColor ? Color.black.alpha_(0.5);
-		fontName = fontName ? "Monaco";
-		fontSize = inFontSize ? 20;
-		
-		view = UserView( parent, Rect( inBounds.left, inBounds.top, 
-				(fontSize * 7.2) + 2, fontSize * 1.2 ) )
-			//.relativeOrigin_( false )
-			//.canFocus_( false )
-			;
-		
-		view.drawFunc = { |v|
-			if( background.notNil )
-				{ Pen.color = background; Pen.fillRect( v.drawBounds ) };
-					
-			pos.asSMPTEString( 1000 )
-				.drawStretchedIn( v.drawBounds, Font( fontName, fontSize ), fontColor );
-				//.drawAtPoint( v.drawBounds.leftTop, Font( fontName, fontSize ), fontColor );
-		
-			if( v.hasFocus && { [-1,3,6,9].includes( selected ).not } )
-				{ 
-				Pen.color = Color.black;
-				Pen.strokeRect( Rect( 
-					(v.drawBounds.left + ((11 - selected) * ((v.drawBounds.width) / 12)))
-						-1,
-					v.drawBounds.top, (v.drawBounds.width) / 12, v.drawBounds.height ) ); };
-				
-			};
-			
-		view.mouseDownAction = { |v, x, y, mod|
-			selected = (11 - (((x+1) - v.drawBounds.left) /
-				((v.drawBounds.width) / 12) ).floor).asInt;
-			counterDragStart = [x@y, pos.copy];
-			mouseDownAction.value( this, x, y, mod );
-			};
-			
-		view.mouseMoveAction = { |v, x, y, mod|
-			var scaler;
-			scaler = [ 0.001, 0.01, 0.1, nil, 1, 10, nil, 60, 600, nil, 3600, 36000 ][ selected ];
-			if( scaler.notNil )
-				{ pos = ( ((counterDragStart[0].y - y) * scaler) + counterDragStart[1] )
-						.max( minTime ).min( maxTime );
-					action.value( this );
-					parent.refresh; };
-			mouseMoveAction.value( this, x, y, mod );
-			};
-	
-		view.mouseUpAction = { |v, x, y, mod|
-			
-			mouseUpAction.value( this, x, y, mod );
-			action.value( this );
-			parent.refresh;
-			};
-		
-			
-		view.keyDownAction = { |v, char, a, b|
-			var validSelections;
-			var scaler;
-			validSelections = [0,1,2,4,5,7,8,10,11];
-			if( char.isDecDigit && { validSelections.includes( selected ) } )
-				{	pos = pos.asSMPTEString( 1000 )
-						.overWrite( char.asString, 11 - selected )
-						.asSeconds( 1000 );
-					action.value( this );
-					parent.refresh;
-					
-				};
-				
-			if( b == 63234 ) // <-
-				{ selected = validSelections[ 
-					(validSelections.indexOf( selected ) ? 10) + 1 ] ? 11;
-					parent.refresh; };
-			if( b == 63235 ) // ->
-				{ selected = validSelections[ 
-					(validSelections.indexOf( selected ) ? 1) - 1 ] ? 0;
-					parent.refresh; };
-			if( b == 63233 ) // v
-				{	
-				scaler = [ 0.001, 0.01, 0.1, nil, 1, 10, nil, 
-						60, 600, nil, 3600, 36000 ][ selected ];
-				if( scaler.notNil )
-						{ pos = (pos - scaler).max(0).min( 60*60*9 );
-						action.value( this );
-						parent.refresh;
-						};
-				};
-			if( b == 63232 ) // ^
-				{	
-				scaler = [ 0.001, 0.01, 0.1, nil, 1, 10, nil, 
-						60, 600, nil, 3600, 36000 ][ selected ];
-				if( scaler.notNil )
-						{ pos = (pos + scaler).max(0).min( 60*60*9 ); 
-						action.value( this );
-						parent.refresh; };
-				};
-			keyDownAction.value( this, char, a, b );
-			
-			};
-			
-		view.keyUpAction = { |v, char, a,b| 
-			var validSelections;
-			validSelections = [0,1,2,4,5,7,8,10,11];
-			if( char.isDecDigit && { validSelections.includes( selected ) } )
-				{ 
-				selected = validSelections[ validSelections.indexOf( selected ) - 1 ] ? -1; 
-				action.value( this );
-				parent.refresh;
-				};
-			
-			keyUpAction.value( this, char, a, b );
-			};
-			
-				
-		
-		}
-	
-	pos_ { |newPos| pos = newPos ? pos; parent.refresh; }
-	posD_ { |newPos| pos = newPos ? pos; { parent.refresh }.defer; }
-	//posNoRefresh_ { |newPos| pos = newPos ? pos; }
-	selected_ { |index| selected = index ? selected; parent.refresh; }
-	fontSize_ { |newFontSize| fontSize = newFontSize ? fontSize;
-		view.bounds = Rect( view.bounds.left, view.bounds.top, 
-				(fontSize * 7.2) + 1, fontSize * 1.2 );
-		 parent.refresh; }
-	fontName_ { |name| fontName = name ? "Monaco"; parent.refresh; }
-		 
-	fontColor_ { |color| fontColor = color ? fontColor; parent.refresh; }
-	background_ { |color| background = color; parent.refresh; }
-	
-	value { ^pos; }
-	string { ^pos.asSMPTEString( 1000 ); }
-	smpte { |fps| ^SMPTE( pos, fps ? 1000 ) }
-	
-	value_ { |val| pos = val ? pos; }
-	string_ { |string| pos = string.asSeconds; parent.refresh; }
-	smpte_ { |smpte| pos = smpte.asSMPTE.fps_( 1000 ).asSeconds; parent.refresh; }
-	
-	bounds { ^view.bounds }
-	bounds_ { |newBounds| view.bounds = newBounds ? view.bounds; }
-		
-	}
\ No newline at end of file
+{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue191;\red0\green0\blue0;\red191\green0\blue0;
+\red0\green0\blue255;\red102\green102\blue191;\red96\green96\blue96;\red51\green51\blue191;}
+{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c75000;\csgenericrgb\c0\c0\c0;\csgenericrgb\c75000\c0\c0;
+\csgenericrgb\c0\c0\c100000;\csgenericrgb\c40000\c40000\c75000;\csgenericrgb\c37500\c37500\c37500;\csgenericrgb\c20000\c20000\c75000;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+
+\f0\fs20 \cf2 SMPTEView\cf3  \{ \cf4 // fps = 1000\cf3 \
+	\cf5 var\cf3  <>parent, <view, <pos = 0, <selected = -1, <fontSize = 20;\
+	\cf5 var\cf3  <fontName, <fontColor, <background;\
+	\cf5 var\cf3  <>keyDownAction, <>keyUpAction, <>mouseDownAction, <>mouseMoveAction, <>mouseUpAction;\
+	\cf5 var\cf3  <>action;\
+	\cf5 var\cf3  <>minTime = 0, <>maxTime = 62330.591114739;\
+	\
+	*new \{ \cf5 |parent, bnds, fontSize = 20|\cf3  \cf4 // bounds can be point; only top and left are used anyway\cf3 \
+		\cf6 this\cf3 .deprecated( \cf6 thisMethod\cf3  );\
+		^\cf6 super\cf3 .newCopyArgs( parent ).init( bnds ? (0@0), fontSize );\
+		\}\
+	\
+	init \{ \cf5 |inBounds, inFontSize = 20|\cf3 \
+		\cf5 var\cf3  counterDragStart;\
+		if( inBounds.class == \cf2 Point\cf3  ) \
+			\{ inBounds = \cf2 Rect\cf3 ( inBounds.x, inBounds.y, 0,0 ); \};\
+		\
+		fontColor = fontColor ? \cf2 Color\cf3 .black.alpha_(0.5);\
+		fontName = fontName ? \cf7 "Monaco"\cf3 ;\
+		fontSize = inFontSize ? 20;\
+		\
+		view = \cf2 UserView\cf3 ( parent, \cf2 Rect\cf3 ( inBounds.left, inBounds.top, \
+				(fontSize * 7.2) + 2, fontSize * 1.2 ) )\
+			\cf4 //.relativeOrigin_( false )\cf3 \
+			\cf4 //.canFocus_( false )\cf3 \
+			;\
+		\
+		view.drawFunc = \{ \cf5 |v|\cf3 \
+			if( background.notNil )\
+				\{ \cf2 Pen\cf3 .color = background; \cf2 Pen\cf3 .fillRect( v.drawBounds ) \};\
+					\
+			pos.asSMPTEString( 1000 )\
+				.drawStretchedIn( v.drawBounds, \cf2 Font\cf3 ( fontName, fontSize ), fontColor );\
+				\cf4 //.drawAtPoint( v.drawBounds.leftTop, Font( fontName, fontSize ), fontColor );\cf3 \
+		\
+			if( v.hasFocus && \{ [-1,3,6,9].includes( selected ).not \} )\
+				\{ \
+				\cf2 Pen\cf3 .color = \cf2 Color\cf3 .black;\
+				\cf2 Pen\cf3 .strokeRect( \cf2 Rect\cf3 ( \
+					(v.drawBounds.left + ((11 - selected) * ((v.drawBounds.width) / 12)))\
+						-1,\
+					v.drawBounds.top, (v.drawBounds.width) / 12, v.drawBounds.height ) ); \};\
+				\
+			\};\
+			\
+		view.mouseDownAction = \{ \cf5 |v, x, y, mod|\cf3 \
+			selected = (11 - (((x+1) - v.drawBounds.left) /\
+				((v.drawBounds.width) / 12) ).floor).asInteger;\
+			counterDragStart = [x@y, pos.copy];\
+			mouseDownAction.value( \cf6 this\cf3 , x, y, mod );\
+			\};\
+			\
+		view.mouseMoveAction = \{ \cf5 |v, x, y, mod|\cf3 \
+			\cf5 var\cf3  scaler;\
+			scaler = [ 0.001, 0.01, 0.1, \cf8 nil\cf3 , 1, 10, \cf8 nil\cf3 , 60, 600, \cf8 nil\cf3 , 3600, 36000 ][ selected ];\
+			if( scaler.notNil )\
+				\{ pos = ( ((counterDragStart[0].y - y) * scaler) + counterDragStart[1] )\
+						.max( minTime ).min( maxTime );\
+					action.value( \cf6 this\cf3  );\
+					parent.refresh; \};\
+			mouseMoveAction.value( \cf6 this\cf3 , x, y, mod );\
+			\};\
+	\
+		view.mouseUpAction = \{ \cf5 |v, x, y, mod|\cf3 \
+			\
+			mouseUpAction.value( \cf6 this\cf3 , x, y, mod );\
+			action.value( \cf6 this\cf3  );\
+			parent.refresh;\
+			\};\
+		\
+			\
+		view.keyDownAction = \{ \cf5 |v, char, a, b|\cf3 \
+			\cf5 var\cf3  validSelections;\
+			\cf5 var\cf3  scaler;\
+			validSelections = [0,1,2,4,5,7,8,10,11];\
+			if( char.isDecDigit && \{ validSelections.includes( selected ) \} )\
+				\{	pos = pos.asSMPTEString( 1000 )\
+						.overWrite( char.asString, 11 - selected )\
+						.asSeconds( 1000 );\
+					action.value( \cf6 this\cf3  );\
+					parent.refresh;\
+					\
+				\};\
+				\
+			if( b == 63234 ) \cf4 // <-\cf3 \
+				\{ selected = validSelections[ \
+					(validSelections.indexOf( selected ) ? 10) + 1 ] ? 11;\
+					parent.refresh; \};\
+			if( b == 63235 ) \cf4 // ->\cf3 \
+				\{ selected = validSelections[ \
+					(validSelections.indexOf( selected ) ? 1) - 1 ] ? 0;\
+					parent.refresh; \};\
+			if( b == 63233 ) \cf4 // v\cf3 \
+				\{	\
+				scaler = [ 0.001, 0.01, 0.1, \cf8 nil\cf3 , 1, 10, \cf8 nil\cf3 , \
+						60, 600, \cf8 nil\cf3 , 3600, 36000 ][ selected ];\
+				if( scaler.notNil )\
+						\{ pos = (pos - scaler).max(0).min( 60*60*9 );\
+						action.value( \cf6 this\cf3  );\
+						parent.refresh;\
+						\};\
+				\};\
+			if( b == 63232 ) \cf4 // ^\cf3 \
+				\{	\
+				scaler = [ 0.001, 0.01, 0.1, \cf8 nil\cf3 , 1, 10, \cf8 nil\cf3 , \
+						60, 600, \cf8 nil\cf3 , 3600, 36000 ][ selected ];\
+				if( scaler.notNil )\
+						\{ pos = (pos + scaler).max(0).min( 60*60*9 ); \
+						action.value( \cf6 this\cf3  );\
+						parent.refresh; \};\
+				\};\
+			keyDownAction.value( \cf6 this\cf3 , char, a, b );\
+			\
+			\};\
+			\
+		view.keyUpAction = \{ \cf5 |v, char, a,b|\cf3  \
+			\cf5 var\cf3  validSelections;\
+			validSelections = [0,1,2,4,5,7,8,10,11];\
+			if( char.isDecDigit && \{ validSelections.includes( selected ) \} )\
+				\{ \
+				selected = validSelections[ validSelections.indexOf( selected ) - 1 ] ? -1; \
+				action.value( \cf6 this\cf3  );\
+				parent.refresh;\
+				\};\
+			\
+			keyUpAction.value( \cf6 this\cf3 , char, a, b );\
+			\};\
+			\
+				\
+		\
+		\}\
+	\
+	pos_ \{ \cf5 |newPos|\cf3  pos = newPos ? pos; parent.refresh; \}\
+	posD_ \{ \cf5 |newPos|\cf3  pos = newPos ? pos; \{ parent.refresh \}.defer; \}\
+	\cf4 //posNoRefresh_ \{ |newPos| pos = newPos ? pos; \}\cf3 \
+	selected_ \{ \cf5 |index|\cf3  selected = index ? selected; parent.refresh; \}\
+	fontSize_ \{ \cf5 |newFontSize|\cf3  fontSize = newFontSize ? fontSize;\
+		view.bounds = \cf2 Rect\cf3 ( view.bounds.left, view.bounds.top, \
+				(fontSize * 7.2) + 1, fontSize * 1.2 );\
+		 parent.refresh; \}\
+	fontName_ \{ \cf5 |name|\cf3  fontName = name ? \cf7 "Monaco"\cf3 ; parent.refresh; \}\
+		 \
+	fontColor_ \{ \cf5 |color|\cf3  fontColor = color ? fontColor; parent.refresh; \}\
+	background_ \{ \cf5 |color|\cf3  background = color; parent.refresh; \}\
+	\
+	value \{ ^pos; \}\
+	string \{ ^pos.asSMPTEString( 1000 ); \}\
+	smpte \{ \cf5 |fps|\cf3  ^\cf2 SMPTE\cf3 ( pos, fps ? 1000 ) \}\
+	\
+	value_ \{ \cf5 |val|\cf3  pos = val ? pos; \}\
+	string_ \{ \cf5 |string|\cf3  pos = string.asSeconds; parent.refresh; \}\
+	smpte_ \{ \cf5 |smpte|\cf3  pos = smpte.asSMPTE.fps_( 1000 ).asSeconds; parent.refresh; \}\
+	\
+	bounds \{ ^view.bounds \}\
+	bounds_ \{ \cf5 |newBounds|\cf3  view.bounds = newBounds ? view.bounds; \}\
+		\
+	\}}
\ No newline at end of file

Modified: wslib/wslib-classes/Main Features/SimpleMIDIFile/SimpleMIDIFile.sc
===================================================================
--- wslib/wslib-classes/Main Features/SimpleMIDIFile/SimpleMIDIFile.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Main Features/SimpleMIDIFile/SimpleMIDIFile.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -477,7 +477,7 @@
 			//	to:		from:
 			
 				int16: (	int8: { |item| item[0..3] ++ [ ( (item[5] * 128) + item[4] ) - (2**13) ]; },
-						float: { |item| item[0..3] ++ [ (item[4] * (2**13)).round(1).asInt ]; } ),
+						float: { |item| item[0..3] ++ [ (item[4] * (2**13)).round(1).asInteger ]; } ),
 						
 				int8: ( 	int16: { |item| var item4;
 							item4 = (item[4] + (2**13)) / 128;

Modified: wslib/wslib-classes/Main Features/SimpleMIDIFile/extSimpleMIDIFile-patterns.sc
===================================================================
--- wslib/wslib-classes/Main Features/SimpleMIDIFile/extSimpleMIDIFile-patterns.sc	2016-12-27 21:37:30 UTC (rev 2832)
+++ wslib/wslib-classes/Main Features/SimpleMIDIFile/extSimpleMIDIFile-patterns.sc	2021-01-18 15:48:15 UTC (rev 2833)
@@ -1,285 +1,295 @@
-+ SimpleMIDIFile {
-	
-	p { |inst, amp = 0.2, useTempo = true| // amp: amp when velo == 127
-		var thisFile;
-		inst = ( inst ? 'default' ).asCollection;
-		
-		// todo: create multi-note events from chords, detect rests
-		
-		if( useTempo ) {
-			if( timeMode == 'seconds' )
-				{ thisFile = this }
-				{ thisFile = this.copy.timeMode_( 'seconds' ); };
-		} {
-			if( timeMode == 'ticks' )
-				{ thisFile = this }
-				{ thisFile = this.copy.timeMode_( 'ticks' ); };
-		};
-		 ^Ppar(
-			({ |tr|
-				var sustainEvents, deltaTimes;
-				sustainEvents = thisFile.noteSustainEvents( nil, tr );
-				if( sustainEvents.size > 0 )
-					{ 
-					sustainEvents = sustainEvents.flop;
-					if( useTempo ) {
-						deltaTimes = sustainEvents[1].differentiate;
-					} {
-						// always use 120BPM
-						deltaTimes = (sustainEvents[1] / (division*2)).differentiate;
-						sustainEvents[6] = sustainEvents[6] / (division*2);
-					};
-					Pbind(
-						\instrument, inst.wrapAt( tr + 1 ),
-						\dur, Pseq( deltaTimes ++ [0], 1 ),
-						\chan, Pseq( [0] ++ sustainEvents[3], 1 ),
-						\midinote, Pseq( [\rest] ++ sustainEvents[4], 1 ),
-						\amp, Pseq( [0] ++ ( sustainEvents[5] / 127 ) * amp, 1 ),
-						\sustain, Pseq( [0] ++ sustainEvents[6], 1 )
-						)   
-					}
-					{ nil }
-				}!this.tracks).select({ |item| item.notNil })
-			);
-		}
-	
-	play { |clock, protoEvent, quant, inst,  amp = 0.2|  
-			^this.p( inst, amp ).play( clock, protoEvent, quant );
-	}
-		
-	*fromPattern { |pattern, maxEvents = 1000, maxAmp = 0.2, startTime = 0, 
-			inTracks = 2, inTempo = 120, timeSignature|
-		var mf;
-		mf = this.new( "~/Desktop/fromPattern.mid" ).init1( inTracks, inTempo, timeSignature );
-		^mf.fromPattern( pattern, maxEvents, maxAmp, startTime );
-	}
-		
-	fromPattern {	|pattern, maxEvents = 1000, maxAmp = 0.2, startTime = 0|
-		var stream, time, count = 0, event, tmode;
-		var defaultEvent, instruments = [];
-		
-		// todo: add key information
-		
-		time = startTime ? 0;
-		if( this.timeMode != \seconds ) 
-			{ tmode = this.timeMode; 
-			  this.timeMode = \seconds; };
-		
-		stream = pattern.asStream;
-		
-		defaultEvent = Event.default;
-		defaultEvent[ \velocity ] = { ~amp.value.linlin(0,maxAmp,1,127,\minmax) };
-		defaultEvent[ \midinote2 ] = { 
-				if( ~freq.isFunction.not )
-					{ ~freq.cpsmidi } 
-					{ ~midinote.value } 
-			};
-		
-		if( format > 0 )
-			{
-			defaultEvent[ \track ] = { // auto recognize tracks by instrument

@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.


_______________________________________________
sc-dev mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: https://listarc.bham.ac.uk/marchives/sc-dev/
search: https://listarc.bham.ac.uk/lists/sc-dev/search/