Forms, Widgets, and Containers
The notion of nesting widgets deserves extra attention, because it's the key by which complex (yet easy-to-use) interfaces are made with the Brew UI Toolkit. As in a traditional desktop GUI, widgets can contain other widgetssome widgets can act as containers, containing other widgets and controlling their layout. Other widgets act as decorators, letting you link their functionality to enhance a given widget. For example, a scrolling text view consists of two widgets: the text widget showing the text, and a scrollbar widget that provides the scrolling behavior, decorating the functionality of the text widget. (You can learn more about the decorator pattern here
, or by reading the description in Gamma, et al's Design Patterns
Widgets which contain other widgets are containers, and implement the IContainer interface. Don't be confused between IContainer and IWidget, or their methods. The IContainer interface lets you manipulate how a widget performs its job as a container; the IWidget interface lets you manipulate the widget itself. This is especially important when working with classes like IXYContainer and IConstraintContainer whose primary function is to contain objects. To use these objects as widgets, you must first obtain the corresponding widget interface from an instance via ICONSTRAINTCONTAINER_QueryInterface. This requests the widget interface for the corresponding container object.
While a specific screen consists of a hierarchy of widgets, your entire application is a collection of forms. A form consists of a top-level container; the Brew UI Toolkit provides a mechanism for your application to track its state as a top-level form (the one currently on-screen) and a stack of forms. As you use an application, the application uses events like soft keys and selection items to create new forms, fills them with widgets, and places them on the top of the stack. When you exit a form (say, by pressing the clear key), the form is popped from the stack. Just as widgets and the MVC pattern give you the ability to conceptualize a value and its relationship to the user, forms and the form stack give you a way to conceptualize application flow within the application.
At the highest level, then, your application consists of one or more forms, each of which has a collection of widgets (the view) which act together on a set of models that represent the state of your application's data. Many widgets will do their work automatically, enabling the user to enter text or select choices from a menu; others might need additional code in the form of a controller.