00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <math.h>
00013 #include "GeometryFltkMenu.h"
00014 #include "GeometryList.h"
00015 #include "Command.h"
00016 #include "VMDApp.h"
00017 #include "PickList.h"
00018 #include "Atom.h"
00019 #include "Molecule.h"
00020 #include "MoleculeList.h"
00021 #include "FL/fl_draw.H"
00022 #include "FL/forms.H"
00023 #include "FL/Fl_Input.H"
00024 #include "TextEvent.h"
00025 #include "Inform.h"
00026
00029 class myFl_Chart : public Fl_Widget {
00030 protected:
00031 void draw();
00032
00033 private:
00034 int num;
00035 float *values;
00036 float min, max;
00037 int imin, imax;
00038
00039 public:
00040 myFl_Chart(int, int, int, int, const char * = 0);
00041 ~myFl_Chart();
00042
00043 void clear();
00044 void set_data(const float *data, int n);
00045 };
00046
00047 myFl_Chart::myFl_Chart(int x, int y, int w, int h, const char *l)
00048 : Fl_Widget(x,y,w,h,l) {
00049 box(FL_BORDER_BOX);
00050 align(FL_ALIGN_BOTTOM);
00051 num = 0;
00052 values = NULL;
00053 min = max = 0;
00054 imin = imax = 0;
00055 }
00056
00057 myFl_Chart::~myFl_Chart() {
00058 delete [] values;
00059 }
00060
00061 void myFl_Chart::clear() {
00062 delete [] values;
00063 values = NULL;
00064 num = 0;
00065 redraw();
00066 }
00067
00068 void myFl_Chart::set_data(const float *data, int n) {
00069 if (n < 1) {
00070 clear();
00071 return;
00072 }
00073 delete [] values;
00074 values = new float[n];
00075 memcpy(values, data, n*sizeof(float));
00076 num = n;
00077 min = max = data[0];
00078 imin = imax = 0;
00079 for (int i=1; i<n; i++) {
00080 if (min > data[i]) { min = data[i]; imin = i; }
00081 if (max < data[i]) { max = data[i]; imax = i; }
00082 }
00083 redraw();
00084 }
00085
00086
00087
00088
00089
00090 static double fltk_rint(double v) {return floor(v+.5);}
00091
00092 void myFl_Chart::draw() {
00093 int xx, yy, ww, hh;
00094 if (!num) return;
00095 xx = x()+9;
00096 yy = y()+9;
00097 ww = w()-2*9;
00098 hh = h()-2*9;
00099
00100 draw_box();
00101
00102 double lh = fl_height();
00103 double incr;
00104 int zeroh;
00105 if (min > 0) {
00106 incr = (hh-2*lh)/max;
00107 zeroh = yy+hh-9;
00108 } else if (max < 0) {
00109 incr = (hh-2*lh)/min;
00110 zeroh = yy-9;
00111 } else {
00112 incr = (hh-2*lh)/(max-min);
00113 zeroh = yy+hh+(int)fltk_rint(min*incr) - 9;
00114 }
00115 double bwidth = ww/double(num);
00116
00117 for (int i=1; i<num; i++) {
00118 int x0 = xx + (int)fltk_rint((i-.5)*bwidth);
00119 int x1 = xx + (int)fltk_rint((i+.5)*bwidth);
00120 int y0 = zeroh - (int)fltk_rint(values[i-1]*incr);
00121 int y1 = zeroh - (int)fltk_rint(values[i]*incr);
00122 int color = FL_GREEN;
00123
00124 if (i == imin) color = FL_RED;
00125 else if (i == imax) color = FL_BLUE;
00126 fl_color(color);
00127 if ((values[i-1]>0.0)!=(values[i]>0.0)) {
00128 double ttt = values[i-1]/(values[i-1]-values[i]);
00129 int xt = xx + (int)fltk_rint((i-.5+ttt)*bwidth);
00130 fl_polygon(x0,zeroh, x0,y0, xt,zeroh);
00131 fl_polygon(xt,zeroh, x1,y1, x1,zeroh);
00132 } else {
00133
00134
00135
00136
00137
00138 fl_polygon(x0, zeroh, x0, y0, x1, y1, x1, zeroh);
00139 }
00140 fl_color(FL_BLACK);
00141 fl_line(x0,y0,x1,y1);
00142 }
00143 fl_line(xx, zeroh, xx+ww, zeroh);
00144 char buf[30];
00145 sprintf(buf, "%d: %3.2f", imin, min);
00146 fl_draw(buf, xx+(int)fltk_rint((imin+.5)*bwidth), zeroh-(int)fltk_rint(min*incr),0,0,
00147 min >= 0 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP);
00148 sprintf(buf, "%d: %3.2f", imax, max);
00149 fl_draw(buf, xx+(int)fltk_rint((imax+.5)*bwidth), zeroh-(int)fltk_rint(max*incr),0,0,
00150 max >= 0 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP);
00151 }
00152
00153 void GeometryFltkMenu::handle_pick(Molecule *m, int atomid, float value) {
00154 char buf[64];
00155
00156 if (!m || !m->current()) return;
00157 MolAtom *atm = m->atom(atomid);
00158 float *framepos = m->current()->pos;
00159
00160 char *molnamebuf = new char[20+strlen(m->molname())];
00161 sprintf(molnamebuf, "%d: %s", m->id(), m->molname());
00162 pickedmolecule->value(molnamebuf);
00163 delete [] molnamebuf;
00164 pickedresname->value(m->resNames.name(atm->resnameindex));
00165 sprintf(buf, "%d", atm->resid);
00166 pickedresid->value(buf);
00167 pickedname->value(m->atomNames.name(atm->nameindex));
00168 pickedtype->value(m->atomTypes.name(atm->typeindex));
00169 sprintf(buf, "%d", atomid);
00170 pickedindex->value(buf);
00171 pickedchain->value(m->chainNames.name(atm->chainindex));
00172 pickedsegname->value(m->segNames.name(atm->segnameindex));
00173 sprintf(buf, "%8.3f %8.3f %8.3f", framepos[3*atomid+0],
00174 framepos[3*atomid+1], framepos[3*atomid+2]);
00175 pickedpos->value(buf);
00176 sprintf(buf, "%8.3f", value);
00177 pickedvalue->value(buf);
00178 }
00179
00180 void GeometryFltkMenu::fill_label_browser() {
00181 int cat = labeltypechooser->value();
00182 GeomListPtr geomlist = glist->geom_list(cat);
00183 int gnum = geomlist->num();
00184
00185 int curnum = labelbrowser->size();
00186
00187
00188 if (curnum != gnum) {
00189 labelbrowser->clear();
00190 }
00191
00192
00193
00194 for (int j=0; j<gnum; j++) {
00195 char geomname[128];
00196 char geomstr[128];
00197 char buf[20];
00198 GeometryMol *g = (*geomlist)[j];
00199 strcpy(geomname, g->name());
00200 geomstr[0] = '\0';
00201 char *start = geomname;
00202 char *s = start;
00203 int done = 0;
00204 while (!done) {
00205 if (*s == '/' || *s == '\0') {
00206 if (!*s)
00207 done = 1;
00208 *s = '\0';
00209
00210 sprintf(buf, "%s%s\t", g->displayed() ? "" : "@C203", start);
00211 strcat(geomstr, buf);
00212 start = s+1;
00213 s = start;
00214 } else {
00215 s++;
00216 }
00217 }
00218 if (curnum != gnum)
00219 labelbrowser->add(geomstr);
00220 else
00221 labelbrowser->text(j+1, geomstr);
00222 }
00223 }
00224
00225 void GeometryFltkMenu::update_labelprops() {
00226 char tmpbuf[100];
00227 float textsize = app->label_get_textsize();
00228 sprintf(tmpbuf, "%5.2f", textsize);
00229 textsizeinput->value(tmpbuf);
00230 textsizeslider->value(textsize);
00231
00232
00233 int ind = labelbrowser->value();
00234 if (ind > 0) {
00235 textoffsetpositioner->activate();
00236 offsetresetbutton->activate();
00237 const float *offset = app->geometryList->getTextOffset(
00238 labeltypechooser->text(), ind-1);
00239 if (offset) {
00240 textoffsetpositioner->xvalue(offset[0]);
00241 textoffsetpositioner->yvalue(-offset[1]);
00242 } else {
00243 msgWarn << "No label found to update text offset!" << sendmsg;
00244 }
00245 if (labeltypechooser->value() == 0) {
00246 textformatinput->activate();
00247 if (!user_is_typing_in_format_input) {
00248 const char *format = app->geometryList->getTextFormat(
00249 labeltypechooser->text(), ind-1);
00250 if (format) {
00251 textformatinput->value(format);
00252 } else {
00253 msgWarn << "No label found to update text format!" << sendmsg;
00254 }
00255 }
00256 }
00257 } else {
00258 textoffsetpositioner->deactivate();
00259 offsetresetbutton->deactivate();
00260 }
00261 if (ind < 1 || labeltypechooser->value() != 0) {
00262 textformatinput->deactivate();
00263 }
00264 }
00265
00266
00267 void GeometryFltkMenu::update_geometry_types() {
00268 labeltypechooser->clear();
00269 for (int j=0; j<glist->num_lists(); j++)
00270 labeltypechooser->add(glist->geom_list_name(j));
00271 labeltypechooser->value(0);
00272 }
00273
00274 void GeometryFltkMenu::typechooser_cb(Fl_Widget *, void *v) {
00275 ((GeometryFltkMenu *)v)->fill_label_browser();
00276 ((GeometryFltkMenu *)v)->update_labelprops();
00277 }
00278
00279 void GeometryFltkMenu::graphinwindow_cb(Fl_Widget *, void *v) {
00280 GeometryFltkMenu *self = (GeometryFltkMenu *)v;
00281 int last_clicked = self->labelbrowser->value();
00282 if (!self->labelbrowser->selected(last_clicked)) {
00283 return;
00284 }
00285
00286 int item = last_clicked-1;
00287 GeomListPtr geomlist = self->glist->geom_list(self->labeltypechooser->value());
00288
00289 if (item >= geomlist->num()) {
00290 return;
00291 }
00292 GeometryMol *geom = (*geomlist)[item];
00293 ResizeArray<float> values;
00294 if (!geom->calculate_all(values)) {
00295 return;
00296 }
00297 if (values.num() < 1) {
00298 return;
00299 }
00300 self->chart->set_data(&(values[0]), values.num());
00301 }
00302
00303 void GeometryFltkMenu::show_cb(Fl_Widget *, void *v) {
00304 GeometryFltkMenu *self = (GeometryFltkMenu *)v;
00305 for (int i=self->labelbrowser->size(); i>0; i--) {
00306 if (self->labelbrowser->selected(i)) {
00307 self->app->label_show(self->labeltypechooser->text(), i-1, 1);
00308 }
00309 }
00310 }
00311
00312 void GeometryFltkMenu::hide_cb(Fl_Widget *, void *v) {
00313 GeometryFltkMenu *self = (GeometryFltkMenu *)v;
00314 for (int i=self->labelbrowser->size(); i>0; i--) {
00315 if (self->labelbrowser->selected(i)) {
00316 self->app->label_show(self->labeltypechooser->text(), i-1, 0);
00317 }
00318 }
00319 }
00320
00321 void GeometryFltkMenu::delete_cb(Fl_Widget *, void *v) {
00322 GeometryFltkMenu *self = (GeometryFltkMenu *)v;
00323 ResizeArray<int> tmp;
00324 int i;
00325 for (i=self->labelbrowser->size(); i>0; i--) {
00326 if (self->labelbrowser->selected(i)) tmp.append(i-1);
00327 }
00328 for (i=0; i<tmp.num(); i++)
00329 self->app->label_delete(self->labeltypechooser->text(), tmp[i]);
00330 }
00331
00332 void GeometryFltkMenu::labelbrowser_cb(Fl_Widget *, void *v) {
00333 GeometryFltkMenu *self = (GeometryFltkMenu *)v;
00334 int ind = self->labelbrowser->value();
00335 if (ind < 1) return;
00336 int labeltype = self->labeltypechooser->value();
00337
00338 GeometryMol *geom = (*(self->glist->geom_list(labeltype)))[ind-1];
00339 int atomid = geom->com_index(0);
00340 int molid = geom->obj_index(0);
00341 Molecule *m = self->app->moleculeList->mol_from_id(molid);
00342
00343 geom->calculate();
00344 self->handle_pick(m, atomid, geom->value());
00345 if (self->previewcheckbutton->value()) {
00346 self->graphinwindow_cb(self->chart, self);
00347 }
00348
00349 self->update_labelprops();
00350 }
00351
00352 void GeometryFltkMenu::exportgraph_cb(Fl_Widget *, void *v) {
00353 GeometryFltkMenu *self = (GeometryFltkMenu *)v;
00354 if (self->labelbrowser->size() < 1) {
00355 msgInfo << "No labels selected" << sendmsg;
00356 return;
00357 }
00358 GeomListPtr geomlist = self->glist->geom_list(self->labeltypechooser->value());
00359 if (geomlist->num() < 1) {
00360 msgErr << "GeometryFltkMenu::exportgraph_cb: No labels in list! That's weird." << sendmsg;
00361 return;
00362 }
00363 ResizeArray<int> items;
00364 for (int item=0; item <self->labelbrowser->size(); item++) {
00365 if (!self->labelbrowser->selected(1+item)) continue;
00366 items.append(item);
00367 GeometryMol *geom = (*geomlist)[item];
00368 ResizeArray<float> values;
00369 if (!geom->calculate_all(values)) {
00370 msgErr << "GeometryFltkMenu::exportgraph_cb: Couldn't calculate values" << sendmsg;
00371 return;
00372 }
00373 if (values.num() < 1) {
00374 msgErr << "Nothing to plot!" << sendmsg;
00375 return;
00376 }
00377 }
00378 self->runcommand(new GraphLabelEvent(self->labeltypechooser->text(),
00379 &items[0], items.num()));
00380 }
00381
00382
00383
00384 void GeometryFltkMenu::savetofile_cb(Fl_Widget *, void *v) {
00385 GeometryFltkMenu *self = (GeometryFltkMenu *)v;
00386 if (self->labelbrowser->size() < 1) {
00387 msgInfo << "No labels selected" << sendmsg;
00388 return;
00389 }
00390 GeomListPtr geomlist = self->glist->geom_list(self->labeltypechooser->value());
00391 if (geomlist->num() < 1) {
00392 msgErr << "GeometryFltkMenu::savetofile_cb: No labels in list! That's weird." << sendmsg;
00393 return;
00394 }
00395 for (int item=0; item <self->labelbrowser->size(); item++) {
00396 if (!self->labelbrowser->selected(1+item)) continue;
00397 GeometryMol *geom = (*geomlist)[item];
00398 ResizeArray<float> values;
00399 if (!geom->calculate_all(values)) {
00400 msgErr << "GeometryFltkMenu::savetofile_cb: Couldn't calculate values" << sendmsg;
00401 return;
00402 }
00403 if (values.num() < 1) {
00404 msgErr << "Nothing to plot!" << sendmsg;
00405 return;
00406 }
00407 char *file = self->app->vmd_choose_file(geom->unique_name(),
00408 "*.dat",
00409 "data file",
00410 1);
00411 if (!file) continue;
00412 FILE *fd = fopen(file, "w");
00413 for (int i=0; i<values.num(); i++) {
00414 fprintf(fd, "%d\t%f\n", i, values[i]);
00415 }
00416 fclose(fd);
00417 }
00418 }
00419
00420
00421 static void textoffset_cb(Fl_Widget *w, void *v) {
00422 Fl_Positioner *p = (Fl_Positioner *)w;
00423
00424 float x = (float) p->xvalue();
00425 float y = (float) -p->yvalue();
00426 ((GeometryFltkMenu *)v)->apply_offset_to_selected_labels(x, y);
00427 }
00428
00429 static void offsetreset_cb(Fl_Widget *, void *v) {
00430 ((GeometryFltkMenu *)v)->apply_offset_to_selected_labels(0, 0);
00431 }
00432
00433 void GeometryFltkMenu::apply_offset_to_selected_labels(float x, float y) {
00434
00435 const char *geomtype = labeltypechooser->text();
00436
00437
00438 for (int i=labelbrowser->size(); i>0; i--) {
00439 if (labelbrowser->selected(i)) {
00440 app->label_set_textoffset(geomtype, i-1, x, y);
00441 }
00442 }
00443 }
00444
00445
00446 static void textformat_cb(Fl_Widget *w, void *v) {
00447 Fl_Input *input = (Fl_Input *)w;
00448 ((GeometryFltkMenu *)v)->apply_format_to_selected_labels(input->value());
00449 }
00450 void GeometryFltkMenu::apply_format_to_selected_labels(const char *format) {
00451
00452 const char *geomtype = labeltypechooser->text();
00453
00454
00455
00456
00457 user_is_typing_in_format_input = TRUE;
00458
00459
00460
00461 for (int i=labelbrowser->size(); i>0; i--) {
00462 if (labelbrowser->selected(i)) {
00463 app->label_set_textformat(geomtype, i-1, format);
00464 }
00465 }
00466 user_is_typing_in_format_input = FALSE;
00467 }
00468
00469 static void textslidercb(Fl_Widget *w, void *v) {
00470 Fl_Slider *slider = (Fl_Slider *)w;
00471 VMDApp *app = (VMDApp *)v;
00472 app->label_set_textsize((float) slider->value());
00473 }
00474
00475 static void textinputcb(Fl_Widget *w, void *v) {
00476 Fl_Float_Input *input = (Fl_Float_Input *)w;
00477 VMDApp *app = (VMDApp *)v;
00478 char *endptr = NULL;
00479 const char *strval = input->value();
00480 double val = strtod(strval, &endptr);
00481 if (endptr != strval) {
00482
00483 app->label_set_textsize((float)val);
00484 }
00485 }
00486
00487 class My_Fl_Positioner : public Fl_Positioner {
00488 public:
00489 My_Fl_Positioner(int x, int y, int w, int h, const char *t=NULL)
00490 : Fl_Positioner(x, y, w, h, t) {}
00491 virtual void draw() {
00492 Fl_Positioner::draw();
00493 fl_circle(90+50, 190+50, 5);
00494 }
00495 };
00496
00497 static const int columns[] = {85, 85, 85, 85, 0};
00498 void GeometryFltkMenu::make_window() {
00499 size(360,335);
00500
00501 {
00502 labelbrowser = new Fl_Multi_Browser(10, 45, 340, 70);
00503 labelbrowser->color(FL_DARKCYAN);
00504 labelbrowser->selection_color(FL_YELLOW);
00505 labelbrowser->callback(labelbrowser_cb, this);
00506 labelbrowser->column_widths(columns);
00507
00508 { Fl_Choice* o = labeltypechooser = new Fl_Choice(10, 15, 95, 25);
00509 o->color(FL_PALEGREEN);
00510 o->selection_color(FL_BLACK);
00511 o->box(FL_THIN_UP_BOX);
00512 o->labeltype(FL_NO_LABEL);
00513 o->callback(typechooser_cb, this);
00514 }
00515 showbutton = new Fl_Button(125, 15, 75, 25, "Show");
00516 showbutton->callback(show_cb, this);
00517 hidebutton = new Fl_Button(200, 15, 75, 25, "Hide");
00518 hidebutton->callback(hide_cb, this);
00519 deletebutton = new Fl_Button(275, 15, 75, 25, "Delete");
00520 deletebutton->callback(delete_cb, this);
00521
00522 { Fl_Tabs* o = new Fl_Tabs(10, 120, 340, 215);
00523 { Fl_Group* o = pickinggroup = new Fl_Group(35, 145, 315, 180, "Picked Atom");
00524 Fl_Widget *w;
00525 w = pickedmolecule = new Fl_Output(110, 155, 230, 25, "Molecule:");
00526 w->selection_color(FL_YELLOW);
00527 w = pickedresname = new Fl_Output(110, 205, 70, 25, "ResName:");
00528 w->selection_color(FL_YELLOW);
00529 w = pickedresid = new Fl_Output(110, 230, 70, 25, "ResID:");
00530 w->selection_color(FL_YELLOW);
00531 w = pickedname = new Fl_Output(110, 255, 70, 25, "Name:");
00532 w->selection_color(FL_YELLOW);
00533 w = pickedtype = new Fl_Output(110, 280, 70, 25, "Type:");
00534 w->selection_color(FL_YELLOW);
00535 w = pickedpos = new Fl_Output(110, 180, 230, 25, "XYZ:");
00536 w->selection_color(FL_YELLOW);
00537 w = pickedchain = new Fl_Output(270, 205, 70, 25, "Chain:");
00538 w->selection_color(FL_YELLOW);
00539 w = pickedsegname = new Fl_Output(270, 230, 70, 25, "SegName:");
00540 w->selection_color(FL_YELLOW);
00541 w = pickedindex = new Fl_Output(270, 255, 70, 25, "Index:");
00542 w->selection_color(FL_YELLOW);
00543 w = pickedvalue = new Fl_Output(270, 280, 70, 25, "Value:");
00544 w->selection_color(FL_YELLOW);
00545 o->end();
00546 }
00547 { Fl_Group* o = geometrygroup = new Fl_Group(35, 145, 315, 180, "Graph");
00548 o->hide();
00549 savetofilebutton = new Fl_Button(285, 155, 55, 25, "Save...");
00550 savetofilebutton->callback(savetofile_cb, this);
00551 exportgraphbutton = new Fl_Button(200, 155, 55, 25, "Graph");
00552 exportgraphbutton->callback(exportgraph_cb, this);
00553 previewcheckbutton = new Fl_Check_Button(40, 155, 25, 25, "Show preview");
00554
00555
00556 chart = new myFl_Chart(45,190,295,125);
00557 o->end();
00558 }
00559 { Fl_Group *o = propertiesgroup = new Fl_Group(35, 145, 315, 180, "Properties");
00560 o->hide();
00561 textsizeinput = new Fl_Float_Input(90, 155, 50, 25, "Text Size:");
00562 textsizeinput->when(FL_WHEN_ENTER_KEY);
00563 textsizeinput->selection_color(FL_YELLOW);
00564 textsizeinput->callback(textinputcb, app);
00565 textsizeslider = new Fl_Slider(140, 155, 190, 25);
00566 textsizeslider->type(FL_HOR_SLIDER);
00567 textsizeslider->color(FL_WHITE);
00568 textsizeslider->when(FL_WHEN_CHANGED);
00569 textsizeslider->callback(textslidercb, app);
00570 textsizeslider->range(0, 5);
00571
00572 textoffsetpositioner = new My_Fl_Positioner(90, 190, 100, 100, "Offset:");
00573 textoffsetpositioner->align(FL_ALIGN_LEFT);
00574 textoffsetpositioner->color(FL_DARKCYAN);
00575 textoffsetpositioner->selection_color(FL_YELLOW);
00576 textoffsetpositioner->when(FL_WHEN_CHANGED);
00577 textoffsetpositioner->callback(textoffset_cb, this);
00578
00579
00580 textoffsetpositioner->xbounds(-.7, .7);
00581 textoffsetpositioner->ybounds(-.5, .5);
00582 textoffsetpositioner->value(0,0);
00583 VMDFLTKTOOLTIP(textoffsetpositioner, "Set the label offset relative to its default position");
00584
00585 offsetresetbutton = new Fl_Button(200, 228, 55, 25, "Reset");
00586 offsetresetbutton->callback(offsetreset_cb, this);
00587 VMDFLTKTOOLTIP(offsetresetbutton, "Reset the label offset to (0,0)");
00588
00589 textformatinput = new Fl_Input(90, 300, 240, 25, "Format:");
00590 textformatinput->selection_color(FL_YELLOW);
00591 textformatinput->when(FL_WHEN_CHANGED);
00592 textformatinput->callback(textformat_cb, this);
00593 VMDFLTKTOOLTIP(textformatinput, "Set selected atom labels with substitutions: %R->resname, %r->camelcase resname, %d->resid, %a->name, %q->charge, %i->index");
00594
00595 o->end();
00596 }
00597 o->end();
00598 }
00599 Fl_Window::end();
00600
00601 update_labelprops();
00602 }
00603 }
00604
00605 GeometryFltkMenu::GeometryFltkMenu(VMDApp *vmdapp)
00606 : VMDFltkMenu("labels", "Labels", vmdapp), glist(vmdapp->geometryList) {
00607
00608 command_wanted(Command::LABEL_ADD);
00609 command_wanted(Command::LABEL_DELETE);
00610 command_wanted(Command::LABEL_SHOW);
00611 command_wanted(Command::LABEL_ADDSPRING);
00612 command_wanted(Command::LABEL_TEXTSIZE);
00613 command_wanted(Command::LABEL_TEXTOFFSET);
00614 command_wanted(Command::LABEL_TEXTFORMAT);
00615 command_wanted(Command::ANIM_NEW_FRAME);
00616 command_wanted(Command::PICK_EVENT);
00617 command_wanted(Command::MOL_DEL);
00618
00619 user_is_typing_in_format_input = FALSE;
00620
00621 make_window();
00622 update_geometry_types();
00623 }
00624
00625 int GeometryFltkMenu::act_on_command(int type, Command *cmd) {
00626 switch (type) {
00627 case Command::PICK_EVENT:
00628 {
00629 PickEvent *event = (PickEvent *)cmd;
00630 Molecule *m = app->moleculeList->check_pickable(event->pickable);
00631 if (m)
00632 handle_pick(m, event->tag, 0);
00633 }
00634 break;
00635
00636 case Command::LABEL_ADD:
00637 case Command::LABEL_ADDSPRING:
00638 case Command::LABEL_DELETE:
00639 case Command::LABEL_SHOW:
00640 fill_label_browser();
00641 update_labelprops();
00642 break;
00643
00644 case Command::ANIM_NEW_FRAME:
00645 labelbrowser->do_callback();
00646 break;
00647
00648 case Command::LABEL_TEXTSIZE:
00649 case Command::LABEL_TEXTOFFSET:
00650 case Command::LABEL_TEXTFORMAT:
00651 update_labelprops();
00652 break;
00653
00654 case Command::MOL_DEL:
00655 glist->prepare();
00656 fill_label_browser();
00657 update_labelprops();
00658 break;
00659 }
00660 return 1;
00661 }
00662