ソースを参照

support for blobwatcher

David Rose 24 年 前
コミット
f18c25abbd

+ 30 - 0
panda/src/tform/mouseWatcher.I

@@ -405,3 +405,33 @@ INLINE ModifierButtons MouseWatcher::
 get_modifier_buttons() const {
   return _mods;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: MouseWatcher::within_region
+//       Access: Protected
+//  Description: Called internally to indicate the mouse pointer has
+//               moved within the indicated region's boundaries.
+////////////////////////////////////////////////////////////////////
+INLINE void MouseWatcher::
+within_region(MouseWatcherRegion *region, const MouseWatcherParameter &param) {
+  region->within(param);
+  throw_event_pattern(_within_pattern, region, ButtonHandle::none());
+  if (_enter_multiple) {
+    enter_region(region, param);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MouseWatcher::without_region
+//       Access: Protected
+//  Description: Called internally to indicate the mouse pointer has
+//               moved outside of the indicated region's boundaries.
+////////////////////////////////////////////////////////////////////
+INLINE void MouseWatcher::
+without_region(MouseWatcherRegion *region, const MouseWatcherParameter &param) {
+  if (_enter_multiple) {
+    exit_region(region, param);
+  }
+  region->without(param);
+  throw_event_pattern(_without_pattern, region, ButtonHandle::none());
+}

+ 44 - 22
panda/src/tform/mouseWatcher.cxx

@@ -56,6 +56,11 @@ MouseWatcher(const string &name) : DataNode(name) {
   // will only be "within" multiple regions, but "entered" into the
   // topmost of those.
   _enter_multiple = false;
+
+  // When this flag is true, moving the pointer into a region is
+  // enough to click it.  The click is simulated with mouse button
+  // one.
+  _implicit_click = false;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -308,12 +313,7 @@ set_current_regions(MouseWatcher::VRegions &regions) {
     } else if ((*old_ri) < (*new_ri)) {
       // Here's a region we don't have any more.
       MouseWatcherRegion *old_region = (*old_ri);
-      old_region->without(param);
-      throw_event_pattern(_without_pattern, old_region, ButtonHandle::none());
-      if (_enter_multiple) {
-        old_region->exit(param);
-        throw_event_pattern(_leave_pattern, old_region, ButtonHandle::none());
-      }
+      without_region(old_region, param);
       any_changes = true;
       ++old_ri;
 
@@ -335,12 +335,7 @@ set_current_regions(MouseWatcher::VRegions &regions) {
   while (old_ri != _current_regions.end()) {
     // Here's a region we don't have any more.
     MouseWatcherRegion *old_region = (*old_ri);
-    old_region->without(param);
-    throw_event_pattern(_without_pattern, old_region, ButtonHandle::none());
-    if (_enter_multiple) {
-      old_region->exit(param);
-      throw_event_pattern(_leave_pattern, old_region, ButtonHandle::none());
-    }
+    without_region(old_region, param);
     any_changes = true;
     ++old_ri;
   }
@@ -354,12 +349,7 @@ set_current_regions(MouseWatcher::VRegions &regions) {
     vector<MouseWatcherRegion *>::const_iterator ri;
     for (ri = new_regions.begin(); ri != new_regions.end(); ++ri) {
       MouseWatcherRegion *new_region = (*ri);
-      new_region->within(param);
-      throw_event_pattern(_within_pattern, new_region, ButtonHandle::none()); 
-      if (_enter_multiple) {
-        new_region->enter(param);
-        throw_event_pattern(_enter_pattern, new_region, ButtonHandle::none());
-      }
+      within_region(new_region, param);
     }
   }
 
@@ -378,13 +368,11 @@ set_current_regions(MouseWatcher::VRegions &regions) {
 
     if (new_preferred_region != _preferred_region) {
       if (_preferred_region != (MouseWatcherRegion *)NULL) {
-        _preferred_region->exit(param);
-        throw_event_pattern(_leave_pattern, _preferred_region, ButtonHandle::none());
+        exit_region(_preferred_region, param);
       }
       _preferred_region = new_preferred_region;
       if (_preferred_region != (MouseWatcherRegion *)NULL) {
-        _preferred_region->enter(param);
-        throw_event_pattern(_enter_pattern, _preferred_region, ButtonHandle::none());
+        enter_region(_preferred_region, param);
       }
     }
   }
@@ -733,6 +721,40 @@ global_keyboard_release(const MouseWatcherParameter &param) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MouseWatcher::enter_region
+//       Access: Protected
+//  Description: Called internally to indicate the mouse pointer is no
+//               longer favoring the indicated region.
+////////////////////////////////////////////////////////////////////
+void MouseWatcher::
+enter_region(MouseWatcherRegion *region, const MouseWatcherParameter &param) {
+  region->enter(param);
+  throw_event_pattern(_enter_pattern, region, ButtonHandle::none());
+  if (_implicit_click) {
+    MouseWatcherParameter param1(param);
+    param1.set_button(MouseButton::one());
+    region->press(param1);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MouseWatcher::exit_region
+//       Access: Protected
+//  Description: Called internally to indicate the mouse pointer is no
+//               longer favoring the indicated region.
+////////////////////////////////////////////////////////////////////
+void MouseWatcher::
+exit_region(MouseWatcherRegion *region, const MouseWatcherParameter &param) {
+  if (_implicit_click) {
+    MouseWatcherParameter param1(param);
+    param1.set_button(MouseButton::one());
+    region->release(param1);
+  }
+  region->exit(param);
+  throw_event_pattern(_leave_pattern, region, ButtonHandle::none());
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: MouseWatcher::transmit_data
 //       Access: Public

+ 6 - 0
panda/src/tform/mouseWatcher.h

@@ -138,6 +138,11 @@ protected:
   void global_keyboard_press(const MouseWatcherParameter &param);
   void global_keyboard_release(const MouseWatcherParameter &param);
 
+  INLINE void within_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
+  INLINE void without_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
+  void enter_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
+  void exit_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
+
   typedef pset< PT(MouseWatcherGroup) > Groups;
   Groups _groups;
 
@@ -151,6 +156,7 @@ protected:
   bool _button_down;
 
   bool _enter_multiple;
+  bool _implicit_click;
 
   string _button_down_pattern;
   string _button_up_pattern;

+ 1 - 0
panda/src/tform/mouseWatcherGroup.h

@@ -58,6 +58,7 @@ private:
   static TypeHandle _type_handle;
 
   friend class MouseWatcher;
+  friend class BlobWatcher;
 };
 
 #endif

+ 2 - 3
panda/src/tform/mouseWatcherParameter.I

@@ -130,12 +130,11 @@ has_button() const {
 //     Function: MouseWatcherParameter::get_button
 //       Access: Published
 //  Description: Returns the mouse or keyboard button associated with
-//               this event.  It is valid to call this only if
-//               has_button(), above, returned true.
+//               this event.  If has_button(), above, returns false,
+//               this returns ButtonHandle::none().
 ////////////////////////////////////////////////////////////////////
 INLINE ButtonHandle MouseWatcherParameter::
 get_button() const {
-  nassertr(has_button(), ButtonHandle::none());
   return _button;
 }