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