Walk the widget family hierarchy from front to back
int PtWidgetTreeTraverse( PtWidget_t *root, PtWidget_t **current, int direction, int (*skip_f)( PtWidget_t *widget, void *data ), void *data );
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:
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().
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, ¤t, 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, ¤t, 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, ¤t, dir, _skip_disjoint, NULL ) ) { if ( dir & FOUND_DISJOINT ) // current is the disjoint widget continue; //do stuff with current... } ...
Photon
Safety: | |
---|---|
Interrupt handler | No |
Signal handler | No |
Thread | No |
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