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

GraphicsFltkReps.h

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: GraphicsFltkReps.h,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.129 $       $Date: 2013/04/03 19:51:46 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  generated by Fast Light User Interface Designer (fluid) version 1.0011
00019  ***************************************************************************/
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <math.h>
00024 #include "FL/forms.H"
00025 #include "FL/Fl_Counter.H"
00026 #include "FL/Fl_Value_Slider.H"
00027 #include "FL/Fl_Float_Input.H"
00028 #include "FL/Fl_Tabs.H"
00029 #include "AtomRep.h"
00030 #include "Molecule.h"
00031 #include "VMDApp.h"
00032 #include "MoleculeList.h"
00033 
00034 
00038 class GraphicsFltkRep : public Fl_Group {
00039 protected:
00040   GraphicsFltkRep()
00041   : Fl_Group(10, 380, 295, 235) {}
00042   virtual void do_reset() {}
00043 
00044   char cmdbuf[256];
00045 
00046 public:
00047   virtual int is_volumetric() { return 0; }
00048   virtual int is_orbital() { return 0; }
00049   virtual const char *repcmd() = 0;
00050   virtual void set_values(AtomRep *) = 0;
00051   void reset() { do_reset(); }
00052 };
00053 
00054 
00055 #define CTRWIDTH   120
00056 #define CTRWIDTHSM  80
00057 #define CTRHEIGHT   25
00058 
00060 class RadiusCounter : public Fl_Counter {
00061 public:
00062   RadiusCounter(int x, int y, const char *nm)
00063   : Fl_Counter(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00064     minimum(0);
00065     precision(1);
00066     step(.1);
00067     lstep(1);
00068     align(FL_ALIGN_LEFT);
00069     when(FL_WHEN_RELEASE);
00070   }
00071 };
00072 
00073 
00075 class GridResCounter : public Fl_Counter {
00076 public:
00077   GridResCounter(int x, int y, const char *nm)
00078   : Fl_Counter(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00079     minimum(0.05);
00080     precision(3);
00081     step(0.005);
00082     lstep(0.025);
00083     align(FL_ALIGN_LEFT);
00084     when(FL_WHEN_RELEASE);
00085   }
00086 };
00087 
00088 
00090 class ResolutionCounter : public Fl_Counter {
00091 public:
00092   ResolutionCounter(int x, int y, const char *nm)
00093   : Fl_Counter(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00094     minimum(1);
00095     precision(0);
00096     step(1);
00097     lstep(5);
00098     align(FL_ALIGN_LEFT);
00099     when(FL_WHEN_RELEASE);
00100   }
00101 };
00102 
00103 
00105 class StepCounter : public Fl_Counter {
00106 public:
00107   StepCounter(int x, int y, const char *nm)
00108   : Fl_Counter(x, y, 90, CTRHEIGHT, nm) {
00109     minimum(1);
00110     precision(0);
00111     step(1);
00112     lstep(4);
00113     align(FL_ALIGN_LEFT);
00114     when(FL_WHEN_RELEASE);
00115   }
00116 };
00117 
00118 
00120 class RepChoice : public Fl_Choice {
00121 public:
00122   RepChoice(int x, int y, const char *nm)  
00123   : Fl_Choice(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00124     color(VMDMENU_CHOOSER_BG);
00125     selection_color(VMDMENU_CHOOSER_SEL);
00126     align(FL_ALIGN_LEFT);
00127   }
00128   int setvalue(int newvalue) {
00129     if (newvalue >= 0 && newvalue < size())
00130       return Fl_Choice::value(newvalue);
00131     return value();
00132   }
00133 };
00134 
00136 class RepChoiceSmall : public Fl_Choice {
00137 public:
00138   RepChoiceSmall(int x, int y, const char *nm)  
00139   : Fl_Choice(x, y, CTRWIDTHSM, CTRHEIGHT, nm) {
00140     color(VMDMENU_CHOOSER_BG);
00141     selection_color(VMDMENU_CHOOSER_SEL);
00142     align(FL_ALIGN_LEFT);
00143   }
00144   int setvalue(int newvalue) {
00145     if (newvalue >= 0 && newvalue < size())
00146       return Fl_Choice::value(newvalue);
00147     return value();
00148   }
00149 };
00150 
00151 
00153 class IsoSlider : public Fl_Value_Slider {
00154 public:
00155   IsoSlider(int x, int y, const char *nm)
00156   : Fl_Value_Slider(x, y, CTRWIDTH+90, CTRHEIGHT, nm) {
00157     color(VMDMENU_SLIDER_BG);
00158     align(FL_ALIGN_LEFT);
00159     type(FL_HOR_SLIDER);
00160   }
00161 };
00162 
00164 class ShortSlider : public Fl_Value_Slider {
00165 public:
00166   ShortSlider(int x, int y, const char *nm)
00167   : Fl_Value_Slider(x, y, CTRWIDTH+50, CTRHEIGHT, nm) {
00168     color(VMDMENU_SLIDER_BG);
00169     align(FL_ALIGN_LEFT);
00170     type(FL_HOR_SLIDER);
00171   }
00172 };
00173 
00175 class GraphicsFltkRepLines : public GraphicsFltkRep {
00176 public:
00177   GraphicsFltkRepLines(Fl_Callback *cb, void *v) {
00178     thickness = new ResolutionCounter(x()+170, y()+120, "Thickness");
00179     thickness->callback(cb, v);
00180     Fl_Group::end();
00181   }
00182   const char *repcmd() {
00183     sprintf(cmdbuf, "Lines %f", thickness->value());
00184     return cmdbuf;
00185   }
00186   void set_values(AtomRep *rep) {
00187     thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
00188   }
00189  
00190 protected:
00191   void do_reset() {
00192     thickness->value(1);
00193   }
00194 
00195 private:
00196   Fl_Counter *thickness;
00197 };
00198 
00199 
00201 class GraphicsFltkRepBonds : public GraphicsFltkRep {
00202 public:
00203   GraphicsFltkRepBonds(Fl_Callback *cb, void *v) {
00204     radius = new RadiusCounter(x()+170, y()+90, "Bond Radius");
00205     resolution= new ResolutionCounter(x()+170,y()+120,"Bond Resolution");
00206     radius->callback(cb, v);
00207     resolution->callback(cb, v);
00208     Fl_Group::end();
00209   }
00210   const char *repcmd() {
00211     sprintf(cmdbuf, "Bonds %f %f", radius->value(), resolution->value());
00212     return cmdbuf;
00213   }
00214   void set_values(AtomRep *rep) {
00215     radius->value(rep->get_data(AtomRep::BONDRAD));
00216     resolution->value(rep->get_data(AtomRep::BONDRES));
00217   }
00218 
00219 protected:
00220   void do_reset() {
00221     radius->value(0.3);
00222     resolution->value(12);
00223   }
00224 
00225 protected:
00226   Fl_Counter *radius;
00227   Fl_Counter *resolution;
00228 };
00229 
00230 
00232 class GraphicsFltkRepDynamicBonds : public GraphicsFltkRep {
00233 private:
00234   Fl_Counter *distance;
00235   Fl_Counter *radius;
00236   Fl_Counter *resolution;
00237 public:
00238   GraphicsFltkRepDynamicBonds(Fl_Callback *cb, void *v) {
00239     distance = new RadiusCounter(x()+170,y()+60,"Distance Cutoff");
00240     distance->callback(cb, v);
00241     radius = new RadiusCounter(x()+170, y()+90, "Bond Radius");
00242     radius->callback(cb, v);
00243     resolution= new ResolutionCounter(x()+170,y()+120,"Bond Resolution");
00244     resolution->callback(cb, v);
00245     Fl_Group::end();
00246   }
00247 protected:
00248   void do_reset() {
00249     distance->value(1.6);
00250     radius->value(0.3);
00251     resolution->value(12.0);
00252   }
00253 public:
00254   const char *repcmd() {
00255     sprintf(cmdbuf, "DynamicBonds %f %f %f", distance->value(), radius->value(),
00256       resolution->value());
00257     return cmdbuf;
00258   }
00259   void set_values(AtomRep *rep) {
00260     distance->value(rep->get_data(AtomRep::SPHERERAD));
00261     radius->value(rep->get_data(AtomRep::BONDRAD));
00262     resolution->value(rep->get_data(AtomRep::BONDRES));
00263   }
00264 };
00265 
00266  
00268 class GraphicsFltkRepCPK : public GraphicsFltkRep {
00269 public:
00270   GraphicsFltkRepCPK(Fl_Callback *cb, void *v) {
00271     bradius = new RadiusCounter(x()+170,y()+90,"Bond Radius");
00272     bresolution= new ResolutionCounter(x()+170,y()+120,"Bond Resolution");
00273     bradius->callback(cb, v);
00274     bresolution->callback(cb, v);
00275 
00276     sradius = new RadiusCounter(x()+170,y()+30,"Sphere Scale");
00277     sresolution= new ResolutionCounter(x()+170,y()+60,"Sphere Resolution");
00278     sradius->callback(cb, v);
00279     sresolution->callback(cb, v);
00280 
00281     Fl_Group::end();
00282   }
00283 
00284   const char *repcmd() {
00285     sprintf(cmdbuf, "CPK %f %f %f %f", sradius->value(), bradius->value(),
00286             sresolution->value(), bresolution->value());
00287     return cmdbuf;
00288   }
00289   void set_values(AtomRep *rep) {
00290     bradius->value(rep->get_data(AtomRep::BONDRAD));
00291     bresolution->value(rep->get_data(AtomRep::BONDRES));
00292     sradius->value(rep->get_data(AtomRep::SPHERERAD));
00293     sresolution->value(rep->get_data(AtomRep::SPHERERES));
00294   }
00295 
00296 protected:
00297   void do_reset() {
00298     bradius->value(0.3);
00299     bresolution->value(12);
00300     sradius->value(1.0);
00301     sresolution->value(12);
00302   }
00303 
00304 private:
00305   Fl_Counter *bradius;
00306   Fl_Counter *bresolution;
00307   Fl_Counter *sradius;
00308   Fl_Counter *sresolution;
00309 };
00310 
00311 
00313 class GraphicsFltkRepPoints : public GraphicsFltkRep {
00314 public:
00315   GraphicsFltkRepPoints(Fl_Callback *cb, void *v) {
00316     size = new ResolutionCounter(x()+170, y()+120, "Size");
00317     size->callback(cb, v);
00318     Fl_Group::end();
00319   }
00320   const char *repcmd() {
00321     sprintf(cmdbuf, "Points %f", size->value());
00322     return cmdbuf;
00323   }
00324   void set_values(AtomRep *rep) {
00325     size->value(rep->get_data(AtomRep::LINETHICKNESS));
00326   }
00327 
00328 protected:
00329   void do_reset() {
00330     size->value(1);
00331   }
00332 
00333 private:
00334   Fl_Counter *size;
00335 };
00336 
00337 
00338  
00340 class GraphicsFltkRepVDW : public GraphicsFltkRep {
00341 public:
00342   GraphicsFltkRepVDW(Fl_Callback *cb, void *v) {
00343     radius = new RadiusCounter(x()+170,y()+90,"Sphere Scale");
00344     resolution= new ResolutionCounter(x()+170,y()+120,"Sphere Resolution");
00345     radius->callback(cb, v);
00346     resolution->callback(cb, v);
00347     Fl_Group::end();
00348   }
00349 
00350   const char *repcmd() {
00351     sprintf(cmdbuf, "VDW %f %f", radius->value(), resolution->value());
00352     return cmdbuf;
00353   }
00354   void set_values(AtomRep *rep) {
00355     radius->value(rep->get_data(AtomRep::SPHERERAD));
00356     resolution->value(rep->get_data(AtomRep::SPHERERES));
00357   }
00358 
00359 protected:
00360   void do_reset() {
00361     radius->value(1.0);
00362     resolution->value(12);
00363   }
00364 
00365 protected:
00366   Fl_Counter *radius;
00367   Fl_Counter *resolution;
00368 };
00369 
00370 
00372 class GraphicsFltkRepBeads : public GraphicsFltkRepVDW {
00373 public:
00374   GraphicsFltkRepBeads(Fl_Callback *cb, void *v)
00375   : GraphicsFltkRepVDW(cb, v) {}
00376   const char *repcmd() {
00377     sprintf(cmdbuf, "Beads %f %f", radius->value(), resolution->value()); 
00378     return cmdbuf;
00379   }
00380 };
00381 
00382 
00384 class GraphicsFltkRepDotted : public GraphicsFltkRepVDW {
00385 public:
00386   GraphicsFltkRepDotted(Fl_Callback *cb, void *v)
00387   : GraphicsFltkRepVDW(cb, v) {}
00388   const char *repcmd() {
00389     sprintf(cmdbuf, "Dotted %f %f", radius->value(), resolution->value()); 
00390     return cmdbuf;
00391   }
00392 };
00393 
00394 
00396 class GraphicsFltkRepTrace : public GraphicsFltkRepBonds {
00397 public:
00398   GraphicsFltkRepTrace(Fl_Callback *cb, void *v)
00399   : GraphicsFltkRepBonds(cb, v) {}
00400   const char *repcmd() {
00401     sprintf(cmdbuf, "Trace %f %f", radius->value(), resolution->value());
00402     return cmdbuf;
00403   }
00404 };
00405 
00406 
00408 class GraphicsFltkRepLicorice : public GraphicsFltkRepBonds {
00409 private:
00410   Fl_Counter *sresolution;
00411 public:
00412   GraphicsFltkRepLicorice(Fl_Callback *cb, void *v)
00413   :  GraphicsFltkRepBonds(cb, v) {
00414     Fl_Group::begin();
00415     sresolution= new ResolutionCounter(x()+170,y()+60,"Sphere Resolution");
00416     sresolution->callback(cb, v);
00417 
00418     Fl_Group::end();
00419   }
00420 protected:
00421   void do_reset() {
00422     GraphicsFltkRepBonds::do_reset();
00423     resolution->value(12);
00424     sresolution->value(12);
00425   }
00426 public:
00427   const char *repcmd() {
00428     sprintf(cmdbuf, "Licorice %f %f %f", radius->value(), sresolution->value(),
00429       resolution->value());
00430     return cmdbuf;
00431   }
00432   void set_values(AtomRep *rep) {
00433     GraphicsFltkRepBonds::set_values(rep);
00434     sresolution->value(rep->get_data(AtomRep::SPHERERES));
00435   }
00436 };
00437     
00438 
00439 #ifdef VMDPOLYHEDRA
00440 
00441 class GraphicsFltkRepPolyhedra : public GraphicsFltkRep {
00442 private:
00443   Fl_Counter *distance;
00444 public:
00445   GraphicsFltkRepPolyhedra(Fl_Callback *cb, void *v) {
00446     distance = new RadiusCounter(x()+170,y()+60,"Distance Cutoff");
00447     distance->callback(cb, v);
00448     Fl_Group::end();
00449   }
00450 protected:
00451   void do_reset() {
00452     distance->value(1.6);
00453   }
00454 public:
00455   const char *repcmd() {
00456     sprintf(cmdbuf, "Polyhedra %f", distance->value());
00457     return cmdbuf;
00458   }
00459   void set_values(AtomRep *rep) {
00460     distance->value(rep->get_data(AtomRep::SPHERERAD));
00461   }
00462 };
00463 #endif
00464 
00466 class GraphicsFltkRepTube : public GraphicsFltkRepBonds {
00467 public:
00468   GraphicsFltkRepTube(Fl_Callback *cb, void *v)
00469   : GraphicsFltkRepBonds(cb, v) {
00470     radius->label("Radius");
00471     resolution->label("Resolution");
00472   }
00473   const char *repcmd() {
00474     sprintf(cmdbuf, "Tube %f %f", radius->value(), resolution->value());
00475     return cmdbuf;
00476   }
00477 };
00478     
00479 
00481 class GraphicsFltkRepRibbons : public GraphicsFltkRepBonds {
00482 protected:
00483   Fl_Counter *thickness;
00484 public:
00485   GraphicsFltkRepRibbons(Fl_Callback *cb, void *v)
00486   : GraphicsFltkRepBonds(cb, v) {
00487     radius->label("Radius"); 
00488     resolution->label("Resolution");
00489     Fl_Group::begin();
00490     thickness = new ResolutionCounter(x()+170,y()+60,"Width");
00491     thickness->callback(cb, v);
00492     Fl_Group::end();
00493   }
00494 protected:
00495   void do_reset() {
00496     GraphicsFltkRepBonds::do_reset();
00497     thickness->value(2);
00498   }
00499 public:
00500   const char *repcmd() {
00501     sprintf(cmdbuf, "Ribbons %f %f %f", radius->value(), resolution->value(),
00502       thickness->value());
00503     return cmdbuf;
00504   }
00505   void set_values(AtomRep *rep) {
00506     GraphicsFltkRepBonds::set_values(rep);
00507     thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
00508   }
00509 };
00510 
00511 
00513 class GraphicsFltkRepNewRibbons : public GraphicsFltkRep {
00514 private:
00515   RepChoice *basis;
00516   IsoSlider *thickness, *ratio;
00517   ResolutionCounter *resolution;
00518 public:
00519   GraphicsFltkRepNewRibbons(Fl_Callback *cb, void *v) {
00520 
00521     Fl_Group::begin();
00522     thickness = new IsoSlider(x()+80, y()+90, "Thickness");
00523     thickness->callback(cb, v);
00524     thickness->minimum(0.1);
00525     thickness->maximum(10.0);
00526 
00527     resolution= new ResolutionCounter(x()+170,y()+120,"Resolution");
00528     resolution->callback(cb, v);
00529     resolution->maximum(50.0);
00530 
00531     ratio= new IsoSlider(x()+80, y()+60, "Aspect Ratio");
00532     ratio->callback(cb, v);
00533     ratio->minimum(1.0);
00534     ratio->maximum(10.0);
00535 
00536     basis = new RepChoice(x()+170,y()+30,"Spline Style");
00537     basis->add("Catmull-Rom");
00538     basis->add("B-Spline");
00539     basis->callback(cb, v);
00540     Fl_Group::end();
00541   }
00542 protected:
00543   void do_reset() {
00544     thickness->value(0.3);
00545     resolution->value(12);
00546     ratio->value(3);
00547     basis->value(0);
00548   }
00549 public:
00550   const char *repcmd() {
00551     sprintf(cmdbuf, "NewRibbons %f %f %f %d", thickness->value(), 
00552         resolution->value(), ratio->value(), basis->value());
00553     return cmdbuf;
00554   }
00555   void set_values(AtomRep *rep) {
00556     ratio->value(rep->get_data(AtomRep::LINETHICKNESS));
00557     basis->value((int)rep->get_data(AtomRep::SPHERERAD));
00558     thickness->value(rep->get_data(AtomRep::BONDRAD));
00559     resolution->value(rep->get_data(AtomRep::BONDRES));
00560   }
00561 };
00562 
00563 
00565 class GraphicsFltkRepCartoon : public GraphicsFltkRepRibbons {
00566 public:
00567   GraphicsFltkRepCartoon(Fl_Callback *cb, void *v)
00568   : GraphicsFltkRepRibbons(cb, v) {
00569     radius->label("Helix/Coil Radius");
00570     resolution->label("Helix/Coil Resolution");
00571     thickness->label("Beta Sheet Thickness");
00572   }
00573   const char *repcmd() {
00574     sprintf(cmdbuf, "Cartoon %f %f %f", radius->value(), resolution->value(),
00575       thickness->value());
00576     return cmdbuf;
00577   }
00578 protected:
00579   void do_reset() {
00580     radius->value(2.1);
00581     resolution->value(24.0);
00582     thickness->value(5.0);
00583   }
00584 };
00585 
00586 
00588 class GraphicsFltkRepNewCartoon : public GraphicsFltkRep {
00589 private:
00590   RepChoice *basis;
00591   IsoSlider *thickness, *ratio;
00592   ResolutionCounter *resolution;
00593 public:
00594   GraphicsFltkRepNewCartoon(Fl_Callback *cb, void *v) {
00595 
00596     Fl_Group::begin();
00597     thickness = new IsoSlider(x()+80, y()+90, "Thickness");
00598     thickness->callback(cb, v);
00599     thickness->minimum(0.1);
00600     thickness->maximum(10.0);
00601 
00602     resolution= new ResolutionCounter(x()+170,y()+120,"Resolution");
00603     resolution->callback(cb, v);
00604     resolution->maximum(50.0);
00605 
00606     ratio= new IsoSlider(x()+80, y()+60, "Aspect Ratio");
00607     ratio->callback(cb, v);
00608     ratio->minimum(1.0);
00609     ratio->maximum(10.0);
00610 
00611     basis = new RepChoice(x()+170,y()+30,"Spline Style");
00612     basis->add("Catmull-Rom");
00613     basis->add("B-Spline");
00614     basis->callback(cb, v);
00615     Fl_Group::end();
00616   }
00617 protected:
00618   void do_reset() {
00619     thickness->value(0.3);
00620     resolution->value(10);
00621     ratio->value(4.1);
00622     basis->value(0);
00623   }
00624 public:
00625   const char *repcmd() {
00626     sprintf(cmdbuf, "NewCartoon %f %f %f %d", thickness->value(), 
00627         resolution->value(), ratio->value(), basis->value());
00628     return cmdbuf;
00629   }
00630   void set_values(AtomRep *rep) {
00631     ratio->value(rep->get_data(AtomRep::LINETHICKNESS));
00632     basis->value((int)rep->get_data(AtomRep::SPHERERAD));
00633     thickness->value(rep->get_data(AtomRep::BONDRAD));
00634     resolution->value(rep->get_data(AtomRep::BONDRES));
00635   }
00636 };
00637 
00638 #ifdef VMDWITHCARBS
00639 
00641 class GraphicsFltkRepWithRingSize : public GraphicsFltkRep {
00642 protected:
00643   ResolutionCounter *max_ring_size;
00644   Fl_Callback *parentcb;
00645   void *parentdata;
00646   
00647   static void sync_cb(Fl_Widget *, void *v) {
00648     GraphicsFltkRepWithRingSize *self = (GraphicsFltkRepWithRingSize *)v;
00649     GraphicsFltkMenu *menu = (GraphicsFltkMenu *) self->parentdata;
00650     
00651     int max_ring_size = (int)self->max_ring_size->value();
00652     
00653     Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
00654     
00655     for (int i=0; i<m->components(); i++) {
00656       DrawMolItem *d = m->component(i);
00657       AtomRep *ar = d->atomRep;
00658 
00659       if (ar->method() == AtomRep::RINGS_PAPERCHAIN || ar->method() == AtomRep::RINGS_TWISTER) {
00660         GraphicsFltkRepWithRingSize *rep;
00661         
00662         if (ar->method() == AtomRep::RINGS_PAPERCHAIN)
00663           rep = (GraphicsFltkRepWithRingSize *) menu->repcontrols.data("PaperChain");
00664         else
00665           rep = (GraphicsFltkRepWithRingSize *) menu->repcontrols.data("Twister");
00666 
00667         rep->set_values(ar);              
00668         rep->max_ring_size->value(max_ring_size);
00669         ar->change(rep->repcmd());
00670         d->force_recalc(d->MOL_REGEN);
00671       }        
00672     }
00673 
00674     // Don't call parent since we've already updated ourselves.
00675     // (self->parentcb)(self->max_ring_size, self->parentdata);
00676   }
00677 };
00678 
00680 class GraphicsFltkRepPaperChain : public GraphicsFltkRepWithRingSize {
00681 private:
00682   ShortSlider *bipyramid_height;
00683 public:
00684   GraphicsFltkRepPaperChain(Fl_Callback *cb, void *v) {
00685     parentcb = cb;
00686     parentdata = v;
00687 
00688     Fl_Group::begin();
00689 
00690     bipyramid_height = new ShortSlider(x()+120, y()+30, "Bipyramid Height");
00691     bipyramid_height->callback(cb, v);
00692     bipyramid_height->minimum(0.1);
00693     bipyramid_height->maximum(10.0);
00694 
00695     max_ring_size = new ResolutionCounter(x()+150, y()+60, "Max. Ring Size");
00696     max_ring_size->callback(sync_cb,this);
00697     max_ring_size->minimum(2);
00698     max_ring_size->maximum(500);
00699 
00700     Fl_Group::end();
00701   }
00702 protected:
00703   void do_reset() {
00704     bipyramid_height->value(1.0);
00705     max_ring_size->value(10);
00706   }
00707 public:
00708   const char *repcmd() {
00709     sprintf(cmdbuf, "PaperChain %f %f", bipyramid_height->value(),
00710                                          max_ring_size->value());
00711     return cmdbuf;
00712   }
00713   void set_values(AtomRep *rep) {
00714     bipyramid_height->value(rep->get_data(AtomRep::LINETHICKNESS));
00715     max_ring_size->value((int)rep->get_data(AtomRep::ISOSTEPSIZE));
00716   }
00717 };
00718 
00720 class GraphicsFltkRepTwister : public GraphicsFltkRepWithRingSize {
00721 private:
00722   RepChoice *start_end_centroid;
00723   RepChoice *hide_shared_links;
00724   ResolutionCounter *rib_steps;
00725   ShortSlider *rib_width;
00726   ShortSlider *rib_height;
00727   ResolutionCounter *max_path_length;
00728 
00729 public:
00730   GraphicsFltkRepTwister(Fl_Callback *cb, void *v) {
00731     parentcb = cb;
00732     parentdata = v;
00733 
00734     Fl_Group::begin();
00735 
00736     start_end_centroid = new RepChoice(x()+150, y()+30, "Start Ribbons At");
00737     start_end_centroid->callback(cb,v);
00738     start_end_centroid->add("Ring Edge");
00739     start_end_centroid->add("Ring Centroid");
00740     
00741     hide_shared_links = new RepChoice(x()+150, y()+60,"Hide Shared Links");
00742     hide_shared_links->callback(cb,v);
00743     hide_shared_links->add("No");
00744     hide_shared_links->add("Yes");
00745     
00746     rib_steps = new ResolutionCounter(x()+150, y()+90, "Steps in Ribbon");
00747     rib_steps->callback(cb,v);
00748     rib_steps->minimum(5);
00749     rib_steps->maximum(500);
00750 
00751     max_ring_size = new ResolutionCounter(x()+150, y()+120, "Max. Ring Size");
00752     max_ring_size->callback(sync_cb,this);
00753     max_ring_size->minimum(2);
00754     max_ring_size->maximum(500);
00755 
00756     max_path_length = new ResolutionCounter(x()+150, y()+150, "Max. Linking Distance");
00757     max_path_length->callback(cb,v);
00758     max_path_length->minimum(1);
00759     max_path_length->maximum(500);
00760 
00761     rib_width = new ShortSlider(x()+110, y()+180, "Ribbon Width");
00762     rib_width->callback(cb,v);
00763     rib_width->minimum(0.01);
00764     rib_width->maximum(10.0);
00765 
00766     rib_height = new ShortSlider(x()+110, y()+210, "Ribbon Height");
00767     rib_height->callback(cb,v);
00768     rib_height->minimum(0.01);
00769     rib_height->maximum(10.0);
00770 
00771     Fl_Group::end();
00772   }
00773 protected:
00774   void do_reset() {
00775     start_end_centroid->value(1);
00776     hide_shared_links->value(0);
00777     rib_steps->value(10);
00778     rib_width->value(0.3);
00779     rib_height->value(0.05);
00780     max_ring_size->value(10);
00781     max_path_length->value(5);
00782   }
00783 public:
00784   const char *repcmd() {
00785     sprintf(cmdbuf, "Twister %f %f %f %f %f %f %f", (float) start_end_centroid->value(),
00786                                                     (float) hide_shared_links->value(),
00787                                                     (float) rib_steps->value(),
00788                                                     rib_width->value(), rib_height->value(),
00789                                                     max_ring_size->value(), max_path_length->value());
00790     return cmdbuf;
00791   }
00792   void set_values(AtomRep *rep) {
00793     start_end_centroid->value((int)rep->get_data(AtomRep::LINETHICKNESS));
00794     hide_shared_links->value((int)rep->get_data(AtomRep::BONDRES));
00795     rib_steps->value((int)rep->get_data(AtomRep::SPHERERAD));
00796     rib_width->value(rep->get_data(AtomRep::BONDRAD));
00797     rib_height->value(rep->get_data(AtomRep::SPHERERES));
00798     max_ring_size->value((int)rep->get_data(AtomRep::ISOSTEPSIZE));
00799     max_path_length->value((int)rep->get_data(AtomRep::ISOLINETHICKNESS));
00800   }
00801 };
00802 
00803 #endif
00804 
00806 class GraphicsFltkRepSolvent : public GraphicsFltkRep {
00807 private:
00808   RepChoice *method;
00809   Fl_Counter *detail;
00810   Fl_Counter *probe; 
00811 public:
00812   GraphicsFltkRepSolvent(Fl_Callback *cb, void *v) {
00813     method = new RepChoice(x()+170,y()+60,"Representation Method");
00814     method->add("Points");
00815     method->add("Crosses");
00816     method->add("Mesh");
00817     detail = new ResolutionCounter(x()+170,y()+90,"Detail Level");
00818     detail->maximum(13);
00819     probe = new RadiusCounter(x()+170,y()+120,"Probe Radius");
00820     method->callback(cb, v);
00821     detail->callback(cb, v);
00822     probe->callback(cb, v);
00823     Fl_Group::end();
00824   }
00825 protected:
00826   void do_reset() {
00827     method->value(0);
00828     detail->value(7.0);
00829     probe->value(0);
00830   }
00831 public:
00832   const char *repcmd() {
00833     sprintf(cmdbuf, "Solvent %f %f %f", probe->value(), detail->value(),
00834       (float)(method->value()+1));
00835     return cmdbuf;
00836   }
00837   void set_values(AtomRep *rep) {
00838     method->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS)-1);
00839     detail->value(rep->get_data(AtomRep::SPHERERES));
00840     probe->value(rep->get_data(AtomRep::SPHERERAD));
00841   }
00842 };
00843  
00844 
00846 class GraphicsFltkRepMSMS : public GraphicsFltkRep {
00847 private:
00848   Fl_Counter *density;
00849   Fl_Counter *probe;
00850   RepChoice *method;
00851   RepChoice *whichatoms;
00852 public:
00853   GraphicsFltkRepMSMS(Fl_Callback *cb, void *v) {
00854     density = new RadiusCounter(x()+170,y()+90,"Sample Density");
00855     density->minimum(0.1);
00856     density->maximum(30.0);
00857     density->callback(cb, v);
00858     probe = new RadiusCounter(x()+170,y()+120, "Probe Radius");
00859     probe->minimum(0.1);
00860     probe->maximum(8.0);
00861     probe->callback(cb, v);
00862     method = new RepChoice(x()+170,y()+60,"Representation Method");
00863     method->add("Solid Surface");
00864     method->add("Wireframe");
00865     method->callback(cb, v);
00866     whichatoms = new RepChoice(x()+170,y()+30, "Which Atoms");
00867     whichatoms->add("Selected");
00868     whichatoms->add("All");
00869     whichatoms->callback(cb, v);
00870     Fl_Group::end();
00871   }
00872 protected:
00873   void do_reset() {
00874     density->value(1.5);
00875     probe->value(1.5);
00876     method->value(0);
00877     whichatoms->value(0);
00878   }
00879 public:
00880   const char *repcmd() {
00881     sprintf(cmdbuf, "MSMS %f %f %f %f", probe->value(), density->value(),
00882       (float)whichatoms->value(), (float)method->value());
00883     return cmdbuf;
00884   }
00885   void set_values(AtomRep *rep) {
00886     density->value(rep->get_data(AtomRep::SPHERERES));
00887     probe->value(rep->get_data(AtomRep::SPHERERAD));
00888     method->setvalue((int)rep->get_data(AtomRep::BONDRES));
00889     whichatoms->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS));
00890   }
00891 };
00892   
00893 
00895 class GraphicsFltkRepHBonds : public GraphicsFltkRep {
00896 private:
00897   Fl_Counter *distance;
00898   Fl_Counter *angle;
00899   Fl_Counter *thickness;
00900 public:
00901   GraphicsFltkRepHBonds(Fl_Callback *cb, void *v) {
00902     distance = new RadiusCounter(x()+170,y()+60,"Distance Cutoff");
00903     distance->callback(cb, v);
00904     angle = new RadiusCounter(x()+170,y()+90,"Angle Cutoff");
00905     angle->precision(0);
00906     angle->step(1);
00907     angle->lstep(10);
00908     angle->callback(cb, v);
00909     thickness = new ResolutionCounter(x()+170,y()+120, "Line Thickness");
00910     thickness->callback(cb, v);
00911     Fl_Group::end();
00912   }
00913 protected:
00914   void do_reset() {
00915     distance->value(3.0);
00916     angle->value(20.0);
00917     thickness->value(1.0);
00918   }
00919 public:
00920   const char *repcmd() {
00921     sprintf(cmdbuf, "HBonds %f %f %f", distance->value(), angle->value(),
00922       thickness->value());
00923     return cmdbuf;
00924   }
00925   void set_values(AtomRep *rep) {
00926     distance->value(rep->get_data(AtomRep::BONDRAD));
00927     angle->value(rep->get_data(AtomRep::SPHERERAD));
00928     thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
00929   }
00930 };
00931      
00932 
00933 
00934 //  QuickSurf callback data structure containing multiple pointers
00935 class GraphicsFltkRepQuickSurf;    
00936 
00937 class quicksurf_cbdata {
00938 public:
00939   GraphicsFltkMenu *self;
00940   GraphicsFltkRepQuickSurf *qsurfrep;
00941 };
00942 
00944 class GraphicsFltkRepQuickSurf : public GraphicsFltkRep {
00945 private:
00946   Fl_Value_Slider *resolution;
00947   RepChoice *quality;
00948   Fl_Counter *radscale;
00949   Fl_Counter *gridspacing;
00950   Fl_Counter *isovalue;
00951   float gridspacingmult;
00952 
00953 public:
00954   GraphicsFltkRepQuickSurf(Fl_Callback *cb, void *v) {
00955     gridspacingmult = 1.0f;
00956     resolution = new IsoSlider(x()+80, y()+60, "Resolution");
00957     resolution->minimum(0.5);
00958     resolution->maximum(8);
00959     resolution->callback(cb, v);
00960     resolution->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS);
00961     radscale = new RadiusCounter(x()+170,y()+90,"Radius Scale");
00962     radscale->minimum(0.1);
00963     radscale->callback(cb, v);
00964     isovalue = new RadiusCounter(x()+170,y()+120,"Density Isovalue");
00965     isovalue->minimum(0.1);
00966     isovalue->maximum(20);
00967     isovalue->callback(cb, v);
00968     gridspacing = new RadiusCounter(x()+170,y()+150,"Grid Spacing");
00969     gridspacing->minimum(0.5);
00970     gridspacing->callback(cb, v);
00971     quality = new RepChoice(x()+170,y()+180, "Surface Quality");
00972     quality->add("Low");
00973     quality->add("Medium");
00974     quality->add("High");
00975     quality->add("Max");
00976     quality->callback(cb, v);
00977     Fl_Group::end();
00978   }
00979 
00980   void set_gridspacing_multiplier(float mult) {
00981     gridspacingmult = mult;
00982   }
00983 
00984   void resolution_changed() {
00985     float val = (float) resolution->value();
00986     float res = val;
00987     
00988     int qual = quality->value();
00989     switch (qual) {
00990       case 0: res *= 2.0f; break;
00991 
00992       case 1: res *= 1.0f; break;
00993 
00994       case 2:
00995       case 3:
00996       default: res /= 2.0f; break;
00997     }
00998     
00999     float density = 0.5f;
01000     if (val > 3.0f) {
01001       density = 30.0f*(val-3.0f)+6.0f*powf((val-3.0f),2.0f)+10.0f*powf(val-3.0f,0.5f)+23.0f;
01002     } else if (val > 1) {
01003       density = 254.83f * expf(-1.018f * val) - 
01004                 5071.0f * powf(val, -0.0189f) + 4980.0f;
01005     } else {
01006       density = val;
01007     }
01008   
01009     radscale->value(val);
01010     isovalue->value(density);
01011     gridspacing->value(res * gridspacingmult);
01012   }
01013 
01014 protected:
01015   void do_reset() {
01016     resolution->value(1.0);
01017     radscale->value(1.0);
01018     gridspacing->value(1.0);
01019     isovalue->value(0.5);
01020     quality->value(1);
01021   }
01022 public:
01023   const char *repcmd() {
01024     sprintf(cmdbuf, "QuickSurf %f %f %f %f", 
01025             radscale->value(), isovalue->value(), gridspacing->value(),
01026            (float)quality->value());
01027     return cmdbuf;
01028   }
01029   void set_values(AtomRep *rep) {
01030     radscale->value(rep->get_data(AtomRep::SPHERERAD));
01031     isovalue->value(rep->get_data(AtomRep::BONDRAD));
01032     gridspacing->value(rep->get_data(AtomRep::GRIDSPACING));
01033     quality->setvalue((int)rep->get_data(AtomRep::BONDRES));
01034   }
01035 };
01036 
01037 
01039 class GraphicsFltkRepSurf : public GraphicsFltkRep {
01040 private:
01041   Fl_Counter *probe;
01042   RepChoice *method;
01043 public:
01044   GraphicsFltkRepSurf(Fl_Callback *cb, void *v) {
01045     probe = new RadiusCounter(x()+170,y()+120,"Probe Radius");
01046     probe->minimum(0.1);
01047     probe->callback(cb, v);
01048     method = new RepChoice(x()+170,y()+90, "Representation Method");
01049     method->add("Solid Surface");
01050     method->add("Wireframe");
01051     method->callback(cb, v);
01052     Fl_Group::end();
01053   }
01054 protected:
01055   void do_reset() {
01056     probe->value(1.4);
01057     method->value(0);
01058   }
01059 public:
01060   const char *repcmd() {
01061     sprintf(cmdbuf, "Surf %f %f", probe->value(), (float)method->value());
01062     return cmdbuf;
01063   }
01064   void set_values(AtomRep *rep) {
01065     probe->value(rep->get_data(AtomRep::SPHERERAD));
01066     method->setvalue((int)rep->get_data(AtomRep::BONDRES));
01067   }
01068 };
01069  
01070 
01075 class GraphicsFltkRepVolumetric: public GraphicsFltkRep {
01076 protected:
01077   RepChoice *dataset;
01078 
01080   struct minmax {
01081     double minval, maxval;
01082     minmax(double themin=0, double themax=0) : minval(themin), maxval(themax) {}
01083     int operator==(const minmax &v) {
01084       return (minval == v.minval && maxval == v.maxval);
01085     }
01086   };
01087   ResizeArray<minmax> minmaxlist;
01088 
01089   GraphicsFltkRepVolumetric(Fl_Callback *cb, void *v) {
01090     dataset = new RepChoice(x()+170, y()+30, "Vol");
01091     dataset->callback(cb, v);
01092   }
01093   virtual void do_dataset_clear() {}
01094   virtual void do_dataset_append(const char *, double, double) {}
01095 
01096 public:
01097   int is_volumetric() { return 1; }
01098   void dataset_clear() {
01099     dataset->clear();
01100     dataset->deactivate();
01101     minmaxlist.clear();
01102     do_dataset_clear();
01103   }
01104   void dataset_append(const char *nm, double newmin, double newmax) {
01105     // Fltk doesn't allow adding a menu item with the same name as
01106     // an existing item, so we use replace, which also avoids 
01107     // problems with the escape characters interpreted by add()
01108     int ind = dataset->add("foobar"); 
01109     char *datalabel = new char[strlen(nm)+32];
01110     sprintf(datalabel, "vol%d: %s", ind, nm);
01111     dataset->replace(ind, datalabel);
01112     delete[] datalabel;
01113     
01114     minmaxlist.append(minmax(newmin, newmax));
01115     dataset->value(minmaxlist.num()-1);
01116     do_dataset_append(nm, newmin, newmax);
01117     dataset->activate();
01118   }
01119 };
01120 
01121 
01122 
01123 //  isosurface callback data structure containing multiple pointers
01124 class GraphicsFltkRepIsosurface; 
01125 
01126 class isosurface_cbdata {
01127 public:
01128   GraphicsFltkMenu *self;
01129   GraphicsFltkRepIsosurface *isorep;
01130 };
01131         
01133 class GraphicsFltkRepIsosurface : public GraphicsFltkRepVolumetric {
01134 private:
01135   Fl_Slider *isovalue;
01136   Fl_Float_Input *isoinput;
01137   Fl_Float_Input *isomininput, *isomaxinput;
01138   Fl_Counter *resolution;
01139   Fl_Counter *thickness;
01140   RepChoice *method;
01141   RepChoice *boundary;
01142   Fl_Callback *parentcb;
01143   void *parentdata;
01144   int gridstepsize;
01145 
01146   static void datasetchanged_cb(Fl_Widget *w, void *v) {
01147     GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01148     if (self->minmaxlist.num() > 0) {
01149       minmax &m = self->minmaxlist[self->dataset->value()];
01150       self->isovalue->range(m.minval, m.maxval);
01151     } else {
01152       self->isovalue->range(0, 1);
01153     }
01154     (self->parentcb)(w, self->parentdata);
01155   }
01156 
01157   static void inputcb(Fl_Widget *, void *v) {
01158     GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01159     char *endptr = NULL;
01160     const char *strval = self->isoinput->value();
01161     double val = strtod(strval, &endptr);
01162     if (endptr != strval) {
01163       // valid conversion performed
01164       self->isovalue->value(val);
01165       (self->parentcb)(self->isovalue, self->parentdata);
01166     }
01167   }
01168   
01169   static void minmaxinputcb(Fl_Widget *, void *v) {
01170     GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01171     // parse values in input fields
01172     char *endptr = NULL;
01173     const char *minstrval = self->isomininput->value();
01174     double minval = strtod(minstrval, &endptr);
01175     if (endptr == minstrval) return; // invalid
01176     const char *maxstrval = self->isomaxinput->value();
01177     double maxval = strtod(maxstrval, &endptr);
01178     if (endptr == maxstrval) return; // invalid
01179 
01180     // fields are valid; update cached minmax
01181     if (self->minmaxlist.num() > 0) {
01182       minmax &m = self->minmaxlist[self->dataset->value()];
01183       m.minval = minval;
01184       m.maxval = maxval;
01185     }
01186 
01187     // update the slider itself.  If we made the value change, trigger
01188     // appropriate callbacks.
01189     self->isovalue->range(minval, maxval);
01190     if (self->isovalue->value() < minval) {
01191       self->isovalue->value(minval);
01192       slidercb(NULL, v);
01193     } else if (self->isovalue->value() > maxval) {
01194       self->isovalue->value(maxval);
01195       slidercb(NULL, v);
01196     } else {
01197       self->setInputFromSlider();
01198     }
01199   }
01200 
01201   void setInputFromSlider() {
01202     char buf[128];
01203     sprintf(buf, "%8g", (float)isovalue->value()); 
01204     isoinput->value(buf);
01205     sprintf(buf, "%8g", (float)isovalue->minimum());
01206     isomininput->value(buf);
01207     sprintf(buf, "%8g", (float)isovalue->maximum());
01208     isomaxinput->value(buf);
01209   }
01210 
01211   static void slidercb(Fl_Widget *, void *v) {
01212     GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01213     self->setInputFromSlider();
01214     (self->parentcb)(self->isovalue, self->parentdata);
01215   }
01216 
01217 protected:
01218   void do_dataset_clear() { 
01219     isovalue->deactivate();
01220     isoinput->deactivate();
01221     boundary->deactivate();
01222     method->deactivate();
01223     resolution->deactivate();
01224     thickness->deactivate();
01225   }
01226   void do_dataset_append(const char *, double min, double max) { 
01227     isovalue->activate();
01228     isoinput->activate();
01229     boundary->activate();
01230     method->activate();
01231     resolution->activate();
01232     thickness->activate();
01233     isovalue->range(min,max);
01234     setInputFromSlider();
01235   }
01236   void do_reset() {
01237     set_grid_stepsize(1); 
01238     resolution->value(1); 
01239     thickness->value(1);  
01240     method->value(2);     
01241     boundary->value(2);   
01242     dataset->value(0);    
01243   }
01244 
01245 public:
01246   GraphicsFltkRepIsosurface(Fl_Callback *cb, void *v)
01247   : GraphicsFltkRepVolumetric(datasetchanged_cb, this) {
01248     parentcb = cb;
01249     parentdata = v;
01250 
01251     resolution= new StepCounter(x()+35,y()+90, "Step");
01252     resolution->callback(cb, v);
01253     thickness= new StepCounter(x()+35,y()+120, "Size");
01254     thickness->callback(cb, v);
01255     method = new RepChoice(x()+170,y()+90,"Draw");
01256     method->add("Solid Surface");
01257     method->add("Wireframe");
01258     method->add("Points");
01259     method->add("Shaded Points");
01260     method->callback(cb, v);
01261     boundary = new RepChoice(x()+170, y()+120, "Show");
01262     boundary->add("Isosurface");
01263     boundary->add("Box");
01264     boundary->add("Box+Isosurface");
01265     boundary->callback(cb, v); 
01266     isovalue = new Fl_Slider(x()+135,y()+60, 155, CTRHEIGHT, "");
01267     isovalue->type(FL_HOR_SLIDER);
01268     isovalue->color(VMDMENU_SLIDER_BG);
01269     isovalue->when(FL_WHEN_CHANGED);
01270     isovalue->callback(slidercb, this);
01271     isoinput = new Fl_Float_Input(x()+60, y()+60, 70, CTRHEIGHT, "Isovalue");
01272     isoinput->when(FL_WHEN_ENTER_KEY);
01273     isoinput->selection_color(VMDMENU_VALUE_SEL);
01274     isoinput->callback(inputcb, this);
01275     isovalue->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS);
01276 
01277     isomininput = new Fl_Float_Input(x()+45, y()+30, 45, CTRHEIGHT, "Range");
01278     isomininput->when(FL_WHEN_ENTER_KEY);
01279     isomininput->selection_color(VMDMENU_VALUE_SEL);
01280     isomininput->callback(minmaxinputcb, this);
01281     isomaxinput = new Fl_Float_Input(x()+90, y()+30, 45, CTRHEIGHT);
01282     isomaxinput->when(FL_WHEN_ENTER_KEY);
01283     isomaxinput->selection_color(VMDMENU_VALUE_SEL);
01284     isomaxinput->callback(minmaxinputcb, this);
01285 
01286     Fl_Group::end();
01287   }
01288   const char *repcmd() {
01289     if (dataset->size() > 0) {
01290       sprintf(cmdbuf, "Isosurface %f %d %d %d %d %d", 
01291               (float) isovalue->value(), 
01292               (int) dataset->value(), 
01293               (int) boundary->value(), 
01294               (int) method->value(), 
01295               gridstepsize + (int) resolution->value() - 1,
01296               (int) thickness->value());
01297     } else {
01298       sprintf(cmdbuf, "Isosurface");
01299     }
01300     return cmdbuf;
01301   }
01302   void set_values(AtomRep *rep) {
01303     dataset->setvalue((int)rep->get_data(AtomRep::SPHERERES));
01304     // minmax needs to update whenever dataset is changed or 
01305     // the selected rep is switched
01306     if (minmaxlist.num() > 0) {
01307       minmax &m = minmaxlist[dataset->value()]; 
01308       isovalue->range(m.minval, m.maxval);
01309     } else {
01310       isovalue->range(0, 1);
01311     }
01312     isovalue->value(rep->get_data(AtomRep::SPHERERAD));
01313     method->setvalue((int)rep->get_data(AtomRep::BONDRES));
01314     boundary->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS));
01315     resolution->value(rep->get_data(AtomRep::ISOSTEPSIZE) - gridstepsize + 1);
01316     thickness->value(rep->get_data(AtomRep::ISOLINETHICKNESS));
01317     setInputFromSlider();
01318   }
01319   void set_grid_stepsize(int step) {
01320     gridstepsize = step;
01321   }
01322 };
01323  
01324 
01326 class GraphicsFltkRepVolumeSlice : public GraphicsFltkRepVolumetric {
01327 private:
01328   Fl_Value_Slider *slice;
01329   RepChoice *axis;
01330   RepChoice *quality;  // texture filtering mode
01331 
01332 protected:
01333   void do_dataset_clear() {
01334     slice->deactivate();
01335     axis->deactivate();
01336     quality->deactivate();
01337   }
01338   void do_dataset_append(const char *, double, double) {
01339     slice->activate();
01340     axis->activate();
01341     quality->activate();
01342   }
01343   void do_reset() {
01344     slice->value(0.5);
01345     axis->value(0);
01346     quality->value(2);
01347   }
01348 public:
01349   GraphicsFltkRepVolumeSlice(Fl_Callback *cb, void *v)
01350   : GraphicsFltkRepVolumetric(cb, v) {
01351     slice = new IsoSlider(x()+80, y()+60, "Slice Offset");
01352     slice->callback(cb, v);
01353     axis = new RepChoice(x()+170, y()+90, "Slice Axis");
01354     axis->add("X");
01355     axis->add("Y");
01356     axis->add("Z");
01357     axis->callback(cb, v);
01358     quality = new RepChoice(x()+170,y()+120, "Render Quality");
01359     quality->add("Low");
01360     quality->add("Medium");
01361     quality->add("High");
01362     quality->callback(cb, v);
01363     Fl_Group::end();
01364   }
01365   const char *repcmd() {
01366     if (dataset->size() > 0) {
01367       sprintf(cmdbuf, "VolumeSlice %f %f %f %f", slice->value(),
01368         (float)dataset->value(), (float)axis->value(), 
01369         (float)quality->value()); 
01370     } else {
01371       sprintf(cmdbuf, "VolumeSlice");
01372     }
01373     return cmdbuf;
01374   }
01375   void set_values(AtomRep *rep) {
01376     dataset->setvalue((int)rep->get_data(AtomRep::SPHERERES));
01377     slice->value(rep->get_data(AtomRep::SPHERERAD));
01378     axis->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS)); 
01379     quality->setvalue((int)rep->get_data(AtomRep::BONDRES));
01380   }
01381 };
01382 
01383 
01384 
01385 //  orbital callback data structure containing multiple pointers
01386 class GraphicsFltkRepOrbital;    
01387 
01388 class orbital_cbdata {
01389 public:
01390   GraphicsFltkMenu *self;
01391   GraphicsFltkRepOrbital *orbrep;
01392 };
01393 
01394 
01396 class GraphicsFltkRepOrbital : public GraphicsFltkRep {
01397 protected:
01398   RepChoice      *wavefnctype;
01399   RepChoiceSmall *wavefncspin;
01400   RepChoiceSmall *wavefncexcitation;
01401   RepChoiceSmall *orbitalindex;
01402 
01404   struct minmax {
01405     double minval, maxval;
01406     minmax(double themin=0, double themax=0) : minval(themin), maxval(themax) {}
01407     int operator==(const minmax &v) {
01408       return (minval == v.minval && maxval == v.maxval);
01409     }
01410   };
01411   ResizeArray<minmax> minmaxlist;
01412 
01413 
01414 public:
01415   int is_orbital() { return 1; }
01416   void dataset_clear() {
01417     orbitalindex->clear();
01418     orbitalindex->deactivate();
01419     minmaxlist.clear();
01420     do_dataset_clear();
01421   }
01422   void dataset_append(const char *nm, double newmin, double newmax) {
01423     // Fltk doesn't allow adding a menu item with the same name as
01424     // an existing item, so we use replace, which also avoids
01425     // problems with the escape characters interpreted by add()
01426     int ind = orbitalindex->add("foobar");
01427     char *datalabel = new char[strlen(nm)+32];
01428     sprintf(datalabel, "%s", nm);
01429     orbitalindex->replace(ind, datalabel);
01430     delete[] datalabel;
01431 
01432     minmaxlist.append(minmax(newmin, newmax));
01433     orbitalindex->value(minmaxlist.num()-1);
01434     do_dataset_append(nm, newmin, newmax);
01435     orbitalindex->activate();
01436   }
01437 
01438   void regen_wavefunctypes() {
01439     int i;
01440     orbital_cbdata *cbdata = (orbital_cbdata *) parentdata;
01441     GraphicsFltkMenu *menu = (GraphicsFltkMenu *) cbdata->self;
01442     Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
01443     int firstvalidwaveftype=-1;
01444     int firstvalidwavefspin=-1;
01445 
01446     if (m != NULL && m->qm_data != NULL) {
01447       // loop over wavefunction types and enable/disable them
01448       // based on their availability for the current molecule.
01449       for (i=0; i<7; i++) {
01450         if (m->qm_data->has_wavef_guitype(i)) {
01451           wavefnctype->mode(i, 0);                 // activate choice
01452           if (firstvalidwaveftype < 0)
01453             firstvalidwaveftype=i;                 // record first valid type
01454         } else {
01455           wavefnctype->mode(i, FL_MENU_INACTIVE);  // deactivate choice
01456         }
01457       }
01458 
01459       // loop over wavefunction spins and enable/disable them
01460       // based on their availability for the current molecule.
01461       for (i=0; i<2; i++) {
01462         if (m->qm_data->has_wavef_spin(i)) {
01463           wavefncspin->mode(i, 0);
01464           if (firstvalidwavefspin < 0)
01465             firstvalidwavefspin=i;                 // record first valid spin
01466         } else {
01467           wavefncspin->mode(i, FL_MENU_INACTIVE);
01468         }
01469       }
01470     } else {
01471       // no qm data or no molecule, so all types/spins disabled
01472       for (i=0; i<7; i++)
01473         wavefnctype->mode(i, FL_MENU_INACTIVE);
01474       for (i=0; i<2; i++)
01475         wavefncspin->mode(i, FL_MENU_INACTIVE);
01476     }
01477 
01478     // automatically set the wavefunction type control to the first valid type
01479     if (firstvalidwaveftype >= 0)
01480       wavefnctype->value(firstvalidwaveftype);
01481 
01482     // automatically set the wavefunction spin control to the first valid spin
01483     if (firstvalidwavefspin >= 0)
01484       wavefncspin->value(firstvalidwavefspin);
01485 
01486     // regenerate the excitation chooser as well
01487     regen_excitationlist();
01488   }
01489 
01490   void regen_excitationlist() {
01491     orbital_cbdata *cbdata = (orbital_cbdata *) parentdata;
01492     GraphicsFltkMenu *menu = (GraphicsFltkMenu *) cbdata->self;
01493     Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
01494 
01495     int wftype = (int) wavefnctype->value();
01496     if (m != NULL && m->qm_data != NULL && 
01497         m->qm_data->has_wavef_guitype(wftype)) {
01498       int maxexcitations = m->qm_data->get_highest_excitation(wftype);
01499       wavefncexcitation->clear();
01500       wavefncexcitation->deactivate();
01501 
01502       // regenerate the contents of the excitation chooser based
01503       // on the currently selected wavefunction type
01504       int i;
01505       for (i=0; i<=maxexcitations; i++) {
01506         char excitationstr[64];
01507         sprintf(excitationstr, "%d", i);
01508         wavefncexcitation->add(excitationstr);
01509       }
01510 
01511       // toggle excitations active/inactive in the GUI
01512       int firstvalidexcitation=-1;
01513       for (i=0; i<=maxexcitations; i++) {
01514         if (m->qm_data->find_wavef_id_from_gui_specs(wftype, GUI_WAVEF_SPIN_ALPHA, i)>=0 ||
01515             m->qm_data->find_wavef_id_from_gui_specs(wftype, GUI_WAVEF_SPIN_BETA, i)>=0) {
01516           // record the first valid excitation for this wavefunction type
01517           if (firstvalidexcitation < 0)
01518             firstvalidexcitation=i;
01519           wavefncexcitation->mode(i, 0); // enable in the GUI
01520         } else {
01521           wavefncexcitation->mode(i, FL_MENU_INACTIVE); // disable in the GUI
01522         }
01523       }
01524 
01525       // automatically set the excitation control to the first valid
01526       // excitation we find (if any)
01527       if (firstvalidexcitation >= 0)
01528         wavefncexcitation->value(firstvalidexcitation);
01529       wavefncexcitation->activate();
01530     }
01531   }
01532 
01533   void regen_orbitallist(int orblistcenter=10) {
01534     dataset_clear();
01535     orbital_cbdata *cbdata = (orbital_cbdata *) parentdata;
01536     GraphicsFltkMenu *menu = (GraphicsFltkMenu *) cbdata->self;
01537     Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
01538     if (m != NULL && m->qm_data != NULL) {
01539       char namestr[80];
01540 
01541       int waveid = 0;
01542       int wftype = (int) wavefnctype->value();
01543       int wfspin = (int) wavefncspin->value();
01544       int wfexcitation = (int) wavefncexcitation->value();
01545 
01546       // convert GUI selections of wavefunction type, spin, and excitation
01547       // into the correct internal wavefunction ID tag
01548       waveid = m->qm_data->find_wavef_id_from_gui_specs(wftype, wfspin, wfexcitation);
01549 
01550       if (waveid < 0) {
01551         orbitalindex->activate();
01552         return;
01553       }
01554 
01555       // get 1-based maximum orbital index 
01556       int molmaxorb = m->qm_data->get_max_avail_orbitals(waveid);
01557 
01558       // set maximum orbital list center value for selected wavefunction
01559       // (1-based index)
01560       orbitallistcounter->maximum(molmaxorb);
01561 
01562       // check for orblistcenter for -1, and read from orbitallistcounter
01563       if (orblistcenter == -1)
01564         orblistcenter = (int) orbitallistcounter->value();
01565       else 
01566         orbitallistcounter->value(orblistcenter);
01567 
01568       // clamp orblistcenter close to valid range
01569       if (orblistcenter > (molmaxorb-10))
01570         orblistcenter = molmaxorb-10;
01571       if (orblistcenter < 10)
01572         orblistcenter = 10;
01573 
01574       int maxorb = orblistcenter+10;
01575       int minorb = orblistcenter-10;
01576 
01577       // clamp range of orbital list precisely
01578       if (minorb < 1) 
01579         minorb=1;
01580       if (maxorb > molmaxorb) 
01581         maxorb=molmaxorb;
01582 
01583       // set class minimum chooser index info
01584       orbitalminindex = minorb - 1; // use 0-based indexing here
01585 
01586 #if 0
01587       // XXX not ready for prime time yet.
01588       // query the HOMO for the zeroth timestep and use it when listing
01589       // the orbitals, as the current implementation doesn't sort the
01590       // orbitals differently for different timesteps, so the HOMO index
01591       // for timestep zero will also be correct for the others.
01592       int HOMO = -1; // init with sentinel so it's only listed if we've got it
01593       Timestep *ts = m->get_frame(0); // timestep zero
01594       if (ts != NULL && ts->qm_timestep != NULL &&
01595           ts->qm_timestep->get_num_wavef()) {
01596         int tmp = ts->qm_timestep->get_homo(waveid);
01597         HOMO = ts->qm_timestep->get_orbital_id_from_index(waveid, tmp);
01598 printf("HOMO: %d\n", HOMO);
01599       } else {
01600 printf("HOMO not set: %d\n", HOMO);
01601       }
01602 #endif
01603 
01604       // regenerate list of orbitals (1-based)
01605       // returned GUI indices are 0-based
01606       int j;
01607       for (j=minorb; j<=maxorb; j++) {
01608 #if 1
01609         sprintf(namestr, "%3d", j);
01610 #else
01611         if (HOMO == j)
01612           sprintf(namestr, "%3d (HOMO)", j); // tag HOMO specially
01613         else
01614           sprintf(namestr, "%3d", j); // others currently just list their ID
01615 #endif
01616 
01617         dataset_append(namestr, -0.1, 0.1);
01618       }
01619       for (j=minorb; j<=maxorb; j++) {
01620         // check whether this orbital exists or not
01621         // GUI indices are 0-based
01622         if (m->qm_data->has_orbital(waveid, j))
01623           orbitalindex->mode(j-1, 0); // enable in the GUI
01624         else 
01625           orbitalindex->mode(j-1, FL_MENU_INACTIVE); // disable in the GUI
01626       }
01627 
01628       orbitalindex->value(0);
01629       orbitalindex->activate();
01630     } else {
01631       orbitalindex->value(0);
01632       orbitalindex->activate();
01633     }
01634   }
01635 
01636 
01637 private:
01638   Fl_Slider *isovalue;
01639   Fl_Float_Input *isoinput;
01640   Fl_Float_Input *isomininput, *isomaxinput;
01641   Fl_Counter *resolution;
01642   Fl_Counter *thickness;
01643   RepChoice *method;
01644   Fl_Callback *parentcb;
01645   void *parentdata;
01646   RepChoice *boundary;
01647   int gridstepsize;
01648   Fl_Counter *orbitallistcounter;
01649   int orbitalminindex;
01650 
01651   static void datasetchanged_cb(Fl_Widget *w, void *v) {
01652     GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01653     if (self->minmaxlist.num() > 0) {
01654       minmax &m = self->minmaxlist[self->orbitalindex->value()];
01655       self->isovalue->range(m.minval, m.maxval);
01656     } else {
01657       self->isovalue->range(0, 1);
01658     }
01659     (self->parentcb)(w, self->parentdata);
01660   }
01661 
01662   static void inputcb(Fl_Widget *, void *v) {
01663     GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01664     char *endptr = NULL;
01665     const char *strval = self->isoinput->value();
01666     double val = strtod(strval, &endptr);
01667     if (endptr != strval) {
01668       // valid conversion performed
01669       self->isovalue->value(val);
01670       (self->parentcb)(self->isovalue, self->parentdata);
01671     }
01672   }
01673   
01674   static void minmaxinputcb(Fl_Widget *, void *v) {
01675     GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01676     // parse values in input fields
01677     char *endptr = NULL;
01678     const char *minstrval = self->isomininput->value();
01679     double minval = strtod(minstrval, &endptr);
01680     if (endptr == minstrval) return; // invalid
01681     const char *maxstrval = self->isomaxinput->value();
01682     double maxval = strtod(maxstrval, &endptr);
01683     if (endptr == maxstrval) return; // invalid
01684 
01685     // fields are valid; update cached minmax
01686     if (self->minmaxlist.num() > 0) {
01687       minmax &m = self->minmaxlist[self->orbitalindex->value()];
01688       m.minval = minval;
01689       m.maxval = maxval;
01690     }
01691 
01692     // update the slider itself.  If we made the value change, trigger
01693     // appropriate callbacks.
01694     self->isovalue->range(minval, maxval);
01695     if (self->isovalue->value() < minval) {
01696       self->isovalue->value(minval);
01697       slidercb(NULL, v);
01698     } else if (self->isovalue->value() > maxval) {
01699       self->isovalue->value(maxval);
01700       slidercb(NULL, v);
01701     } else {
01702       self->setInputFromSlider();
01703     }
01704   }
01705 
01706   void setInputFromSlider() {
01707     char buf[128];
01708     sprintf(buf, "%8g", (float)isovalue->value()); 
01709     isoinput->value(buf);
01710     sprintf(buf, "%8g", (float)isovalue->minimum());
01711     isomininput->value(buf);
01712     sprintf(buf, "%8g", (float)isovalue->maximum());
01713     isomaxinput->value(buf);
01714   }
01715 
01716   static void slidercb(Fl_Widget *, void *v) {
01717     GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01718     self->setInputFromSlider();
01719     (self->parentcb)(self->isovalue, self->parentdata);
01720   }
01721 
01722 protected:
01723   void do_dataset_clear() { 
01724     isovalue->deactivate();
01725     isoinput->deactivate();
01726     boundary->deactivate();
01727     method->deactivate();
01728     resolution->deactivate();
01729     thickness->deactivate();
01730     orbitallistcounter->deactivate();
01731   }
01732   void do_dataset_append(const char *, double min, double max) { 
01733     isovalue->activate();
01734     isoinput->activate();
01735     boundary->activate();
01736     method->activate();
01737     resolution->activate();
01738     thickness->activate();
01739     orbitallistcounter->activate();
01740     isovalue->range(min,max);
01741     setInputFromSlider();
01742   }
01743   void do_reset() {
01744     set_grid_stepsize(1);           
01745     resolution->value(0.075);       
01746     thickness->value(1);            
01747     orbitallistcounter->minimum(1); 
01748     orbitallistcounter->value(10);  
01749     orbitallistcounter->step(10);
01750     orbitallistcounter->lstep(50);
01751     method->value(0);               
01752     boundary->value(0);             
01753     wavefnctype->value(0);          
01754     wavefncspin->value(0);          
01755     wavefncexcitation->value(0);    
01756     orbitalindex->value(0);         
01757     isovalue->value(0.05);          
01758 
01759     // regenerate GUI selectors
01760     regen_wavefunctypes();
01761     regen_orbitallist();
01762   }
01763 
01764 public:
01765   GraphicsFltkRepOrbital(Fl_Callback *cb, void *v) {
01766     parentcb = cb;
01767     parentdata = v;
01768     gridstepsize = 1;
01769     orbitalminindex = 0;
01770 
01771     int gx = x();
01772     int gy = y();
01773 
01774     // The order of wavefunction type indexes is hard-coded and cannot 
01775     // be changed safely without introducing extra mapping logic
01776     wavefnctype = new RepChoice(gx+170, gy+30, "Wavefunction Type");
01777     wavefnctype->add("Canonical");
01778     wavefnctype->add("GVB geminal pairs");
01779     wavefnctype->add("MCSCF natural");
01780     wavefnctype->add("MCSCF optimized");
01781     wavefnctype->add("CI natural");
01782     wavefnctype->add("Localized");
01783     wavefnctype->add("Other");
01784     wavefnctype->callback(cb, v);
01785 
01786     wavefncspin = new RepChoiceSmall(gx+65, gy+60, "Spin");
01787     wavefncspin->add("Alpha");
01788     wavefncspin->add("Beta");
01789     wavefncspin->callback(cb, v);
01790 
01791     wavefncexcitation = new RepChoiceSmall(gx+65, gy+90, "Excitation");
01792     int i;
01793     for (i=0; i<11; i++) {
01794       char excitationstr[64];
01795       sprintf(excitationstr, "%d", i);
01796       wavefncexcitation->add(excitationstr);
01797     }
01798     wavefncexcitation->callback(cb, v);
01799 
01800     gy+=60;
01801 
01802     orbitallistcounter= new StepCounter(gx+200,gy, "OrbList");
01803     orbitallistcounter->callback(cb, v);
01804     orbitalindex = new RepChoiceSmall(gx+210, gy+30, "Orbital");
01805     orbitalindex->callback(cb, v);
01806 
01807     resolution= new GridResCounter(gx+170,gy+150, "Grid Spacing");
01808     resolution->callback(cb, v);
01809     thickness= new StepCounter(gx+40,gy+120, "Size");
01810     thickness->callback(cb, v);
01811     method = new RepChoice(gx+170,gy+90,"Draw");
01812     method->add("Solid Surface");
01813     method->add("Wireframe");
01814     method->add("Points");
01815     method->add("Shaded Points");
01816     method->callback(cb, v);
01817     boundary = new RepChoice(gx+170, gy+120, "Show");
01818     boundary->add("Isosurface");
01819     boundary->add("Box");
01820     boundary->add("Box+Isosurface");
01821     boundary->callback(cb, v); 
01822     isovalue = new Fl_Slider(gx+150,gy+60, 140, CTRHEIGHT, "");
01823     isovalue->type(FL_HOR_SLIDER);
01824     isovalue->color(VMDMENU_SLIDER_BG);
01825     isovalue->when(FL_WHEN_CHANGED);
01826     isovalue->callback(slidercb, this); 
01827     isoinput = new Fl_Float_Input(gx+80, gy+60, 70, CTRHEIGHT, "Isovalue");
01828     isoinput->when(FL_WHEN_ENTER_KEY);
01829     isoinput->selection_color(VMDMENU_SLIDER_SEL);
01830     isoinput->callback(inputcb, this);
01831     isovalue->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS);
01832 
01833     isomininput = new Fl_Float_Input(gx+40, gy+90, 45, CTRHEIGHT, "Range");
01834     isomininput->when(FL_WHEN_ENTER_KEY);
01835     isomininput->selection_color(VMDMENU_VALUE_SEL);
01836     isomininput->callback(minmaxinputcb, this);
01837     isomaxinput = new Fl_Float_Input(gx+85, gy+90, 45, CTRHEIGHT);
01838     isomaxinput->when(FL_WHEN_ENTER_KEY);
01839     isomaxinput->selection_color(VMDMENU_VALUE_SEL);
01840     isomaxinput->callback(minmaxinputcb, this);
01841 
01842     Fl_Group::end();
01843   }
01844   const char *repcmd() {
01845     sprintf(cmdbuf, "Orbital %f %d %d %d %.3f %d %d %d %d %d", 
01846             (float) isovalue->value(), 
01847             (int) (orbitalindex->value() + orbitalminindex + 1), // 1-based
01848             (int) boundary->value(), 
01849             (int) method->value(), 
01850             (float) resolution->value(),
01851             (int) thickness->value(),
01852             (int) wavefnctype->value(), 
01853             (int) wavefncspin->value(), 
01854             (int) wavefncexcitation->value(),
01855             gridstepsize);
01856     return cmdbuf;
01857   }
01858   void set_values(AtomRep *rep) {
01859     int oldtype = wavefnctype->value();
01860     int oldspin = wavefncspin->value();
01861     int oldexcitation = wavefncexcitation->value();
01862 
01863     int newtype = (int) rep->get_data(AtomRep::WAVEFNCTYPE);
01864     int newspin = (int) rep->get_data(AtomRep::WAVEFNCSPIN);
01865     int newexcitation = (int) rep->get_data(AtomRep::WAVEFNCEXCITATION);
01866   
01867     // Only regenerate the orbital list when required, otherwise
01868     // the updates interfere with the isovalue slider operation.
01869     if (oldtype != newtype || oldspin != newspin || 
01870         oldexcitation != newexcitation) {
01871       wavefnctype->setvalue(newtype);
01872       wavefncspin->setvalue(newspin);
01873 
01874       if (oldtype != newtype) {
01875         // regenerate the excitation chooser contents based on the
01876         // currently selected wavefunction type
01877         regen_excitationlist();
01878       } 
01879       wavefncexcitation->setvalue(newexcitation);
01880     }
01881 
01882     // regenerate the orbital index list if the wavefunction has
01883     // changed, or if a text command has gone beyond the range of
01884     // the existing orbital list.
01885     int oldorbidx = orbitalindex->value() + orbitalminindex + 1; // 1-based
01886     int neworbidx = (int)rep->get_data(AtomRep::SPHERERES);
01887     if (oldtype != newtype || oldspin != newspin || 
01888         oldexcitation != newexcitation ||
01889         abs(neworbidx-oldorbidx) > 10) {
01890       // regenerate the orbital chooser contents based on the
01891       // currently selected wavefunction type, spin, and excitation
01892       regen_orbitallist(neworbidx);
01893     }
01894     orbitalindex->setvalue(neworbidx - orbitalminindex - 1); // 0-based
01895 
01896     // minmax needs to update whenever dataset is changed or 
01897     // the selected rep is switched
01898     if (minmaxlist.num() > 0) {
01899       minmax &m = minmaxlist[orbitalindex->value()]; 
01900       isovalue->range(m.minval, m.maxval);
01901     } else {
01902       isovalue->range(0, 1);
01903     }
01904     isovalue->value(rep->get_data(AtomRep::SPHERERAD));
01905     method->setvalue((int)rep->get_data(AtomRep::BONDRES));
01906     boundary->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS));
01907     resolution->value(rep->get_data(AtomRep::GRIDSPACING));
01908     thickness->value(rep->get_data(AtomRep::ISOLINETHICKNESS));
01909     set_grid_stepsize((int) rep->get_data(AtomRep::ISOSTEPSIZE));
01910     setInputFromSlider();
01911   }
01912   void set_grid_stepsize(int step) {
01913     if (step < 1)
01914       step=1;
01915 
01916     gridstepsize = step;
01917   }
01918 };
01919 
01920  
01921 
01922 
01924 class GraphicsFltkRepFieldLines : public GraphicsFltkRepVolumetric {
01925 private:
01926   Fl_Counter *thickness;
01927   Fl_Value_Slider *gradmag;
01928   Fl_Value_Slider *minlen;
01929   Fl_Value_Slider *maxlen;
01930 
01931 protected:
01932   void do_dataset_clear() {
01933     gradmag->deactivate();
01934     minlen->deactivate();
01935     maxlen->deactivate();
01936     thickness->deactivate();
01937   }
01938   void do_dataset_append(const char *, double, double) {
01939     gradmag->activate();
01940     minlen->activate();
01941     maxlen->activate();
01942     thickness->activate();
01943   }
01944   void do_reset() {
01945     gradmag->value(1.8);
01946     minlen->value(10);
01947     maxlen->value(50);
01948     thickness->value(1);
01949   }
01950 
01951 public:
01952   GraphicsFltkRepFieldLines(Fl_Callback *cb, void *v)
01953   : GraphicsFltkRepVolumetric(cb, v) {
01954     thickness = new ResolutionCounter(x()+20, y()+30, "Size");
01955     thickness->callback(cb, v);
01956     gradmag = new IsoSlider(x()+80,  y()+60, "GradientMag");
01957     gradmag->callback(cb, v);
01958     minlen = new IsoSlider(x()+80,  y()+90, "Min Length");
01959     minlen->callback(cb, v);
01960     maxlen = new IsoSlider(x()+80, y()+120, "Max Length");
01961     maxlen->callback(cb, v);
01962     Fl_Group::end();
01963   }
01964   const char *repcmd() {
01965     if (dataset->size() > 0) {
01966       sprintf(cmdbuf, "FieldLines %f %f %f %f %f", 
01967         (float)dataset->value(), gradmag->value(), minlen->value(), maxlen->value(), thickness->value());
01968     } else {
01969       sprintf(cmdbuf, "FieldLines");
01970     }
01971     return cmdbuf;
01972   }
01973   void set_values(AtomRep *rep) {
01974     dataset->setvalue((int)rep->get_data(AtomRep::SPHERERES));
01975     gradmag->range(0.05, 25.0);
01976     gradmag->value(rep->get_data(AtomRep::SPHERERAD));
01977     minlen->range(1, 500.0);
01978     minlen->value(rep->get_data(AtomRep::BONDRAD));
01979     maxlen->range(1, 500.0);
01980     maxlen->value(rep->get_data(AtomRep::BONDRES));
01981     thickness->range(1, 10);
01982     thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
01983   }
01984 };
01985 
01986 

Generated on Tue May 21 01:46:17 2013 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002