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

GraphicsFltkMenu.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2019 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.164 $       $Date: 2020/07/08 04:21:12 $
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] = { 0 };
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 #ifdef VMDNANOSHAPER
00417     repcontrols.add_name("NanoShaper",new GraphicsFltkRepNanoShaper(repcontrol_cb, this));
00418 #endif
00419     repcontrols.add_name("Surf",new GraphicsFltkRepSurf(repcontrol_cb, this));
00420     repcontrols.add_name("VolumeSlice",new GraphicsFltkRepVolumeSlice(repcontrol_cb, this));
00421    
00422     // special callback data structure to pass multiple pointers 
00423     isosurfcbdata = new isosurface_cbdata;
00424     isosurfcbdata->self = this;
00425     isosurfcbdata->isorep = new GraphicsFltkRepIsosurface(isosurfacerepcontrol_cb, isosurfcbdata);
00426     repcontrols.add_name("Isosurface", isosurfcbdata->isorep);
00427     repcontrols.add_name("FieldLines", new GraphicsFltkRepFieldLines(repcontrol_cb, this));
00428 
00429     // special callback data structure to pass multiple pointers 
00430     orbcbdata = new orbital_cbdata;
00431     orbcbdata->self = this;
00432     orbcbdata->orbrep = new GraphicsFltkRepOrbital(orbitalrepcontrol_cb, orbcbdata);
00433     repcontrols.add_name("Orbital", orbcbdata->orbrep);
00434 
00435     repcontrols.add_name("Beads",new GraphicsFltkRepBeads(repcontrol_cb, this));
00436     repcontrols.add_name("Dotted",new GraphicsFltkRepDotted(repcontrol_cb, this));
00437     repcontrols.add_name("Solvent",new GraphicsFltkRepSolvent(repcontrol_cb, this));
00438 #ifdef VMDLATTICECUBES
00439     repcontrols.add_name("LatticeCubes",new GraphicsFltkRepLatticeCubes(repcontrol_cb, this));
00440 #endif
00441 
00442     stylegroup->end();
00443     selbuilder = new SelectionBuilder(0, 300, this, selectioninput, app->atomSelParser);
00444 #if defined(VMDMENU_WINDOW)
00445     selbuilder->color(VMDMENU_WINDOW, FL_GRAY);
00446     selbuilder->selection_color(VMDMENU_WINDOW);
00447 #endif
00448     selbuilder->end();
00449 
00450 #if defined(REPCOLORTAB)
00458     Fl_Group *colorgroup = new Fl_Group(0, 300, grwwidth, 295, "Color");
00459 
00460     Fl_Box *b2 = new Fl_Box(20, 380, 200, 25, "Color Scale Data Range:");
00461     VMDFLTKTOOLTIP(b2, "Customize mapping of data to color scale by entering min and max values")
00462     b2->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00463     colorscale_min = new Fl_Float_Input(20, 405, 70, 20);
00464     colorscale_min->color(VMDMENU_VALUE_BG, VMDMENU_VALUE_SEL);
00465     colorscale_min->when(FL_WHEN_ENTER_KEY);
00466     colorscale_min->callback(colorscale_minmax_cb, this);
00467 
00468     colorscale_max = new Fl_Float_Input(95, 405, 70, 20);
00469     colorscale_max->color(VMDMENU_VALUE_BG, VMDMENU_VALUE_SEL);
00470     colorscale_max->when(FL_WHEN_ENTER_KEY);
00471     colorscale_max->callback(colorscale_minmax_cb, this);
00472 
00473     Fl_Button *b3 = new Fl_Button(170, 405, 50, 20, "Set");
00474 #if defined(VMDMENU_WINDOW)
00475     b3->color(VMDMENU_WINDOW, FL_GRAY);
00476 #endif
00477     b3->callback(colorscale_minmax_cb, this);
00478 
00479     Fl_Button *b4 = new Fl_Button(225, 405, 80, 20, "Autoscale");
00480 #if defined(VMDMENU_WINDOW)
00481     b4->color(VMDMENU_WINDOW, FL_GRAY);
00482 #endif
00483     b4->callback(colorscale_auto_cb, this);
00484 
00485     colorgroup->end();
00486 #endif /* REPCOLORTAB */
00487 
00488     Fl_Group *animationgroup = new Fl_Group(0, 300, grwwidth, 295, "Trajectory");
00489 #if defined(VMDMENU_WINDOW)
00490     animationgroup->color(VMDMENU_WINDOW, FL_GRAY);
00491     animationgroup->selection_color(VMDMENU_WINDOW);
00492 #endif
00493 
00494     autoupdatebutton = new Fl_Check_Button(20, 320, 230, 25, "Update Selection Every Frame");
00495     autoupdatebutton->callback(autoupdate_cb, this);
00496     autoupdatebutton->down_box(FL_DIAMOND_DOWN_BOX);
00497     autoupdatebutton->align(132 | FL_ALIGN_INSIDE);
00498     autoupdatebutton->value(0);
00499 
00500     colorupdatebutton = new Fl_Check_Button(20, 350, 230, 25, "Update Color Every Frame");
00501     colorupdatebutton->callback(colorupdate_cb, this);
00502     colorupdatebutton->down_box(FL_DIAMOND_DOWN_BOX);
00503     colorupdatebutton->align(132 | FL_ALIGN_INSIDE);
00504     colorupdatebutton->value(0);
00505 
00506 #if !defined(REPCOLORTAB)
00507     Fl_Box *b2 = new Fl_Box(20, 380, 200, 25, "Color Scale Data Range:");
00508     VMDFLTKTOOLTIP(b2, "Customize mapping of data to color scale by entering min and max values")
00509     b2->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00510     colorscale_min = new Fl_Float_Input(20, 405, 70, 20);
00511     colorscale_min->color(VMDMENU_VALUE_BG, VMDMENU_VALUE_SEL);
00512     colorscale_min->when(FL_WHEN_ENTER_KEY);
00513     colorscale_min->callback(colorscale_minmax_cb, this);
00514     colorscale_max = new Fl_Float_Input(95, 405, 70, 20);
00515     colorscale_max->color(VMDMENU_VALUE_BG, VMDMENU_VALUE_SEL);
00516     colorscale_max->when(FL_WHEN_ENTER_KEY);
00517     colorscale_max->callback(colorscale_minmax_cb, this);
00518     Fl_Button *b3 = new Fl_Button(170, 405, 50, 20, "Set");
00519 #if defined(VMDMENU_WINDOW)
00520     b3->color(VMDMENU_WINDOW, FL_GRAY);
00521 #endif
00522     b3->callback(colorscale_minmax_cb, this);
00523     Fl_Button *b4 = new Fl_Button(225, 405, 80, 20, "Autoscale");
00524 #if defined(VMDMENU_WINDOW)
00525     b4->color(VMDMENU_WINDOW, FL_GRAY);
00526 #endif
00527     b4->callback(colorscale_auto_cb, this);
00528 #endif
00529 
00530     new Fl_Box(10, 440, 250, 25, "Draw Multiple Frames: (now, b:e, b:s:e)");
00531     multiframeinput = new Fl_Input(20, 465, 250, 20);
00532     multiframeinput->align(FL_ALIGN_TOP);
00533     multiframeinput->when(FL_WHEN_ENTER_KEY);
00534     multiframeinput->color(VMDMENU_VALUE_BG);
00535     multiframeinput->selection_color(VMDMENU_VALUE_SEL);
00536     multiframeinput->callback(multiframeinput_cb, this);
00537     multiframeinput->value("now");
00538     VMDFLTKTOOLTIP(multiframeinput, "Select the frames to be drawn simultaneously")
00539 
00540     Fl_Box *b1 = new Fl_Box(30, 490, 300, 25, 
00541         "Trajectory Smoothing Window Size:");
00542     b1->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00543     smoothcounter = new ResolutionCounter(70, 515, NULL);
00544     smoothcounter->size(smoothcounter->w(), 20);
00545     smoothcounter->minimum(0);
00546     smoothcounter->callback(smooth_cb, this);
00547 
00548     animationgroup->end();
00549 
00550     pbcControls = new PBCControls(0, 300, grwwidth, 295, "Periodic");
00551 #if defined(VMDMENU_WINDOW)
00552     pbcControls->color(VMDMENU_WINDOW, FL_GRAY);
00553     pbcControls->selection_color(VMDMENU_WINDOW);
00554 #endif
00555     pbcControls->callback(pbc_cb, this);
00556 
00557     tabs->end();
00558     Fl_Window::end();
00559 
00560     for (int j=0; j<repcontrols.num(); j++) {
00561       repcontrols.data(j)->reset();
00562       repcontrols.data(j)->hide();
00563     }
00564   }
00565 
00566   command_wanted(Command::MOL_NEW);
00567   command_wanted(Command::MOL_DEL);
00568   command_wanted(Command::MOL_ON);
00569   command_wanted(Command::MOL_RENAME);
00570   command_wanted(Command::MOL_VOLUME);
00571   command_wanted(Command::MOL_ADDREP);
00572   command_wanted(Command::MOL_DELREP);
00573   command_wanted(Command::MOL_MODREP);
00574   command_wanted(Command::MOL_MODREPITEM);
00575   command_wanted(Command::MOL_SHOWPERIODIC);
00576   command_wanted(Command::MOL_NUMPERIODIC);
00577   command_wanted(Command::MOL_DRAWFRAMES);
00578   command_wanted(Command::MOL_SCALEMINMAX);
00579   command_wanted(Command::MOL_SMOOTHREP);
00580   command_wanted(Command::MOL_SHOWREP);
00581   command_wanted(Command::MATERIAL_RENAME);
00582   command_wanted(Command::MATERIAL_ADD);
00583   command_wanted(Command::MATERIAL_DELETE);
00584   command_wanted(Command::MOL_REPSELUPDATE);
00585   command_wanted(Command::MOL_REPCOLORUPDATE);
00586   command_wanted(Command::ATOMSEL_ADDMACRO);
00587   command_wanted(Command::ATOMSEL_DELMACRO);
00588 
00589   init_colorchooser();
00590   init_materialchooser();
00591   init_stylechooser();
00592 
00593   selbuilder->update_macrobrowser();
00594 }
00595 
00596 GraphicsFltkMenu::~GraphicsFltkMenu() {
00597   delete isosurfcbdata;
00598   delete orbcbdata;
00599   delete qsurfcbdata;
00600 }
00601 
00602 int GraphicsFltkMenu::auto_update() const {
00603   return applyautobutton->value();
00604 }
00605 
00606 void GraphicsFltkMenu::init_colorchooser() {
00607   colorchooser->clear();
00608 
00609   // Add "pretty" menu names for use in the GUI, which also allows us
00610   // to add submenus and other organizational structure to the menu.
00611   // The cost of this is that we cannot compare indices between menus and
00612   // coloring modes, we have to match strings instead. 
00613   for (int j=0; j<AtomColor::TOTAL; j++) 
00614     colorchooser->add(AtomColorMenuName[j]); 
00615 
00616   colorchooser->value(0); // force init to first menu item
00617 
00618   // set to "Name" coloring method by default
00619   set_chooser_from_string(AtomColorMenuName[AtomColor::NAME], colorchooser);
00620 }
00621 
00622 void GraphicsFltkMenu::init_materialchooser() {
00623   materialchooser->clear();
00624   for (int j=0; j<app->materialList->num(); j++) 
00625     materialchooser->add(app->materialList->material_name(j)); 
00626   materialchooser->value(0);
00627 }
00628 
00629 void GraphicsFltkMenu::init_stylechooser() {
00630   stylechooser->clear();
00631   for (int j=0; j<AtomRep::TOTAL; j++) 
00632     stylechooser->add(AtomRepInfo[j].name); 
00633   stylechooser->value(0);
00634   show_repcontrols();
00635 }
00636 
00637 void GraphicsFltkMenu::isosurfacerepcontrol_cb(Fl_Widget *w, void *v) {
00638   isosurface_cbdata *cbdata = (isosurface_cbdata *) v;
00639   GraphicsFltkMenu *menu = cbdata->self;
00640   GraphicsFltkRepIsosurface *iso = cbdata->isorep; 
00641 
00642   if (!strcmp(w->label(), "Drawing Method")) 
00643     menu->show_repcontrols();
00644   if (!menu->auto_update()) return;
00645   if (menu->molindex < 0 || menu->repindex < 0) return;
00646   int molid = menu->app->molecule_id(menu->molindex);
00647 
00648   if (Fl::event_state(FL_BUTTON1 | FL_BUTTON2 | FL_BUTTON3)) {
00649     if (Fl::event_state(FL_SHIFT | FL_CTRL | FL_ALT | FL_META | FL_BUTTON2 | FL_BUTTON3)) { 
00650       // drag callback, with a modifier key pressed
00651       // this allows the user to retain full resolution if they really want
00652       iso->set_grid_stepsize(1);
00653     } else {
00654       // drag callback, use a larger step size while dragging so that the
00655       // isosurface computes more quickly
00656       iso->set_grid_stepsize(2);
00657     }
00658   } else {
00659     // release callback
00660     iso->set_grid_stepsize(1);
00661   }
00662   menu->app->molrep_set_style(molid, menu->repindex, menu->create_repcmd());
00663 }
00664 
00665 
00666 void GraphicsFltkMenu::orbitalrepcontrol_cb(Fl_Widget *w, void *v) {
00667   orbital_cbdata *cbdata = (orbital_cbdata *) v;
00668   GraphicsFltkMenu *menu = cbdata->self;
00669   GraphicsFltkRepOrbital *orb = cbdata->orbrep; 
00670 
00671   if (!strcmp(w->label(), "Drawing Method")) 
00672     menu->show_repcontrols();
00673 
00674   // regenerate the excitation list whenever the wavefunction type is changed
00675   if (!strcmp(w->label(), "Wavefunction Type")) {
00676     orb->regen_excitationlist();
00677   }
00678 
00679   // regenerate the orbital list whenever wavefunction type, spin, or 
00680   // excitation selections are changed.
00681   if (!strcmp(w->label(), "Wavefunction Type") ||
00682       !strcmp(w->label(), "Spin") ||
00683       !strcmp(w->label(), "Excitation")) {
00684     orb->regen_orbitallist();
00685   }    
00686 
00687   // regenerate the orbital list whenever the user selects a different
00688   // range of orbitals using the "OrbList" counter
00689   if (!strcmp(w->label(), "OrbList")) {
00690     orb->regen_orbitallist(-1);
00691   }    
00692 
00693   // if the menu isn't set to apply changes automatically, then
00694   // we do nothing further and simply return
00695   if (!menu->auto_update()) return;
00696 
00697   if (menu->molindex < 0 || menu->repindex < 0) return;
00698   int molid = menu->app->molecule_id(menu->molindex);
00699 
00700   if (Fl::event_state(FL_BUTTON1 | FL_BUTTON2 | FL_BUTTON3)) {
00701     if (Fl::event_state(FL_SHIFT | FL_CTRL | FL_ALT | FL_META | FL_BUTTON2 | FL_BUTTON3)) { 
00702       // drag callback, with a modifier key pressed
00703       // this allows the user to retain full resolution if they really want
00704       orb->set_grid_stepsize(1);
00705     } else {
00706       // drag callback, use a larger step size while dragging so that the
00707       // isosurface computes more quickly
00708       orb->set_grid_stepsize(2);
00709     }
00710   } else {
00711     // release callback
00712     orb->set_grid_stepsize(1);
00713   }
00714   menu->app->molrep_set_style(molid, menu->repindex, menu->create_repcmd());
00715 }
00716 
00717 
00718 void GraphicsFltkMenu::quicksurfrepcontrol_cb(Fl_Widget *w, void *v) {
00719   quicksurf_cbdata *cbdata = (quicksurf_cbdata *) v;
00720   GraphicsFltkMenu *menu = cbdata->self;
00721   GraphicsFltkRepQuickSurf *qsurf = cbdata->qsurfrep; 
00722 
00723   if (!strcmp(w->label(), "Drawing Method")) 
00724     menu->show_repcontrols();
00725 
00726   // if the menu isn't set to apply changes automatically, then
00727   // we do nothing further and simply return
00728   if (!menu->auto_update()) return;
00729 
00730   if (menu->molindex < 0 || menu->repindex < 0) return;
00731   int molid = menu->app->molecule_id(menu->molindex);
00732 
00733   if (Fl::event_state(FL_BUTTON1 | FL_BUTTON2 | FL_BUTTON3)) {
00734     if (Fl::event_state(FL_SHIFT | FL_CTRL | FL_ALT | FL_META | FL_BUTTON2 | FL_BUTTON3)) {
00735       // drag callback, with a modifier key pressed
00736       // this allows the user to retain full resolution if they really want
00737       qsurf->set_gridspacing_multiplier(1.0f);
00738     } else {
00739       // drag callback, use a larger grid spacing while dragging so that the
00740       // density map computes more quickly
00741       qsurf->set_gridspacing_multiplier(2.0f);
00742     }
00743   } else {
00744     // release callback
00745     qsurf->set_gridspacing_multiplier(1.0f);
00746   }
00747 
00748   // regenerate the parameters when the resolution slider is changed
00749   if (!strcmp(w->label(), "Resolution")) {
00750     qsurf->resolution_changed();
00751   }
00752 
00753   menu->app->molrep_set_style(molid, menu->repindex, menu->create_repcmd());
00754 }
00755 
00756 
00757 void GraphicsFltkMenu::molchooser_cb(Fl_Widget *w, void *v) {
00758   Fl_Choice *choice = (Fl_Choice *)w;
00759   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00760   menu->molindex = choice->value();
00761   menu->update_molchooser();
00762 }
00763 
00764 void GraphicsFltkMenu::repbrowser_cb(Fl_Widget *w, void *v) {
00765   Fl_Hold_Browser *b = (Fl_Hold_Browser *)w;
00766   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00767   menu->repindex = b->value()-1;
00768   menu->update_rep();
00769 }
00770  
00771 void GraphicsFltkMenu::repcontrol_cb(Fl_Widget *w, void *v) {
00772   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00773   if (!strcmp(w->label(), "Drawing Method")) 
00774     menu->show_repcontrols();
00775   if (!menu->auto_update()) return;
00776   if (menu->molindex < 0 || menu->repindex < 0) return;
00777   int molid = menu->app->molecule_id(menu->molindex);
00778   menu->app->molrep_set_style(molid, menu->repindex, menu->create_repcmd());
00779 }
00780 
00781 void GraphicsFltkMenu::colorchooser_cb(Fl_Widget *w, void *v) {
00782   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00783   menu->colindex_visible();
00784   menu->volindex_visible();
00785   if (!menu->auto_update()) return;
00786   if (menu->molindex < 0 || menu->repindex < 0) return;
00787   int molid = menu->app->molecule_id(menu->molindex);
00788   menu->app->molrep_set_color(molid, menu->repindex, menu->create_colorcmd());
00789 }
00790   
00791 void GraphicsFltkMenu::selectioninput_cb(Fl_Widget *, void *v) {
00792   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00793   if (!menu->auto_update()) return;
00794   if (menu->molindex < 0 || menu->repindex < 0) return;
00795   int molid = menu->app->molecule_id(menu->molindex);
00796   if (!menu->app->molrep_set_selection(molid, menu->repindex, menu->create_selcmd())) 
00797     fl_alert("The atom selection you typed could not be understood.");
00798 }
00799 
00800 void GraphicsFltkMenu::materialchooser_cb(Fl_Widget *, void *v) {
00801   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00802   if (!menu->auto_update()) return;
00803   if (menu->molindex < 0 || menu->repindex < 0) return;
00804   int molid = menu->app->molecule_id(menu->molindex);
00805   menu->app->molrep_set_material(molid, menu->repindex, menu->create_matcmd());
00806 }
00807     
00808 void GraphicsFltkMenu::createnew_cb(Fl_Widget *w, void *v) {
00809   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00810   
00811   menu->app->molecule_set_color(menu->create_colorcmd());
00812   menu->app->molecule_set_style(menu->create_repcmd());
00813   menu->app->molecule_set_selection(menu->create_selcmd());
00814   menu->app->molecule_set_material(menu->create_matcmd());
00815   int molid = menu->app->molecule_id(menu->molindex);
00816   menu->app->molecule_addrep(molid);
00817 }
00818   
00819 void GraphicsFltkMenu::deleterep_cb(Fl_Widget *w, void *v) {
00820   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00821   int molid = menu->app->molecule_id(menu->molindex);
00822   menu->app->molrep_delete(molid, menu->repindex); 
00823 }
00824 
00825 void GraphicsFltkMenu::apply_cb(Fl_Widget *w, void *v) {
00826   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00827   if (menu->molindex < 0 || menu->repindex < 0) return;
00828 
00829   int molid = menu->app->molecule_id(menu->molindex);
00830   menu->app->molecule_set_color(menu->create_colorcmd());
00831   menu->app->molecule_set_style(menu->create_repcmd());
00832   menu->app->molecule_set_selection(menu->create_selcmd());
00833   menu->app->molecule_set_material(menu->create_matcmd());
00834   menu->app->molecule_modrep(molid, menu->repindex);
00835 }
00836 
00837 void GraphicsFltkMenu::default_cb(Fl_Widget *, void *v) {
00838   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00839   menu->reset_rep();
00840   GraphicsFltkMenu::apply_cb(0, menu);
00841 }
00842 
00843 void GraphicsFltkMenu::smooth_cb(Fl_Widget *, void *v) {
00844   GraphicsFltkMenu *menu = (GraphicsFltkMenu *)v;
00845   int molid = menu->app->molecule_id(menu->molindex);
00846   menu->app->molrep_set_smoothing(molid, menu->repindex, 
00847       (int)menu->smoothcounter->value());
00848 }
00849 
00850 void GraphicsFltkMenu::use_colorscale_minmax() {
00851   if (molindex >= 0 && repindex >= 0) {
00852     int molid = app->molecule_id(molindex);
00853     float min = (float) atof(colorscale_min->value());
00854     float max = (float) atof(colorscale_max->value());
00855     if (!app->molrep_set_scaleminmax(molid, repindex, min, max)) {
00856       fl_alert("Could not set color scale data range with values %s-%s",
00857           colorscale_min->value(), colorscale_max->value());
00858     }
00859   }
00860 }
00861 
00862 void GraphicsFltkMenu::use_colorscale_auto() {
00863   if (molindex >= 0 && repindex >= 0) {
00864     int molid = app->molecule_id(molindex);
00865     if (!app->molrep_reset_scaleminmax(molid, repindex)) {
00866       fl_alert("Could not autoscale color scale data range.");
00867     } else { // update Min/Max text fields
00868       float min=0, max=0;
00869       char buf[128] = { 0 }; // must hold potentially huge FP numbers
00870       app->molrep_get_scaleminmax(molid, repindex, &min, &max);
00871       sprintf(buf, "%3.2f", min);
00872       colorscale_min->value(buf);
00873       sprintf(buf, "%3.2f", max);
00874       colorscale_max->value(buf);
00875     }
00876   }
00877 }
00878 
00879 void GraphicsFltkMenu::update_selection(const char *s) {
00880   if (s) {
00881     selectioninput->value(s);
00882     selectioninput->do_callback();
00883   } else {
00884     int id = app->molecule_id(molindex);
00885     const char *txt = app->molrep_get_selection(id, repindex);
00886     if (txt) {
00887       selectioninput->value(s);
00888 // XXX this causes the user to see an error box for no good reason
00889 //      selectioninput->do_callback();
00890     }
00891   }
00892 }
00893  
00894 const char *GraphicsFltkMenu::selectiontext() const {
00895   return selectioninput->value();
00896 }
00897 
00898 void GraphicsFltkMenu::reset_rep() {
00899   int typecode = repcontrols.typecode(stylechooser->text());
00900   // assert(typecode >= 0);
00901   repcontrols.data(typecode)->reset();
00902 }
00903  
00904 void GraphicsFltkMenu::update_molchooser() {
00905   fill_fltk_molchooser(molchooser, app, NULL);
00906   volindex_update();
00907 
00908   if (molindex >= 0) {
00909     Molecule *m = app->moleculeList->molecule(molindex);
00910 
00911 #if 0
00912     // disable volumetric coloring/reps if no volume data loaded
00913     int volmode = 0; // no flags by default, item active
00914     if (m->num_volume_data() < 1) {
00915       volmode = FL_MENU_INACTIVE;
00916     }
00917     colorchooser->mode(find_menu_from_string(AtomColorName[AtomColor::VOLUME], colorchooser->menu()), volmode);
00918     stylechooser->mode(AtomRep::VOLSLICE, volmode);
00919     stylechooser->mode(AtomRep::ISOSURFACE, volmode);
00920     stylechooser->mode(AtomRep::FIELDLINES, volmode);
00921 #endif
00922 
00923     molchooser->value(molindex);
00924     for (int k=0; k<repcontrols.num(); k++) {
00925       if (repcontrols.data(k)->is_volumetric()) { 
00926         GraphicsFltkRepVolumetric *rep = 
00927           (GraphicsFltkRepVolumetric *)repcontrols.data(k);
00928         rep->dataset_clear();
00929         for (int j=0; j<m->num_volume_data(); j++) {
00930           VolumetricData *data = m->modify_volume_data(j);
00931           float datamin, datamax;
00932           data->datarange(datamin, datamax);
00933           rep->dataset_append(data->name, datamin, datamax);
00934         }
00935       }
00936 
00937       // deal with Orbital reps
00938       if (repcontrols.data(k)->is_orbital()) { 
00939         GraphicsFltkRepOrbital *rep = 
00940           (GraphicsFltkRepOrbital *)repcontrols.data(k);
00941 
00942         // update the list of available wavefunction types
00943         rep->regen_wavefunctypes();
00944 
00945         // regenerate the orbital chooser contents based on the
00946         // currently selected wavefunction type, spin, and excitation
00947         rep->regen_orbitallist();
00948       }
00949     }
00950   } else {
00951     molchooser->redraw();
00952   }
00953   selbuilder->use_molecule(app->moleculeList->molecule(molindex));
00954   app->highlighted_molid = app->molecule_id(molindex);
00955   update_repindex();
00956   update_repbrowser();
00957 }
00958 
00959 void GraphicsFltkMenu::update_repbrowser(bool remember_position) {
00960   int vposition =  repbrowser->position();
00961   repbrowser->clear();
00962   Molecule *mol = app->moleculeList->molecule(molindex);
00963   if (!mol) return;
00964 
00965   for (int j=0; j<mol->components(); j++) {
00966     DrawMolItem *d = mol->component(j);
00967     add_rep_to_browser(d, repbrowser, 0);
00968   }
00969   // assert(repindex < repbrowser->size());
00970   if (repindex >= 0) {
00971     repbrowser->select(repindex+1);
00972     if (remember_position) 
00973       repbrowser->position(vposition);
00974   }
00975   update_rep();
00976 }
00977  
00978 void GraphicsFltkMenu::update_rep() {
00979   if (molindex >= 0 && repindex >= 0) {
00980     Molecule *m = app->moleculeList->molecule(molindex);
00981     DrawMolItem *d = m->component(repindex);
00982 
00983     // colors
00984     AtomColor *ac = d->atomColor;
00985 
00986     // find the named menu item, set it active if a match is found
00987     set_chooser_from_string(AtomColorMenuName[ac->method()], colorchooser);
00988 
00989     // volume texturing
00990     volindex_visible(); 
00991     if (ac->method() == AtomColor::VOLUME){
00992       volindexchooser->value(ac->volume_index());
00993     } 
00994 
00995     // coloring method
00996     colindex_visible(); 
00997     if (ac->method() == AtomColor::COLORID){
00998       colindexchooser->value(ac->color_index());
00999     }
01000 
01001     colorupdatebutton->value(ac->do_update);
01002     float min=0, max=0;
01003     char buf[128] = { 0 }; // must hold potentially huge FP numbers
01004     ac->get_colorscale_minmax(&min, &max);
01005     sprintf(buf, "%3.2f", min);
01006     colorscale_min->value(buf);
01007     sprintf(buf, "%3.2f", max);
01008     colorscale_max->value(buf);
01009 
01010     materialchooser->value(d->curr_material());
01011     AtomRep *ar = d->atomRep;
01012     if (stylechooser->value() != ar->method()) {
01013       stylechooser->value(ar->method());
01014       show_repcontrols();
01015     }
01016     repcontrols.data(stylechooser->text())->set_values(ar);
01017     AtomSel *as = d->atomSel;
01018     selectioninput->value(as->cmdStr);
01019     if (ar->is_volumetric()) selectioninput->deactivate();
01020     else selectioninput->activate();
01021     selbuilder->set_selection(as->cmdStr);
01022     autoupdatebutton->value(as->do_update);
01023     smoothcounter->value((double)d->get_smoothing());
01024     multiframeinput->value(d->get_drawframes());
01025     update_pbc();
01026   }
01027   app->highlighted_rep = repindex;
01028 }
01029    
01030 // update the pbc controls for the current rep
01031 void GraphicsFltkMenu::update_pbc() {
01032   if (molindex >= 0 && repindex >= 0) {
01033     Molecule *m = app->moleculeList->molecule(molindex);
01034     const DrawMolItem *d = m->component(repindex);
01035     int pbc = d->get_pbc();
01036     int n = d->get_pbc_images();
01037     pbcControls->update(pbc, n);
01038   }
01039 }
01040 
01041 // set pbc values for the current rep, if any
01042 void GraphicsFltkMenu::set_pbc(int pbc, int n) {
01043   if (molindex >= 0 && repindex >= 0) {
01044     Molecule *m = app->moleculeList->molecule(molindex);
01045     int id = m->id();
01046     app->molrep_set_pbc(id, repindex, pbc);
01047     app->molrep_set_pbc_images(id, repindex, n);
01048   }
01049 }
01050 
01051 void GraphicsFltkMenu::set_autoupdate(int on) {
01052   if (molindex >= 0 && repindex >= 0) {
01053     int id = app->molecule_id(molindex);
01054     app->molrep_set_selupdate(id, repindex, on);
01055   }
01056 }
01057 
01058 void GraphicsFltkMenu::set_colorupdate(int on) {
01059   if (molindex >= 0 && repindex >= 0) {
01060     int id = app->molecule_id(molindex);
01061     app->molrep_set_colorupdate(id, repindex, on);
01062   }
01063 }
01064 
01065 void GraphicsFltkMenu::update_repindex() {
01066   // auto-grow the rep index array as needed, initializing reps to -1
01067   while (molactiverep.num() <= lastmolindex) {
01068     molactiverep.append(-1);
01069   }
01070 
01071   // save active repindex for last molecule accessed before we update
01072   Molecule *oldmol = app->moleculeList->molecule(lastmolindex);
01073   if (oldmol) {
01074     molactiverep[lastmolindex] = repindex;
01075   } 
01076 
01077   // see if new molecule exists
01078   Molecule *mol = app->moleculeList->molecule(molindex);
01079   if (!mol) {
01080     repindex = -1;
01081     return;
01082   }
01083  
01084   // auto-grow the rep index array as needed, initializing reps to -1
01085   while (molactiverep.num() <= molindex) {
01086     molactiverep.append(-1);
01087   }
01088 
01089   // retrieve previous rep index for this molecule
01090   repindex = molactiverep[molindex];
01091   lastmolindex = molindex;
01092 
01093   // bounds check the repindex before returning
01094   int n = mol->components();
01095   if (n > 0 && repindex == -1) {
01096     repindex = 0;
01097     return;
01098   }
01099   if (repindex >= n) {
01100     repindex = n-1;
01101   }
01102 }
01103     
01104 void GraphicsFltkMenu::show_repcontrols() {
01105   for (int j=0; j<repcontrols.num(); j++) 
01106     repcontrols.data(j)->hide();
01107 
01108   int typecode = repcontrols.typecode(stylechooser->text());
01109   // assert(typecode >= 0);
01110   repcontrols.data(typecode)->show();
01111   redraw();
01112 }
01113 
01114 char *GraphicsFltkMenu::create_repcmd() {
01115   int typecode = repcontrols.typecode(stylechooser->text());
01116   // assert(typecode >= 0);
01117   return (char *)repcontrols.data(typecode)->repcmd();
01118 }
01119 
01120 char *GraphicsFltkMenu::create_colorcmd() {
01121   // find the coloring method mode that matches the currently selected
01122   // colorchooser item name
01123   int colorval = find_name_string_from_menuname(colorchooser->text(), AtomColorMenuName, AtomColor::TOTAL);
01124 
01125   // if we got a valid color name index, set the color command text
01126   if (colorval >= 0) {
01127     if (colorval == AtomColor::COLORID) {
01128       sprintf(colorcmdbuf, "%s %d", AtomColorName[colorval],
01129               colindexchooser->value());
01130     } else if (colorval == AtomColor::VOLUME) {
01131       sprintf(colorcmdbuf, "%s %d", AtomColorName[colorval],
01132               volindexchooser->value());
01133     } else {
01134       strcpy(colorcmdbuf, AtomColorName[colorval]);
01135     }
01136   } else {
01137     colorcmdbuf[0] = '\0';
01138   }
01139 
01140   return colorcmdbuf;
01141 }
01142         
01143 char *GraphicsFltkMenu::create_selcmd() {
01144   return (char *)(selectioninput->value()); 
01145 }
01146 
01147 char *GraphicsFltkMenu::create_matcmd() {
01148   return (char *)(materialchooser->text());
01149 }
01150 
01151 char *GraphicsFltkMenu::create_multiframecmd() {
01152   return (char *)(multiframeinput->value()); 
01153 }
01154 
01155 void GraphicsFltkMenu::colindex_visible() {
01156   // compare menu names to check for a match, since indices aren't correlated
01157   if (!strcmp(AtomColorMenuName[AtomColor::COLORID], colorchooser->text())) {
01158     colindexchooser->show();
01159     colindexchooser->activate();
01160   } else {
01161     colindexchooser->hide();
01162     colindexchooser->deactivate();
01163   }
01164 }
01165 
01166 void GraphicsFltkMenu::volindex_visible() {
01167   // compare menu names to check for a match, since indices aren't correlated
01168   if (!strcmp(AtomColorMenuName[AtomColor::VOLUME], colorchooser->text())) {
01169     volindexchooser->show();
01170     volindexchooser->activate();
01171   } else {
01172     volindexchooser->hide();
01173     volindexchooser->deactivate();
01174   }
01175 }
01176 
01177 void GraphicsFltkMenu::volindex_update() {
01178   int newvolid = volindexchooser->value();
01179   volindexchooser->clear();
01180 
01181   // XXX This code makes the short-term assumption that volume ID's are
01182   // sequentially numbered with no gaps, presently true but ultimately
01183   // this will break once volumes can be deleted.  Needs to use an extra
01184   // GUI index to volume index mapping array to be correct long-term, much
01185   // like we do with molecules.
01186   if (molindex >= 0) {
01187     Molecule *m = app->moleculeList->molecule(molindex);
01188     for (int j=0; j<m->num_volume_data(); j++) {
01189       char volnamebuf[80];
01190       const VolumetricData *data = m->get_volume_data(j);
01191 
01192       memset(volnamebuf, 0, sizeof(volnamebuf));
01193       sprintf(volnamebuf, "%d: ", j);
01194       strncpy(volnamebuf+strlen(volnamebuf), data->name, (sizeof(volnamebuf) - strlen(volnamebuf) - 2));
01195 
01196       // Fltk doesn't allow adding a menu item with the same name as
01197       // an existing item, so we use replace, which also avoids 
01198       // problems with the escape characters interpreted by add()
01199       int ind = volindexchooser->add("foobar");
01200       volindexchooser->replace(ind, volnamebuf);
01201     }
01202 
01203     // range-check the old volume index against what we have now
01204     // if the old index is now out of range, set it to zero.
01205     if ((newvolid < 0) || (newvolid >= m->num_volume_data()))
01206       newvolid = 0;
01207     volindexchooser->value(newvolid);
01208   }
01209 }
01210 
01211 int GraphicsFltkMenu::act_on_command(int type, Command *cmd) {
01212   if (type == Command::MOL_NEW || type == Command::MOL_DEL ||
01213       type == Command::MOL_VOLUME || type == Command::MOL_RENAME) {
01214     Molecule *mol = app->moleculeList->top();
01215     if (mol)
01216       molindex = app->moleculeList->mol_index_from_id(mol->id());
01217     else
01218       molindex = -1;
01219     update_repindex();
01220     update_molchooser();
01221   } else if (type == Command::MOL_ON) {
01222     update_molchooser();
01223 
01224   } else if (type == Command::MOL_ADDREP || type == Command::MOL_DELREP ||
01225              type == Command::MOL_MODREP || type == Command::MOL_MODREPITEM ||
01226              type == Command::MOL_DRAWFRAMES ||
01227              type == Command::MOL_SCALEMINMAX ||
01228              type == Command::MOL_SHOWREP ||
01229              type == Command::MOL_SMOOTHREP) {
01230     if (type == Command::MOL_DELREP) {
01231       int delrep = ((CmdMolDeleteRep *)cmd)->repn;
01232       if (delrep < repindex) --repindex;
01233     } else if (type == Command::MOL_ADDREP) {
01234       // make update_repindex highlight the last rep
01235       repindex = 99999; 
01236     }
01237 
01238     // Keep the browser line at the same position unless we're adding
01239     // or deleting representations.
01240     bool remember_position = true;
01241     if (type == Command::MOL_ADDREP || type == Command::MOL_DELREP) 
01242       remember_position = false;
01243     update_repindex();
01244     update_repbrowser(remember_position);
01245   } else if (type == Command::MATERIAL_RENAME
01246           || type == Command::MATERIAL_ADD
01247           || type == Command::MATERIAL_DELETE) {
01248     int cur = materialchooser->value();
01249     MaterialList *mlist = app->materialList;
01250     materialchooser->clear();
01251     for (int m=0; m<mlist->num(); m++) {
01252       materialchooser->add(mlist->material_name(m));
01253     }
01254     if (type != Command::MATERIAL_DELETE) {
01255       materialchooser->value(cur);
01256     } else {
01257       if (molindex >= 0 && repindex >= 0) {
01258         Molecule *mol = app->moleculeList->molecule(molindex);
01259         DrawMolItem *d = mol->component(repindex);
01260         materialchooser->value(d->curr_material());
01261       } else {
01262         materialchooser->value(0);
01263       }
01264     }
01265   } else if (type == Command::MOL_REPSELUPDATE ||
01266              type == Command::MOL_REPCOLORUPDATE) {
01267     update_rep();
01268   } else if (type == Command::ATOMSEL_ADDMACRO || 
01269            type == Command::ATOMSEL_DELMACRO) {
01270     selbuilder->update_macrobrowser();
01271 
01272   } else if (type == Command::MOL_SHOWPERIODIC ||
01273              type == Command::MOL_NUMPERIODIC) {
01274     update_pbc();
01275   } else {
01276     return FALSE;
01277   }
01278   return TRUE;
01279 }
01280 
01281 
01282 int GraphicsFltkMenu::selectmol(int selmol) {
01283   if (selmol >= 0 && selmol < molchooser->size()-1) 
01284     molindex = selmol;
01285   update_molchooser();
01286   return TRUE;
01287 }
01288 

Generated on Fri Oct 4 02:44:06 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002