From: <jer...@us...> - 2008-07-04 15:05:49
|
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. |