diff options
Diffstat (limited to 'tests/bullet/Extras/glui/glui.cpp')
-rw-r--r-- | tests/bullet/Extras/glui/glui.cpp | 2171 |
1 files changed, 2171 insertions, 0 deletions
diff --git a/tests/bullet/Extras/glui/glui.cpp b/tests/bullet/Extras/glui/glui.cpp new file mode 100644 index 00000000..239b12f5 --- /dev/null +++ b/tests/bullet/Extras/glui/glui.cpp @@ -0,0 +1,2171 @@ +/**************************************************************************** + + GLUI User Interface Toolkit (LGPL) + --------------------------- + + glui.cpp + + -------------------------------------------------- + + Copyright (c) 1998 Paul Rademacher + + WWW: http://sourceforge.net/projects/glui/ + Forums: http://sourceforge.net/forum/?group_id=92496 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ +#include "glui_internal_control.h" + + +/** + Note: moving this routine here from glui_add_controls.cpp prevents the linker + from touching glui_add_controls.o in non-deprecated programs, which + descreases the linked size of small GLUI programs substantially (100K+). (OSL 2006/06) +*/ +void GLUI_Node::add_child_to_control(GLUI_Node *parent,GLUI_Control *child) +{ + GLUI_Control *parent_control; + + /*** Collapsible nodes have to be handled differently, b/c the first and + last children are swapped in and out ***/ + parent_control = ((GLUI_Control*)parent); + if ( parent_control->collapsible == true ) { + if ( NOT parent_control->is_open ) { + /** Swap in the original first and last children **/ + parent_control->child_head = parent_control->collapsed_node.child_head; + parent_control->child_tail = parent_control->collapsed_node.child_tail; + + /*** Link this control ***/ + child->link_this_to_parent_last( parent_control ); + + /** Swap the children back out ***/ + parent_control->collapsed_node.child_head = parent_control->child_head; + parent_control->collapsed_node.child_tail = parent_control->child_tail; + parent_control->child_head = NULL; + parent_control->child_tail = NULL; + } + else { + child->link_this_to_parent_last( parent_control ); + } + } + else { + child->link_this_to_parent_last( parent_control ); + } + child->glui = (GLUI*) parent_control->glui; + child->update_size(); + child->enabled = parent_control->enabled; + child->glui->refresh(); + + /** Now set the 'hidden' var based on the parent **/ + if ( parent_control->hidden OR + (parent_control->collapsible AND NOT parent_control->is_open ) ) + { + child->hidden = true; + } +} + + +/************************************ GLUI_Node::add_control() **************/ + +int GLUI_Node::add_control( GLUI_Control *child ) +{ + add_child_to_control(this,child); + return true; +} + +/************************************ GLUI_Main::add_control() **************/ + +int GLUI_Main::add_control( GLUI_Node *parent, GLUI_Control *control ) +{ + add_child_to_control(parent,control); + return true; +} + + + +/*** This object must be used to create a GLUI ***/ + +GLUI_Master_Object GLUI_Master; + +/************************************ finish_drawing() *********** + Probably a silly routine. Called after all event handling callbacks. +*/ + +static void finish_drawing(void) +{ + glFinish(); +} + +/************************************ GLUI_CB::operator()() ************/ +void GLUI_CB::operator()(GLUI_Control*ctrl) const +{ + if (idCB) idCB(ctrl->user_id); + if (objCB) objCB(ctrl); +} + + +/************************************************ GLUI::GLUI() **********/ + +int GLUI::init( const char *text, long flags, int x, int y, int parent_window ) +{ + int old_glut_window; + + this->flags = flags; + + window_name = text; + + buffer_mode = buffer_back; ///< New smooth way + //buffer_mode = buffer_front; ///< Old flickery way (a bit faster). + + /*** We copy over the current window callthroughs ***/ + /*** (I think this might actually only be needed for subwindows) ***/ + /* glut_keyboard_CB = GLUI_Master.glut_keyboard_CB; + glut_reshape_CB = GLUI_Master.glut_reshape_CB; + glut_special_CB = GLUI_Master.glut_special_CB; + glut_mouse_CB = GLUI_Master.glut_mouse_CB;*/ + + + if ( (flags & GLUI_SUBWINDOW) != GLUI_SUBWINDOW ) { /* not a subwindow, creating a new top-level window */ + old_glut_window = glutGetWindow(); + + create_standalone_window( window_name.c_str(), x, y ); + setup_default_glut_callbacks(); + + if ( old_glut_window > 0 ) + glutSetWindow( old_glut_window ); + + top_level_glut_window_id = glut_window_id; + } + else /* *is* a subwindow */ + { + old_glut_window = glutGetWindow(); + + create_subwindow( parent_window, flags ); + setup_default_glut_callbacks(); + + if ( old_glut_window > 0 ) + glutSetWindow( old_glut_window ); + + top_level_glut_window_id = parent_window; + + /* + glutReshapeFunc( glui_parent_window_reshape_func ); + glutSpecialFunc( glui_parent_window_special_func ); + glutKeyboardFunc( glui_parent_window_keyboard_func ); + glutMouseFunc( glui_parent_window_mouse_func ); + */ + + } + + return true; +} + + +/**************************** GLUI_Main::create_standalone_window() ********/ + +void GLUI_Main::create_standalone_window( const char *name, int x, int y ) +{ + glutInitWindowSize( 100, 100 ); + if ( x >= 0 OR y >= 0 ) + glutInitWindowPosition( x, y ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glut_window_id = glutCreateWindow( name ); +} + + +/******************************** GLUI_Main::create_subwindow() **********/ + +void GLUI_Main::create_subwindow( int parent_window, int window_alignment ) +{ + glut_window_id = glutCreateSubWindow(parent_window, 0,0, 100, 100); + this->parent_window = parent_window; +} + + +/**************************** GLUI_Main::setup_default_glut_callbacks() *****/ + +void GLUI_Main::setup_default_glut_callbacks( void ) +{ + glutDisplayFunc( glui_display_func ); + glutReshapeFunc( glui_reshape_func ); + glutKeyboardFunc( glui_keyboard_func ); + glutSpecialFunc( glui_special_func ); + glutMouseFunc( glui_mouse_func ); + glutMotionFunc( glui_motion_func ); + glutPassiveMotionFunc( glui_passive_motion_func ); + glutEntryFunc( glui_entry_func ); + glutVisibilityFunc( glui_visibility_func ); + /* glutIdleFunc( glui_idle_func ); // FIXME! 100% CPU usage! */ +} + + +/********************************************** glui_display_func() ********/ + +void glui_display_func(void) +{ + GLUI *glui; + + /* printf( "display func\n" ); */ + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->display(); + /* + Do not do anything after the above line, b/c the GLUI + window might have just closed itself + */ + } +} + + +/********************************************** glui_reshape_func() ********/ + +void glui_reshape_func(int w,int h ) +{ + GLUI *glui; + GLUI_Glut_Window *glut_window; + int current_window; + + /*printf( "glui_reshape_func(): %d w/h: %d/%d\n", glutGetWindow(), w, h ); */ + + current_window = glutGetWindow(); + + /*** First check if this is main glut window ***/ + glut_window = GLUI_Master.find_glut_window( current_window ); + if ( glut_window ) { + if (glut_window->glut_reshape_CB) glut_window->glut_reshape_CB(w,h); + + /*** Now send reshape events to all subwindows ***/ + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while(glui) { + if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND + glui->parent_window == current_window ) { + glutSetWindow( glui->get_glut_window_id()); + glui->reshape(w,h); + /* glui->check_subwindow_position(); */ + } + glui = (GLUI*) glui->next(); + } + } + else { + /*** A standalone GLUI window ***/ + + glui = GLUI_Master.find_glui_by_window_id( current_window ); + + if ( glui ) { + glui->reshape(w,h); + } + } +} + +/********************************************** glui_keyboard_func() ********/ + +void glui_keyboard_func(unsigned char key, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + /*printf( "key: %d\n", current_window ); */ + + if ( glut_window ) { /** Was event in a GLUT window? **/ + if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) { + glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() ); + + GLUI_Master.active_control_glui->keyboard(key,x,y); + finish_drawing(); + + glutSetWindow( current_window ); + } + else { + if (glut_window->glut_keyboard_CB) + glut_window->glut_keyboard_CB( key, x, y ); + } + } + else { /*** Nope, event was in a standalone GLUI window **/ + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->keyboard(key,x,y); + finish_drawing(); + } + } +} + + + + +void glui_special_up_func(int key, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + if (glut_window) /** Was event in a GLUT window? **/ + { + if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) + { + glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() ); + + GLUI_Master.active_control_glui->special_up(key,x,y); + finish_drawing(); + + glutSetWindow( current_window ); + } + else + { + if (glut_window->glut_special_up_CB) + glut_window->glut_special_up_CB( key, x, y ); + } + } + else /*** Nope, event was in a standalone GLUI window **/ + { + glui = GLUI_Master.find_glui_by_window_id(glutGetWindow()); + + if ( glui ) + { + glui->special_up(key,x,y); + finish_drawing(); + } + } +} + + + +/************************************************ glui_special_func() ********/ + +void glui_special_func(int key, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + if (glut_window) /** Was event in a GLUT window? **/ + { + if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) + { + glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() ); + + GLUI_Master.active_control_glui->special(key,x,y); + finish_drawing(); + + glutSetWindow( current_window ); + } + else + { + if (glut_window->glut_special_CB) + glut_window->glut_special_CB( key, x, y ); + } + } + else /*** Nope, event was in a standalone GLUI window **/ + { + glui = GLUI_Master.find_glui_by_window_id(glutGetWindow()); + + if ( glui ) + { + glui->special(key,x,y); + finish_drawing(); + } + } +} + +/********************************************** glui_mouse_func() ********/ + +void glui_mouse_func(int button, int state, int x, int y) +{ + GLUI *glui; + int current_window; + GLUI_Glut_Window *glut_window; + + current_window = glutGetWindow(); + glut_window = GLUI_Master.find_glut_window( current_window ); + + if ( glut_window ) { /** Was event in a GLUT window? **/ + if ( GLUI_Master.active_control_glui != NULL ) + GLUI_Master.active_control_glui->deactivate_current_control(); + + if (glut_window->glut_mouse_CB) + glut_window->glut_mouse_CB( button, state, x, y ); + finish_drawing(); + } + else { /** Nope - event was in a GLUI standalone window **/ + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + if ( glui ) { + glui->passive_motion( 0,0 ); + glui->mouse( button, state, x, y ); + finish_drawing(); + } + } +} + + +/********************************************** glui_motion_func() ********/ + +void glui_motion_func(int x, int y) +{ + GLUI *glui; + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->motion(x,y); + finish_drawing(); + } + +} + + +/**************************************** glui_passive_motion_func() ********/ + +void glui_passive_motion_func(int x, int y) +{ + GLUI *glui; + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->passive_motion(x,y); + finish_drawing(); + } +} + + +/********************************************** glui_entry_func() ********/ + +void glui_entry_func(int state) +{ + GLUI *glui; + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->entry(state); + } +} + + +/******************************************** glui_visibility_func() ********/ + +void glui_visibility_func(int state) +{ + GLUI *glui; + + /* printf( "IN GLUI VISIBILITY()\n" ); */ + /* fflush( stdout ); */ + + glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() ); + + if ( glui ) { + glui->visibility(state); + } +} + + +/********************************************** glui_idle_func() ********/ +/* Send idle event to each glui, then to the main window */ + +void glui_idle_func(void) +{ + GLUI *glui; + + glui = (GLUI*) GLUI_Master.gluis.first_child(); + while( glui ) { + glui->idle(); + finish_drawing(); + + glui = (GLUI*) glui->next(); + } + + if ( GLUI_Master.glut_idle_CB ) { + /*** We set the current glut window before calling the user's + idle function, even though glut explicitly says the window id is + undefined in an idle callback. ***/ + + /** Check what the current window is first ***/ + + /*** Arbitrarily set the window id to the main gfx window of the + first glui window ***/ + /* int current_window, new_window; */ + /* current_window = glutGetWindow(); */ + /* if (GLUI_Master.gluis.first_child() != NULL ) { */ + /* new_window = ((GLUI_Main*)GLUI_Master.gluis.first_child())-> */ + /* main_gfx_window_id; */ + /* if ( new_window > 0 AND new_window != old_window ) { */ + /* --- Window is changed only if its not already the current window ---*/ + /* glutSetWindow( new_window ); */ + /* } */ + /*} */ + + GLUI_Master.glut_idle_CB(); + } +} + +/*********************************** GLUI_Master_Object::GLUI_Master_Object() ******/ + +GLUI_Master_Object::GLUI_Master_Object() +: glui_id_counter(1), + glut_idle_CB(NULL) +{ +} + +GLUI_Master_Object::~GLUI_Master_Object() +{ +} + +/*********************************** GLUI_Master_Object::create_glui() ******/ + +GLUI *GLUI_Master_Object::create_glui( const char *name, long flags,int x,int y ) +{ + GLUI *new_glui = new GLUI; + new_glui->init( name, flags, x, y, -1 ); + new_glui->link_this_to_parent_last( &this->gluis ); + return new_glui; +} + + +/************************** GLUI_Master_Object::create_glui_subwindow() ******/ + +GLUI *GLUI_Master_Object::create_glui_subwindow( int parent_window, + long flags ) +{ + GLUI *new_glui = new GLUI; + GLUI_String new_name; + glui_format_str( new_name, "subwin_%p", this ); + + new_glui->init( new_name.c_str(), flags | GLUI_SUBWINDOW, 0,0, + parent_window ); + new_glui->main_panel->set_int_val( GLUI_PANEL_EMBOSSED ); + new_glui->link_this_to_parent_last( &this->gluis ); + return new_glui; +} + + +/********************** GLUI_Master_Object::find_glui_by_window_id() ********/ + +GLUI *GLUI_Master_Object::find_glui_by_window_id( int window_id ) +{ + GLUI_Node *node; + + node = gluis.first_child(); + while( node ) { + if ( ((GLUI*)node)->get_glut_window_id() == window_id ) + return (GLUI*) node; + + node = node->next(); + } + return NULL; +} + + +/******************************************** GLUI_Main::display() **********/ + +void GLUI_Main::display( void ) +{ + int win_w, win_h; + + /* SUBTLE: on freeGLUT, the correct window is always already set. + But older versions of GLUT need this call, or else subwindows + don't update properly when resizing or damage-painting. + */ + glutSetWindow( glut_window_id ); + + /* Set up OpenGL state for widget drawing */ + glDisable( GL_DEPTH_TEST ); + glCullFace( GL_BACK ); + glDisable( GL_CULL_FACE ); + glDisable( GL_LIGHTING ); + set_current_draw_buffer(); + + /**** This function is used as a special place to do 'safe' processing, + e.g., handling window close requests. + That is, we can't close the window directly in the callback, so + we set a flag, post a redisplay message (which eventually calls + this function), then close the window safely in here. ****/ + if ( closing ) { + close_internal(); + return; + } + + /* if ( TEST_AND( this->flags, GLUI_SUBWINDOW )) + check_subwindow_position(); + */ + + win_w = glutGet( GLUT_WINDOW_WIDTH ); + win_h = glutGet( GLUT_WINDOW_HEIGHT ); + + /*** Check here if the window needs resizing ***/ + if ( win_w != main_panel->w OR win_h != main_panel->h ) { + glutReshapeWindow( main_panel->w, main_panel->h ); + return; + } + + /******* Draw GLUI window ******/ + glClearColor( (float) bkgd_color.r / 255.0, + (float) bkgd_color.g / 255.0, + (float) bkgd_color.b / 255.0, + 1.0 ); + glClear( GL_COLOR_BUFFER_BIT ); /* | GL_DEPTH_BUFFER_BIT ); */ + + set_ortho_projection(); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + /*** Rotate image so y increases downward. + In normal OpenGL, y increases upward. ***/ + glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 ); + glRotatef( 180.0, 0.0, 1.0, 0.0 ); + glRotatef( 180.0, 0.0, 0.0, 1.0 ); + glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 ); + + // Recursively draw the main panel + // main_panel->draw_bkgd_box( 0, 0, win_w, win_h ); + main_panel->draw_recursive( 0, 0 ); + + switch (buffer_mode) { + case buffer_front: /* Make sure drawing gets to screen */ + glFlush(); + break; + case buffer_back: /* Bring back buffer to front */ + glutSwapBuffers(); + break; + } +} + + + + +/*************************************** _glutBitmapWidthString() **********/ + +int _glutBitmapWidthString( void *font, const char *s ) +{ + const char *p = s; + int width = 0; + + while( *p != '\0' ) { + width += glutBitmapWidth( font, *p ); + p++; + } + + return width; +} + +/************************************ _glutBitmapString *********************/ +/* Displays the contents of a string using GLUT's bitmap character function */ +/* Does not handle newlines */ + +void _glutBitmapString( void *font, const char *s ) +{ + const char *p = s; + + while( *p != '\0' ) { + glutBitmapCharacter( font, *p ); + p++; + } +} + + + +/****************************** GLUI_Main::reshape() **************/ + +void GLUI_Main::reshape( int reshape_w, int reshape_h ) +{ + int new_w, new_h; + + pack_controls(); + + new_w = main_panel->w;/* + 1; */ + new_h = main_panel->h;/* + 1; */ + + if ( reshape_w != new_w OR reshape_h != new_h ) { + this->w = new_w; + this->h = new_h; + + glutReshapeWindow( new_w, new_h ); + } + else { + } + + if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) { + check_subwindow_position(); + + /***** if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) { + } + ****/ + } + + glViewport( 0, 0, new_w, new_h ); + + /* printf( "%d: %d\n", glutGetWindow(), this->flags ); */ + + glutPostRedisplay(); +} + + +/****************************** GLUI_Main::keyboard() **************/ + +void GLUI_Main::keyboard(unsigned char key, int x, int y) +{ + GLUI_Control *new_control; + + curr_modifiers = glutGetModifiers(); + + /*** If it's a tab or shift tab, we don't pass it on to the controls. + Instead, we use it to cycle through active controls ***/ + if ( key == '\t' AND !mouse_button_down AND + (!active_control || !active_control->wants_tabs())) { + if ( curr_modifiers & GLUT_ACTIVE_SHIFT ) { + new_control = find_prev_control( active_control ); + } + else { + new_control = find_next_control( active_control ); + } + + /* if ( new_control ) + printf( "new_control: %s\n", new_control->name ); + */ + + deactivate_current_control(); + activate_control( new_control, GLUI_ACTIVATE_TAB ); + } + else if ( key == ' ' AND active_control + AND active_control->spacebar_mouse_click ) { + /*** If the user presses the spacebar, and a non-edittext control + is active, we send it a mouse down event followed by a mouse up + event (simulated mouse-click) ***/ + + active_control->mouse_down_handler( 0, 0 ); + active_control->mouse_up_handler( 0, 0, true ); + } else { + /*** Pass the keystroke onto the active control, if any ***/ + if ( active_control != NULL ) + active_control->key_handler( key, curr_modifiers ); + } +} + + + +void GLUI_Main::special_up(int key, int x, int y) +{ + curr_modifiers = glutGetModifiers(); + + /*** Pass the keystroke onto the active control, if any ***/ + if ( active_control != NULL ) + active_control->special_up_handler( key, glutGetModifiers() ); +} + + +/****************************** GLUI_Main::special() **************/ + +void GLUI_Main::special(int key, int x, int y) +{ + curr_modifiers = glutGetModifiers(); + + /*** Pass the keystroke onto the active control, if any ***/ + if ( active_control != NULL ) + active_control->special_handler( key, glutGetModifiers() ); +} + + + +/****************************** GLUI_Main::mouse() **************/ + +void GLUI_Main::mouse(int button, int state, int x, int y) +{ + int callthrough; + GLUI_Control *control; + + /* printf( "MOUSE: %d %d\n", button, state ); */ + + callthrough = true; + + curr_modifiers = glutGetModifiers(); + + if ( button == GLUT_LEFT ) { + control = find_control( x, y ); + + /*if ( control ) printf( "control: %s\n", control->name.c_str() ); */ + + if ( mouse_button_down AND active_control != NULL AND + state == GLUT_UP ) + { + /** We just released the mouse, which was depressed at some control **/ + + callthrough = active_control-> + mouse_up_handler( x, y, control==active_control); + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); + + if ( active_control AND + active_control->active_type == GLUI_CONTROL_ACTIVE_MOUSEDOWN AND 0) + { + /*** This is a control that needs to be deactivated when the + mouse button is released ****/ + deactivate_current_control(); + } + } + else { + if ( control ) { + if ( NOT mouse_button_down AND state == GLUT_DOWN ) { + /*** We just pressed the mouse down at some control ***/ + + if ( active_control != control ) { + if ( active_control != NULL ) { + /** There is an active control still - deactivate it ***/ + deactivate_current_control(); + } + } + + if ( control->enabled ) { + activate_control( control, GLUI_ACTIVATE_MOUSE ); + callthrough = control->mouse_down_handler( x, y ); + } + } + } + } + + if ( state == GLUT_DOWN ) + mouse_button_down = true; + else if ( state == GLUT_UP ) + mouse_button_down = false; + } + + /** + NO CALLTHROUGH NEEDED FOR MOUSE EVENTS + if ( callthrough AND glut_mouse_CB ) + glut_mouse_CB( button, state, x, y ); + **/ + + callthrough=callthrough; /* To get rid of compiler warnings */ +} + + +/****************************** GLUI_Main::motion() **************/ + +void GLUI_Main::motion(int x, int y) +{ + int callthrough; + GLUI_Control *control; + + /* printf( "MOTION: %d %d\n", x, y ); */ + + callthrough = true; + + control = find_control(x,y); + + if ( mouse_button_down AND active_control != NULL ) { + callthrough = + active_control->mouse_held_down_handler(x,y,control==active_control); + } + + /** + NO CALLTHROUGH NEEDED FOR MOUSE EVENTS + + if ( callthrough AND glut_motion_CB ) + glut_motion_CB(x,y); + **/ + + callthrough=callthrough; /* To get rid of compiler warnings */ +} + + +/*********************** GLUI_Main::passive_motion() **************/ + +void GLUI_Main::passive_motion(int x, int y) +{ + GLUI_Control *control; + + control = find_control( x, y ); + + /* printf( "%p %p\n", control, mouse_over_control ); */ + + if ( control != mouse_over_control ) { + if ( mouse_over_control ) { + mouse_over_control->mouse_over( false, x, y ); + } + + if ( control ) { + control->mouse_over( true, x, y ); + mouse_over_control = control; + } + } + + /* + if ( curr_cursor != GLUT_CURSOR_INHERIT ) { + curr_cursor = GLUT_CURSOR_INHERIT; + glutSetCursor( GLUT_CURSOR_INHERIT ); + }*/ + +} + + +/****************************** GLUI_Main::entry() **************/ + +void GLUI_Main::entry(int state) +{ + /*if ( NOT active_control OR ( active_control AND ( active_control->type == GLUI_CONTROL_EDITTEXT + OR active_control->type == GLUI_CONTROL_SPINNER) ) )*/ + glutSetCursor( GLUT_CURSOR_LEFT_ARROW ); +} + + +/****************************** GLUI_Main::visibility() **************/ + +void GLUI_Main::visibility(int state) +{ +} + + +/****************************** GLUI_Main::idle() **************/ + +void GLUI_Main::idle(void) +{ + /*** Pass the idle event onto the active control, if any ***/ + + /* printf( "IDLE \t" ); */ + + if ( active_control != NULL ) { + /* First we check if the control actually needs the idle right now. + Otherwise, let's avoid wasting cycles and OpenGL context switching */ + + if ( active_control->needs_idle() ) { + /*** Set the current glut window to the glui window */ + /*** But don't change the window if we're already at that window ***/ + + if ( glut_window_id > 0 AND glutGetWindow() != glut_window_id ) { + glutSetWindow( glut_window_id ); + } + + active_control->idle(); + } + } +} + +int GLUI_Main::needs_idle( void ) +{ + return active_control != NULL && active_control->needs_idle(); +} + + +/******************************************* GLUI_Main::find_control() ******/ + +GLUI_Control *GLUI_Main::find_control( int x, int y ) +{ + GLUI_Control *node, *last_container; + + last_container = NULL; + + node = main_panel; + while( node != NULL ) { + if ( !node->dynamicCastGLUI_Column() AND + PT_IN_BOX( x, y, + node->x_abs, node->x_abs + node->w, + node->y_abs, node->y_abs + node->h ) + ) + { + /*** Point is inside current node ***/ + + if ( node->first_child() == NULL ) { + /*** SPECIAL CASE: for edittext boxes, we make sure click is + in box, and not on name string. This should be generalized + for all controls later... ***/ + if ( node->dynamicCastGLUI_EditText() ) { + if ( x < node->x_abs + ((GLUI_EditText*)node)->text_x_offset ) + return (GLUI_Control*) node->parent(); + } + + return node; /* point is inside this node, and node has no children, + so return this node as the selected node */ + } + else { + /*** This is a container class ***/ + last_container = node; + node = (GLUI_Control*) node->first_child(); /* Descend into child */ + } + + } + else { + node = (GLUI_Control*) node->next(); + } + } + + /** No leaf-level nodes found to accept the mouse click, so + return the last container control found which DOES accept the click **/ + + if ( last_container ) { + /* printf( "ctrl: '%s'\n", last_container->name ); */ + + return last_container; + } + else { + return NULL; + } +} + + +/************************************* GLUI_Main::pack_controls() ***********/ + +void GLUI_Main::pack_controls( void ) +{ + main_panel->pack(0,0); + + /**** Now align controls within their bounds ****/ + align_controls( main_panel ); + + /*** If this is a subwindow, expand panel to fit parent window ***/ + if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) { + int parent_h, parent_w; + int orig_window; + + orig_window = glutGetWindow(); + glutSetWindow( this->top_level_glut_window_id ); + parent_h = glutGet( GLUT_WINDOW_HEIGHT ); + parent_w = glutGet( GLUT_WINDOW_WIDTH ); + + glutSetWindow( orig_window ); + + /* printf( "%d %d\n", parent_h, parent_w ); */ + + if ( 1 ) { + if ( TEST_AND(this->flags,GLUI_SUBWINDOW_TOP )) { + main_panel->w = MAX( main_panel->w, parent_w ); + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) { + main_panel->h = MAX( main_panel->h, parent_h ); + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_BOTTOM )) { + main_panel->w = MAX( main_panel->w, parent_w ); + } + else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) { + main_panel->h = MAX( main_panel->h, parent_h ); + } + } + } + + this->w = main_panel->w; + this->h = main_panel->h; +} + + +/************************************ GLUI_Main::align_controls() **********/ + +void GLUI_Main::align_controls( GLUI_Control *control ) +{ + GLUI_Control *child; + + control->align(); + + child = (GLUI_Control*) control->first_child(); + + while( child != NULL ) { + align_controls( child ); + + child = (GLUI_Control*)child->next(); + } +} + + + +/*********************************** GLUI::set_main_gfx_window() ************/ + +void GLUI::set_main_gfx_window( int window_id ) +{ + main_gfx_window_id = window_id; +} + + +/********************************* GLUI_Main::post_update_main_gfx() ********/ + +void GLUI_Main::post_update_main_gfx( void ) +{ + int old_window; + + if ( main_gfx_window_id > 0 ) { + old_window = glutGetWindow(); + glutSetWindow( main_gfx_window_id ); + glutPostRedisplay(); + if( old_window > 0 ) + glutSetWindow( old_window ); + } +} + +/********************************* GLUI_Main::should_redraw_now() ********/ +/** Return true if this control should redraw itself immediately (front buffer); + Or queue up a redraw and return false if it shouldn't (back buffer). + + Called from GLUI_Control::redraw. +*/ +bool GLUI_Main::should_redraw_now(GLUI_Control *ctl) +{ + switch (buffer_mode) { + case buffer_front: return true; /* always draw in front-buffer mode */ + case buffer_back: { + int orig = ctl->set_to_glut_window(); + glutPostRedisplay(); /* redraw soon */ + ctl->restore_window(orig); + return false; /* don't draw now. */ + } + } + return false; /* never executed */ +} + +/********************************* GLUI_Main::set_current_draw_buffer() ********/ + +int GLUI_Main::set_current_draw_buffer( void ) +{ + /* Save old buffer */ + GLint state; + glGetIntegerv( GL_DRAW_BUFFER, &state ); + /* Switch to new buffer */ + switch (buffer_mode) { + case buffer_front: glDrawBuffer(GL_FRONT); break; + case buffer_back: glDrawBuffer(GL_BACK); break; /* might not be needed... */ + } + return (int)state; +} + + +/********************************* GLUI_Main::restore_draw_buffer() **********/ + +void GLUI_Main::restore_draw_buffer( int buffer_state ) +{ + glDrawBuffer( buffer_state ); +} + + +/******************************************** GLUI_Main::GLUI_Main() ********/ + +GLUI_Main::GLUI_Main( void ) +{ + mouse_button_down = false; + w = 0; + h = 0; + active_control = NULL; + mouse_over_control = NULL; + main_gfx_window_id = -1; + glut_window_id = -1; + curr_modifiers = 0; + closing = false; + parent_window = -1; + glui_id = GLUI_Master.glui_id_counter; |