1998-06-12 09:04:52 +08:00
|
|
|
#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 ;
|
|
|
|
|
1998-07-14 04:59:34 +08:00
|
|
|
/*
|
|
|
|
* June 17th, 1998, Shammi
|
|
|
|
* There seems to be some mismatch with the
|
|
|
|
* #define pumenusize and the actual size
|
|
|
|
* There seems to be some overlap resulting
|
|
|
|
* in more than one option being highlighted.
|
|
|
|
* By setting the size to the actual values,
|
|
|
|
* the overlap area seems to be less now.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int w, h ;
|
|
|
|
|
1998-06-12 09:04:52 +08:00
|
|
|
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
|
|
|
|
{
|
|
|
|
ob -> getSize ( &w, &h ) ;
|
|
|
|
|
|
|
|
if ( w > widest ) widest = w ;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
|
1998-07-14 04:59:34 +08:00
|
|
|
{
|
|
|
|
ob -> getSize ( &w, &h ) ;
|
|
|
|
ob -> setSize ( widest, h ) ;
|
|
|
|
}
|
1998-06-12 09:04:52 +08:00
|
|
|
|
|
|
|
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 ) ;
|
|
|
|
|
1998-07-14 04:59:34 +08:00
|
|
|
/*
|
|
|
|
* June 17th, 1998, Shammi :
|
|
|
|
* There seemed to be a miscalculation with the menus initially
|
|
|
|
* Therefore I moved the recalculation stuff before the clearing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
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();
|
|
|
|
x -= abox.min[0] ;
|
|
|
|
y -= abox.min[1] ;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* June 17th, 1998, Shammi :
|
|
|
|
* Also clear the menu when the dragging the mouse and not hit.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN ||
|
|
|
|
( updown == PU_DRAG && !hit ) )
|
1998-06-12 09:04:52 +08:00
|
|
|
{
|
1998-07-14 04:59:34 +08:00
|
|
|
|
|
|
|
/* June 17th, 1998, Shammi :
|
|
|
|
* Do not hide the menu if mouse is dragged out
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( updown != PU_DRAG )
|
|
|
|
hide () ;
|
1998-06-12 09:04:52 +08:00
|
|
|
|
|
|
|
/* Turn everything off ready for next time. */
|
|
|
|
|
1998-07-14 04:59:34 +08:00
|
|
|
/* June 17th, 1998, Shammi:
|
|
|
|
* Make sure we check for a hit, if the mouse is moved
|
|
|
|
* out of the menu.
|
|
|
|
*/
|
|
|
|
|
1998-06-12 09:04:52 +08:00
|
|
|
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
|
1998-07-14 04:59:34 +08:00
|
|
|
{
|
|
|
|
if ( ! hit )
|
|
|
|
bo -> checkHit ( button, updown, x , y ) ;
|
|
|
|
|
1998-06-12 09:04:52 +08:00
|
|
|
bo -> clrValue () ;
|
1998-07-14 04:59:34 +08:00
|
|
|
}
|
1998-06-12 09:04:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! hit )
|
|
|
|
return FALSE ;
|
|
|
|
|
|
|
|
puObject *bo ;
|
1998-07-14 04:59:34 +08:00
|
|
|
|
1998-06-12 09:04:52 +08:00
|
|
|
/*
|
|
|
|
We have to walk the list backwards to ensure that
|
|
|
|
the click order is the same as the DRAW order.
|
|
|
|
*/
|
|
|
|
|
1998-07-14 04:59:34 +08:00
|
|
|
/* June 17th, 1998, Shammi :
|
|
|
|
* If the mouse is dragged and the menuItem is not hit,
|
|
|
|
* clear it
|
|
|
|
*/
|
|
|
|
|
1998-06-12 09:04:52 +08:00
|
|
|
for ( bo = dlist ; bo->next != NULL ; bo = bo->next )
|
1998-07-14 04:59:34 +08:00
|
|
|
if ( updown == PU_DRAG && ! bo -> checkHit ( button, updown, x, y ) )
|
|
|
|
bo -> clrValue () ;
|
|
|
|
|
1998-06-12 09:04:52 +08:00
|
|
|
/* Find the last object in our list. */ ;
|
|
|
|
|
|
|
|
for ( ; bo != NULL ; bo = bo->prev )
|
|
|
|
if ( bo -> checkHit ( button, updown, x, y ) )
|
|
|
|
return TRUE ;
|
|
|
|
|
|
|
|
return FALSE ;
|
|
|
|
}
|
|
|
|
|
1998-07-14 04:59:34 +08:00
|
|
|
|