reference updates
[org.ibex.core.git] / doc / reference / reference.xml
index 28f8a34..37148d6 100644 (file)
-<ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org">
+<ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org" logo="ibex-logo.pdf">
 
 <!-- ----------------------------------------------------------------------- -->
 <section title="Introduction">
 
-    **
-    If you are reading the html version of this document and are
-    thinking of printing it out, you might be interested in the nicely
-    typeset <link url="reference.pdf" text="pdf version"/> produced
-    with LaTeX.
-    **
+    
+    ** If you are reading the html version of this document and are       **
+    ** thinking of printing it out, you might be interested in the nicely **
+    ** typeset <link url="reference.pdf" text="pdf version"/> produced    **
+    ** with LaTeX.                                                        ** 
+
+  Ibex is a software platform based on the philosophy that the most
+  useful systems consist of both **statically typed** and
+  **dynamically typed** languages, working in concert.
+
+  <list>
+
+      - Statically typed languages (such as Java) are well suited for
+        high-performance, reliable, reusable code.  Unfortunately
+        programs written in statically typed languages often take
+        longer to develop, and their commitment to a specific type
+        system makes interoperating with other languages cumbersome.
 
-    This document is a __reference__. It is not a
-    __specification__ or a
-    __tutorial__.
+      - Dynamically typed languages (such as JavaScript) typically
+        perform poorly (due to runtime checks and inadequate static
+        information for optimization), tend to admit more errors (due
+        to less static checking), and export APIs which are not
+        precisely defined (due to the huge number of possible
+        type/method combinations).  However, writing programs in
+        dynamically typed languages is a much more rapid process, and
+        the implicit coercions in such languages make interoperability
+        between similar languages very easy.
+
+   </list>
     
-    This document does not guide the user gently through examples (as a
-    tutorial would), and it doesn't provide enough detail and formality
-    for a third party to construct a compatible re-implementation of the
-    Ibex Core (as a specification would).
+   The architectural incarnation of this philosophy is the Ibex Object
+   Model, a universal interface to dynamically typed languages.  The
+   IOM serves as a common interface between statically typed languages
+   and dynamically typed languages both locally and over the network.
+
+   <section title="The Ibex Object Model">
+
+      The Ibex Object Model consists of three primitive types:
     
-    Rather, the goal of this document is to completely describe every
-    aspect of the environment that the Ibex Core provides to client
-    applications, from the bottom up. If you want to be an Ibex expert,
-    this is the right document to read. It is assumed that you are already
-    familiar with XML and with either JavaScript or ECMAscript.
+      <list>
+          - __number__  -- a floating point number
+          - __string__  -- a unicode string
+          - __boolean__ -- either [[true]] or [[false]]
+      </list>
+    
+      From these primitives, more complex structures can be built from
+      two aggregate types:
     
-    If you need to use or rely on some behavior you notice in the Ibex
-    Core, but which is not clearly defined here, please post to <link
-    url="http://lists.ibex.org/listinfo/users" text="the users mailing list"/>.
+      <list>
+          - __array__   -- a collection of objects indexed by a non-negative integer
+          - __hash__    -- a collection of objects indexed by objects (often strings)
+      </list>
+    
+      Any of the following actions can be performed on an object:
+    
+      <list>
+          - __get(key)__ -- attempts to retrieve the object indexed by
+            [[key]].  Returns an object.
     
+          - __put(key, val)__ -- attempts to add object [[val]] with key
+            [[key]] to an object.  Does not return a value.
+    
+          - __call(args)__ -- attempts to call the object as if it were a
+            function.  The [[args]] value is a list of arguments.  May or
+            may not return a value.
+      </list>
+    
+      The keys of some objects may be enumerated by attempting to "call"
+      the object; the return value will be an array of the object's keys.
+
+      Finally, an object may be **coerced** to any of the three
+      primitive types, although this coercion may fail.  Objects may
+      also be coerced to the **bytestream** type, which represents an
+      unbounded stream of octets.  Dynamically typed code may not
+      explicitly manipulate bytestreams, although it can pass objects
+      to statically typed code which in turn coerces those objects to
+      bytestreams.
+    
+      Any of the above operations may **throw** an exception, which is
+      itself an object.
+
+      Any entity in the statically typed world which supports these
+      operations may expose itself to the dynamically typed world.
+      Furthermore, it can expect that any values passed to it will support
+      all of the operations shown above.
+    </section>
+
+    <section title="Namespaces">
+        - relation to XML
+        - cover templates here with David's isomorphism?
+    </section>
+
+    <section title="Platforms Founded on the Ibex Object Model">
+
+       The remainder of this document describes the three major
+       systems founded on the Ibex Object Model:
+
+       <list>
+           - The Ibex User Interface
+           - The Ibex Persistent Storage Service
+           - The Ibex Mail Server
+           - IbexDoc
+       </list>
+
+       Currently, all four of these systems use Java as the statically
+       typed language and IbexScript (a derivitave of JavaScript) as
+       the dynamically typed language.  However, since they interact
+       strictly via the Ibex Object Model, either component can be
+       rewritten in a different language.
+
+    </section>
+  
   <section title="Key Concepts">
   
     <definition term="The Core">
         </definition>
 
   </section>
+</section>
 
+<section title="The Ibex User Interface">
   <section title="Life Cycle of an Ibex Application">
   
     <image url="lifecycle.pdf" caption="The Lifecycle of an Ibex Application"/>
 
     A user typically begins an Ibex session by clicking on a link to
-    an Ibex application.  This link serves the {\tt launch.html} file
-    to the user's browser, which in turn downloads the appropriate
-    {\it Wildebeest} -- currently either an ActiveX Control
+    an Ibex application.  This link serves the [[launch.html]] file
+    to the user's browser (1), which in turn downloads the appropriate
+    **Wildebeest** (2)-- currently either an ActiveX Control
     (Win32/MSIE), XPInstaller (Mozilla), or Signed Applet (all
     others).
 
     The Wildebeest downloads the appropriate core for the user's
-    machine and verifies its digital signature.  It then launches the
-    core, which downloads the UI (an [[.ibex]] archive), loads it,
-    applies the [[main.t]] template (found in the archive), and
-    renders it onto the screen, running any associated JavaScript
-    code.
+    machine and verifies its digital signature (3).  It then launches
+    the core, which downloads the UI (4), (an [[.ibex]] archive),
+    loads it, applies the [[main.t]] template (found in the archive),
+    and renders it onto the screen, running any associated JavaScript
+    code (5).
       
     The user interacts with the application by clicking and moving the
-    mouse, and by pressing keys on the keyboard.  These actions trigger
-    fragments of JavaScript code which are designated to handle events.
-    This JavaScript code can then relay important information back to the
-    server using XML-RPC or SOAP, or it can modify the structure and
-    properties of the user interface to change its appearance, thereby
-    giving feedback to the user.
+    mouse, and by pressing keys on the keyboard (5).  These actions
+    trigger fragments of JavaScript code which are designated to
+    handle events.  This JavaScript code can then relay important
+    information back to the server using XML-RPC or SOAP (5), or it
+    can modify the structure and properties of the user interface to
+    change its appearance, thereby giving feedback to the user.
       
     The Ibex core quits when the last remaining surface has been destroyed.
 
     of Ibex.
       
   </section>
