Panda3D
 All Classes Functions Variables Enumerations
mouseWatcher.h
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 &regions, const LPoint2 &pos) const;
00162   static MouseWatcherRegion *get_preferred_region(const Regions &regions);
00163 
00164   void set_current_regions(Regions &regions);
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 &regions_a,
00177                                 const Regions &regions_b);
00178   static bool remove_region_from(Regions &regions,
00179                                  MouseWatcherRegion *region);
00180   static bool has_region_in(const Regions &regions,
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 &param);
00195   void global_keyboard_release(const MouseWatcherParameter &param);
00196 
00197   INLINE void within_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
00198   INLINE void without_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
00199   void enter_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
00200   void exit_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
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
 All Classes Functions Variables Enumerations