00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #include "Mouse.h"
00034 #include "DisplayDevice.h"
00035 #include "TextEvent.h"
00036 #include "CommandQueue.h"
00037 #include "Inform.h"
00038 #include "PickList.h"
00039 #include "VMDApp.h"
00040 
00041 #include "VideoStream.h" 
00042 
00043 
00044 Mouse::Mouse(VMDApp *vmdapp) : UIObject(vmdapp) {
00045 
00046 #ifndef VMDGUI
00047   
00048   
00049   app->display->queue_events(); 
00050 #endif
00051 
00052   
00053 
00054   
00055   rocking_enabled = 1;
00056   transInc = 0.002f;
00057   rotInc = 1.0f/15.0f;
00058   scaleInc = 0.0002f;
00059   RotVelScale = 0.4f;
00060   currX = currY = oldX = oldY = 0;
00061   stop_rotation();
00062   moveObj = 0;
00063   moveMode = ROTATION;
00064   pickInProgress = B_NONE;
00065   buttonDown = B_NONE;
00066 
00067 #ifdef VMDVRJUGGLER
00068   
00069   if (app && app->display)
00070     app->display->set_cursor(DisplayDevice::NORMAL_CURSOR); 
00071 #else
00072   app->display->set_cursor(DisplayDevice::NORMAL_CURSOR); 
00073 #endif
00074 
00075   reset();
00076 }
00077 
00078 
00079 
00080 Mouse::~Mouse(void) {
00081   move_mode(ROTATION);
00082 }
00083 
00084 const char* Mouse::get_mode_str(MoveMode mm) {
00085   const char* modestr;
00086   
00087   switch (mm) {
00088     default:
00089     case ROTATION:    
00090                       modestr = "rotate";     break; 
00091     case TRANSLATION: modestr = "translate";  break;
00092     case SCALING:     modestr = "scale";      break;
00093     case LIGHT:       modestr = "light";      break;
00094     case USERPOINT:   modestr = "userpoint";  break;
00095   
00096     case PICK:        modestr = "pick";       break;
00097     case QUERY:       modestr = "query";      break;
00098     case CENTER:      modestr = "center";     break;
00099     case LABELATOM:   modestr = "labelatom";  break;
00100     case LABELBOND:   modestr = "labelbond";  break;
00101     case LABELANGLE:  modestr = "labelangle"; break;
00102     case LABELDIHEDRAL: modestr = "labeldihedral"; break;
00103     case MOVEATOM:    modestr = "moveatom";   break;
00104     case MOVERES:     modestr = "moveres";    break;
00105     case MOVEFRAG:    modestr = "movefrag";   break;
00106     case MOVEMOL:     modestr = "movemol";    break;
00107     case FORCEATOM:   modestr = "forceatom";  break;
00108     case FORCERES:    modestr = "forceres";   break;
00109     case FORCEFRAG:   modestr = "forcefrag";  break;
00110     case MOVEREP:     modestr = "moverep";    break;
00111     case ADDBOND:     modestr = "addbond";    break;
00112   }
00113   
00114   return modestr;
00115 }
00116 
00118 
00119 
00120 void Mouse::stop_rotation(void) {
00121   xRotVel = yRotVel = zRotVel = 0.0; 
00122 }
00123 
00124 
00125 int Mouse::move_mode(MoveMode mm, int mobj) {
00126   const char *modestr;
00127 
00128   
00129   if (pickInProgress)
00130     return FALSE; 
00131 
00132   
00133   stop_rotation();
00134 
00135   
00136   if (moveMode == LIGHT) {
00137     app->light_highlight(moveObj, FALSE); 
00138   }
00139 
00140   
00141   if (mm == LIGHT) {
00142     moveObj = mobj;
00143     app->light_highlight(moveObj, TRUE); 
00144   }
00145 
00146   
00147   moveMode = mm; 
00148 
00149   
00150   
00151   
00152   modestr = get_mode_str(moveMode);
00153   runcommand(new MouseModeEvent(modestr, mobj));    
00154 
00155   
00156   switch (moveMode) {
00157     case ROTATION:
00158     case LIGHT:
00159     case USERPOINT:
00160       app->display->set_cursor(DisplayDevice::NORMAL_CURSOR);
00161       break;
00162 
00163     case TRANSLATION:
00164       app->display->set_cursor(DisplayDevice::TRANS_CURSOR);
00165       break;
00166 
00167     case SCALING:
00168       app->display->set_cursor(DisplayDevice::SCALE_CURSOR);
00169       break;
00170 
00171     
00172     default:
00173       app->display->set_cursor(DisplayDevice::PICK_CURSOR);
00174       break;
00175   }
00176 
00177   return TRUE; 
00178 }
00179 
00180 
00181 
00182 
00183 
00184 
00185 int Mouse::mouse_moved() {
00186   int dx, dy, mymouseMoved;
00187   int b1Down, b2Down;
00188 
00189   b1Down = buttonDown == B_LEFT;
00190 
00191   
00192   
00193   b2Down = (buttonDown == B_MIDDLE || buttonDown == B_RIGHT);
00194 
00195   if (b1Down || b2Down) {
00196     xRotVel = yRotVel = zRotVel = 0.0; 
00197   }
00198 
00199   
00200   currX = app->display->x();
00201   currY = app->display->y();
00202 
00203   
00204   dx =  5 * (currX - oldX);
00205   dy = -5 * (currY - oldY); 
00206 
00207   mymouseMoved = (dx != 0 || dy != 0);
00208   if (!mymouseMoved)
00209     return FALSE;  
00210 
00211   
00212   if (make_callbacks && !b1Down && !b2Down) {
00213     float r[2], oldr[2];
00214     r[0] = (float) currX; 
00215     r[1] = (float) currY;
00216     oldr[0] = (float) oldX; 
00217     oldr[1] = (float) oldY;
00218     int tag;
00219 
00220     app->display->rel_screen_pos(r[0], r[1]);
00221     app->display->rel_screen_pos(oldr[0], oldr[1]);
00222     if ((r[0] >= 0.0 && r[0] <= 1.0 && r[1] >= 0.0 && r[1] <= 1.0)) {
00223       
00224       app->pickList->pick_check(2, r, tag, NULL, 0.01f, (char *)"mouse");
00225     } else if (oldr[0] >= 0.0 && oldr[0] <= 1.0 && oldr[1] >= 0.0 &&
00226                oldr[1] <= 1.0) {
00227       
00228       app->commandQueue->runcommand(new PickAtomCallbackEvent(-1,-1,"mouse"));
00229     }
00230   }
00231 
00232 
00233   
00234   oldX = currX;
00235   oldY = currY;
00236 
00237   if (!b1Down && !b2Down) return FALSE;
00238 
00239   
00240   if (pickInProgress) {
00241     float mx = (float) currX;
00242     float my = (float) currY;
00243     app->display->rel_screen_pos(mx, my);
00244     if (mx >= 0.0 && mx <= 1.0 && my >= 0.0 && my <= 1.0) {
00245       float p[2];
00246       p[0] = mx;
00247       p[1] = my;
00248       app->pickList->pick_move(p);
00249     }
00250     return TRUE; 
00251   }
00252 
00253   
00254   
00255 
00256 #if defined(VMDXPLOR)
00257   
00258   DisplayDevice* dispDev = app->display;
00259   
00260   if (b1Down) {
00261     if (dispDev->shift_state()==0 &&
00262         (moveMode == ROTATION || moveMode == LIGHT || moveMode >= PICK)) {
00263 #else
00264   
00265   
00266   if (b1Down) {
00267     if (moveMode == ROTATION || moveMode == LIGHT || moveMode >= PICK) {
00268 #endif
00269       xRotVel = rotInc * (float)dy;
00270       yRotVel = rotInc * (float)dx;
00271       if (moveMode == ROTATION ||  moveMode >= PICK) {
00272         
00273         if (xRotVel != 0.0) {
00274           app->scene_rotate_by(xRotVel, 'x');
00275           xRotVel *= RotVelScale;
00276         }
00277         if (yRotVel != 0.0) {
00278           app->scene_rotate_by(yRotVel, 'y');
00279           yRotVel *= RotVelScale;
00280         }
00281       } else {
00282         
00283         if (xRotVel != 0.0) {
00284           app->light_rotate(moveObj, xRotVel, 'x');
00285           xRotVel *= RotVelScale;
00286         }
00287         if (yRotVel != 0.0) {
00288           app->light_rotate(moveObj, yRotVel, 'y');
00289           yRotVel *= RotVelScale;
00290         }
00291       }
00292 
00293 #if defined(VMDXPLOR)
00294     
00295     } else if ((dispDev->shift_state() & DisplayDevice::SHIFT ||
00296                 moveMode == TRANSLATION) && mymouseMoved) {
00297       app->scene_translate_by(transInc*(float)dx, -transInc*(float)dy, 0.0);
00298     } else if ((dispDev->shift_state() & DisplayDevice::CONTROL ||
00299                 moveMode == SCALING) && dx != 0) {
00300 #else
00301     
00302     } else if (moveMode == TRANSLATION && mymouseMoved) {
00303       app->scene_translate_by(transInc*(float)dx, -transInc*(float)dy, 0.0);
00304     } else if (moveMode == SCALING && dx != 0) {
00305 #endif
00306       float scf = scaling + scaleInc * (float)dx;
00307       if(scf < 0.0)
00308         scf = 0.0;
00309       app->scene_scale_by(scf);
00310     }
00311   }
00312   
00313   
00314   if (b2Down) {
00315 #if defined(VMDXPLOR)
00316     
00317     if (dispDev->shift_state()==0 &&
00318        (moveMode == ROTATION || moveMode == LIGHT || moveMode >= PICK)) {
00319 #else
00320     
00321     if (moveMode == ROTATION || moveMode == LIGHT || moveMode >= PICK) {
00322 #endif
00323       zRotVel = rotInc * (float)dx;
00324       if (moveMode == ROTATION ||  moveMode >= PICK) {
00325         if (zRotVel != 0.0) {
00326           app->scene_rotate_by(zRotVel, 'z');
00327           zRotVel *= RotVelScale;
00328         }
00329       } else {
00330         if (zRotVel != 0.0) {
00331           app->light_rotate(moveObj, zRotVel, 'z');
00332           zRotVel *= RotVelScale;
00333         }
00334       }
00335 #if defined(VMDXPLOR)
00336     
00337     } else if ((dispDev->shift_state() & DisplayDevice::SHIFT ||
00338                moveMode == TRANSLATION) && dx != 0) {
00339       app->scene_translate_by(0.0, 0.0, transInc * (float)dx);
00340     } else if ((dispDev->shift_state() & DisplayDevice::CONTROL ||
00341                moveMode == SCALING) && dx != 0) {
00342 #else
00343     
00344     } else if(moveMode == TRANSLATION && dx != 0) {
00345       app->scene_translate_by(0.0, 0.0, transInc * (float)dx);
00346     } else if(moveMode == SCALING && dx != 0) {
00347 #endif
00348       float scf = scaling + 10.0f * scaleInc * (float)dx;
00349       if(scf < 0.0)
00350         scf = 0.0;
00351       app->scene_scale_by(scf);
00352     }
00353   }
00354 
00355   return TRUE; 
00356 }
00357 
00358 
00359 
00360 
00361 
00362 int Mouse::mouse_userpoint() {
00363   float mpos[2];
00364 
00365   xRotVel = yRotVel = zRotVel = 0.0; 
00366 
00367   
00368   currX = app->display->x();
00369   currY = app->display->y();
00370 
00371   mpos[0] = (float) currX;
00372   mpos[1] = (float) currY;
00373 
00374   app->display->rel_screen_pos(mpos[0], mpos[1]);
00375 
00376   
00377   app->commandQueue->runcommand(new MousePositionEvent(mpos[0], mpos[1], buttonDown));
00378 
00379   
00380   oldX = currX;
00381   oldY = currY;
00382 
00383   
00384   
00385   return FALSE;
00386 }
00387 
00388 
00389 
00391    
00392 
00393 void Mouse::reset(void) {
00394   scaling = 1.0;
00395   stop_rotation();
00396   currX = oldX = app->display->x();
00397   currY = oldY = app->display->y();
00398 }
00399 
00400 void Mouse::handle_winevent(long dev, long val) {
00401   switch(dev) {
00402     case DisplayDevice::WIN_WHEELUP:
00403       app->scene_scale_by(1.200f); 
00404       break;
00405 
00406     case DisplayDevice::WIN_WHEELDOWN:
00407       app->scene_scale_by(0.833f); 
00408       break;
00409 
00410     case DisplayDevice::WIN_LEFT:
00411     case DisplayDevice::WIN_MIDDLE:
00412     case DisplayDevice::WIN_RIGHT:
00413       if (val == 1 && buttonDown == B_NONE) {
00414         
00415         xRotVel = yRotVel = zRotVel = 0.0; 
00416 
00417         oldX = currX = app->display->x(); 
00418         oldY = currY = app->display->y();
00419   
00420         if (dev == DisplayDevice::WIN_LEFT)
00421           buttonDown = B_LEFT;
00422         else if (dev == DisplayDevice::WIN_MIDDLE)
00423           buttonDown = B_MIDDLE; 
00424         else
00425           buttonDown = B_RIGHT;
00426 
00427         
00428         if ( moveMode >= PICK && ! pickInProgress) {
00429           pickInProgress = buttonDown;
00430           float mx = (float) currX;
00431           float my = (float) currY;
00432           app->display->rel_screen_pos(mx, my);
00433   
00434           
00435           float p[2];
00436           p[0] = mx;
00437           p[1] = my;
00438           if (app->pickList->pick_start(pickInProgress, 2, p) < 0)
00439             pickInProgress = B_NONE;
00440         }
00441       } else if (val == 0 && buttonDown != B_NONE) {
00442         
00443         if (pickInProgress) {
00444           pickInProgress = B_NONE;
00445           app->pickList->pick_end(); 
00446         }
00447 
00448         
00449         buttonDown = B_NONE;
00450       }
00451       break;
00452 
00453     case DisplayDevice::WIN_KBD:
00454     case DisplayDevice::WIN_KBD_ESCAPE:
00455     case DisplayDevice::WIN_KBD_UP:
00456     case DisplayDevice::WIN_KBD_DOWN:
00457     case DisplayDevice::WIN_KBD_LEFT: 
00458     case DisplayDevice::WIN_KBD_RIGHT: 
00459     case DisplayDevice::WIN_KBD_PAGE_UP:
00460     case DisplayDevice::WIN_KBD_PAGE_DOWN:
00461     case DisplayDevice::WIN_KBD_HOME:
00462     case DisplayDevice::WIN_KBD_END:
00463     case DisplayDevice::WIN_KBD_INSERT:
00464     case DisplayDevice::WIN_KBD_DELETE:
00465     case DisplayDevice::WIN_KBD_F1:
00466     case DisplayDevice::WIN_KBD_F2:
00467     case DisplayDevice::WIN_KBD_F3:
00468     case DisplayDevice::WIN_KBD_F4:
00469     case DisplayDevice::WIN_KBD_F5:
00470     case DisplayDevice::WIN_KBD_F6:
00471     case DisplayDevice::WIN_KBD_F7:
00472     case DisplayDevice::WIN_KBD_F8:
00473     case DisplayDevice::WIN_KBD_F9:
00474     case DisplayDevice::WIN_KBD_F10:
00475     case DisplayDevice::WIN_KBD_F11:
00476     case DisplayDevice::WIN_KBD_F12:
00477       
00478       
00479       
00480       if (app->uivs && app->uivs->cli_connected()) {
00481         app->uivs->cli_send_keyboard(dev, (char) val, app->display->shift_state());
00482       } else {
00483         runcommand(new UserKeyEvent((DisplayDevice::EventCodes) dev, (char) val, app->display->shift_state()));
00484       }
00485       break;
00486 
00487     default:
00488       ; 
00489   }  
00490 }
00491 
00492 void Mouse::set_rocking(int on) {
00493   rocking_enabled = on;
00494   if (!on) {
00495     xRotVel = yRotVel = zRotVel = 0; 
00496   }
00497 }
00498 
00499 
00500 int Mouse::check_event(void) {
00501   int retval = FALSE;
00502   long dev=0, val=0; 
00503 
00504   if ((retval = app->display->read_event(dev, val)))
00505     handle_winevent(dev, val);
00506 
00507   if (moveMode == USERPOINT) {
00508     mouse_userpoint(); 
00509   } else if (make_callbacks || buttonDown != B_NONE) {
00510     if (mouse_moved()) {
00511       
00512     } 
00513   }
00514 
00515   
00516   if (rocking_enabled && !(app->uivs && app->uivs->cli_connected())) {
00517     
00518     if (xRotVel != 0.0 || yRotVel != 0.0 || zRotVel != 0.0) {
00519       if (moveMode != LIGHT) {          
00520         if (xRotVel != 0.0)
00521           app->scene_rotate_by(xRotVel, 'x');
00522         if (yRotVel != 0.0)
00523           app->scene_rotate_by(yRotVel, 'y');
00524         if (zRotVel != 0.0)
00525           app->scene_rotate_by(zRotVel, 'z');
00526       } else {                         
00527         if (xRotVel != 0.0)
00528           app->light_rotate(moveObj, xRotVel, 'x');
00529         if (yRotVel != 0.0)
00530           app->light_rotate(moveObj, yRotVel, 'y');
00531         if (zRotVel != 0.0)
00532           app->light_rotate(moveObj, zRotVel, 'z');
00533       }
00534     }
00535   }
00536   return retval;
00537 }
00538 
00539 
00540