Jump to content

Rebol Programming/Language Features/View

From Wikibooks, open books for an open world

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.