-</section>
   
 <section title="The XML Template Representation">
 
   A template (discussed in the next section) is an XML file which acts
   as a blueprint for constructing a tree of boxes.  We call this
-  construction process **applying**, since unlike
-  **instantiation** in object-oriented programming systems, you
-  always apply a template to a pre-existing box, and you can apply
-  multiple templates to the same box.
+  construction process **applying**, since unlike **instantiation** in
+  object-oriented programming systems, you always apply a template to
+  a pre-existing box, and you can apply multiple templates to the same
+  box.
 
   Each XML tag corresponds to a single box, or to another template
   which will be applied to that box.  For example, a [[scrollbar]]
 </section>
 
 <!-- ----------------------------------------------------------------------- -->
-<section title="Layout and Rendering">
-
-      Each box occupies a rectangular region on the surface.  The visual
-      appearance of a surface is created by rendering each box in its tree.
-      Unless the [[clip]] attribute is [[false]], each box will
-      clip its childrens' visual representations to its own, so that the
-      children appear "confined to" the parent.  Children are rendered after
-      their parents so they appear "on top of" their parents.
-      
-      Each box has two major visual components, each with subcomponents:
+<section title="Rendering">
+
+      FIXME: needs way, way, way more diagrams of nonrectangular boxes.
+
+      Each box occupies a region on the surface.  The visual
+      appearance of a surface is created by rendering each box in its
+      tree.  Unless the [[clip]] attribute is [[false]], each box will
+      clip its childrens' visual representations to its own, so that
+      the children appear "confined to" the parent.  Children are
+      rendered after their parents so they appear "on top of" their
+      parents.
       
