Rebol Programming/Language Features/View

View is a powerful two dimensional compositing graphical engine that was designed to display user interfaces. It takes a face object, which contains a hierarchical description of various graphical elements, and calls the operating system to render them to the user display. Various visual objects, or faces, may have handlers that deal specifically with certain visual events such as mouse overs, clicks, window resizing etc, and these events are linked into Rebol's event handling system with the call to 'do-events.

This means that when a mouse click is detected in a window, and the mouse click is over a button object, View is able to execute the handling code defined by that button that deals with mouse clicks.

Rebol uses a standard face that is used as a blue print for all graphical objects. View needs to use this as the base object as it contains the minimum set of properties needed to render and allow interaction with the operating system. It is defined in system/standard/face and is also referred to by the global variable face.

Let's define a face by templating from the system face as follows:

a-face: make face [ offset: 100x100 size: 200x100 color: red effect: [gradient] ]

The default face has an offset of 0x0, has a color of value 200.200.200 and size of 100x100. We've changed it here to add some red with the gradient changing across the face, repositioned and resized it.

How did we know what properties the system face object has? Simply, by typing

>> help face

FACE is an object of value: type           word! face offset         pair! 0x0 size           pair! 100x100 span           none! none pane           none! none text           none! none color          tuple! 200.200.200  image           none! none effect         none! none data           none! none edge           object! [color image effect size] font           object! [name style size color offset space align valign s...  para            object! [origin margin indent tabs wrap? scroll] feel           object! [redraw detect over engage] saved-area     none! none rate           none! none show? logic! true options        none! none parent-face    none! none old-offset     none! none old-size       none! none line-list      none! none changes        none! none face-flags     integer! 0  action          none! none

To become proficient directly using View requires an intimate knowledge of the various graphic components. For most users wishing to build user interfaces, this degree of detail is not necessary, and fortunately Rebol has a visual interfaces dialect (VID) which greatly simplifies the process.

To build an interface with a text label, and a text entry field, is as simple with VID as

view layout [ label "Enter Name:" field [ print face/text ]]

which looks like this:

layout parses the block, and from this, builds a face with a complex set of graphical elements that handle text editing, and mouse overs. The View engine then renders this to the screen.

Although VID is touted as being only an example of a dialect that can be created to build user interfaces, it has, by virtue of being built in, and being simpler than programming directly in View, become the default way to build user interfaces.

There are a number of problems with this approach. Since VID programming greatly simplifies the builing of a user interface, it also hides the complexity behind what happens so that if you wish to do something which is not documented, it does mean examining the source to VID to see how this might be done. Furthermore, VID remains incomplete in its range of graphical interface objects with third party widgets often failing to work well with each other. There is also a lot of redundancy in the code generated by the layout engine since not every facet of an object is needed in every instance, but is still generated. It also lacks an automatic resizing mechanism, and elements have to be repositioned manually.