14 /***********************************\
16 * These are the PUI widget pointers *
18 \***********************************/
20 puMenuBar *main_menu_bar ;
21 puButton *hide_menu_button ;
22 puDialogBox *dialog_box ;
23 puText *dialog_box_message ;
24 puOneShot *dialog_box_ok_button ;
26 puSlider *rspeedSlider;
29 /***********************************\
31 * This is a generic tumbling cube *
33 \***********************************/
35 GLfloat light_diffuse [] = {0.0, 1.0, 0.0, 1.0} ; /* Red diffuse light. */
36 GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0} ; /* Infinite light location. */
38 GLfloat cube_n[6][3] = /* Normals */
40 {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
41 { 0.0,-1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0,-1.0}
44 GLint cube_i[6][4] = /* Vertex indices */
46 {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
47 {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3}
50 GLfloat cube_v[8][3] = /* Vertices */
52 {-1.0,-1.0, 1.0}, {-1.0,-1.0,-1.0}, {-1.0, 1.0,-1.0}, {-1.0, 1.0, 1.0},
53 { 1.0,-1.0, 1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, { 1.0, 1.0, 1.0}
65 Deliberately do this only once - it's a better test of
66 PUI's attempts to leave the OpenGL state undisturbed
70 glLightfv ( GL_LIGHT0, GL_DIFFUSE , light_diffuse ) ;
71 glLightfv ( GL_LIGHT0, GL_POSITION, light_position ) ;
72 glEnable ( GL_LIGHT0 ) ;
73 glEnable ( GL_LIGHTING ) ;
74 glEnable ( GL_DEPTH_TEST ) ;
75 glMatrixMode ( GL_PROJECTION ) ;
76 gluPerspective ( 40.0, 1.0, 1.0, 10.0 ) ;
77 glMatrixMode ( GL_MODELVIEW ) ;
78 gluLookAt ( 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ) ;
79 glTranslatef ( 0.0, 0.0, -1.0 ) ;
80 glRotatef ( 60.0, 1.0, 0.0, 0.0 ) ;
83 glCullFace ( GL_FRONT ) ;
84 glEnable ( GL_CULL_FACE ) ;
85 // glRotatef ( 1.0f, 0.0, 0.0, 1.0 ) ; /* Tumble that cube! */
87 glBegin ( GL_QUADS ) ;
89 for ( int i = 0 ; i < 6 ; i++ )
91 glNormal3fv ( &cube_n[i][0] ) ;
92 glVertex3fv ( cube_v[cube_i[i][0]] ) ; glVertex3fv ( cube_v[cube_i[i][1]] ) ;
93 glVertex3fv ( cube_v[cube_i[i][2]] ) ; glVertex3fv ( cube_v[cube_i[i][3]] ) ;
99 /********************************\
101 * End of cube renderer in OpenGL *
103 \********************************/
106 /**************************************\
108 * These three functions capture mouse *
109 * and keystrokes (special and mundane) *
110 * from GLUT and pass them on to PUI. *
112 \**************************************/
114 static void specialfn ( int key, int, int )
116 puKeyboard ( key + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN ) ;
117 glutPostRedisplay () ;
120 static void keyfn ( unsigned char key, int, int )
122 puKeyboard ( key, PU_DOWN ) ;
123 glutPostRedisplay () ;
126 static void motionfn ( int x, int y )
129 glutPostRedisplay () ;
132 static void mousefn ( int button, int updown, int x, int y )
134 puMouse ( button, updown, x, y ) ;
135 glutPostRedisplay () ;
138 /**************************************\
140 * This function redisplays the PUI and *
141 * the tumbling cube, flips the double *
142 * buffer and then asks GLUT to post a *
143 * redisplay command - so we re-render *
146 \**************************************/
148 static void displayfn (void)
150 /* Clear the screen */
152 glClearColor ( 0.0, 0.0, 0.0, 1.0 ) ;
153 glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
155 /* Draw the tumbling cube */
157 float val ; rspeedSlider->getValue ( &val ) ;
159 glRotatef( 4*val, 15.0, 10.0 , 5.0 );
163 /* Update the 'timer' */
165 time_t t = time ( NULL ) ;
166 timer_text -> setLabel ( ctime ( & t ) ) ;
168 /* Make PUI redraw */
172 /* Off we go again... */
175 glutPostRedisplay () ;
179 /***********************************\
181 * Here are the PUI widget callback *
184 \***********************************/
186 void hide_menu_cb ( puObject *cb )
188 if ( cb -> getValue () )
190 main_menu_bar -> reveal () ;
191 hide_menu_button->setLegend ( "Hide Menu" ) ;
195 main_menu_bar -> hide () ;
196 hide_menu_button->setLegend ( "Show Menu" ) ;
201 void go_away_cb ( puObject * )
204 Delete the dialog box when its 'OK' button is pressed.
206 This seems to crash on MSVC compilers - probably because
207 I delete dialog_box - whose member function is calling
208 this function. Hence we return to something that is
209 in a distinctly 'iffy' state.
216 void mk_dialog ( char *txt )
218 dialog_box = new puDialogBox ( 150, 50 ) ;
220 new puFrame ( 0, 0, 400, 100 ) ;
221 dialog_box_message = new puText ( 10, 70 ) ;
222 dialog_box_message -> setLabel ( txt ) ;
223 dialog_box_ok_button = new puOneShot ( 180, 10, 240, 50 ) ;
224 dialog_box_ok_button -> setLegend ( "OK" ) ;
225 dialog_box_ok_button -> makeReturnDefault ( TRUE ) ;
226 dialog_box_ok_button -> setCallback ( go_away_cb ) ;
228 dialog_box -> close () ;
229 dialog_box -> reveal () ;
232 void ni_cb ( puObject * )
234 mk_dialog ( "Sorry, that function isn't implemented" ) ;
237 void about_cb ( puObject * )
239 mk_dialog ( "This is the PUI 'complex' program" ) ;
242 void help_cb ( puObject * )
244 mk_dialog ( "Sorry, no help is available for this demo" ) ;
247 void edit_cb ( puObject * )
251 void exit_cb ( puObject * )
253 fprintf ( stderr, "Exiting PUI demo program.\n" ) ;
257 /* Menu bar entries: */
259 char *file_submenu [] = { "Exit", "Close", "--------", "Print", "--------", "Save", "New", NULL } ;
260 puCallback file_submenu_cb [] = { exit_cb, exit_cb, NULL, ni_cb , NULL, ni_cb, ni_cb, NULL } ;
262 char *edit_submenu [] = { "Edit text", NULL } ;
263 puCallback edit_submenu_cb [] = { edit_cb, NULL } ;
265 char *help_submenu [] = { "About...", "Help", NULL } ;
266 puCallback help_submenu_cb [] = { about_cb, help_cb, NULL } ;
269 void sliderCB( puObject *sliderObj)
274 int main ( int argc, char **argv )
279 glutInitWindowPosition( 0, 0 ) ;
281 glutInitWindowSize ( 640, 480 ) ;
282 glutInit ( &argc, argv ) ;
283 glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;
284 glutCreateWindow ( "Complex PUI Application" ) ;
285 glutDisplayFunc ( displayfn ) ;
286 glutKeyboardFunc ( keyfn ) ;
287 glutSpecialFunc ( specialfn ) ;
288 glutMouseFunc ( mousefn ) ;
289 glutMotionFunc ( motionfn ) ;
290 glutPassiveMotionFunc ( motionfn ) ;
291 glutIdleFunc ( displayfn ) ;
299 puSetDefaultStyle ( PUSTYLE_SMALL_SHADED ) ;
300 puSetDefaultColourScheme ( 0.8, 0.8, 0.8 ) ;
302 timer_text = new puText ( 300, 10 ) ;
303 timer_text -> setColour ( PUCOL_LABEL, 1.0, 1.0, 1.0 ) ;
305 /* Make a button to hide the menu bar */
307 hide_menu_button = new puButton ( 10, 10, 150, 50 ) ;
308 hide_menu_button->setValue ( TRUE ) ;
309 hide_menu_button->setLegend ( "Hide Menu" ) ;
310 hide_menu_button->setCallback ( hide_menu_cb ) ;
311 hide_menu_button->makeReturnDefault ( TRUE ) ;
313 /* Make the menu bar */
315 main_menu_bar = new puMenuBar () ;
317 main_menu_bar -> add_submenu ( "File", file_submenu, file_submenu_cb ) ;
318 main_menu_bar -> add_submenu ( "Edit", edit_submenu, edit_submenu_cb ) ;
319 main_menu_bar -> add_submenu ( "Help", help_submenu, help_submenu_cb ) ;
321 main_menu_bar -> close () ;
323 rspeedSlider = new puSlider (20,80,150,TRUE);
324 rspeedSlider->setDelta(0.1);
325 rspeedSlider->setCBMode( PUSLIDER_DELTA );
326 rspeedSlider->setCallback(sliderCB);