Revision: 6763
          http://playerstage.svn.sourceforge.net/playerstage/?rev=6763&view=rev
Author:   jeremy_asher
Date:     2008-07-04 15:05:58 -0700 (Fri, 04 Jul 2008)

Log Message:
-----------
Rewrote model selection code to mirror standard selection functionality and to 
fix bugs

Modified Paths:
--------------
    code/stage/trunk/libstage/canvas.cc
    code/stage/trunk/libstage/stage.hh

Modified: code/stage/trunk/libstage/canvas.cc
===================================================================
--- code/stage/trunk/libstage/canvas.cc 2008-07-04 22:01:25 UTC (rev 6762)
+++ code/stage/trunk/libstage/canvas.cc 2008-07-04 22:05:58 UTC (rev 6763)
@@ -73,8 +73,6 @@
   interval = 50; //msec between redraws
 
   graphics = true;
-  dragging = false;
-  rotating = false;
 
   // // start the timer that causes regular redraws
   Fl::add_timeout( ((double)interval/1000), 
@@ -86,12 +84,8 @@
 {
 }
 
-StgModel* StgCanvas::Select( int x, int y )
+StgModel* StgCanvas::getModel( int x, int y )
 {
-  // TODO XX
-  //return NULL;
-
-       
   // render all models in a unique color
   make_current(); // make sure the GL context is current
   glClearColor ( 1,1,1,1 ); // white
@@ -158,30 +152,47 @@
   glEnable(GL_DITHER);
   glEnable(GL_BLEND);
   glClearColor ( 0.7, 0.7, 0.8, 1.0);
+  
+  return mod;
+}
 
-  if( mod ) // we clicked on a root model
+bool StgCanvas::selected( StgModel* mod ) {
+       if( g_list_find( selected_models, mod ) )
+               return true;
+       else
+               return false;
+}
+
+void StgCanvas::select( StgModel* mod ) {
+       if( mod )
     {
-      // if it's already selected
-      if( GList* link = g_list_find( selected_models, mod ) )
-       {
-         // remove it from the selected list
-         selected_models = 
-           g_list_remove_link( selected_models, link );
-         mod->Disable();
-       }                         
-      else      
-       {
-         last_selection = mod;
-         selected_models = g_list_prepend( selected_models, mod );
-         mod->Enable();
-       }
-
-      invalidate();
+               last_selection = mod;
+               selected_models = g_list_prepend( selected_models, mod );
+//             mod->Disable();
     }
+}
 
-  return mod;
+void StgCanvas::unSelect( StgModel* mod ) {
+       if( mod )
+       {
+               if ( GList* link = g_list_find( selected_models, mod ) ) 
+               {
+                       // remove it from the selected list
+                       selected_models = 
+                       g_list_remove_link( selected_models, link );
+//                     mod->Enable();
+               }
+       }  
 }
 
+void StgCanvas::unSelectAll() { 
+//     for( GList* it=selected_models; it; it=it->next )
+//             ((StgModel*)it->data)->Enable();
+       
+       g_list_free( selected_models );
+       selected_models = NULL;
+}
+
 // convert from 2d window pixel to 3d world coordinates
 void StgCanvas::CanvasToWorld( int px, int py, 
                               double *wx, double *wy, double* wz )
@@ -207,194 +218,205 @@
        case FL_MOUSEWHEEL:
                if( selected_models )
                {
-         // rotate all selected models
-         for( GList* it = selected_models; it; it=it->next )
-           {
-             StgModel* mod = (StgModel*)it->data;
-             mod->AddToPose( 0,0,0, 0.1*(double)Fl::event_dy() );
-           }
-         redraw();
+                       // rotate all selected models
+                       for( GList* it = selected_models; it; it=it->next )
+                       {
+                               StgModel* mod = (StgModel*)it->data;
+                               mod->AddToPose( 0,0,0, 
0.1*(double)Fl::event_dy() );
+                       }
+                       redraw();
                }
-      else
-       {
-         if( perspectiveCam == true ) {
-           perspective_camera.scroll( Fl::event_dy() / 10.0 );
-         } else {
-           camera.scale( Fl::event_dy(),  Fl::event_x(), w(), Fl::event_y(), 
h() );
-         }
-         invalidate();
-         redraw();
-       }
-      return 1;
+               else
+               {
+                       if( perspectiveCam == true ) {
+                               perspective_camera.scroll( Fl::event_dy() / 
10.0 );
+                       }
+                       else {
+                               camera.scale( Fl::event_dy(),  Fl::event_x(), 
w(), Fl::event_y(), h() );
+                       }
+                       invalidate();
+                       redraw();
+               }
+               return 1;
+                       
+       case FL_MOVE: // moused moved while no button was pressed
+               if( Fl::event_state( FL_CTRL ) )
+               {          
+                       int dx = Fl::event_x() - startx;
+                       int dy = Fl::event_y() - starty;
 
-    case FL_MOVE: // moused moved while no button was pressed
-      if( Fl::event_state( FL_CTRL ) )
-       {          
-         int dx = Fl::event_x() - startx;
-         int dy = Fl::event_y() - starty;
+                       if( perspectiveCam == true ) {
+                               perspective_camera.addYaw( -dx );
+                               perspective_camera.addPitch( -dy );
+                       } 
+                       else {
+                               camera.pitch( 0.5 * static_cast<double>( dy ) );
+                               camera.yaw( 0.5 * static_cast<double>( dx ) );
+                       }
+                       invalidate();
+                       redraw();
+               }
+               else if( Fl::event_state( FL_ALT ) )
+               {   
+                       int dx = Fl::event_x() - startx;
+                       int dy = Fl::event_y() - starty;
 
-         if( perspectiveCam == true ) {
-           perspective_camera.addYaw( -dx );
-           perspective_camera.addPitch( -dy );
-         } else {
-           camera.pitch( 0.5 * static_cast<double>( dy ) );
-           camera.yaw( 0.5 * static_cast<double>( dx ) );
-         }
+                       if( perspectiveCam == true ) {
+                               perspective_camera.move( -dx, dy, 0.0 );
+                       } 
+                       else {
+                               camera.move( -dx, dy );
+                       }
+                       invalidate();
 
-         invalidate();
-         redraw();
-       }
-      else if( Fl::event_state( FL_ALT ) )
-       {   
-         int dx = Fl::event_x() - startx;
-         int dy = Fl::event_y() - starty;
+               }
+               startx = Fl::event_x();
+               starty = Fl::event_y();
+               return 1;
 
-         if( perspectiveCam == true ) {
-           perspective_camera.move( -dx, dy, 0.0 );
-         } else {
-           camera.move( -dx, dy );
+       case FL_PUSH: // button pressed
+               StgModel* mod = getModel( startx, starty );
+               startx = Fl::event_x();
+               starty = Fl::event_y();
+               selectedModel = false;
+               switch( Fl::event_button() )
+               {
+               case 1:                 
+                       if( mod ) { 
+                               // clicked a model
+                               if ( Fl::event_state( FL_SHIFT ) ) {
+                                       // holding shift, toggle selection
+                                       if ( selected( mod ) ) 
+                                               unSelect( mod );
+                                       else {
+                                               select( mod );
+                                               selectedModel = true; // 
selected a model
+                                       }
+                               }
+                               else {
+                                       if ( !selected( mod ) ) {
+                                               // clicked on an unselected 
model while
+                                               //  not holding shift, this is 
the new
+                                               //  selection
+                                               unSelectAll();
+                                               select( mod );
+                                       }
+                                       selectedModel = true; // selected a 
model
+                               }
+                       }
+                       else {
+                               // clicked on empty space, unselect all
+                               unSelectAll();
+                       }
+                       return 1;
+               case 3:
+               {
+                       // leave selections alone
+                       // rotating handled within FL_DRAG
+                       return 1;
+               }
+               default:
+                       return 0;
+               }    
 
-         }
-         invalidate();
-
-       }
-
-      startx = Fl::event_x();
-      starty = Fl::event_y();
-                       
-      return 1;
-
-    case FL_PUSH: // button pressed
-      switch( Fl::event_button() )
+       case FL_DRAG: // mouse moved while button was pressed
        {
-       case 1:
-         startx = Fl::event_x();
-         starty = Fl::event_y();
-         if( Select( startx, starty ) )
-           dragging = true;      
-         return 1;
-       case 3:
-         {
-           startx = Fl::event_x();
-           starty = Fl::event_y();
-           if( Select( startx, starty ) )
-             rotating = true;    
-           return 1;
-         }
-       default:
-         return 0;
-       }    
+               int dx = Fl::event_x() - startx;
+               int dy = Fl::event_y() - starty;
 
-    case FL_DRAG: // mouse moved while button was pressed
-      {
-       int dx = Fl::event_x() - startx;
-       int dy = Fl::event_y() - starty;
+               if ( Fl::event_state( FL_BUTTON1 ) ) {
+                       // Left mouse button drag
+                       if ( selectedModel ) {
+                               // started dragging on a selected model
+                               
+                               double sx,sy,sz;
+                               CanvasToWorld( startx, starty,
+                                                         &sx, &sy, &sz );
+                               double x,y,z;
+                               CanvasToWorld( Fl::event_x(), Fl::event_y(),
+                                                         &x, &y, &z );
+                               // move all selected models to the mouse pointer
+                               for( GList* it = selected_models; it; 
it=it->next )
+                               {
+                                       StgModel* mod = (StgModel*)it->data;
+                                       mod->AddToPose( x-sx, y-sy, 0, 0 );
+                               }
+                       }
+                       else {
+                               // started dragging on empty space or an
+                               //  unselected model, move the canvas
+                               camera.move( -dx, dy );
+                               invalidate(); // so the projection gets updated
+                       }
+               }
+               else if ( Fl::event_state( FL_BUTTON3 ) ) {
+                               // rotate all selected models
+                               for( GList* it = selected_models; it; 
it=it->next )
+                               {
+                                       StgModel* mod = (StgModel*)it->data;
+                                       mod->AddToPose( 0,0,0, 0.05*dx );
+                               }
+               }
+               
+               startx = Fl::event_x();
+               starty = Fl::event_y();
 
-       switch( Fl::event_button() )
-         {
-         case 1:
-           if( dragging )
-             {
-               assert(selected_models);
+               redraw();
+               return 1;
+       } // end case FL_DRAG
 
-               double sx,sy,sz;
-               CanvasToWorld( startx, starty,
-                              &sx, &sy, &sz );
-               double x,y,z;
-               CanvasToWorld( Fl::event_x(), Fl::event_y(),
-                              &x, &y, &z );
+       case FL_RELEASE:   // mouse button released
+               
+               return 1;
 
-               // move all selected models to the mouse pointer
-               for( GList* it = selected_models; it; it=it->next )
-                 {
-                   StgModel* mod = (StgModel*)it->data;
-                   mod->AddToPose( x-sx, y-sy, 0, 0 );
-                 }
-             }
-           else
-             {
-               camera.move( -dx, dy );
-               invalidate(); // so the projection gets updated
-             }
-           break;          
-         case 3: // right button
-           if( rotating )
-             {
-               // move all selected models to the mouse pointer
-               for( GList* it = selected_models; it; it=it->next )
-                 {
-                   StgModel* mod = (StgModel*)it->data;
-                   mod->AddToPose( 0,0,0, 0.05*dx );
-                 }
-             }
-           break;
-         }
-      }
-      startx = Fl::event_x();
-      starty = Fl::event_y();
+       case FL_FOCUS:
+       case FL_UNFOCUS:
+               //.... Return 1 if you want keyboard events, 0 otherwise
+               return 1;
 
