128 lines
2.6 KiB
C++
128 lines
2.6 KiB
C++
|
|
||
|
#include "puLocal.h"
|
||
|
|
||
|
#define PUMENU_BUTTON_HEIGHT 25
|
||
|
#define PUMENU_BUTTON_EXTRA_WIDTH 25
|
||
|
|
||
|
puObject *puPopupMenu::add_item ( char *str, puCallback cb )
|
||
|
{
|
||
|
int w, h ;
|
||
|
getSize ( &w, &h ) ;
|
||
|
puOneShot *b = new puOneShot ( 0, h, str ) ;
|
||
|
b->setStyle ( PUSTYLE_PLAIN ) ;
|
||
|
b->setColourScheme ( colour[PUCOL_FOREGROUND][0],
|
||
|
colour[PUCOL_FOREGROUND][1],
|
||
|
colour[PUCOL_FOREGROUND][2],
|
||
|
colour[PUCOL_FOREGROUND][3] ) ;
|
||
|
b->setCallback ( cb ) ;
|
||
|
recalc_bbox () ;
|
||
|
return b ;
|
||
|
}
|
||
|
|
||
|
void puPopupMenu::close ( void )
|
||
|
{
|
||
|
puPopup::close () ;
|
||
|
|
||
|
int widest = 0 ;
|
||
|
puObject *ob = dlist ;
|
||
|
|
||
|
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
|
||
|
{
|
||
|
int w, h ;
|
||
|
|
||
|
ob -> getSize ( &w, &h ) ;
|
||
|
|
||
|
if ( w > widest ) widest = w ;
|
||
|
}
|
||
|
|
||
|
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
|
||
|
ob -> setSize ( widest, PUMENU_BUTTON_HEIGHT ) ;
|
||
|
|
||
|
recalc_bbox () ;
|
||
|
}
|
||
|
|
||
|
|
||
|
int puPopupMenu::checkKey ( int key, int updown )
|
||
|
{
|
||
|
if ( dlist == NULL || ! isVisible () || ! isActive () )
|
||
|
return FALSE ;
|
||
|
|
||
|
if ( updown == PU_DOWN )
|
||
|
{
|
||
|
hide () ;
|
||
|
|
||
|
/* Turn everything off ready for next time. */
|
||
|
|
||
|
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
|
||
|
bo -> clrValue () ;
|
||
|
}
|
||
|
|
||
|
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 puPopupMenu::checkHit ( int button, int updown, int x, int y )
|
||
|
{
|
||
|
if ( dlist == NULL || ! isVisible () || ! isActive () )
|
||
|
return FALSE ;
|
||
|
|
||
|
/* Must test 'isHit' before making the menu invisible! */
|
||
|
|
||
|
int hit = isHit ( x, y ) ;
|
||
|
|
||
|
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN )
|
||
|
{
|
||
|
hide () ;
|
||
|
|
||
|
/* Turn everything off ready for next time. */
|
||
|
|
||
|
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
|
||
|
bo -> clrValue () ;
|
||
|
}
|
||
|
|
||
|
if ( ! hit )
|
||
|
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 ;
|
||
|
}
|
||
|
|