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

GraphicsFltkReps.h

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

Generated on Wed Apr 17 02:45:44 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002