<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet href="_c74_vig.xsl" type="text/xsl"?>
<vignette name="The Patcher Object" package="Max">
<h1>The Patcher Object</h1>
<p>
The Patcher object is a Javascript representation of a Max patcher. You can find, create, modify, and iterate through objects within a patcher, send messages to a patcher that you would use with the thispatcher object, etc.
</p>
<p>
There are currently three ways to get a Patcher:
</p>
<ul>
<li>
Use the Constructor
</li><li>
Access the patcher property of a <b>jsthis</b> (accessed as this.patcher)
</li><li>
Use the subpatcher() method of a Maxobj object
</li></ul>
<h2>Patcher Constructor</h2>
<code language="javascript">
  var p = new Patcher(left,top,bottom,right);
</code>
<p>
left, top, bottom, right: global screen coordinates of the Patcher window
</p>
<code language="javascript">
  var p = new Patcher();
</code>
<p>
Uses 100,100,400,400 as default window coordinates
</p>
<jsproperty_list name="Patcher">
	<jsproperty name="box" get="1" set="0" type="Maxobj">
		<description>
			If the patcher is a subpatcher, the box property returns the Maxobj that contains it. To traverse up to the top-level patcher:
			<code language="javascript">
				var prev = 0;
				var owner = this.patcher.box;
				while (owner) {
					prev = owner;
					owner = owner.patcher.box;
				}
				if (prev)
				post("top patcher is",prev.patcher.name);
			</code>
    	</description>
	</jsproperty>

	<jsproperty name="count" get="1" set="0" type="Number">
		<description>
			Number of objects in the patcher
    	</description>
	</jsproperty>

	<jsproperty name="filepath" get="1" set="0" type="String">
		<description>
			The patcher’s file path on disk
    	</description>
	</jsproperty>

	<jsproperty name="firstobject" get="1" set="0" type="Maxobj">
		<description>
			If the patcher contains objects, this is the first one in its list. You can iterate through all objects in a patcher using the nextobject property of a Maxobj.
    	</description>
	</jsproperty>

	<jsproperty name="name" get="1" set="1" type="String">
		<description>
			The patcher's name (its window title, without any brackets that appear for subpatchers)
    	</description>
	</jsproperty>

	<jsproperty name="locked" get="1" set="1" type="Boolean">
		<description>
			The patcher's locked state. This property is read-only in the runtime version of Max.
    	</description>
	</jsproperty>

	<jsproperty name="maxclass" get="1" set="0" type="String">
		<description>
			Returns “patcher”
    	</description>
	</jsproperty>

	<jsproperty name="parentclass" get="1" set="0" type="String">
		<description>
			Returns the Max class name of the parent object if this is a subpatcher, or a nil value if this is a top-level patcher.
    	</description>
	</jsproperty>

	<jsproperty name="parentpatcher" get="1" set="0" type="Patcher">
		<description>
			If the patcher is a subpatcher, this returns the parent patcher. Otherwise it returns a nil value.
    	</description>
	</jsproperty>

	<jsproperty name="scrolloffset" get="1" set="1" type="Array">
		<description>
			X/Y coordinate array for the scroll offset of a patcher is window
    	</description>
	</jsproperty>

	<jsproperty name="scrollorigin" get="1" set="1" type="Array">
		<description>
			X/Y coordinate array for the patcher's fixed origin
    	</description>
	</jsproperty>
	<jsproperty name="wind" get="1" set="0" type="Object">
		<description>
			A Javascript representation of the window associated with the patcher. For more information, see <link type="vignette" module="js" name="jswindobj">the Wind Object</link>.
    	</description>
	</jsproperty>
</jsproperty_list>

<h2>Patcher Methods Overview</h2>
<p>
Any message to a patcher that you can send in Max (via the thispatcher object) you can send in Javascript in js.
</p>
<p>
Examples:
</p>
<code language="javascript">
  p = this.patcher;
  p.fullscreen(1);  // makes the patcher take up the whole screen
  p.dirty();    // make an editable patcher dirty
