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

Generated on Sat May 26 01:48:01 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002