Initial revision.

This commit is contained in:
curt 1998-06-12 01:04:52 +00:00
parent 2caad4a27b
commit cfe0e18e4e
18 changed files with 2427 additions and 0 deletions

24
PUI/Makefile.am Normal file
View File

@ -0,0 +1,24 @@
libdir = ${exec_prefix}/lib
lib_LTLIBRARIES = libPui.la
libPui_la_SOURCES = \
pu.h puLocal.h \
pu.cxx \
puBox.cxx \
puButton.cxx \
puButtonBox.cxx \
puDialogBox.cxx \
puFrame.cxx \
puInput.cxx \
puInterface.cxx \
puMenuBar.cxx \
puObject.cxx \
puOneShot.cxx \
puPopup.cxx \
puPopupMenu.cxx \
puSlider.cxx \
puText.cxx
INCLUDES += -I$(top_builddir)

238
PUI/pu.cxx Normal file
View File

@ -0,0 +1,238 @@
#include "puLocal.h"
#define PU_STRING_X_FUDGE 6
#define PU_STRING_Y_FUDGE 6
int puRefresh = TRUE ;
puColour _puDefaultColourTable[] =
{
{ 0.5, 0.5, 0.5, 1.0 }, /* PUCOL_FOREGROUND */
{ 0.3, 0.3, 0.3, 1.0 }, /* PUCOL_BACKGROUND */
{ 0.7, 0.7, 0.7, 1.0 }, /* PUCOL_HIGHLIGHT */
{ 0.0, 0.0, 0.0, 1.0 }, /* PUCOL_LABEL */
{ 1.0, 1.0, 1.0, 1.0 }, /* PUCOL_TEXT */
{ 0.0, 0.0, 0.0, 0.0 } /* ILLEGAL */
} ;
puValue::~puValue () {}
static int _puCursor_enable = FALSE ;
static int _puCursor_x = 0 ;
static int _puCursor_y = 0 ;
static float _puCursor_bgcolour [4] = { 1.0f, 1.0f, 1.0f, 1.0f } ;
static float _puCursor_fgcolour [4] = { 0.0f, 0.0f, 0.0f, 1.0f } ;
void puHideCursor ( void ) { _puCursor_enable = FALSE ; }
void puShowCursor ( void ) { _puCursor_enable = TRUE ; }
int puCursorIsHidden ( void ) { return ! _puCursor_enable ; }
void puCursor ( int x, int y )
{
_puCursor_x = x ;
_puCursor_y = y ;
}
int puGetStringDescender ( void *fnt )
{
if ( fnt == NULL )
fnt = GLUT_BITMAP_9_BY_15 ;
if ( fnt == GLUT_BITMAP_8_BY_13 ) return 2 ;
if ( fnt == GLUT_BITMAP_9_BY_15 ) return 3 ;
if ( fnt == GLUT_BITMAP_TIMES_ROMAN_10 ) return 2 ;
if ( fnt == GLUT_BITMAP_TIMES_ROMAN_24 ) return 5 ;
if ( fnt == GLUT_BITMAP_HELVETICA_10 ) return 2 ;
if ( fnt == GLUT_BITMAP_HELVETICA_12 ) return 3 ;
if ( fnt == GLUT_BITMAP_HELVETICA_18 ) return 4 ;
return 0 ;
}
int puGetStringHeight ( void *fnt )
{
/* Height *excluding* descender */
if ( fnt == NULL )
fnt = GLUT_BITMAP_9_BY_15 ;
if ( fnt == GLUT_BITMAP_8_BY_13 ) return 9 ;
if ( fnt == GLUT_BITMAP_9_BY_15 ) return 10 ;
if ( fnt == GLUT_BITMAP_TIMES_ROMAN_10 ) return 7 ;
if ( fnt == GLUT_BITMAP_TIMES_ROMAN_24 ) return 17 ;
if ( fnt == GLUT_BITMAP_HELVETICA_10 ) return 8 ;
if ( fnt == GLUT_BITMAP_HELVETICA_12 ) return 9 ;
if ( fnt == GLUT_BITMAP_HELVETICA_18 ) return 14 ;
return 0 ;
}
int puGetStringWidth ( void *fnt, char *str )
{
if ( str == NULL )
return 0 ;
if ( fnt == NULL )
fnt = GLUT_BITMAP_9_BY_15 ;
int res = 0 ;
while ( *str != '\0' )
{
res += glutBitmapWidth ( fnt, *str ) ;
str++ ;
}
return res ;
}
void puDrawString ( void *fnt, char *str, int x, int y )
{
if ( str == NULL )
return ;
if ( fnt == NULL )
fnt = GLUT_BITMAP_9_BY_15 ;
glRasterPos2f ( x, y ) ;
while ( *str != '\0' )
{
glutBitmapCharacter ( fnt, *str ) ;
str++ ;
}
}
static void puDrawCursor ( int x, int y )
{
glColor4fv ( _puCursor_bgcolour ) ;
glBegin ( GL_TRIANGLES ) ;
glVertex2i ( x, y ) ;
glVertex2i ( x + 13, y - 4 ) ;
glVertex2i ( x + 4, y - 13 ) ;
glVertex2i ( x + 8, y - 3 ) ;
glVertex2i ( x + 17, y - 12 ) ;
glVertex2i ( x + 12, y - 17 ) ;
glVertex2i ( x + 12, y - 17 ) ;
glVertex2i ( x + 3, y - 8 ) ;
glVertex2i ( x + 8, y - 3 ) ;
glEnd () ;
glColor4fv ( _puCursor_fgcolour ) ;
glBegin ( GL_TRIANGLES ) ;
glVertex2i ( x+1, y-1 ) ;
glVertex2i ( x + 11, y - 4 ) ;
glVertex2i ( x + 4, y - 11 ) ;
glVertex2i ( x + 8, y - 5 ) ;
glVertex2i ( x + 15, y - 12 ) ;
glVertex2i ( x + 12, y - 15 ) ;
glVertex2i ( x + 12, y - 15 ) ;
glVertex2i ( x + 5, y - 8 ) ;
glVertex2i ( x + 8, y - 5 ) ;
glEnd () ;
}
void puInit ( void )
{
static int firsttime = TRUE ;
if ( firsttime )
{
puInterface *base_interface = new puInterface ( 0, 0 ) ;
puPushInterface ( base_interface ) ;
puPushLiveInterface ( base_interface ) ;
firsttime = FALSE ;
}
}
static void puSetOpenGLState ( void )
{
int w = glutGet ( (GLenum) GLUT_WINDOW_WIDTH ) ;
int h = glutGet ( (GLenum) GLUT_WINDOW_HEIGHT ) ;
glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_TRANSFORM_BIT ) ;
glDisable ( GL_LIGHTING ) ;
glDisable ( GL_FOG ) ;
glDisable ( GL_TEXTURE_2D ) ;
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_CULL_FACE ) ;
glViewport ( 0, 0, w, h ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPushMatrix () ;
glLoadIdentity () ;
gluOrtho2D ( 0, w, 0, h ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glPushMatrix () ;
glLoadIdentity () ;
}
static void puRestoreOpenGLState ( void )
{
glMatrixMode ( GL_PROJECTION ) ;
glPopMatrix () ;
glMatrixMode ( GL_MODELVIEW ) ;
glPopMatrix () ;
glPopAttrib () ;
}
void puDisplay ( void )
{
puSetOpenGLState () ;
puGetUltimateLiveInterface () -> draw ( 0, 0 ) ;
if ( _puCursor_enable )
puDrawCursor ( _puCursor_x,
glutGet((GLenum)GLUT_WINDOW_HEIGHT) - _puCursor_y ) ;
puRestoreOpenGLState () ;
}
int puKeyboard ( int key, int updown )
{
return puGetBaseLiveInterface () -> checkKey ( key, updown ) ;
}
static int last_buttons = 0 ;
int puMouse ( int button, int updown, int x, int y )
{
puCursor ( x, y ) ;
if ( updown == PU_DOWN )
last_buttons |= ( 1 << button ) ;
else
last_buttons &= ~( 1 << button ) ;
return puGetBaseLiveInterface () -> checkHit ( button, updown, x,
glutGet((GLenum)GLUT_WINDOW_HEIGHT) - y ) ;
}
int puMouse ( int x, int y )
{
puCursor ( x, y ) ;
if ( last_buttons == 0 )
return FALSE ;
int button = (last_buttons & (1<<PU_LEFT_BUTTON )) ? PU_LEFT_BUTTON :
(last_buttons & (1<<PU_MIDDLE_BUTTON)) ? PU_MIDDLE_BUTTON :
(last_buttons & (1<<PU_RIGHT_BUTTON )) ? PU_RIGHT_BUTTON : 0 ;
return puGetBaseLiveInterface () -> checkHit ( button, PU_DRAG, x,
glutGet((GLenum)GLUT_WINDOW_HEIGHT) - y ) ;
}

744
PUI/pu.h Normal file
View File

@ -0,0 +1,744 @@
#ifndef _PU_H_
#define _PU_H_
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glut.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/*
Webster's Dictionary (for American English) permits
Color or Colour as acceptable spellings - but
The Oxford English Dictionary (for English) only
permits Colour.
Hence, the logical thing to do is to use 'colour',
which *ought* to be acceptable on both sides of
the atlantic.
However, as a concession to the illogical:
*/
#define setColorScheme setColourScheme
#define setColor setColour
#define getColor getColour
#define puColor puColour
#define puSetColor puSetColour
#define puSetDefaultColorScheme puSetDefaultColourScheme
#define puGetDefaultColorScheme puGetDefaultColourScheme
typedef void *puFont ;
#define PUFONT_8_BY_13 GLUT_BITMAP_8_BY_13
#define PUFONT_9_BY_15 GLUT_BITMAP_9_BY_15
#define PUFONT_TIMES_ROMAN_10 GLUT_BITMAP_TIMES_ROMAN_10
#define PUFONT_TIMES_ROMAN_24 GLUT_BITMAP_TIMES_ROMAN_24
#define PUFONT_HELVETICA_10 GLUT_BITMAP_HELVETICA_10
#define PUFONT_HELVETICA_12 GLUT_BITMAP_HELVETICA_12
#define PUFONT_HELVETICA_18 GLUT_BITMAP_HELVETICA_18
#define PU_LEFT_BUTTON GLUT_LEFT_BUTTON
#define PU_MIDDLE_BUTTON GLUT_MIDDLE_BUTTON
#define PU_RIGHT_BUTTON GLUT_RIGHT_BUTTON
#define PU_DOWN GLUT_DOWN
#define PU_UP GLUT_UP
#define PU_UP_AND_DOWN 254
#define PU_DRAG 255
#define PU_CONTINUAL PU_DRAG
#define PU_KEY_GLUT_SPECIAL_OFFSET 256
#define PU_KEY_F1 (GLUT_KEY_F1 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F2 (GLUT_KEY_F2 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F3 (GLUT_KEY_F3 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F4 (GLUT_KEY_F4 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F5 (GLUT_KEY_F5 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F6 (GLUT_KEY_F6 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F7 (GLUT_KEY_F7 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F8 (GLUT_KEY_F8 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F9 (GLUT_KEY_F9 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F10 (GLUT_KEY_F10 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F11 (GLUT_KEY_F11 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F12 (GLUT_KEY_F12 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_LEFT (GLUT_KEY_LEFT + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_UP (GLUT_KEY_UP + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_RIGHT (GLUT_KEY_RIGHT + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_DOWN (GLUT_KEY_DOWN + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_PAGE_UP (GLUT_KEY_PAGE_UP + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_PAGE_DOWN (GLUT_KEY_PAGE_DOWN + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_HOME (GLUT_KEY_HOME + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_END (GLUT_KEY_END + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_INSERT (GLUT_KEY_INSERT + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PUPLACE_DEFAULT PUPLACE_RIGHT
#define PUPLACE_ABOVE 0
#define PUPLACE_BELOW 1
#define PUPLACE_LEFT 2
#define PUPLACE_RIGHT 3
#define PUCOL_FOREGROUND 0
#define PUCOL_BACKGROUND 1
#define PUCOL_HIGHLIGHT 2
#define PUCOL_LABEL 3
#define PUCOL_LEGEND 4
#define PUCOL_MAX 5
#define PUSLIDER_CLICK 0
#define PUSLIDER_ALWAYS 1
#define PUSLIDER_DELTA 2
/* These styles may be negated to get 'highlighted' graphics */
#define PUSTYLE_DEFAULT PUSTYLE_BEVELLED
#define PUSTYLE_NONE 0
#define PUSTYLE_PLAIN 1
#define PUSTYLE_BEVELLED 2
#define PUSTYLE_BOXED 3
#define PUSTYLE_DROPSHADOW 4
#define PUSTYLE_SPECIAL_UNDERLINED 5
#define PUSTYLE_SMALL_BEVELLED 6
#define PUSTYLE_RADIO 7
#define PUSTYLE_MAX 8
/* These are the gaps that we try to leave around text objects */
#define PUSTR_TGAP 5
#define PUSTR_BGAP 5
#define PUSTR_LGAP 5
#define PUSTR_RGAP 5
#define PUSTR_MAX_HEIGHT ( 25 + PUSTR_TGAP + PUSTR_BGAP )
#define PU_RADIO_BUTTON_SIZE 16
extern int puRefresh ;
#define PUCLASS_VALUE 0x00000001
#define PUCLASS_OBJECT 0x00000002
#define PUCLASS_INTERFACE 0x00000004
#define PUCLASS_FRAME 0x00000008
#define PUCLASS_TEXT 0x00000010
#define PUCLASS_BUTTON 0x00000020
#define PUCLASS_ONESHOT 0x00000040
#define PUCLASS_POPUP 0x00000080
#define PUCLASS_POPUPMENU 0x00000100
#define PUCLASS_MENUBAR 0x00000200
#define PUCLASS_INPUT 0x00000400
#define PUCLASS_BUTTONBOX 0x00000800
#define PUCLASS_SLIDER 0x00001000
#define PUCLASS_DIALOGBOX 0x00002000
class puValue ;
class puObject ;
class puInterface ;
class puButtonBox ;
class puFrame ;
class puText ;
class puButton ;
class puOneShot ;
class puPopup ;
class puPopupMenu ;
class puMenuBar ;
class puInput ;
class puSlider ;
typedef float puColour [ 4 ] ; /* RGBA */
struct puBox
{
int min [ 2 ] ;
int max [ 2 ] ;
void draw ( int dx, int dy, int style, puColour colour[], int am_default ) ;
void extend ( puBox *bx ) ;
void empty ( void ) { min[0]=min[1]=1000000 ; max[0]=max[1]=-1000000 ; }
int isEmpty ( void ) { return min[0]>max[0] || min[1]>max[1] ; }
} ;
#define PUSTRING_MAX 80
/* If you change - or add to these, be sure to change _puDefaultColourTable */
extern puColour _puDefaultColourTable[] ;
inline void puSetColour ( puColour dst, puColour src )
{
dst[0] = src[0] ; dst[1] = src[1] ; dst[2] = src[2] ; dst[3] = src[3] ;
}
inline void puSetColour ( puColour c, float r, float g, float b, float a = 1.0f )
{
c [ 0 ] = r ; c [ 1 ] = g ; c [ 2 ] = b ; c [ 3 ] = a ;
}
void puInit ( void ) ;
void puDisplay ( void ) ;
int puMouse ( int button, int updown, int x, int y ) ;
int puMouse ( int x, int y ) ;
int puKeyboard ( int key, int updown ) ;
void puHideCursor ( void ) ;
void puShowCursor ( void ) ;
int puCursorIsHidden ( void ) ;
void puDrawString ( puFont fnt, char *str, int x, int y ) ;
int puGetStringWidth ( puFont fnt, char *str ) ;
int puGetStringHeight ( puFont fnt = NULL ) ;
int puGetStringDescender ( puFont fnt = NULL ) ;
class puValue
{
protected:
int type ;
int integer ;
float floater ;
char string [ PUSTRING_MAX ] ;
public:
puValue () { type = PUCLASS_VALUE ; clrValue () ; }
virtual ~puValue () ;
int getType ( void ) { return type ; }
char *getTypeString ( void ) ;
void clrValue ( void ) { setValue ( "" ) ; }
void setValue ( puValue *pv )
{
integer = pv -> integer ;
floater = pv -> floater ;
strcpy ( string, pv -> string ) ;
puRefresh = TRUE ;
}
void setValue ( int i ) { integer = i ; floater = (float) i ; sprintf ( string, "%d", i ) ; puRefresh = TRUE ; }
void setValue ( float f ) { integer = (int) f ; floater = f ; sprintf ( string, "%g", f ) ; puRefresh = TRUE ; }
void setValue ( char *s ) {
if ( s == NULL || s[0] == '\0' )
{
integer = 0 ;
floater = 0.0f ;
s = "" ;
}
else
{
integer = atoi(s) ;
floater = atof(s) ;
if ( string != s ) strcpy ( string, s ) ;
}
puRefresh = TRUE ;
}
void getValue ( int *i ) { *i = integer ; }
void getValue ( float *f ) { *f = floater ; }
void getValue ( char **s ) { *s = string ; }
void getValue ( char *s ) { strcpy ( s, string ) ; }
int getValue ( void ) { return integer ; }
} ;
typedef void (*puCallback)(class puObject *) ;
void puSetDefaultStyle ( int style ) ;
int puGetDefaultStyle ( void ) ;
void puSetDefaultFonts ( puFont legendFont, puFont labelFont ) ;
void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont ) ;
void puSetDefaultColourScheme ( float r, float g, float b, float a = 1.0 ) ;
void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a = NULL );
class puObject : public puValue
{
protected:
puValue default_value ;
puBox bbox ; /* Bounding box of entire Object */
puBox abox ; /* Active (clickable) area */
puColour colour [ PUCOL_MAX ] ;
puInterface *parent ;
int active_mouse_edge ; /* is it PU_UP or PU_DOWN (or both) that activates this? */
int style ;
int visible ;
int active ;
int highlighted ;
int am_default ;
char *label ; puFont labelFont ; int labelPlace ;
char *legend ; puFont legendFont ;
void *user_data ;
puCallback cb ;
virtual void draw_label ( int dx, int dy ) ;
virtual int isHit ( int x, int y ) { return isVisible() && isActive() &&
x >= abox.min[0] &&
x <= abox.max[0] &&
y >= abox.min[1] &&
y <= abox.max[1] ; }
virtual void doHit ( int button, int updown, int x, int y ) ;
public:
puObject ( int minx, int miny, int maxx, int maxy ) ;
~puObject () ;
puObject *next ;
puObject *prev ;
puBox *getBBox ( void ) { return & bbox ; }
puBox *getABox ( void ) { return & abox ; }
void setPosition ( int x, int y )
{
if ( abox.isEmpty() )
{
abox.max[0] = abox.min[0] = x ;
abox.max[1] = abox.min[1] = y ;
}
else
{
abox.max[0] += x - abox.min[0] ;
abox.max[1] += y - abox.min[1] ;
abox.min[0] = x ;
abox.min[1] = y ;
}
recalc_bbox() ; puRefresh = TRUE ;
}
void setSize ( int w, int h )
{
abox.max[0] = abox.min[0] + w ;
abox.max[1] = abox.min[1] + h ;
recalc_bbox() ; puRefresh = TRUE ;
}
void getPosition ( int *x, int *y )
{
if ( abox . isEmpty () )
{
if ( x ) *x = 0 ;
if ( y ) *y = 0 ;
}
else
{
if ( x ) *x = abox.min[0] ;
if ( y ) *y = abox.min[1] ;
}
}
void getSize ( int *w, int *h )
{
if ( abox . isEmpty () )
{
if ( w ) *w = 0 ;
if ( h ) *h = 0 ;
}
else
{
if ( w ) *w = abox.max[0] - abox.min[0] ;
if ( h ) *h = abox.max[1] - abox.min[1] ;
}
}
virtual void recalc_bbox ( void ) ;
virtual int checkHit ( int button, int updown, int x, int y ) ;
virtual int checkKey ( int key , int updown ) ;
virtual void draw ( int dx, int dy ) = 0 ;
puInterface *getParent ( void ) { return parent ; }
puObject *getNextObject ( void ) { return next ; }
puObject *getPrevObject ( void ) { return prev ; }
void setCallback ( puCallback c ) { cb = c ; }
puCallback getCallback ( void ) { return cb ; }
void invokeCallback ( void ) { if ( cb ) (*cb)(this) ; }
void makeReturnDefault ( int def ) { am_default = def ; }
int isReturnDefault ( void ) { return am_default ; }
void setActiveDirn ( int e ) { active_mouse_edge = e ; }
int getActiveDirn ( void ) { return active_mouse_edge ; }
void setLegend ( char *l ) { legend = l ; recalc_bbox() ; puRefresh = TRUE ; }
char *getLegend ( void ) { return legend ; }
void setLegendFont ( puFont f ) { legendFont = f ; recalc_bbox() ; puRefresh = TRUE ; }
puFont getLegendFont ( void ) { return legendFont ; }
void setLabel ( char *l ) { label = l ; recalc_bbox() ; puRefresh = TRUE ; }
char *getLabel ( void ) { return label ; }
void setLabelFont ( puFont f ) { labelFont = f ; recalc_bbox() ; puRefresh = TRUE ; }
puFont getLabelFont ( void ) { return labelFont ; }
void setLabelPlace ( int lp ) { labelPlace = lp ; recalc_bbox() ; puRefresh = TRUE ; }
int getLabelPlace ( void ) { return labelPlace ; }
void activate ( void ) { if ( ! active ) { active = TRUE ; puRefresh = TRUE ; } }
void greyOut ( void ) { if ( active ) { active = FALSE ; puRefresh = TRUE ; } }
int isActive ( void ) { return active ; }
void highlight ( void ) { if ( ! highlighted ) { highlighted = TRUE ; puRefresh = TRUE ; } }
void lowlight ( void ) { if ( highlighted ) { highlighted = FALSE ; puRefresh = TRUE ; } }
int isHighlighted( void ){ return highlighted ; }
void reveal ( void ) { if ( ! visible ) { visible = TRUE ; puRefresh = TRUE ; } }
void hide ( void ) { if ( visible ) { visible = FALSE ; puRefresh = TRUE ; } }
int isVisible ( void ) { return visible ; }
void setStyle ( int which )
{
style = which ;
recalc_bbox () ;
puRefresh = TRUE ;
}
int getStyle ( void ) { return style ; }
void setColourScheme ( float r, float g, float b, float a = 1.0f ) ;
void setColour ( int which, float r, float g, float b, float a = 1.0f )
{
puSetColour ( colour [ which ], r, g, b, a ) ;
puRefresh = TRUE ;
}
void getColour ( int which, float *r, float *g, float *b, float *a = NULL )
{
if ( r ) *r = colour[which][0] ;
if ( g ) *g = colour[which][1] ;
if ( b ) *b = colour[which][2] ;
if ( a ) *a = colour[which][3] ;
}
void setUserData ( void *data ) { user_data = data ; }
void *getUserData ( void ) { return user_data ; }
void defaultValue ( void ) { setValue ( & default_value ) ; }
void setDefaultValue ( int i ) { default_value . setValue ( i ) ; }
void setDefaultValue ( float f ) { default_value . setValue ( f ) ; }
void setDefaultValue ( char *s ) { default_value . setValue ( s ) ; }
void getDefaultValue ( int *i ) { default_value . getValue ( i ) ; }
void getDefaultValue ( float *f ) { default_value . getValue ( f ) ; }
void getDefaultValue ( char **s ) { default_value . getValue ( s ) ; }
int getDefaultValue ( void ) { return default_value . getValue () ; }
} ;
/*
The 'live' interface stack is used for clicking and rendering.
*/
void puPushLiveInterface ( puInterface *in ) ;
void puPopLiveInterface ( void ) ;
int puNoLiveInterface ( void ) ;
puInterface *puGetBaseLiveInterface ( void ) ;
puInterface *puGetUltimateLiveInterface ( void ) ;
/*
The regular interface stack is used for adding widgets
*/
void puPushInterface ( puInterface *in ) ;
void puPopInterface ( void ) ;
int puNoInterface ( void ) ;
puInterface *puGetCurrInterface ( void ) ;
class puInterface : public puObject
{
protected:
int num_children ;
puObject *dlist ;
void doHit ( int button, int updown, int x, int y ) ;
public:
puInterface ( int x, int y ) : puObject ( x, y, x, y )
{
type |= PUCLASS_INTERFACE ;
dlist = NULL ;
num_children = 0 ;
puPushInterface ( this ) ;
puPushLiveInterface ( this ) ;
}
~puInterface () ;
void recalc_bbox ( void ) ;
virtual void add ( puObject *new_object ) ;
virtual void remove ( puObject *old_object ) ;
void draw ( int dx, int dy ) ;
int checkHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key , int updown ) ;
puObject *getFirstChild ( void ) { return dlist ; }
int getNumChildren ( void ) { return num_children ; }
virtual void close ( void )
{
if ( puGetCurrInterface () != this )
fprintf ( stderr, "PUI: puInterface::close() is mismatched!\n" ) ;
else
puPopInterface () ;
}
} ;
class puFrame : public puObject
{
protected:
virtual int isHit ( int /* x */, int /* y */ ) { return FALSE ; }
public:
void draw ( int dx, int dy ) ;
puFrame ( int minx, int miny, int maxx, int maxy ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_FRAME ;
}
} ;
class puText : public puObject
{
protected:
virtual int isHit ( int /* x */, int /* y */ ) { return FALSE ; }
public:
void draw ( int dx, int dy ) ;
puText ( int x, int y ) : puObject ( x, y, x, y )
{
type |= PUCLASS_TEXT ;
}
} ;
class puButton : public puObject
{
protected:
public:
void doHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
puButton ( int minx, int miny, char *l ) :
puObject ( minx, miny,
minx + puGetStringWidth ( NULL, l ) + PUSTR_LGAP + PUSTR_RGAP,
miny + puGetStringHeight () + puGetStringDescender () + PUSTR_TGAP + PUSTR_BGAP )
{
type |= PUCLASS_BUTTON ;
setLegend ( l ) ;
}
puButton ( int minx, int miny, int maxx, int maxy ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_BUTTON ;
}
} ;
class puSlider : public puObject
{
protected:
int vert ;
float last_cb_value ;
float cb_delta ;
int cb_mode ;
float slider_fraction ;
public:
void doHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
puSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
puObject ( minx, miny, vertical ?
( minx + puGetStringWidth ( NULL, "W" ) +
PUSTR_LGAP + PUSTR_RGAP ) :
( minx + sz ),
vertical ?
( miny + sz ) :
( miny + puGetStringHeight () +
puGetStringDescender () +
PUSTR_TGAP + PUSTR_BGAP )
)
{
type |= PUCLASS_SLIDER ;
slider_fraction = 0.1f ;
getValue ( & last_cb_value ) ;
vert = vertical ;
cb_delta = 0.1f ;
cb_mode = PUSLIDER_ALWAYS ;
}
void setCBMode ( int m ) { cb_mode = m ; }
float getCBMode ( void ) { return cb_mode ; }
int isVertical ( void ) { return vert ; }
void setDelta ( float f ) { cb_delta = (f<=0.0f) ? 0.1f : (f>=1.0) ? 0.9 : f ; }
float getDelta ( void ) { return cb_delta ; }
void setSliderFraction ( float f ) { slider_fraction = (f<=0.0f) ? 0.1f : (f>=1.0) ? 0.9 : f ; }
float getSliderFraction ( void ) { return slider_fraction ; }
} ;
class puOneShot : public puButton
{
protected:
public:
void doHit ( int button, int updown, int x, int y ) ;
puOneShot ( int minx, int miny, char *l ) : puButton ( minx, miny, l )
{
type |= PUCLASS_ONESHOT ;
}
puOneShot ( int minx, int miny, int maxx, int maxy ) :
puButton ( minx, miny, maxx, maxy )
{
type |= PUCLASS_ONESHOT ;
}
} ;
class puPopup : public puInterface
{
protected:
public:
puPopup ( int x, int y ) : puInterface ( x, y )
{
type |= PUCLASS_POPUP ;
hide () ;
}
} ;
class puPopupMenu : public puPopup
{
protected:
public:
puPopupMenu ( int x, int y ) : puPopup ( x, y )
{
type |= PUCLASS_POPUPMENU ;
}
puObject *add_item ( char *str, puCallback cb ) ;
int checkHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key , int updown ) ;
void close ( void ) ;
} ;
class puMenuBar : public puInterface
{
protected:
public:
puMenuBar ( int h = -1 ) :
puInterface ( 0, h < 0 ? glutGet((GLenum) GLUT_WINDOW_HEIGHT ) -
( puGetStringHeight() + PUSTR_TGAP + PUSTR_BGAP ) : h )
{
type |= PUCLASS_MENUBAR ;
}
void add_submenu ( char *str, char *items[], puCallback cb[] ) ;
void close ( void ) ;
} ;
class puInput : public puObject
{
int accepting ;
int cursor_position ;
int select_start_position ;
int select_end_position ;
void normalize_cursors ( void ) ;
public:
void draw ( int dx, int dy ) ;
void doHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key, int updown ) ;
int isAcceptingInput ( void ) { return accepting ; }
void rejectInput ( void ) { accepting = FALSE ; }
void acceptInput ( void ) { accepting = TRUE ;
cursor_position = strlen ( string ) ;
select_start_position = select_end_position = -1 ; }
int getCursor ( void ) { return cursor_position ; }
void setCursor ( int c ) { cursor_position = c ; }
void setSelectRegion ( int s, int e )
{
select_start_position = s ;
select_end_position = e ;
}
void getSelectRegion ( int *s, int *e )
{
if ( s ) *s = select_start_position ;
if ( e ) *e = select_end_position ;
}
puInput ( int minx, int miny, int maxx, int maxy ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_INPUT ;
accepting = FALSE ;
cursor_position = 0 ;
select_start_position = -1 ;
select_end_position = -1 ;
setColourScheme ( 0.8, 0.7, 0.7 ) ; /* Yeukky Pink */
}
} ;
class puButtonBox : public puObject
{
protected:
int one_only ;
int num_kids ;
char **button_labels ;
public:
puButtonBox ( int minx, int miny, int maxx, int maxy,
char **labels, int one_button ) ;
int isOneButton ( void ) { return one_only ; }
int checkKey ( int key , int updown ) ;
int checkHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
} ;
class puDialogBox : public puPopup
{
protected:
public:
puDialogBox ( int x, int y ) : puPopup ( x, y )
{
type |= PUCLASS_DIALOGBOX ;
}
} ;
#endif

