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

GraphicsFltkMenu.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: GraphicsFltkMenu.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.111 $       $Date: 2008/08/13 21:11:22 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  generated by Fast Light User Interface Designer (fluid) version 1.0011
00019  ***************************************************************************/
00020 
00021 #include <assert.h>
00022 #include "GraphicsFltkMenu.h"
00023 #include "GraphicsFltkReps.h"
00024 #include "Command.h"
00025 #include "MoleculeList.h"
00026 #include "Molecule.h"
00027 #include "VMDApp.h"
00028 #include "AtomRep.h"
00029 #include "AtomColor.h"
00030 #include "MaterialList.h"
00031 #include "FL/forms.H"
00032 #include "FL/Fl_Tabs.H"
00033 #include "FL/Fl_Box.H"
00034 #include "FL/Fl_Float_Input.H"
00035 #include "SelectionBuilder.h"
00036 #include "CmdMol.h"
00037 #include "CommandQueue.h"
00038 #include "VMDDisplayList.h" // for PBC #defines
00039 #include "VolumetricData.h" 
00040 #include "Scene.h"
00041 
00042 // XXX enable new color tab, or not
00043 // #define REPCOLORTAB 1
00044 
00045 static const int widths[] = { 100, 100, 200, 0 };
00046 
00048 class isosurface_cbdata {
00049 public:
00050   GraphicsFltkMenu *self;
00051   GraphicsFltkRepIsosurface *isorep;
00052 };
00053 
00054 
00055 static void add_rep_to_browser(DrawMolItem *d, Fl_Browser *browser, int replace) {
00056   char repbuf[20];
00057   const char *sel_str;
00058   strncpy(repbuf, d->atomRep->cmdStr, 20);
00059   repbuf[19] = '\0';
00060   char *firstspace = strchr(repbuf, ' ');
00061   if (firstspace) {
00062     *firstspace = '\0';
00063   } 
00064   
00065   if (!d->atomRep->is_volumetric()) 
00066     sel_str = d->atomSel->cmdStr;
00067   else 
00068     sel_str = "<volume>";
00069   
00070   char *buf = (char *)malloc(strlen(repbuf) + strlen(d->atomColor->cmdStr)
00071     + strlen(sel_str) + 20);
00072   const char *color = d->displayed() ? "" : "@C203";
00073   sprintf(buf,"%s%s\t%s%s\t%s%s", color, repbuf, color, d->atomColor->cmdStr, 
00074                                   color, sel_str);
00075   if (replace > 0)
00076     browser->text(replace, buf);
00077   else
00078     browser->add(buf);
00079   free(buf);
00080 }
00081 
00082 
00083 //
00084 // Find the array index of a string that matches the name of the given menu
00085 // item.  XXX Only checks leaf node menu names, not full pathnames currently
00086 //
00087 static int find_name_string_from_menuname(const char *mn, const char **names, int num) {
00088   // FLTK 1.1.4
00089   int i, strindex;
00090   for (strindex=-1, i=0; i < num; i++) {
00091     // find leaf menu name from full menu path
00092     const char *colstr;
00093     if ((colstr = strrchr(AtomColorMenuName[i], '/')) == NULL)
00094       colstr = AtomColorMenuName[i];
00095     else 
00096       colstr++;
00097 
00098     // compare leaf submenu item name against left color mode name
00099     if (!strcmp(colstr, mn)) {
00100       strindex=i;
00101       break;
00102     }
00103   }
00104 
00105   return strindex;
00106 }
00107 
00108 
00109 //
00110 // Find the menu index with a name that matches the string.
00111 // XXX Only checks leaf node menu names, not full pathnames currently
00112 //
00113 static int find_menu_from_string(const char *namestr, const Fl_Menu *m) {
00114   // FLTK 1.1.7 XXX should do the same use the built-in 
00115   // find_item() or item_pathname() routines to do the same work we do below
00116 
00117   // FLTK 1.1.4 -- only checks leaf node menu names, ignores full pathname
00118   // find leaf menu name from full menu path
00119   const char *nstr;
00120   if ((nstr = strrchr(namestr, '/')) == NULL)
00121     nstr = namestr;
00122   else 
00123     nstr++;
00124 
00125   int i, val;
00126   for (val=-1, i=0; i<m->size()-1; i++) {
00127     const char *mstr = m[i].text;
00128     // compare leaf submenu item name against left color mode name
00129     if ((mstr != NULL) && (!strcmp(nstr, mstr))) {
00130       val=i;
00131       break;
00132     }
00133   }
00134 
00135   return val;
00136 }
00137 
00138 
00139 //
00140 // Set the chooser to the menu name matching the given string.
00141 // XXX Only checks the leaf node menu names, not full pathnames currently
00142 //
00143 static void set_chooser_from_string(const char *namestr,
00144                                     class Fl_Choice *chooser) { 
00145   int m = find_menu_from_string(namestr, chooser->menu());
00146 
00147   // don't set the menu if we can't find the string
00148   if (m >= 0)
00149     chooser->value(m);
00150 }
00151 
00152 
00155 class myBrowser : public Fl_Hold_Browser {
00156 public:
00157   myBrowser(VMDApp *anApp, GraphicsFltkMenu *aMenu, 
00158       int ix, int iy, int iw, int ih) 
00159   : Fl_Hold_Browser(ix, iy, iw, ih), app(anApp), menu(aMenu) {}
00160   int handle(int type) {
00161     // toggle the highlighted rep on/off when double clicked...
00162     if (type == FL_PUSH && Fl::event_button() == FL_LEFT_MOUSE && 
00163         Fl::event_clicks()) {
00164       // ...but ignore double clicks on the scrollbar.  We distinguish these
00165       // events by checking that x value is inside the text bounding box.
00166       int bx, by, bw, bh;
00167       bbox(bx, by, bw, bh);
00168       if (Fl::event_x() < bx+bw) {
00169         Fl::event_is_click(0);
00170         int molid = app->molecule_id(menu->molindex);
00171         int rep = value()-1;
00172         app->molrep_show(molid, rep, !app->molrep_is_shown(molid, rep));
00173       }
00174       return 0;
00175     }
00176     return Fl_Hold_Browser::handle(type);
00177   }
00178 private:
00179   VMDApp *app;
00180   GraphicsFltkMenu *menu;
00181 };
00182 
00185 class PBCControls : public Fl_Group {
00186   Fl_Check_Button *plusx, *plusy, *plusz, *minusx, *minusy, *minusz, *self;
00187   Fl_Counter *ncounter;
00188 public:
00189   PBCControls(int ix, int iy, int iw, int ih, const char *myname)
00190   : Fl_Group(ix, iy, iw, ih, myname) {
00191     Fl_Box *b = new Fl_Box(ix+30, iy+20, 190, 25, "Select periodic images to draw:");
00192     b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00193     plusx = new Fl_Check_Button(ix+50, iy+50, 70, 25, "+X");
00194     plusx->callback(cb, this);
00195     plusy = new Fl_Check_Button(ix+50, iy+80, 70, 25, "+Y");
00196     plusy->callback(cb, this);
00197     plusz = new Fl_Check_Button(ix+50, iy+110, 70, 25, "+Z");
00198     plusz->callback(cb, this);
00199     minusx = new Fl_Check_Button(ix+140, iy+50, 70, 25, "-X");
00200     minusx->callback(cb, this);
00201     minusy = new Fl_Check_Button(ix+140, iy+80, 70, 25, "-Y");
00202     minusy->callback(cb, this);
00203     minusz = new Fl_Check_Button(ix+140, iy+110, 70, 25, "-Z");
00204     minusz->callback(cb, this);
00205     self = new Fl_Check_Button(ix+50, iy+140, 70, 25, "Self");
00206     self->callback(cb, this);
00207     ncounter = new Fl_Counter(ix+50, iy+190, CTRWIDTH, CTRHEIGHT, 
00208         "Number of images");
00209     ncounter->precision(0);
00210     ncounter->minimum(1);
00211     ncounter->step(1);
00212     ncounter->lstep(5);
00213     ncounter->align(FL_ALIGN_TOP);
00214     ncounter->when(FL_WHEN_RELEASE);
00215     ncounter->callback(cb, this);
00216     end();
00217     update(0, 1);
00218   }
00219   static void cb(Fl_Widget *, void *v) { ((PBCControls *)v)->do_callback(); }
00220 
00221   // update checkboxes to reflect given pbc state
00222   void update(int pbc, int n) {
00223     plusx->value(pbc & PBC_X);
00224     plusy->value(pbc & PBC_Y);
00225     plusz->value(pbc & PBC_Z);
00226     minusx->value(pbc & PBC_OPX);
00227     minusy->value(pbc & PBC_OPY);
00228     minusz->value(pbc & PBC_OPZ);
00229     self->value(! (pbc & PBC_NOSELF));
00230     ncounter->value((double)n);
00231   }
00232   
00233   // Return current pbc state
00234   int state() const {
00235     int pbc = PBC_NONE;
00236     if (plusx->value()) pbc |= PBC_X;
00237     if (plusy->value()) pbc |= PBC_Y;
00238     if (plusz->value()) pbc |= PBC_Z;
00239     if (minusx->value()) pbc |= PBC_OPX;
00240     if (minusy->value()) pbc |= PBC_OPY;
00241     if (minusz->value()) pbc |= PBC_OPZ;
00242     if (!self->value()) pbc |= PBC_NOSELF;
00243     return pbc;
00244   }
00245 
00246   // Return number of periodic images
00247   int num_images() const { return (int)ncounter->value(); }
00248 };
00249 
00250 void GraphicsFltkMenu::pbc_cb(Fl_Widget *w, void *v) {
00251   GraphicsFltkMenu *self = (GraphicsFltkMenu *)v;
00252   PBCControls *control = (PBCControls *)w;
00253   self->set_pbc(control->state(), control->num_images());
00254 }
00255 
00256 void GraphicsFltkMenu::multiframeinput_cb(Fl_Widget *, void *v) {
00257   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00258   if (!menu->auto_update()) return;
00259   if (menu->molindex < 0 || menu->repindex < 0) return;
00260   int molid = menu->app->molecule_id(menu->molindex);
00261 
00262   if (!menu->app->molrep_set_drawframes(molid, menu->repindex, menu->create_multiframecmd()))
00263     fl_alert("The frame selection you typed could not be understood.");
00264 }
00265 
00266 static void autoupdate_cb(Fl_Widget *w, void *v) {
00267   Fl_Button *b = (Fl_Button *)w;
00268   ((GraphicsFltkMenu *)v)->set_autoupdate(b->value());
00269 }
00270 static void colorupdate_cb(Fl_Widget *w, void *v) {
00271   Fl_Button *b = (Fl_Button *)w;
00272   ((GraphicsFltkMenu *)v)->set_colorupdate(b->value());
00273 }
00274 
00275 static void colorscale_minmax_cb(Fl_Widget *, void *v) {
00276   GraphicsFltkMenu *self = (GraphicsFltkMenu *)v;
00277   self->use_colorscale_minmax();
00278 }
00279 static void colorscale_auto_cb(Fl_Widget *, void *v) {
00280   GraphicsFltkMenu *self = (GraphicsFltkMenu *)v;
00281   self->use_colorscale_auto();
00282 }
00283 
00284 GraphicsFltkMenu::GraphicsFltkMenu(VMDApp *vmdapp)
00285 : VMDFltkMenu("graphics", "Graphical Representations", vmdapp) {
00286   app = vmdapp;
00287   molindex = -1;
00288   lastmolindex = -1;
00289   repindex = -1;
00290 
00291 #if defined(REPCOLORTAB)
00292   int grwwidth = 365;
00293 #else
00294   int grwwidth = 315;
00295 #endif
00296 
00297   size(grwwidth - 2, 650);
00298   size_range(grwwidth, 650);
00299   { //Fl_Window* o = new Fl_Window(grwwidth, 541);
00300     //w = o;
00301     //o->user_data((void*)(this));
00302     { Fl_Box* o = repframe = new Fl_Box(5, 55, grwwidth - 10, 170);
00303       o->box(FL_ENGRAVED_FRAME);
00304     }
00305     Fl_Group *q = new Fl_Group(3, 5, grwwidth - 5, 45);
00306     q->resizable(NULL);
00307     { Fl_Choice* o = molchooser = new Fl_Choice(5, 25, grwwidth - 10, 25, "Selected Molecule");
00308       o->color(FL_PALEGREEN);
00309       o->selection_color(FL_BLACK);
00310       o->box(FL_THIN_UP_BOX);
00311       o->align(FL_ALIGN_TOP);
00312       o->callback(molchooser_cb, this);
00313     }
00314     q->end();
00315     Fl_Group *p = new Fl_Group(5, 60, grwwidth - 15, 50);
00316     p->resizable(NULL);
00317     createnewbutton = new Fl_Button(10, 65, 100, 25, "Create Rep");
00318     createnewbutton->callback(createnew_cb, this);
00319     { Fl_Button* o = deleterepbutton = new Fl_Button(grwwidth - 110, 65, 100, 25, "Delete Rep");
00320       o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
00321       o->callback(deleterep_cb, this);
00322     }
00323     new Fl_Box(13,95,100,20, "Style");
00324     new Fl_Box(113,95,100,20, "Color");
00325     new Fl_Box(213,95,100,20, "Selection");
00326     p->end();
00327 
00328     { Fl_Browser* o = repbrowser = new myBrowser(app, this, 10, 115, grwwidth - 20, 100);
00329       o->color(FL_DARKCYAN);
00330       o->selection_color(FL_YELLOW);
00331       o->labeltype(FL_NO_LABEL);
00332       o->column_widths(widths);
00333       o->callback(repbrowser_cb, this);
00334       Fl_Group::current()->resizable(o);
00335       //o->resizable(o);
00336     }
00337     { Fl_Input* o = selectioninput = new Fl_Input(10, 245, grwwidth - 20, 30, "Selected Atoms");
00338       o->align(FL_ALIGN_TOP);
00339       o->when(FL_WHEN_ENTER_KEY);
00340       o->color(FL_WHITE);
00341       o->selection_color(FL_YELLOW);
00342       o->callback(selectioninput_cb, this);
00343     }
00344 
00345     Fl_Tabs *tabs = new Fl_Tabs(0, 280, grwwidth, 370);
00346     tabs->resizable(NULL);
00347 
00348     Fl_Group *stylegroup = new Fl_Group(0, 300, grwwidth, 350, "Draw style");
00349 
00350     { Fl_Choice* o = colorchooser = new Fl_Choice(10, 320, 120, 25, "Coloring Method");
00351       o->color(FL_PALEGREEN);
00352       o->selection_color(FL_BLACK);
00353       o->box(FL_THIN_UP_BOX);
00354       o->align(FL_ALIGN_TOP);
00355       o->callback(colorchooser_cb, this);
00356     }
00357     { Fl_Choice* o = materialchooser = new Fl_Choice(180, 320, 120, 25, "Material");
00358       VMDFLTKTOOLTIP(o, "Select a material for shading geometry")
00359       o->color(FL_PALEGREEN);
00360       o->selection_color(FL_BLACK);
00361       o->box(FL_THIN_UP_BOX);
00362       o->align(FL_ALIGN_TOP);
00363       o->callback(materialchooser_cb, this);
00364     }
00365     { Fl_Choice* o = stylechooser = new Fl_Choice(10, 375, 120, 25, "Drawing Method");
00366       VMDFLTKTOOLTIP(o, "Select a molecular representation drawing method")
00367       o->color(FL_PALEGREEN);
00368       o->selection_color(FL_BLACK);
00369       o->box(FL_THIN_UP_BOX);
00370       o->callback(repcontrol_cb, this);
00371       o->align(FL_ALIGN_TOP);
00372     }
00373     { Fl_Button* o = defaultbutton = new Fl_Button(180, 375, CTRWIDTH,CTRHEIGHT, "Default");
00374       VMDFLTKTOOLTIP(o, "Reset controls to defaults for this drawing method")
00375       o->callback(default_cb, this);
00376     }
00377 
00378     // color index chooser, hide initially only shown for ColorID method
00379     { Fl_Choice* o = colindexchooser = new Fl_Choice(130, 320, 50, 25);
00380       o->color(FL_PALEGREEN, FL_BLACK);
00381       for (int c=0; c<REGCLRS; c++) {
00382         char buf[128];
00383         sprintf(buf, "%d     %s", c, app->scene->color_name(c));
00384         o->add(buf);
00385       }
00386       o->value(0);
00387       o->callback(colorchooser_cb, this);
00388       o->hide();
00389       o->deactivate();
00390     }
00391 
00392     // volume index chooser, hide initially only shown for Volume method
00393     { Fl_Choice* o = volindexchooser = new Fl_Choice(130, 320, 50, 25);
00394       o->color(FL_PALEGREEN, FL_BLACK);
00395       o->value(0);
00396       o->callback(colorchooser_cb, this);
00397       o->hide();
00398       o->deactivate();
00399     }
00400 
00401     { Fl_Check_Button* o = applyautobutton = new Fl_Check_Button(35, 620, 240, 25, "Apply Changes Automatically");
00402       o->down_box(FL_DIAMOND_DOWN_BOX);
00403       o->align(132|FL_ALIGN_INSIDE);
00404       o->value(1);
00405     }
00406     applybutton = new Fl_Button(255, 620, 45, 25, "Apply");
00407     applybutton->callback(apply_cb, this);
00408 
00409     repcontrols.add_name("Lines",new GraphicsFltkRepLines(repcontrol_cb, this));
00410     repcontrols.add_name("Bonds",new GraphicsFltkRepBonds(repcontrol_cb, this));
00411     repcontrols.add_name("DynamicBonds",new GraphicsFltkRepDynamicBonds(repcontrol_cb, this));
00412     repcontrols.add_name("HBonds",new GraphicsFltkRepHBonds(repcontrol_cb, this));
00413 
00414     repcontrols.add_name("Points",new GraphicsFltkRepPoints(repcontrol_cb, this));
00415     repcontrols.add_name("VDW",new GraphicsFltkRepVDW(repcontrol_cb, this));
00416     repcontrols.add_name("CPK",new GraphicsFltkRepCPK(repcontrol_cb, this));
00417     repcontrols.add_name("Licorice",new GraphicsFltkRepLicorice(repcontrol_cb, this));
00418     repcontrols.add_name("Trace",new GraphicsFltkRepTrace(repcontrol_cb, this));
00419     repcontrols.add_name("Tube",new GraphicsFltkRepTube(repcontrol_cb, this));
00420     repcontrols.add_name("Ribbons",new GraphicsFltkRepRibbons(repcontrol_cb, this));
00421     repcontrols.add_name("NewRibbons",new GraphicsFltkRepNewRibbons(repcontrol_cb, this));
00422     repcontrols.add_name("Cartoon",new GraphicsFltkRepCartoon(repcontrol_cb, this));
00423     repcontrols.add_name("NewCartoon",new GraphicsFltkRepNewCartoon(repcontrol_cb, this));
00424 
00425 #ifdef VMDWITHCARBS
00426     repcontrols.add_name("PaperChain",new GraphicsFltkRepPaperChain(repcontrol_cb, this));
00427     repcontrols.add_name("Twister",new GraphicsFltkRepTwister(repcontrol_cb, this));
00428 #endif
00429 #ifdef VMDPOLYHEDRA
00430     repcontrols.add_name("Polyhedra",new GraphicsFltkRepPolyhedra(repcontrol_cb, this));
00431 #endif
00432     repcontrols.add_name("MSMS",new GraphicsFltkRepMSMS(repcontrol_cb, this));
00433     repcontrols.add_name("Surf",new GraphicsFltkRepSurf(repcontrol_cb, this));
00434     repcontrols.add_name("VolumeSlice",new GraphicsFltkRepVolumeSlice(repcontrol_cb, this));
00435    
00436     // special callback data structure to pass multiple pointers 
00437     cbdata = new isosurface_cbdata;
00438     cbdata->self = this;
00439     cbdata->isorep = new GraphicsFltkRepIsosurface(isosurfacerepcontrol_cb, cbdata);
00440     repcontrols.add_name("Isosurface", cbdata->isorep);
00441 #ifdef VMDFIELDLINES
00442     repcontrols.add_name("FieldLines", new GraphicsFltkRepFieldLines(repcontrol_cb, this));
00443 #endif
00444 
00445     repcontrols.add_name("Beads",new GraphicsFltkRepBeads(repcontrol_cb, this));
00446     repcontrols.add_name("Dotted",new GraphicsFltkRepDotted(repcontrol_cb, this));
00447     repcontrols.add_name("Solvent",new GraphicsFltkRepSolvent(repcontrol_cb, this));
00448     stylegroup->end();
00449     selbuilder = new SelectionBuilder(0, 300, this, selectioninput, app->atomSelParser);
00450     selbuilder->end();
00451 
00452 #if defined(REPCOLORTAB)
00460     Fl_Group *colorgroup = new Fl_Group(0, 300, grwwidth, 295, "Color");
00461 
00462     Fl_Box *b2 = new Fl_Box(20, 380, 200, 25, "Color Scale Data Range:");
00463     VMDFLTKTOOLTIP(b2, "Customize mapping of data to color scale by entering min and max values")
00464     b2->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00465     colorscale_min = new Fl_Float_Input(20, 405, 70, 20);
00466     colorscale_min->color(FL_WHITE, FL_YELLOW);
00467     colorscale_min->when(FL_WHEN_ENTER_KEY);
00468     colorscale_min->callback(colorscale_minmax_cb, this);
00469     colorscale_max = new Fl_Float_Input(95, 405, 70, 20);
00470     colorscale_max->color(FL_WHITE, FL_YELLOW);
00471     colorscale_max->when(FL_WHEN_ENTER_KEY);
00472     colorscale_max->callback(colorscale_minmax_cb, this);
00473     Fl_Button *b3 = new Fl_Button(170, 405, 50, 20, "Set");
00474     b3->callback(colorscale_minmax_cb, this);
00475     Fl_Button *b4 = new Fl_Button(225, 405, 80, 20, "Autoscale");
00476     b4->callback(colorscale_auto_cb, this);
00477 
00478     colorgroup->end();
00479 #endif
00480 
00481     Fl_Group *animationgroup = new Fl_Group(0, 300, grwwidth, 295, "Trajectory");
00482     autoupdatebutton = new Fl_Check_Button(20, 320, 230, 25, "Update Selection Every Frame");
00483     autoupdatebutton->callback(autoupdate_cb, this);
00484     autoupdatebutton->down_box(FL_DIAMOND_DOWN_BOX);
00485     autoupdatebutton->align(132 | FL_ALIGN_INSIDE);
00486     autoupdatebutton->value(0);
00487 
00488     colorupdatebutton = new Fl_Check_Button(20, 350, 230, 25, "Update Color Every Frame");
00489     colorupdatebutton->callback(colorupdate_cb, this);
00490     colorupdatebutton->down_box(FL_DIAMOND_DOWN_BOX);
00491     colorupdatebutton->align(132 | FL_ALIGN_INSIDE);
00492     colorupdatebutton->value(0);
00493 
00494 #if !defined(REPCOLORTAB)
00495     Fl_Box *b2 = new Fl_Box(20, 380, 200, 25, "Color Scale Data Range:");
00496     VMDFLTKTOOLTIP(b2, "Customize mapping of data to color scale by entering min and max values")
00497     b2->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00498     colorscale_min = new Fl_Float_Input(20, 405, 70, 20);
00499     colorscale_min->color(FL_WHITE, FL_YELLOW);
00500     colorscale_min->when(FL_WHEN_ENTER_KEY);
00501     colorscale_min->callback(colorscale_minmax_cb, this);
00502     colorscale_max = new Fl_Float_Input(95, 405, 70, 20);
00503     colorscale_max->color(FL_WHITE, FL_YELLOW);
00504     colorscale_max->when(FL_WHEN_ENTER_KEY);
00505     colorscale_max->callback(colorscale_minmax_cb, this);
00506     Fl_Button *b3 = new Fl_Button(170, 405, 50, 20, "Set");
00507     b3->callback(colorscale_minmax_cb, this);
00508     Fl_Button *b4 = new Fl_Button(225, 405, 80, 20, "Autoscale");
00509     b4->callback(colorscale_auto_cb, this);
00510 #endif
00511 
00512     new Fl_Box(10, 440, 250, 25, "Draw Multiple Frames: (now, b:e, b:s:e)");
00513     multiframeinput = new Fl_Input(20, 465, 250, 20);
00514     multiframeinput->align(FL_ALIGN_TOP);
00515     multiframeinput->when(FL_WHEN_ENTER_KEY);
00516     multiframeinput->color(FL_WHITE);
00517     multiframeinput->selection_color(FL_YELLOW);
00518     multiframeinput->callback(multiframeinput_cb, this);
00519     multiframeinput->value("now");
00520     VMDFLTKTOOLTIP(multiframeinput, "Select the frames to be drawn simultaneously")
00521 
00522     Fl_Box *b1 = new Fl_Box(30, 490, 300, 25, 
00523         "Trajectory Smoothing Window Size:");
00524     b1->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00525     smoothcounter = new ResolutionCounter(70, 515, NULL);
00526     smoothcounter->size(smoothcounter->w(), 20);
00527     smoothcounter->minimum(0);
00528     smoothcounter->callback(smooth_cb, this);
00529 
00530     animationgroup->end();
00531 
00532     pbcControls = new PBCControls(0, 300, grwwidth, 295, "Periodic");
00533     pbcControls->callback(pbc_cb, this);
00534 
00535     tabs->end();
00536     Fl_Window::end();
00537 
00538     for (int j=0; j<repcontrols.num(); j++) {
00539       repcontrols.data(j)->reset();
00540       repcontrols.data(j)->hide();
00541     }
00542   }
00543 
00544   command_wanted(Command::MOL_NEW);
00545   command_wanted(Command::MOL_DEL);
00546   command_wanted(Command::MOL_ON);
00547   command_wanted(Command::MOL_RENAME);
00548   command_wanted(Command::MOL_VOLUME);
00549   command_wanted(Command::MOL_ADDREP);
00550   command_wanted(Command::MOL_DELREP);
00551   command_wanted(Command::MOL_MODREP);
00552   command_wanted(Command::MOL_MODREPITEM);
00553   command_wanted(Command::MOL_SHOWPERIODIC);
00554   command_wanted(Command::MOL_NUMPERIODIC);
00555   command_wanted(Command::MOL_DRAWFRAMES);
00556   command_wanted(Command::MOL_SCALEMINMAX);
00557   command_wanted(Command::MOL_SMOOTHREP);
00558   command_wanted(Command::MOL_SHOWREP);
00559   command_wanted(Command::MATERIAL_RENAME);
00560   command_wanted(Command::MATERIAL_ADD);
00561   command_wanted(Command::MATERIAL_DELETE);
00562   command_wanted(Command::MOL_REPSELUPDATE);
00563   command_wanted(Command::MOL_REPCOLORUPDATE);
00564   command_wanted(Command::ATOMSEL_ADDMACRO);
00565   command_wanted(Command::ATOMSEL_DELMACRO);
00566 
00567   init_colorchooser();
00568   init_materialchooser();
00569   init_stylechooser();
00570 
00571   selbuilder->update_macrobrowser();
00572 }
00573 
00574 GraphicsFltkMenu::~GraphicsFltkMenu() {
00575   delete cbdata;
00576 }
00577 
00578 int GraphicsFltkMenu::auto_update() const {
00579   return applyautobutton->value();
00580 }
00581 
00582 void GraphicsFltkMenu::init_colorchooser() {
00583   colorchooser->clear();
00584 
00585   // Add "pretty" menu names for use in the GUI, which also allows us
00586   // to add submenus and other organizational structure to the menu.
00587   // The cost of this is that we cannot compare indices between menus and
00588   // coloring modes, we have to match strings instead. 
00589   for (int j=0; j<AtomColor::TOTAL; j++) 
00590     colorchooser->add(AtomColorMenuName[j]); 
00591 
00592   colorchooser->value(0); // force init to first menu item
00593 
00594   // set to "Name" coloring method by default
00595   set_chooser_from_string(AtomColorMenuName[AtomColor::NAME], colorchooser);
00596 }
00597 
00598 void GraphicsFltkMenu::init_materialchooser() {
00599   materialchooser->clear();
00600   for (int j=0; j<app->materialList->num(); j++) 
00601     materialchooser->add(app->materialList->material_name(j)); 
00602   materialchooser->value(0);
00603 }
00604 
00605 void GraphicsFltkMenu::init_stylechooser() {
00606   stylechooser->clear();
00607   for (int j=0; j<AtomRep::TOTAL; j++) 
00608     stylechooser->add(AtomRepInfo[j].name); 
00609   stylechooser->value(0);
00610   show_repcontrols();
00611 }
00612 
00613 void GraphicsFltkMenu::isosurfacerepcontrol_cb(Fl_Widget *w, void *v) {
00614   isosurface_cbdata *cbdata = (isosurface_cbdata *) v;
00615   GraphicsFltkMenu *menu = cbdata->self;
00616   GraphicsFltkRepIsosurface *iso = cbdata->isorep; 
00617 
00618   if (!strcmp(w->label(), "Drawing Method")) 
00619     menu->show_repcontrols();
00620   if (!menu->auto_update()) return;
00621   if (menu->molindex < 0 || menu->repindex < 0) return;
00622   int molid = menu->app->molecule_id(menu->molindex);
00623 
00624   if (Fl::event_state(FL_BUTTON1 | FL_BUTTON2 | FL_BUTTON3)) {
00625     if (Fl::event_state(FL_SHIFT | FL_CTRL | FL_ALT | FL_META | FL_BUTTON2 | FL_BUTTON3)) { 
00626       // drag callback, with a modifier key pressed
00627       // this allows the user to retain full resolution if they really want
00628       iso->set_grid_stepsize(1);
00629     } else {
00630       // drag callback, use a larger step size while dragging so that the
00631       // isosurface computes more quickly
00632       iso->set_grid_stepsize(2);
00633     }
00634   } else {
00635     // release callback
00636     iso->set_grid_stepsize(1);
00637   }
00638   menu->app->molrep_set_style(molid, menu->repindex, menu->create_repcmd());
00639 }
00640 
00641 void GraphicsFltkMenu::molchooser_cb(Fl_Widget *w, void *v) {
00642   Fl_Choice *choice = (Fl_Choice *)w;
00643   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00644   menu->molindex = choice->value();
00645   menu->update_molchooser();
00646 }
00647 
00648 void GraphicsFltkMenu::repbrowser_cb(Fl_Widget *w, void *v) {
00649   Fl_Hold_Browser *b = (Fl_Hold_Browser *)w;
00650   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00651   menu->repindex = b->value()-1;
00652   menu->update_rep();
00653 }
00654  
00655 void GraphicsFltkMenu::repcontrol_cb(Fl_Widget *w, void *v) {
00656   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00657   if (!strcmp(w->label(), "Drawing Method")) 
00658     menu->show_repcontrols();
00659   if (!menu->auto_update()) return;
00660   if (menu->molindex < 0 || menu->repindex < 0) return;
00661   int molid = menu->app->molecule_id(menu->molindex);
00662   menu->app->molrep_set_style(molid, menu->repindex, menu->create_repcmd());
00663 }
00664 
00665 void GraphicsFltkMenu::colorchooser_cb(Fl_Widget *w, void *v) {
00666   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00667   menu->colindex_visible();
00668   menu->volindex_visible();
00669   if (!menu->auto_update()) return;
00670   if (menu->molindex < 0 || menu->repindex < 0) return;
00671   int molid = menu->app->molecule_id(menu->molindex);
00672   menu->app->molrep_set_color(molid, menu->repindex, menu->create_colorcmd());
00673 }
00674   
00675 void GraphicsFltkMenu::selectioninput_cb(Fl_Widget *, void *v) {
00676   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00677   if (!menu->auto_update()) return;
00678   if (menu->molindex < 0 || menu->repindex < 0) return;
00679   int molid = menu->app->molecule_id(menu->molindex);
00680   if (!menu->app->molrep_set_selection(molid, menu->repindex, menu->create_selcmd())) 
00681     fl_alert("The atom selection you typed could not be understood.");
00682 }
00683 
00684 void GraphicsFltkMenu::materialchooser_cb(Fl_Widget *, void *v) {
00685   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00686   if (!menu->auto_update()) return;
00687   if (menu->molindex < 0 || menu->repindex < 0) return;
00688   int molid = menu->app->molecule_id(menu->molindex);
00689   menu->app->molrep_set_material(molid, menu->repindex, menu->create_matcmd());
00690 }
00691     
00692 void GraphicsFltkMenu::createnew_cb(Fl_Widget *w, void *v) {
00693   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00694   
00695   menu->app->molecule_set_color(menu->create_colorcmd());
00696   menu->app->molecule_set_style(menu->create_repcmd());
00697   menu->app->molecule_set_selection(menu->create_selcmd());
00698   menu->app->molecule_set_material(menu->create_matcmd());
00699   int molid = menu->app->molecule_id(menu->molindex);
00700   menu->app->molecule_addrep(molid);
00701 }
00702   
00703 void GraphicsFltkMenu::deleterep_cb(Fl_Widget *w, void *v) {
00704   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00705   int molid = menu->app->molecule_id(menu->molindex);
00706   menu->app->molrep_delete(molid, menu->repindex); 
00707 }
00708 
00709 void GraphicsFltkMenu::apply_cb(Fl_Widget *w, void *v) {
00710   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00711   if (menu->molindex < 0 || menu->repindex < 0) return;
00712 
00713   int molid = menu->app->molecule_id(menu->molindex);
00714   menu->app->molecule_set_color(menu->create_colorcmd());
00715   menu->app->molecule_set_style(menu->create_repcmd());
00716   menu->app->molecule_set_selection(menu->create_selcmd());
00717   menu->app->molecule_set_material(menu->create_matcmd());
00718   menu->app->molecule_modrep(molid, menu->repindex);
00719 }
00720 
00721 void GraphicsFltkMenu::default_cb(Fl_Widget *, void *v) {
00722   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00723   menu->reset_rep();
00724   GraphicsFltkMenu::apply_cb(0, menu);
00725 }
00726 
00727 void GraphicsFltkMenu::smooth_cb(Fl_Widget *, void *v) {
00728   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00729   int molid = menu->app->molecule_id(menu->molindex);
00730   menu->app->molrep_set_smoothing(molid, menu->repindex, 
00731       (int)menu->smoothcounter->value());
00732 }
00733 
00734 void GraphicsFltkMenu::use_colorscale_minmax() {
00735   if (molindex >= 0 && repindex >= 0) {
00736     int molid = app->molecule_id(molindex);
00737     float min = (float) atof(colorscale_min->value());
00738     float max = (float) atof(colorscale_max->value());
00739     if (!app->molrep_set_scaleminmax(molid, repindex, min, max)) {
00740       fl_alert("Could not set color scale data range with values %s-%s",
00741           colorscale_min->value(), colorscale_max->value());
00742     }
00743   }
00744 }
00745 
00746 void GraphicsFltkMenu::use_colorscale_auto() {
00747   if (molindex >= 0 && repindex >= 0) {
00748     int molid = app->molecule_id(molindex);
00749     if (!app->molrep_reset_scaleminmax(molid, repindex)) {
00750       fl_alert("Could not autoscale color scale data range.");
00751     } else { // update Min/Max text fields
00752       float min=0, max=0;
00753       char buf[128]; // must hold potentially huge FP numbers
00754       app->molrep_get_scaleminmax(molid, repindex, &min, &max);
00755       sprintf(buf, "%3.2f", min);
00756       colorscale_min->value(buf);
00757       sprintf(buf, "%3.2f", max);
00758       colorscale_max->value(buf);
00759     }
00760   }
00761 }
00762 
00763 void GraphicsFltkMenu::update_selection(const char *s) {
00764   if (s) {
00765     selectioninput->value(s);
00766     selectioninput->do_callback();
00767   } else {
00768     int id = app->molecule_id(molindex);
00769     const char *txt = app->molrep_get_selection(id, repindex);
00770     if (txt) {
00771       selectioninput->value(s);
00772 // XXX this causes the user to see an error box for no good reason
00773 //      selectioninput->do_callback();
00774     }
00775   }
00776 }
00777  
00778 const char *GraphicsFltkMenu::selectiontext() const {
00779   return selectioninput->value();
00780 }
00781 
00782 void GraphicsFltkMenu::reset_rep() {
00783   int typecode = repcontrols.typecode(stylechooser->text());
00784   assert(typecode >= 0);
00785   repcontrols.data(typecode)->reset();
00786 }
00787  
00788 void GraphicsFltkMenu::update_molchooser() {
00789   molchooser->clear();
00790   fill_fltk_molchooser(molchooser, app);
00791   volindex_update();
00792 
00793   if (molindex >= 0) {
00794     molchooser->value(molindex);
00795     for (int k=0; k<repcontrols.num(); k++) {
00796       if (!repcontrols.data(k)->is_volumetric()) 
00797         continue; 
00798 
00799       GraphicsFltkRepVolumetric *rep = 
00800         (GraphicsFltkRepVolumetric *)repcontrols.data(k);
00801       Molecule *m = app->moleculeList->molecule(molindex);
00802       rep->dataset_clear();
00803       for (int j=0; j<m->num_volume_data(); j++) {
00804         const VolumetricData *data = m->get_volume_data(j);
00805         rep->dataset_append(data->name, data->datamin, data->datamax);
00806       }
00807     }
00808   } else {
00809     molchooser->redraw();
00810   }
00811   selbuilder->use_molecule(app->moleculeList->molecule(molindex));
00812   app->highlighted_molid = app->molecule_id(molindex);
00813   update_repindex();
00814   update_repbrowser();
00815 }
00816 
00817 void GraphicsFltkMenu::update_repbrowser(bool remember_position) {
00818   int vposition =  repbrowser->position();
00819   repbrowser->clear();
00820   Molecule *mol = app->moleculeList->molecule(molindex);
00821   if (!mol) return;
00822 
00823   for (int j=0; j<mol->components(); j++) {
00824     DrawMolItem *d = mol->component(j);
00825     add_rep_to_browser(d, repbrowser, 0);
00826   }
00827   assert(repindex < repbrowser->size());
00828   if (repindex >= 0) {
00829     repbrowser->select(repindex+1);
00830     if (remember_position) 
00831       repbrowser->position(vposition);
00832   }
00833   update_rep();
00834 }
00835  
00836 void GraphicsFltkMenu::update_rep() {
00837   if (molindex >= 0 && repindex >= 0) {
00838     Molecule *m = app->moleculeList->molecule(molindex);
00839     assert(m != NULL);
00840     DrawMolItem *d = m->component(repindex);
00841     assert(d != NULL);
00842 
00843     // colors
00844     AtomColor *ac = d->atomColor;
00845     assert(ac != NULL);
00846 
00847     // find the named menu item, set it active if a match is found
00848     set_chooser_from_string(AtomColorMenuName[ac->method()], colorchooser);
00849 
00850     // volume texturing
00851     volindex_visible(); 
00852     if (ac->method() == AtomColor::VOLUME){
00853       volindexchooser->value(ac->volume_index());
00854     } 
00855 
00856     // coloring method
00857     colindex_visible(); 
00858     if (ac->method() == AtomColor::COLORID){
00859       colindexchooser->value(ac->color_index());
00860     }
00861 
00862     colorupdatebutton->value(ac->do_update);
00863     float min=0, max=0;
00864     char buf[128]; // must hold potentially huge FP numbers
00865     ac->get_colorscale_minmax(&min, &max);
00866     sprintf(buf, "%3.2f", min);
00867     colorscale_min->value(buf);
00868     sprintf(buf, "%3.2f", max);
00869     colorscale_max->value(buf);
00870 
00871     materialchooser->value(d->curr_material());
00872     AtomRep *ar = d->atomRep;
00873     assert(ar != NULL);
00874     if (stylechooser->value() != ar->method()) {
00875       stylechooser->value(ar->method());
00876       show_repcontrols();
00877     }
00878     repcontrols.data(stylechooser->text())->set_values(ar);
00879     AtomSel *as = d->atomSel;
00880     assert(as != NULL);
00881     selectioninput->value(as->cmdStr);
00882     if (ar->is_volumetric()) selectioninput->deactivate();
00883     else selectioninput->activate();
00884     selbuilder->set_selection(as->cmdStr);
00885     autoupdatebutton->value(as->do_update);
00886     smoothcounter->value((double)d->get_smoothing());
00887     multiframeinput->value(d->get_drawframes());
00888     update_pbc();
00889   }
00890   app->highlighted_rep = repindex;
00891 }
00892    
00893 // update the pbc controls for the current rep
00894 void GraphicsFltkMenu::update_pbc() {
00895   if (molindex >= 0 && repindex >= 0) {
00896     Molecule *m = app->moleculeList->molecule(molindex);
00897     const DrawMolItem *d = m->component(repindex);
00898     int pbc = d->get_pbc();
00899     int n = d->get_pbc_images();
00900     pbcControls->update(pbc, n);
00901   }
00902 }
00903 
00904 // set pbc values for the current rep, if any
00905 void GraphicsFltkMenu::set_pbc(int pbc, int n) {
00906   if (molindex >= 0 && repindex >= 0) {
00907     Molecule *m = app->moleculeList->molecule(molindex);
00908     int id = m->id();
00909     app->molrep_set_pbc(id, repindex, pbc);
00910     app->molrep_set_pbc_images(id, repindex, n);
00911   }
00912 }
00913 
00914 void GraphicsFltkMenu::set_autoupdate(int on) {
00915   if (molindex >= 0 && repindex >= 0) {
00916     int id = app->molecule_id(molindex);
00917     app->molrep_set_selupdate(id, repindex, on);
00918   }
00919 }
00920 
00921 void GraphicsFltkMenu::set_colorupdate(int on) {
00922   if (molindex >= 0 && repindex >= 0) {
00923     int id = app->molecule_id(molindex);
00924     app->molrep_set_colorupdate(id, repindex, on);
00925   }
00926 }
00927 
00928 void GraphicsFltkMenu::update_repindex() {
00929   // auto-grow the rep index array as needed, initializing reps to -1
00930   while (molactiverep.num() <= lastmolindex) {
00931     molactiverep.append(-1);
00932   }
00933 
00934   // save active repindex for last molecule accessed before we update
00935   Molecule *oldmol = app->moleculeList->molecule(lastmolindex);
00936   if (oldmol) {
00937     molactiverep[lastmolindex] = repindex;
00938   } 
00939 
00940   // see if new molecule exists
00941   Molecule *mol = app->moleculeList->molecule(molindex);
00942   if (!mol) {
00943     repindex = -1;
00944     return;
00945   }
00946  
00947   // auto-grow the rep index array as needed, initializing reps to -1
00948   while (molactiverep.num() <= molindex) {
00949     molactiverep.append(-1);
00950   }
00951 
00952   // retrieve previous rep index for this molecule
00953   repindex = molactiverep[molindex];
00954   lastmolindex = molindex;
00955 
00956   // bounds check the repindex before returning
00957   int n = mol->components();
00958   if (n > 0 && repindex == -1) {
00959     repindex = 0;
00960     return;
00961   }
00962   if (repindex >= n) {
00963     repindex = n-1;
00964   }
00965 }
00966     
00967 void GraphicsFltkMenu::show_repcontrols() {
00968   for (int j=0; j<repcontrols.num(); j++) 
00969     repcontrols.data(j)->hide();
00970 
00971   int typecode = repcontrols.typecode(stylechooser->text());
00972   assert(typecode >= 0);
00973   repcontrols.data(typecode)->show();
00974   redraw();
00975 }
00976 
00977 char *GraphicsFltkMenu::create_repcmd() {
00978   int typecode = repcontrols.typecode(stylechooser->text());
00979   assert(typecode >= 0);
00980   return (char *)repcontrols.data(typecode)->repcmd();
00981 }
00982 
00983 char *GraphicsFltkMenu::create_colorcmd() {
00984   // find the coloring method mode that matches the currently selected
00985   // colorchooser item name
00986   int colorval = find_name_string_from_menuname(colorchooser->text(), AtomColorMenuName, AtomColor::TOTAL);
00987 
00988   // if we got a valid color name index, set the color command text
00989   if (colorval >= 0) {
00990     if (colorval == AtomColor::COLORID) {
00991       sprintf(colorcmdbuf, "%s %d", AtomColorName[colorval],
00992               colindexchooser->value());
00993     } else if (colorval == AtomColor::VOLUME) {
00994       sprintf(colorcmdbuf, "%s %d", AtomColorName[colorval],
00995               volindexchooser->value());
00996     } else {
00997       strcpy(colorcmdbuf, AtomColorName[colorval]);
00998     }
00999   } else {
01000     colorcmdbuf[0] = '\0';
01001   }
01002 
01003   return colorcmdbuf;
01004 }
01005         
01006 char *GraphicsFltkMenu::create_selcmd() {
01007   return (char *)(selectioninput->value()); 
01008 }
01009 
01010 char *GraphicsFltkMenu::create_matcmd() {
01011   return (char *)(materialchooser->text());
01012 }
01013 
01014 char *GraphicsFltkMenu::create_multiframecmd() {
01015   return (char *)(multiframeinput->value()); 
01016 }
01017 
01018 void GraphicsFltkMenu::colindex_visible() {
01019   // compare menu names to check for a match, since indices aren't correlated
01020   if (!strcmp(AtomColorMenuName[AtomColor::COLORID], colorchooser->text())) {
01021     colindexchooser->show();
01022     colindexchooser->activate();
01023   } else {
01024     colindexchooser->hide();
01025     colindexchooser->deactivate();
01026   }
01027 }
01028 
01029 void GraphicsFltkMenu::volindex_visible() {
01030   // compare menu names to check for a match, since indices aren't correlated
01031   if (!strcmp(AtomColorMenuName[AtomColor::VOLUME], colorchooser->text())) {
01032     volindexchooser->show();
01033     volindexchooser->activate();
01034   } else {
01035     volindexchooser->hide();
01036     volindexchooser->deactivate();
01037   }
01038 }
01039 
01040 void GraphicsFltkMenu::volindex_update() {
01041   int newvolid = volindexchooser->value();
01042   volindexchooser->clear();
01043 
01044   // XXX This code makes the short-term assumption that volume ID's are
01045   // sequentially numbered with no gaps, presently true but ultimately
01046   // this will break once volumes can be deleted.  Needs to use an extra
01047   // GUI index to volume index mapping array to be correct long-term, much
01048   // like we do with molecules.
01049   if (molindex >= 0) {
01050     Molecule *m = app->moleculeList->molecule(molindex);
01051     for (int j=0; j<m->num_volume_data(); j++) {
01052       char volnamebuf[80];
01053       const VolumetricData *data = m->get_volume_data(j);
01054 
01055       memset(volnamebuf, 0, sizeof(volnamebuf));
01056       sprintf(volnamebuf, "%d: ", j);
01057       strncpy(volnamebuf+strlen(volnamebuf), data->name, (sizeof(volnamebuf) - strlen(volnamebuf) - 2));
01058 
01059       // Fltk doesn't allow adding a menu item with the same name as
01060       // an existing item, so we use replace, which also avoids 
01061       // problems with the escape characters interpreted by add()
01062       int ind = volindexchooser->add("foobar");
01063       volindexchooser->replace(ind, volnamebuf);
01064     }
01065 
01066     // range-check the old volume index against what we have now
01067     // if the old index is now out of range, set it to zero.
01068     if ((newvolid < 0) || (newvolid >= m->num_volume_data()))
01069       newvolid = 0;
01070     volindexchooser->value(newvolid);
01071   }
01072 }
01073 
01074 int GraphicsFltkMenu::act_on_command(int type, Command *cmd) {
01075   if (type == Command::MOL_NEW || type == Command::MOL_DEL ||
01076       type == Command::MOL_VOLUME || type == Command::MOL_RENAME) {
01077     Molecule *mol = app->moleculeList->top();
01078     if (mol)
01079       molindex = app->moleculeList->mol_index_from_id(mol->id());
01080     else
01081       molindex = -1;
01082     update_repindex();
01083     update_molchooser();
01084   } else if (type == Command::MOL_ON) {
01085     update_molchooser();
01086 
01087   } else if (type == Command::MOL_ADDREP || type == Command::MOL_DELREP ||
01088              type == Command::MOL_MODREP || type == Command::MOL_MODREPITEM ||
01089              type == Command::MOL_DRAWFRAMES ||
01090              type == Command::MOL_SCALEMINMAX ||
01091              type == Command::MOL_SHOWREP ||
01092              type == Command::MOL_SMOOTHREP) {
01093     if (type == Command::MOL_DELREP) {
01094       int delrep = ((CmdMolDeleteRep *)cmd)->repn;
01095       if (delrep < repindex) --repindex;
01096     } else if (type == Command::MOL_ADDREP) {
01097       // make update_repindex highlight the last rep
01098       repindex = 99999; 
01099     }
01100 
01101     // Keep the browser line at the same position unless we're adding
01102     // or deleting representations.
01103     bool remember_position = true;
01104     if (type == Command::MOL_ADDREP || type == Command::MOL_DELREP) 
01105       remember_position = false;
01106     update_repindex();
01107     update_repbrowser(remember_position);
01108   } else if (type == Command::MATERIAL_RENAME
01109           || type == Command::MATERIAL_ADD
01110           || type == Command::MATERIAL_DELETE) {
01111     int cur = materialchooser->value();
01112     MaterialList *mlist = app->materialList;
01113     materialchooser->clear();
01114     for (int m=0; m<mlist->num(); m++) {
01115       materialchooser->add(mlist->material_name(m));
01116     }
01117     if (type != Command::MATERIAL_DELETE) {
01118       materialchooser->value(cur);
01119     } else {
01120       if (molindex >= 0 && repindex >= 0) {
01121         Molecule *mol = app->moleculeList->molecule(molindex);
01122         assert(mol != NULL);
01123         DrawMolItem *d = mol->component(repindex);
01124         assert(d != NULL);
01125         materialchooser->value(d->curr_material());
01126       } else {
01127         materialchooser->value(0);
01128       }
01129     }
01130   } else if (type == Command::MOL_REPSELUPDATE ||
01131              type == Command::MOL_REPCOLORUPDATE) {
01132     update_rep();
01133   } else if (type == Command::ATOMSEL_ADDMACRO || 
01134            type == Command::ATOMSEL_DELMACRO) {
01135     selbuilder->update_macrobrowser();
01136 
01137   } else if (type == Command::MOL_SHOWPERIODIC ||
01138              type == Command::MOL_NUMPERIODIC) {
01139     update_pbc();
01140   } else {
01141     return FALSE;
01142   }
01143   return TRUE;
01144 }
01145 
01146 
01147 int GraphicsFltkMenu::selectmol(int selmol) {
01148   if (selmol >= 0 && selmol < molchooser->size()-1) 
01149     molindex = selmol;
01150   update_molchooser();
01151   return TRUE;
01152 }
01153 

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