00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
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
00216
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
00277 virtual void do_transmit_data(DataGraphTraverser *trav,
00278 const DataNodeTransmit &input,
00279 DataNodeTransmit &output);
00280
00281 private:
00282
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
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