Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

MolBrowser.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2008 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: MolBrowser.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.31 $      $Date: 2008/03/27 19:36:41 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Molecule browser
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   // handle paste operations
00068   if (type == FL_PASTE) {
00069     // ignore paste operations that weren't due to drag-and-drop 
00070     // since they could be any arbitrary data/text, and not just filenames.
00071     if (dragpending) {
00072       int len = Fl::event_length();
00073 
00074       // ignore zero-length paste events (why do these occur???)
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           // parse out all but last filename, which doesn't have a CR
00085           if (ctext[i] == '\n') {
00086             memcpy(filename, lastc, (i-lasti)*sizeof(char));
00087             filename[i-lasti] = '\0';
00088 
00089             // attempt to load the file into a new molecule
00090             app->molecule_load(-1, filename, NULL, &spec);
00091 
00092             lasti=i+1;
00093             lastc=&ctext[lasti];
00094             numfiles++;
00095           }
00096 
00097           // special-case last filename, since there's no CR
00098           if (i == (len-1)) {
00099             memcpy(filename, lastc, (1+i-lasti)*sizeof(char));
00100             filename[1+i-lasti] = '\0';
00101 
00102             // attempt to load the file into a new molecule
00103             app->molecule_load(-1, filename, NULL, &spec);
00104             numfiles++;
00105           }
00106         }
00107 
00108         free(filename);
00109       }
00110 
00111       dragpending = 0; // no longer waiting for drag-and-drop paste
00112     }
00113 
00114     return 1; // indicate that we handled the paste operation
00115   }
00116 
00117   // handle drag-and-drop operations
00118   if (type == FL_DND_ENTER || type == FL_DND_DRAG) {
00119     return 1; // indicate that we want the drag-and-drop operation
00120   }
00121   if (type == FL_DND_RELEASE) {
00122     Fl::paste(*this);
00123     dragpending = 1; // flag to expect incoming paste due to DND operation
00124     return 1;
00125   }
00126 #endif
00127 
00128   if (type == FL_RELEASE) {
00129     // update the MainMenu gui in case the molecule selections have changed
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     // figure out which line is selected; since it's a double click there
00136     // can be only one.
00137     int molid = -1; //unique ID of selected mol
00138     int selmol= -1; //GUI index of the selected mol
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       // figure out where on the line the double click occurred. 
00152       int mx = Fl::event_x();
00153       if (mx >= 30 && mx < 48) {
00154         if ( Fl::event_clicks() > 1){ // triple click: single A/T/D molecule
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) { //rename
00175         // this code snippet is an exact copy of code in MainFltkMenu.C:
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) { //delete frames
00181         // this code snippet is an exact copy of code in MainFltkMenu.C:
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; // do not allow parent to process event
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   

Generated on Sun Sep 7 01:26:00 2008 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002