193
PUI/puBox.cxx Normal file
View File

@ -0,0 +1,193 @@
#include "puLocal.h"
#define PU_BEVEL 5
#define PU_SMALL_BEVEL 2
#define PU_DFLT_OFFSET 8
#define PU_BOX_WIDTH 2
#define PU_DROPSHADOW_OFFSET 10
void puBox::extend ( puBox *bx )
{
if ( bx -> isEmpty () ) return ;
if ( min[0]>bx->min[0] ) min[0] = bx->min[0] ;
if ( min[1]>bx->min[1] ) min[1] = bx->min[1] ;
if ( max[0]<bx->max[0] ) max[0] = bx->max[0] ;
if ( max[1]<bx->max[1] ) max[1] = bx->max[1] ;
}
void puBox::draw ( int dx, int dy, int style, puColour colour[], int am_default )
{
int hi, mid, lo ;
/* Colour assignments */
switch ( style )
{
case PUSTYLE_NONE :
return ;
case PUSTYLE_PLAIN :
case PUSTYLE_DROPSHADOW :
mid = PUCOL_FOREGROUND ;
lo = PUCOL_BACKGROUND ;
break ;
case PUSTYLE_SMALL_BEVELLED :
case PUSTYLE_BEVELLED :
case PUSTYLE_BOXED :
case PUSTYLE_SPECIAL_UNDERLINED :
mid = PUCOL_FOREGROUND ;
hi = PUCOL_HIGHLIGHT ;
lo = PUCOL_BACKGROUND ;
break ;
case PUSTYLE_RADIO :
case -PUSTYLE_RADIO :
hi = PUCOL_HIGHLIGHT ;
lo = PUCOL_BACKGROUND ;
break ;
case -PUSTYLE_PLAIN :
case -PUSTYLE_DROPSHADOW :
mid = PUCOL_HIGHLIGHT ;
lo = PUCOL_BACKGROUND ;
break ;
case -PUSTYLE_SMALL_BEVELLED :
case -PUSTYLE_BEVELLED :
case -PUSTYLE_BOXED :
case -PUSTYLE_SPECIAL_UNDERLINED :
mid = PUCOL_FOREGROUND ;
hi = PUCOL_BACKGROUND ;
lo = PUCOL_HIGHLIGHT ;
break ;
default :
fprintf ( stderr, "PUI: Unrecognised 'style' %d\n", style ) ;
return ;
}
switch ( abs(style) )
{
case PUSTYLE_PLAIN :
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + max[1] ) ;
break ;
case PUSTYLE_SMALL_BEVELLED :
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
glVertex2i ( dx + min[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glEnd () ;
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0], dy + min[1] ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
glEnd () ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0] + PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL,
dx + max[0] - PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
break ;
case PUSTYLE_BEVELLED :
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_BEVEL, dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
glVertex2i ( dx + min[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glEnd () ;
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_BEVEL, dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + max[0], dy + min[1] ) ;
glVertex2i ( dx + max[0] - PU_BEVEL, dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
glEnd () ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0] + PU_BEVEL, dy + min[1] + PU_BEVEL,
dx + max[0] - PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
break ;
case PUSTYLE_BOXED :
glColor4fv ( colour [ hi ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + max[1] ) ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0]+PU_BOX_WIDTH, dy + min[1]+PU_BOX_WIDTH,
dx + max[0]-PU_BOX_WIDTH, dy + max[1]-PU_BOX_WIDTH ) ;
break ;
case PUSTYLE_RADIO :
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_LINE_LOOP ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + PU_RADIO_BUTTON_SIZE ) ;
glVertex2i ( dx + min[0] , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glEnd () ;
if ( style < 0 )
{
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUADS ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + 2 ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE-2, dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + PU_RADIO_BUTTON_SIZE-2 ) ;
glVertex2i ( dx + min[0] + 2 , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glEnd () ;
}
break ;
case PUSTYLE_SPECIAL_UNDERLINED :
glColor4fv ( colour [ hi ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + min[1]+2 ) ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0], dy + min[1]+1,
dx + max[0], dy + max[1] ) ;
break ;
case PUSTYLE_DROPSHADOW :
glColor4fv ( colour [ lo ] ) ;
glRecti ( dx + min[0] + PU_DROPSHADOW_OFFSET, dy + min[1] - PU_DROPSHADOW_OFFSET,
dx + max[0] + PU_DROPSHADOW_OFFSET, dy + max[1] - PU_DROPSHADOW_OFFSET ) ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + max[1] ) ;
break ;
}
if ( am_default )
{
glColor4fv ( colour [ PUCOL_BACKGROUND ] ) ;
glLineStipple ( 1, 0xF0F0 ) ;
glEnable ( GL_LINE_STIPPLE ) ;
glBegin ( GL_LINE_LOOP ) ;
glVertex2i ( dx + min[0] + PU_DFLT_OFFSET, dy + min[1] + PU_DFLT_OFFSET ) ;
glVertex2i ( dx + min[0] + PU_DFLT_OFFSET, dy + max[1] - PU_DFLT_OFFSET ) ;
glVertex2i ( dx + max[0] - PU_DFLT_OFFSET, dy + max[1] - PU_DFLT_OFFSET ) ;
glVertex2i ( dx + max[0] - PU_DFLT_OFFSET, dy + min[1] + PU_DFLT_OFFSET ) ;
glEnd () ;
glDisable ( GL_LINE_STIPPLE ) ;
}
}

