[Previous] [Contents] [Index] [Next]

PtWidgetTreeTraverse()

Walk the widget family hierarchy from front to back

Synopsis:

int PtWidgetTreeTraverse( 
        PtWidget_t *root, 
        PtWidget_t **current, 
        int direction, 
        int (*skip_f)( PtWidget_t *widget, 
                       void *data ), 
        void *data );

Description:

This function walks the widget family hierarchy from the frontmost widget of the current branch to root.

If a skip_f() function is provided, it's called prior to the traversal into each branch of the family hierarchy. If the skip_f() function returns a value other than Pt_CONTINUE, that branch may be skipped. The skip_f() function is passed the current widget (root of the branch to be traversed next) and data, as provided in the last parameter to PtWidgetTreeTraverse().

The direction parameter controls the direction of the traversal to the next current widget. To begin a traversal, a direction of Pt_TRAVERSE_START should be passed. New direction values are returned by the function and should be used in subsequent calls during the traversal.

The direction value returned is treated primarily as a bit field in which the bottom four bits (0xF) are reserved for direction and general state control. These bits are:

Pt_TRAVERSE_ROOT
current is root.
Pt_TRAVERSE_LAST
current is last widget in hierarchy to be processed.
Pt_TRAVERSE_BACK
Walk towards root.
Pt_TRAVERSE_FORCE
Return the return value from skip_f unaltered (the return value is usually ORed with direction prior to return).

When the traversal is complete direction equals Pt_TRAVERSE_DONE (0).

The return value from skip_f(), if not Pt_CONTINUE, is ORed with the current direction control value unless the Pt_TRAVERSE_FORCE bit is set in that return value. This result is returned to the calling function (the function invoking PtWidgetTreeTraverse()). If the return value from skip_f() is Pt_CONTINUE, the branch is stepped into without returning from PtWidgetTreeTraverse().

Returns:

0
Successful completion of traversal.
-1
An error occurred.
Other values
Traversal is in progress.

Examples:

Example 1 - Implementation of PtWidgetTree():



static int
_skip_delay_realize( PtWidget_t *widget, void *data )
{
    data;
    return (
           (    
           (
           ( widget->flags & ( Pt_DELAY_REALIZE | 
                                      Pt_REALIZED ) )
               == Pt_DELAY_REALIZED
            ) 
        ) ? Pt_TRAVERSE_BACK : Pt_CONTINUE );
}

int 
PtWidgetTree( PtWidget_t *root, PtWidget_t **cur, int D )
{
    return PtWidgetTreeTraverse( root, cur, D, 
                                 _skip_delay_realize, NULL );
}

Example 2 - Find the frontmost widget in ABW_pane1 (unconditionally):

PtWidget_t *current;

(void) PtWidgetTreeTraverse( NULL, &current, Pt_TRAVERSE_START, 
                             NULL, NULL );
// current now points to the widget at the very front 
// of ABW_pane1

Example 3 - Find the frontmost widget in ABW_pane1 that isn't within a disjoint child:

#define FOUND_DISJOINT 0x10  

_skip_disjoint( PtWidget_t *widget, void *data )
{
    return( PtWidgetClassFlags( widget ) & Pt_DISJOINT ? 
                 FOUND_DISJOINT : Pt_CONTINUE );
}

...
dir = Pt_TRAVERSE_START;
while( dir = PtWidgetTreeTraverse( NULL, &current, 
                                   dir, _skip_disjoint, NULL ) )
     if( !( dir & FOUND_DISJOINT ) )
        break;
...

Example 4 - Walk the widget family hierarchy from the frontmost descendant within ABW_pane1 back to ABW_base (skipping disjoint subhierarchies):

#define FOUND_DISJOINT 0x10  
_skip_disjoint( PtWidget_t *widget, void *data )
{
    return( PtWidgetClassFlags( widget ) & Pt_DISJOINT ? 
            FOUND_DISJOINT : Pt_CONTINUE );
}

...
current = ABW_pane1;
dir = Pt_TRAVERSE_START;
while( dir = PtWidgetTreeTraverse( ABW_base, &current, dir, 
                                   _skip_disjoint, NULL ) )
    {
      if ( dir & FOUND_DISJOINT ) 
        // current is the disjoint widget
        continue;
        //do stuff with current...
    }
...

Classification:

Photon

Safety:
Interrupt handler No
Signal handler No
Thread No

See also:

PtNextTopLevelWidget(), PtWidgetBrotherBehind(), PtWidgetBrotherInFront(), PtWidgetChildBack(), PtWidgetChildFront(), PtWidgetFamily(), PtWidgetParent(), PtWidgetSkip(), PtWidgetTree()

"Ordering widgets" in the Creating Widgets in Application Code chapter of the Photon Programmer's Guide


[Previous] [Contents] [Index] [Next]