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