50
PUI/puButton.cxx Normal file
View File

@ -0,0 +1,50 @@
#include "puLocal.h"
void puButton::draw ( int dx, int dy )
{
if ( !visible ) return ;
/* If button is pushed or highlighted - use inverse style for button itself */
abox . draw ( dx, dy, ( getValue() ^ highlighted ) ? -style : style, colour,
isReturnDefault() ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0 ) ; /* 50% more transparent */
int xx = ( abox.max[0] - abox.min[0] - puGetStringWidth(legendFont,legend) ) / 2 ;
int yy = ( abox.max[1] - abox.min[1] - puGetStringHeight(legendFont) ) / 2 ;
puDrawString ( legendFont, legend,
dx + abox.min[0] + xx,
dy + abox.min[1] + yy ) ;
draw_label ( dx, dy ) ;
}
void puButton::doHit ( int button, int updown, int, int )
{
if ( button == PU_LEFT_BUTTON )
{
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN )
{
lowlight () ;
setValue ( (int) ! getValue () ) ;
invokeCallback () ;
}
else
highlight () ;
}
else
lowlight () ;
}

100
PUI/puButtonBox.cxx Normal file
View File

@ -0,0 +1,100 @@
#include "puLocal.h"
puButtonBox::puButtonBox ( int minx, int miny, int maxx, int maxy,
char **labels, int one_button ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_BUTTONBOX ;
one_only = one_button ;
button_labels = labels ;
for ( num_kids = 0 ; button_labels [ num_kids ] != NULL ; num_kids++ )
/* Count number of labels */ ;
}
int puButtonBox::checkKey ( int key, int updown )
{
if ( updown == PU_UP ||
! isReturnDefault() ||
( key != '\r' && key != '\n' ) )
return FALSE ;
int v = getValue () ;
if ( ! one_only )
v = ~v ;
else
if ( v++ > num_kids )
v = 0 ;
setValue ( v ) ;
invokeCallback() ;
return TRUE ;
}
int puButtonBox::checkHit ( int button, int updown, int x, int y )
{
if ( ! isHit ( x, y ) ||
( updown != active_mouse_edge &&
active_mouse_edge != PU_UP_AND_DOWN ) )
return FALSE ;
int i = num_kids - 1 - (( y - abox.min[1] - PUSTR_BGAP ) * num_kids ) /
( abox.max[1] - abox.min[1] - PUSTR_BGAP - PUSTR_TGAP ) ;
if ( i < 0 ) i = 0 ;
if ( i >= num_kids ) i = num_kids - 1 ;
if ( one_only )
setValue ( i ) ;
else
setValue ( getValue () ^ ( 1 << i ) ) ;
invokeCallback () ;
return TRUE ;
}
void puButtonBox::draw ( int dx, int dy )
{
if ( !visible ) return ;
abox . draw ( dx, dy, style, colour, isReturnDefault() ) ;
for ( int i = 0 ; i < num_kids ; i++ )
{
puBox tbox ;
tbox . min [ 0 ] = abox.min [ 0 ] + PUSTR_LGAP + PUSTR_LGAP ;
tbox . min [ 1 ] = abox.min [ 1 ] + ((abox.max[1]-abox.min[1]-PUSTR_TGAP-PUSTR_BGAP)/num_kids) * (num_kids-1-i) ;
tbox . max [ 0 ] = tbox.min [ 0 ] ;
tbox . max [ 1 ] = tbox.min [ 1 ] ;
if (( one_only && i == getValue() ) ||
( !one_only && ((1<<i) & getValue() ) != 0 ) )
tbox . draw ( dx, dy + PUSTR_BGAP + PUSTR_BGAP, -PUSTYLE_RADIO, colour, FALSE ) ;
else
tbox . draw ( dx, dy + PUSTR_BGAP + PUSTR_BGAP, PUSTYLE_RADIO, colour, FALSE ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0 ) ; /* 50% more transparent */
puDrawString ( legendFont, button_labels[i],
dx + tbox.min[0] + PU_RADIO_BUTTON_SIZE + PUSTR_LGAP,
dy + tbox.min[1] + puGetStringDescender(legendFont) + PUSTR_BGAP + PUSTR_BGAP) ;
}
draw_label ( dx, dy ) ;
}