</code>
<p>
The Patcher methods listed below present a slighly more usable implementation of patcher scripting. You can still script a patcher using the script message, since, as shown above, a Javascript Patcher object can accept any message you can send to a thispatcher object.
</p>
	<jsmethod_list name="Patcher">
	  	<jsmethod name="newobject">
		    <arglist>
		    	<arg name="classname" type="String" />
		    	<arg name="params" type="Anything"/>
		    </arglist>
		    <description>
				Creates a new object of Max class classname in a patcher using the specified parameters and returns a Maxobj (see below) that represents it.
				<p>
					<b>Example:</b>
				</p>
				<code language="javascript">
					a = patcher.newobject("toggle",122,90,15,0);
				</code>
			</description>
	  	</jsmethod>

  		<jsmethod name="newdefault">
		    <arglist>
		    	<arg name="left" type="Number"/>
		    	<arg name="top" type="Number"/>
		    	<arg name="classname" type="String"/>
		    	<arg name="arguments" type="Anything"/>
		    </arglist>
		    <description>
		    	Creates a new object of class classname in a patcher using the specified parameters and return a Maxobj (see below) that represents it.
		    	<p>
					<b>Example:</b>
				</p>
				<code language="javascript">
					a = patcher.newdefault(122,90,"toggle");
				</code>
				<p>
					The newdefault() method also accepts additional arguments for non-user interface objects that represent the created object’s typed-in arguments.
				</p>
				<p>
					<b>Example:</b>
				</p>
				<code language="javascript">
					a = patcher.newdefault(122,90,"pack", "rgb", 255, 128, 64);
				</code>
		    </description>
  		</jsmethod>

  		<jsmethod name="connect">
		    <arglist>
		    	<arg name="from-object" type="String"/>
		    	<arg name="outlet" type="Number"/>
		    	<arg name="to-object" type="String"/>
		    	<arg name="inlet" type="Number"/>
		    </arglist>
		    <description>
		    	Connects two objects (of type Maxobj) in a patcher. Indices for the outlet and inlet arguments start at 0 for the leftmost inlet or outlet.
		    	<p>
					<b>Example:</b>
				</p>
				<code language="javascript">
				  p = this.patcher;
				  a = p.newobject("toggle",122,90,15,0);
				  b = p.newobject("toggle",122,140,15,0);
				  p.connect(a,0,b,0);
				</code>
		    </description>
  		</jsmethod>

  		<jsmethod name="hiddenconnect">
		    <arglist>
		    	<arg name="from-object" type="String"/>
		    	<arg name="outlet" type="Number"/>
		    	<arg name="to-object" type="String"/>
		    	<arg name="inlet" type="Number"/>
		    </arglist>
		    <description>
		    	Connects two objects (of type Maxobj) in a patcher with a hidden patch cord. Arguments are the same as for the connect message above.
		    </description>
  		</jsmethod>

  		<jsmethod name="disconnect">
		    <arglist>
		    	<arg name="from-object" type="String"/>
		    	<arg name="outlet" type="Number"/>
		    	<arg name="to-object" type="String"/>
		    	<arg name="inlet" type="Number"/>
		    </arglist>
		    <description>
		    	Disconnects an existing connection between two objects (of type Maxobj) in a patcher. Indices for the outlet and inlet arguments start at 0 for the leftmost inlet or outlet.
		    	<p>
					<b>Example:</b> (assuming the connect() example above):
				</p>
				<code language="javascript">
				  p.disconnect(a,0,b,0);
				</code>
		    </description>
  		</jsmethod>

  		<jsmethod name="apply">
		    <arglist>
		    	<arg name="function" type="String"/>
		    </arglist>
		    <description>
		    	For all objects in a patcher, calls the function with the each object's Maxobj as an argument. Does not recurse into subpatchers. The following example prints the name of each object's class in the Max window:
		    	<code language="javascript">
				  function printobj(a)
				  {
				    post(a.maxclass);
				    post();
				    return true;
				  // iterfun must return true to continue
				  // iterating, else stops
				  }
				  this.patcher.apply(printobj);
				</code>
		    </description>
  		</jsmethod>

  		<jsmethod name="applydeep">
		    <arglist>
		    	<arg name="function" type="String"/>
		    </arglist>
		    <description>
		    	Same as apply() except that applydeep() recurses into subpatchers (depth first).
		    </description>
  		</jsmethod>

  		<jsmethod name="applyif">
		    <arglist>
		    	<arg name="action_function" type="String" />
		    	<arg name="test_function" type="String"/>
		    </arglist>
		    <description>
		    	For all objects in a patcher, run the test_function for each object's Maxobj as an argument. If the test_function returns true, the action_function is executed with the Maxobj as an argument.
		    </description>
  		</jsmethod>

  		<jsmethod name="applydeepif">
		    <arglist>
		    	<arg name="action_function" type="String" />
		    	<arg name="test_function" type="String"/>
		    </arglist>
		    <description>
		    	Same as applyif() except that applydeepif() recurses into subpatchers
		    </description>
  		</jsmethod>

  		<jsmethod name="remove">
		    <arglist>
		    	<arg name="object" type="String"/>
		    </arglist>
		    <description>
		    	Removes the object (a Maxobj passed as an argument) from a patcher
		    </description>
  		</jsmethod>

  		<jsmethod name="getnamed">
		    <arglist>
		    	<arg name="name" type="String"/>
		    </arglist>
		    <description>
		    	Returns the first object found in a patcher with the given name. The name is a local name as specified by the Name... dialog in a patcher, not the name of a send or <o>receive</o> object. You can also set an object's name using the varname property of a Maxobj.
		    </description>
  		</jsmethod>

  		<jsmethod name="getlogical">
		    <arglist>
		    	<arg name="function" type="String"/>
		    </arglist>
		    <description>
		    	Calls the function on each object in a patcher, passing it as a Maxobj argument to the function. If the function returns true, the iteration stops and the Maxobj object is returned as the value of the getlogical() method. Otherwise getlogical() returns a nil value. Please note that access to patcher attributes in global code is not supported. This requires the use of <b>loadbang()</b>.
		    	<p>
					<b>Example:</b>
				</p>
				<code language="javascript">
				// post the patching rectangle and Max class of each object in the current patch
					function logical(a)
					{
						if(a)
							return 1;
						else
							return 0;
					}

					function loadbang()
					{
						e = patcher.getlogical(logical); //uses the return value as an array
						if (e &amp;&amp; e.length) {
							for (var i=0;i &lt; e.length;i++) {
								post(e[i].maxclass+": "+e[i].rect+"\n");
							}
						}
					}

					function bang()
					{
						loadbang();
					}
				</code>
		    </description>
  		</jsmethod>

  		<jsmethod name="bringtofront">
		    <arglist>
		    	<arg name="object" type="String"/>
		    </arglist>
		    <description>
		    	Moves the object to the front of the current layer to which it is assigned (either background or foreground). You can change the layer by setting the background property of a Maxobj.
		    </description>
  		</jsmethod>

  		<jsmethod name="sendtoback">
		    <arglist>
		    	<arg name="object" type="String"/>
		    </arglist>
		    <description>
		    	Moves the object to the back of the current layer to which it is assigned (either background or foreground). You can change the layer by setting the background property of a Maxobj.
		    </description>
  		</jsmethod>
	</jsmethod_list>
</vignette>
