- <section title="Root Box Properties">
-
- The following special properties are only meaningful on the root box
- of a surface.
-
- <property name="Focused">
- The value <t>true</t> is put to this property on the root box
- when the surface gains the input focus, and <t>false</t> when
- the surface loses the input focus. Reading from this value will
- return <t>true</t> if the surface is focused and <t>false</t>
- if it is not. Putting <t>true</t> to this property will
- <i>not</i> cause the surface to "steal" the input focus from other
- windows.
- </property>
-
- <property name="Maximized">
- The value <t>true</t> is put to this property on the root box
- when the surface is maximized, and <t>false</t> when the surface
- is un-maximized. Reading from this value will return <t>true</t>
- if the surface is maximized and <t>false</t> if it is
- not. Putting <t>true</t> to this property will maximize the
- window, and putting <t>false</t> to this property will
- unmaximize the window.
- Note that not all platforms support maximization.
- </property>
-
- <property name="Minimized">
- The value <t>true</t> is put to this property on the root box
- when the surface is minimized, and <t>false</t> when the surface
- is unminimized. Reading from this value will return <t>true</t>
- if the surface is minimized and <t>false</t> if it is
- not. Putting <t>true</t> to this property will minimize the
- window, and putting <t>false</t> will unminimize it.
- </property>
-
- <property name="Close">
- When the user attempts to close a surface, the value
- <t>true</t> will be put to this property. Scripts may trap
- this property to prevent the window from closing. Putting the
- value
- <t>true</t> to this property on a root box has the same
- effect as putting <t>null</t> to the <t>thisbox</t>
- 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>
-
- <property name="titlebar">
- The surface's titlebar text. Note that not all platforms support
- this property. Only ASCII characters 0x20-0x7F are permitted.
- </property>
+ <section title="Root Box Properties">
+
+ The following special properties are only meaningful on the root box
+ of a surface.
+
+ <property name="Focused">
+ The value [[true]] is put to this property on the root box
+ when the surface gains the input focus, and [[false]] when
+ the surface loses the input focus. Reading from this value will
+ return [[true]] if the surface is focused and [[false]]
+ if it is not. Putting [[true]] to this property will
+ **not** cause the surface to "steal" the input focus from other
+ windows.
+ </property>
+
+ <property name="Maximized Minimized">
+ The value [[true]] is put to this property on the root box
+ 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="Close">
+ When the user attempts to close a surface, the value
+ [[true]] will be put to this property. Scripts may trap
+ this property to prevent the window from closing. Putting the
+ value
+ [[true]] to this property on a root box has the same
+ effect as putting [[null]] to the [[thisbox]]
+ property.
+ </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>
+
+ </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.