4
PUI/puDialogBox.cxx Normal file
View File

@ -0,0 +1,4 @@
#include "puLocal.h"

30
PUI/puFrame.cxx Normal file
View File

@ -0,0 +1,30 @@
#include "puLocal.h"
void puFrame::draw ( int dx, int dy )
{
if ( !visible ) return ;
abox . draw ( dx, dy, style, colour, FALSE ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0 ) ; /* 50% more transparent */
int xx = ( abox.max[0] - abox.min[0] - puGetStringWidth ( legendFont, legend ) ) / 2 ;
puDrawString ( legendFont, legend,
dx + abox.min[0] + xx,
dy + abox.min[1] + puGetStringDescender ( legendFont ) + PUSTR_BGAP ) ;
draw_label ( dx, dy ) ;
}

225
PUI/puInput.cxx Normal file
View File

@ -0,0 +1,225 @@
#include "puLocal.h"
void puInput::normalize_cursors ( void )
{
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
int sl = strlen ( val ) ;
/* Clamp the positions to the limits of the text. */
if ( cursor_position < 0 ) cursor_position = 0 ;
if ( select_start_position < 0 ) select_start_position = 0 ;
if ( select_end_position < 0 ) select_end_position = 0 ;
if ( cursor_position > sl ) cursor_position = sl ;
if ( select_start_position > sl ) select_start_position = sl ;
if ( select_end_position > sl ) select_end_position = sl ;
/* Swap the ends of the select window if they get crossed over */
if ( select_end_position < select_start_position )
{
int tmp = select_end_position ;
select_end_position = select_start_position ;
select_start_position = tmp ;
}
}
void puInput::draw ( int dx, int dy )
{
normalize_cursors () ;
if ( !visible ) return ;
/* 3D Input boxes look nicest if they are always in inverse style. */
abox . draw ( dx, dy, (style==PUSTYLE_SMALL_BEVELLED) ? -style :
(accepting ? -style : style ), colour, FALSE ) ;
int xx = puGetStringWidth ( legendFont, " " ) ;
int yy = ( abox.max[1] - abox.min[1] - puGetStringHeight(legendFont) ) / 2 ;
if ( accepting )
{
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
/* Highlight the select area */
if ( select_end_position > 0 &&
select_end_position != select_start_position )
{
val [ select_end_position ] = '\0' ;
int cpos2 = puGetStringWidth ( legendFont, val ) + xx + dx + abox.min[0] ;
val [ select_start_position ] = '\0' ;
int cpos1 = puGetStringWidth ( legendFont, val ) + xx + dx + abox.min[0] ;
glColor3f ( 1.0, 1.0, 0.7 ) ;
glRecti ( cpos1, dy + abox.min[1] + 6 ,
cpos2, dy + abox.max[1] - 6 ) ;
}
}
/* Draw the text */
{
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0 ) ; /* 50% more transparent */
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
puDrawString ( legendFont, val,
dx + abox.min[0] + xx,
dy + abox.min[1] + yy ) ;
draw_label ( dx, dy ) ;
}
if ( accepting )
{
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
/* Draw the 'I' bar cursor. */
if ( cursor_position >= 0 )
{
val [ cursor_position ] = '\0' ;
int cpos = puGetStringWidth ( legendFont, val ) + xx + dx + abox.min[0] ;
glColor3f ( 0.1, 0.1, 1.0 ) ;
glBegin ( GL_LINES ) ;
glVertex2i ( cpos , dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos , dy + abox.max[1] - 7 ) ;
glVertex2i ( cpos - 1, dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos - 1, dy + abox.max[1] - 7 ) ;
glVertex2i ( cpos - 4, dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos + 3, dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos - 4, dy + abox.max[1] - 7 ) ;
glVertex2i ( cpos + 3, dy + abox.max[1] - 7 ) ;
glEnd () ;
}
}
}
void puInput::doHit ( int button, int updown, int x, int /* y */ )
{
if ( button == PU_LEFT_BUTTON )
{
/* Most GUI's activate a button on button-UP not button-DOWN. */
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN )
{
lowlight () ;
char *strval ;
getValue ( & strval ) ;
char *tmpval = new char [ strlen(strval) + 1 ] ;
strcpy ( tmpval, strval ) ;
int i = strlen ( tmpval ) ;
while ( x <= puGetStringWidth ( legendFont, tmpval ) + abox.min[0] &&
i >= 0 )
tmpval[--i] = '\0' ;
accepting = TRUE ;
cursor_position = i ;
normalize_cursors () ;
invokeCallback () ;
}
else
highlight () ;
}
else
lowlight () ;
}
int puInput::checkKey ( int key, int updown )
{
(updown,updown);
if ( ! isAcceptingInput() || ! isActive () || ! isVisible () )
return FALSE ;
normalize_cursors () ;
char *p ;
switch ( key )
{
case PU_KEY_PAGE_UP :
case PU_KEY_PAGE_DOWN :
case PU_KEY_INSERT : return FALSE ;
case PU_KEY_UP :
case PU_KEY_DOWN :
case 0x1B /* ESC */ :
case '\t' :
case '\r' :
case '\n' : /* Carriage return/Line Feed/TAB -- End of input */
rejectInput () ;
normalize_cursors () ;
invokeCallback () ;
break ;
case '\b' : /* Backspace */
if ( cursor_position > 0 )
for ( p = & string [ --cursor_position ] ; *p != '\0' ; p++ )
*p = *(p+1) ;
break ;
case 0x7F : /* DEL */
if ( select_start_position != select_end_position )
{
char *p1 = & string [ select_start_position ] ;
char *p2 = & string [ select_end_position ] ;
while ( *p1 != '\0' )
*p1++ = *p2++ ;
select_end_position = select_start_position ;
}
else
for ( p = & string [ cursor_position ] ; *p != '\0' ; p++ )
*p = *(p+1) ;
break ;
case 0x15 /* ^U */ : string [ 0 ] = '\0' ; break ;
case PU_KEY_HOME : cursor_position = 0 ; break ;
case PU_KEY_END : cursor_position = PUSTRING_MAX ; break ;
case PU_KEY_LEFT : cursor_position-- ; break ;
case PU_KEY_RIGHT : cursor_position++ ; break ;
default:
if ( key < ' ' || key > 127 ) return FALSE ;
if ( strlen ( string ) >= PUSTRING_MAX )
return FALSE ;
for ( p = & string [ strlen(string) ] ;
p != &string[cursor_position] ; p-- )
*(p+1) = *p ;
*p = key ;
cursor_position++ ;
break ;
}
setValue ( string ) ;
normalize_cursors () ;
return TRUE ;
}

