Developer

API Reference

IContainer

Brew Release
Brew MP 1.0.2
See Also
- ICardContainer Interface
- IRootContainer Interface
- IPropContainer Interface
- IXYContainer Interface
- IWidget_MoveFocus()
- IWidget_ForceLayout()
- IWidget_EnableLayout()
Description
IContainer is an abstract interface intended as the base from which more complex container interfaces (such as the card container or XY container interfaces) inherit. The widgets framework supplies several implementations of containers, all based on the IContainer interface. These derived containers differ from one another in the manner with which each lays out their child widgets. The derived container objects are:
   Card Container
   --------------
   The card container organizes widgets much like a deck of cards -- one on top of
   another, managing which is visible at the top of the deck.  Widgets in card
   containers do not have 'x' and 'y' coordinates on the display -- only 'z' ordering,
   with one widget at each level of the display.  Only one of the widgets managed by
   the container will be visible on the display, with the others hidden from view as
   if they were the remaining cards in the deck.  The card container is described in
   greater detail in AEECardContainer.h.
       
   Prop Container
   --------------
   The prop container will lay out all of its widgets in a single direction, either
   vertically or horizontally, using widget extents and proportions relative to other
   widgets as the determining factor in placing the widget on the display.  For
   example, three widgets laid out vertically -- each of which has been assigned a
   different proportional value -- will be sized and positioned in the container
   based on the size of the container and vertical extent of each widget.  The prop
   container is described in greater detail in AEEPropContainer.h.
   
   XY Container
   ------------
   The XY container will layout all of its widgets in absolute (x, y) coordinates
   within the container -- i.e. widgets will be displayed exactly as they have been
   defined, regardless of container size or the relation of one widget to another.
   'x' is 'x', 'y' is 'y' and the world becomes very predictable and boring (though
   precise, well understood, and easy to debug).  The XY container is described in
   greater detail in AEEXYContainer.h.
   
   Constraint Container
   --------------------
   The constraint container is the Mad Scientist Experimentation Gizmo of all containers!
   It's a floor wax and a dessert topping!  Its glass is half-full and half-empty!  It's
   Norman Bates and his mother, all rolled into one!  In a constraint container, widgets
   are laid out relative to the placement of other widgets and/or the container.  For
   example, the top edge of a widget could be defined to always be 4 pixels from the top
   of its parent.  Likewise, the left edge of one widget might be defined to be located
   2 pixels from the left edge of the previous widget.  In all cases, the position and
   size of a widget will be determined by the size of the parent container, and the
   position and size of all the other widgets in the container.  As the size and shape of
   the container changes, so shall the size, shape and position of each of the widgets it
   manages.  Regardless of the size and shape of the container, the widgets it manages
   will maintain consistent appearance relative to one another.  The constraint container
   is described in greater detail in AEEConstraintContainer.h.

Conceptually, a container is the parent to a collection of child widgets, managed as a stack within the container object. This stack keeps track of the relative order of the widgets being managed and provides operational services such as drawing and focus management to those widgets. For example, let's invent a new application called Art Auction. This application will include a screen that includes a scrollable lists of paintings (as images, of course), along with a text control and a "Bid" softkey so that the user can place twenty million dollar bids on their favorite Picasso while riding the subway to work. The widgets on this screen could all be collected in a container, which would be responsible for managing the order and drawing of each widget. The container knows which widget is created first, which is next and so on... and -- most importantly -- dictates the order that the widgets will be drawn.
Illustrating the default relationship of widgets within a container:
                              Container   
                         +----------------+
   Created last  ------> |    Widget n    | <--- Drawn last (topmost)
                         |----------------|
                         |        :       |
                         |----------------|
   Created 3rd   ------> |    Widget 3    | <--- Drawn 3rd
                         |----------------|
   Created 2nd   ------> |    Widget 2    | <--- Drawn 2nd
                         |----------------|  
   Created first ------> |    Widget 1    | <--- Drawn first (bottommost)
                         +----------------+

