23 Webster's Dictionary (for American English) permits
24 Color or Colour as acceptable spellings - but
25 The Oxford English Dictionary (for English) only
28 Hence, the logical thing to do is to use 'colour',
29 which *ought* to be acceptable on both sides of
32 However, as a concession to the illogical:
35 #define setColorScheme setColourScheme
36 #define setColor setColour
37 #define getColor getColour
38 #define puColor puColour
39 #define puSetColor puSetColour
40 #define puSetDefaultColorScheme puSetDefaultColourScheme
41 #define puGetDefaultColorScheme puGetDefaultColourScheme
44 typedef void *puFont ;
46 #define PUFONT_8_BY_13 GLUT_BITMAP_8_BY_13
47 #define PUFONT_9_BY_15 GLUT_BITMAP_9_BY_15
48 #define PUFONT_TIMES_ROMAN_10 GLUT_BITMAP_TIMES_ROMAN_10
49 #define PUFONT_TIMES_ROMAN_24 GLUT_BITMAP_TIMES_ROMAN_24
50 #define PUFONT_HELVETICA_10 GLUT_BITMAP_HELVETICA_10
51 #define PUFONT_HELVETICA_12 GLUT_BITMAP_HELVETICA_12
52 #define PUFONT_HELVETICA_18 GLUT_BITMAP_HELVETICA_18
54 #define PU_LEFT_BUTTON GLUT_LEFT_BUTTON
55 #define PU_MIDDLE_BUTTON GLUT_MIDDLE_BUTTON
56 #define PU_RIGHT_BUTTON GLUT_RIGHT_BUTTON
57 #define PU_DOWN GLUT_DOWN
59 #define PU_UP_AND_DOWN 254
61 #define PU_CONTINUAL PU_DRAG
63 #define PU_KEY_GLUT_SPECIAL_OFFSET 256
64 #define PU_KEY_F1 (GLUT_KEY_F1 + PU_KEY_GLUT_SPECIAL_OFFSET)
65 #define PU_KEY_F2 (GLUT_KEY_F2 + PU_KEY_GLUT_SPECIAL_OFFSET)
66 #define PU_KEY_F3 (GLUT_KEY_F3 + PU_KEY_GLUT_SPECIAL_OFFSET)
67 #define PU_KEY_F4 (GLUT_KEY_F4 + PU_KEY_GLUT_SPECIAL_OFFSET)
68 #define PU_KEY_F5 (GLUT_KEY_F5 + PU_KEY_GLUT_SPECIAL_OFFSET)
69 #define PU_KEY_F6 (GLUT_KEY_F6 + PU_KEY_GLUT_SPECIAL_OFFSET)
70 #define PU_KEY_F7 (GLUT_KEY_F7 + PU_KEY_GLUT_SPECIAL_OFFSET)
71 #define PU_KEY_F8 (GLUT_KEY_F8 + PU_KEY_GLUT_SPECIAL_OFFSET)
72 #define PU_KEY_F9 (GLUT_KEY_F9 + PU_KEY_GLUT_SPECIAL_OFFSET)
73 #define PU_KEY_F10 (GLUT_KEY_F10 + PU_KEY_GLUT_SPECIAL_OFFSET)
74 #define PU_KEY_F11 (GLUT_KEY_F11 + PU_KEY_GLUT_SPECIAL_OFFSET)
75 #define PU_KEY_F12 (GLUT_KEY_F12 + PU_KEY_GLUT_SPECIAL_OFFSET)
76 #define PU_KEY_LEFT (GLUT_KEY_LEFT + PU_KEY_GLUT_SPECIAL_OFFSET)
77 #define PU_KEY_UP (GLUT_KEY_UP + PU_KEY_GLUT_SPECIAL_OFFSET)
78 #define PU_KEY_RIGHT (GLUT_KEY_RIGHT + PU_KEY_GLUT_SPECIAL_OFFSET)
79 #define PU_KEY_DOWN (GLUT_KEY_DOWN + PU_KEY_GLUT_SPECIAL_OFFSET)
80 #define PU_KEY_PAGE_UP (GLUT_KEY_PAGE_UP + PU_KEY_GLUT_SPECIAL_OFFSET)
81 #define PU_KEY_PAGE_DOWN (GLUT_KEY_PAGE_DOWN + PU_KEY_GLUT_SPECIAL_OFFSET)
82 #define PU_KEY_HOME (GLUT_KEY_HOME + PU_KEY_GLUT_SPECIAL_OFFSET)
83 #define PU_KEY_END (GLUT_KEY_END + PU_KEY_GLUT_SPECIAL_OFFSET)
84 #define PU_KEY_INSERT (GLUT_KEY_INSERT + PU_KEY_GLUT_SPECIAL_OFFSET)
86 #define PUPLACE_DEFAULT PUPLACE_RIGHT
87 #define PUPLACE_ABOVE 0
88 #define PUPLACE_BELOW 1
89 #define PUPLACE_LEFT 2
90 #define PUPLACE_RIGHT 3
92 #define PUCOL_FOREGROUND 0
93 #define PUCOL_BACKGROUND 1
94 #define PUCOL_HIGHLIGHT 2
96 #define PUCOL_LEGEND 4
99 #define PUSLIDER_CLICK 0
100 #define PUSLIDER_ALWAYS 1
101 #define PUSLIDER_DELTA 2
103 /* These styles may be negated to get 'highlighted' graphics */
105 #define PUSTYLE_DEFAULT PUSTYLE_BEVELLED
106 #define PUSTYLE_NONE 0
107 #define PUSTYLE_PLAIN 1
108 #define PUSTYLE_BEVELLED 2
109 #define PUSTYLE_BOXED 3
110 #define PUSTYLE_DROPSHADOW 4
111 #define PUSTYLE_SPECIAL_UNDERLINED 5
112 #define PUSTYLE_SMALL_BEVELLED 6
113 #define PUSTYLE_RADIO 7
114 #define PUSTYLE_MAX 8
116 /* These are the gaps that we try to leave around text objects */
122 #define PUSTR_MAX_HEIGHT ( 25 + PUSTR_TGAP + PUSTR_BGAP )
124 #define PU_RADIO_BUTTON_SIZE 16
126 extern int puRefresh ;
128 #define PUCLASS_VALUE 0x00000001
129 #define PUCLASS_OBJECT 0x00000002
130 #define PUCLASS_INTERFACE 0x00000004
131 #define PUCLASS_FRAME 0x00000008
132 #define PUCLASS_TEXT 0x00000010
133 #define PUCLASS_BUTTON 0x00000020
134 #define PUCLASS_ONESHOT 0x00000040
135 #define PUCLASS_POPUP 0x00000080
136 #define PUCLASS_POPUPMENU 0x00000100
137 #define PUCLASS_MENUBAR 0x00000200
138 #define PUCLASS_INPUT 0x00000400
139 #define PUCLASS_BUTTONBOX 0x00000800
140 #define PUCLASS_SLIDER 0x00001000
141 #define PUCLASS_DIALOGBOX 0x00002000
157 typedef float puColour [ 4 ] ; /* RGBA */
164 void draw ( int dx, int dy, int style, puColour colour[], int am_default ) ;
165 void extend ( puBox *bx ) ;
167 void empty ( void ) { min[0]=min[1]=1000000 ; max[0]=max[1]=-1000000 ; }
168 int isEmpty ( void ) { return min[0]>max[0] || min[1]>max[1] ; }
171 #define PUSTRING_MAX 80
173 /* If you change - or add to these, be sure to change _puDefaultColourTable */
175 extern puColour _puDefaultColourTable[] ;
178 inline void puSetColour ( puColour dst, puColour src )
180 dst[0] = src[0] ; dst[1] = src[1] ; dst[2] = src[2] ; dst[3] = src[3] ;
183 inline void puSetColour ( puColour c, float r, float g, float b, float a = 1.0f )
185 c [ 0 ] = r ; c [ 1 ] = g ; c [ 2 ] = b ; c [ 3 ] = a ;
189 void puInit ( void ) ;
190 void puDisplay ( void ) ;
191 int puMouse ( int button, int updown, int x, int y ) ;
192 int puMouse ( int x, int y ) ;
193 int puKeyboard ( int key, int updown ) ;
194 void puHideCursor ( void ) ;
195 void puShowCursor ( void ) ;
196 int puCursorIsHidden ( void ) ;
198 void puDrawString ( puFont fnt, char *str, int x, int y ) ;
199 int puGetStringWidth ( puFont fnt, char *str ) ;
200 int puGetStringHeight ( puFont fnt = NULL ) ;
201 int puGetStringDescender ( puFont fnt = NULL ) ;
209 char string [ PUSTRING_MAX ] ;
211 puValue () { type = PUCLASS_VALUE ; clrValue () ; }
213 virtual ~puValue () ;
215 int getType ( void ) { return type ; }
216 char *getTypeString ( void ) ;
217 void clrValue ( void ) { setValue ( "" ) ; }
219 void setValue ( puValue *pv )
221 integer = pv -> integer ;
222 floater = pv -> floater ;
223 strcpy ( string, pv -> string ) ;
227 void setValue ( int i ) { integer = i ; floater = (float) i ; sprintf ( string, "%d", i ) ; puRefresh = TRUE ; }
228 void setValue ( float f ) { integer = (int) f ; floater = f ; sprintf ( string, "%g", f ) ; puRefresh = TRUE ; }
229 void setValue ( char *s ) {
230 if ( s == NULL || s[0] == '\0' )
241 if ( string != s ) strcpy ( string, s ) ;
246 void getValue ( int *i ) { *i = integer ; }
247 void getValue ( float *f ) { *f = floater ; }
248 void getValue ( char **s ) { *s = string ; }
249 void getValue ( char *s ) { strcpy ( s, string ) ; }
251 int getValue ( void ) { return integer ; }
254 typedef void (*puCallback)(class puObject *) ;
256 void puSetDefaultStyle ( int style ) ;
257 int puGetDefaultStyle ( void ) ;
258 void puSetDefaultFonts ( puFont legendFont, puFont labelFont ) ;
259 void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont ) ;
260 void puSetDefaultColourScheme ( float r, float g, float b, float a = 1.0 ) ;
261 void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a = NULL );
263 class puObject : public puValue
266 puValue default_value ;
268 puBox bbox ; /* Bounding box of entire Object */
269 puBox abox ; /* Active (clickable) area */
270 puColour colour [ PUCOL_MAX ] ;
271 puInterface *parent ;
273 int active_mouse_edge ; /* is it PU_UP or PU_DOWN (or both) that activates this? */
280 char *label ; puFont labelFont ; int labelPlace ;
281 char *legend ; puFont legendFont ;
286 virtual void draw_label ( int dx, int dy ) ;
287 virtual int isHit ( int x, int y ) { return isVisible() && isActive() &&
292 virtual void doHit ( int button, int updown, int x, int y ) ;
295 puObject ( int minx, int miny, int maxx, int maxy ) ;
301 puBox *getBBox ( void ) { return & bbox ; }
302 puBox *getABox ( void ) { return & abox ; }
304 void setPosition ( int x, int y )
306 if ( abox.isEmpty() )
308 abox.max[0] = abox.min[0] = x ;
309 abox.max[1] = abox.min[1] = y ;
313 abox.max[0] += x - abox.min[0] ;
314 abox.max[1] += y - abox.min[1] ;
318 recalc_bbox() ; puRefresh = TRUE ;
321 void setSize ( int w, int h )
323 abox.max[0] = abox.min[0] + w ;
324 abox.max[1] = abox.min[1] + h ;
325 recalc_bbox() ; puRefresh = TRUE ;
328 void getPosition ( int *x, int *y )
330 if ( abox . isEmpty () )
337 if ( x ) *x = abox.min[0] ;
338 if ( y ) *y = abox.min[1] ;
342 void getSize ( int *w, int *h )
344 if ( abox . isEmpty () )
351 if ( w ) *w = abox.max[0] - abox.min[0] ;
352 if ( h ) *h = abox.max[1] - abox.min[1] ;
356 virtual void recalc_bbox ( void ) ;
357 virtual int checkHit ( int button, int updown, int x, int y ) ;
358 virtual int checkKey ( int key , int updown ) ;
359 virtual void draw ( int dx, int dy ) = 0 ;
361 puInterface *getParent ( void ) { return parent ; }
362 puObject *getNextObject ( void ) { return next ; }
363 puObject *getPrevObject ( void ) { return prev ; }
365 void setCallback ( puCallback c ) { cb = c ; }
366 puCallback getCallback ( void ) { return cb ; }
367 void invokeCallback ( void ) { if ( cb ) (*cb)(this) ; }
369 void makeReturnDefault ( int def ) { am_default = def ; }
370 int isReturnDefault ( void ) { return am_default ; }
372 void setActiveDirn ( int e ) { active_mouse_edge = e ; }
373 int getActiveDirn ( void ) { return active_mouse_edge ; }
375 void setLegend ( char *l ) { legend = l ; recalc_bbox() ; puRefresh = TRUE ; }
376 char *getLegend ( void ) { return legend ; }
378 void setLegendFont ( puFont f ) { legendFont = f ; recalc_bbox() ; puRefresh = TRUE ; }
379 puFont getLegendFont ( void ) { return legendFont ; }
381 void setLabel ( char *l ) { label = l ; recalc_bbox() ; puRefresh = TRUE ; }
382 char *getLabel ( void ) { return label ; }
384 void setLabelFont ( puFont f ) { labelFont = f ; recalc_bbox() ; puRefresh = TRUE ; }
385 puFont getLabelFont ( void ) { return labelFont ; }
387 void setLabelPlace ( int lp ) { labelPlace = lp ; recalc_bbox() ; puRefresh = TRUE ; }
388 int getLabelPlace ( void ) { return labelPlace ; }
390 void activate ( void ) { if ( ! active ) { active = TRUE ; puRefresh = TRUE ; } }
391 void greyOut ( void ) { if ( active ) { active = FALSE ; puRefresh = TRUE ; } }
392 int isActive ( void ) { return active ; }
394 void highlight ( void ) { if ( ! highlighted ) { highlighted = TRUE ; puRefresh = TRUE ; } }
395 void lowlight ( void ) { if ( highlighted ) { highlighted = FALSE ; puRefresh = TRUE ; } }
396 int isHighlighted( void ){ return highlighted ; }
398 void reveal ( void ) { if ( ! visible ) { visible = TRUE ; puRefresh = TRUE ; } }
399 void hide ( void ) { if ( visible ) { visible = FALSE ; puRefresh = TRUE ; } }
400 int isVisible ( void ) { return visible ; }
402 void setStyle ( int which )
409 int getStyle ( void ) { return style ; }
411 void setColourScheme ( float r, float g, float b, float a = 1.0f ) ;
413 void setColour ( int which, float r, float g, float b, float a = 1.0f )
415 puSetColour ( colour [ which ], r, g, b, a ) ;
419 void getColour ( int which, float *r, float *g, float *b, float *a = NULL )
421 if ( r ) *r = colour[which][0] ;
422 if ( g ) *g = colour[which][1] ;
423 if ( b ) *b = colour[which][2] ;
424 if ( a ) *a = colour[which][3] ;
427 void setUserData ( void *data ) { user_data = data ; }
428 void *getUserData ( void ) { return user_data ; }
430 void defaultValue ( void ) { setValue ( & default_value ) ; }
432 void setDefaultValue ( int i ) { default_value . setValue ( i ) ; }
433 void setDefaultValue ( float f ) { default_value . setValue ( f ) ; }
434 void setDefaultValue ( char *s ) { default_value . setValue ( s ) ; }
436 void getDefaultValue ( int *i ) { default_value . getValue ( i ) ; }
437 void getDefaultValue ( float *f ) { default_value . getValue ( f ) ; }
438 void getDefaultValue ( char **s ) { default_value . getValue ( s ) ; }
439 int getDefaultValue ( void ) { return default_value . getValue () ; }
443 The 'live' interface stack is used for clicking and rendering.
446 void puPushLiveInterface ( puInterface *in ) ;
447 void puPopLiveInterface ( void ) ;
448 int puNoLiveInterface ( void ) ;
449 puInterface *puGetBaseLiveInterface ( void ) ;
450 puInterface *puGetUltimateLiveInterface ( void ) ;
453 The regular interface stack is used for adding widgets
456 void puPushInterface ( puInterface *in ) ;
457 void puPopInterface ( void ) ;
458 int puNoInterface ( void ) ;
459 puInterface *puGetCurrInterface ( void ) ;
461 class puInterface : public puObject
467 void doHit ( int button, int updown, int x, int y ) ;
471 puInterface ( int x, int y ) : puObject ( x, y, x, y )
473 type |= PUCLASS_INTERFACE ;
476 puPushInterface ( this ) ;
477 puPushLiveInterface ( this ) ;
482 void recalc_bbox ( void ) ;
483 virtual void add ( puObject *new_object ) ;
484 virtual void remove ( puObject *old_object ) ;
486 void draw ( int dx, int dy ) ;
487 int checkHit ( int button, int updown, int x, int y ) ;
488 int checkKey ( int key , int updown ) ;
490 puObject *getFirstChild ( void ) { return dlist ; }
491 int getNumChildren ( void ) { return num_children ; }
493 virtual void close ( void )
495 if ( puGetCurrInterface () != this )
496 fprintf ( stderr, "PUI: puInterface::close() is mismatched!\n" ) ;
502 class puFrame : public puObject
505 virtual int isHit ( int /* x */, int /* y */ ) { return FALSE ; }
507 void draw ( int dx, int dy ) ;
508 puFrame ( int minx, int miny, int maxx, int maxy ) :
509 puObject ( minx, miny, maxx, maxy )
511 type |= PUCLASS_FRAME ;
516 class puText : public puObject
519 virtual int isHit ( int /* x */, int /* y */ ) { return FALSE ; }
521 void draw ( int dx, int dy ) ;
522 puText ( int x, int y ) : puObject ( x, y, x, y )
524 type |= PUCLASS_TEXT ;
529 class puButton : public puObject
533 void doHit ( int button, int updown, int x, int y ) ;
534 void draw ( int dx, int dy ) ;
535 puButton ( int minx, int miny, char *l ) :
536 puObject ( minx, miny,
537 minx + puGetStringWidth ( NULL, l ) + PUSTR_LGAP + PUSTR_RGAP,
538 miny + puGetStringHeight () + puGetStringDescender () + PUSTR_TGAP + PUSTR_BGAP )
540 type |= PUCLASS_BUTTON ;
544 puButton ( int minx, int miny, int maxx, int maxy ) :
545 puObject ( minx, miny, maxx, maxy )
547 type |= PUCLASS_BUTTON ;
552 class puSlider : public puObject
556 float last_cb_value ;
559 float slider_fraction ;
561 void doHit ( int button, int updown, int x, int y ) ;
562 void draw ( int dx, int dy ) ;
563 puSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
564 puObject ( minx, miny, vertical ?
565 ( minx + puGetStringWidth ( NULL, "W" ) +
566 PUSTR_LGAP + PUSTR_RGAP ) :
570 ( miny + puGetStringHeight () +
571 puGetStringDescender () +
572 PUSTR_TGAP + PUSTR_BGAP )
575 type |= PUCLASS_SLIDER ;
576 slider_fraction = 0.1f ;
577 getValue ( & last_cb_value ) ;
580 cb_mode = PUSLIDER_ALWAYS ;
583 void setCBMode ( int m ) { cb_mode = m ; }
584 float getCBMode ( void ) { return cb_mode ; }
586 int isVertical ( void ) { return vert ; }
588 void setDelta ( float f ) { cb_delta = (f<=0.0f) ? 0.1f : (f>=1.0) ? 0.9 : f ; }
589 float getDelta ( void ) { return cb_delta ; }
591 void setSliderFraction ( float f ) { slider_fraction = (f<=0.0f) ? 0.1f : (f>=1.0) ? 0.9 : f ; }
592 float getSliderFraction ( void ) { return slider_fraction ; }
597 class puOneShot : public puButton
601 void doHit ( int button, int updown, int x, int y ) ;
603 puOneShot ( int minx, int miny, char *l ) : puButton ( minx, miny, l )
605 type |= PUCLASS_ONESHOT ;
608 puOneShot ( int minx, int miny, int maxx, int maxy ) :
609 puButton ( minx, miny, maxx, maxy )
611 type |= PUCLASS_ONESHOT ;
617 class puPopup : public puInterface
621 puPopup ( int x, int y ) : puInterface ( x, y )
623 type |= PUCLASS_POPUP ;
628 class puPopupMenu : public puPopup
632 puPopupMenu ( int x, int y ) : puPopup ( x, y )
634 type |= PUCLASS_POPUPMENU ;
637 puObject *add_item ( char *str, puCallback cb ) ;
638 int checkHit ( int button, int updown, int x, int y ) ;
639 int checkKey ( int key , int updown ) ;
640 void close ( void ) ;
644 class puMenuBar : public puInterface
648 puMenuBar ( int h = -1 ) :
649 puInterface ( 0, h < 0 ? glutGet((GLenum) GLUT_WINDOW_HEIGHT ) -
650 ( puGetStringHeight() + PUSTR_TGAP + PUSTR_BGAP ) : h )
652 type |= PUCLASS_MENUBAR ;
655 void add_submenu ( char *str, char *items[], puCallback cb[] ) ;
656 void close ( void ) ;
660 class puInput : public puObject
663 int cursor_position ;
664 int select_start_position ;
665 int select_end_position ;
667 void normalize_cursors ( void ) ;
670 void draw ( int dx, int dy ) ;
671 void doHit ( int button, int updown, int x, int y ) ;
672 int checkKey ( int key, int updown ) ;
674 int isAcceptingInput ( void ) { return accepting ; }
675 void rejectInput ( void ) { accepting = FALSE ; }
676 void acceptInput ( void ) { accepting = TRUE ;
677 cursor_position = strlen ( string ) ;
678 select_start_position = select_end_position = -1 ; }
680 int getCursor ( void ) { return cursor_position ; }
681 void setCursor ( int c ) { cursor_position = c ; }
683 void setSelectRegion ( int s, int e )
685 select_start_position = s ;
686 select_end_position = e ;
689 void getSelectRegion ( int *s, int *e )
691 if ( s ) *s = select_start_position ;
692 if ( e ) *e = select_end_position ;
695 puInput ( int minx, int miny, int maxx, int maxy ) :
696 puObject ( minx, miny, maxx, maxy )
698 type |= PUCLASS_INPUT ;
702 cursor_position = 0 ;
703 select_start_position = -1 ;
704 select_end_position = -1 ;
706 setColourScheme ( 0.8, 0.7, 0.7 ) ; /* Yeukky Pink */
711 class puButtonBox : public puObject
716 char **button_labels ;
720 puButtonBox ( int minx, int miny, int maxx, int maxy,
721 char **labels, int one_button ) ;
723 int isOneButton ( void ) { return one_only ; }
725 int checkKey ( int key , int updown ) ;
726 int checkHit ( int button, int updown, int x, int y ) ;
727 void draw ( int dx, int dy ) ;
732 class puDialogBox : public puPopup
737 puDialogBox ( int x, int y ) : puPopup ( x, y )
739 type |= PUCLASS_DIALOGBOX ;