245
PUI/puInterface.cxx Normal file
View File

@ -0,0 +1,245 @@
#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 ;
}

16
PUI/puLocal.h Normal file
View File

@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <math.h>
#include <GL/glut.h>
#include "pu.h"

83
PUI/puMenuBar.cxx Normal file
View File

@ -0,0 +1,83 @@
#include "puLocal.h"
void drop_down_the_menu ( puObject *b )
{
puPopupMenu *p = (puPopupMenu *) b -> getUserData () ;
if ( b -> getValue () )
p->reveal () ;
else
p->hide () ;
for ( puObject *child = b -> getParent () -> getFirstChild () ;
child != NULL ; child = child -> next )
{
if (( child -> getType() & PUCLASS_BUTTON ) != 0 && child != b ) child -> clrValue () ;
if (( child -> getType() & PUCLASS_POPUPMENU ) != 0 && child != p ) child -> hide () ;
}
}
void puMenuBar::add_submenu ( char *str, char *items[], puCallback cb[] )
{
int w, h ;
getSize ( &w, &h ) ;
puOneShot *b = new puOneShot ( w+10, 0, str ) ;
b -> setStyle ( PUSTYLE_SPECIAL_UNDERLINED ) ;
b -> setColourScheme ( colour[PUCOL_FOREGROUND][0],
colour[PUCOL_FOREGROUND][1],
colour[PUCOL_FOREGROUND][2],
colour[PUCOL_FOREGROUND][3] ) ;
b -> setCallback ( drop_down_the_menu ) ;
b -> setActiveDirn ( PU_UP_AND_DOWN ) ;
puPopupMenu *p = new puPopupMenu ( w+10, 0 ) ;
b -> setUserData ( p ) ;
for ( int i = 0 ; items[i] != NULL ; i++ )
p -> add_item ( items[i], cb[i] ) ;
p->close () ;
recalc_bbox () ;
}
void puMenuBar::close (void)
{
puInterface::close () ;
if ( dlist == NULL )
return ;
int width = 0 ;
puObject *ob ;
/*
Use alternate objects - which gets the puOneShot/puPopupMenu pairs
*/
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
{
int w, h ;
/* Reposition the button so it looks nice */
ob -> getSize ( &w, &h ) ;
ob -> setPosition ( width, 0 ) ;
ob = ob -> next ;
/* Reposition the submenu so it sits under the button */
int w2, h2 ;
ob -> getSize ( &w2, &h2 ) ;
ob -> setPosition ( width, -h2 ) ;
/* Next please! */
width += w ;
}
recalc_bbox () ;
}

