00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: PickModeMolLabel.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.46 $ $Date: 2019年01月17日 21:21:01 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * 00019 * The PickMode object which allows a pointer to be used to create new 00020 * geometrical monitoring labels. This particular version is used only for 00021 * adding molecular labels, i.e. Atoms, Bonds, Angles, and Dihedrals. As 00022 * more atoms are selected, they are remembered until enough have been picked 00023 * to create the relevant label (i.e. 3 atoms to create an Angle label). 00024 * 00025 ***************************************************************************/ 00026 00027 #include <math.h> 00028 #include "PickModeMolLabel.h" 00029 #include "Pickable.h" 00030 #include "DisplayDevice.h" 00031 #include "Inform.h" 00032 #include "DrawMolecule.h" 00033 #include "CommandQueue.h" 00034 #include "TextEvent.h" 00035 #include "VMDApp.h" 00036 #include "utilities.h" 00037 00038 PickModeMolLabel::PickModeMolLabel(const char *nm, int size, VMDApp *vmdapp) 00039 : needItems(size), app(vmdapp) { 00040 00041 modename = stringdup(nm); 00042 00043 needName = FALSE; 00044 00045 // save number of elements needed, and allocate storage 00046 molids = new int[size]; 00047 atmids = new int[size]; 00048 cells = new int[3L*size]; 00049 00050 // indicate we're still at the starting trying to find something 00051 haveItems = 0; 00052 } 00053 00054 PickModeMolLabel::~PickModeMolLabel(void) { 00055 00056 delete [] molids; 00057 delete [] atmids; 00058 delete [] cells; 00059 delete [] modename; 00060 } 00061 00062 00063 void PickModeMolLabel::pick_molecule_start(DrawMolecule *mol, DisplayDevice *d, 00064 int, int tag, const int *cell, int dim, const float *pos) { 00065 atom = tag; 00066 // XXX shouldn't we be saving the molid as well??? 00067 memcpy(pPos, pos, dim*sizeof(float)); 00068 memcpy(lastCell, cell, 3*sizeof(int)); 00069 needName = TRUE; 00070 00071 int shift_pressed = d->shift_state() & DisplayDevice::SHIFT; 00072 app->commandQueue->runcommand(new PickAtomEvent(mol->id(), tag, 00073 shift_pressed)); 00074 } 00075 00076 void PickModeMolLabel::pick_molecule_move(DrawMolecule *, DisplayDevice *, 00077 int, int dim, const float *pos) { 00078 00079 // just keep track to see if the pointer moves any; if so, cancel action 00080 if(needName) { 00081 float mvdist = 0.0; 00082 for(int i=0; i < dim; i++) 00083 mvdist += (float) fabs(pPos[i] - pos[i]); 00084 00085 if(mvdist > 0.01) 00086 needName = FALSE; 00087 } 00088 } 00089 00090 void PickModeMolLabel::pick_molecule_end(DrawMolecule *m, DisplayDevice *) { 00091 00092 if(needName) { 00093 // the selection was successful; first save the info for the object 00094 00095 int id = m->id(); 00096 molids[haveItems] = id; 00097 atmids[haveItems] = atom; 00098 memcpy(cells+3*haveItems, lastCell, 3*sizeof(int)); 00099 00100 // every time an atom is selected, add an Atoms label 00101 app->label_add("Atoms", 1, &id, &atom, lastCell, 0.0f, 1); 00102 00103 // indicate we have one more items in the ones we need 00104 haveItems++; 00105 00106 // now check if we have enough items for the object we're out for 00107 if(haveItems >= needItems) { 00108 00109 if(needItems > 1) { 00110 // for labels other than just atoms, add new monitor 00111 app->label_add(modename, needItems, molids, atmids, cells, 0.0f, 1); 00112 } 00113 00114 // indicate we're done with this selection 00115 haveItems = 0; 00116 } 00117 } 00118 needName = FALSE; 00119 } 00120 00121 void PickModeMolLabel::pick_graphics(int molid, int tag, int btn, DisplayDevice *d) { 00122 int shift_pressed = d->shift_state() & DisplayDevice::SHIFT; 00123 app->commandQueue->runcommand(new PickGraphicsEvent(molid, tag, btn, shift_pressed)); 00124 } 00125