glui.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:57k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /****************************************************************************
  2.   
  3.   GLUI User Interface Toolkit (LGPL)
  4.   ---------------------------
  5.      glui.cpp
  6.           --------------------------------------------------
  7.   Copyright (c) 1998 Paul Rademacher
  8.   WWW:    http://sourceforge.net/projects/glui/
  9.   Forums: http://sourceforge.net/forum/?group_id=92496
  10.   This library is free software; you can redistribute it and/or
  11.   modify it under the terms of the GNU Lesser General Public
  12.   License as published by the Free Software Foundation; either
  13.   version 2.1 of the License, or (at your option) any later version.
  14.   This library is distributed in the hope that it will be useful,
  15.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.   Lesser General Public License for more details.
  18.   You should have received a copy of the GNU Lesser General Public
  19.   License along with this library; if not, write to the Free Software
  20.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21. *****************************************************************************/
  22. #include "glui_internal_control.h"
  23. /**
  24.  Note: moving this routine here from glui_add_controls.cpp prevents the linker
  25.  from touching glui_add_controls.o in non-deprecated programs, which 
  26.  descreases the linked size of small GLUI programs substantially (100K+). (OSL 2006/06)
  27. */
  28. void GLUI_Node::add_child_to_control(GLUI_Node *parent,GLUI_Control *child)
  29. {
  30.   GLUI_Control *parent_control;
  31.   /*** Collapsible nodes have to be handled differently, b/c the first and 
  32.     last children are swapped in and out  ***/
  33.   parent_control = ((GLUI_Control*)parent);
  34.   if ( parent_control->collapsible == true ) {
  35.     if ( NOT parent_control->is_open ) {
  36.       /** Swap in the original first and last children **/
  37.       parent_control->child_head  = parent_control->collapsed_node.child_head;
  38.       parent_control->child_tail  = parent_control->collapsed_node.child_tail;
  39.       /*** Link this control ***/
  40.       child->link_this_to_parent_last( parent_control );
  41.       /** Swap the children back out ***/
  42.       parent_control->collapsed_node.child_head = parent_control->child_head;
  43.       parent_control->collapsed_node.child_tail = parent_control->child_tail;
  44.       parent_control->child_head = NULL;
  45.       parent_control->child_tail = NULL;
  46.     }
  47.     else {
  48.       child->link_this_to_parent_last( parent_control );
  49.     }
  50.   }
  51.   else {
  52.     child->link_this_to_parent_last( parent_control );
  53.   }
  54.   child->glui = (GLUI*) parent_control->glui;
  55.   child->update_size();
  56.   child->enabled = parent_control->enabled;
  57.   child->glui->refresh();
  58.   /** Now set the 'hidden' var based on the parent **/
  59.   if ( parent_control->hidden OR 
  60.        (parent_control->collapsible AND NOT parent_control->is_open ) )
  61.   {
  62.     child->hidden = true;
  63.   }
  64. }
  65. /************************************ GLUI_Node::add_control() **************/
  66. int GLUI_Node::add_control( GLUI_Control *child )
  67. {
  68.   add_child_to_control(this,child);
  69.   return true;
  70. }
  71. /************************************ GLUI_Main::add_control() **************/
  72.  
  73. int GLUI_Main::add_control( GLUI_Node *parent, GLUI_Control *control )
  74. {
  75.   add_child_to_control(parent,control);
  76.   return true;
  77. }
  78. /*** This object must be used to create a GLUI ***/
  79. GLUI_Master_Object GLUI_Master;
  80. /************************************ finish_drawing() ***********
  81.   Probably a silly routine.  Called after all event handling callbacks.
  82. */
  83. static void finish_drawing(void)
  84. {
  85. glFinish();
  86. }
  87. /************************************ GLUI_CB::operator()() ************/
  88. void GLUI_CB::operator()(GLUI_Control*ctrl) const
  89. {
  90.   if (idCB)  idCB(ctrl->user_id);
  91.   if (objCB) objCB(ctrl);
  92. }
  93. /************************************************ GLUI::GLUI() **********/
  94. int GLUI::init( const char *text, long flags, int x, int y, int parent_window ) 
  95. {
  96.   int old_glut_window;
  97.   this->flags = flags;
  98.   window_name = text;
  99.   
  100.   buffer_mode = buffer_back;  ///< New smooth way
  101.   //buffer_mode = buffer_front; ///< Old flickery way (a bit faster).
  102.   /*** We copy over the current window callthroughs ***/
  103.   /*** (I think this might actually only be needed for subwindows) ***/
  104.   /*  glut_keyboard_CB = GLUI_Master.glut_keyboard_CB;
  105.       glut_reshape_CB  = GLUI_Master.glut_reshape_CB;
  106.       glut_special_CB  = GLUI_Master.glut_special_CB;
  107.       glut_mouse_CB    = GLUI_Master.glut_mouse_CB;*/
  108.   if ( (flags & GLUI_SUBWINDOW) != GLUI_SUBWINDOW ) {  /* not a subwindow, creating a new top-level window */
  109.     old_glut_window = glutGetWindow();
  110.     create_standalone_window( window_name.c_str(), x, y );
  111.     setup_default_glut_callbacks();
  112.     if ( old_glut_window > 0 )
  113.       glutSetWindow( old_glut_window );
  114.     top_level_glut_window_id = glut_window_id;
  115.   } 
  116.   else /* *is* a subwindow */
  117.   {
  118.     old_glut_window = glutGetWindow();
  119.     create_subwindow( parent_window, flags );
  120.     setup_default_glut_callbacks();
  121.     if ( old_glut_window > 0 )
  122.       glutSetWindow( old_glut_window );
  123.     top_level_glut_window_id = parent_window;
  124.     /*
  125.       glutReshapeFunc( glui_parent_window_reshape_func );
  126.       glutSpecialFunc( glui_parent_window_special_func );
  127.       glutKeyboardFunc( glui_parent_window_keyboard_func );
  128.       glutMouseFunc( glui_parent_window_mouse_func );
  129.       */
  130.     
  131.   }
  132.   return true;
  133. }
  134. /**************************** GLUI_Main::create_standalone_window() ********/
  135. void GLUI_Main::create_standalone_window( const char *name, int x, int y )
  136. {
  137.   glutInitWindowSize( 100, 100 );
  138.   if ( x >= 0 OR y >= 0 )
  139.     glutInitWindowPosition( x, y );
  140.   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); 
  141.   glut_window_id = glutCreateWindow( name );
  142. }
  143. /******************************** GLUI_Main::create_subwindow() **********/
  144. void GLUI_Main::create_subwindow( int parent_window, int window_alignment )
  145. {
  146.   glut_window_id = glutCreateSubWindow(parent_window, 0,0, 100, 100);
  147.   this->parent_window = parent_window;
  148. }
  149. /**************************** GLUI_Main::setup_default_glut_callbacks() *****/
  150. void GLUI_Main::setup_default_glut_callbacks( void )
  151. {
  152.   glutDisplayFunc( glui_display_func );
  153.   glutReshapeFunc( glui_reshape_func );
  154.   glutKeyboardFunc( glui_keyboard_func );
  155.   glutSpecialFunc( glui_special_func );
  156.   glutMouseFunc( glui_mouse_func );
  157.   glutMotionFunc( glui_motion_func );
  158.   glutPassiveMotionFunc( glui_passive_motion_func );
  159.   glutEntryFunc( glui_entry_func );
  160.   glutVisibilityFunc( glui_visibility_func );
  161.   /*  glutIdleFunc( glui_idle_func );    // FIXME!  100% CPU usage!      */
  162. }
  163. /********************************************** glui_display_func() ********/
  164. void glui_display_func(void)
  165. {
  166.   GLUI *glui;
  167.   /*  printf( "display funcn" );          */
  168.   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
  169.   if ( glui ) {
  170.     glui->display(); 
  171.     /* 
  172.        Do not do anything after the above line, b/c the GLUI
  173.        window might have just closed itself 
  174.    */
  175.   }
  176. }
  177. /********************************************** glui_reshape_func() ********/
  178. void glui_reshape_func(int w,int h )
  179. {
  180.   GLUI             *glui;
  181.   GLUI_Glut_Window *glut_window;
  182.   int               current_window;
  183.   /*printf( "glui_reshape_func(): %d  w/h: %d/%dn", glutGetWindow(), w, h );          */
  184.   current_window = glutGetWindow();
  185.   /***  First check if this is main glut window ***/
  186.   glut_window = GLUI_Master.find_glut_window( current_window );
  187.   if ( glut_window ) {
  188.     if (glut_window->glut_reshape_CB) glut_window->glut_reshape_CB(w,h);
  189.     /***  Now send reshape events to all subwindows  ***/
  190.     glui = (GLUI*) GLUI_Master.gluis.first_child();
  191.     while(glui) {
  192.       if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND 
  193.    glui->parent_window == current_window ) {
  194. glutSetWindow( glui->get_glut_window_id());
  195. glui->reshape(w,h);
  196. /* glui->check_subwindow_position();          */
  197.       }
  198.       glui = (GLUI*) glui->next();
  199.     }
  200.   }
  201.   else {
  202.     /***  A standalone GLUI window  ***/
  203.     glui = GLUI_Master.find_glui_by_window_id( current_window );
  204.     if ( glui ) {
  205.       glui->reshape(w,h);
  206.     }
  207.   }
  208. }
  209. /********************************************** glui_keyboard_func() ********/
  210. void glui_keyboard_func(unsigned char key, int x, int y)
  211. {
  212.   GLUI              *glui;
  213.   int                current_window;
  214.   GLUI_Glut_Window  *glut_window;
  215.   current_window = glutGetWindow();
  216.   glut_window = GLUI_Master.find_glut_window( current_window );
  217.   /*printf( "key: %dn", current_window );          */
  218.   if ( glut_window ) { /**  Was event in a GLUT window?  **/
  219.     if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) {
  220.       glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() );
  221.       
  222.       GLUI_Master.active_control_glui->keyboard(key,x,y);    
  223.   finish_drawing();
  224.       
  225.       glutSetWindow( current_window );
  226.     }
  227.     else {
  228.       if (glut_window->glut_keyboard_CB) 
  229.         glut_window->glut_keyboard_CB( key, x, y );
  230.     } 
  231.   }
  232.   else {   /***  Nope, event was in a standalone GLUI window  **/
  233.     glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
  234.     if ( glui ) {
  235.       glui->keyboard(key,x,y);
  236.   finish_drawing();
  237.     }
  238.   }
  239. }
  240. /************************************************ glui_special_func() ********/
  241. void glui_special_func(int key, int x, int y)
  242. {
  243.   GLUI              *glui;
  244.   int                current_window;
  245.   GLUI_Glut_Window  *glut_window;
  246.   current_window = glutGetWindow();
  247.   glut_window = GLUI_Master.find_glut_window( current_window );
  248.   if (glut_window) /**  Was event in a GLUT window?  **/
  249.   {
  250.     if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control )
  251.     {
  252.       glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() );
  253.       
  254.       GLUI_Master.active_control_glui->special(key,x,y);    
  255.       finish_drawing();
  256.       
  257.       glutSetWindow( current_window );
  258.     }
  259.     else
  260.     {
  261.       if (glut_window->glut_special_CB)
  262.         glut_window->glut_special_CB( key, x, y );
  263.     } 
  264.   }
  265.   else /***  Nope, event was in a standalone GLUI window  **/
  266.   {
  267.     glui = GLUI_Master.find_glui_by_window_id(glutGetWindow());
  268.     if ( glui )
  269.     {
  270.       glui->special(key,x,y);
  271.       finish_drawing();
  272.     }
  273.   }
  274. }
  275. /********************************************** glui_mouse_func() ********/
  276. void glui_mouse_func(int button, int state, int x, int y)
  277. {
  278.   GLUI              *glui;
  279.   int                current_window;
  280.   GLUI_Glut_Window  *glut_window;
  281.   current_window = glutGetWindow();
  282.   glut_window = GLUI_Master.find_glut_window( current_window );
  283.   if ( glut_window ) { /**  Was event in a GLUT window?  **/
  284.     if ( GLUI_Master.active_control_glui != NULL ) 
  285.       GLUI_Master.active_control_glui->deactivate_current_control();
  286.     if (glut_window->glut_mouse_CB)
  287.       glut_window->glut_mouse_CB( button, state, x, y );
  288. finish_drawing();
  289.   }
  290.   else {               /**  Nope - event was in a GLUI standalone window  **/
  291.     glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
  292.     if ( glui ) {
  293.       glui->passive_motion( 0,0 );
  294.       glui->mouse( button, state, x, y );
  295.   finish_drawing();
  296.     }
  297.   }
  298. }
  299. /********************************************** glui_motion_func() ********/
  300. void glui_motion_func(int x, int y)
  301. {
  302.   GLUI *glui;
  303.   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
  304.   if ( glui ) {
  305.     glui->motion(x,y);
  306. finish_drawing();
  307.   }
  308. }
  309. /**************************************** glui_passive_motion_func() ********/
  310. void glui_passive_motion_func(int x, int y)
  311. {
  312.   GLUI *glui;
  313.   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
  314.   if ( glui ) {
  315.     glui->passive_motion(x,y);
  316. finish_drawing();
  317.   }
  318. }
  319. /********************************************** glui_entry_func() ********/
  320. void glui_entry_func(int state)
  321. {
  322.   GLUI *glui;
  323.   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
  324.   if ( glui ) {
  325.     glui->entry(state);
  326.   }
  327. }
  328. /******************************************** glui_visibility_func() ********/
  329. void glui_visibility_func(int state)
  330. {
  331.   GLUI *glui;
  332.   /*  printf( "IN GLUI VISIBILITY()n" );          */
  333.   /*  fflush( stdout );          */
  334.   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
  335.   if ( glui ) {
  336.     glui->visibility(state);
  337.   }
  338. }
  339. /********************************************** glui_idle_func() ********/
  340. /* Send idle event to each glui, then to the main window            */
  341. void glui_idle_func(void)
  342. {
  343.   GLUI *glui;
  344.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  345.   while( glui ) {
  346.     glui->idle();
  347. finish_drawing();
  348.     
  349.     glui = (GLUI*) glui->next();
  350.   }
  351.   if ( GLUI_Master.glut_idle_CB ) {
  352.     /*** We set the current glut window before calling the user's
  353.       idle function, even though glut explicitly says the window id is 
  354.       undefined in an idle callback.  ***/
  355.     
  356.     /** Check what the current window is first ***/
  357.     /*** Arbitrarily set the window id to the main gfx window of the 
  358.       first glui window ***/
  359.     /*   int current_window, new_window;          */
  360.     /*   current_window = glutGetWindow();          */
  361.     /*   if (GLUI_Master.gluis.first_child() != NULL ) {          */
  362.     /*      new_window = ((GLUI_Main*)GLUI_Master.gluis.first_child())-> */
  363.     /*   main_gfx_window_id;          */
  364.     /*   if ( new_window > 0 AND new_window != old_window ) {          */
  365.     /*   --- Window is changed only if its not already the current window ---*/
  366.     /*  glutSetWindow( new_window );          */
  367.     /* }          */
  368.     /*}          */
  369.     
  370.     GLUI_Master.glut_idle_CB();
  371.   }
  372. }
  373. /*********************************** GLUI_Master_Object::GLUI_Master_Object() ******/
  374. GLUI_Master_Object::GLUI_Master_Object()
  375. : glui_id_counter(1),
  376.     glut_idle_CB(NULL)
  377. {
  378. }
  379. GLUI_Master_Object::~GLUI_Master_Object()
  380. {
  381. }
  382. /*********************************** GLUI_Master_Object::create_glui() ******/
  383. GLUI *GLUI_Master_Object::create_glui( const char *name, long flags,int x,int y )
  384. {
  385.   GLUI *new_glui = new GLUI;
  386.   new_glui->init( name, flags, x, y, -1 );
  387.   new_glui->link_this_to_parent_last( &this->gluis );
  388.   return new_glui;
  389. }
  390. /************************** GLUI_Master_Object::create_glui_subwindow() ******/
  391. GLUI *GLUI_Master_Object::create_glui_subwindow( int parent_window, 
  392.    long flags )
  393. {
  394.   GLUI *new_glui = new GLUI;
  395.   GLUI_String new_name;
  396.   glui_format_str( new_name, "subwin_%p", this );
  397.   new_glui->init( new_name.c_str(), flags | GLUI_SUBWINDOW, 0,0,
  398.     parent_window );
  399.   new_glui->main_panel->set_int_val( GLUI_PANEL_EMBOSSED );
  400.   new_glui->link_this_to_parent_last( &this->gluis );
  401.   return new_glui;
  402. }
  403. /********************** GLUI_Master_Object::find_glui_by_window_id() ********/
  404. GLUI  *GLUI_Master_Object::find_glui_by_window_id( int window_id )
  405. {
  406.   GLUI_Node *node;
  407.   node = gluis.first_child();
  408.   while( node ) {
  409.     if ( ((GLUI*)node)->get_glut_window_id() == window_id ) 
  410.       return (GLUI*) node;
  411.     
  412.     node = node->next();
  413.   }
  414.   return NULL;
  415. }
  416. /******************************************** GLUI_Main::display() **********/
  417. void    GLUI_Main::display( void )
  418. {
  419.   int       win_w, win_h;
  420.   /* SUBTLE: on freeGLUT, the correct window is always already set.
  421.   But older versions of GLUT need this call, or else subwindows
  422.   don't update properly when resizing or damage-painting.
  423.   */
  424.   glutSetWindow( glut_window_id );
  425.   
  426.   /* Set up OpenGL state for widget drawing */
  427.   glDisable( GL_DEPTH_TEST );
  428.   glCullFace( GL_BACK );
  429.   glDisable( GL_CULL_FACE );
  430.   glDisable( GL_LIGHTING );
  431.   set_current_draw_buffer();
  432.   /**** This function is used as a special place to do 'safe' processing,
  433.     e.g., handling window close requests.
  434.     That is, we can't close the window directly in the callback, so 
  435.     we set a flag, post a redisplay message (which eventually calls
  436.     this function), then close the window safely in here.  ****/
  437.   if ( closing ) {
  438.     close_internal();
  439.     return;
  440.   }
  441.   /*  if ( TEST_AND( this->flags, GLUI_SUBWINDOW ))
  442.       check_subwindow_position();
  443.       */
  444.   win_w = glutGet( GLUT_WINDOW_WIDTH );
  445.   win_h = glutGet( GLUT_WINDOW_HEIGHT );
  446.   /*** Check here if the window needs resizing ***/
  447.   if ( win_w != main_panel->w OR win_h != main_panel->h ) {
  448.     glutReshapeWindow( main_panel->w, main_panel->h );
  449.     return;
  450.   }
  451.   /*******    Draw GLUI window     ******/
  452.   glClearColor( (float) bkgd_color.r / 255.0,
  453. (float) bkgd_color.g / 255.0,
  454. (float) bkgd_color.b / 255.0,
  455. 1.0 );
  456.   glClear( GL_COLOR_BUFFER_BIT ); /* | GL_DEPTH_BUFFER_BIT );          */
  457.   set_ortho_projection();
  458.   glMatrixMode( GL_MODELVIEW );
  459.   glLoadIdentity();
  460.   /*** Rotate image so y increases downward.
  461.       In normal OpenGL, y increases upward. ***/
  462.   glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 );
  463.   glRotatef( 180.0, 0.0, 1.0, 0.0 );
  464.   glRotatef( 180.0, 0.0, 0.0, 1.0 );
  465.   glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 );
  466.   // Recursively draw the main panel
  467.   //  main_panel->draw_bkgd_box( 0, 0, win_w, win_h );
  468.   main_panel->draw_recursive( 0, 0 );
  469.   switch (buffer_mode) {
  470.   case buffer_front: /* Make sure drawing gets to screen */
  471.    glFlush();
  472. break;
  473.   case buffer_back: /* Bring back buffer to front */
  474.    glutSwapBuffers();
  475. break;
  476.   }
  477. }
  478. /*************************************** _glutBitmapWidthString() **********/
  479. int _glutBitmapWidthString( void *font, const char *s )
  480. {
  481.   const char *p = s;
  482.   int  width = 0;
  483.   while( *p != '' )  {
  484.     width += glutBitmapWidth( font, *p );
  485.     p++;
  486.   }
  487.   return width;
  488. }
  489. /************************************ _glutBitmapString *********************/
  490. /* Displays the contents of a string using GLUT's bitmap character function */
  491. /* Does not handle newlines                                             */
  492. void _glutBitmapString( void *font, const char *s )
  493. {
  494.   const char *p = s;
  495.   while( *p != '' )  {
  496.     glutBitmapCharacter( font, *p );
  497.     p++;
  498.   }
  499. }
  500. /****************************** GLUI_Main::reshape() **************/
  501. void    GLUI_Main::reshape( int reshape_w, int reshape_h )
  502. {
  503.   int new_w, new_h;
  504.   pack_controls();
  505.   new_w = main_panel->w;/* + 1;          */
  506.   new_h = main_panel->h;/* + 1;          */
  507.   if ( reshape_w != new_w OR reshape_h != new_h ) {
  508.     this->w = new_w;
  509.     this->h = new_h;
  510.     
  511.     glutReshapeWindow( new_w, new_h );
  512.   }
  513.   else {
  514.   }
  515.   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
  516.     check_subwindow_position();
  517.     /***** if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
  518.       }
  519.       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
  520.       }
  521.       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
  522.       }
  523.       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) {
  524.       }
  525.       ****/
  526.   }
  527.   
  528.   glViewport( 0, 0, new_w, new_h );
  529.   /*  printf( "%d: %dn", glutGetWindow(), this->flags );          */
  530.   glutPostRedisplay();
  531. }
  532. /****************************** GLUI_Main::keyboard() **************/
  533. void    GLUI_Main::keyboard(unsigned char key, int x, int y)
  534. {
  535.   GLUI_Control *new_control;
  536.   curr_modifiers = glutGetModifiers();
  537.   /*** If it's a tab or shift tab, we don't pass it on to the controls.
  538.     Instead, we use it to cycle through active controls ***/
  539.   if ( key == 't' AND !mouse_button_down AND 
  540.        (!active_control || !active_control->wants_tabs())) {
  541.     if ( curr_modifiers & GLUT_ACTIVE_SHIFT ) {
  542.       new_control = find_prev_control( active_control );
  543.     }
  544.     else {
  545.       new_control = find_next_control( active_control );
  546.     }
  547.     /*    if ( new_control )
  548.   printf( "new_control: %sn", new_control->name );
  549.   */
  550.     deactivate_current_control();
  551.     activate_control( new_control, GLUI_ACTIVATE_TAB );
  552.   }
  553.   else if ( key == ' ' AND active_control 
  554.           AND active_control->spacebar_mouse_click ) { 
  555.     /*** If the user presses the spacebar, and a non-edittext control
  556.       is active, we send it a mouse down event followed by a mouse up
  557.       event (simulated mouse-click) ***/
  558.     
  559.     active_control->mouse_down_handler( 0, 0 );
  560.     active_control->mouse_up_handler( 0, 0, true );
  561.   } else {
  562.     /*** Pass the keystroke onto the active control, if any ***/
  563.     if ( active_control != NULL )
  564.       active_control->key_handler( key, curr_modifiers );
  565.   }
  566. }
  567. /****************************** GLUI_Main::special() **************/
  568. void    GLUI_Main::special(int key, int x, int y)
  569. {
  570.   curr_modifiers = glutGetModifiers();
  571.   /*** Pass the keystroke onto the active control, if any ***/
  572.   if ( active_control != NULL )
  573.     active_control->special_handler( key, glutGetModifiers() );
  574. }
  575. /****************************** GLUI_Main::mouse() **************/
  576. void    GLUI_Main::mouse(int button, int state, int x, int y)
  577. {
  578.   int callthrough;
  579.   GLUI_Control *control;
  580.   /*  printf( "MOUSE: %d %dn", button, state );          */
  581.   callthrough = true;
  582.   curr_modifiers = glutGetModifiers();
  583.   if ( button == GLUT_LEFT ) {
  584.     control = find_control( x, y );
  585.     /*if ( control ) printf( "control: %sn", control->name.c_str() );      */
  586.     
  587.     if ( mouse_button_down AND active_control != NULL AND
  588.         state == GLUT_UP ) 
  589.     {
  590.       /** We just released the mouse, which was depressed at some control **/
  591.       callthrough = active_control->
  592.         mouse_up_handler( x, y, control==active_control);
  593.       glutSetCursor( GLUT_CURSOR_LEFT_ARROW );
  594.       if ( active_control AND 
  595.            active_control->active_type == GLUI_CONTROL_ACTIVE_MOUSEDOWN AND 0)
  596.       {
  597.         /*** This is a control that needs to be deactivated when the
  598.         mouse button is released ****/
  599.         deactivate_current_control();
  600.       }
  601.     }
  602.     else {
  603.       if ( control ) {
  604.         if ( NOT mouse_button_down AND state == GLUT_DOWN ) {
  605.           /*** We just pressed the mouse down at some control ***/
  606.           if ( active_control != control ) {
  607.             if ( active_control != NULL ) {
  608.               /** There is an active control still - deactivate it ***/
  609.               deactivate_current_control();
  610.             }
  611.           }
  612.           if ( control->enabled ) {
  613.             activate_control( control, GLUI_ACTIVATE_MOUSE );
  614.             callthrough    = control->mouse_down_handler( x, y );
  615.           }
  616.         }
  617.       }
  618.     }
  619.     if ( state == GLUT_DOWN )
  620.       mouse_button_down = true;
  621.     else if ( state == GLUT_UP )
  622.       mouse_button_down = false;
  623.   }
  624.   /**
  625.     NO CALLTHROUGH NEEDED FOR MOUSE EVENTS
  626.     if ( callthrough AND glut_mouse_CB )
  627.     glut_mouse_CB( button, state, x, y );
  628.     **/
  629.   callthrough=callthrough; /* To get rid of compiler warnings */
  630. }
  631. /****************************** GLUI_Main::motion() **************/
  632. void    GLUI_Main::motion(int x, int y)
  633. {
  634.   int           callthrough;
  635.   GLUI_Control *control;
  636.   /*  printf( "MOTION: %d %dn", x, y );          */
  637.   callthrough = true;
  638.   control = find_control(x,y);
  639.   
  640.   if ( mouse_button_down AND active_control != NULL ) {
  641.     callthrough = 
  642.       active_control->mouse_held_down_handler(x,y,control==active_control);
  643.   }
  644.   
  645.   /**
  646.     NO CALLTHROUGH NEEDED FOR MOUSE EVENTS
  647.     if ( callthrough AND glut_motion_CB )
  648.     glut_motion_CB(x,y);
  649.     **/
  650.   callthrough=callthrough; /* To get rid of compiler warnings */
  651. }
  652. /*********************** GLUI_Main::passive_motion() **************/
  653. void    GLUI_Main::passive_motion(int x, int y)
  654. {
  655.   GLUI_Control *control;
  656.   control = find_control( x, y );
  657.   /*  printf( "%p %pn", control, mouse_over_control );          */
  658.   if ( control != mouse_over_control ) {
  659.     if ( mouse_over_control ) {
  660.       mouse_over_control->mouse_over( false, x, y );
  661.     }
  662.     if ( control ) {
  663.       control->mouse_over( true, x, y );
  664.       mouse_over_control = control;
  665.     }
  666.   }
  667.   /*
  668.     if ( curr_cursor != GLUT_CURSOR_INHERIT ) {
  669.     curr_cursor = GLUT_CURSOR_INHERIT;
  670.     glutSetCursor( GLUT_CURSOR_INHERIT );
  671.     }*/
  672. }
  673. /****************************** GLUI_Main::entry() **************/
  674. void    GLUI_Main::entry(int state)
  675. {
  676.   /*if ( NOT active_control OR ( active_control AND ( active_control->type == GLUI_CONTROL_EDITTEXT
  677.     OR active_control->type == GLUI_CONTROL_SPINNER) ) )*/
  678.   glutSetCursor( GLUT_CURSOR_LEFT_ARROW );
  679. }
  680. /****************************** GLUI_Main::visibility() **************/
  681. void    GLUI_Main::visibility(int state)
  682. {
  683. }
  684. /****************************** GLUI_Main::idle() **************/
  685. void    GLUI_Main::idle(void)
  686. {
  687.   /*** Pass the idle event onto the active control, if any ***/
  688.   /*  printf( "IDLE t" );          */
  689.   if ( active_control != NULL ) {
  690.     /* First we check if the control actually needs the idle right now.
  691.        Otherwise, let's avoid wasting cycles and OpenGL context switching */
  692.     if ( active_control->needs_idle() ) {
  693.       /*** Set the current glut window to the glui window */
  694.       /*** But don't change the window if we're already at that window ***/
  695.       if ( glut_window_id > 0 AND glutGetWindow() != glut_window_id ) {
  696. glutSetWindow( glut_window_id );
  697.       }
  698.       
  699.       active_control->idle();
  700.     }
  701.   }
  702. }
  703. int  GLUI_Main::needs_idle( void )
  704. {
  705.   return active_control != NULL && active_control->needs_idle();
  706. }
  707. /******************************************* GLUI_Main::find_control() ******/
  708. GLUI_Control  *GLUI_Main::find_control( int x, int y )
  709. {
  710.   GLUI_Control *node, *last_container;
  711.   last_container = NULL;
  712.   node = main_panel;
  713.   while( node != NULL ) {
  714.     if ( !dynamic_cast<GLUI_Column*>(node) AND
  715.          PT_IN_BOX( x, y, 
  716.                     node->x_abs, node->x_abs + node->w, 
  717.                     node->y_abs, node->y_abs + node->h ) 
  718.          ) 
  719.     {
  720.       /*** Point is inside current node ***/
  721.       
  722.       if ( node->first_child() == NULL ) {
  723.         /*** SPECIAL CASE: for edittext boxes, we make sure click is
  724.              in box, and not on name string.  This should be generalized
  725.              for all controls later... ***/
  726.         if ( dynamic_cast<GLUI_EditText*>(node) ) {
  727.           if ( x < node->x_abs + ((GLUI_EditText*)node)->text_x_offset )
  728.             return (GLUI_Control*) node->parent();
  729.         }
  730.         return node;   /* point is inside this node, and node has no children,
  731.                           so return this node as the selected node */
  732.       }
  733.       else {
  734.         /*** This is a container class ***/
  735.         last_container = node;
  736.         node = (GLUI_Control*) node->first_child();  /* Descend into child */
  737.       }
  738.       
  739.     }
  740.     else {
  741.       node = (GLUI_Control*) node->next();
  742.     }
  743.   }
  744.  
  745.   /** No leaf-level nodes found to accept the mouse click, so
  746.       return the last container control found which DOES accept the click **/
  747.   
  748.   if ( last_container ) {
  749.     /*    printf( "ctrl: '%s'n", last_container->name );          */
  750.   
  751.     return last_container;
  752.   }
  753.   else {
  754.     return NULL;
  755.   }
  756. }
  757. /************************************* GLUI_Main::pack_controls() ***********/
  758. void      GLUI_Main::pack_controls( void )
  759. {
  760.   main_panel->pack(0,0);
  761.   /**** Now align controls within their bounds ****/
  762.   align_controls( main_panel );
  763.   /***  If this is a subwindow, expand panel to fit parent window  ***/
  764.   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
  765.     int parent_h, parent_w;
  766.     int orig_window;
  767.     orig_window = glutGetWindow();
  768.     glutSetWindow( this->top_level_glut_window_id );
  769.     parent_h = glutGet( GLUT_WINDOW_HEIGHT );
  770.     parent_w = glutGet( GLUT_WINDOW_WIDTH );
  771.     glutSetWindow( orig_window );
  772.     /* printf( "%d %dn", parent_h, parent_w );          */
  773.     if ( 1 ) {
  774.       if ( TEST_AND(this->flags,GLUI_SUBWINDOW_TOP )) {
  775. main_panel->w = MAX( main_panel->w, parent_w );
  776.       }
  777.       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
  778. main_panel->h = MAX( main_panel->h, parent_h );
  779.       }
  780.       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_BOTTOM )) {
  781. main_panel->w = MAX( main_panel->w, parent_w );
  782.       }
  783.       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) {
  784. main_panel->h = MAX( main_panel->h, parent_h );
  785.       }
  786.     }
  787.   }
  788.   this->w = main_panel->w;
  789.   this->h = main_panel->h;
  790. }
  791. /************************************ GLUI_Main::align_controls() **********/
  792. void    GLUI_Main::align_controls( GLUI_Control *control )
  793. {
  794.   GLUI_Control *child;
  795.   control->align();
  796.   child = (GLUI_Control*) control->first_child();
  797.   while( child != NULL ) {
  798.     align_controls( child );
  799.     
  800.     child = (GLUI_Control*)child->next();
  801.   }  
  802. }
  803. /*********************************** GLUI::set_main_gfx_window() ************/
  804. void   GLUI::set_main_gfx_window( int window_id )
  805. {
  806.   main_gfx_window_id = window_id;
  807. }
  808. /********************************* GLUI_Main::post_update_main_gfx() ********/
  809. void   GLUI_Main::post_update_main_gfx( void )
  810. {
  811.   int old_window;
  812.   if ( main_gfx_window_id > 0 ) {
  813.     old_window = glutGetWindow();
  814.     glutSetWindow( main_gfx_window_id );
  815.     glutPostRedisplay();
  816.     if( old_window > 0 )
  817.       glutSetWindow( old_window );
  818.   }
  819. }
  820. /********************************* GLUI_Main::should_redraw_now() ********/
  821. /** Return true if this control should redraw itself immediately (front buffer);
  822.    Or queue up a redraw and return false if it shouldn't (back buffer).
  823.    
  824.    Called from GLUI_Control::redraw.
  825. */
  826. bool      GLUI_Main::should_redraw_now(GLUI_Control *ctl)
  827. {
  828.   switch (buffer_mode) {
  829.   case buffer_front: return true; /* always draw in front-buffer mode */
  830.   case buffer_back: {
  831.     int orig = ctl->set_to_glut_window();
  832.     glutPostRedisplay(); /* redraw soon */
  833.     ctl->restore_window(orig);
  834.     return false; /* don't draw now. */
  835.    }
  836.   }
  837.   return false; /* never executed */
  838. }
  839. /********************************* GLUI_Main::set_current_draw_buffer() ********/
  840. int          GLUI_Main::set_current_draw_buffer( void )
  841. {
  842.   /* Save old buffer */
  843.   GLint state;
  844.   glGetIntegerv( GL_DRAW_BUFFER, &state );
  845.   /* Switch to new buffer */
  846.   switch (buffer_mode) {
  847.   case buffer_front: glDrawBuffer(GL_FRONT); break;
  848.   case buffer_back:  glDrawBuffer(GL_BACK);  break; /* might not be needed... */
  849.   }
  850.   return (int)state;
  851. }
  852.  
  853. /********************************* GLUI_Main::restore_draw_buffer() **********/
  854. void         GLUI_Main::restore_draw_buffer( int buffer_state )
  855. {
  856.   glDrawBuffer( buffer_state );
  857. }
  858. /******************************************** GLUI_Main::GLUI_Main() ********/
  859. GLUI_Main::GLUI_Main( void ) 
  860. {
  861.   mouse_button_down       = false;
  862.   w                       = 0;
  863.   h                       = 0;
  864.   active_control          = NULL;
  865.   mouse_over_control      = NULL;
  866.   main_gfx_window_id      = -1;
  867.   glut_window_id          = -1;
  868.   curr_modifiers          = 0;
  869.   closing                 = false;
  870.   parent_window           = -1;
  871.   glui_id                 = GLUI_Master.glui_id_counter;
  872.   GLUI_Master.glui_id_counter++;
  873.   font                    = GLUT_BITMAP_HELVETICA_12;
  874.   curr_cursor             = GLUT_CURSOR_LEFT_ARROW;
  875.   int r=200, g=200, b=200;
  876.   bkgd_color.set( r,g,b );
  877.   bkgd_color_f[0] = r / 255.0;
  878.   bkgd_color_f[1] = g / 255.0;
  879.   bkgd_color_f[2] = b / 255.0;
  880.   /*** Create the main panel ***/
  881.   main_panel              = new GLUI_Panel;
  882.   main_panel->set_int_val( GLUI_PANEL_NONE );
  883.   main_panel->glui        = (GLUI*) this;
  884.   main_panel->name        = "";
  885. }
  886. /************************************ GLUI_Main::draw_raised_box() **********/
  887. void      GLUI_Main::draw_raised_box( int x, int y, int w, int h )
  888. {
  889.   w = w+x;
  890.   h = h+y;
  891.   glColor3ub( bkgd_color.r, bkgd_color.g, bkgd_color.b );
  892.   glBegin( GL_LINE_LOOP );
  893.   glVertex2i( x+1, y+1 );  glVertex2i( w-1, y+1 );
  894.   glVertex2i( w-1, h-1 );  glVertex2i( x+1, h-1 );
  895.   glEnd();
  896.   glColor3d( 1.0, 1.0, 1.0 );
  897.   glBegin( GL_LINE_STRIP );
  898.   glVertex2i( x, h );  glVertex2i( x, y );  glVertex2i( w, y );
  899.   glEnd();
  900.   glColor3d( 0.0, 0.0, 0.0 );
  901.   glBegin( GL_LINE_STRIP );
  902.   glVertex2i( w, y );  glVertex2i( w, h );  glVertex2i( x, h );
  903.   glEnd();
  904.   glColor3d( .5, .5, .5 );
  905.   glBegin( GL_LINE_STRIP );
  906.   glVertex2i( w-1, y+1 );  glVertex2i( w-1, h-1 );  glVertex2i( x+1, h-1 );
  907.   glEnd();
  908. }
  909. /************************************ GLUI_Main::draw_lowered_box() **********/
  910. /* Not quite perfect...      **/
  911. void      GLUI_Main::draw_lowered_box( int x, int y, int w, int h )
  912. {
  913.   w = w+x;
  914.   h = h+y;
  915.   glColor3ub( bkgd_color.r, bkgd_color.g, bkgd_color.b );
  916.   glBegin( GL_LINE_LOOP );
  917.   glVertex2i( x+1, y+1 );         glVertex2i( w-1, y+1 );
  918.   glVertex2i( w-1, h-1 );     glVertex2i( x+1, h-1 );
  919.   glEnd();
  920.   glColor3d( 0.0, 0.0, 0.0 );
  921.   glBegin( GL_LINE_STRIP );
  922.   glVertex2i( x, h );  glVertex2i( x, y );  glVertex2i( w, y );
  923.   glEnd();
  924.   glColor3d( 1.0, 1.0, 1.0 );
  925.   glBegin( GL_LINE_STRIP );
  926.   glVertex2i( w, y );  glVertex2i( w, h );  glVertex2i( x, h );
  927.   glEnd();
  928.   glColor3d( .5, .5, .5 );
  929.   glBegin( GL_LINE_STRIP );
  930.   glVertex2i( w-1, y+1 );  glVertex2i( w-1, h-1 );  glVertex2i( x+1, h-1 );
  931.   glEnd();
  932. }
  933. /************************************* GLUI_Main::activate_control() *********/
  934. void         GLUI_Main::activate_control( GLUI_Control *control, int how )
  935. {
  936.   /** Are we not activating a control in the same window as the
  937.     previous active control? */
  938.   if ( GLUI_Master.active_control_glui AND
  939.        this != (GLUI_Main*) GLUI_Master.active_control_glui ) {
  940.     GLUI_Master.active_control_glui->deactivate_current_control();
  941.   }
  942.   /*******      Now activate it      *****/
  943.   if ( control != NULL AND control->can_activate AND control->enabled ) {
  944.     active_control = control;
  945.     
  946.     control->activate(how);
  947.     /*if ( NOT active_control->is_container OR           */
  948.     /* active_control->type == GLUI_CONTROL_ROLLOUT) {          */
  949.     active_control->redraw();
  950.     /*}          */
  951.   }
  952.   else {
  953.     active_control = NULL;
  954.   }
  955.   /*  printf( "activate: %dn", glutGetWindow() );          */
  956.   GLUI_Master.active_control      = active_control;
  957.   GLUI_Master.active_control_glui = (GLUI*) this;
  958. }
  959. /************************* GLUI_Main::deactivate_current_control() **********/
  960. void         GLUI_Main::deactivate_current_control( void )
  961. {
  962.   int orig;
  963.   if ( active_control != NULL ) {
  964.     orig = active_control->set_to_glut_window();
  965.     active_control->deactivate();
  966.     
  967.     /** If this isn't a container control, then redraw it in its 
  968.       deactivated state.  Container controls, such as panels, look
  969.       the same activated or not **/
  970.     /*if ( NOT active_control->is_container OR           */
  971.     /* active_control->type == GLUI_CONTROL_ROLLOUT ) {        */
  972.     active_control->redraw();
  973.     /*}          */
  974.     active_control->restore_window( orig );
  975.     active_control = NULL;
  976.   }
  977.   /*  printf( "deactivate: %dn", glutGetWindow() );          */
  978.   GLUI_Master.active_control      = NULL;
  979.   GLUI_Master.active_control_glui = NULL;
  980. }
  981. /****************************** GLUI_Main::find_next_control() **************/
  982. GLUI_Control  *GLUI_Main::find_next_control_( GLUI_Control *control )
  983. {
  984.   /*** THIS IS NOT find_next_control()!  This is an unused older
  985.     version (look at the underscore at the end) ***/
  986.   if ( control == NULL )
  987.     return find_next_control_rec( main_panel );
  988.   else
  989.     return find_next_control_rec( control );
  990. }
  991. /****************************** GLUI_Main::find_next_control() **************/
  992. GLUI_Control  *GLUI_Main::find_next_control_rec( GLUI_Control *control )
  993. {
  994.   GLUI_Control *child = NULL, *rec_control, *sibling;
  995.   /*** Recursively investigate children ***/
  996.   child = (GLUI_Control*) control->first_child();
  997.   if ( child ) {
  998.     /*** If we can activate the first child, then do so ***/
  999.     if ( child->can_activate AND child->enabled )
  1000.       return child;
  1001.     else     /*** Recurse into first child ***/
  1002.       rec_control = find_next_control_rec( child );    
  1003.     if ( rec_control )
  1004.       return rec_control;
  1005.   }
  1006.   /*** At this point, either we don't have children, or the child cannot
  1007.     be activated.  So let's try the next sibling ***/
  1008.   sibling = (GLUI_Control*) control->next();
  1009.   if ( sibling ) {
  1010.     if ( sibling->can_activate AND sibling->enabled )
  1011.       return sibling;
  1012.     else     /*** Recurse into sibling ***/
  1013.       rec_control = find_next_control_rec( sibling );    
  1014.     if ( rec_control )
  1015.       return rec_control;
  1016.   }
  1017.   
  1018.   return NULL;
  1019. }
  1020. /****************************** GLUI_Main::find_next_control() **************/
  1021. GLUI_Control  *GLUI_Main::find_next_control( GLUI_Control *control )
  1022. {
  1023.   GLUI_Control *tmp_control = NULL;
  1024.   int           back_up;
  1025.   
  1026.   if ( control == NULL )
  1027.     control = main_panel;
  1028.   while( control != NULL ) {
  1029.     /** see if this control has a child **/
  1030.     tmp_control = (GLUI_Control*) control->first_child();
  1031.     if ( tmp_control != NULL ) {
  1032.       if ( tmp_control->can_activate AND tmp_control->enabled )
  1033. return tmp_control;
  1034.       
  1035.       control = tmp_control;  /* Descend into child */
  1036.       continue;
  1037.     }
  1038.     
  1039.     /*** At this point, control has no children ***/
  1040.     /** see if this control has a next sibling **/
  1041.     tmp_control = (GLUI_Control*) control->next();
  1042.     
  1043.     if ( tmp_control != NULL ) {
  1044.       if ( tmp_control->can_activate AND tmp_control->enabled )
  1045. return tmp_control;
  1046.       
  1047.       control = tmp_control;  
  1048.       continue;
  1049.     }
  1050.     /** back up until we find a sibling of an ancestor **/
  1051.     back_up = true;
  1052.     while ( control->parent() AND back_up ) {
  1053.       control = (GLUI_Control*) control->parent();
  1054.       if ( control->next() ) {
  1055. control = (GLUI_Control*) control->next();  
  1056. if ( control->can_activate AND control->enabled )
  1057.   return control;
  1058. else
  1059.   back_up = false;
  1060. /*** if ( control->is_container ) {
  1061.   tmp_control = control;
  1062.   control     = NULL;
  1063.   break;
  1064.   }
  1065.   else {
  1066.   back_up = false;
  1067.   }
  1068.   ***/
  1069.       }
  1070.     }
  1071.     /** Check if we've cycled back to the top... if so, return NULL **/
  1072.     if ( control == main_panel ) {
  1073.       return NULL;
  1074.     }
  1075.   }
  1076.   /*
  1077.     if ( tmp_control != NULL AND tmp_control->can_activate AND
  1078.     tmp_control->enabled ) {
  1079.     return tmp_control;
  1080.     }*/
  1081.   return NULL;
  1082. }
  1083. /****************************** GLUI_Main::find_prev_control() **************/
  1084. GLUI_Control  *GLUI_Main::find_prev_control( GLUI_Control *control )
  1085. {
  1086.   GLUI_Control *tmp_control, *next_control;
  1087.   if ( control == NULL ) {        /* here we find the last valid control */
  1088.     next_control = main_panel;
  1089.   
  1090.     do {
  1091.       tmp_control  = next_control;
  1092.       next_control = find_next_control( tmp_control ); 
  1093.     } while( next_control != NULL );
  1094.     return tmp_control;    
  1095.   }
  1096.   else {                         /* here we find the actual previous control */
  1097.     next_control = main_panel;
  1098.   
  1099.     do {
  1100.       tmp_control  = next_control;
  1101.       next_control = find_next_control( tmp_control ); 
  1102.     } while( next_control != NULL AND next_control != control );
  1103.     
  1104.     if ( next_control == NULL OR tmp_control == main_panel )
  1105.       return NULL;
  1106.     else 
  1107.       return tmp_control;
  1108.   }
  1109. }
  1110. /************************* GLUI_Master_Object::set_glutIdleFunc() ***********/
  1111. void    GLUI_Master_Object::set_glutIdleFunc(void (*f)(void))
  1112. {
  1113.   glut_idle_CB = f;
  1114.   GLUI_Master.glui_setIdleFuncIfNecessary();
  1115. }
  1116. /**************************************** GLUI::disable() ********************/
  1117. void   GLUI::disable( void )
  1118.   deactivate_current_control();
  1119.   main_panel->disable(); 
  1120. }
  1121. /******************************************** GLUI::sync_live() **************/
  1122. void   GLUI::sync_live( void )
  1123. {
  1124.   main_panel->sync_live(true, true);
  1125. }
  1126. /********************************* GLUI_Master_Object::sync_live_all() *****/
  1127. void   GLUI_Master_Object::sync_live_all( void ) 
  1128. {
  1129.   GLUI *glui;
  1130.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  1131.   while( glui ) {
  1132.    
  1133.     glui->sync_live();  /** sync it **/
  1134.  
  1135.     glui = (GLUI*) glui->next();
  1136.   }  
  1137. }
  1138. /************************************* GLUI_Master_Object::close() **********/
  1139. void   GLUI_Master_Object::close_all( void ) 
  1140. {
  1141.   GLUI *glui;
  1142.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  1143.   while( glui ) {
  1144.    
  1145.     glui->close();  /** Set flag to close **/
  1146.  
  1147.     glui = (GLUI*) glui->next();
  1148.   }  
  1149. }
  1150. /************************************* GLUI_Main::close_internal() **********/
  1151. void   GLUI_Main::close_internal( void ) 
  1152. {
  1153.   glutDestroyWindow(glutGetWindow()); /** Close this window **/
  1154.   this->unlink();
  1155.   
  1156.   if ( GLUI_Master.active_control_glui == this ) {
  1157.     GLUI_Master.active_control      = NULL;
  1158.     GLUI_Master.active_control_glui = NULL;
  1159.   }
  1160.     
  1161.   if ( parent_window != -1 ) {
  1162.     glutSetWindow( parent_window );
  1163.     int win_w = glutGet( GLUT_WINDOW_WIDTH );
  1164.     int win_h = glutGet( GLUT_WINDOW_HEIGHT );
  1165.     glutReshapeWindow(win_w+1, win_h);
  1166.     glutReshapeWindow(win_w-1, win_h);
  1167.   }
  1168.   delete this->main_panel;
  1169.   delete this;
  1170. }
  1171. /************************************************** GLUI::close() **********/
  1172. void   GLUI::close( void ) 
  1173. {
  1174.   int   old_glut_window;
  1175.   closing = true;
  1176.   old_glut_window = glutGetWindow();
  1177.   glutSetWindow( get_glut_window_id() );
  1178.   glutPostRedisplay();
  1179.   glutSetWindow( old_glut_window );
  1180. }
  1181. /************************** GLUI_Main::check_subwindow_position() **********/
  1182. void   GLUI_Main::check_subwindow_position( void )
  1183. {
  1184.   /*** Reposition this window if subwindow ***/
  1185.   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
  1186.     int parent_w, parent_h, new_x, new_y;
  1187.     int old_window = glutGetWindow();
  1188.     glutSetWindow( glut_window_id );
  1189.     glutSetWindow( glutGet( GLUT_WINDOW_PARENT ));
  1190.     parent_w = glutGet( GLUT_WINDOW_WIDTH );
  1191.     parent_h = glutGet( GLUT_WINDOW_HEIGHT );
  1192.     glutSetWindow( glut_window_id );
  1193.     if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) {
  1194.       new_x = parent_w - this->w;
  1195.       new_y = 0;
  1196.     } 
  1197.     else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
  1198.       new_x = 0;
  1199.       new_y = 0;
  1200.     } 
  1201.     else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_BOTTOM )) {
  1202.       new_x = 0;
  1203.       new_y = parent_h - this->h;
  1204.     } 
  1205.     else {    /***   GLUI_SUBWINDOW_TOP    ***/
  1206.       new_x = 0;
  1207.       new_y = 0;
  1208.     }
  1209.     /** Now make adjustments based on presence of other subwindows **/
  1210.     GLUI *curr_glui;
  1211.     curr_glui = (GLUI*) GLUI_Master.gluis.first_child(); 
  1212.     while( curr_glui ) {
  1213.       if ( TEST_AND( curr_glui->flags, GLUI_SUBWINDOW) AND 
  1214.    curr_glui->parent_window == this->parent_window ) {
  1215. if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) {
  1216. }
  1217. else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) {
  1218. }
  1219. else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) {
  1220. }
  1221. else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) AND 
  1222.   ( TEST_AND( this->flags,GLUI_SUBWINDOW_LEFT ) OR
  1223.     TEST_AND( this->flags,GLUI_SUBWINDOW_RIGHT ) ) ) {
  1224.   /** If we are a RIGHT or LEFT subwindow, and there exists some 
  1225.     TOP subwindow, bump our position down  **/
  1226.   new_y += curr_glui->h;
  1227. }
  1228. /** CHeck multiple subwins at same position  **/
  1229. /** We check the glui_id's:  only the glui with the higher
  1230.   ID number (meaning it was created later) gets bumped over **/
  1231. if ( curr_glui != this AND this->glui_id > curr_glui->glui_id ) {
  1232.   if ( TEST_AND( this->flags,GLUI_SUBWINDOW_LEFT ) AND
  1233.        TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) {
  1234.     new_x += curr_glui->w;
  1235.   }
  1236.   else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_TOP ) AND
  1237.     TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) ) {
  1238.     new_y += curr_glui->h;
  1239.   }
  1240.   else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_BOTTOM ) AND
  1241.     TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) {
  1242.     new_y -= curr_glui->h;
  1243.   }
  1244.   else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_RIGHT ) AND
  1245.     TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) {
  1246.     new_x -= curr_glui->w;
  1247.   }
  1248. }
  1249.       }
  1250.       curr_glui = (GLUI*) curr_glui->next();
  1251.     }
  1252.     CLAMP( new_x, 0, new_x );
  1253.     CLAMP( new_y, 0, new_y );
  1254.     glutPositionWindow( new_x, new_y );
  1255.     /* glutPostRedisplay();          */
  1256.     glutSetWindow( old_window );
  1257.   }
  1258. }
  1259. /********************************* GLUI_Master_Object::reshape() **********/
  1260. /* This gets called by the user from a GLUT reshape callback.  So we look */
  1261. /* for subwindows that belong to the current window                   */
  1262. void  GLUI_Master_Object::reshape( void )
  1263. {
  1264.   GLUI *glui;
  1265.   int   current_window;
  1266.   current_window = glutGetWindow();
  1267.   
  1268.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  1269.   while( glui ) {
  1270.     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND 
  1271.  glui->parent_window == current_window ) {
  1272.       glutSetWindow( glui->get_glut_window_id());
  1273.       glui->check_subwindow_position();
  1274.     }
  1275.     
  1276.     glui = (GLUI*) glui->next();
  1277.   }  
  1278.   glutSetWindow(current_window);
  1279. }
  1280. /**************************** GLUI_Master_Object::set_glutReshapeFunc() *****/
  1281. void GLUI_Master_Object::set_glutReshapeFunc(void (*f)(int width, int height))
  1282. {
  1283.   glutReshapeFunc( glui_reshape_func );
  1284.   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_RESHAPE, (void*) f);
  1285. }
  1286. /**************************** GLUI_Master_Object::set_glutKeyboardFunc() ****/
  1287. void GLUI_Master_Object::set_glutKeyboardFunc(void (*f)(unsigned char key, 
  1288. int x, int y))
  1289. {
  1290.   glutKeyboardFunc( glui_keyboard_func );
  1291.   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_KEYBOARD, (void*) f);
  1292. }
  1293. /*********************** GLUI_Master_Object::set_glutSpecialFunc() **********/
  1294. void GLUI_Master_Object::set_glutSpecialFunc(void (*f)(int key, 
  1295.        int x, int y))
  1296. {
  1297.   glutSpecialFunc( glui_special_func );
  1298.   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_SPECIAL, (void*) f);
  1299. }
  1300. /*********************** GLUI_Master_Object::set_glutMouseFunc() **********/
  1301. void GLUI_Master_Object::set_glutMouseFunc(void (*f)(int button, int state,
  1302.      int x, int y))
  1303. {
  1304.   glutMouseFunc( glui_mouse_func );
  1305.   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_MOUSE, (void*) f);
  1306. }
  1307. /****************************** glui_parent_window_reshape_func() **********/
  1308. /* This is the reshape callback for a window that contains subwindows      */
  1309. void glui_parent_window_reshape_func( int w, int h )
  1310. {
  1311.   int   current_window;
  1312.   GLUI  *glui;
  1313.   int   first = true;
  1314.   /*  printf( "glui_parent_window_reshape_func: %dn", glutGetWindow() );          */
  1315.   current_window = glutGetWindow();
  1316.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  1317.   while( glui ) {
  1318.     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND 
  1319.  glui->parent_window == current_window ) {
  1320.       glutSetWindow( glui->get_glut_window_id());
  1321.       glui->check_subwindow_position();
  1322.       glutSetWindow( current_window );
  1323.       if ( first ) {
  1324.         if (glui->glut_reshape_CB) glui->glut_reshape_CB( w, h );
  1325.         first = false;
  1326.       }
  1327.     }
  1328.     
  1329.     glui = (GLUI*) glui->next();
  1330.   }  
  1331. }
  1332. /****************************** glui_parent_window_keyboard_func() **********/
  1333. void glui_parent_window_keyboard_func(unsigned char key, int x, int y)
  1334. {
  1335.   /*  printf( "glui_parent_window_keyboard_func: %dn", glutGetWindow() );          */
  1336.   int   current_window;
  1337.   GLUI  *glui;
  1338.   current_window = glutGetWindow();
  1339.   if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) {
  1340.     glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() );
  1341.     GLUI_Master.active_control_glui->keyboard(key,x,y);    
  1342.     glutSetWindow( current_window );
  1343.   }
  1344.   else {
  1345.     glui = (GLUI*) GLUI_Master.gluis.first_child();
  1346.     while( glui ) {
  1347.       if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND 
  1348.            glui->parent_window == current_window AND
  1349.            glui->glut_keyboard_CB ) 
  1350.       {
  1351.         glui->glut_keyboard_CB( key, x, y );
  1352.         break;
  1353.       }
  1354.       glui = (GLUI*) glui->next();
  1355.     }
  1356.   } 
  1357. }
  1358. /****************************** glui_parent_window_special_func() **********/
  1359. void glui_parent_window_special_func(int key, int x, int y)
  1360. {
  1361.   /*printf( "glui_parent_window_special_func: %dn", glutGetWindow() );          */
  1362.   int   current_window;
  1363.   GLUI  *glui;
  1364.   /**  If clicking in the main area of a window w/subwindows, 
  1365.     deactivate any current control  **/
  1366.   if ( GLUI_Master.active_control_glui != NULL ) 
  1367.     GLUI_Master.active_control_glui->deactivate_current_control();
  1368.   /***   Now pass on the mouse event   ***/
  1369.   current_window = glutGetWindow();
  1370.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  1371.   while( glui ) {
  1372.     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND 
  1373.          glui->parent_window == current_window ) 
  1374.     {
  1375.       glutSetWindow( glui->get_glut_window_id());
  1376.       if (glui->glut_special_CB) glui->glut_special_CB( key, x, y );
  1377.       break;
  1378.     }
  1379.     
  1380.     glui = (GLUI*) glui->next();
  1381.   }  
  1382. }
  1383. /****************************** glui_parent_window_mouse_func() **********/
  1384. void glui_parent_window_mouse_func(int button, int state, int x, int y)
  1385. {
  1386.   int   current_window;
  1387.   GLUI  *glui;
  1388.   /**  If clicking in the main area of a window w/subwindows, 
  1389.     deactivate any current control  **/
  1390.   if ( GLUI_Master.active_control_glui != NULL ) 
  1391.     GLUI_Master.active_control_glui->deactivate_current_control();
  1392.   /***   Now pass on the mouse event   ***/
  1393.   current_window = glutGetWindow();
  1394.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  1395.   while( glui ) {
  1396.     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND 
  1397.          glui->parent_window == current_window AND
  1398.          glui->glut_mouse_CB) 
  1399.     {
  1400.       glutSetWindow( glui->get_glut_window_id());
  1401.       glui->glut_mouse_CB( button, state, x, y );
  1402.       break;
  1403.     }
  1404.     
  1405.     glui = (GLUI*) glui->next();
  1406.   } 
  1407. }
  1408. /************************** GLUI_Master_Object::find_glut_window() **********/
  1409. GLUI_Glut_Window  *GLUI_Master_Object::find_glut_window( int window_id )
  1410. {
  1411.   GLUI_Glut_Window *window;
  1412.   window = (GLUI_Glut_Window*) glut_windows.first_child();
  1413.   while( window ) {
  1414.     if ( window->glut_window_id == window_id ) 
  1415.       return window;
  1416.     
  1417.     window = (GLUI_Glut_Window*) window->next();
  1418.   }
  1419.   /***  Window not found - return NULL ***/
  1420.   return NULL;
  1421. }
  1422. /******************** GLUI_Master_Object::add_cb_to_glut_window() **********/
  1423. void     GLUI_Master_Object::add_cb_to_glut_window(int window_id,
  1424.    int cb_type,void *cb)
  1425. {
  1426.   GLUI_Glut_Window *window;
  1427.   window = find_glut_window( window_id );
  1428.   if ( NOT window ) {
  1429.     /***  Allocate new window structure  ***/
  1430.     
  1431.     window                 = new GLUI_Glut_Window;
  1432.     window->glut_window_id = window_id;
  1433.     window->link_this_to_parent_last( (GLUI_Node*) &this->glut_windows );
  1434.   }
  1435.   switch( cb_type ) {
  1436.   case GLUI_GLUT_RESHAPE:
  1437.     window->glut_reshape_CB   = (void(*)(int,int)) cb;
  1438.     break;
  1439.   case GLUI_GLUT_DISPLAY:
  1440.     window->glut_display_CB   = (void(*)()) cb;
  1441.     break;
  1442.   case GLUI_GLUT_KEYBOARD:
  1443.     window->glut_keyboard_CB  = (void(*)(unsigned char,int,int)) cb;
  1444.     break;
  1445.   case GLUI_GLUT_SPECIAL:
  1446.     window->glut_special_CB   = (void(*)(int,int,int)) cb;
  1447.     break;
  1448.   case GLUI_GLUT_MOUSE:
  1449.     window->glut_mouse_CB     = (void(*)(int,int,int,int)) cb;
  1450.     break;
  1451.   case GLUI_GLUT_MOTION:
  1452.     window->glut_motion_CB    = (void(*)(int,int)) cb;
  1453.     break;
  1454.   case GLUI_GLUT_PASSIVE_MOTION:
  1455.     window->glut_passive_motion_CB = (void(*)(int,int)) cb;
  1456.     break;
  1457.   case GLUI_GLUT_ENTRY:
  1458.     window->glut_entry_CB     = (void(*)(int)) cb;
  1459.     break;
  1460.   case GLUI_GLUT_VISIBILITY:
  1461.     window->glut_visibility_CB= (void(*)(int)) cb;
  1462.     break;
  1463.   }
  1464. }
  1465. /************* GLUI_Master_Object::set_left_button_glut_menu_control() *****/
  1466. void  GLUI_Master_Object::set_left_button_glut_menu_control( 
  1467.     GLUI_Control *control )
  1468. {
  1469.   curr_left_button_glut_menu = control;
  1470. }
  1471. /******************************* GLUI_Main::set_ortho_projection() **********/
  1472. void  GLUI_Main::set_ortho_projection( void )
  1473. {
  1474.   int win_h, win_w;
  1475.   win_w = glutGet( GLUT_WINDOW_WIDTH );
  1476.   win_h = glutGet( GLUT_WINDOW_HEIGHT );
  1477.   glMatrixMode( GL_PROJECTION );
  1478.   glLoadIdentity();
  1479.   /*  gluOrtho2D( 0.0, (float) win_w, 0.0, (float) win_h );          */
  1480.   glOrtho( 0.0, (float)win_w, 0.0, (float) win_h, -1000.0, 1000.0 );
  1481.   glMatrixMode( GL_MODELVIEW );
  1482.  
  1483.   return; /****-----------------------------------------------***/
  1484.   glMatrixMode( GL_MODELVIEW );
  1485.   glLoadIdentity();
  1486.   /*** Rotate image so y increases upwards, contrary to OpenGL axes ***/
  1487.   glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 );
  1488.   glRotatef( 180.0, 0.0, 1.0, 0.0 );
  1489.   glRotatef( 180.0, 0.0, 0.0, 1.0 );
  1490.   glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 );
  1491. }
  1492. /******************************* GLUI_Main::set_viewport() **********/
  1493. void  GLUI_Main::set_viewport( void )
  1494. {
  1495.   glViewport( 0, 0, main_panel->w, main_panel->h );
  1496. }
  1497. /****************************** GLUI_Main::refresh() ****************/
  1498. void    GLUI_Main::refresh( void )
  1499. {
  1500.   int orig;
  1501.   /******  GLUI_Glut_Window *glut_window;
  1502.     int              current_window;
  1503.     current_window = glutGetWindow();
  1504.     glut_window    = GLUI_Master.find_glut_window( current_window );
  1505.     if ( glut_window ) {
  1506.     glut_window->glut_reshape_CB(w,h);
  1507.     ******/
  1508.   orig  = glutGetWindow();
  1509.   pack_controls();
  1510.   if ( glut_window_id > 0 )
  1511.     glutSetWindow( glut_window_id );
  1512.   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
  1513.     /*** GLUI subwindow ***/
  1514.     check_subwindow_position();
  1515.   }
  1516.   else {
  1517.     /*** Standalone GLUI window ***/
  1518.     glutReshapeWindow( this->h, this->w );
  1519.   }
  1520.   glutPostRedisplay();
  1521.   glutSetWindow( orig);
  1522. }
  1523. /***************** GLUI_Master_Object::get_main_gfx_viewport() ***********/
  1524. void     GLUI_Master_Object::get_viewport_area( int *x, int *y, 
  1525. int *w, int *h )
  1526. {
  1527.   GLUI *curr_glui;
  1528.   int   curr_x, curr_y, curr_w, curr_h;
  1529.   int   curr_window;
  1530.   curr_window = glutGetWindow();
  1531.   curr_x = 0;
  1532.   curr_y = 0;
  1533.   curr_w = glutGet( GLUT_WINDOW_WIDTH );
  1534.   curr_h = glutGet( GLUT_WINDOW_HEIGHT );
  1535.   curr_glui = (GLUI*) gluis.first_child(); 
  1536.   while( curr_glui ) {
  1537.     if ( TEST_AND( curr_glui->flags, GLUI_SUBWINDOW) AND 
  1538.  curr_glui->parent_window == curr_window ) {
  1539.       /* printf( "%s -> %d   %d %dn", curr_glui->window_name.c_str(), curr_glui->flags,
  1540. curr_glui->w, curr_glui->h );*/
  1541.       if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) {
  1542. curr_x += curr_glui->w;
  1543. curr_w -= curr_glui->w;
  1544.       }
  1545.       else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) {
  1546. curr_y += curr_glui->h;
  1547. curr_h -= curr_glui->h;
  1548.       }
  1549.       else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) {
  1550. curr_w -= curr_glui->w;
  1551.       }
  1552.       else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) ) {
  1553. curr_h -= curr_glui->h;
  1554.       }
  1555.     }
  1556.     curr_glui = (GLUI*) curr_glui->next();
  1557.   }
  1558.   curr_x = MAX( 0, curr_x );
  1559.   curr_y = MAX( 0, curr_y );
  1560.   curr_w = MAX( 0, curr_w );
  1561.   curr_h = MAX( 0, curr_h );
  1562.   *x = curr_x;
  1563.   *y = curr_y;
  1564.   *w = curr_w;
  1565.   *h = curr_h;
  1566. }
  1567. /*****************GLUI_Master_Object::auto_set_main_gfx_viewport() **********/
  1568. void           GLUI_Master_Object::auto_set_viewport( void )
  1569. {
  1570.   int x, y, w, h;
  1571.   get_viewport_area( &x, &y, &w, &h );
  1572.   glViewport( MAX(x,0), MAX(y,0), MAX(w,0), MAX(h,0) );
  1573. }
  1574. /***************************************** GLUI::show() **********************/
  1575. void            GLUI::show( void )
  1576. {
  1577.   int orig_window;
  1578.   orig_window = main_panel->set_to_glut_window();
  1579.   glutShowWindow();
  1580.   main_panel->restore_window(orig_window);
  1581. }
  1582. /***************************************** GLUI::hide() **********************/
  1583. void            GLUI::hide( void )
  1584. {
  1585.   int orig_window;
  1586.   this->deactivate_current_control();
  1587.   orig_window = main_panel->set_to_glut_window();
  1588.   glutHideWindow();
  1589.   main_panel->restore_window(orig_window);
  1590. }
  1591. /**************** GLUI_DrawingSentinal **************/
  1592. GLUI_DrawingSentinal::GLUI_DrawingSentinal(GLUI_Control *c_) 
  1593. :c(c_)
  1594. {
  1595. orig_win = c->set_to_glut_window();
  1596. orig_buf = c->glui->set_current_draw_buffer();
  1597. }
  1598. GLUI_DrawingSentinal::~GLUI_DrawingSentinal() {
  1599. c->glui->restore_draw_buffer(orig_buf);
  1600. c->restore_window(orig_win);
  1601. }
  1602. void GLUI_Master_Object::glui_setIdleFuncIfNecessary( void )
  1603. {
  1604.   GLUI *glui;
  1605.   glui = (GLUI*) GLUI_Master.gluis.first_child();
  1606.   int necessary;
  1607.   if (this->glut_idle_CB) 
  1608.     necessary = true;
  1609.   else {
  1610.     necessary = false;
  1611.     while( glui ) {
  1612.       if( glui->needs_idle() ) {
  1613. necessary = true;
  1614. break;
  1615.       }
  1616.       glui = (GLUI*) glui->next();
  1617.     }
  1618.   }
  1619.   if( necessary )
  1620.     glutIdleFunc( glui_idle_func );  
  1621.   else
  1622.     glutIdleFunc( NULL );  
  1623. }