-      redraw();
-      return 1; // end case FL_DRAG
-
-    case FL_RELEASE:   // mouse button released
-      // unselect everyone unless shift is pressed
-      if( ! Fl::event_state( FL_SHIFT ) )
-       {
-         for( GList* it=selected_models; it; it=it->next )
-           ((StgModel*)it->data)->Enable();
-
-         g_list_free( selected_models );
-         selected_models = NULL;
-         dragging = false;
-         rotating = false;
-         redraw();
-       }
-      return 1;
-
-    case FL_FOCUS :
-    case FL_UNFOCUS :
-      //.... Return 1 if you want keyboard events, 0 otherwise
-      return 1;
-    case FL_KEYBOARD:
-      switch( Fl::event_key() )
-       {
-       case 'p': // pause
-         world->TogglePause();
-         break;
-       case ' ': // space bar
-         camera.resetAngle();
-         //invalidate();
-         if( Fl::event_state( FL_CTRL ) ) {
-                 resetCamera();
-         }
-         redraw();
-         break;
-       case FL_Left:
-         if( perspectiveCam == false ) { camera.move( -10, 0 ); } 
-         else { perspective_camera.strafe( -0.5 ); } break;
-       case FL_Right: 
-         if( perspectiveCam == false ) {camera.move( 10, 0 ); } 
-         else { perspective_camera.strafe( 0.5 ); } break;
-       case FL_Down:  
-         if( perspectiveCam == false ) {camera.move( 0, -10 ); } 
-         else { perspective_camera.forward( -0.5 ); } break;
-       case FL_Up:  
-         if( perspectiveCam == false ) {camera.move( 0, 10 ); } 
-         else { perspective_camera.forward( 0.5 ); } break;
+       case FL_KEYBOARD:
+               switch( Fl::event_key() )
+               {
+               case 'p': // pause
+                       world->TogglePause();
+                       break;
+               case ' ': // space bar
+                       camera.resetAngle();
+                       //invalidate();
+                       if( Fl::event_state( FL_CTRL ) ) {
+                               resetCamera();
+                       }
+                       redraw();
+                       break;                  
+               case FL_Left:
+                       if( perspectiveCam == false ) { camera.move( -10, 0 ); 
} 
+                       else { perspective_camera.strafe( -0.5 ); } break;
+               case FL_Right: 
+                       if( perspectiveCam == false ) {camera.move( 10, 0 ); } 
+                       else { perspective_camera.strafe( 0.5 ); } break;
+               case FL_Down:  
+                       if( perspectiveCam == false ) {camera.move( 0, -10 ); } 
+                       else { perspective_camera.forward( -0.5 ); } break;
+               case FL_Up:  
+                       if( perspectiveCam == false ) {camera.move( 0, 10 ); } 
+                       else { perspective_camera.forward( 0.5 ); } break;
+               default:
+                       return 0; // keypress unhandled
+               }
+               
+               invalidate(); // update projection
+               return 1;
+                       
+//     case FL_SHORTCUT:
+//             //... shortcut, key is in Fl::event_key(), ascii in 
Fl::event_text()
+//             //... Return 1 if you understand/use the shortcut event, 0 
otherwise...
+//             return 1;
        default:
-         return 0; // keypress unhandled
-       }
-      invalidate(); // update projection
-      return 1;
-      //case FL_SHORTCUT:
-      ///... shortcut, key is in Fl::event_key(), ascii in Fl::event_text()
-      // ... Return 1 if you understand/use the shortcut event, 0 otherwise...
-      //return 1;
-    default:
-      // pass other events to the base class...
-      //printf( "EVENT %d\n", event );
-      return Fl_Gl_Window::handle(event);
-    }
+               // pass other events to the base class...
+               //printf( "EVENT %d\n", event );
+               return Fl_Gl_Window::handle(event);
+                       
+    } // end switch( event )
 }
 
 void StgCanvas::FixViewport(int W,int H) 
