00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MolBrowser.h"
00022 #include "FL/Fl_Menu_Button.H"
00023 #include "FL/Fl_Menu_Item.H"
00024 #include "FL/Fl_Multi_Browser.H"
00025 #include "FL/forms.H"
00026 #include "frame_selector.h"
00027
00028 #include "VMDApp.h"
00029 #include "Molecule.h"
00030 #include "MoleculeList.h"
00031
00032 #if FL_MAJOR_VERSION <= 1
00033 #if FL_MINOR_VERSION < 1
00034 #include "FL/fl_file_chooser.H"
00035 #endif
00036 #endif
00037
00038 static const int widths[] = { 30, 18, 18, 18, 18, 160, 80, 70, 22, 0 };
00039
00040 MolBrowser::MolBrowser(VMDApp *vmdapp, MainFltkMenu *mm,
00041 int x, int y, int xw, int yw)
00042 : Fl_Multi_Browser(x, y, xw, yw), app(vmdapp) {
00043 mainmenu = mm;
00044 dragpending = 0;
00045 align(FL_ALIGN_TOP_LEFT);
00046 column_widths(widths);
00047 color(VMDMENU_BROWSER_BG);
00048 selection_color(VMDMENU_BROWSER_SEL);
00049
00050 VMDFLTKTOOLTIP(this, "Select molecule, toggle top/active/drawn/fixed, \nload/save coordinates or trajectory frames, \ndouble-click to rename molecule")
00051
00052 new Fl_Box(x, y-20,30,20,"ID");
00053 new Fl_Box(x+32,y-20,18,20,"T");
00054 new Fl_Box(x+50,y-20,18,20,"A");
00055 new Fl_Box(x+68,y-20,18,20,"D");
00056 new Fl_Box(x+86,y-20,18,20,"F");
00057 Fl_Box *b = new Fl_Box(x+102,y-20,220,20,"Molecule");
00058 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00059 b = new Fl_Box(x+262,y-20,80,20,"Atoms");
00060 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00061 b = new Fl_Box(x+342,y-20,60,20,"Frames");
00062 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00063 b = new Fl_Box(x+412,y-20,30,20,"Vol");
00064 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00065 end();
00066 }
00067
00068 int MolBrowser::handle(int type) {
00069 #if 1
00070
00071 if (type == FL_PASTE) {
00072
00073
00074 if (dragpending) {
00075 int len = Fl::event_length();
00076
00077
00078 if (len > 0) {
00079 int numfiles, i;
00080 const char *lastc;
00081 int lasti;
00082 FileSpec spec;
00083 const char *ctext = Fl::event_text();
00084 char *filename = (char *) malloc((1 + len) * sizeof(char));
00085
00086 for (lasti=0,lastc=ctext,numfiles=0,i=0; i<len; i++) {
00087
00088 if (ctext[i] == '\n') {
00089 memcpy(filename, lastc, (i-lasti)*sizeof(char));
00090 filename[i-lasti] = '\0';
00091
00092
00093 app->molecule_load(-1, filename, NULL, &spec);
00094
00095 lasti=i+1;
00096 lastc=&ctext[lasti];
00097 numfiles++;
00098 }
00099
00100
00101 if (i == (len-1)) {
00102 memcpy(filename, lastc, (1+i-lasti)*sizeof(char));
00103 filename[1+i-lasti] = '\0';
00104
00105
00106 app->molecule_load(-1, filename, NULL, &spec);
00107 numfiles++;
00108 }
00109 }
00110
00111 free(filename);
00112 }
00113
00114 dragpending = 0;
00115 }
00116
00117 return 1;
00118 }
00119
00120
00121 if (type == FL_DND_ENTER || type == FL_DND_DRAG) {
00122 return 1;
00123 }
00124 if (type == FL_DND_RELEASE) {
00125 Fl::paste(*this);
00126 dragpending = 1;
00127 return 1;
00128 }
00129 #endif
00130
00131 if (type == FL_RELEASE) {
00132
00133 if (mainmenu) mainmenu->update_gui_state();
00134 }
00135
00136 if (type == FL_PUSH && Fl::event_button() == FL_LEFT_MOUSE
00137 && Fl::event_clicks()) {
00138
00139
00140 int molid = -1;
00141 int selmol= -1;
00142
00143 for (int i=1; i<=size(); i++) {
00144 if (selected(i)) {
00145 selmol = i-1;
00146 molid = app->molecule_id(selmol);
00147 break;
00148 }
00149 }
00150
00151 if (molid >= 0) {
00152 char need_more_clicks = FALSE;
00153
00154
00155 int mx = Fl::event_x();
00156 if (mx >= 30 && mx < 48) {
00157 if ( Fl::event_clicks() > 1){
00158 for (int j=1; j<= size(); j++) {
00159 int id = app->molecule_id(j-1);
00160 app->molecule_activate(id, molid == id);
00161 app->molecule_display(id, molid == id);
00162 app->menu_select_mol("graphics", selmol);
00163 }
00164 app->molecule_make_top(molid);
00165 app->scene_resetview();
00166 }
00167 else {
00168 app->molecule_make_top(molid);
00169 need_more_clicks = TRUE;
00170 }
00171 } else if (mx >= 48 && mx < 66) {
00172 app->molecule_activate(molid, !app->molecule_is_active(molid));
00173 } else if (mx >= 66 && mx < 84) {
00174 app->molecule_display(molid, !app->molecule_is_displayed(molid));
00175 } else if (mx >= 84 && mx < 102) {
00176 app->molecule_fix(molid, !app->molecule_is_fixed(molid));
00177 } else if (mx >= 102 && mx < 262) {
00178
00179 const char *oldname = app->molecule_name(molid);
00180 const char *newname = fl_input("Enter a new name for molecule %d:",
00181 oldname, molid);
00182 if (newname) app->molecule_rename(molid, newname);
00183 } else if (mx >= 332 && mx < 412) {
00184
00185 int numframes = app->molecule_numframes(molid);
00186 if (!numframes) {
00187 fl_alert("Molecule %d has no frames to delete!", molid);
00188 } else {
00189 const char *molname = app->molecule_name(molid);
00190 int frst=0, lst=numframes-1, stride=0;
00191 int ok = frame_delete_selector(molname, numframes-1, &frst, &lst, &stride);
00192 if (ok) app->molecule_deleteframes(molid, frst, lst, stride);
00193 }
00194 }
00195 else need_more_clicks = TRUE;
00196 if (!need_more_clicks) Fl::event_is_click(0);
00197 }
00198 }
00199
00200 if (mainmenu && type == FL_PUSH && Fl::event_button() == FL_RIGHT_MOUSE) {
00201 const Fl_Menu_Item *menuitem;
00202 menuitem=mainmenu->browserpopup_menuitems->popup(Fl::event_x(), Fl::event_y());
00203 if (menuitem && menuitem->callback())
00204 menuitem->do_callback((Fl_Widget *) mainmenu->menubar, menuitem->user_data());
00205 return 1;
00206 }
00207
00208 return Fl_Multi_Browser::handle(type);
00209 }
00210
00211 void MolBrowser::update() {
00212 MoleculeList *mlist = app->moleculeList;
00213 int nummols = mlist->num();
00214
00215 #if 1
00216
00217
00218
00219
00220
00221
00222 if (size() > nummols)
00223 clear();
00224
00225 for (int i=0; i<nummols; i++) {
00226 char buf[256] = { 0 };
00227 char molnamebuf[81] = { 0 };
00228 Molecule *mol = mlist->molecule(i);
00229
00230
00231 strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1);
00232
00233
00234 sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d",
00235 mol->id(),
00236 mlist->is_top(i) ? "T" : " ",
00237 mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE,
00238 mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED,
00239 mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED,
00240 molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data()
00241 );
00242
00243 if (i < size())
00244 text(i+1, buf);
00245 else
00246 add(buf);
00247 }
00248 #else
00249
00250
00251
00252
00253
00254 char buf[256] = { 0 };
00255 char molnamebuf[81] = { 0 };
00256 int need_full_regen = 0;
00257
00258 #if 1
00259
00260
00261
00262
00263
00264 if (size() > nummols || size() == nummols) {
00265 need_full_regen = 1;
00266 }
00267 #else
00268 need_full_regen = 1;
00269 #endif
00270
00271 if (need_full_regen) {
00272 clear();
00273
00274 for (int i=0; i<nummols; i++) {
00275 Molecule *mol = mlist->molecule(i);
00276
00277
00278 strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1);
00279
00280
00281 sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d",
00282 mol->id(),
00283 mlist->is_top(i) ? "T" : " ",
00284 mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE,
00285 mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED,
00286 mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED,
00287 molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data()
00288 );
00289
00290 if (i < size())
00291 text(i+1, buf);
00292 else
00293 add(buf);
00294 }
00295 } else {
00296
00297 int i = nummols - 1;
00298 Molecule *mol = mlist->molecule(i);
00299
00300
00301 strncpy(molnamebuf, mol->molname(), sizeof(molnamebuf)-1);
00302
00303
00304 sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-9d\t%-7d\t%-3d",
00305 mol->id(),
00306 mlist->is_top(i) ? "T" : " ",
00307 mlist->active(i) ? VMDMENU_MOL_ACTIVE : VMDMENU_MOL_INACTIVE,
00308 mlist->displayed(i) ? VMDMENU_MOL_DISPLAYED : VMDMENU_MOL_NONDISPLAYED,
00309 mlist->fixed(i) ? VMDMENU_MOL_FIXED : VMDMENU_MOL_NONFIXED,
00310 molnamebuf, mol->nAtoms, mol->numframes(), mol->num_volume_data()
00311 );
00312
00313 if (i < size())
00314 text(i+1, buf);
00315 else
00316 add(buf);
00317 }
00318 #endif
00319
00320 if (mainmenu) mainmenu->update_gui_state();
00321 }
00322