00001 #include "disp/ray.H"
00002 #include "geom/world.H"
00003 #include "gtex/smooth_shade.H"
00004 #include "mesh/lmesh.H"
00005 #include "std/time.H"
00006
00007 #include "manip/cam_edit.H"
00008
00009 using namespace mlib;
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 Cam_int_edit::Cam_int_edit(
00036 CEvent &down_ev,
00037 CEvent &move_ev,
00038 CEvent &up_ev,
00039
00040 CEvent &down2_ev,
00041 CEvent &up2_ev,
00042
00043 CEvent &rot_down_ev,
00044 CEvent &trans_down_ev,
00045 CEvent &zoom_down_ev,
00046
00047 CEvent &rot_up_ev,
00048 CEvent &trans_up_ev,
00049 CEvent &zoom_up_ev
00050 )
00051 {
00052 Event toggle(NULL, Evd('Y', KEYD));
00053
00054 _cam_rot += Arc(move_ev, Cb(&Cam_int_edit::rot));
00055 _cam_rot += Arc(up_ev, Cb(&Cam_int_edit::up, (State *)-1));
00056 _cam_rot += Arc(up2_ev, Cb(&Cam_int_edit::up, (State *)-1));
00057 _cam_pan += Arc(move_ev, Cb(&Cam_int_edit::pan));
00058 _cam_pan += Arc(up_ev, Cb(&Cam_int_edit::up, (State *)-1));
00059 _cam_pan += Arc(down2_ev,Cb(&Cam_int_edit::noop, &_cam_rot));
00060 _cam_zoom += Arc(move_ev, Cb(&Cam_int_edit::zoom));
00061 _cam_zoom += Arc(up_ev, Cb(&Cam_int_edit::up, (State *)-1));
00062 _cam_zoom += Arc(down2_ev,Cb(&Cam_int_edit::noop, &_cam_rot));
00063 _cam_choose += Arc(down2_ev,Cb(&Cam_int_edit::noop, &_cam_rot));
00064 _cam_choose += Arc(move_ev, Cb(&Cam_int_edit::choose));
00065 _cam_choose += Arc(up_ev, Cb(&Cam_int_edit::up, (State *)-1));
00066
00067
00068
00069
00070
00071 _rot_z_move += Arc(move_ev, Cb(&Cam_int_edit::rot_z));
00072 _rot_z_move += Arc(up_ev, Cb(&Cam_int_edit::up, &_rot_z));
00073 _rot_z += Arc(down_ev, Cb(&Cam_int_edit::edit_down, &_rot_z_move));
00074 _rot_z += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00075
00076
00077
00078
00079 _ymove += Arc(move_ev, Cb(&Cam_int_edit::rot_y));
00080 _ymove += Arc(up_ev, Cb(&Cam_int_edit::up, &_rot_y));
00081 _rot_y += Arc(down_ev, Cb(&Cam_int_edit::edit_down, &_ymove));
00082 _rot_y += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00083
00084
00085
00086 _rot_x_move += Arc(move_ev, Cb(&Cam_int_edit::rot_x));
00087 _rot_x_move += Arc(up_ev, Cb(&Cam_int_edit::up, &_rot_x));
00088 _rot_x += Arc(down_ev, Cb(&Cam_int_edit::edit_down, &_rot_x_move));
00089 _rot_x += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00090
00091
00092
00093 _scale_move += Arc(move_ev, Cb(&Cam_int_edit::scale));
00094 _scale_move += Arc(up_ev, Cb(&Cam_int_edit::up, &_scale));
00095 _scale += Arc(down_ev, Cb(&Cam_int_edit::edit_down, &_scale_move));
00096 _scale += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00097 _scale += Arc(toggle, Cb(&Cam_int_edit::toggle_buttons));
00098
00099
00100
00101
00102
00103 _scalex_move += Arc(move_ev, Cb(&Cam_int_edit::scale_x));
00104 _scalex_move += Arc(up_ev, Cb(&Cam_int_edit::up, &_scalex));
00105 _scalex += Arc(down_ev, Cb(&Cam_int_edit::edit_down, &_scalex_move));
00106 _scalex += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00107
00108
00109
00110
00111
00112 _scaley_move += Arc(move_ev, Cb(&Cam_int_edit::scale_y));
00113 _scaley_move += Arc(up_ev, Cb(&Cam_int_edit::up, &_scaley));
00114 _scaley += Arc(down_ev, Cb(&Cam_int_edit::edit_down, &_scaley_move));
00115 _scaley += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00116
00117
00118
00119
00120
00121 _scalez_move += Arc(move_ev, Cb(&Cam_int_edit::scale_z));
00122 _scalez_move += Arc(up_ev, Cb(&Cam_int_edit::up, &_scalez));
00123 _scalez += Arc(down_ev, Cb(&Cam_int_edit::edit_down, &_scalez_move));
00124 _scalez += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00125
00126
00127 _entry += Arc(down_ev, Cb(&Cam_int_edit::down, &_cam_choose));
00128 _entry += Arc(down2_ev, Cb(&Cam_int_edit::down2));
00129
00130
00131 _but_trans += Arc(move_ev , Cb(&Cam_int_edit::pan2, &_but_trans));
00132 _but_trans += Arc(trans_up_ev , Cb(&Cam_int_edit::noop, (State *)-1));
00133 _but_rot += Arc(move_ev , Cb(&Cam_int_edit::rot2, &_but_rot));
00134 _but_rot += Arc(rot_up_ev , Cb(&Cam_int_edit::noop, (State *)-1));
00135 _but_zoom += Arc(move_ev , Cb(&Cam_int_edit::zoom2, &_but_zoom));
00136 _but_zoom += Arc(zoom_up_ev , Cb(&Cam_int_edit::noop, (State *)-1));
00137
00138
00139
00140
00141
00142
00143 _entry2 += Arc(trans_down_ev, Cb(&Cam_int_edit::predown,&_but_trans));
00144 _entry2 += Arc(rot_down_ev, Cb(&Cam_int_edit::predown,&_but_rot));
00145 _entry2 += Arc(zoom_down_ev, Cb(&Cam_int_edit::predown,&_but_zoom));
00146
00147 }
00148
00149
00150
00151 int
00152 Cam_int_edit::predown(
00153 CEvent &e,
00154 State *&
00155 )
00156 {
00157 DEVice_buttons *btns = (DEVice_buttons *)e._d;
00158 DEVice_2d *ptr = btns->ptr2d();
00159
00160 _view = e.view();
00161
00162
00163 _do_reset = 0;
00164 _dtime = the_time();
00165 _dist = 0;
00166 _scale_pt = ptr->cur();
00167 _start_pix= ptr->cur();
00168
00169 CAMdataptr data(_view->cam()->data());
00170 RAYhit r (_view->intersect(ptr->cur()));
00171 if (r.success()) {
00172 double dist = r.dist();
00173 _down_pt = r.point() + dist * r.vec();
00174 } else {
00175 _down_pt = Wplane(data->center(),data->at_v()).intersect(ptr->cur());
00176 }
00177 _down_pt_2d = _down_pt;
00178
00179
00180
00181 data->start_manip();
00182 return 0;
00183 }
00184
00185 int
00186 Cam_int_edit::down(
00187 CEvent &e,
00188 State *&s
00189 )
00190 {
00191 DEVice_buttons *btns = (DEVice_buttons *)e._d;
00192 DEVice_2d *ptr = btns->ptr2d();
00193 VIEWptr view(e.view());
00194
00195 int x, y; view->get_size(x,y);
00196 PIXEL curpix(ptr->cur());
00197 XYpt curpt (curpix[0]/x*2-1, curpix[1]/y*2-1);
00198
00199 predown(e,s);
00200
00201
00202 if (fabs(curpt[0]) > .85 || fabs(curpt[1]) > .9)
00203 {
00204 s = &_cam_rot;
00205 return 0;
00206 }
00207
00208
00209
00210 return 0;
00211 }
00212
00213
00214 int
00215 Cam_int_edit::down2(
00216 CEvent &e,
00217 State *&s
00218 )
00219 {
00220 DEVice_buttons *btns = (DEVice_buttons *)e._d;
00221 DEVice_2d *ptr = btns->ptr2d();
00222
00223 _view = e.view();
00224
00225 CAMdataptr data(_view->cam()->data());
00226 RAYhit r (_view->intersect(ptr->cur()));
00227 if (r.success()) {
00228
00229
00230
00231 if(r.geom()->name() == "scale")
00232 {
00233 BaseJOTapp::deactivate_button();
00234 if(s == &_scale)
00235 s = (State *)-1;
00236 else
00237 {
00238 BaseJOTapp::activate_button("scale");
00239 s = &_scale;
00240 }
00241 }
00242
00243
00244
00245 if(r.geom()->name() == "scalex")
00246 {
00247 BaseJOTapp::deactivate_button();
00248 if(s == &_scalex)
00249 s = (State *)-1;
00250 else
00251 {
00252 BaseJOTapp::activate_button("scalex");
00253 s = &_scalex;
00254 }
00255 }
00256
00257
00258
00259 if(r.geom()->name() == "scaley")
00260 {
00261 BaseJOTapp::deactivate_button();
00262 if(s == &_scaley)
00263 s = (State *)-1;
00264 else
00265 {
00266 BaseJOTapp::activate_button("scaley");
00267 s = &_scaley;
00268 }
00269 }
00270
00271
00272
00273 if(r.geom()->name() == "scalez")
00274 {
00275 BaseJOTapp::deactivate_button();
00276 if(s == &_scalez)
00277 s = (State *)-1;
00278 else
00279 {
00280 BaseJOTapp::activate_button("scalez");
00281 s = &_scalez;
00282 }
00283 }
00284
00285
00286
00287 if(r.geom()->name() == "rotateX")
00288 {
00289 BaseJOTapp::deactivate_button();
00290 if(s == &_rot_x)
00291 s = (State *)-1;
00292 else
00293 {
00294 BaseJOTapp::activate_button("rotateX");
00295 s = &_rot_x;
00296 }
00297 }
00298
00299
00300
00301 if(r.geom()->name() == "rotateY")
00302 {
00303 BaseJOTapp::deactivate_button();
00304 if(s == &_rot_y)
00305 s = (State *)-1;
00306 else
00307 {
00308 BaseJOTapp::activate_button("rotateY");
00309 s = &_rot_y;
00310 }
00311 }
00312
00313
00314
00315 if(r.geom()->name() == "rotateZ")
00316 {
00317 BaseJOTapp::deactivate_button();
00318 if(s == &_rot_z)
00319 s = (State *)-1;
00320 else
00321 {
00322 BaseJOTapp::activate_button("rotateZ");
00323 s = &_rot_z;
00324 }
00325 }
00326
00327
00328
00329 else if(r.geom()->name() == "eye_button")
00330 {
00331 s = (State *)-1;
00332 BaseJOTapp::cam_switch(e,s);
00333 }
00334 }
00335 return 0;
00336 }
00337
00338
00339 int
00340 Cam_int_edit::choose(
00341 CEvent &e,
00342 State *&s
00343 )
00344 {
00345 DEVice_2d *ptr =(DEVice_2d *)e._d;
00346 PIXEL te (ptr->cur());
00347 XYvec delta(ptr->delta());
00348 double tdelt(the_time() - _dtime);
00349
00350 _dist += sqrt(delta * delta);
00351
00352 VEXEL sdelt(te - _start_pix);
00353
00354 int xa=0,ya=1;
00355 if (Config::get_var_bool("FLIP_CAM_MANIP",false,true))
00356 swap(xa,ya);
00357
00358 if (fabs(sdelt[ya])/sdelt.length() > 0.9 && tdelt > 0.05) {
00359 s = &_cam_zoom;
00360 ptr->set_old(_start_pix);
00361 } else if (tdelt < 0.1 && _dist < 0.03)
00362 return 0;
00363 else {
00364 if (fabs(sdelt[xa])/sdelt.length() > 0.6 )
00365 s = &_cam_pan;
00366 else s = &_cam_zoom;
00367 ptr->set_old(_start_pix);
00368 }
00369 VIEWptr view(e.view());
00370 view->save_cam();
00371
00372 return 0;
00373 }
00374
00375
00376
00377 int
00378 Cam_int_edit::zoom2(
00379 CEvent &e,
00380 State *&
00381 )
00382 {
00383 DEVice_2d *ptr = (DEVice_2d *)e._d;
00384 CAMptr cam (e.view()->cam());
00385 PIXEL curpt (ptr->cur());
00386 XYpt startpt(_start_pix);
00387 int w,h; e.view()->get_size(w,h);
00388
00389 double zoom_factor = 1 + Sign(ptr->delta()[0]) *
00390 (PIXEL(ptr->cur())-PIXEL(ptr->old())).length()/(w/4);
00391
00392 cam->set_zoom(cam->zoom() * zoom_factor);
00393 cam->set_min (cam->min() + NDCvec(XYpt(_start_pix) - startpt));
00394
00395 ptr->set_cur(curpt);
00396 cam->data()->changed();
00397
00398 return 0;
00399 }
00400
00401 int
00402 Cam_int_edit::rot2(
00403 CEvent &e,
00404 State *&
00405 )
00406 {
00407 CAMptr cam(e.view()->cam());
00408
00409 cam->set_zoom(1);
00410 cam->set_min(NDCpt(XYpt(-1,-1)));
00411 cam->data()->changed();
00412
00413 return 0;
00414 }
00415
00416 int
00417 Cam_int_edit::pan2(
00418 CEvent &e,
00419 State *&
00420 )
00421 {
00422 DEVice_2d *ptr=(DEVice_2d *)e._d;
00423 CAMptr cam (e.view()->cam());
00424 PIXEL curpt(ptr->cur());
00425
00426 cam->set_min(cam->min() + NDCvec(ptr->delta()));
00427 cam->data()->changed();
00428 ptr->set_cur(curpt);
00429 return 0;
00430 }
00431
00432 int
00433 Cam_int_edit::pan(
00434 CEvent &e,
00435 State *&
00436 )
00437 {
00438 DEVice_2d *ptr=(DEVice_2d *)e._d;
00439 CAMptr cam (e.view()->cam());
00440 CAMdataptr data (cam->data());
00441 Wvec delta(Wpt(ptr->cur(),_down_pt) - Wpt(ptr->old(),_down_pt));
00442
00443 data->translate(-delta);
00444 data->set_at(Wline(data->from(), data->at_v()).project(_down_pt));
00445 data->set_center(data->at());
00446 return 0;
00447 }
00448
00449 int
00450 Cam_int_edit::zoom(
00451 CEvent &e,
00452 State *&
00453 )
00454 {
00455 DEVice_2d *ptr=(DEVice_2d *)e._d;
00456 CAMptr cam (e.view()->cam());
00457 CAMdataptr data (cam->data());
00458 XYvec delta(ptr->delta());
00459 double ratio;
00460
00461 if (data->persp()) {
00462 Wvec movec(_down_pt - data->from());
00463
00464 data->set_center(_down_pt);
00465 data->translate(movec.normalized() * (movec.length() * delta[1] * -4));
00466
00467 ratio = cam->height() / cam->width() *
00468 (movec * data->at_v()) * data->width() / data->focal();
00469
00470 } else {
00471 Wpt spt (XYpt(ptr->cur()[0],_scale_pt[1]));
00472 Wvec svec (spt - Wline(data->from(), data->at_v()).project(spt));
00473 double sfact(1 + delta[1]);
00474 data->translate( svec * (1.0 - sfact));
00475 data->set_width (data->width() * sfact);
00476 data->set_height(data->height()* sfact);
00477 ratio = data->height();
00478 }
00479
00480 data->translate(-delta[0]/2 * data->right_v() * ratio);
00481 data->set_at(Wline(data->from(), data->at_v()).project(data->center()));
00482 data->set_center(data->at());
00483 return 0;
00484 }
00485
00486 int
00487 Cam_int_edit::rot(
00488 CEvent &e,
00489 State *&
00490 )
00491 {
00492 CAMptr cam (e.view()->cam());
00493 CAMdataptr data(cam->data());
00494 DEVice_2d *ptr=(DEVice_2d *)e._d;
00495
00496 cam->set_zoom(1);
00497 cam->set_min(NDCpt(XYpt(-1,-1)));
00498 cam->data()->changed();
00499
00500 XYpt cpt = data->center();
00501 double radsq = sqr(1+fabs(cpt[0]));
00502 XYpt tp = ptr->old();
00503 XYpt te = ptr->cur();
00504
00505 Wvec op (tp[0], 0, 0);
00506 Wvec oe (te[0], 0, 0);
00507 double opsq = op * op, oesq = oe * oe;
00508 double lop = opsq > radsq ? 0 : sqrt(radsq - opsq);
00509 double loe = oesq > radsq ? 0 : sqrt(radsq - oesq);
00510 Wvec nop = Wvec(op[0], 0, lop).normalized();
00511 Wvec noe = Wvec(oe[0], 0, loe).normalized();
00512 double dot = nop * noe;
00513
00514 if (fabs(dot) > 0.0001) {
00515 data->rotate(Wline(data->center(), Wvec::Y()),
00516 -2*Acos(dot) * Sign(te[0]-tp[0]));
00517
00518 Wvec dvec = data->from() - data->center();
00519 double rdist = te[1]-tp[1];
00520
00521
00522 CAMdata dd = CAMdata(*data);
00523
00524 Wline raxe(data->center(),data->right_v());
00525 data->rotate(raxe, rdist);
00526 data->set_up(data->from() + Wvec::Y());
00527 if (data->right_v() * dd.right_v() < 0)
00528 *data = dd;
00529 }
00530
00531 return 0;
00532 }
00533
00534 int
00535 Cam_int_edit::up(
00536 CEvent &e,
00537 State *&s
00538 )
00539 {
00540
00541
00542 VIEWptr view(e.view());
00543 CAMptr cam (view->cam());
00544
00545 _model = NULL;
00546 cam->data()->end_manip();
00547 return 0;
00548 }
00549
00550
00551
00552
00553
00554
00555 int
00556 Cam_int_edit::scale
00557 (CEvent &e,
00558 State *&s)
00559 {
00560 CAMptr cam (e.view()->cam());
00561 CAMdataptr data(cam->data());
00562 DEVice_2d *ptr=(DEVice_2d *)e._d;
00563
00564 if(_model == NULL)
00565 return 0;
00566
00567 XYpt tp = ptr->old();
00568 XYpt te = ptr->cur();
00569
00570 double Scale;
00571 double dist = te[1]-tp[1];
00572
00573
00574 if(dist < 0)
00575 Scale = 1-(abs(dist));
00576 else
00577 Scale = 1+(abs(dist));
00578
00579 Wtransf xf = _model->obj_to_world() * Wtransf::scaling(Scale,Scale,Scale);
00580
00581 _model->set_xform(xf);
00582
00583 return 0;
00584
00585 }
00586
00587
00588
00589
00590
00591
00592
00593 int
00594 Cam_int_edit::scale_x
00595 (CEvent &e,
00596 State *&s)
00597 {
00598 CAMptr cam (e.view()->cam());
00599 CAMdataptr data(cam->data());
00600 DEVice_2d *ptr=(DEVice_2d *)e._d;
00601
00602 if(_model == NULL)
00603 return 0;
00604
00605 XYpt tp = ptr->old();
00606 XYpt te = ptr->cur();
00607
00608 double Scale;
00609 double dist = te[1]-tp[1];
00610
00611
00612 if(dist < 0)
00613 Scale = 1-(abs(dist));
00614 else
00615 Scale = 1+(abs(dist));
00616
00617 Wtransf xf = _model->obj_to_world() * Wtransf::scaling(Scale,1,1);
00618
00619 _model->set_xform(xf);
00620
00621 return 0;
00622
00623 }
00624
00625
00626
00627
00628
00629
00630 int
00631 Cam_int_edit::scale_y
00632 (CEvent &e,
00633 State *&s)
00634 {
00635 CAMptr cam (e.view()->cam());
00636 CAMdataptr data(cam->data());
00637 DEVice_2d *ptr=(DEVice_2d *)e._d;
00638
00639 if(_model == NULL)
00640 return 0;
00641
00642 XYpt tp = ptr->old();
00643 XYpt te = ptr->cur();
00644
00645 double Scale;
00646 double dist = te[1]-tp[1];
00647
00648
00649 if(dist < 0)
00650 Scale = 1-(abs(dist));
00651 else
00652 Scale = 1+(abs(dist));
00653
00654 Wtransf xf = _model->obj_to_world() * Wtransf::scaling(1,Scale,1);
00655
00656 _model->set_xform(xf);
00657
00658 return 0;
00659
00660 }
00661
00662
00663
00664
00665
00666
00667 int
00668 Cam_int_edit::scale_z
00669 (CEvent &e,
00670 State *&s)
00671 {
00672 CAMptr cam (e.view()->cam());
00673 CAMdataptr data(cam->data());
00674 DEVice_2d *ptr=(DEVice_2d *)e._d;
00675
00676 if(_model == NULL)
00677 return 0;
00678
00679 XYpt tp = ptr->old();
00680 XYpt te = ptr->cur();
00681
00682 double Scale;
00683 double dist = te[1]-tp[1];
00684
00685
00686 if(dist < 0)
00687 Scale = 1-(abs(dist));
00688 else
00689 Scale = 1+(abs(dist));
00690
00691 Wtransf xf = _model->obj_to_world() * Wtransf::scaling(1,1,Scale);
00692
00693 _model->set_xform(xf);
00694
00695 return 0;
00696
00697 }
00698
00699
00700
00701
00702 int
00703 Cam_int_edit::rot_z
00704 (CEvent &e,
00705 State *&s)
00706 {
00707 CAMptr cam (e.view()->cam());
00708 CAMdataptr data(cam->data());
00709 DEVice_2d *ptr=(DEVice_2d *)e._d;
00710
00711
00712 if(_model == NULL)
00713 return 0;
00714
00715 XYpt tp = ptr->old();
00716 XYpt te = ptr->cur();
00717
00718
00719 double angle = (te[0]-tp[0])*3;
00720
00721
00722 Wtransf xf = _model->obj_to_world() * Wtransf::rotation(Wvec::Z(), angle);
00723 _model->set_xform(xf);
00724 return 0;
00725 }
00726
00727
00728
00729
00730
00731 int
00732 Cam_int_edit::rot_y
00733 (CEvent &e,
00734 State *&s)
00735 {
00736 CAMptr cam (e.view()->cam());
00737 CAMdataptr data(cam->data());
00738 DEVice_2d *ptr=(DEVice_2d *)e._d;
00739
00740
00741 if(_model == NULL)
00742 return 0;
00743
00744 XYpt tp = ptr->old();
00745 XYpt te = ptr->cur();
00746
00747
00748 double angle = (te[0]-tp[0])*3;
00749
00750
00751 Wtransf xf = _model->obj_to_world() * Wtransf::rotation(Wvec::Y(), angle);
00752 _model->set_xform(xf);
00753 return 0;
00754 }
00755
00756
00757
00758
00759 int
00760 Cam_int_edit::rot_x
00761 (CEvent &e,
00762 State *&s)
00763 {
00764 CAMptr cam (e.view()->cam());
00765 CAMdataptr data(cam->data());
00766 DEVice_2d *ptr=(DEVice_2d *)e._d;
00767
00768
00769 if(_model == NULL)
00770 return 0;
00771
00772 XYpt tp = ptr->old();
00773 XYpt te = ptr->cur();
00774
00775
00776 double angle = (te[1]-tp[1])*3;
00777
00778
00779 Wtransf xf = _model->obj_to_world() * Wtransf::rotation(Wvec::X(), angle);
00780 _model->set_xform(xf);
00781 return 0;
00782 }
00783
00784
00785
00786
00787
00788 int
00789 Cam_int_edit::edit_down (
00790 CEvent &e,
00791 State *&s)
00792 {
00793 DEVice_buttons *btns = (DEVice_buttons *)e._d;
00794 DEVice_2d *ptr = btns->ptr2d();
00795
00796 _view = e.view();
00797
00798 CAMdataptr data(_view->cam()->data());
00799 RAYhit r (_view->intersect(ptr->cur()));
00800 if (r.success())
00801 _model = (ray_geom(r,GEOM::null));
00802 return 0;
00803
00804 }
00805
00806 int
00807 Cam_int_edit::toggle_buttons(
00808 CEvent &e,
00809 State *&s
00810 )
00811 {
00812 BaseJOTapp::button_toggle(e,s);
00813 return 0;
00814 }