By default widgets are added to a container as they would be added to a stack; i.e., new items are added to the "top". When the container is drawn, the widgets will be drawn in the order that they appear in the container's widget stack. Therefore, where widgets may overlap one another, widgets at the top of the stack will be drawn forward (i.e., on top) of widgets buried deeper within the stack.
By default the widget stack within a container grows from bottom to top. However, an application may choose to insert new widgets at a particular place within the stack. So, though the widgets may not appear in the container in the same order that they have been created, their management and display will still be determined by the stack order.
Theoretically, the widgets collected within a container are "in" that container. While this is an accurate accounting of the object relationship that exists between a container and the widgets it manages, those widgets are not necessarily constrained by the container's bounding rectangle. The widgets managed by a container are expressed in coordinates relative to the container's origin and may be wholly enclosed within the container's extent (widget's 1, 2 and 5 in the diagram below), partially enclosed (widget 4), or defined to be entirely outside of the container's extent (widget 3). The container sets up the clipping rectangle before telling each widget to draw, and in cases where the widget is fully clipped (e.g. widget 3), will simply not call on it to draw itself at all.
                                                            +- - - - - - - +
                          c o n t a i n e r                 :              :
                +-----------------------------------+       :   Widget 3   :
                |+---------------------------------+|       :              :
                ||            Widget 5             ||       + - - - - - - -+
                |+---------------------------------+|
                |                                   |
                |                                   |
                |                                   |
                |                                   |
                |                  +----------------|- - - - - - - - - +
                |                  |                |                  :
                |                  |                |                  :
                |                  |         Widget | 4                :
                |                  |                |                  :
                |                  |                |                  :
                |                  +----------------|- - - - - - - - - +
                |                                   |
                |                                   |
                |                                   |
                |                                   |
                |+---------------------------------+|
                ||   Widget 1     |   Widget 2     ||
                |+---------------------------------+|
                +-----------------------------------+

Widgets held in the container's widget stack may be created as either visible or invisible. An invisible widget is one that occupies a place in the container stack relative to other widgets, but is not factored into operations involving display. So when the container objects are being drawn, an invisible widget will not be displayed. Likewise, an invisible object will not respond to operations that would calculate in an object's rectangle. Though benign with regards to "immediate" display operations, at any time an invisible widget could be made visible -- at which time it would be factored into display operations at the spot it occupies in the widget stack.
The objects stored in a container's widget stack may contain any combination of widgets and... other containers! For example, a single widget that combines the services of two widgets -- say, a widget that has been created to combine a checkbox and a static text widget as a single entity -- would define a container around the checkbox and static text widgets. An application that wishes to display this "checkbox with text" widget on the same screen as an image widget would create a container. That container would in turn hold an image widget and the container that manages the "checkbox with text" widget.
By combining multiple levels of containers and widgets, a container hierarchy is built with a single container at the hierarchy's base -- referred to as the "root container". The relationship between the root container and all other objects within its hierarchy can be illustrated by the following diagram:
   +------------------+        
   |                  |
   | Root Container   |
   |        +         |
   +--------|---------+        
            |
            V
   +------------------+        
   |                  |
   | Prop Container +------> +----------------+
   |                  |      |                |
   +------------------+      |   Container  +--------> +----------------+
                             |                |        |                |
                             |----------------|        |     Widget     |
                             |                |        |                |
                             |     Widget     |        +----------------|
                             |                |
                             |----------------|
                             |                |
                             |   Container  +--------> +----------------+
                             |                |        |                |
                             |----------------|        |   Container  +--------> +----------------+
                             |                |        |                |        |                |
                             |     Widget     |        +----------------+        |     Widget     |
                             |                |        |                |        |                |
                             |----------------|        |     Widget     |        +----------------+
                             |                |        |                |
                             |     Widget     |        +----------------+
                             |                |        |                |
                             +----------------+        |     Widget     |
                                                       |                |
                                                       +----------------+

In the above diagram, a single root container serves as the parent to a Prop Container (a special type of container object that manages the lays out of its children in a proportional fashion -- see AEEPropContainer.h for more information). The prop container serves as a parent to 5 child objects -- three widgets and two containers. One of those containers serves as the parent for a single widget, while the other is the parent to three objects -- two widget and yet another container. Finally, this container is parent to one child widget. Operations within the container/widget hierarchy (such as invalidating a portion of the display) will trickle up the object hierarchy. For example, if the widget on the far right of the above diagram were to be invalidated, the rectangle occupied by that widget will be invalidated in the widget's parent container -- and so on up to that container's parent, up eventually to the root container.
By default, containers will be created with the following characteristics:
      Border width:  0 pixels

Supported Events: The widget framework defines a small set of events used to support focus changes in container objects. These events are sent to containers in addition to the normal set of BREW events such as key presses or property queries. A container that derives from the base container object should be prepared to handle these events in whatever manner is appropriate for the behavior of that specific type of container.
The base container object processes events in three passes. In the first pass, the container will pass all events to the border event handler where border property events may be handled. Events not handled during this first pass are then processed by the container itself -- specifically, those events that set or move the focus. Finally, if the event is not handled, it will be passed on to the widget within the container that currently holds the focus.
The base container will accept the following events:
Event                 Description
-----                 ------------------------------------------------------------
EVT_WDG_SETFOCUS:     The base container responds to this event by accepting the focus and
                      effectively moving the focus to the first focusable widget held in the
                      container's widget stack.  Upon setting the focus, the base container
                      will pass an EVT_WDG_SETFOCUS event to the widget that will be accepting
                      the focus.  This event is also sent to a widget when it loses focus.

