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, 70, 70, 22, 0 };
00039
00040 MolBrowser::MolBrowser(VMDApp *vmdapp, MainFltkMenu *mm, int x, int y)
00041 : Fl_Multi_Browser(x, y, 450, 90), app(vmdapp) {
00042 mainmenu = mm;
00043 dragpending = 0;
00044 align(FL_ALIGN_TOP_LEFT);
00045 column_widths(widths);
00046 color(FL_DARKCYAN);
00047 selection_color(FL_YELLOW);
00048
00049 new Fl_Box(x, y-20,30,20,"ID");
00050 new Fl_Box(x+32,y-20,18,20,"T");
00051 new Fl_Box(x+50,y-20,18,20,"A");
00052 new Fl_Box(x+68,y-20,18,20,"D");
00053 new Fl_Box(x+86,y-20,18,20,"F");
00054 Fl_Box *b = new Fl_Box(x+102,y-20,220,20,"Molecule");
00055 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00056 b = new Fl_Box(x+262,y-20,70,20,"Atoms");
00057 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00058 b = new Fl_Box(x+332,y-20,60,20,"Frames");
00059 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00060 b = new Fl_Box(x+402,y-20,30,20,"Vol");
00061 b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00062 end();
00063 }
00064
00065 int MolBrowser::handle(int type) {
00066 #if 1
00067
00068 if (type == FL_PASTE) {
00069
00070
00071 if (dragpending) {
00072 int len = Fl::event_length();
00073
00074
00075 if (len > 0) {
00076 int numfiles, i;
00077 const char *lastc;
00078 int lasti;
00079 FileSpec spec;
00080 const char *ctext = Fl::event_text();
00081 char *filename = (char *) malloc((1 + len) * sizeof(char));
00082
00083 for (lasti=0,lastc=ctext,numfiles=0,i=0; i<len; i++) {
00084
00085 if (ctext[i] == '\n') {
00086 memcpy(filename, lastc, (i-lasti)*sizeof(char));
00087 filename[i-lasti] = '\0';
00088
00089
00090 app->molecule_load(-1, filename, NULL, &spec);
00091
00092 lasti=i+1;
00093 lastc=&ctext[lasti];
00094 numfiles++;
00095 }
00096
00097
00098 if (i == (len-1)) {
00099 memcpy(filename, lastc, (1+i-lasti)*sizeof(char));
00100 filename[1+i-lasti] = '\0';
00101
00102
00103 app->molecule_load(-1, filename, NULL, &spec);
00104 numfiles++;
00105 }
00106 }
00107
00108 free(filename);
00109 }
00110
00111 dragpending = 0;
00112 }
00113
00114 return 1;
00115 }
00116
00117
00118 if (type == FL_DND_ENTER || type == FL_DND_DRAG) {
00119 return 1;
00120 }
00121 if (type == FL_DND_RELEASE) {
00122 Fl::paste(*this);
00123 dragpending = 1;
00124 return 1;
00125 }
00126 #endif
00127
00128 if (type == FL_RELEASE) {
00129
00130 if (mainmenu) mainmenu->update_gui_state();
00131 }
00132
00133 if (type == FL_PUSH && Fl::event_button() == FL_LEFT_MOUSE
00134 && Fl::event_clicks()) {
00135
00136
00137 int molid = -1;
00138 int selmol= -1;
00139
00140 for (int i=1; i<=size(); i++) {
00141 if (selected(i)) {
00142 selmol = i-1;
00143 molid = app->molecule_id(selmol);
00144 break;
00145 }
00146 }
00147
00148 if (molid >= 0) {
00149 char need_more_clicks = FALSE;
00150
00151
00152 int mx = Fl::event_x();
00153 if (mx >= 30 && mx < 48) {
00154 if ( Fl::event_clicks() > 1){
00155 for (int j=1; j<= size(); j++) {
00156 int id = app->molecule_id(j-1);
00157 app->molecule_activate(id, molid == id);
00158 app->molecule_display(id, molid == id);
00159 app->menu_select_mol("graphics", selmol);
00160 }
00161 app->molecule_make_top(molid);
00162 app->scene_resetview();
00163 }
00164 else {
00165 app->molecule_make_top(molid);
00166 need_more_clicks = TRUE;
00167 }
00168 } else if (mx >= 48 && mx < 66) {
00169 app->molecule_activate(molid, !app->molecule_is_active(molid));
00170 } else if (mx >= 66 && mx < 84) {
00171 app->molecule_display(molid, !app->molecule_is_displayed(molid));
00172 } else if (mx >= 84 && mx < 102) {
00173 app->molecule_fix(molid, !app->molecule_is_fixed(molid));
00174 } else if (mx >= 102 && mx < 262) {
00175
00176 const char *oldname = app->molecule_name(molid);
00177 const char *newname = fl_input("Enter a new name for molecule %d:",
00178 oldname, molid);
00179 if (newname) app->molecule_rename(molid, newname);
00180 } else if (mx >= 332 && mx < 402) {
00181
00182 int numframes = app->molecule_numframes(molid);
00183 if (!numframes) {
00184 fl_alert("Molecule %d has no frames to delete!", molid);
00185 } else {
00186 const char *molname = app->molecule_name(molid);
00187 int frst=0, lst=numframes-1, stride=0;
00188 int ok = frame_delete_selector(molname, numframes-1, &frst, &lst, &stride);
00189 if (ok) app->molecule_deleteframes(molid, frst, lst, stride);
00190 }
00191 }
00192 else need_more_clicks = TRUE;
00193 if (!need_more_clicks) Fl::event_is_click(0);
00194 }
00195 }
00196
00197 if (mainmenu && type == FL_PUSH && Fl::event_button() == FL_RIGHT_MOUSE) {
00198 const Fl_Menu_Item *menuitem;
00199 menuitem=mainmenu->browserpopup_menuitems->popup(Fl::event_x(), Fl::event_y());
00200 if (menuitem && menuitem->callback())
00201 menuitem->do_callback((Fl_Widget *) mainmenu->menubar, menuitem->user_data());
00202 return 1;
00203 }
00204
00205 return Fl_Multi_Browser::handle(type);
00206 }
00207
00208 void MolBrowser::update() {
00209 MoleculeList *mlist = app->moleculeList;
00210 int nummols = mlist->num();
00211
00212 if (size() > nummols)
00213 clear();
00214
00215 for (int i=0; i<nummols; i++) {
00216 char buf[256];
00217 Molecule *mol = mlist->molecule(i);
00218
00219 sprintf(buf, "%d\t%s\t%s\t%s\t%s\t%-13s\t%-7d\t%-7d\t%-3d",
00220 mol->id(),
00221 mlist->is_top(i) ? "T" : " ",
00222 mlist->active(i) ? "A" : "@C203A",
00223 mlist->displayed(i) ? "D" : "@C203D",
00224 mlist->fixed(i) ? "F" : "@C203F",
00225 mol->molname(), mol->nAtoms, mol->numframes(), mol->num_volume_data()
00226 );
00227
00228 if (i < size())
00229 text(i+1, buf);
00230 else
00231 add(buf);
00232 }
00233
00234 if (mainmenu) mainmenu->update_gui_state();
00235 }
00236