222
PUI/puObject.cxx Normal file
View File

@ -0,0 +1,222 @@
#include "puLocal.h"
inline float clamp01 ( float x )
{
return (x >= 1.0) ? 1.0 : x ;
}
static void load_colour_scheme ( float col[][4], float r, float g,
float b, float a )
{
puSetColour ( col [ PUCOL_FOREGROUND ], r, g, b, a ) ;
puSetColour ( col [ PUCOL_BACKGROUND ], r/2, g/2, b/2, a ) ;
puSetColour ( col [ PUCOL_HIGHLIGHT ], clamp01(r*1.3), clamp01(g*1.3),
clamp01(b*1.3), a ) ;
if ( 4 * g + 3 * r + b > 0.5 )
puSetColour ( col [ PUCOL_LEGEND ], 0.0, 0.0, 0.0, a ) ;
else
puSetColour ( col [ PUCOL_LEGEND ], 1.0, 1.0, 1.0, a ) ;
}
static int defaultStyle = PUSTYLE_DEFAULT ;
static puFont defaultLegendFont = NULL ;
static puFont defaultLabelFont = NULL ;
static float defaultColourScheme [ 4 ] ;
void puSetDefaultStyle ( int style ) { defaultStyle = style ; }
int puGetDefaultStyle ( void ) { return defaultStyle ; }
void puSetDefaultFonts ( puFont legendFont, puFont labelFont )
{
defaultLegendFont = legendFont ;
defaultLabelFont = labelFont ;
}
void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont )
{
if ( legendFont ) *legendFont = defaultLegendFont ;
if ( labelFont ) *labelFont = defaultLabelFont ;
}
void puSetDefaultColourScheme ( float r, float g, float b, float a )
{
defaultColourScheme[0] = r ;
defaultColourScheme[1] = g ;
defaultColourScheme[2] = b ;
defaultColourScheme[3] = a ;
load_colour_scheme ( _puDefaultColourTable, r, g, b, a ) ;
}
void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a )
{
if ( r ) *r = defaultColourScheme[0] ;
if ( g ) *g = defaultColourScheme[1] ;
if ( b ) *b = defaultColourScheme[2] ;
if ( a ) *a = defaultColourScheme[3] ;
}
void puObject::setColourScheme ( float r, float g, float b, float a )
{
load_colour_scheme ( colour, r, g, b, a ) ;
}
puObject::puObject ( int minx, int miny, int maxx, int maxy ) : puValue ()
{
type |= PUCLASS_OBJECT ;
bbox.min[0] = abox.min[0] = minx ;
bbox.min[1] = abox.min[1] = miny ;
bbox.max[0] = abox.max[0] = maxx ;
bbox.max[1] = abox.max[1] = maxy ;
active_mouse_edge = PU_UP ;
style = defaultStyle ;
visible = active = TRUE ;
highlighted = FALSE ;
am_default = FALSE ;
cb = NULL ;
user_data = NULL ;
next = prev = NULL ;
label = NULL ;
labelPlace = PUPLACE_DEFAULT ;
labelFont = defaultLabelFont ;
legend = NULL ;
legendFont = defaultLegendFont ;
for ( int i = 0 ; i < PUCOL_MAX ; i++ )
puSetColour ( colour[i], _puDefaultColourTable[i] ) ;
if ( ! puNoInterface() )
{
parent = puGetCurrInterface() ;
parent -> add ( this ) ;
}
else
parent = NULL ;
}
puObject::~puObject ()
{
if ( parent != this && parent != NULL )
parent -> remove ( this ) ;
}
void puObject::recalc_bbox ( void )
{
bbox = abox ;
if ( label != NULL )
switch ( labelPlace )
{
case PUPLACE_ABOVE : bbox.max[1] += puGetStringHeight ( getLabelFont() ) + puGetStringDescender ( getLabelFont () ) + PUSTR_TGAP + PUSTR_BGAP ; break ;
case PUPLACE_BELOW : bbox.min[1] -= puGetStringHeight ( getLabelFont() ) + puGetStringDescender ( getLabelFont () ) + PUSTR_TGAP + PUSTR_BGAP ; break ;
case PUPLACE_LEFT : bbox.min[0] -= puGetStringWidth ( getLabelFont(), getLabel() ) + PUSTR_LGAP + PUSTR_RGAP ; break ;
case PUPLACE_RIGHT : bbox.max[0] += puGetStringWidth ( getLabelFont(), getLabel() ) + PUSTR_LGAP + PUSTR_RGAP ; break ;
}
if ( parent != NULL )
parent -> recalc_bbox () ;
}
void puObject::draw_label ( int dx, int dy )
{
if ( !visible ) return ;
/* If greyed out then halve the opacity when drawing the label */
if ( active )
glColor4fv ( colour [ PUCOL_LABEL ] ) ;
else
glColor4f ( colour [ PUCOL_LABEL ][0],
colour [ PUCOL_LABEL ][1],
colour [ PUCOL_LABEL ][2],
colour [ PUCOL_LABEL ][3] / 2.0 ) ; /* 50% more transparent */
switch ( labelPlace )
{
case PUPLACE_ABOVE : puDrawString ( labelFont, label, dx + abox.min[0] + PUSTR_LGAP, dy + abox.max[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
case PUPLACE_BELOW : puDrawString ( labelFont, label, dx + abox.min[0] + PUSTR_LGAP, dy + bbox.min[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
case PUPLACE_LEFT : puDrawString ( labelFont, label, dx + bbox.min[0] + PUSTR_LGAP, dy + abox.min[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
case PUPLACE_RIGHT : puDrawString ( labelFont, label, dx + abox.max[0] + PUSTR_LGAP, dy + abox.min[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
}
}
int puObject::checkKey ( int key, int updown )
{
if ( updown == PU_UP )
return FALSE ;
if ( isReturnDefault() && ( key == '\r' || key == '\n' ) )
{
checkHit ( PU_LEFT_BUTTON, PU_DOWN, (abox.min[0]+abox.max[0])/2,
(abox.min[1]+abox.max[1])/2 ) ;
checkHit ( PU_LEFT_BUTTON, PU_UP , (abox.min[0]+abox.max[0])/2,
(abox.min[1]+abox.max[1])/2 ) ;
return TRUE ;
}
return FALSE ;
}
void puObject::doHit ( int button, int updown, int x, int y )
{
(x,x);(y,y);
if ( button == PU_LEFT_BUTTON )
{
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN )
{
lowlight () ;
invokeCallback () ;
}
else
highlight () ;
}
else
lowlight () ;
}
int puObject::checkHit ( int button, int updown, int x, int y )
{
if ( isHit( x, y ) )
{
doHit ( button, updown, x, y ) ;
return TRUE ;
}
lowlight () ;
return FALSE ;
}
char *puValue::getTypeString ( void )
{
int i = getType () ;
if ( i & PUCLASS_DIALOGBOX ) return "puDialogBox" ;
if ( i & PUCLASS_SLIDER ) return "puSlider" ;
if ( i & PUCLASS_BUTTONBOX ) return "puButtonBox" ;
if ( i & PUCLASS_INPUT ) return "puInput" ;
if ( i & PUCLASS_MENUBAR ) return "puMenuBar" ;
if ( i & PUCLASS_POPUPMENU ) return "puPopupMenu" ;
if ( i & PUCLASS_POPUP ) return "puPopup" ;
if ( i & PUCLASS_ONESHOT ) return "puOneShot" ;
if ( i & PUCLASS_BUTTON ) return "puButton" ;
if ( i & PUCLASS_TEXT ) return "puText" ;
if ( i & PUCLASS_FRAME ) return "puFrame" ;
if ( i & PUCLASS_INTERFACE ) return "puInterface" ;
if ( i & PUCLASS_OBJECT ) return "puObject" ;
if ( i & PUCLASS_VALUE ) return "puValue" ;
return "Unknown Object type." ;
}

9
PUI/puOneShot.cxx Normal file
View File

@ -0,0 +1,9 @@
#include "puLocal.h"
void puOneShot::doHit ( int button, int updown, int x, int y )
{
puButton::doHit ( button, updown, x, y ) ;
setValue ( 0 ) ;
}

3
PUI/puPopup.cxx Normal file
View File

@ -0,0 +1,3 @@
#include "puLocal.h"

127
PUI/puPopupMenu.cxx Normal file
View File

@ -0,0 +1,127 @@
#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 ;
}

106
PUI/puSlider.cxx Normal file
View File

@ -0,0 +1,106 @@
#include "puLocal.h"
void puSlider::draw ( int dx, int dy )
{
if ( !visible ) return ;
abox . draw ( dx, dy,
style==PUSTYLE_BEVELLED ? -PUSTYLE_BOXED : -style,
colour, FALSE ) ;
int sd, od ;
if ( isVertical() ) { sd = 1 ; od = 0 ; } else { sd = 0 ; od = 1 ; }
int sz = abox.max [sd] - abox.min [sd] ;
float val ;
getValue ( & val ) ;
if ( val < 0.0f ) val = 0.0f ;
if ( val > 1.0f ) val = 1.0f ;
val *= (float) sz * (1.0f - slider_fraction) ;
puBox bx ;
bx . min [ sd ] = abox . min [ sd ] + (int) val ;
bx . max [ sd ] = (int) ( (float) bx . min [ sd ] + (float) sz * slider_fraction ) ;
bx . min [ od ] = abox . min [ od ] + 2 ;
bx . max [ od ] = abox . max [ od ] - 2 ;
bx . draw ( dx, dy, PUSTYLE_SMALL_BEVELLED, colour, FALSE ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0 ) ; /* 50% more transparent */
int xx = ( abox.max[0] - abox.min[0] - puGetStringWidth(legendFont,legend) ) / 2 ;
int yy = ( abox.max[1] - abox.min[1] - puGetStringHeight(legendFont) ) / 2 ;
puDrawString ( legendFont, legend,
dx + abox.min[0] + xx,
dy + abox.min[1] + yy ) ;
draw_label ( dx, dy ) ;
}
void puSlider::doHit ( int button, int updown, int x, int y )
{
if ( button == PU_LEFT_BUTTON )
{
int sd = isVertical() ;
int sz = abox.max [sd] - abox.min [sd] ;
int coord = isVertical() ? y : x ;
float next_value ;
if ( sz == 0 )
next_value = 0.5f ;
else
{
next_value = ( (float)coord - (float)abox.min[sd] - (float)sz * slider_fraction / 2.0f ) /
( (float) sz * (1.0f - slider_fraction) ) ;
}
next_value = (next_value < 0.0f) ? 0.0f : (next_value > 1.0) ? 1.0f : next_value ;
setValue ( next_value ) ;
switch ( cb_mode )
{
case PUSLIDER_CLICK :
if ( updown == active_mouse_edge )
{
last_cb_value = next_value ;
invokeCallback () ;
}
break ;
case PUSLIDER_DELTA :
if ( fabs ( last_cb_value - next_value ) >= cb_delta )
{
last_cb_value = next_value ;
invokeCallback () ;
}
break ;
case PUSLIDER_ALWAYS :
default :
last_cb_value = next_value ;
invokeCallback () ;
break ;
}
}
}

8
PUI/puText.cxx Normal file
View File

@ -0,0 +1,8 @@
#include "puLocal.h"
void puText::draw ( int dx, int dy )
{
draw_label ( dx, dy ) ;
}