EVT_WDG_GETFOCUS:     The base container responds to this event by returning the widget that 
                      it currently maintains as the focused widget. This may be NULL. 
                      
EVT_WDG_MOVEFOCUS:    The focus has been moved to a particular widget within the container.
                      The 'dwParam' parameter identifies the new focus item, either explicitly
                      as a pointer to an IWidget in the container's widget stack, or implicitly
                      as a defined constant that expresses the relation of the new focus item
                      relative to the current focus.  The constants used to identify relative
                      focus changes, are defined as follows
                              
                          WIDGET_FOCUS_NONE   - The current focus should be canceled and no
                                                widget will have the focus.
                          WIDGET_FOCUS_FIRST  - The focus has been moved to the first focusable
                                                widget in the container.
                          WIDGET_FOCUS_LAST   - The focus has been moved to the last focusable
                                                widget in the container.
                          WIDGET_FOCUS_NEXT   - The focus has been moved to the next focusable
                                                widget in the container.
                          WIDGET_FOCUS_PREV   - The focus has been moved to the previous 
                                                focusable widget in the container.
                              
                      The base container will return TRUE or FALSE depending on whether or not
                      it was able to change the focus as requested.  Upon accepting the focus
                      change, the base container will pass an EVT_WDG_SETFOCUS event to the
                      widget that will be accepting the focus. 

EVT_WDG_FOCUSCANCEL:  This event will be sent to a container when the currently focused child widget 
                      is being removed.  This allows containers to reset focus logic accordingly.

EVT_WDG_SETLAYOUT:    This event can be used to request a container to not auto-layout its children. 
                      This can be used when a number of widgets need to be added, removed or manipulated 
                      in a container. Multiple re-layouts and invalidations can be performance problems. 
                      By turning off layout while manipulating a container, all layouts and invalidations 
                      are turned off. When finished manipulating the container, turn on layout to re-layout 
                      the container and have it invalidate itself. You can also force a re-layout by using 
                      IWidget_ForceLayout 

EVT_WDG_SETPROPERTY:  The container responds to this event by attempting to set the
                      property identified by the 'wParam' parameter.  The container
                      allows the following properties to be set
                      
                          PROP_FLAGS          --  Set various container flags
                          PROP_VISIBLE        --  Sets the visibility of a child widget
                      
                      These properties are discussed below in greater detail.

EVT_WDG_GETPROPERTY:  The container responds to this event by attempting to retrieve the
                      property identified by the 'wParam' parameter.  These properties are
                      discussed below in greater detail.
                      
                          PROP_FLAGS         --  Retrieves various image widget flags
                          PROP_VISIBLE       --  Gets the visibility of a child widget

EVT_WDG_TRAVERSE:     The container responds to this event by executing a function on each 
                      widget in its containment tree, including itself. The 'dwParam' parameter
                      is a pointer to a TraverseDesc data structure containing a function
                      callback, a callback context pointer, and the number of levels to 
                      descend in the container hierarchy.  (See the TraverseDesc data structure.)



Properties:
Property             Description
--------             ------------------------------------------------------------
PROP_FLAGS:          This property contains a set of mutually exclusive flags that dictate how a
                     container will behave.  These flags are passed in the 'dwParam' of the
                     event.  The following flags are identified for IContainer

                        CWF_NOFILTERKEYS
                        ----------------
                        This flag disables filtering of mismatched key events that may occur 
                        when the container's focus widget changes.  By default, containers 
                        will watch for EVT_KEY_PRESS events and only route subsequent 
                        EVT_KEY and EVT_KEY_RELEASE events on to the widget that had the 
                        focus when EVT_KEY_PRESS occurred.  When this flag is set, this key 
                        filtering is disabled.  This flag was added for backwards 
                        compatibility and for advanced applications that want to deal with 
                        non-filtered keys.  

                        Property Value:  uint32

                        CWF_NOROUTEFOCUS
                        ----------------
                        This flag disables the routing of events to the focused child widget.
                        Normally, containers will send events to their focused child if they are 
                        unable to handle them.  This flag will prevent any events the container
                        could not handle from being sent to the focused child.

                        Property Value:  uint32

                        CWF_BROADCAST
                        -------------
                        This flag changes the default routing of events from the focused child
                        widget to the first widget in the container who reports that it is
                        handling the event.  The widgets are enumerated based on their Z ordering
                        with the top-most widget receiving the event first and the bottom-most widget
                        receiving the event last.
                        
                        Property Value: uint32

                        CWF_ZTOPFOCUSONCHANGE
                        ---------------------
                        This flag enables the auto assignment of focus to the WIDGET_ZTOPMOST child widget
                        in the container whenever a widget is inserted or removed from the container.
                        
                        Property Value:  uint32
                         

