Progress Programming Tips

By Rod Gaither (rdg@worldinfo.com)


PPT-5  Walking the Widget Tree

Tip:

With the advent of widgets Progress began opening up the door
to dynamic operations other than the old RUN VALUE() statement.
Since many attributes can be affected from the widget-handle of a
widget you now have the opportunity to customize some display and
behaviour characteristics of widgets at run time.  One tool everyone
should have available is a procedure to traverse the widget tree of
widget handles.  The sample included below is designed to accomplish
several things.

1.  Traverse the tree from starting point X.
2.  Only affect widgets by name and type
3.  Run the passed in procedure for each selected widget

---- Code insert begins ----

PROCEDURE widget-walk :
/*--------------------------------------------------------------------
----------
  Purpose:     Walks the widget tree to various purposes
  Parameters:  Starting widget handle, run procedure info
  Notes:       Requires run procedure to have the following
               parameters - (INPUT widget-handle, INPUT character)

    p-start    Start traversal with this widget, usually a frame
    p-run      Name of the internal procedure to run for each widget
    p-in       Handle of program to run the internal procedure in
    p-pass     A parameter the caller can set to pass to the IP
    p-types    Only affect these types of widgets - selection criteria
    p-name     The list of widget names to be affected
----------------------------------------------------------------------
--------*/

  DEFINE INPUT  PARAMETER  p-start   AS WIDGET-HANDLE  NO-UNDO.
  DEFINE INPUT  PARAMETER  p-run     AS CHAR           NO-UNDO.
  DEFINE INPUT  PARAMETER  p-in      AS HANDLE         NO-UNDO.
  DEFINE INPUT  PARAMETER  p-pass    AS CHAR           NO-UNDO.
  DEFINE INPUT  PARAMETER  p-types   AS CHAR           NO-UNDO.
  DEFINE INPUT  PARAMETER  p-names   AS CHAR           NO-UNDO.

  DEF VAR  t-wh    AS WIDGET-HANDLE  NO-UNDO.
  DEF VAR  t-name  AS CHAR           NO-UNDO.
  DEF VAR  l-loop  AS LOGICAL        NO-UNDO.
  DEF VAR  l-down  AS LOGICAL        NO-UNDO.

  ASSIGN 
    t-wh   = p-start
    l-loop = (IF VALID-HANDLE(t-wh) THEN TRUE ELSE FALSE)
    l-down = TRUE.

  BLK-MAIN:
  DO WHILE l-loop:
    /***[ Execute current item ]***/

    /* setup the name portion for checking */
    /* may want this to be an internal procedure to deal with prefixes
    */ ASSIGN t-name = p-wh:NAME.

    /***[ Do type and name checking then execute internal procedure
    ]***/

    IF l-down AND (IF p-types <> "" THEN CAN-DO(p-types,t-wh:TYPE)
    ELSE TRUE)
      AND (IF p-names <> "" THEN CAN-DO(p-names,t-name) ELSE TRUE)
    THEN RUN VALUE(p-run) IN p-in (INPUT t-wh, INPUT p-pass) NO-ERROR.


    /***[ Try to go down first - only on first time ]***/
    IF CAN-QUERY(t-wh,"FIRST-CHILD")
         AND VALID-HANDLE(t-wh:FIRST-CHILD) 
         AND l-down
       THEN ASSIGN t-wh   = t-wh:FIRST-CHILD
                   l-down = TRUE.

      /***[ If down not an option try sideways ]***/
      ELSE IF VALID-HANDLE(t-wh:NEXT-SIBLING) 
             THEN ASSIGN t-wh   = t-wh:NEXT-SIBLING
                         l-down = TRUE.

             /***[ If not down or sideways then go back up ]***/   
             /***[ If up is back to top then signal exit   ]***/ ELSE
             IF t-wh:PARENT = p-start
                    THEN ASSIGN t-wh   = p-start
                                l-loop = FALSE.

                    /***[ Go up but look sideways ]***/
                    ELSE ASSIGN t-wh   = t-wh:PARENT
                                l-down = FALSE.

  END.  /***[ End of DO WHILE ]***/


END PROCEDURE.

---- Code insert ends ----

Wisdom:

Just because you CAN do something doesn't always mean you SHOULD.

Rod Gaither                  | rdg@worldinfo.com
World Information Systems    | (910) 333-2580  Voice
Greensboro, NC               | (910) 333-2584  Fax