00001 #include "geom/world.H"
00002 #include "gtex/buffer_ref_image.H"
00003 #include "std/config.H"
00004
00005 #include "gest_int.H"
00006
00007 using mlib::PIXEL;
00008
00009 static bool debug = Config::get_var_bool("DEBUG_GEST_INT",false);
00010
00011 GEST_INT::GEST_INT(
00012 CVIEWptr& view,
00013 CEvent &d, CEvent &m, CEvent &u,
00014 CEvent &d2, CEvent &u2) :
00015 Simple_int(d,m,u),
00016 _view(view),
00017 _obs(0),
00018 _stack(16),
00019 _drawer(new GestureDrawer()),
00020 _fsa(&_entry),
00021 _keep_history(false),
00022 _num_history(0)
00023 {
00024
00025 _stack.begin_index();
00026
00027
00028 _obs.set_unique();
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 _entry +=
00040 Arc(d2, Cb((_callb::_method) &GEST_INT::null_cb, &_b2_pressed));
00041 _b2_pressed +=
00042 Arc(u2, Cb((_callb::_method) &GEST_INT::null_cb, (State *)-1));
00043
00044
00045 _view->cam()->data()->add_cb(this);
00046 }
00047
00048 void
00049 GEST_INT::rem_obs(GestObs* g)
00050 {
00051 _obs -= g;
00052 if (_obs.empty())
00053 deactivate();
00054 }
00055
00056 void
00057 GEST_INT::add_obs(GestObs* g)
00058 {
00059 _obs += g;
00060 activate();
00061 }
00062
00063 void
00064 GEST_INT::activate()
00065 {
00066
00067 _view->schedule(this);
00068
00069
00070 VIEWint_list::get(_view)->add_interactor(&_fsa);
00071 }
00072
00073 void
00074 GEST_INT::deactivate()
00075 {
00076
00077 _view->unschedule(this);
00078
00079
00080 VIEWint_list::get(_view)->rem_interactor(&_fsa);
00081 }
00082
00083 int
00084 GEST_INT::down(CEvent &e, State *&s)
00085 {
00086
00087 for (int k=0; k<_obs.num(); k++) {
00088 if (_obs[k]->handle_event(e,s))
00089 return 0;
00090 }
00091
00092
00093
00094 DEVice_buttons *btns=(DEVice_buttons *)e._d;
00095 DEVice_2d *ptr=btns->ptr2d();
00096 RAYhit r(ptr->cur());
00097
00098
00099 if (e.view()->intersect(r).success() &&
00100 ray_geom(r,GEOM::null) &&
00101 ray_geom(r,GEOM::null)->interactive(e,s))
00102 return 0;
00103
00104
00105
00106
00107 _stack += new GESTURE(
00108 this, _stack.num(), ptr->cur(), ptr->pressure(), _drawer, e
00109 );
00110
00111 BufferRefImage *buf = BufferRefImage::lookup(_view);
00112 if (buf && (buf->is_observing()))
00113 buf->add(_stack.last());
00114 else
00115 WORLD::display(_stack.last(), false);
00116
00117
00118 return 0;
00119 }
00120
00121 int
00122 GEST_INT::move(CEvent &, State *&)
00123 {
00124
00125 if (!DEVice_2d::last)
00126 return 0;
00127
00128 DEVice_2d* ptr = DEVice_2d::last;
00129
00130 double MIN_DIST = Config::get_var_dbl("GEST_ADD_MIN_DIST", 2.5, true);
00131
00132
00133
00134
00135
00136 if ( !_stack.empty() ) {
00137 _stack.last()->add(
00138 PIXEL(ptr->cur()),
00139 MIN_DIST,
00140 ptr->pressure()
00141 );
00142 } else {
00143 err_adv(debug, "GEST_INT::move: tossing event for missing gesture.");
00144 }
00145 return 0;
00146 }
00147
00148 int
00149 GEST_INT::up(CEvent &e, State *&)
00150 {
00151
00152 if (!DEVice_2d::last)
00153 return 0;
00154
00155 if (_stack.empty()) {
00156
00157
00158
00159 err_adv(debug, "GEST_INT::move: tossing event for missing gesture.");
00160 } else {
00161 _stack.last()->complete(DEVice_2d::last->cur(), e);
00162
00163
00164
00165
00166 BufferRefImage *buf = BufferRefImage::lookup(_view);
00167 if (buf && buf->is_observing())
00168 buf->rem(_stack.last());
00169 else
00170 WORLD::undisplay(_stack.last(), false);
00171
00172 for (int k=0; k<_obs.num(); k++)
00173 _obs[k]->notify_gesture(this, _stack.last());
00174 }
00175
00176 return 0;
00177 }
00178
00179 void
00180 GEST_INT::start_history()
00181 {
00182
00183 err_mesg(ERR_LEV_SPAM, "GEST_INT::start_history()");
00184
00185 if(!_keep_history)
00186 return;
00187
00188 assert(_num_history < _stack.num());
00189
00190
00191 for(int i=0; i<_num_history; i++)
00192 {
00193 err_mesg(ERR_LEV_SPAM, "GEST_INT::start_history() - Clearing history: %d", i);
00194 }
00195
00196 _num_history = 0;
00197 }
00198
00199 void
00200 GEST_INT::notify(CCAMdataptr&)
00201 {
00202
00203
00204
00205
00206 if (!(_stack.empty() || _stack.last()->complete()))
00207 {
00208 err_adv(debug, "GEST_INT::move: undisplaying 'dangling' gesture.");
00209 BufferRefImage *buf = BufferRefImage::lookup(_view);
00210 if (buf && buf->is_observing())
00211 buf->rem(_stack.last());
00212 else
00213 WORLD::undisplay(_stack.last(), false);
00214 }
00215
00216
00217 _stack.clear();
00218 }
00219
00220 int
00221 GEST_INT::tick()
00222 {
00223
00224
00225 return 1;
00226 }
00227
00228