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