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