PROP_VISIBLE:        This property is used to determine the visibility of a child widget.  The
                     'dwParam' of IWidget_HandleEvent() should point to a WidgetVis struct
                     pointer.  WidgetVis has two members, a pointer to the widget (piw)
                     whose visibility we want to get/set and a boolean (bVisible) whose
                     usage depends on whether we are setting or getting.  WidgetVis is
                     used for both setting and getting this property.
                     
                     When requesting the visibility of a child widget, the 'pVal' param of
                     IWidget_GetProperty() will be a pointer to a WidgetVis struct.  The 'piw'
                     member should point to the child widget whose visibility is being requested.
                     The 'bVisible' member will be set to TRUE if the widget is visible and FALSE
                     if it is not visible.  IWIDGET_GetProperty() will return AEE_SUCCESS if 'piw'
                     is found to be a child widget of the container and 'bVisible' is successfully
                     set to TRUE or FALSE (depending on visibility).    

                     When setting the visibility of a child widget, the 'val' param of
                     IWidget_SetProperty() should be a pointer to a WidgetVis struct.
                     The 'piw' member of WidgetVis should point to the child widget whose
                     visibility is being set.  The 'bVisible' members should be set to
                     TRUE if the widget should be set to visible and FALSE if it should be
                     set to not visible.  IWIDGET_SetProperty() will return AEE_SUCCESS if 'piw'
                     is found to be a child widget of the container and its visibility
                     was successfully set.

                     There are also a number of helper functions available which use this
                     property to change visibility
                        
                          IWidget_SetChildVisibility()
                          IWidget_GetChildVisibility()
                          IWidget_IsVisible()
                          IWidget_SetVisible()
                     
                       Property Value: WidgetVis*


PROP_RAISE           This property is used to "raise" a child widget of this container to 
                     an IXYContainer target.  Raising a widget means that a widget is 
                     added to the child list of an IXYContainer (called the raise target), 
                     in addition to being a child of its original container.  The original 
                     container is responsible for the layout or positioning of the widget, 
                     and the raise target is responsible for drawing the widget.  Since 
                     the raise target is doing the drawing, the widget will be clipped to 
                     the dimensions and z-order of the raise target instead of the 
                     original parent container.  

                     The property value is a pointer to a RaiseDesc data structure, which 
                     contains two members, the first describes the child widget to 
                     raise, and the second is an IXYContainer pointer which is the raise 
                     target.

                        typedef struct RaiseDesc {
                           IXYContainer * pixyTarget;    // xy container we are raising TO
                           IWidget *      piw;           // the widget we are raising
                        } RaiseDesc;

                     To "unraise" an already raised widget, set the 'pixyTarget' member of 
                     the RaiseDesc structure to NULL, and the 'piw' member to the raised 
                     child before setting the property. 

                     For a 'Get' property operation, set the 'piw' member of the RaiseDesc 
                     structure to one of the child widgets of the container, before 
                     getting the property. On return, the 'pixyTarget' will contain a 
                     pointer to the raise target container, or NULL if the widget is not 
                     raised.
                     
                        Property Value: RaiseDesc *
                       
Usage
Here are some suggestions of how developers can use containers in their application:
- To create an instance of a particular container an application would call
ISHELL_CreateInstance() with a class ID of the container type. For example AEECLSID_ConstraintContainer, AEECLSID_XYContainer, AEECLSID_CardContainer, etc. - Insert the container’s widget in a container that, up the hierarchy, leads
to a root container to make sure that the container is displayed on the screen. (For example, one can call the api: ICONTAINER_Insert().) - To insert widgets in a container use: ICONSTRAINTCONTAINER_Insert(),
ICARDCONTAINER_Insert(), IPROPCONTAINER_Insert(), etc. - Query interface to container widget. This will allow the user to utilize
the IWIDGET apis, for example to set/get extent, border properties, background color, etc. - The ICONTAINER apis can be used for manipulating the container, such as
inserting a widget, invalidating, getting/removing a widget, etc.
Comment
None
  • Follow