Panda3D
|
00001 // Filename: mouseWatcher.h 00002 // Created by: drose (12Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef MOUSEWATCHER_H 00016 #define MOUSEWATCHER_H 00017 00018 #include "pandabase.h" 00019 00020 #include "mouseWatcherRegion.h" 00021 #include "mouseWatcherGroup.h" 00022 #include "dataNode.h" 00023 #include "luse.h" 00024 #include "pointerTo.h" 00025 #include "eventHandler.h" 00026 #include "modifierButtons.h" 00027 #include "buttonHandle.h" 00028 #include "buttonEventList.h" 00029 #include "pointerEvent.h" 00030 #include "pointerEventList.h" 00031 #include "linmath_events.h" 00032 #include "bitArray.h" 00033 #include "clockObject.h" 00034 #include "pvector.h" 00035 #include "displayRegion.h" 00036 00037 class MouseWatcherParameter; 00038 class DisplayRegion; 00039 00040 //////////////////////////////////////////////////////////////////// 00041 // Class : MouseWatcher 00042 // Description : This TFormer maintains a list of rectangular regions 00043 // on the screen that are considered special mouse 00044 // regions; typically these will be click buttons. When 00045 // the mouse passes in or out of one of these regions, 00046 // or when a button is clicked while the mouse is in one 00047 // of these regions, an event is thrown. 00048 // 00049 // Mouse events may also be suppressed from the rest of 00050 // the datagraph in these special regions. 00051 // 00052 // This class can also implement a software mouse 00053 // pointer by automatically generating a transform to 00054 // apply to a piece of geometry placed under the 2-d 00055 // scene graph. It will move the geometry around 00056 // according to the mouse's known position. 00057 // 00058 // Finally, this class can keep a record of the mouse 00059 // trail. This is useful if you want to know, not just 00060 // where the mouse is, but the exact sequence of movements 00061 // it took to get there. This information is mainly useful 00062 // for gesture-recognition code. To use trail logging, 00063 // you need to enable the generation of pointer events 00064 // in the GraphicsWindowInputDevice and set the trail 00065 // log duration in the MouseWatcher. Otherwise, the 00066 // trail log will be empty. 00067 //////////////////////////////////////////////////////////////////// 00068 class EXPCL_PANDA_TFORM MouseWatcher : public DataNode, public MouseWatcherGroup { 00069 PUBLISHED: 00070 MouseWatcher(const string &name = ""); 00071 ~MouseWatcher(); 00072 00073 bool remove_region(MouseWatcherRegion *region); 00074 00075 INLINE bool has_mouse() const; 00076 INLINE bool is_mouse_open() const; 00077 INLINE const LPoint2 &get_mouse() const; 00078 INLINE PN_stdfloat get_mouse_x() const; 00079 INLINE PN_stdfloat get_mouse_y() const; 00080 00081 INLINE void set_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top); 00082 INLINE void set_frame(const LVecBase4 &frame); 00083 INLINE const LVecBase4 &get_frame() const; 00084 00085 INLINE bool is_over_region() const; 00086 INLINE bool is_over_region(PN_stdfloat x, PN_stdfloat y) const; 00087 INLINE bool is_over_region(const LPoint2 &pos) const; 00088 00089 INLINE MouseWatcherRegion *get_over_region() const; 00090 INLINE MouseWatcherRegion *get_over_region(PN_stdfloat x, PN_stdfloat y) const; 00091 MouseWatcherRegion *get_over_region(const LPoint2 &pos) const; 00092 00093 INLINE bool is_button_down(ButtonHandle button) const; 00094 00095 INLINE void set_button_down_pattern(const string &pattern); 00096 INLINE const string &get_button_down_pattern() const; 00097 00098 INLINE void set_button_up_pattern(const string &pattern); 00099 INLINE const string &get_button_up_pattern() const; 00100 00101 INLINE void set_button_repeat_pattern(const string &pattern); 00102 INLINE const string &get_button_repeat_pattern() const; 00103 00104 INLINE void set_enter_pattern(const string &pattern); 00105 INLINE const string &get_enter_pattern() const; 00106 00107 INLINE void set_leave_pattern(const string &pattern); 00108 INLINE const string &get_leave_pattern() const; 00109 00110 INLINE void set_within_pattern(const string &pattern); 00111 INLINE const string &get_within_pattern() const; 00112 00113 INLINE void set_without_pattern(const string &pattern); 00114 INLINE const string &get_without_pattern() const; 00115 00116 INLINE void set_geometry(PandaNode *node); 00117 INLINE bool has_geometry() const; 00118 INLINE PandaNode *get_geometry() const; 00119 INLINE void clear_geometry(); 00120 00121 INLINE void set_extra_handler(EventHandler *eh); 00122 INLINE EventHandler *get_extra_handler() const; 00123 00124 INLINE void set_modifier_buttons(const ModifierButtons &mods); 00125 INLINE ModifierButtons get_modifier_buttons() const; 00126 00127 INLINE void set_display_region(DisplayRegion *dr); 00128 INLINE void clear_display_region(); 00129 INLINE DisplayRegion *get_display_region() const; 00130 INLINE bool has_display_region() const; 00131 00132 bool add_group(MouseWatcherGroup *group); 00133 bool remove_group(MouseWatcherGroup *group); 00134 bool replace_group(MouseWatcherGroup *old_group, MouseWatcherGroup *new_group); 00135 int get_num_groups() const; 00136 MouseWatcherGroup *get_group(int n) const; 00137 MAKE_SEQ(get_groups, get_num_groups, get_group); 00138 00139 INLINE void set_inactivity_timeout(double timeout); 00140 INLINE bool has_inactivity_timeout() const; 00141 INLINE double get_inactivity_timeout() const; 00142 INLINE void clear_inactivity_timeout(); 00143 00144 INLINE void set_inactivity_timeout_event(const string &event); 00145 INLINE const string &get_inactivity_timeout_event() const; 00146 00147 INLINE CPT(PointerEventList) get_trail_log() const; 00148 INLINE int num_trail_recent() const; 00149 void set_trail_log_duration(double duration); 00150 PT(GeomNode) get_trail_node(); 00151 void clear_trail_node(); 00152 INLINE void clear_trail_log(); 00153 00154 void note_activity(); 00155 00156 public: 00157 virtual void output(ostream &out) const; 00158 virtual void write(ostream &out, int indent_level = 0) const; 00159 00160 protected: 00161 void get_over_regions(Regions ®ions, const LPoint2 &pos) const; 00162 static MouseWatcherRegion *get_preferred_region(const Regions ®ions); 00163 00164 void set_current_regions(Regions ®ions); 00165 void clear_current_regions(); 00166 00167 #ifndef NDEBUG 00168 virtual void do_show_regions(const NodePath &render2d, 00169 const string &bin_name, int draw_order); 00170 virtual void do_hide_regions(); 00171 #endif // NDEBUG 00172 00173 static void intersect_regions(Regions &only_a, 00174 Regions &only_b, 00175 Regions &both, 00176 const Regions ®ions_a, 00177 const Regions ®ions_b); 00178 static bool remove_region_from(Regions ®ions, 00179 MouseWatcherRegion *region); 00180 static bool has_region_in(const Regions ®ions, 00181 MouseWatcherRegion *region); 00182 00183 void throw_event_pattern(const string &pattern, 00184 const MouseWatcherRegion *region, 00185 const ButtonHandle &button); 00186 00187 void move(); 00188 void press(ButtonHandle button, bool keyrepeat); 00189 void release(ButtonHandle button); 00190 void keystroke(int keycode); 00191 void candidate(const wstring &candidate, size_t highlight_start, 00192 size_t highlight_end, size_t cursor_pos); 00193 00194 void global_keyboard_press(const MouseWatcherParameter ¶m); 00195 void global_keyboard_release(const MouseWatcherParameter ¶m); 00196 00197 INLINE void within_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m); 00198 INLINE void without_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m); 00199 void enter_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m); 00200 void exit_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m); 00201 00202 void set_no_mouse(); 00203 void set_mouse(const LVecBase2 &xy, const LVecBase2 &pixel_xy); 00204 00205 private: 00206 void consider_keyboard_suppress(const MouseWatcherRegion *region); 00207 void discard_excess_trail_log(); 00208 void update_trail_node(); 00209 00210 static bool constrain_display_region(DisplayRegion *display_region, 00211 LVecBase2 &f, LVecBase2 &p, 00212 Thread *current_thread); 00213 00214 private: 00215 // This wants to be a set, but because you cannot export sets across 00216 // dlls in windows, we will make it a vector instead 00217 typedef pvector< PT(MouseWatcherGroup) > Groups; 00218 Groups _groups; 00219 00220 bool _has_mouse; 00221 int _internal_suppress; 00222 int _external_suppress; 00223 LPoint2 _mouse; 00224 LPoint2 _mouse_pixel; 00225 BitArray _current_buttons_down; 00226 00227 LVecBase4 _frame; 00228 00229 PT(PointerEventList) _trail_log; 00230 int _num_trail_recent; 00231 double _trail_log_duration; 00232 PT(GeomNode) _trail_node; 00233 00234 Regions _current_regions; 00235 PT(MouseWatcherRegion) _preferred_region; 00236 PT(MouseWatcherRegion) _preferred_button_down_region; 00237 bool _button_down; 00238 00239 bool _enter_multiple; 00240 bool _implicit_click; 00241 00242 string _button_down_pattern; 00243 string _button_up_pattern; 00244 string _button_repeat_pattern; 00245 string _enter_pattern; 00246 string _leave_pattern; 00247 string _within_pattern; 00248 string _without_pattern; 00249 00250 PT(PandaNode) _geometry; 00251 00252 EventHandler *_eh; 00253 ModifierButtons _mods; 00254 DisplayRegion *_display_region; 00255 00256 bool _has_inactivity_timeout; 00257 double _inactivity_timeout; 00258 string _inactivity_timeout_event; 00259 double _last_activity; 00260 00261 enum InactivityState { 00262 IS_active, 00263 IS_inactive, 00264 IS_active_to_inactive, 00265 IS_inactive_to_active, 00266 }; 00267 InactivityState _inactivity_state; 00268 00269 #ifndef NDEBUG 00270 NodePath _show_regions_render2d; 00271 string _show_regions_bin_name; 00272 int _show_regions_draw_order; 00273 #endif 00274 00275 protected: 00276 // Inherited from DataNode 00277 virtual void do_transmit_data(DataGraphTraverser *trav, 00278 const DataNodeTransmit &input, 00279 DataNodeTransmit &output); 00280 00281 private: 00282 // inputs 00283 int _pixel_xy_input; 00284 int _pixel_size_input; 00285 int _xy_input; 00286 int _button_events_input; 00287 int _pointer_events_input; 00288 00289 // outputs 00290 int _pixel_xy_output; 00291 int _pixel_size_output; 00292 int _xy_output; 00293 int _button_events_output; 00294 00295 PT(EventStoreVec2) _pixel_xy; 00296 PT(EventStoreVec2) _xy; 00297 PT(EventStoreVec2) _pixel_size; 00298 PT(ButtonEventList) _button_events; 00299 00300 public: 00301 static TypeHandle get_class_type() { 00302 return _type_handle; 00303 } 00304 static void init_type() { 00305 DataNode::init_type(); 00306 register_type(_type_handle, "MouseWatcher", 00307 DataNode::get_class_type()); 00308 } 00309 virtual TypeHandle get_type() const { 00310 return get_class_type(); 00311 } 00312 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00313 00314 private: 00315 static TypeHandle _type_handle; 00316 }; 00317 00318 #include "mouseWatcher.I" 00319 00320 #endif