00001
00002
00003
00004
00005
00006
00007
00008 #include "Inform.h"
00009 #include "MainFltkMenu.h"
00010 #include "FL/Fl_Menu_Bar.H"
00011 #include "FL/Fl_Menu_Button.H"
00012 #include "FL/Fl_Menu_Item.H"
00013 #include "MolBrowser.h"
00014 #include "frame_selector.h"
00015 #include "FL/Fl_Radio_Button.H"
00016 #include "FL/Fl_Value_Slider.H"
00017 #include "FL/Fl_Int_Input.H"
00018 #include "TextEvent.h"
00019
00020 #if FL_MAJOR_VERSION <= 1
00021 #if FL_MINOR_VERSION < 1
00022 #include "FL/fl_file_chooser.H"
00023 #endif
00024 #endif
00025
00026
00027 #include "FL/forms.H"
00028 #include "VMDApp.h"
00029 #include "VMDMenu.h"
00030 #include "CommandQueue.h"
00031 #include "CmdMenu.h"
00032 #include "CmdAnimate.h"
00033 #include "Mouse.h"
00034 #include "TextEvent.h"
00035 #include "FPS.h"
00036 #include "Stage.h"
00037 #include "Axes.h"
00038 #include "Scene.h"
00039 #include "Animation.h"
00040 #include "DisplayDevice.h"
00041 #include "PickModeList.h"
00042
00043 #define EXT_MENU_NAME "Extensions"
00044
00045
00046
00047
00048 void MainFltkMenu::vmd_main_window_cb(Fl_Widget * w, void *) {
00049 MainFltkMenu *m = (MainFltkMenu *)w;
00050
00051 if (Fl::event_key() == FL_Escape) return;
00052
00053 if (fl_show_question("Really Quit?", 0))
00054 m->app->VMDexit("",0,0);
00055
00056
00057
00058 }
00059
00060
00061 static void menu_cb(Fl_Widget *w, void *v) {
00062 VMDApp *app = (VMDApp *)(w->user_data());
00063 const char *name = (const char *)v;
00064 app->menu_show(name, 0);
00065 app->menu_show(name, 1);
00066 }
00067
00068 static void loadnew_cb(Fl_Widget *w, void *v) {
00069 VMDApp *app = (VMDApp *)(w->user_data());
00070 app->menu_select_mol("files", -1);
00071 app->menu_show("files", 0);
00072 app->menu_show("files", 1);
00073 }
00074
00075 void MainFltkMenu::loadfile_cb(Fl_Widget *w, void *v) {
00076 VMDApp *app = (VMDApp *)(w->user_data());
00077 int selmol = ((MainFltkMenu *) v)->get_selected_molecule();
00078 app->menu_select_mol("files", selmol);
00079 app->menu_show("files", 0);
00080 app->menu_show("files", 1);
00081 }
00082
00083 void MainFltkMenu::savefile_cb(Fl_Widget *w, void *v) {
00084 VMDApp *app = (VMDApp *)(w->user_data());
00085 int selmol = ((MainFltkMenu *) v)->get_selected_molecule();
00086 app->menu_select_mol("save", selmol);
00087 app->menu_show("save", 0);
00088 app->menu_show("save", 1);
00089 }
00090
00091 static void render_cb(Fl_Widget *w, void *v) {
00092 VMDApp *app = (VMDApp *)(w->user_data());
00093 app->menu_show("render", 0);
00094 app->menu_show("render", 1);
00095 }
00096
00097 static void savestate_cb(Fl_Widget *w, void *) {
00098 VMDApp *app = (VMDApp *)(w->user_data());
00099 if (!app->save_state()) {
00100 fl_alert("Save State failed.");
00101 }
00102 }
00103
00104 static void logfile_cb(Fl_Widget *w, void *) {
00105 VMDApp *app = (VMDApp *)(w->user_data());
00106 char *file = app->vmd_choose_file(
00107 "Enter filename for VMD session log:",
00108 "*.vmd",
00109 "VMD files",
00110 1
00111 );
00112 if (!file) return;
00113 char *buf = new char[strlen(file)+13];
00114 sprintf(buf, "logfile {%s}", file);
00115 app->commandQueue->runcommand(new TclEvalEvent(buf));
00116 delete [] buf;
00117 delete [] file;
00118 }
00119
00120 static void logconsole_cb(Fl_Widget *w, void *) {
00121 VMDApp *app = (VMDApp *)(w->user_data());
00122 const char *buf = "logfile console";
00123 app->commandQueue->runcommand(new TclEvalEvent(buf));
00124 }
00125
00126 static void logoff_cb(Fl_Widget *w, void *) {
00127 VMDApp *app = (VMDApp *)(w->user_data());
00128 const char *buf = "logfile off";
00129 app->commandQueue->runcommand(new TclEvalEvent(buf));
00130 }
00131
00132 static void quit_cb(Fl_Widget *w, void *) {
00133 VMDApp *app = (VMDApp *)(w->user_data());
00134 if (fl_show_question("Really Quit?", 0))
00135 app->VMDexit("",0,0);
00136 }
00137
00138 static void aa_cb(Fl_Widget *w, void *) {
00139 VMDApp *app = (VMDApp *)(w->user_data());
00140 app->display_set_aa(
00141 ((Fl_Menu_ *)w)->mvalue()->value());
00142 }
00143
00144 static void depthcue_cb(Fl_Widget *w, void *) {
00145 VMDApp *app = (VMDApp *)(w->user_data());
00146 app->display_set_depthcue(
00147 ((Fl_Menu_ *)w)->mvalue()->value());
00148 }
00149
00150 static void culling_cb(Fl_Widget *w, void *) {
00151 VMDApp *app = (VMDApp *)(w->user_data());
00152 app->display_set_culling(
00153 ((Fl_Menu_ *)w)->mvalue()->value());
00154 }
00155
00156 static void fps_cb(Fl_Widget *w, void *) {
00157 VMDApp *app = (VMDApp *)(w->user_data());
00158 app->display_set_fps(
00159 ((Fl_Menu_ *)w)->mvalue()->value());
00160 }
00161
00162 static void light_cb(Fl_Widget *w, void *v) {
00163 VMDApp *app = (VMDApp *)(w->user_data());
00164 int *whichlight = (int *)v;
00165 int turnon = ((Fl_Menu_ *)w)->mvalue()->value();
00166 app->light_on(*whichlight, turnon);
00167 }
00168
00169 static void stage_cb(Fl_Widget *w, void *v) {
00170 Fl_Menu_ *m = (Fl_Menu_ *)w;
00171 VMDApp *app = (VMDApp *)v;
00172 app->stage_set_location(m->text());
00173 }
00174
00175 static void axes_cb(Fl_Widget *w, void *v) {
00176 Fl_Menu_ *m = (Fl_Menu_ *)w;
00177 VMDApp *app = (VMDApp *)v;
00178 app->axes_set_location(m->text());
00179 }
00180
00181 static void backgroundmode_cb(Fl_Widget *w, void *v) {
00182 Fl_Menu_ *m = (Fl_Menu_ *)w;
00183 VMDApp *app = (VMDApp *)(w->user_data());
00184 if (!strcmp("Gradient", m->text())) {
00185 app->display_set_background_mode(1);
00186 } else {
00187 app->display_set_background_mode(0);
00188 }
00189 }
00190
00191 static void stereo_cb(Fl_Widget *w, void *v) {
00192 Fl_Menu_ *m = (Fl_Menu_ *)w;
00193 VMDApp *app = (VMDApp *)v;
00194 app->display_set_stereo(m->text());
00195 }
00196
00197 static void stereoswap_cb(Fl_Widget *w, void *v) {
00198 Fl_Menu_ *m = (Fl_Menu_ *)w;
00199 VMDApp *app = (VMDApp *)v;
00200 if (!strcmp("On", m->text())) {
00201 app->display_set_stereo_swap(1);
00202 } else {
00203 app->display_set_stereo_swap(0);
00204 }
00205 }
00206
00207 static void cachemode_cb(Fl_Widget *w, void *v) {
00208 Fl_Menu_ *m = (Fl_Menu_ *)w;
00209 VMDApp *app = (VMDApp *)v;
00210 app->display_set_cachemode(m->text());
00211 }
00212
00213 static void rendermode_cb(Fl_Widget *w, void *v) {
00214 Fl_Menu_ *m = (Fl_Menu_ *)w;
00215 VMDApp *app = (VMDApp *)v;
00216 app->display_set_rendermode(m->text());
00217 }
00218
00219 static void resetview_cb(Fl_Widget *w, void *) {
00220 VMDApp *app = (VMDApp *)(w->user_data());
00221 app->scene_stoprotation();
00222 app->scene_resetview();
00223 }
00224
00225 static void stoprotation_cb(Fl_Widget *w, void *) {
00226 VMDApp *app = (VMDApp *)(w->user_data());
00227 app->scene_stoprotation();
00228 }
00229
00230 static void proj_cb(Fl_Widget *w, void *) {
00231 Fl_Menu_ *m = (Fl_Menu_ *)w;
00232 VMDApp *app = (VMDApp *)(w->user_data());
00233 app->display_set_projection(m->text());
00234 }
00235
00236 static void mouse_cb(Fl_Widget *w, void *v) {
00237 VMDApp *app = (VMDApp *)(w->user_data());
00238 app->mouse_set_mode(*((int *)v), -1);
00239 }
00240
00241 static void move_light_cb(Fl_Widget *w, void *v) {
00242 VMDApp *app = (VMDApp *)(w->user_data());
00243 app->mouse_set_mode(Mouse::LIGHT, *((int *)v) );
00244 }
00245
00246 static void help_cb(Fl_Widget *w, void *v) {
00247 VMDApp *app = (VMDApp *)(w->user_data());
00248 app->commandQueue->runcommand(new HelpEvent((const char*)v));
00249 }
00250
00251
00252 static void mol_top_cb(Fl_Widget *w, void *v) {
00253 VMDApp *app = (VMDApp *)w->user_data();
00254 MolBrowser *browser = (MolBrowser *)v;
00255 for (int i=0; i<browser->size(); i++) {
00256 if (browser->selected(i+1)) {
00257 app->molecule_make_top(app->molecule_id(i));
00258 break;
00259 }
00260 }
00261 }
00262
00263 static void mol_active_cb(Fl_Widget *w, void *v) {
00264 VMDApp *app = (VMDApp *)w->user_data();
00265 MolBrowser *browser = (MolBrowser *)v;
00266 for (int i=0; i<browser->size(); i++) {
00267 if (browser->selected(i+1)) {
00268 int molid = app->molecule_id(i);
00269 app->molecule_activate(molid, !app->molecule_is_active(molid));
00270 }
00271 }
00272 }
00273
00274 static void mol_displayed_cb(Fl_Widget *w, void *v) {
00275 VMDApp *app = (VMDApp *)w->user_data();
00276 MolBrowser *browser = (MolBrowser *)v;
00277 for (int i=0; i<browser->size(); i++) {
00278 if (browser->selected(i+1)) {
00279 int molid = app->molecule_id(i);
00280 app->molecule_display(molid, !app->molecule_is_displayed(molid));
00281 }
00282 }
00283 }
00284
00285 static void mol_fixed_cb(Fl_Widget *w, void *v) {
00286 VMDApp *app = (VMDApp *)w->user_data();
00287 MolBrowser *browser = (MolBrowser *)v;
00288 for (int i=0; i<browser->size(); i++) {
00289 if (browser->selected(i+1)) {
00290 int molid = app->molecule_id(i);
00291 app->molecule_fix(molid, !app->molecule_is_fixed(molid));
00292 }
00293 }
00294 }
00295
00296
00297 static void mol_rename_cb(Fl_Widget *w, void *v) {
00298 VMDApp *app = (VMDApp *)w->user_data();
00299 MolBrowser *browser = (MolBrowser *)v;
00300 int molid=-1;
00301 for (int i=0; i<browser->size(); i++)
00302 if (browser->selected(i+1)) {
00303 molid = app->molecule_id(i);
00304 break;
00305 }
00306 if (molid < 0) return;
00307
00308
00309 const char *oldname = app->molecule_name(molid);
00310 const char *newname = fl_input("Enter a new name for molecule %d:",
00311 oldname, molid);
00312 if (newname) app->molecule_rename(molid, newname);
00313 }
00314
00315
00316 static void mol_cancel_cb(Fl_Widget *w, void *v) {
00317 VMDApp *app = (VMDApp *)w->user_data();
00318 MolBrowser *browser = (MolBrowser *)v;
00319 for (int i=0; i<browser->size(); i++) {
00320 if (browser->selected(i+1)) {
00321 int molid = app->molecule_id(i);
00322 app->molecule_cancel_io(molid);
00323 }
00324 }
00325 }
00326
00327 static void mol_delete_ts_cb(Fl_Widget *w, void *v) {
00328 VMDApp *app = (VMDApp *)w->user_data();
00329 MolBrowser *browser = (MolBrowser *)v;
00330 int molid=-1;
00331 for (int i=0; i<browser->size(); i++)
00332 if (browser->selected(i+1)) {
00333 molid = app->molecule_id(i);
00334 break;
00335 }
00336 if (molid < 0) return;
00337
00338
00339 int numframes = app->molecule_numframes(molid);
00340 if (!numframes) {
00341 fl_alert("Molecule %d has no frames to delete!", molid);
00342 } else {
00343 const char *molname = app->molecule_name(molid);
00344 int first=0, last=numframes-1, stride=0;
00345 int ok = frame_delete_selector(molname, last, &first, &last, &stride);
00346 if (ok) app->molecule_deleteframes(molid, first, last, stride);
00347 }
00348 }
00349
00350 static void mol_delete_cb(Fl_Widget *w, void *v) {
00351 VMDApp *app = (VMDApp *)w->user_data();
00352 MolBrowser *browser = (MolBrowser *)v;
00353 ResizeArray<int> idlist;
00354 for (int i=0; i<browser->size(); i++) {
00355 if (browser->selected(i+1)) {
00356 idlist.append(app->molecule_id(i));
00357 }
00358 }
00359 for (int j=0; j<idlist.num(); j++)
00360 app->molecule_delete(idlist[j]);
00361 }
00362
00363 static void loadstate_cb(Fl_Widget *w, void *v) {
00364 VMDApp *app = (VMDApp *)w->user_data();
00365 char *file = app->vmd_choose_file(
00366 "Enter filename containing VMD saved state:",
00367 "*.vmd",
00368 "VMD files",
00369 0
00370 );
00371 if (!file) return;
00372 char *buf = new char[strlen(file)+10];
00373 sprintf(buf, "play {%s}", file);
00374 app->commandQueue->runcommand(new TclEvalEvent(buf));
00375 delete [] buf;
00376 delete [] file;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385 static const MenuBehavior file_menu_behavior[] = {
00386 MENU_ALWAYS_ON,
00387 MENU_NEED_UNIQUE_SEL,
00388 MENU_NEED_UNIQUE_SEL,
00389 MENU_ALWAYS_ON,
00390 MENU_ALWAYS_ON,
00391 MENU_ALWAYS_ON,
00392 MENU_ALWAYS_ON,
00393 MENU_ALWAYS_ON,
00394 MENU_ALWAYS_ON,
00395 MENU_ALWAYS_ON
00396 };
00397
00398
00399
00400 static const Fl_Menu_Item init_file_menuitems[] = {
00401 {"New Molecule...", 0, loadnew_cb},
00402 {"Load Data Into Molecule...", 0, NULL },
00403 {"Save Coordinates...", 0, NULL , NULL, FL_MENU_DIVIDER},
00404 {"Load Visualization State...", 0, loadstate_cb},
00405 {"Save Visualization State...", 0, savestate_cb, NULL, FL_MENU_DIVIDER},
00406 {"Log Tcl Commands to Console", 0, logconsole_cb, NULL},
00407 {"Log Tcl Commands to File...", 0, logfile_cb, NULL},
00408 {"Turn Off Logging", 0, logoff_cb, NULL, FL_MENU_DIVIDER},
00409 {"Render...", 0, render_cb, NULL, FL_MENU_DIVIDER},
00410 {"Quit", 0, quit_cb},
00411 {NULL}
00412 };
00413
00414 static const MenuBehavior molecule_menu_behavior[] = {
00415 MENU_NEED_UNIQUE_SEL,
00416 MENU_NEED_SEL,
00417 MENU_NEED_SEL,
00418 MENU_NEED_SEL,
00419 MENU_NEED_UNIQUE_SEL,
00420 MENU_NEED_UNIQUE_SEL,
00421 MENU_NEED_SEL,
00422 MENU_NEED_SEL
00423 };
00424
00425
00426
00427 static const Fl_Menu_Item init_molecule_menuitems[] = {
00428 {"Make Top", 0, mol_top_cb, },
00429 {"Toggle Active", 0, mol_active_cb, },
00430 {"Toggle Displayed", 0, mol_displayed_cb, },
00431 {"Toggle Fixed", 0, mol_fixed_cb, NULL, FL_MENU_DIVIDER},
00432 {"Rename...", 0, mol_rename_cb },
00433 {"Delete Frames...", 0, mol_delete_ts_cb },
00434 {"Abort File I/O", 0, mol_cancel_cb, },
00435 {"Delete Molecule", 0, mol_delete_cb },
00436 {NULL}
00437 };
00438
00439
00440 static const MenuBehavior browserpopup_menu_behavior[] = {
00441 MENU_ALWAYS_ON,
00442 MENU_NEED_UNIQUE_SEL,
00443 MENU_NEED_UNIQUE_SEL,
00444 MENU_NEED_UNIQUE_SEL,
00445 MENU_NEED_UNIQUE_SEL,
00446 MENU_NEED_SEL,
00447 MENU_NEED_SEL
00448 };
00449
00450
00451
00452 static const Fl_Menu_Item init_browserpopup_menuitems[] = {
00453
00454 {"New Molecule...", 0, loadnew_cb },
00455 {"Load Data Into Molecule...", 0, NULL },
00456 {"Save Coordinates...", 0, NULL , NULL, FL_MENU_DIVIDER},
00457
00458 {"Rename...", 0, mol_rename_cb },
00459 {"Delete Frames...", 0, mol_delete_ts_cb },
00460 {"Abort File I/O", 0, mol_cancel_cb, },
00461 {"Delete Molecule", 0, mol_delete_cb },
00462 {NULL}
00463 };
00464
00465 static const Fl_Menu_Item graphics_menuitems[] = {
00466 {"Representations...", 0, menu_cb, (void *)"graphics"},
00467 {"Colors...", 0, menu_cb, (void *)"color"},
00468 {"Materials...", 0, menu_cb, (void *)"material"},
00469 {"Labels...", 0, menu_cb, (void *)"labels", FL_MENU_DIVIDER},
00470 {"Tools...", 0, menu_cb, (void *)"tool"},
00471 {0}
00472 };
00473
00474 static int cbdata[] = {
00475 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22
00476 };
00477
00478 static const Fl_Menu_Item init_display_menuitems[] = {
00479 {"Reset View", '=', resetview_cb},
00480 {"Stop Rotation", 0, stoprotation_cb, NULL, FL_MENU_DIVIDER},
00481 {"Perspective", 0, proj_cb, NULL, FL_MENU_RADIO },
00482 {"Orthographic", 0, proj_cb, NULL, FL_MENU_RADIO | FL_MENU_DIVIDER},
00483 {"Antialiasing", 0, aa_cb, NULL, FL_MENU_TOGGLE | FL_MENU_INACTIVE},
00484 {"Depth Cueing", 0, depthcue_cb, NULL, FL_MENU_TOGGLE | FL_MENU_INACTIVE},
00485 {"Culling", 0, culling_cb, NULL, FL_MENU_TOGGLE | FL_MENU_INACTIVE},
00486 {"FPS Indicator", 0, fps_cb, NULL, FL_MENU_TOGGLE | FL_MENU_DIVIDER},
00487 {"Light 0", 0, light_cb, cbdata+0, FL_MENU_TOGGLE},
00488 {"Light 1", 0, light_cb, cbdata+1, FL_MENU_TOGGLE},
00489 {"Light 2", 0, light_cb, cbdata+2, FL_MENU_TOGGLE},
00490 {"Light 3", 0, light_cb, cbdata+3, FL_MENU_TOGGLE | FL_MENU_DIVIDER},
00491 {"Axes", 0, NULL, NULL, FL_SUBMENU_POINTER},
00492 {"Background", 0, backgroundmode_cb, NULL, FL_SUBMENU_POINTER},
00493 {"Stage", 0, NULL, NULL, FL_SUBMENU_POINTER | FL_MENU_DIVIDER},
00494 {"Stereo", 0, NULL, NULL, FL_SUBMENU_POINTER},
00495 {"Stereo Eye Swap", 0, NULL, NULL, FL_SUBMENU_POINTER | FL_MENU_DIVIDER},
00496 {"Cachemode", 0, NULL, NULL, FL_SUBMENU_POINTER},
00497 {"Rendermode", 0, NULL, NULL, FL_SUBMENU_POINTER | FL_MENU_DIVIDER},
00498 {"Display Settings...", 0, menu_cb, (void *)"display"},
00499 {0}
00500 };
00501
00502
00503 static void cb_cb(Fl_Widget *w, void *v);
00504
00505
00506
00507
00508 static const Fl_Menu_Item init_mouse_menuitems[] = {
00509 {"Rotate Mode", 'r', mouse_cb, cbdata+Mouse::ROTATION,FL_MENU_RADIO|FL_MENU_VALUE},
00510 {"Translate Mode",'t',mouse_cb,cbdata+Mouse::TRANSLATION,FL_MENU_RADIO},
00511 {"Scale Mode", 's', mouse_cb, cbdata+Mouse::SCALING, FL_MENU_RADIO | FL_MENU_DIVIDER},
00512 {"Center", 'c', mouse_cb, cbdata+Mouse::CENTER, FL_MENU_RADIO},
00513 {"Query", '0', mouse_cb, cbdata+Mouse::QUERY, FL_MENU_RADIO},
00514
00515 {"Label",0,cb_cb,0, FL_SUBMENU | FL_MENU_TOGGLE },
00516 {"Atoms", '1', mouse_cb, cbdata+Mouse::LABELATOM, FL_MENU_RADIO},
00517 {"Bonds", '2', mouse_cb, cbdata+Mouse::LABELBOND, FL_MENU_RADIO},
00518 {"Angles", '3', mouse_cb, cbdata+Mouse::LABELANGLE, FL_MENU_RADIO},
00519 {"Dihedrals", '4', mouse_cb, cbdata+Mouse::LABELDIHEDRAL, FL_MENU_RADIO},
00520 {0},
00521 {"Move",0,cb_cb,0, FL_SUBMENU | FL_MENU_TOGGLE},
00522 {"Atom", '5', mouse_cb, cbdata+Mouse::MOVEATOM, FL_MENU_RADIO},
00523 {"Residue", '6', mouse_cb, cbdata+Mouse::MOVERES, FL_MENU_RADIO},
00524 {"Fragment", '7', mouse_cb, cbdata+Mouse::MOVEFRAG, FL_MENU_RADIO},
00525 {"Molecule", '8', mouse_cb, cbdata+Mouse::MOVEMOL, FL_MENU_RADIO},
00526 {"Rep", '9', mouse_cb, cbdata+Mouse::MOVEREP, FL_MENU_RADIO},
00527 {0},
00528 {"Force",0,cb_cb,0, FL_SUBMENU | FL_MENU_TOGGLE},
00529 {"Atom", '%', mouse_cb, cbdata+Mouse::FORCEATOM, FL_MENU_RADIO},
00530 {"Residue", '^', mouse_cb, cbdata+Mouse::FORCERES, FL_MENU_RADIO},
00531 {"Fragment", '&', mouse_cb, cbdata+Mouse::FORCEFRAG, FL_MENU_RADIO},
00532 {0},
00533 {"Move Light", 0,cb_cb,0, FL_SUBMENU | FL_MENU_TOGGLE},
00534 {"0", 0, move_light_cb, cbdata+0, FL_MENU_RADIO},
00535 {"1", 0, move_light_cb, cbdata+1, FL_MENU_RADIO},
00536 {"2", 0, move_light_cb, cbdata+2, FL_MENU_RADIO},
00537 {"3", 0, move_light_cb, cbdata+3, FL_MENU_RADIO},
00538 {0},
00539 {"Add/Remove Bonds", 0, mouse_cb, cbdata+Mouse::ADDBOND, FL_MENU_RADIO},
00540 {"Pick", 'p', mouse_cb, cbdata+Mouse::PICK, FL_MENU_RADIO},
00541 {0}
00542 };
00543
00544 static const Fl_Menu_Item init_help_menuitems[] = {
00545 {"Quick Help", 0, help_cb, (void*) "quickhelp"},
00546 {"User's Guide", 0, help_cb, (void*) "userguide"},
00547 {"Tutorial", 0, help_cb, (void*) "tutorial", FL_MENU_DIVIDER},
00548 {"Homepage", 0, help_cb, (void*) "homepage"},
00549 {"FAQ", 0, help_cb, (void*) "faq"},
00550 {"Mailing List", 0, help_cb, (void*) "maillist"},
00551 {"Script Library", 0, help_cb, (void*) "scripts"},
00552 {"Plugin Library", 0, help_cb, (void*) "plugins", FL_MENU_DIVIDER},
00553 {"3D Renderers", 0, 0, 0, FL_SUBMENU},
00554 {"POV-Ray", 0, help_cb, (void*) "povray"},
00555 {"Radiance", 0, help_cb, (void*) "radiance"},
00556 {"Raster3D", 0, help_cb, (void*) "raster3D"},
00557 {"Rayshade", 0, help_cb, (void*) "rayshade"},
00558 {"Tachyon", 0, help_cb, (void*) "tachyon"},
00559 {"VRML", 0, help_cb, (void*) "vrml"},
00560 {0},
00561 {"Auxiliary Programs", 0, 0, 0, FL_SUBMENU},
00562 {"BioCoRE", 0, help_cb, (void*) "biocore"},
00563 {"MSMS", 0, help_cb, (void*) "msms"},
00564 {"NAMD", 0, help_cb, (void*) "namd"},
00565 {"Tcl/Tk", 0, help_cb, (void*) "tcl"},
00566 {"Python", 0, help_cb, (void*) "python"},
00567 {0},
00568 {0}
00569 };
00570
00571
00572
00573 static void cb_cb(Fl_Widget *w, void *v) {
00574 Fl_Menu_Item *titleitem = (Fl_Menu_Item*) ((Fl_Menu_ *)w)->mvalue();
00575 const Fl_Menu_Item *item;
00576 for (item = titleitem+1; item->label(); item++)
00577 if (item->value()) {
00578 titleitem->set();
00579 return;
00580 }
00581 titleitem->clear();
00582 }
00583
00584 void MainFltkMenu::frameslider_cb(Fl_Widget *w, void *v) {
00585 Fl_Valuator *val = (Fl_Valuator *)w;
00586 MainFltkMenu *self = (MainFltkMenu *)v;
00587
00588
00589 if (Fl::event_state(FL_BUTTON3)) {
00590 if (!Fl::event_state()) {
00591 self->app->animation_set_frame((int)val->value());
00592 } else {
00593
00594 char buf[10];
00595 sprintf(buf, "%d", (int)val->value());
00596 self->curframe->value(buf);
00597 }
00598 } else {
00599 self->app->animation_set_frame((int)val->value());
00600 }
00601 }
00602
00603 static void curframe_cb(Fl_Widget *w, void *v) {
00604 Fl_Input *inp = (Fl_Input *)w;
00605 VMDApp *app = (VMDApp *)v;
00606 int val = atoi(inp->value());
00607 int max = app->molecule_numframes(app->molecule_top());
00608 if (val < 0) val = 0;
00609 if (val >= max) val = max-1;
00610 app->animation_set_frame(val);
00611 }
00612
00613 static void start_cb(Fl_Widget *, void *v) {
00614 VMDApp *app = (VMDApp *)v;
00615 app->animation_set_frame(-1);
00616 }
00617
00618 static void stop_cb(Fl_Widget *, void *v) {
00619 VMDApp *app = (VMDApp *)v;
00620 app->animation_set_frame(-2);
00621 }
00622
00623 static void prev_cb(Fl_Widget *, void *v) {
00624 VMDApp *app = (VMDApp *)v;
00625 app->animation_set_dir(Animation::ANIM_REVERSE1);
00626 }
00627
00628 static void next_cb(Fl_Widget *, void *v) {
00629 VMDApp *app = (VMDApp *)v;
00630 app->animation_set_dir(Animation::ANIM_FORWARD1);
00631 }
00632
00633 static void forward_cb(Fl_Widget *w, void *v) {
00634 Fl_Button *button = (Fl_Button *)w;
00635 VMDApp *app = (VMDApp *)v;
00636 if (button->value())
00637 app->animation_set_dir(Animation::ANIM_FORWARD);
00638 else
00639 app->animation_set_dir(Animation::ANIM_PAUSE);
00640 }
00641
00642 static void reverse_cb(Fl_Widget *w, void *v) {
00643 Fl_Button *button = (Fl_Button *)w;
00644 VMDApp *app = (VMDApp *)v;
00645 if (button->value())
00646 app->animation_set_dir(Animation::ANIM_REVERSE);
00647 else
00648 app->animation_set_dir(Animation::ANIM_PAUSE);
00649 }
00650
00651 static void style_cb(Fl_Widget *w, void *v) {
00652 Fl_Choice *choice = (Fl_Choice *)w;
00653 VMDApp *app = (VMDApp *)v;
00654 app->animation_set_style(choice->value());
00655 }
00656
00657 static void step_cb(Fl_Widget *w, void *v) {
00658 Fl_Counter *counter = (Fl_Counter *)w;
00659 VMDApp *app = (VMDApp *)v;
00660 app->animation_set_stride((int)counter->value());
00661 }
00662
00663 static void speed_cb(Fl_Widget *w, void *v) {
00664 Fl_Slider *slider = (Fl_Slider *)w;
00665 VMDApp *app = (VMDApp *)v;
00666 app->animation_set_speed((float) slider->value());
00667 }
00668
00669 void MainFltkMenu::zoom_cb(Fl_Widget *w, void *v) {
00670 Fl_Button *b = (Fl_Button *)w;
00671 MainFltkMenu *self = (MainFltkMenu *)v;
00672 int numframes = self->app->molecule_numframes(self->app->molecule_top());
00673 if (numframes < 1) return;
00674 double full_range = (double)numframes;
00675 if (b->value()) {
00676
00677 double pixel_range = 100;
00678 if (full_range > pixel_range) {
00679 double curval = self->frameslider->value();
00680 double curfrac = curval/full_range;
00681 self->frameslider->range(curval - pixel_range*curfrac,
00682 curval + pixel_range*(1.0-curfrac));
00683 self->frameslider->color(VMDMENU_SLIDER_BG, VMDMENU_SLIDER_FG);
00684 self->frameslider->redraw();
00685 }
00686 } else {
00687
00688 self->frameslider->range(0, full_range-1);
00689 self->frameslider->color(VMDMENU_SLIDER_BG, VMDMENU_SLIDER_FG);
00690 self->frameslider->redraw();
00691 }
00692 }
00693
00694 void MainFltkMenu::update_mousemode(Command *cmd) {
00695 int mode = ((CmdMouseMode *)cmd)->mouseMode;
00696 int setting = ((CmdMouseMode *)cmd)->mouseSetting;
00697
00698 Fl_Menu_Item *items = mouse_menuitems;
00699 int menulen = sizeof(init_mouse_menuitems)/sizeof(Fl_Menu_Item);
00700 for (int j=0; j<menulen; j++)
00701 items[j].clear();
00702
00703 switch(mode) {
00704 case Mouse::ROTATION: items[ 0].setonly(); break;
00705 case Mouse::TRANSLATION: items[ 1].setonly(); break;
00706 case Mouse::SCALING: items[ 2].setonly(); break;
00707 case Mouse::QUERY: items[ 4].setonly(); break;
00708 case Mouse::CENTER: items[ 3].setonly(); break;
00709 case Mouse::LABELATOM: items[ 6].setonly(); break;
00710 case Mouse::LABELBOND: items[ 7].setonly(); break;
00711 case Mouse::LABELANGLE: items[ 8].setonly(); break;
00712 case Mouse::LABELDIHEDRAL: items[ 9].setonly(); break;
00713 case Mouse::MOVEATOM: items[12].setonly(); break;
00714 case Mouse::MOVERES: items[13].setonly(); break;
00715 case Mouse::MOVEFRAG: items[14].setonly(); break;
00716 case Mouse::MOVEMOL: items[15].setonly(); break;
00717 case Mouse::MOVEREP: items[16].setonly(); break;
00718 case Mouse::FORCEATOM: items[19].setonly(); break;
00719 case Mouse::FORCERES: items[20].setonly(); break;
00720 case Mouse::FORCEFRAG: items[21].setonly(); break;
00721 case Mouse::ADDBOND: items[29].setonly(); break;
00722 case Mouse::PICK: items[30].setonly(); break;
00723 case Mouse::LIGHT:
00724 switch (setting) {
00725 case 0: items[24].setonly(); break;
00726 case 1: items[25].setonly(); break;
00727 case 2: items[26].setonly(); break;
00728 case 3: items[27].setonly(); break;
00729 }
00730 }
00731 if (mode >= Mouse::PICK) {
00732 items[0].setonly();
00733 if (mode == Mouse::LABELATOM || mode == Mouse::LABELBOND || \
00734 mode == Mouse::LABELANGLE || mode == Mouse::LABELDIHEDRAL)
00735 items[5].set();
00736 else if (mode == Mouse::MOVEATOM || mode == Mouse::MOVERES || \
00737 mode == Mouse::MOVEMOL || mode == Mouse::MOVEREP)
00738 items[11].set();
00739 else if (mode == Mouse::FORCEATOM || mode == Mouse::FORCERES || mode == Mouse::FORCEFRAG)
00740 items[18].set();
00741 } else if (mode == Mouse::LIGHT) {
00742 if (setting >= 0 && setting <= 3) items[23].set();
00743 }
00744 }
00745
00746 void MainFltkMenu::update_dispmode() {
00747 const char *projname = app->display->get_projection();
00748 for (int ii=2; ii<=3; ii++) {
00749 if (!strupcmp(projname, display_menuitems[ii].label())) {
00750 display_menuitems[ii].setonly();
00751 break;
00752 }
00753 }
00754 if (app->display->aa_enabled())
00755 display_menuitems[4].set();
00756 else
00757 display_menuitems[4].clear();
00758
00759 if (app->display->cueing_enabled())
00760 display_menuitems[5].set();
00761 else
00762 display_menuitems[5].clear();
00763
00764 if (app->display->culling_enabled())
00765 display_menuitems[6].set();
00766 else
00767 display_menuitems[6].clear();
00768
00769 if (app->fps->displayed())
00770 display_menuitems[7].set();
00771 else
00772 display_menuitems[7].clear();
00773
00774 for (int j=0; j<4; j++)
00775 if (app->scene->light_active(j))
00776 display_menuitems[8+j].set();
00777 else
00778 display_menuitems[8+j].clear();
00779
00780 axes_menuitems[app->axes->location()].setonly();
00781 backgroundmode_menuitems[app->scene->background_mode()].setonly();
00782 stage_menuitems[app->stage->location()].setonly();
00783 stereo_menuitems[app->display->stereo_mode()].setonly();
00784 stereoswap_menuitems[app->display->stereo_swap()].setonly();
00785 cachemode_menuitems[app->display->cache_mode()].setonly();
00786 rendermode_menuitems[app->display->render_mode()].setonly();
00787 }
00788
00789
00790
00791
00792 #if defined(__APPLE__)
00793 #define MAINFLTKMENUHEIGHT 205
00794 #else
00795 #define MAINFLTKMENUHEIGHT 190
00796 #endif
00797
00798 #if 0
00799
00800 #define MAINFLTKMENUWIDTH 450
00801 #else
00802
00803 #define MAINFLTKMENUWIDTH 470
00804 #endif
00805
00806
00807 MainFltkMenu::MainFltkMenu(VMDApp *vmdapp)
00808 : VMDFltkMenu("main", "VMD Main", vmdapp) {
00809
00810 size(MAINFLTKMENUWIDTH, MAINFLTKMENUHEIGHT);
00811
00812
00813 size_range(MAINFLTKMENUWIDTH, MAINFLTKMENUHEIGHT, MAINFLTKMENUWIDTH, 0);
00814
00815 command_wanted(Command::MOL_NEW);
00816 command_wanted(Command::MOL_DEL);
00817 command_wanted(Command::MOL_ACTIVE);
00818 command_wanted(Command::MOL_ON);
00819 command_wanted(Command::MOL_RENAME);
00820 command_wanted(Command::MOL_FIX);
00821 command_wanted(Command::MOL_TOP);
00822 command_wanted(Command::MOL_VOLUME);
00823 command_wanted(Command::ANIM_JUMP);
00824 command_wanted(Command::ANIM_NEW_FRAME);
00825 command_wanted(Command::ANIM_NEW_NUM_FRAMES);
00826 command_wanted(Command::MOUSE_MODE);
00827 command_wanted(Command::MENU_TK_ADD);
00828 command_wanted(Command::MENU_TK_REMOVE);
00829 command_wanted(Command::ANIM_STYLE);
00830 command_wanted(Command::ANIM_SKIP);
00831 command_wanted(Command::ANIM_SPEED);
00832 command_wanted(Command::ANIM_DIRECTION);
00833 command_wanted(Command::ANIM_JUMP);
00834
00835 command_wanted(Command::DISP_DEPTHCUE);
00836 command_wanted(Command::DISP_CULLING);
00837 command_wanted(Command::DISP_ANTIALIAS);
00838 command_wanted(Command::DISP_FPS);
00839 command_wanted(Command::DISP_LIGHT_ON);
00840 command_wanted(Command::CMD_STAGE);
00841 command_wanted(Command::CMD_AXES);
00842 command_wanted(Command::DISP_BACKGROUNDGRADIENT);
00843 command_wanted(Command::DISP_PROJ);
00844 command_wanted(Command::DISP_STEREO);
00845 command_wanted(Command::DISP_STEREOSWAP);
00846 command_wanted(Command::DISP_CACHEMODE);
00847 command_wanted(Command::DISP_RENDERMODE);
00848
00849 browser = new MolBrowser(vmdapp, this, 0, 60, MAINFLTKMENUWIDTH, 90);
00850
00851
00852
00853
00854
00855 int menulen;
00856 Fl_Menu_Item nullitem = {NULL};
00857
00858
00859 menulen = sizeof(init_file_menuitems)/sizeof(Fl_Menu_Item);
00860 file_menuitems = new Fl_Menu_Item[menulen];
00861 int j;
00862 for (j=0; j<menulen; j++) {
00863 file_menuitems[j] = init_file_menuitems[j];
00864 file_menuitems[j].user_data(this);
00865 }
00866
00867 file_menuitems[1].callback(loadfile_cb);
00868 file_menuitems[2].callback(savefile_cb);
00869
00870 menulen = sizeof(init_molecule_menuitems)/sizeof(Fl_Menu_Item);
00871 molecule_menuitems = new Fl_Menu_Item[menulen];
00872 for (j=0; j<menulen; j++) {
00873 molecule_menuitems[j] = init_molecule_menuitems[j];
00874 molecule_menuitems[j].user_data(browser);
00875 }
00876
00877
00878
00879 menulen = sizeof(init_browserpopup_menuitems)/sizeof(Fl_Menu_Item);
00880 browserpopup_menuitems = new Fl_Menu_Item[menulen];
00881 for (j=0; j<3; j++) {
00882 browserpopup_menuitems[j] = init_browserpopup_menuitems[j];
00883 browserpopup_menuitems[j].user_data(this);
00884 }
00885 for (j=3; j<menulen; j++) {
00886 browserpopup_menuitems[j] = init_browserpopup_menuitems[j];
00887 browserpopup_menuitems[j].user_data(browser);
00888 }
00889
00890 browserpopup_menuitems[1].callback(loadfile_cb);
00891 browserpopup_menuitems[2].callback(savefile_cb);
00892
00893
00894 menulen = sizeof(init_display_menuitems)/sizeof(Fl_Menu_Item);
00895 display_menuitems = new Fl_Menu_Item[menulen];
00896 for (j=0; j<menulen; j++)
00897 display_menuitems[j] = init_display_menuitems[j];
00898 if (app->display->aa_available()) display_menuitems[4].activate();
00899 if (app->display->cueing_available()) display_menuitems[5].activate();
00900 if (app->display->culling_available()) display_menuitems[6].activate();
00901
00902 menulen = app->axes->locations();
00903 axes_menuitems_storage = new Fl_Menu_Item[menulen+2];
00904 axes_menuitems_storage[0] = nullitem;
00905
00906 axes_menuitems = axes_menuitems_storage+1;
00907 for (j=0; j<menulen; j++) {
00908 Fl_Menu_Item item = {app->axes->loc_description(j), 0, axes_cb, app, FL_MENU_RADIO};
00909 axes_menuitems[j] = item;
00910 }
00911 axes_menuitems[menulen] = nullitem;
00912 display_menuitems[12].user_data(axes_menuitems);
00913
00914 menulen = 2;
00915 backgroundmode_menuitems_storage = new Fl_Menu_Item[menulen+2];
00916 backgroundmode_menuitems_storage[0] = nullitem;
00917 backgroundmode_menuitems = backgroundmode_menuitems_storage+1;
00918 {
00919 Fl_Menu_Item item = { "Solid Color", 0, backgroundmode_cb, app, FL_MENU_RADIO};
00920 backgroundmode_menuitems[0] = item;
00921 }
00922 {
00923 Fl_Menu_Item item = { "Gradient", 0, backgroundmode_cb, app, FL_MENU_RADIO};
00924 backgroundmode_menuitems[1] = item;
00925 }
00926 backgroundmode_menuitems[menulen] = nullitem;
00927 display_menuitems[13].user_data(backgroundmode_menuitems);
00928
00929 menulen = app->stage->locations();
00930 stage_menuitems_storage = new Fl_Menu_Item[menulen+2];
00931 stage_menuitems_storage[0] = nullitem;
00932 stage_menuitems = stage_menuitems_storage+1;
00933 for (j=0; j<menulen; j++) {
00934 Fl_Menu_Item item = {app->stage->loc_description(j), 0, stage_cb, app, FL_MENU_RADIO};
00935 stage_menuitems[j] = item;
00936 }
00937 stage_menuitems[menulen] = nullitem;
00938 display_menuitems[14].user_data(stage_menuitems);
00939
00940 menulen = app->display->num_stereo_modes();
00941 stereo_menuitems_storage = new Fl_Menu_Item[menulen+2];
00942 stereo_menuitems_storage[0] = nullitem;
00943 stereo_menuitems = stereo_menuitems_storage+1;
00944 for (j=0; j<menulen; j++) {
00945 Fl_Menu_Item item = {app->display->stereo_name(j), 0, stereo_cb, vmdapp, FL_MENU_RADIO};
00946 stereo_menuitems[j] = item;
00947 }
00948 stereo_menuitems[menulen] = nullitem;
00949 display_menuitems[15].user_data(stereo_menuitems);
00950
00951 menulen = 2;
00952 stereoswap_menuitems_storage = new Fl_Menu_Item[menulen+2];
00953 stereoswap_menuitems_storage[0] = nullitem;
00954 stereoswap_menuitems = stereoswap_menuitems_storage+1;
00955 for (j=0; j<menulen; j++) {
00956 const char * StereoSwap[] = { "Off", "On" };
00957 Fl_Menu_Item item = {StereoSwap[j], 0, stereoswap_cb, vmdapp, FL_MENU_RADIO};
00958 stereoswap_menuitems[j] = item;
00959 }
00960 stereoswap_menuitems[menulen] = nullitem;
00961 display_menuitems[16].user_data(stereoswap_menuitems);
00962
00963 menulen = app->display->num_cache_modes();
00964 cachemode_menuitems_storage = new Fl_Menu_Item[menulen+2];
00965 cachemode_menuitems_storage[0] = nullitem;
00966 cachemode_menuitems = cachemode_menuitems_storage+1;
00967 for (j=0; j<menulen; j++) {
00968 Fl_Menu_Item item = {app->display->cache_name(j), 0, cachemode_cb, vmdapp, FL_MENU_RADIO};
00969 cachemode_menuitems[j] = item;
00970 }
00971 cachemode_menuitems[menulen] = nullitem;
00972 display_menuitems[17].user_data(cachemode_menuitems);
00973
00974 menulen = app->display->num_render_modes();
00975 rendermode_menuitems_storage = new Fl_Menu_Item[menulen+2];
00976 rendermode_menuitems_storage[0] = nullitem;
00977 rendermode_menuitems = rendermode_menuitems_storage+1;
00978 for (j=0; j<menulen; j++) {
00979 Fl_Menu_Item item = {app->display->render_name(j), 0, rendermode_cb, vmdapp, FL_MENU_RADIO};
00980 rendermode_menuitems[j] = item;
00981 }
00982 rendermode_menuitems[menulen] = nullitem;
00983 display_menuitems[18].user_data(rendermode_menuitems);
00984
00985 update_dispmode();
00986
00987 menulen = sizeof(init_mouse_menuitems)/sizeof(Fl_Menu_Item);
00988 mouse_menuitems_storage = new Fl_Menu_Item[menulen+2];
00989 mouse_menuitems_storage[0] = nullitem;
00990 mouse_menuitems = mouse_menuitems_storage+1;
00991 for (j=0; j<menulen; j++)
00992 mouse_menuitems[j] = init_mouse_menuitems[j];
00993
00994
00995
00996 menubar = new Fl_Menu_Bar(0, 0, MAINFLTKMENUWIDTH, 30);
00997 #if defined(VMDMENU_WINDOW)
00998 menubar->color(VMDMENU_WINDOW);
00999 #endif
01000 menubar->add("File",0,0,(void *)file_menuitems,FL_SUBMENU_POINTER);
01001 menubar->add("Molecule",0,0,(void *)molecule_menuitems,FL_SUBMENU_POINTER);
01002 menubar->add("Graphics",0,0,(void *)graphics_menuitems, FL_SUBMENU_POINTER);
01003 menubar->add("Display",0,0,(void*)display_menuitems, FL_SUBMENU_POINTER);
01004 menubar->add("Mouse",0,0,(void *)mouse_menuitems, FL_SUBMENU_POINTER);
01005 menubar->add(EXT_MENU_NAME,0,0, NULL, FL_SUBMENU);
01006 menubar->add("Help",0,0,(void *)init_help_menuitems, FL_SUBMENU_POINTER);
01007 menubar->user_data(vmdapp);
01008 menubar->selection_color(VMDMENU_MENU_SEL);
01009
01010
01011 Fl_Group::current()->resizable(browser);
01012
01013 Fl_Button *b;
01014 int bwidth = 20, bheight = 20;
01015 b = new Fl_Button(0, 150, bwidth, bheight, "@4->|");
01016 VMDFLTKTOOLTIP(b, "Jump to beginning")
01017 b->labeltype(FL_SYMBOL_LABEL);
01018 b->callback(start_cb, app);
01019
01020 reverse = new Fl_Button(0, 150+bheight, bwidth, bheight, "@<");
01021 VMDFLTKTOOLTIP(reverse, "Play in reverse")
01022 reverse->labeltype(FL_SYMBOL_LABEL);
01023 reverse->type(FL_TOGGLE_BUTTON);
01024 reverse->callback(reverse_cb, app);
01025
01026 b = new Fl_Button(bwidth, 150+bheight, bwidth, bheight, "@<|");
01027 VMDFLTKTOOLTIP(b, "Step in reverse")
01028 b->labeltype(FL_SYMBOL_LABEL);
01029 b->callback(prev_cb, app);
01030
01031 b = new Fl_Button(MAINFLTKMENUWIDTH-bwidth, 150, bwidth, bheight, "@->|");
01032 VMDFLTKTOOLTIP(b, "Jump to end")
01033 b->labeltype(FL_SYMBOL_LABEL);
01034 b->callback(stop_cb, app);
01035
01036 forward = new Fl_Button(MAINFLTKMENUWIDTH-bwidth, 150+bheight,
01037 bwidth, bheight, "@>");
01038 VMDFLTKTOOLTIP(forward, "Play forward")
01039 forward->labeltype(FL_SYMBOL_LABEL);
01040 forward->type(FL_TOGGLE_BUTTON);
01041 forward->callback(forward_cb, app);
01042
01043 b = new Fl_Button(MAINFLTKMENUWIDTH-2*bwidth, 150+bheight,
01044 bwidth, bheight, "@|>");
01045 VMDFLTKTOOLTIP(b, "Step forward")
01046 b->labeltype(FL_SYMBOL_LABEL);
01047 b->callback(next_cb, app);
01048
01049 curframe = new Fl_Int_Input(bwidth, 150, 2*bwidth, bheight);
01050 VMDFLTKTOOLTIP(curframe, "Set current frame")
01051 curframe->textsize(12);
01052 curframe->callback(curframe_cb, app);
01053 curframe->when(FL_WHEN_ENTER_KEY);
01054 curframe->selection_color(VMDMENU_VALUE_SEL2);
01055
01056 frameslider = new Fl_Slider(3*bwidth, 150,
01057 MAINFLTKMENUWIDTH-4*bwidth, bheight);
01058 VMDFLTKTOOLTIP(frameslider, "Drag to set current frame")
01059 frameslider->type(FL_HOR_NICE_SLIDER);
01060 frameslider->step(1,1);
01061 frameslider->callback(frameslider_cb, this);
01062 frameslider->color(VMDMENU_SLIDER_BG, VMDMENU_SLIDER_FG);
01063 frameslider->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE);
01064
01065 step = new Fl_Counter(220,150+bheight, 45,bheight, "step");
01066 VMDFLTKTOOLTIP(step, "Animation step size")
01067 step->labelsize(12);
01068 step->type(FL_SIMPLE_COUNTER);
01069 step->step(1,1);
01070 step->minimum(1);
01071 step->value(1);
01072 step->callback(step_cb, app);
01073 step->align(FL_ALIGN_LEFT);
01074
01075 style = new Fl_Choice(120, 150+bheight, 65, bheight);
01076 VMDFLTKTOOLTIP(style, "Set animation looping mode")
01077 style->textsize(12);
01078 style->selection_color(VMDMENU_MENU_SEL);
01079 style->box(FL_THIN_UP_BOX);
01080 for (int s=0; s<Animation::ANIM_TOTAL_STYLES; s++)
01081 style->add(animationStyleName[s]);
01082
01083
01084
01085 style->value(1);
01086 style->callback(style_cb, app);
01087
01088 zoom = new Fl_Check_Button(80, 150+bheight-2, bwidth+5, bheight+5, "zoom");
01089 VMDFLTKTOOLTIP(zoom, "Zoom in slider onto 100-frame subrange centered on current frame")
01090 zoom->labelsize(12);
01091 zoom->align(FL_ALIGN_LEFT);
01092 zoom->value(0);
01093
01094 zoom->color(VMDMENU_CHECKBOX_BG, VMDMENU_CHECKBOX_FG);
01095 zoom->callback(zoom_cb, this);
01096
01097 speed = new Fl_Slider(315, 150+bheight, 90, bheight, "speed");
01098 VMDFLTKTOOLTIP(speed, "Drag slider to change animation speed")
01099 speed->labelsize(12);
01100 speed->type(FL_HORIZONTAL);
01101 speed->color(VMDMENU_SLIDER_BG, VMDMENU_SLIDER_FG);
01102 speed->value(1.0);
01103 speed->callback(speed_cb, app);
01104 speed->align(FL_ALIGN_LEFT);
01105
01106 guistate = UNDEFINED;
01107 update_gui_state();
01108
01109 callback(vmd_main_window_cb);
01110
01111 Fl_Window::end();
01112 }
01113
01114 int MainFltkMenu::act_on_command(int type, Command *cmd) {
01115 if (type == Command::MOL_NEW) {
01116
01117
01118 app->animation_set_style(style->value());
01119 }
01120
01121 if (type == Command::MOL_ACTIVE ||
01122 type == Command::MOL_ON ||
01123 type == Command::MOL_FIX ||
01124 type == Command::MOL_NEW ||
01125 type == Command::MOL_RENAME ||
01126 type == Command::MOL_VOLUME ||
01127 type == Command::ANIM_NEW_NUM_FRAMES ||
01128 type == Command::MOL_DEL ||
01129 type == Command::MOL_TOP
01130 ) {
01131 browser->update();
01132 }
01133
01134 if (type == Command::MOL_TOP ||
01135 type == Command::MOL_DEL ||
01136 type == Command::MOL_NEW ||
01137 type == Command::MOL_VOLUME ||
01138 type == Command::ANIM_JUMP ||
01139 type == Command::ANIM_NEW_NUM_FRAMES ||
01140 type == Command::ANIM_NEW_FRAME) {
01141 int id = app->molecule_top();
01142 int frame = app->molecule_frame(id);
01143 if (type != Command::ANIM_NEW_FRAME) {
01144 int max = app->molecule_numframes(id);
01145 frameslider->range(0, max-1);
01146 }
01147 frameslider->value(frame);
01148 char buf[20];
01149 sprintf(buf, "%d", frame);
01150 curframe->value(buf);
01151 if (type == Command::ANIM_JUMP) {
01152 forward->value(0);
01153 reverse->value(0);
01154 }
01155 } else if (type == Command::MOUSE_MODE) {
01156 update_mousemode(cmd);
01157 } else if (type == Command::DISP_DEPTHCUE || type == Command::DISP_CULLING
01158 || type == Command::DISP_ANTIALIAS || type == Command::DISP_FPS
01159 || type == Command::DISP_LIGHT_ON || type == Command::CMD_STAGE
01160 || type == Command::CMD_AXES || type == Command::DISP_PROJ
01161 || type == Command::DISP_BACKGROUNDGRADIENT
01162 || type == Command::DISP_STEREO || type == Command::DISP_STEREOSWAP
01163 || type == Command::DISP_CACHEMODE
01164 || type == Command::DISP_RENDERMODE) {
01165 update_dispmode();
01166 } else if (type == Command::MENU_TK_ADD) {
01167 char *shortpath = ((CmdMenuExtensionAdd *)cmd)->menupath;
01168 char *longpath = new char[strlen(EXT_MENU_NAME)+strlen(shortpath)+2];
01169 sprintf(longpath, "%s/%s",EXT_MENU_NAME,((CmdMenuExtensionAdd *)cmd)->menupath);
01170 char *menuname = stringdup(((CmdMenuExtensionAdd *)cmd)->name);
01171 menubar->add(longpath, 0, menu_cb, menuname);
01172 delete[] longpath;
01173 } else if (type == Command::MENU_TK_REMOVE) {
01174 const Fl_Menu_Item *menubase = menubar->menu();
01175 int remove_menu_index = 0;
01176 int m;
01177
01178 for (m=0; m<menubase->size(); m++)
01179 if (!strcmp(menubase[m].label(), EXT_MENU_NAME)) break;
01180 const Fl_Menu_Item *extmenu = menubase+m;
01181 for (m=1; m<extmenu[1].size(); m++)
01182 if (extmenu[m].user_data() && !strcmp((char*)extmenu[m].user_data(), ((CmdMenuExtensionRemove*)cmd)->name)) {
01183 remove_menu_index = extmenu-menubase+m;
01184 break;
01185 }
01186 if (remove_menu_index) menubar->remove(remove_menu_index);
01187 } else if (type == Command::ANIM_STYLE) {
01188 style->value((int)((CmdAnimStyle *)cmd)->newStyle);
01189 } else if (type == Command::ANIM_SKIP) {
01190 step->value(((CmdAnimSkip *)cmd)->newSkip);
01191 } else if (type == Command::ANIM_SPEED) {
01192
01193
01194 double val = ((CmdAnimSpeed *)cmd)->newSpeed;
01195 speed->value(val);
01196 } else if (type == Command::ANIM_DIRECTION) {
01197 Animation::AnimDir newDir = ((CmdAnimDir *)cmd)->newDir;
01198 forward->value(newDir == Animation::ANIM_FORWARD);
01199 reverse->value(newDir == Animation::ANIM_REVERSE);
01200 } else {
01201 return TRUE;
01202 }
01203
01204 return FALSE;
01205 }
01206
01207 MainFltkMenu::~MainFltkMenu() {
01208 delete[] file_menuitems;
01209 delete[] molecule_menuitems;
01210 delete[] display_menuitems;
01211 delete[] axes_menuitems_storage;
01212 delete[] backgroundmode_menuitems_storage;
01213 delete[] stage_menuitems_storage;
01214 delete[] stereo_menuitems_storage;
01215 delete[] stereoswap_menuitems_storage;
01216 delete[] cachemode_menuitems_storage;
01217 delete[] rendermode_menuitems_storage;
01218 delete[] mouse_menuitems_storage;
01219 delete[] browserpopup_menuitems;
01220 }
01221
01222 int MainFltkMenu::get_selected_molecule() {
01223 for (int j=0; j<browser->size(); j++)
01224 if (browser->selected(j+1))
01225 return j;
01226
01227 return -1;
01228 }
01229
01231 void MainFltkMenu::update_menu_state(Fl_Menu_Item* mymenuitems, const MenuBehavior* mymenu_behavior) {
01232 int j;
01233
01234 switch (guistate) {
01235 case MANY_SELECTED_MOL:
01236 for (j=0; mymenuitems[j].label(); j++) {
01237 if (mymenu_behavior[j] == MENU_NEED_UNIQUE_SEL) mymenuitems[j].deactivate();
01238 else mymenuitems[j].activate();
01239 }
01240 break;
01241 case ONE_SELECTED_MOL:
01242 for (j=0; mymenuitems[j].label(); j++)
01243 mymenuitems[j].activate();
01244 break;
01245 case NO_SELECTED_MOL:
01246 for (j=0; mymenuitems[j].label(); j++) {
01247 if (mymenu_behavior[j] & MENU_NEED_SEL) mymenuitems[j].deactivate();
01248 else mymenuitems[j].activate();
01249 }
01250 break;
01251 case UNDEFINED:
01252 break;
01253 }
01254 }
01255
01256
01257 void MainFltkMenu::update_gui_state() {
01258 char has_selected_mol = 0;
01259 int old_guistate = guistate;
01260
01261 for (int item=1; item<=browser->size(); item++) {
01262 if (browser->selected(item)) {
01263 has_selected_mol++;
01264 if (has_selected_mol >= 2) break;
01265 }
01266 }
01267
01268 if (has_selected_mol == 2) guistate = MANY_SELECTED_MOL;
01269 else if (has_selected_mol == 1) guistate = ONE_SELECTED_MOL;
01270 else if (!has_selected_mol) guistate = NO_SELECTED_MOL;
01271
01272
01273 if (old_guistate != guistate) {
01274 update_menu_state(file_menuitems, file_menu_behavior);
01275 update_menu_state(molecule_menuitems, molecule_menu_behavior);
01276 update_menu_state(browserpopup_menuitems, browserpopup_menu_behavior);
01277 }
01278
01279 }
01280
01281
01282
01283 void MainFltkMenu::draw() {
01284 #if defined(ARCH_MACOSX) || defined(ARCH_MACOSXX86) || defined(ARCH_MACOSXX86_64)
01285 size(MAINFLTKMENUWIDTH, h());
01286 #endif
01287 Fl_Window::draw();
01288 }
01289