@@ -595,15 +617,17 @@
   
   // draw the model-specific visualizations
        if( showData ) {
-               GList* it;
-               if ( visualizeAll )
-                       it = world->StgWorld::children;
-               else
-                       it = selected_models;
-                       for( ; it; it=it->next ) 
+               if ( visualizeAll ) {
+                       for( GList* it = world->StgWorld::children; it; 
it=it->next ) 
                                ((StgModel*)it->data)->DataVisualizeTree();
-
-               
+               }
+               else if ( selected_models ) {
+                       for( GList* it = selected_models; it; it=it->next ) 
+                               ((StgModel*)it->data)->DataVisualizeTree();
+               }
+               else if ( last_selection ) {
+                       last_selection->DataVisualizeTree();
+               }
        }
   
   if( showGrid ) 

Modified: code/stage/trunk/libstage/stage.hh
===================================================================
--- code/stage/trunk/libstage/stage.hh  2008-07-04 22:01:25 UTC (rev 6762)
+++ code/stage/trunk/libstage/stage.hh  2008-07-04 22:05:58 UTC (rev 6763)
@@ -1928,8 +1928,7 @@
   StgPerspectiveCamera perspective_camera;
   
   int startx, starty;
-  bool dragging;
-  bool rotating;
+  bool selectedModel;
   GList* selected_models; ///< a list of models that are currently
   ///selected by the user
   StgModel* last_selection; ///< the most recently selected model
@@ -1986,7 +1985,11 @@
        void CanvasToWorld( int px, int py, 
                        double *wx, double *wy, double* wz );
 
-       StgModel* Select( int x, int y );
+       StgModel* getModel( int x, int y );
+       bool selected( StgModel* mod );
+       void select( StgModel* mod );
+       void unSelect( StgModel* mod );
+       void unSelectAll();
 
        inline void PushColor( stg_color_t col )
        { colorstack.Push( col ); } 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to