simgear/PUI/puInterface.cxx
1998-06-12 01:04:52 +00:00

246 lines
4.8 KiB
C++

#include "puLocal.h"
#define PUSTACK_MAX 100
static int currLiveInterface = -1 ;
static puInterface *liveInterfaceStack [ PUSTACK_MAX ] ;
static int currInterface = -1 ;
static puInterface *interfaceStack [ PUSTACK_MAX ] ;
void puPushLiveInterface ( puInterface *in )
{
if ( currLiveInterface < PUSTACK_MAX )
liveInterfaceStack [ ++currLiveInterface ] = in ;
else
fprintf ( stderr, "PUI: Too many live puInterfaces open at once!\n" ) ;
}
void puPushInterface ( puInterface *in )
{
if ( currInterface < PUSTACK_MAX )
interfaceStack [ ++currInterface ] = in ;
else
fprintf ( stderr, "PUI: Too many puInterfaces open at once!\n" ) ;
}
void puPopLiveInterface ( void )
{
if ( currLiveInterface > 0 )
--currLiveInterface ;
else
fprintf ( stderr, "PUI: Live puInterface stack is empty!\n" ) ;
}
void puPopInterface ( void )
{
if ( currInterface > 0 )
--currInterface ;
else
fprintf ( stderr, "PUI: puInterface stack is empty!\n" ) ;
}
int puNoLiveInterface ( void )
{
return currLiveInterface < 0 ;
}
int puNoInterface ( void )
{
return currInterface < 0 ;
}
puInterface *puGetUltimateLiveInterface ( void )
{
if ( currLiveInterface < 0 )
{
fprintf ( stderr, "PUI: No Live Interface!\n" ) ;
return NULL ;
}
return liveInterfaceStack [ 0 ] ;
}
puInterface *puGetBaseLiveInterface ( void )
{
if ( currLiveInterface < 0 )
{
fprintf ( stderr, "PUI: No Live Interface!\n" ) ;
return NULL ;
}
/*
Work down the interface stack until you
either get to the bottom or find a block
in the form of a puDialogBox.
*/
for ( int i = currLiveInterface ; i > 0 ; i-- )
if ( liveInterfaceStack [ i ] -> getType () & PUCLASS_DIALOGBOX )
return liveInterfaceStack [ i ] ;
return liveInterfaceStack [ 0 ] ;
}
puInterface *puGetCurrInterface ( void )
{
if ( currInterface < 0 )
{
fprintf ( stderr, "PUI: No Interface!\n" ) ;
return NULL ;
}
return interfaceStack [ currInterface ] ;
}
void puInterface::remove ( puObject *obj )
{
if ( dlist == NULL )
return ;
/* Are we the first object in the list */
if ( obj -> prev == NULL )
dlist = obj -> next ;
else
obj -> prev -> next = obj -> next ;
/* Are we the last object in the list */
if ( obj -> next != NULL )
obj -> next -> prev = obj -> prev ;
obj -> next = NULL ;
obj -> prev = NULL ;
num_children-- ;
recalc_bbox () ;
}
void puInterface::add ( puObject *new_obj )
{
if ( dlist == NULL )
{
dlist = new_obj ;
new_obj -> next = NULL ;
new_obj -> prev = NULL ;
}
else
{
puObject *last ;
for ( last = dlist ; last->next != NULL ; last = last->next )
/* Search for end of list. */ ;
last -> next = new_obj ;
new_obj -> prev = last ;
new_obj -> next = NULL ;
}
num_children++ ;
recalc_bbox () ;
}
int puInterface::checkKey ( int key, int updown )
{
if ( dlist == NULL || ! isVisible () || ! isActive () )
return FALSE ;
puObject *bo ;
/*
We have to walk the list backwards to ensure that
the click order is the same as the DRAW order.
*/
for ( bo = dlist ; bo->next != NULL ; bo = bo->next )
/* Find the last object in our list. */ ;
for ( ; bo != NULL ; bo = bo->prev )
if ( bo -> checkKey ( key, updown ) )
return TRUE ;
return FALSE ;
}
int puInterface::checkHit ( int button, int updown, int x, int y )
{
if ( dlist == NULL || ! isVisible () || ! isActive () )
return FALSE ;
/*
This might be a bit redundant - but it's too hard to keep
track of changing abox sizes when daughter objects are
changing sizes.
*/
recalc_bbox () ;
puObject *bo ;
x -= abox.min[0] ;
y -= abox.min[1] ;
/*
We have to walk the list backwards to ensure that
the click order is the same as the DRAW order.
*/
for ( bo = dlist ; bo->next != NULL ; bo = bo->next )
/* Find the last object in our list. */ ;
for ( ; bo != NULL ; bo = bo->prev )
if ( bo -> checkHit ( button, updown, x, y ) )
return TRUE ;
return FALSE ;
}
void puInterface::draw ( int dx, int dy )
{
if ( isVisible () )
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
bo -> draw ( dx + abox.min[0], dy + abox.min[1] ) ;
}
void puInterface::recalc_bbox ( void )
{
puBox contents ;
contents . empty () ;
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
contents . extend ( bo -> getBBox() ) ;
if ( contents . isEmpty () )
{
abox . max[0] = abox . min[0] ;
abox . max[1] = abox . min[1] ;
}
else
{
abox . max[0] = abox . min[0] + contents . max[0] ;
abox . max[1] = abox . min[1] + contents . max[1] ;
}
puObject::recalc_bbox () ;
}
void puInterface::doHit ( int, int, int, int )
{
}
puInterface::~puInterface ()
{
puPopLiveInterface () ;
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
delete bo ;
}