00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ToolFltkMenu.h"
00022 #include "P_CmdTool.h"
00023 #include "VMDApp.h"
00024 #include "P_UIVR.h"
00025 #include "P_Tool.h"
00026 #include "FL/forms.H"
00027
00028 static void createtool_cb(Fl_Widget *, void *v) {
00029 ToolFltkMenu *self = (ToolFltkMenu *)v;
00030 self->create_tool();
00031 }
00032 static void deletetool_cb(Fl_Widget *, void *v) {
00033 ToolFltkMenu *self = (ToolFltkMenu *)v;
00034 self->delete_tool();
00035 }
00036 static void select_tool_cb(Fl_Widget *w, void *v) {
00037 ToolFltkMenu *self = (ToolFltkMenu *)v;
00038 self->select_tool();
00039 }
00040 static void select_tool_type_cb(Fl_Widget *, void *v) {
00041 ToolFltkMenu *self = (ToolFltkMenu *)v;
00042 self->select_tool_type();
00043 }
00044 static void position_cb(Fl_Widget *w, void *v) {
00045 ToolFltkMenu *self = (ToolFltkMenu *)v;
00046 Fl_Choice *menu = (Fl_Choice *)w;
00047 if (menu->value() == 0)
00048 self->choose_tracker(NULL);
00049 else
00050 self->choose_tracker(menu->text());
00051 }
00052 static void force_cb(Fl_Widget *w, void *v) {
00053 ToolFltkMenu *self = (ToolFltkMenu *)v;
00054 Fl_Choice *menu = (Fl_Choice *)w;
00055 if (menu->value() == 0)
00056 self->choose_feedback(NULL);
00057 else
00058 self->choose_feedback(menu->text());
00059 }
00060 static void button_cb(Fl_Widget *w, void *v) {
00061 ToolFltkMenu *self = (ToolFltkMenu *)v;
00062 Fl_Choice *menu = (Fl_Choice *)w;
00063 if (menu->value() == 0)
00064 self->choose_buttons(NULL);
00065 else
00066 self->choose_buttons(menu->text());
00067 }
00068 static void offset_cb(Fl_Widget *, void *v) {
00069 ToolFltkMenu *self = (ToolFltkMenu *)v;
00070 self->set_offset();
00071 }
00072 static void positionscale_cb(Fl_Widget *, void *v) {
00073 ToolFltkMenu *self = (ToolFltkMenu *)v;
00074 self->set_positionscale();
00075 }
00076 static void forceconstant_cb(Fl_Widget *, void *v) {
00077 ToolFltkMenu *self = (ToolFltkMenu *)v;
00078 self->set_springscale();
00079 }
00080 static void forcescale_cb(Fl_Widget *, void *v) {
00081 ToolFltkMenu *self = (ToolFltkMenu *)v;
00082 self->set_forcescale();
00083 }
00084 static void toolrep_cb(Fl_Widget *, void *v) {
00085 ToolFltkMenu *self = (ToolFltkMenu *)v;
00086 self->set_toolrep();
00087 }
00088 static void moleculerep_cb(Fl_Widget *, void *v) {
00089 ToolFltkMenu *self = (ToolFltkMenu *)v;
00090 self->update_replist();
00091 self->set_toolrep();
00092 }
00093
00094 void ToolFltkMenu::make_window() {
00095 size(540, 335);
00096 {
00097 { Fl_Box* o = new Fl_Box(15, 15, 325, 160);
00098 o->box(FL_ENGRAVED_FRAME);
00099 }
00100 { Fl_Button* o = new Fl_Button(25, 30, 125, 25, "Create tool");
00101 o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
00102 #if defined(VMDMENU_WINDOW)
00103 o->color(VMDMENU_WINDOW, FL_GRAY);
00104 #endif
00105 o->callback(createtool_cb, this);
00106 }
00107 { Fl_Choice* o = tooltypechooser = new Fl_Choice(25, 80, 125, 25, "Set tool type:");
00108 o->down_box(FL_BORDER_BOX);
00109 o->align(FL_ALIGN_TOP_LEFT);
00110 o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00111 o->callback(select_tool_type_cb, this);
00112 }
00113 {
00114 Fl_Button *o = new Fl_Button(25, 120, 125, 25, "Delete tool");
00115 #if defined(VMDMENU_WINDOW)
00116 o->color(VMDMENU_WINDOW, FL_GRAY);
00117 #endif
00118 o->callback(deletetool_cb, this);
00119 }
00120 toolbrowser = new Fl_Hold_Browser(175, 30, 155, 135);
00121 toolbrowser->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
00122 toolbrowser->callback(select_tool_cb, this);
00123 { Fl_Box* o = new Fl_Box(350, 15, 175, 160, "label");
00124 o->box(FL_ENGRAVED_FRAME);
00125 o->labeltype(FL_NO_LABEL);
00126 }
00127 { Fl_Box* o = new Fl_Box(20, 5, 45, 25, "Tools");
00128 o->box(FL_FLAT_BOX);
00129 #if defined(VMDMENU_WINDOW)
00130 o->color(VMDMENU_WINDOW, FL_GRAY);
00131 #endif
00132 }
00133 { Fl_Box* o = new Fl_Box(355, 5, 100, 25, "Tool devices");
00134 o->box(FL_FLAT_BOX);
00135 #if defined(VMDMENU_WINDOW)
00136 o->color(VMDMENU_WINDOW, FL_GRAY);
00137 #endif
00138 }
00139 { Fl_Choice* o = positionchooser = new Fl_Choice(360, 50, 150, 25, "Position");
00140 o->down_box(FL_BORDER_BOX);
00141 o->align(FL_ALIGN_TOP_LEFT);
00142 o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00143 o->callback(position_cb, this);
00144 }
00145 { Fl_Choice* o = buttonchooser = new Fl_Choice(360, 95, 150, 25, "Buttons");
00146 o->down_box(FL_BORDER_BOX);
00147 o->align(FL_ALIGN_TOP_LEFT);
00148 o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00149 o->callback(button_cb, this);
00150 }
00151 { Fl_Choice* o = forcechooser = new Fl_Choice(360, 140, 150, 25, "Force Feedback");
00152 o->down_box(FL_BORDER_BOX);
00153 o->align(FL_ALIGN_TOP_LEFT);
00154 o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00155 o->callback(force_cb, this);
00156 }
00157 { Fl_Tabs* o = tooltabs = new Fl_Tabs(15, 185, 510, 150);
00158 #if defined(VMDMENU_WINDOW)
00159 o->color(VMDMENU_WINDOW, FL_GRAY);
00160 o->selection_color(VMDMENU_WINDOW);
00161 #endif
00162
00163 { Fl_Group* o = new Fl_Group(40, 210, 485, 125, "Position");
00164 #if defined(VMDMENU_WINDOW)
00165 o->color(VMDMENU_WINDOW, FL_GRAY);
00166 o->selection_color(VMDMENU_WINDOW);
00167 #endif
00168 xoffsetinput = new Fl_Value_Input(105, 230, 65, 25, "X Offset:");
00169 xoffsetinput->selection_color(VMDMENU_VALUE_SEL);
00170 xoffsetinput->step(.01);
00171 xoffsetinput->range(-100, 100);
00172 xoffsetinput->callback(offset_cb, this);
00173 yoffsetinput = new Fl_Value_Input(105, 260, 65, 25, "Y Offset:");
00174 yoffsetinput->selection_color(VMDMENU_VALUE_SEL);
00175 yoffsetinput->step(.01);
00176 yoffsetinput->range(-100, 100);
00177 yoffsetinput->callback(offset_cb, this);
00178 zoffsetinput = new Fl_Value_Input(105, 290, 65, 25, "Z Offset:");
00179 zoffsetinput->selection_color(VMDMENU_VALUE_SEL);
00180 zoffsetinput->step(.01);
00181 zoffsetinput->range(-100, 100);
00182 zoffsetinput->callback(offset_cb, this);
00183 positionscalinginput = new Fl_Value_Input(295, 230, 65, 25, "Position scaling:");
00184 positionscalinginput->selection_color(VMDMENU_VALUE_SEL);
00185 positionscalinginput->step(0.01);
00186 positionscalinginput->range(0.01, 100);
00187 positionscalinginput->callback(positionscale_cb, this);
00188 o->end();
00189 }
00190 { Fl_Group* o = new Fl_Group(40, 210, 485, 125, "Force");
00191 #if defined(VMDMENU_WINDOW)
00192 o->color(VMDMENU_WINDOW, FL_GRAY);
00193 o->selection_color(VMDMENU_WINDOW);
00194 #endif
00195 o->hide();
00196 forceconstantinput = new Fl_Value_Input(180, 230, 60, 25, "Feedback scaling:");
00197 forceconstantinput->selection_color(VMDMENU_VALUE_SEL);
00198 forceconstantinput->step(0.1);
00199 forceconstantinput->range(0.1, 100);
00200 forceconstantinput->callback(forceconstant_cb, this);
00201 forcescalinginput = new Fl_Value_Input(180, 260, 60, 25, "Applied force scaling:");
00202 forcescalinginput->selection_color(VMDMENU_VALUE_SEL);
00203 forcescalinginput->step(0.1);
00204 forcescalinginput->range(0.1, 100);
00205 forcescalinginput->callback(forcescale_cb, this);
00206 o->end();
00207 }
00208 { Fl_Group* o = new Fl_Group(40, 210, 485, 125, "Assigned Rep");
00209 #if defined(VMDMENU_WINDOW)
00210 o->color(VMDMENU_WINDOW, FL_GRAY);
00211 o->selection_color(VMDMENU_WINDOW);
00212 #endif
00213 o->hide();
00214 { Fl_Round_Button* o = forceatombutton = new Fl_Round_Button(45, 245, 200, 25, "Apply force to picked atom");
00215 o->down_box(FL_ROUND_DOWN_BOX);
00216 o->type(FL_RADIO_BUTTON);
00217 o->callback(toolrep_cb, this);
00218 }
00219 { Fl_Round_Button* o = forcerepbutton = new Fl_Round_Button(45, 270, 200, 25, "Apply force to molecule rep");
00220 o->down_box(FL_ROUND_DOWN_BOX);
00221 o->type(FL_RADIO_BUTTON);
00222 o->callback(toolrep_cb, this);
00223 }
00224 { Fl_Choice* o = repmoleculechooser = new Fl_Choice(280, 245, 205, 25, "Selected molecule:");
00225 o->down_box(FL_BORDER_BOX);
00226 o->align(FL_ALIGN_TOP_LEFT);
00227 o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00228 o->callback(moleculerep_cb, this);
00229 }
00230 { Fl_Choice* o = reprepchooser = new Fl_Choice(280, 290, 205, 25, "Selected rep:");
00231 o->down_box(FL_BORDER_BOX);
00232 o->align(FL_ALIGN_TOP_LEFT);
00233 o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00234 o->callback(toolrep_cb, this);
00235 }
00236 o->end();
00237 }
00238 o->end();
00239 }
00240 }
00241 }
00242
00243 void ToolFltkMenu::reset_device_menus() {
00244 ResizeArray<JString *> *trackers, *feedback, *buttons;
00245 positionchooser->clear();
00246 buttonchooser->clear();
00247 forcechooser->clear();
00248
00249 positionchooser->add("None");
00250 buttonchooser->add("None");
00251 forcechooser->add("None");
00252
00253 trackers = app->uivr->get_tracker_names();
00254 feedback = app->uivr->get_feedback_names();
00255 buttons = app->uivr->get_button_names();
00256
00257 int t;
00258 for (t=0; t<trackers->num(); t++) {
00259 positionchooser->add(*(*trackers)[t]);
00260 delete (*trackers)[t];
00261 }
00262 for (t=0; t<feedback->num(); t++) {
00263 forcechooser->add(*(*feedback)[t]);
00264 delete (*feedback)[t];
00265 }
00266 for (t=0; t<buttons->num(); t++) {
00267 buttonchooser->add(*(*buttons)[t]);
00268 delete (*buttons)[t];
00269 }
00270 delete trackers;
00271 delete feedback;
00272 delete buttons;
00273 }
00274
00275 void ToolFltkMenu::reset_tool_list() {
00276 int curline = toolbrowser->value();
00277 toolbrowser->clear();
00278 for (int t=0; t<app->uivr->num_tools(); t++) {
00279 if (app->uivr->gettool(t)->alive()) {
00280 toolbrowser->add(app->uivr->gettool(t)->type_name());
00281 }
00282 }
00283 toolbrowser->value(curline);
00284 }
00285 void ToolFltkMenu::create_tool() {
00286 const char *tooltype = tooltypechooser->text();
00287 app->tool_create(tooltype, 0, NULL);
00288 }
00289
00290 void ToolFltkMenu::delete_tool() {
00291 app->tool_delete(toolbrowser->value()-1);
00292 }
00293
00294 void ToolFltkMenu::select_tool_type() {
00295 int n = toolbrowser->value();
00296 const char *type = tooltypechooser->text(tooltypechooser->value());
00297 app->tool_change_type(n-1, type);
00298 }
00299
00300 void ToolFltkMenu::select_tool() {
00301 int n = toolbrowser->value();
00302 if (n == 0 && toolbrowser->size() == 1) {
00303
00304 n = 1;
00305 toolbrowser->value(1);
00306 }
00307 Tool *tool = app->uivr->gettool(n-1);
00308 if (!tool || !tool->alive()) {
00309 positionchooser->deactivate();
00310 buttonchooser->deactivate();
00311 forcechooser->deactivate();
00312 tooltabs->deactivate();
00313 } else {
00314 for (int k=0; k<tooltypechooser->size()-1; k++) {
00315 if (!strcmp(tooltypechooser->text(k), tool->type_name())) {
00316 tooltypechooser->value(k);
00317 break;
00318 }
00319 }
00320 positionchooser->activate();
00321 positionchooser->value(0);
00322 buttonchooser->activate();
00323 buttonchooser->value(0);
00324 forcechooser->activate();
00325 forcechooser->value(0);
00326 tooltabs->activate();
00327 const char *pos = tool->get_tracker();
00328 const char *but = tool->get_buttons();
00329 const char *fce = tool->get_feedback();
00330 if (pos) {
00331
00332 for (int t=1; t<positionchooser->size()-1; t++) {
00333 if (!strcmp(positionchooser->text(t), pos))
00334 positionchooser->value(t);
00335 }
00336 }
00337 if (but) {
00338 for (int t=1; t<buttonchooser->size()-1; t++) {
00339 if (!strcmp(buttonchooser->text(t), but))
00340 buttonchooser->value(t);
00341 }
00342 }
00343 if (fce) {
00344 for (int t=1; t<forcechooser->size()-1; t++) {
00345 if (!strcmp(forcechooser->text(t), fce))
00346 forcechooser->value(t);
00347 }
00348 }
00349 const float *offset = tool->getoffset();
00350 if (offset) {
00351 xoffsetinput->value(offset[0]);
00352 yoffsetinput->value(offset[1]);
00353 zoffsetinput->value(offset[2]);
00354 } else {
00355 xoffsetinput->value(0);
00356 yoffsetinput->value(0);
00357 zoffsetinput->value(0);
00358 }
00359 forcescalinginput->value(tool->getforcescale());
00360 forceconstantinput->value(tool->getspringscale());
00361 positionscalinginput->value(tool->getscale());
00362
00363 update_toolrep_choosers();
00364 }
00365 }
00366
00367 void ToolFltkMenu::choose_tracker(const char *dev) {
00368 app->uivr->set_tracker(toolbrowser->value()-1, dev);
00369 select_tool();
00370 }
00371 void ToolFltkMenu::choose_feedback(const char *dev) {
00372 app->uivr->set_feedback(toolbrowser->value()-1, dev);
00373 select_tool();
00374 }
00375 void ToolFltkMenu::choose_buttons(const char *dev) {
00376 app->uivr->set_buttons(toolbrowser->value()-1, dev);
00377 select_tool();
00378 }
00379
00380 void ToolFltkMenu::set_offset() {
00381 int n = toolbrowser->value();
00382 if (n > 0) {
00383 float offset[3];
00384 offset[0] = (float)xoffsetinput->value();
00385 offset[1] = (float)yoffsetinput->value();
00386 offset[2] = (float)zoffsetinput->value();
00387 runcommand(new CmdToolOffset(offset, n-1));
00388 }
00389 }
00390 void ToolFltkMenu::set_forcescale() {
00391 int n = toolbrowser->value();
00392 if (n > 0) {
00393 float newval = (float)forcescalinginput->value();
00394 if (newval < 0) newval = -1.0f/newval;
00395 app->tool_set_force_scale(n-1, newval);
00396 }
00397 }
00398 void ToolFltkMenu::set_springscale() {
00399 int n = toolbrowser->value();
00400 if (n > 0) {
00401 float newval = (float)forceconstantinput->value();
00402 if (newval < 0) newval = -1.0f/newval;
00403 app->tool_set_spring_scale(n-1, newval);
00404 }
00405 }
00406 void ToolFltkMenu::set_positionscale() {
00407 int n = toolbrowser->value();
00408 if (n > 0) {
00409 float newval = (float)positionscalinginput->value();
00410 if (newval < 0) newval = -1.0f/newval;
00411 app->tool_set_position_scale(n-1, newval);
00412 }
00413 }
00414
00415 void ToolFltkMenu::set_toolrep() {
00416 int n = toolbrowser->value();
00417 if (n > 0) {
00418 if (forcerepbutton->value()) {
00419 int molid = app->molecule_id(repmoleculechooser->value()-1);
00420 int repid = reprepchooser->value()-1;
00421 runcommand(new CmdToolRep(n-1, molid, repid));
00422 } else {
00423 runcommand(new CmdToolRep(n-1, -1, -1));
00424 }
00425 }
00426 }
00427
00428 void ToolFltkMenu::update_toolrep_choosers() {
00429
00430
00431
00432 int has_valid_rep = FALSE;
00433 int molid = -1;
00434 int repid = -1;
00435 int molind = 0, repind;
00436 int n = toolbrowser->value();
00437 const Tool *tool = app->uivr->gettool(n-1);
00438 if (tool) {
00439 molid = tool->get_rep_molid();
00440 const char *rep = tool->get_rep_name();
00441 repid = app->molrep_get_by_name(molid, rep);
00442 if (repid >= 0) has_valid_rep = TRUE;
00443 }
00444 if (has_valid_rep) {
00445 for (int m=0; m<app->num_molecules(); m++)
00446 if (molid == app->molecule_id(m))
00447 molind = m+1;
00448 repind = repid+1;
00449 } else {
00450 molind = repmoleculechooser->value();
00451 repind = reprepchooser->value();
00452 }
00453
00454 fill_fltk_molchooser(repmoleculechooser, app, "None");
00455 if (molind >= 0 && molind < repmoleculechooser->size()-1) {
00456 repmoleculechooser->value(molind);
00457 } else {
00458 repmoleculechooser->value(0);
00459 }
00460
00461 reprepchooser->clear();
00462 update_replist();
00463 if (repind >= reprepchooser->size()-1)
00464 repind = 0;
00465 reprepchooser->value(repind);
00466
00467 if (has_valid_rep) {
00468 forcerepbutton->setonly();
00469 } else {
00470 forceatombutton->setonly();
00471 }
00472 }
00473
00474 void ToolFltkMenu::update_replist() {
00475 int molid = app->molecule_id(repmoleculechooser->value()-1);
00476 reprepchooser->clear();
00477 reprepchooser->add("None");
00478 reprepchooser->value(0);
00479 for (int r=0; r<app->num_molreps(molid); r++) {
00480 const char *sel = app->molrep_get_selection(molid, r);
00481 char *buf = new char[strlen(sel)+10];
00482 sprintf(buf, "%d: %s", r, sel);
00483 reprepchooser->add(buf);
00484 delete [] buf;
00485 }
00486 }
00487
00488
00489
00490
00491 static int cmdList[6] = {
00492 Command::TOOL_CREATE, Command::TOOL_DELETE, Command::TOOL_CHANGE,
00493 Command::TOOL_OFFSET, Command::TOOL_ADD_DEVICE, Command::TOOL_DELETE_DEVICE
00494 };
00495
00496 static int toolrepCmdList[6] = {
00497 Command::MOL_NEW, Command::MOL_DEL,
00498 Command::MOL_RENAME,
00499 Command::MOL_MODREP, Command::MOL_DELREP,
00500 Command::TOOL_REP
00501 };
00502
00503 ToolFltkMenu::ToolFltkMenu(VMDApp *vmdapp)
00504 : VMDFltkMenu("tool", "Tool Controls", vmdapp) {
00505 int t;
00506
00507 make_window();
00508 for (t=0; t<app->uivr->num_tool_types(); t++)
00509 tooltypechooser->add(app->uivr->tool_name(t));
00510 tooltypechooser->value(0);
00511 reset_device_menus();
00512
00513 for (t=0; t < 6; command_wanted(cmdList[t++]));
00514 for (t=0; t < 6; command_wanted(toolrepCmdList[t++]));
00515 command_wanted(Command::TOOL_SCALE);
00516 command_wanted(Command::TOOL_SCALE_FORCE);
00517 command_wanted(Command::TOOL_SCALE_SPRING);
00518 positionchooser->value(0);
00519 buttonchooser->value(0);
00520 forcechooser->value(0);
00521
00522 forceatombutton->setonly();
00523 }
00524
00525 int ToolFltkMenu::act_on_command(int type, Command *) {
00526 int t;
00527 for (t=0; t<6; t++) if (type == cmdList[t]) {
00528 reset_tool_list();
00529 select_tool();
00530 return TRUE;
00531 }
00532 for (t=0; t<6; t++) if (type == toolrepCmdList[t]) {
00533 update_toolrep_choosers();
00534 return TRUE;
00535 }
00536 if (type == Command::TOOL_SCALE ||
00537 type == Command::TOOL_SCALE_FORCE ||
00538 type == Command::TOOL_SCALE_SPRING) {
00539 select_tool();
00540 return TRUE;
00541 }
00542 return FALSE;
00543 }
00544