<?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" rankfactor="2">
  <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;
				  }
				  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 name="getattrnames">
      <arglist />
      <description>
          Returns an Array value containing the names of available attributes for the Patcher.
      </description>
    </jsmethod>
    <jsmethod name="getattr">
      <arglist>
        <arg name="attribute_name" type="string"/>
      </arglist>
      <description>
          Returns the value of the Patcher attribute specified by <m>attribute_name</m>. Lists are returned as JS Array objects.
      </description>
    </jsmethod>
    <jsmethod name="setattr">
      <arglist>
        <arg name="attribute_name" type="string"/>
        <arg name="anything" type="string"/>
      </arglist>
      <description>
          Sets the value of the Patcher attribute specified by <m>attribute_name</m>.
      </description>
    </jsmethod>
  </jsmethod_list>
</vignette>