-      FIXME: diagram
+      <heading title="Boxes Don't Have to Be Rectangular"/>
+
+      Until now we've tactily assumed that boxes are rectangular.  In
+      fact, unlike its predecessor (XWT), Ibex boxes can be **any
+      shape at all**.  We refer to the outline of a box as its path,
+      which may be composed of lines and curves (arcs and splines).
+      If the path is not set (or set to [[null]]), the box's path is
+      **implicitly** a rectangle.
+
+      A key step in understanding how Ibex works, and understanding
+      how operations on rectangular boxes generalize to arbitrary
+      boxes is to realize that "the path **is** the box".  Just as a
+      rectangular box clips its children to the inside of the
+      rectangle, a circular box will clip its children to the inside
+      of the circle.
+
+      In fact, Ibex's integration of vector graphics with
+      constraint-based user interface layout runs quite deep -- boxes
+      which "contain" text are actually boxes whose outline path
+      **is** the actual letters of the text.  This means that you can
+      assign children to a text-shaped box, and the children's
+      appearance will be cliped to the **inside** of the text letters.
+
+      The only time rectangular and non-rectangular boxes act
+      differently is when box packing takes place; when packing boxes,
+      Ibex only looks at the **bounding box** of a path (the smallest
+      rectangle that completely encloses the box's path).  In the case
+      of rectangular boxes (which have not been rotated or sheared),
+      this bounding box happens to be exactly the same as the box's
+      path.  So Ibex is actually treating these boxes the same, but
+      the chosen treatment favors rectangular boxes.
+
+      <section title="Visual Elements">
+
+      The appearance of a box consists of three visual elements: its
+      path, stroke, and fill.
       
-      <definition term="path">
-  
-          A box's [[path]] consists of zero or more lines and curves.
-          The path may be filled with a color, gradient, or texture, and
-          may be stroked with a line of a given thickness and color.  If
-          the path is not specified, it defaults to the perimiter of the
-          box.  [**Note: Vector Graphics support (including the ability
-          to set the [[path]] property to anything other than the
-          default) is currently not implemented**].
-  
-          A path also has:
-  
-          <list>
-              an associated [[strokecolor]], which is a color
-  
-              an associated [[strokewidth]], which is a number
-              specifying the width of the stroke.  [**Note: Vector
-              Graphics support (including the [[strokewidth]]
-              property) is currently not implemented**]
-              
-              a [[fill]], which is either a color, gradient, or
-              texture
-          </list>        
-          </definition>
-  
-      <definition term="text">
-  
-          Each box also has a single line of [[text]], whose
-          appearance is determined by its:
-  
-          <list>
-              associated [[font]], which can be any font supported by
-              the <link url="http://www.freetype.org" text="FreeType2"/>
-              library.
-              
-              an associated [[fontsize]] in **pixels**
-              
-              an associated [[textcolor]]
-          </list>
-          </definition>
+      <property name="path" type="string" default='""'>
+          A box's [[path]] consists of zero or more contours, each of
+          which consists of one or more lines, bezier curves (cubic or
+          quadradic), or generalized elliptic arcs.  The grammar and
+          feature set supported are identical to that specified in <link
+          url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
+          section 8"/>.
+
+    One of the most common sources of frustration when working with
+    text representations of vector paths, or programs that manipulate
+    them, is making a mistake when setting a transform which causes
+    the entire path to be off the screen.  Since no part of the path
+    is visible, you have no idea which direction it went! To minimize
+    the chance of this happening, and generally make dealing with
+    vectors a more enjoyable experience, Ibex always **recenters** a
+    path.  When you set a box's path (either by writing to its
+    [[path]] or [[text]] properties), Ibex translates the entire path
+    so that it is lined up with the X and Y axes, as close to the
+    origin as possible, in the positive-X, positive-Y quadrant.  Ibex
+    will note this translation by setting the box's [[transform]] to
+    the transformation used to do this.  If you do not desire this
+    behavior, just set the [[transform]] back to the identity
+    transform.
+         </property>
+    
+    <property name="stroke" type="string" default="clear">
+          The color with which to stroke the path.  Ibex paths may
+          only be stroked with a single color, solid line (not
+          dashed), of "hairline width" (meaning that the line is never more than one
+          antialiased pixel wide no matter what magnification it is
+          viewed at).
+
+          This property can be set to a 5-character hex string
+          ([[#RGB]]), 7-character hex string ([[#RRGGBB]]),
+          9-character hex string ([[#AARRGGBB]]), specifying the box's
+          hexadecimal color.  Any other string is compared against the
+          <link url="http://www.color.org/ICC-1A_1999-04.PDF"
+          text="ICC"/> colors (the same set of color names supported
+          by SVG).  If this property is set to [[null]], the stroke
+          color will be set to clear ([[#00000000]]).
+
+          Other vector formats (notably SVG and PDF) support "thick"
+          lines, dashed lines, lines stroked with a gradient or
+          texture, and an assortment of special caps and joins for
+          these thick lines (hairline lines do not need joins or
+          caps).  Fortunately, all of these constructs can be
+          converted into **filled** paths rather easily, making it
+          possible for Ibex to support the same functionality with a
+          much simpler API (and more efficient rendering engine).
+          </property>
+    
+      <property name="fill">
+          The graphic element with which to fill the path.  This
+          property can be set to any of the values specified for
+          [[stroke]], as well as to a texture (an image) or a
+          gradient.  Paths which self-intersect are filled according
+          to the SVG guidelines.
+
+          When an image (texture) is written to this property, the
+          box's [[minwidth]] and [[minheight]] properties will be
+          automatically set to the dimensions of the image (they can
+          be changed later if desired).
+          </property>
+      </section>   
+
+      <section title="Text">
+
+      Ibex treats text exactly the same way it treats other paths.
+      Writing to the [[text]] property actually sets the box's path to
+      the outline of the rendered form of the text, and text is
+      subject to the same rotation, shearing, and scaling
+      transformations as all other boxes.  You can even **read back**
+      the curves from which the text is composed by reading from the
+      [[path]] property (the string returned will be in SVG Path
+      syntax), modify it, and write it to the [[path]] property of
+      another box.
+
+    <property name="text" type="string" default='""'>
+      The box's text; writing [[null]] to this property sets it to
+      [[""]].  In order to help eliminate common chores when working
+      with text, Ibex will automatically take the following actions
+      when you write to the [[text]] property:
+      </property>
+
+      <list>
+          The text is converted to curves using the Freetype library,
+          and the resulting curve becomes the box's path.
+
+          If the box's [[strokecolor]] is [[null]], it is set to black
+          ([[#FF000000]]).  When first created, a box has an invisible
+          stroke; automatically setting the stroke to a visible color
+          helps eliminate confusing errors.  You can change the stroke
+          color back to clear after writing to the [[text]] property.
+
+          The box's [[aspect]] property is automatically set to the
+          correct aspect ratio for the chosen string in the chosen
+          font.  This ensures that resizing will not warp the text.
+      </list>
+    
+    <property name="font" type="stream" default=".ibex.ui.font.sansserif">
+        Fonts are rendered using the [[stroke]] assigned to the box,
+        using the font assigned to the [[font]] property.  When an
+        object is written to this property, it is coerced to a stream which is interpreted using
+        the <link url="http://www.freetype.org" text="FreeType 2
+        library"/>, and the resulting font is used to render the box's
+        [[text]].
+
+        To choose the size of a font, just set the box's [[height]]
+        property to the desired height **in pixels**.  Conversion
+        functions from points to pixels are available.
+        </property>
+     </section>
+
+     <section title="Transformations">
+      The [[transform]] property allows the user to specify an
+      arbitrary affine transformation to be applied to the box's path,
+      text, and children.  The syntax and features supported are
+      identical to those described in <link
+      url="http://www.w3.org/TR/SVG11/coords.html" text="SVG 1.1,
+      section 7"/>, and include rotation, shearing, scaling, and
+      translation.
+
+      <property name="transform">
+          FIXME
+      </property>
+
+      One tricky part about transformations is their interaction with
+      box packing and dimension properties.  A box's size properties
+      (such as [[minwidth]] or [[height]]) are **always** measured in
+      the box's own coordinate space (ie after applying the box's
+      [[transform]]).  This means that the sum of the [[width]]s of a
+      box's children may not be equal to the parent box's [[width]],
+      even if the children appear (on screen) to completely fill its
+      width.
+
+      One other consequence of combining transformations with
+      constraint-based layout is that when a box is rotated, its width
+      and height are no longer completely independent (remember, the
+      box's width is measured in the rotated coordinate space).  If a
+      box is turned at a 45 degree angle and then forced into a space
+      10 pixels wide, enlarging the box's width will force a reduction
+      in its height (in order to cram it in the 10 pixel space).  In
+      situations like this, Ibex will first look to the box's
+      [[aspect]], if explicitly set, and obey that.  If the box's
+      [[aspect]] is unspecified, Ibex will use the ratio between the
+      box's [[minwidth]] and [[minheight]] to guide the tradeoff.  If
+      either of these properties is [[0]], Ibex will simply attempt to
+      make the ratio as close to [[1:1]] as possible.
+
+      When we talk about a box's **bounding box**, we are referring to
+      the smallest rectangle in the **parent's** coordinate space
+      which completely encloses the child box's path.  This is the
+      only time we will deal with the size of a child using a
+      coordinate space other than its own.
+    </section>
+
+  <section title="Layout Properties">
+
+    We will cover the layout algorithm in detail in the next section,
+    but we introduce the properties at play here and give an intuition
+    about their purpose.
+    
+    <property name="packed" type="boolean" default="true">
+        The layout strategy for this box.  If set to [[true]], the
+        box occupies no cells and is laid out independently of its
+        siblings.
+        </property>
+    
+    <property name="zoom" type="boolean" default="false">
+        This property controls the strategy Ibex uses for changing the
+        box's width and height in response to layout constraints.
+
+        If [[zoom]] is set to [[false]] (the default), then the box's
+        [[path]] will be altered by multiplying all the vertices by a
+        scaling factor in order to make the path's bounding box meet
+        the required constraints.  The box's [[transform]] will not be
+        affected, and the scaling of the box's children will not be
+        affected.
+
+        If [[zoom]] is set to [[true]], the box's [[path]] will not be
+        altered in response to layout constraints; rather, its
+        [[transform]] will be altered in order to "zoom in" or "zoom
+        out" and bring all of the path's vertices within the desired
+        region.  Since the box's [[transform]] also applies to its
+        descendants, they too will be magnified or reduced.
+        </property>
+    
+    <property name="shrink" type="boolean" default="false">
+        If set to [[true]], this box will shrink
+        (horizontally/vertically/both) to the smallest size allowed by
+        its children and the bounding box of its path.
+        </property>
+    
+    <property name="x y" type="integer" default="varies">
+        If the box is a root box, writing to these properties moves
+        the surface; reading from them returns the position of the
+        surface.
+
+        On non-root boxes, writing to these properties is a shorthand
+        for adding a [["translate(x, y)"]] to the box's [[transform]].
+        Reading from these properties will return FIXME.
+        </property>
+    
+    <property name="minwidth minheight" type="integer" default="0">
+        The desired minimum width and height.  See the [[zoom]]
+        property for a description of how the box is altered to meet
+        these constraints.
+        </property>
+    
+    <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
+        The desired maximum width and height.  See the [[zoom]]
+        property for a description of how the box is altered to meet
+        these constraints.
+        </property>
+    
+    <property name="width height" type="integer">
+        When read, this is the current (width/height) of this box.
+        Writing to this property is equivalent to writing to
+        **both** the minimum and maximum (width/height).
+        </property>
+    
+    <property name="cols rows" type="integer" default="0">
+        The number of (columns/rows) in which to lay out the children of this
+        box.  If set to zero, the number of (columns/rows) is unconstrained.
+        Either [[rows]] or [[cols]] must be zero.  If
+        [[0]] is written to [[cols]] when [[rows]] is
+        [[0]], the write is ignored.  If a nonzero value is
+        written to [[cols]] when [[rows]] is nonzero,
+        [[rows]] is set to [[0]], and vice versa.
+        </property>
+    
+    <property name="colspan rowspan" type="integer" default="1">
+        The number of (columns/rows) that this box spans within its parent.
+        </property>
+    
+    <property name="aspect" type="float" default="0.0">
+        The width-to-height ratio constraint for this box; can be set
+        either as a floating point number ([[0.5]]) or a ratio
+        ([["1:2"]]).  Setting this to [[0.0]] disables the ratio
+        constraint.
+
+      Note packed boxes always **shrink** in order to satisfy aspect
+      constraints, while unpacked boxes always **grow** in order to
+      satisfy them -- even if this means growing larger than the box's
+      parent.
+        </property>
+    
+    <property name="visible" type="boolean" default="true">
+        If set to [[false]], this box will be rendered as if its
+        width and height were zero. If this is a root box, the
+        associated surface will be hidden.
+
+        When reading from this property, the value [[false]] will
+        be returned if this box **or any of its ancestors** is not
+        visible.  Thus it is possible to write [[true]] to a box's
+        [[visible]] property and then read back [[false]].
+        </property>
+    </section>
+
+</section>
   
-      These eight components plus the size of a box fully specify its
-      appearance.  Every single box you see in Ibex is drawn only on the
-      basis of these components and its size.
+<section title="Layout Algorithm">
 
       The size and position of every box is determined by its
       properties, its childrens' sizes, and its parent's size and
       not the same thing as the property [[minwidth]], although they
       are closely related.
       
-      <heading title="The Size of the Root Box"/>
-  
-      When the user resizes a window, Ibex changes the root box's
-      [[maxwidth]] and [[maxheight]] to match the size chosen by
-      the user and then determines the root box's size using the same sizing
-      rules it uses for other boxes.
-      
-      Ibex will always attempt to prevent the
-      user from making the surface smaller than the root box's
-      [[minwidth]] and [[minheight]].  If the [[hshrink]] or
-      [[vshrink]] flag is set, Ibex will try to prevent the user from
-      resizing the surface at all.  However, not all platforms give Ibex
-      enough control to do this.
-      
-    <heading title="The alignment point"/>
-  
-      When talking about positioning, we will often refer to the
-      **alignment point**.
-      
-          If the [[align]] property is "[[center]]", then the
-          alignment point is the center of the box.
-          
-          If the [[align]] property is "[[topleft]]",
-          "[[bottomleft]]", "[[topright]]", or
-          "[[bottomright]]", then the alignment point is
-          corresponding corner of the box.
-          
-          If the [[align]] property is "[[top]]",
-          "[[bottom]]", "[[right]]", or "[[left]]", then
-          the alignment point is middle of the corresponding edge of the
-          box.
-  
     <section title="Packing">
   
       A grid of **cells** is created within the parent.  If the
       infinite number of columns.  Either [[cols]] or [[rows]]
       must be zero, but not both.
           
-      If a child's [[visible]] property is [[false]], it does
-      not occupy any cells (and is not rendered).  Otherwise, each child
-      occupies a rectangular set of cells [[child.colspan]] cells
-      wide and [[child.rowspan]] cells high.
+      <heading title="Target Regions"/>
+
+      A box's target region is the portion of its parent which the
+      layout algorithm has determined that the box should occupy.  A
+      box's target region is determined mainly by the value of its
+      [[pinned]] property:
+
+      <property name="pinned" type="box" default="null">
+          If a box's [[pinned]] property is [[null]], it is said to be
+          "unpinned" or "not pinned".  In this case, the box's target
+          region will be the set of cells in its parent which it
+          occupies.
+
+          If a box's [[pinned]] region is set to some other box, then
+          this box's target region will be the projection of that
+          other box's actual dimensions and position, projected onto
+          this box's parent.  The net effect is that the pinned box
+          will "track" the size and position of the box it is pinned
+          to.  A box may not be pinned to one of its descendants, nor
+          may boxes be pinned in a cycle (A is pinned to B, B is
+          pinned to C, and C is pinned to A).
+          </property>
+
+      If a child's [[visible]] property is [[false]], it does not
+      occupy any cells (and is not rendered).  If a box's [[pinned]]
+      property (described below) is non-[[null]], it does not occupy
+      any cells and is exempt from the packing process.  Otherwise,
+      each child occupies a rectangular set of cells [[child.colspan]]
+      cells wide and [[child.rowspan]] cells high.
           
       The Core iterates over the cells in the grid in the following
       order: if [[rows]] is 0, the Core iterates across each column
       before proceeding to the next row; otherwise rows come before
       columns.  At each cell, the Core attempts to place the **first
-      remaining unplaced child's** top-left corner in that cell
-      (with the child occupying some set of cells extending down and
-      to the right of that cell).  If the parent has a fixed number of
-      columns and the child's [[colspan]] exceeds that limit, the
-      child is placed in column zero regardless, but only occupies the
-      available set of cells (it does not "hang off the end" of the
-      box).  <image url="layout.pdf" width="1in"/>
+      remaining unplaced, packed child's** top-left corner in that
+      cell (with the child occupying some set of cells extending down
+      and to the right of that cell).  If the parent has a fixed
+      number of columns and the child's [[colspan]] exceeds that
+      limit, the child is placed in column zero regardless, but only
+      occupies the available set of cells (it does not "hang off the
+      end" of the box).  <image url="layout.pdf" width="1in"/>
       
       <pre>
       <ui:box cols="3">
       </section>
   
     <section title="Constraining">
-  
       Each box's minimum width is computed recursively as the
       maximum of:
   
       <list>
           Its [[minwidth]]
                
-          The width of the box's [[text]] (after applying the
-          box's [[transform]]) [**Note: Vector Graphics support
-          (including the [[transform]] property) is currently not
-          implemented**].
+          The width of its [[path]]
                
-          The width of the box's path (after applying the box's
-          [[transform]]) **if the box is [[packed]]**.
-               
-          The minimum width of the children in each row.
+          The sum of the widths of the bounding boxes enclosing its
+          children, when those children are sized to **their own**
+          minimum widths.
+
+          The box's minimum **height** multiplied by its [[aspect]],
+          if its aspect is not [[0]] (unspecified).
       </list>
-          
+
       If a box's [[hshrink]] property is set to
       [[true]], the box's maximum width is the same as its
       minimum width; otherwise it is the box's
       [[maxwidth]].
-
     </section>  
 
     <section title="Placing">
-  
-      <heading title="Non-Packed Boxes"/>
 
-      Each non-packed box is transformed according to the parent's
-      [[transform]] property and then positioned so that its alignment
-      point is [[(child.x, child.y)]] pixels from the corresponding
-      edge/corner/center of its parent.
+      <heading title="Target Origin"/>
+
+      Once the box's size and the size and position of its target
+      region have been computed, the box is placed relative to its
+      **target origin**, which is determined by by the [[origin]]
+      property:
+
+      <property name="origin" type="string" default="center">
+          Determines which corner of the box's target region should be
+          treated as the origin for layout purposes.
+
+          If the [[origin]] property is "[[center]]", then the
+          target origin is at the center of the target region.
+          
+          If the [[origin]] property is "[[topleft]]",
+          "[[bottomleft]]", "[[topright]]", or "[[bottomright]]", then
+          the target origin is at the corresponding corner of the
+          target region.
+          
+          If the [[origin]] property is "[[top]]", "[[bottom]]",
+          "[[right]]", or "[[left]]", then the target origin is middle
+          of the corresponding edge of the target region.
+          </property>
+
+      <property name="x y" type="number" default="0">
+          Determines the offset from the box's origin at which it will
+          be placed.
+          </property>
+
+      If the box's [[hshrink]] property is not set, it is expanded to
+      its maximum width, but no larger than its parent's width.
+
+      Finally, if the child has a nonzero [[aspect]], one of its
+      dimensions (either width or height) will **grow** in order to
+      ensure that [[width == height * aspect]].  This may cause the
+      child to exceed the paren't size.
+
+      <heading title="Non-Packed Boxes with a transform"/>
+
+      First, the coordinate space in which the child is positioned is
+      translated so that the origin coincides with the
+      corner/edge/center of the box's parent corresponding to the
+      child's [[align]] property.  The child's [[transform]] attribute
+      is applied to the coordinate space, and the child is positioned
+      in this transformed space with its aligment point at the origin.
+
+      The following diagram may be helpful:
+
+      FIXME: diagram
 
       <heading title="Packed Boxes"/>
 
+      Thoughout this section, when we refer to the [[minwidth]],
+      [[maxwidth]], or minimum width of a child box, we are referring
+      to the corresponding dimension of the child's **bounding box**
+      -- the smallest rectangle **in the parent's coordinate space**
+      that completely encloses the child's path.
+
       Ibex formulates a set of constraints for placing a box's
       **packed** children as follows:
 
       <list>
-          - A box's width can be no greater than the sum of the
+            A box's width can be no greater than the sum of the
             columns it occupies
-          - The sum of a set of colums cannot be smaller than the
+
+            The sum of a set of colums cannot be smaller than the
             minimum width of a box that spans them.
-          - The sum of the widths of the parents' columns will be at
+
+            The sum of the widths of the parents' columns will be at
             least as large as the parent's width is (but possibly
             larger).
       </list>
       prioritized from most important to least important:
 
       <list>
-          - (__Most Important__) The sum of all columns will be a close
+            (__Most Important__) The sum of all columns will be a close
             to the parent's with as possible (ie as small as possible)
-          - Ibex will attempt to make a set of columns no wider than
+
+            Ibex will attempt to make a set of columns no wider than
             the [[maxwidth]] of a box spanning them.
-          - (__Least Important__) Ibex will attempt to make all
-            columns the same width.
+
+            Ibex will attempt to make all
+            columns the same width. (**least important**)
       </list>
 
       Each packed box is then placed within the set of cells that it
       spans.  Usually the box will exactly fill this rectangle; if it
-      does not (due to [[maxwidth]] or minimum width constraints), the
-      box's will be placed so that its alignment point coincides with
-      the alignment point of that rectangle of cells.
+      does not (due to [[maxwidth]], minimum width, or aspect
+      constraints), the box's will be placed so that its alignment
+      point coincides with the alignment point of that rectangle of
+      cells.
 
+      <heading title="The Size of the Root Box"/>
+  
+      When the user resizes a window, Ibex changes the root box's
+      [[maxwidth]] and [[maxheight]] to match the size chosen by
+      the user and then determines the root box's size using the same sizing
+      rules it uses for other boxes.
+      
+      Ibex will always attempt to prevent the
+      user from making the surface smaller than the root box's
+      [[minwidth]] and [[minheight]].  If the [[hshrink]] or
+      [[vshrink]] flag is set, Ibex will try to prevent the user from
+      resizing the surface at all.  However, not all platforms give Ibex
+      enough control to do this.
+      
   </section>
 
-  <section title="Rendering">
-
-    Boxes are rendered in a depth-first, pre-order traversal.  Note that
-    this may cause a non-packed box to overlap its siblings.
-    
-    <list type="ordered">
-        
-        If the box's [[transform]] property is non-null, the
-        coordinate space is transformed accordingly for the rest of
-        this phase and for the rendering of all children.  [**Note:
-        Vector Graphics support (including the [[transform]]
-        property) is currently not implemented**].
-        
-        If the box is packed and has a non-[[null]] path, the
-        path is translated such that the alignment point of the path's
-        bounding box coincides with the box's alignment point (both
-        alignment points are determined by the box's [[align]]
-        property).
-        
-        If a box has a path, that path is filled with the color,
-        gradient, or image specified by the [[fill]] property and
-        stroked with the color and width specified by the
-        [[strokecolor]] and [[strokewidth]] properties.
-        
-        If the box has a non-null [[text]] attribute,
-        the text is rendered in [[font]] with size
-        [[fontsize]] and color [[textcolor]].  The text is
-        then translated such that the alignment point of the text's
-        bounding box coincides with the box's alignment point (both
-        alignment points are determined by the box's [[align]]
-        property).
-        
-        The box's children are rendered (pre-order traversal).
-
-    </list>
-    
-    </section>
 </section>
 
 <!-- ----------------------------------------------------------------------- -->
   meaning, which will be explained later.  Each box's numeric
   properties hold its **child boxes**.
 
-  <section title="Rendering Properties">
-
-    Every box has several special properties which control how it is
-    drawn. In general, if you put an
-    invalid value to a special property, no action will be taken -- the
-    put will be ignored.
-    
-    <property name="strokecolor" type="string" default="clear">
-
-             If the value is a 5-character hex string ([[#RGB]]),
-             7-character hex string ([[#RRGGBB]]), 9-character hex
-             string ([[#AARRGGBB]]), the box's stroke color will be set
-             to that color. 
-
-             If the value is one of the <link
-             url="http://www.color.org/ICC-1A_1999-04.PDF"
-             text="ICC"/> colors (the same set of color names
-             supported by SVG), the stroke color be set to that color.
-
-             If the value is [[null]], the stroke color will be set
-             to clear ([[#00000000]]).
-             </property>
-    
-    <property name="strokewidth" type="int" default="1">
-             The width (in pixels) to stroke the path with.
-             </property>
-    
-    <property name="fill">
-             This property can be set to any of the values specified for
-             [[strokecolor]].  
-             Alternatively, if the value written is an object, its stream
-             will be read and interpreted as a PNG, GIF, or JPEG image,
-             which will become the texture for this box, and the box's
-             [[minwidth]] and [[minheight]] properties will be
-             automatically set to the dimensions of the image.
-             </property>
-    
-    <property name="path" type="string" default='""'>
-            The box's path.  The grammar and feature set supported are
-            identical to that specified in <link
-            url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
-            section 8"/>.
-            </property>
-    
-    <property name="text" type="string" default='""'>
-            The box's text; writing [[null]] to this property sets it
-            to [[""]].
-            </property>
-    
-    <property name="textcolor" type="number" default="black">
-            The color in which to render the font; accepts the same values as [[strokecolor]].
-            </property>
-
-    <property name="font" type="stream" default=".ibex.ui.font.sansserif">
-            When an object is written to this property, its stream is read
-            using the <link url="http://www.freetype.org" text="FreeType 2 library"/>,
-            and the resulting font is used to render the
-            box's [[text]].
-            </property>
-            
-    <property name="fontsize" type="number" default="10">
-            The size (in points) to render the text.
-            </property>
-    
-    </section>
-
-  <section title="Layout Properties">
-    
-    <property name="shrink" type="boolean" default="false">
-        If set to [[true]], this box will shrink
-        (horizontally/vertically/both) to the smallest size allowed by
-        its children and the bounding box of its path.
-        </property>
-    
-    <property name="x y" type="integer" default="varies">
-        If the box is a root box, this is the (x/y)-coordinate of the
-        surface; otherwise it is the distance between the parent's
-        alignment point and the corresponding corner/edge/center of
-        its parent.
-        </property>
-    
-    <property name="minwidth minheight" type="integer" default="0">
-        The desired minimum width and height.
-        </property>
-    
-    <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
-        The desired maximum width and height.
-        </property>
-    
-    <property name="width height" type="integer">
-        When read, this is the current (width/height) of this box.
-        Writing to this property is equivalent to writing to
-        **both** the minimum and maximum (width/height).
-        </property>
-    
-    <property name="cols rows" type="integer" default="0">
-        The number of (columns/rows) in which to lay out the children of this
-        box.  If set to zero, the number of (columns/rows) is unconstrained.
-        Either [[rows]] or [[cols]] must be zero.  If
-        [[0]] is written to [[cols]] when [[rows]] is
-        [[0]], the write is ignored.  If a nonzero value is
-        written to [[cols]] when [[rows]] is nonzero,
-        [[rows]] is set to [[0]], and vice versa.
-        </property>
-    
-    <property name="colspan rowspan" type="integer" default="1">
-        The number of (columns/rows) that this box spans within its parent.
-        </property>
-    
-    <property name="align" type="string" default="center">
-        Determines the box's alignment point for positioning its text,
-        texture, path, and children.
-        </property>
-    
-    <property name="visible" type="boolean" default="true">
-        If set to [[false]], this box will be rendered as if its
-        width and height were zero. If this is a root box, the
-        associated surface will be hidden.
-
-        When reading from this property, the value [[false]] will
-        be returned if this box **or any of its ancestors** is not
-        visible.  Thus it is possible to write [[true]] to a box's
-        [[visible]] property and then read back [[false]].
-        </property>
-    
-    <property name="packed" type="boolean" default="true">
-        The layout strategy for this box.  If set to [[true]], the
-        box occupies no cells and is laid out independently of its
-        siblings.
-        </property>
-    
-    </section>
-
   <section title="Child Control Properties">
     
     <property name="redirect" type="box" default="thisbox">
     
    
     <property name="surface" type="" default="null">
-        FIXME
         If this box has a parent, this property returns
         [[**parent**.surface]]; otherwise it returns null.
         This property is a simple building block that the widget
         windows.
         </property>
     
-    <property name="Maximized">
+    <property name="Maximized Minimized">
         The value [[true]] is put to this property on the root box
-        when the surface is maximized, and [[false]] when the surface
-        is un-maximized. Reading from this value will return [[true]]
-        if the surface is maximized and [[false]] if it is
-        not. Putting [[true]] to this property will maximize the
-        window, and putting [[false]] to this property will
-        unmaximize the window.
+        when the surface is maximized/minimized, and [[false]] when
+        the surface is un-maximized/minimized. Reading from this value
+        will return [[true]] if the surface is maximized/minimized and
+        [[false]] if it is not. Putting [[true]] to this property will
+        maximize/minimize the window, and putting [[false]] to this
+        property will unmaximize/unminimize the window.
+
         Note that not all platforms support maximization.
         </property>
     
-    <property name="Minimized">
-        The value [[true]] is put to this property on the root box
-        when the surface is minimized, and [[false]] when the surface
-        is unminimized. Reading from this value will return [[true]]
-        if the surface is minimized and [[false]] if it is
-        not. Putting [[true]] to this property will minimize the
-        window, and putting [[false]] will unminimize it.
-        </property>
-    
     <property name="Close">
         When the user attempts to close a surface, the value
         [[true]] will be put to this property. Scripts may trap
         property.
         </property>
     
-    <property name="icon">
-        The surface's icon. This is usually displayed on the titlebar of a
-        window.  The value should be an object whose stream is a PNG image. Note
-        that not all platforms support this property.
+    <property name="titlebar">
+        The surface's titlebar text and icon.  If a string is written
+        to this property, the surface's titlebar text is set to that
+        string; if a stream yielding an image is written, the
+        surface's icon is set to that image.  Note that not all
+        platforms support this property. Only ASCII characters
+        0x20-0x7F are permitted.
         </property>
     
-    <property name="titlebar">
-        The surface's titlebar text. Note that not all platforms support
-        this property. Only ASCII characters 0x20-0x7F are permitted.
+    </section>
+
+  </section>
+
+
+<section title="Events">
+
+    Every execution of the Event Context begins with an event, which
+    consists of a key/value pair, and a mouse position, which consists of
+    an x and y coordinate.  The possible keys are [[_Press[1-3]]],
+    [[_Release[1-3]]], [[_Click[1-3]]], [[_DoubleClick[1-3]]],
+    [[_Move]], [[_KeyPressed]], and [[_KeyReleased]].
+    
+    Here are two example events:
+    
+    An event is triggered by writing the key to the value on a box.  This
+    triggers any trap handlers which may be present.  Once these handlers
+    have executed, Ibex figures out which child of the current box contains
+    the mouse (taking into account that some boxes may cover up others)
+    and writes the key and value to that box.  If none of the box's
+    children contain the mouse position, Ibex removes the leading
+    underscore from the key name and writes the value to
+    **that** property.  Once all the traps on that property have
+    executed, the value is written to the box's parent.
+    
+    Intuitively, Ibex delivers the underscored event to every box from the
+    root to the target, and then delivers the non-underscored event to
+    that same set of boxes in reverse order.  So the event travels down
+    the tree to the target, and then back up to the root.  The following
+    example prints out "first second third fourth" in that order.
+    
+    <pre>
+    <ui:box>
+        _Press1 ++= function(b) { ibex.log.info("first"); }
+         Press1 ++= function(b) { ibex.log.info("fourth"); }
+        <ui:box>
+          _Press1 ++= function(b) { ibex.log.info("second"); }
+           Press1 ++= function(b) { ibex.log.info("third"); }
+        </ui:box>
+    </ui:box>
+    </pre>
+
+    In general, you should use the **non-underscore** names to respond
+    to user input and use the underscored names when you want to override
+    child boxes' behavior or route events to particular boxes (for
+    example, when implementing a focus protocol).  This is why the
+    underscored elements are delivered to parents before children (so
+    parents can override their childrens' behavior), but non-underscored
+    events are delivered to children before parents (since, visually, a
+    mouse click is usually "intended" for the leaf box underneath the
+    cursor).
+    
+  <heading title="Stopping the Process"/>
+
+    At any point in this sequence, a trap handler can choose not to
+    cascade (by returning [[true]] from the trap handler function).
+    This will immediately cease the propagation of the event.  This is how
+    you would indicate that an event has been "handled".
+    
+  <heading title="Non-Propagating Events"/>
+
+    Ibex uses the following events to notify a box about changes that
+    only matter to that particular box.  These events do not propagate
+    either up or down the tree.
+
+    <property name="Enter Leave">
+        The value [[true]] is written to this property when the mouse (enters/leaves) the box.
+        </property>
+    
+    <property name="SizeChange">
+        The value [[true]] is put to this property after the size
+        of this box changes.
+        </property>
+
+    <property name="ChildChange">
+        When a child is added or removed, that child is written to
+        this property.  The write is always performed **after** the
+        addition or removal, so these two cases can be distinguished
+        by checking [[indexof(child)]].
+
+        Note that if the parent's redirect target is set to another
+        box, this trap will only be invoked when children are
+        manipulated by reading and writing to the parent.  Reads and
+        writes directly to the redirect target will **not** trigger
+        this trap.
+
+        Note also that this traps is still triggered if a box's
+        [[redirect]] target is **null**.  This is useful for
+        boxes that need to accept children and then relocate them
+        elsewhere.
+        </property>
+    
+  <section title="Listing of Events">
+    
+    <property name="Press1 Press2 Press3">
+        Indicates that the use has pressed a mouse button.  On
+        platforms with three mouse buttons, the **middle** button
+        is button 3 -- this ensures that applications written to only
+        use two buttons (1 and 2) will work intuitively on three button
+        platforms.
+        </property>
+    
+    <property name="Release1 Release2 Release3">
+        Indicates that the use has released a mouse button.
+        </property>
+    
+    <property name="Click1 Click2 Click3">
+        Indicates that the user has pressed and released the
+        mouse button without moving the mouse much (exactly how
+        much is platform-dependent).
+        </property>
+    
+    <property name="DoubleClick1 DoubleClick2 DoubleClick3">
+        Indicates that the user has clicked the 
+        mouse button twice within a short period of time (exactly how long is platform-dependent).
         </property>
     
+    <property name="Move">
+        Indicates that the mouse has moved while within this box, or that
+        the mouse while outside this box **if a button was pressed while within this box and has not yet been released**
+        </property>
+    
+    <property name="KeyPressed KeyReleased">
+
+        A string is written to this property when a key is pressed or
+        released If the key was any other key, a multi-character
+        string describing the key will be put. For simplicity, we use
+        the VK_ constants in the <link
+        url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
+        text=" Java 1.1 API java.awt.event.KeyEvent class"/>.  When a
+        key is pressed or released, the string put will be the portion
+        of its VK_ constant after the underscore, all in lower case.
+
+        <list>
+        If the shift key was depressed immediately before the
+        event took place, then the string will be capitalized. Special
+        keynames are also capitalized; shift+home is reported as
+        "[[HOME]]".  Symbols are capitalized as they appear on the
+        keyboard; for example, on an American QWERTY keyboard, shift+2
+        is reported as "[[@]]".
+
+        If the alt, meta, or command key was depressed immediately
+        before this key was pressed, then the string will be prefixed
+        with the string "[[A-]]". If the control key was depressed
+        while this key was pressed, then the string will be prefixed
+        with the string "[[C-]]". If both alt and control are
+        depressed, the string is prefixed with "[[C-A-]]".
+
+        Ibex does not distinguish between a key press resulting from
+        the user physically pushing down a key, and a 'key press'
+        resulting from the keyboard's typematic repeat. In the rare
+        case that an application needs to distinguish between these
+        two events, it should watch for KeyReleased messages and
+        maintain an internal key-state vector.
+        </list>
+        </property>
+    </section>
+  <section title="Re-routing events">
+
+    At any point in the Event Context, you can write to the [[mouse]]
+    property on any box.  The value written should be an object with two
+    properties, [[x]] and [[y]].  For example:
+    
+    <pre>
+    _Press1 ++= function(p) {
+        mouse = { x: 32, y: 77 };
+    }
+    </pre>
+
+    The coordinates specified are relative to the box whose [[mouse]]
+    property is being written to.  There is no need to supply the
+    [[inside]] property; it is computed automatically.  Writing to
+    the [[mouse]] property causes Ibex to recompute the eventual
+    target box, and also alter the values returned by [[mouse.x]],
+    [[mouse.y]], and [[mouse.inside]] for any **descendants**
+    of the current box.  Writing to the [[mouse]] property also
+    automatically prevents the event from returning to the box's parents
+    -- it is equivalent to not cascading on the non-underscored event.
+    This ensures that child boxes cannot trick their parent boxes into
+    thinking that the mouse has moved.
+    
+    If you want the event to "skip over" the boxes between the trapee
+    and the target, or if you want to re-route an event to a box which
+    is not a descendant of the current box, simply write the value to
+    the proper key on the target box.
+    
+    <pre>
+    <ui:box>
+        _KeyPressed = function(k) { ibex.log.info("first"); }
+         KeyPressed = function(k) { ibex.log.info("sixth"); }
+        $recipient.target = $target;
+        <ui:box id="recipient">
+            _KeyPressed = function(k) {
+                ibex.log.info("second");
+                thisbox.target.KeyPressed = k;
+                // inhibit cascade; keep event from going to $excluded
+                return true;
+            }
+             KeyPressed = function(k) { ibex.log.info("fifth"); }
+            <ui:box id="excluded">
+                _KeyPressed = function(k) {
+                   ibex.log.info("this never happens");
+                }
+            </ui:box>
+        </ui:box>
+        <ui:box id="target"> 
+            _KeyPressed = function(k) { ibex.log.info("third"); }
+             KeyPressed = function(k) { ibex.log.info("fourth"); }
+        </ui:box>
+    </ui:box>
+    </pre>
+
+    </section>
+
+  <section title="Synthesizing Your Own Events">
+
+    You can create "fake events" by simply writing to the [[mouse]]
+    property and then writing a value to one of the underscored properties
+    on a box.  This will have exactly the same effect as if the use had
+    actually pressed a key, clicked a button, or moved the mouse -- they
+    are indistinguishable.
+    
     </section>
+ </section>
 
-  </section>
+</section>
 
+<section title="Ibex Base Services">
 <!-- ----------------------------------------------------------------------- -->
 <section title="Streams">
     
     </section>
 
 
-<!-- ----------------------------------------------------------------------- -->
-<section title="Threads">
-
   <section title="Contexts">
 
     From the perspective of an application writer, Ibex is strictly
     
     </section>
 </section>
-
-<section title="Events">
-
-    Every execution of the Event Context begins with an event, which
-    consists of a key/value pair, and a mouse position, which consists of
-    an x and y coordinate.  The possible keys are [[_Press[1-3]]],
-    [[_Release[1-3]]], [[_Click[1-3]]], [[_DoubleClick[1-3]]],
-    [[_Move]], [[_KeyPressed]], and [[_KeyReleased]].
-    
-    Here are two example events:
-    
-    An event is triggered by writing the key to the value on a box.  This
-    triggers any trap handlers which may be present.  Once these handlers
-    have executed, Ibex figures out which child of the current box contains
-    the mouse (taking into account that some boxes may cover up others)
-    and writes the key and value to that box.  If none of the box's
-    children contain the mouse position, Ibex removes the leading
-    underscore from the key name and writes the value to
-    **that** property.  Once all the traps on that property have
-    executed, the value is written to the box's parent.
-    
-    Intuitively, Ibex delivers the underscored event to every box from the
-    root to the target, and then delivers the non-underscored event to
-    that same set of boxes in reverse order.  So the event travels down
-    the tree to the target, and then back up to the root.  The following
-    example prints out "first second third fourth" in that order.
-    
-    <pre>
-    <ui:box>
-        _Press1 ++= function(b) { ibex.log.info("first"); }
-         Press1 ++= function(b) { ibex.log.info("fourth"); }
-        <ui:box>
-          _Press1 ++= function(b) { ibex.log.info("second"); }
-           Press1 ++= function(b) { ibex.log.info("third"); }
-        </ui:box>
-    </ui:box>
-    </pre>
-
-    In general, you should use the **non-underscore** names to respond
-    to user input and use the underscored names when you want to override
-    child boxes' behavior or route events to particular boxes (for
-    example, when implementing a focus protocol).  This is why the
-    underscored elements are delivered to parents before children (so
-    parents can override their childrens' behavior), but non-underscored
-    events are delivered to children before parents (since, visually, a
-    mouse click is usually "intended" for the leaf box underneath the
-    cursor).
-    
-    </section>
-
-  <heading title="Stopping the Process"/>
-
-    At any point in this sequence, a trap handler can choose not to
-    cascade (by returning [[true]] from the trap handler function).
-    This will immediately cease the propagation of the event.  This is how
-    you would indicate that an event has been "handled".
-    
-  <heading title="Non-Propagating Events"/>
-
-    Ibex uses the following events to notify a box about changes that
-    only matter to that particular box.  These events do not propagate
-    either up or down the tree.
-
-    <property name="Enter Leave">
-        The value [[true]] is written to this property when the mouse (enters/leaves) the box.
-        </property>
-    
-    <property name="SizeChange">
-        The value [[true]] is put to this property after the size
-        of this box changes.
-        </property>
-
-    <property name="ChildChange">
-        When a child is added or removed, that child is written to
-        this property.  The write is always performed **after** the
-        addition or removal, so these two cases can be distinguished
-        by checking [[indexof(child)]].
-
-        Note that if the parent's redirect target is set to another
-        box, this trap will only be invoked when children are
-        manipulated by reading and writing to the parent.  Reads and
-        writes directly to the redirect target will **not** trigger
-        this trap.
-
-        Note also that this traps is still triggered if a box's
-        [[redirect]] target is **null**.  This is useful for
-        boxes that need to accept children and then relocate them
-        elsewhere.
-        </property>
-    
-  <section title="Listing of Events">
-    
-    <property name="Press1 Press2 Press3">
-        Indicates that the use has pressed a mouse button.  On
-        platforms with three mouse buttons, the **middle** button
-        is button 3 -- this ensures that applications written to only
-        use two buttons (1 and 2) will work intuitively on three button
-        platforms.
-        </property>
-    
-    <property name="Release1 Release2 Release3">
-        Indicates that the use has released a mouse button.
-        </property>
-    
-    <property name="Click1 Click2 Click3">
-        Indicates that the user has pressed and released the
-        mouse button without moving the mouse much (exactly how
-        much is platform-dependent).
-        </property>
-    
-    <property name="DoubleClick1 DoubleClick2 DoubleClick3">
-        Indicates that the user has clicked the 
-        mouse button twice within a short period of time (exactly how long is platform-dependent).
-        </property>
-    
-    <property name="Move">
-        Indicates that the mouse has moved while within this box, or that
-        the mouse while outside this box **if a button was pressed while within this box and has not yet been released**
-        </property>
-    
-    <property name="KeyPressed KeyReleased">
-
-        A string is written to this property when a key is pressed or
-        released If the key was any other key, a multi-character
-        string describing the key will be put. For simplicity, we use
-        the VK_ constants in the <link
-        url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
-        text=" Java 1.1 API java.awt.event.KeyEvent class"/>.  When a
-        key is pressed or released, the string put will be the portion
-        of its VK_ constant after the underscore, all in lower case.
-
-        <list>
-        If the shift key was depressed immediately before the
-        event took place, then the string will be capitalized. Special
-        keynames are also capitalized; shift+home is reported as
-        "[[HOME]]".  Symbols are capitalized as they appear on the
-        keyboard; for example, on an American QWERTY keyboard, shift+2
-        is reported as "[[@]]".
-
-        If the alt, meta, or command key was depressed immediately
-        before this key was pressed, then the string will be prefixed
-        with the string "[[A-]]". If the control key was depressed
-        while this key was pressed, then the string will be prefixed
-        with the string "[[C-]]". If both alt and control are
-        depressed, the string is prefixed with "[[C-A-]]".
-
-        Ibex does not distinguish between a key press resulting from
-        the user physically pushing down a key, and a 'key press'
-        resulting from the keyboard's typematic repeat. In the rare
-        case that an application needs to distinguish between these
-        two events, it should watch for KeyReleased messages and
-        maintain an internal key-state vector.
-        </list>
-        </property>
-
-    </section>
-
-</section>
-
 <!-- ----------------------------------------------------------------------- -->
 <section title="Networking">
     
     
   </section>
 
-<!-- ----------------------------------------------------------------------- -->
-<section title="Advanced Topics">
-
-  <section title="Re-routing events">
-
-    At any point in the Event Context, you can write to the [[mouse]]
-    property on any box.  The value written should be an object with two
-    properties, [[x]] and [[y]].  For example:
-    
-    <pre>
-    _Press1 ++= function(p) {
-        mouse = { x: 32, y: 77 };
-    }
-    </pre>
-
-    The coordinates specified are relative to the box whose [[mouse]]
-    property is being written to.  There is no need to supply the
-    [[inside]] property; it is computed automatically.  Writing to
-    the [[mouse]] property causes Ibex to recompute the eventual
-    target box, and also alter the values returned by [[mouse.x]],
-    [[mouse.y]], and [[mouse.inside]] for any **descendants**
-    of the current box.  Writing to the [[mouse]] property also
-    automatically prevents the event from returning to the box's parents
-    -- it is equivalent to not cascading on the non-underscored event.
-    This ensures that child boxes cannot trick their parent boxes into
-    thinking that the mouse has moved.
-    
-    If you want the event to "skip over" the boxes between the trapee
-    and the target, or if you want to re-route an event to a box which
-    is not a descendant of the current box, simply write the value to
-    the proper key on the target box.
-    
-    <pre>
-    <ui:box>
-        _KeyPressed = function(k) { ibex.log.info("first"); }
-         KeyPressed = function(k) { ibex.log.info("sixth"); }
-        $recipient.target = $target;
-        <ui:box id="recipient">
-            _KeyPressed = function(k) {
-                ibex.log.info("second");
-                thisbox.target.KeyPressed = k;
-                // inhibit cascade; keep event from going to $excluded
-                return true;
-            }
-             KeyPressed = function(k) { ibex.log.info("fifth"); }
-            <ui:box id="excluded">
-                _KeyPressed = function(k) {
-                   ibex.log.info("this never happens");
-                }
-            </ui:box>
-        </ui:box>
-        <ui:box id="target"> 
-            _KeyPressed = function(k) { ibex.log.info("third"); }
-             KeyPressed = function(k) { ibex.log.info("fourth"); }
-        </ui:box>
-    </ui:box>
-    </pre>
-
-    </section>
-
-  <section title="Synthesizing Your Own Events">
-
-    You can create "fake events" by simply writing to the [[mouse]]
-    property and then writing a value to one of the underscored properties
-    on a box.  This will have exactly the same effect as if the use had
-    actually pressed a key, clicked a button, or moved the mouse -- they
-    are indistinguishable.
-    
-    </section>
 
   <section title="Ibex self-emulation">
 
     new_ibex.load ++= function() { return newLoadFunction; }
     ibex.apply(ibex.box, .main, new_ibex);
     </pre>
-  </section>
+</section>
 </section>
 
 <!-- ----------------------------------------------------------------------- -->