46MouseWatcher(
const string &name) :
49 _pixel_xy_input = define_input(
"pixel_xy", EventStoreVec2::get_class_type());
50 _pixel_size_input = define_input(
"pixel_size", EventStoreVec2::get_class_type());
51 _xy_input = define_input(
"xy", EventStoreVec2::get_class_type());
52 _button_events_input = define_input(
"button_events", ButtonEventList::get_class_type());
53 _pointer_events_input = define_input(
"pointer_events", PointerEventList::get_class_type());
55 _pixel_xy_output = define_output(
"pixel_xy", EventStoreVec2::get_class_type());
56 _pixel_size_output = define_output(
"pixel_size", EventStoreVec2::get_class_type());
57 _xy_output = define_output(
"xy", EventStoreVec2::get_class_type());
58 _button_events_output = define_output(
"button_events", ButtonEventList::get_class_type());
66 _internal_suppress = 0;
67 _preferred_region =
nullptr;
68 _preferred_button_down_region =
nullptr;
71 _display_region =
nullptr;
72 _button_down_display_region =
nullptr;
74 _frame.set(-1.0f, 1.0f, -1.0f, 1.0f);
76 _inactivity_timeout = inactivity_timeout;
77 _has_inactivity_timeout = !IS_NEARLY_ZERO(_inactivity_timeout);
79 _num_trail_recent = 0;
80 _trail_log_duration = 0.0;
83 _inactivity_timeout_event =
"inactivity_timeout";
85 _inactivity_state = IS_active;
90 _enter_multiple =
false;
94 _implicit_click =
false;
112 remove_region_from(_current_regions, region);
113 if (region == _preferred_region) {
114 if (_preferred_region !=
nullptr) {
117 _preferred_region =
nullptr;
119 if (region == _preferred_button_down_region) {
120 _preferred_button_down_region =
nullptr;
123 return MouseWatcherBase::do_remove_region(region);
136 get_over_regions(regions, pos);
137 return get_preferred_region(regions);
158 Groups::const_iterator gi =
159 find(_groups.begin(), _groups.end(), pt);
160 if (gi != _groups.end()) {
166 if (!_show_regions_render2d.
is_empty()) {
167 group->
show_regions(_show_regions_render2d, _show_regions_bin_name,
168 _show_regions_draw_order);
173 _groups.push_back(pt);
187 group->do_sort_regions();
190 intersect_regions(only_a, only_b, both,
191 _current_regions, group->_regions);
192 set_current_regions(only_a);
194 if (has_region_in(both, _preferred_region)) {
195 if (_preferred_region !=
nullptr) {
198 _preferred_region =
nullptr;
200 if (has_region_in(both, _preferred_button_down_region)) {
201 _preferred_button_down_region =
nullptr;
205 if (!_show_regions_render2d.
is_empty()) {
206 group->do_hide_regions();
212 Groups::iterator gi =
213 find(_groups.begin(), _groups.end(), pt);
214 if (gi != _groups.end()) {
235 if (old_group == new_group) {
245 old_group->do_sort_regions();
246 new_group->do_sort_regions();
249 if (!_show_regions_render2d.
is_empty()) {
250 old_group->do_hide_regions();
251 new_group->do_show_regions(_show_regions_render2d, _show_regions_bin_name,
252 _show_regions_draw_order);
258 intersect_regions(remove, add, keep,
259 old_group->_regions, new_group->_regions);
262 bool any_new_current_regions =
false;
265 if (!remove.
empty()) {
267 intersect_regions(only_a, only_b, both,
268 _current_regions, remove);
269 new_current_regions.
swap(only_a);
270 any_new_current_regions =
true;
272 if (has_region_in(both, _preferred_region)) {
273 if (_preferred_region !=
nullptr) {
276 _preferred_region =
nullptr;
278 if (has_region_in(both, _preferred_button_down_region)) {
279 _preferred_button_down_region =
nullptr;
301 if (any_new_current_regions) {
302 set_current_regions(new_current_regions);
307 Groups::iterator gi =
308 find(_groups.begin(), _groups.end(), pt);
309 if (gi == _groups.end()) {
310 _groups.push_back(new_group);
314 if (!_show_regions_render2d.
is_empty()) {
315 new_group->do_update_regions();
321 gi = find(_groups.begin(), _groups.end(), pt);
322 if (gi != _groups.end()) {
339 return _groups.size();
348 nassertr(n >= 0 && n < (
int)_groups.size(),
nullptr);
359 if (duration < 0.0) {
362 _trail_log_duration = duration;
363 discard_excess_trail_log();
374discard_excess_trail_log() {
375 if (_trail_log_duration == 0.0) {
378 if (_trail_log->get_num_events() > 2) {
380 while ((_trail_log->get_num_events() > 2)&&
381 (_trail_log->get_time(0) <= old)&&
382 (_trail_log->get_time(1) <= old)) {
383 _trail_log->pop_front();
402 if (_trail_node ==
nullptr) {
403 _trail_node =
new GeomNode(
"Mouse Trail Node");
417 _trail_node =
nullptr;
425 if (_trail_node ==
nullptr) {
428 _trail_node->remove_all_geoms();
430 if (_trail_log->get_num_events() < 2) {
441 double xscale = 2.0 / _pixel_size->get_value().get_x();
442 double yscale = 2.0 / _pixel_size->get_value().get_y();
444 for (
int i=0; i<(int)_trail_log->get_num_events(); i++) {
445 double x = (_trail_log->get_xpos(i) * xscale) - 1.0;
446 double y = (_trail_log->get_ypos(i) * yscale) - 1.0;
447 vertex.add_data3(LVecBase3(x,0.0,-y));
448 lines->add_vertex(i);
450 lines->close_primitive();
453 l_geom->add_primitive(lines);
454 _trail_node->add_geom(l_geom);
470 switch (_inactivity_state) {
475 _inactivity_state = IS_inactive_to_active;
478 case IS_active_to_inactive:
479 _inactivity_state = IS_active;
482 case IS_inactive_to_active:
492output(std::ostream &out)
const {
500 size_t count = _regions.size();
502 count += group->get_num_regions();
505 out <<
" (" << count <<
" regions)";
512write(std::ostream &out,
int indent_level)
const {
514 <<
"MouseWatcher " << get_name() <<
":\n";
515 MouseWatcherBase::write(out, indent_level + 2);
519 indent(out, indent_level + 2)
521 group->write(out, indent_level + 4);
531 nassertv(_lock.debug_is_locked());
534 PN_stdfloat mx = (pos[0] + 1.0f) * 0.5f * (_frame[1] - _frame[0]) + _frame[0];
535 PN_stdfloat my = (pos[1] + 1.0f) * 0.5f * (_frame[3] - _frame[2]) + _frame[2];
549 const LVecBase4 &frame = region->get_frame();
551 if (region->get_active() &&
552 mx >= frame[0] && mx <= frame[1] &&
553 my >= frame[2] && my <= frame[3]) {
561 group->sort_regions();
564 const LVecBase4 &frame = region->get_frame();
566 if (region->get_active() &&
567 mx >= frame[0] && mx <= frame[1] &&
568 my >= frame[2] && my <= frame[3]) {
578 sort(regions.
begin(), regions.
end());
588 if (regions.
empty()) {
592 Regions::const_iterator ri;
593 ri = regions.
begin();
596 while (ri != regions.
end()) {
599 if (*region < *preferred) {
617 nassertv(_lock.debug_is_locked());
625 Regions::const_iterator new_ri = regions.
begin();
626 Regions::const_iterator old_ri = _current_regions.
begin();
630 std::vector<MouseWatcherRegion *> new_regions;
632 bool any_changes =
false;
633 while (new_ri != regions.
end() && old_ri != _current_regions.
end()) {
634 if ((*new_ri) < (*old_ri)) {
637 new_regions.push_back(new_region);
641 }
else if ((*old_ri) < (*new_ri)) {
644 without_region(old_region, param);
655 while (new_ri != regions.
end()) {
658 new_regions.push_back(new_region);
663 while (old_ri != _current_regions.
end()) {
666 without_region(old_region, param);
674 _current_regions.
swap(regions);
677 std::vector<MouseWatcherRegion *>::const_iterator ri;
678 for (ri = new_regions.begin(); ri != new_regions.end(); ++ri) {
680 within_region(new_region, param);
684 if (!_enter_multiple) {
689 get_preferred_region(_current_regions);
691 if (_button_down && new_preferred_region != _preferred_button_down_region) {
694 new_preferred_region =
nullptr;
697 if (new_preferred_region != _preferred_region) {
698 if (_preferred_region !=
nullptr) {
699 exit_region(_preferred_region, param);
701 _preferred_region = new_preferred_region;
702 if (_preferred_region !=
nullptr) {
703 enter_region(_preferred_region, param);
713clear_current_regions() {
714 nassertv(_lock.debug_is_locked());
716 if (!_current_regions.
empty()) {
722 Regions::const_iterator old_ri = _current_regions.
begin();
724 while (old_ri != _current_regions.
end()) {
727 without_region(old_region, param);
731 _current_regions.
clear();
733 if (_preferred_region !=
nullptr) {
734 exit_region(_preferred_region, param);
735 _preferred_region =
nullptr;
745do_show_regions(
const NodePath &render2d,
const string &bin_name,
748 MouseWatcherBase::do_show_regions(render2d, bin_name, draw_order);
749 _show_regions_render2d = render2d;
750 _show_regions_bin_name = bin_name;
751 _show_regions_draw_order = draw_order;
754 group->show_regions(render2d, bin_name, draw_order);
766 MouseWatcherBase::do_hide_regions();
767 _show_regions_render2d =
NodePath();
768 _show_regions_bin_name = string();
769 _show_regions_draw_order = 0;
772 group->hide_regions();
793 Regions::const_iterator a_ri = regions_a.
begin();
794 Regions::const_iterator b_ri = regions_b.
begin();
796 while (a_ri != regions_a.
end() && b_ri != regions_b.
end()) {
797 if ((*a_ri) < (*b_ri)) {
802 }
else if ((*b_ri) < (*a_ri)) {
825 Regions::iterator ri = lower_bound(regions.
begin(), regions.
end(), ptr);
826 if (ri != regions.
end() && (*ri) == ptr) {
843 Regions::const_iterator ri = lower_bound(regions.
begin(), regions.
end(), ptr);
844 return (ri != regions.
end() && (*ri) == ptr);
854 if (pattern.empty()) {
858 if (region !=
nullptr) {
864 if (button != ButtonHandle::none()) {
874 for (
size_t p = 0; p < pattern.size(); ++p) {
875 if (pattern[p] ==
'%') {
876 string cmd = pattern.substr(p + 1, 1);
879 if (region !=
nullptr) {
880 event += region->get_name();
883 }
else if (cmd ==
"b") {
888 <<
"Invalid symbol in event_pattern: %" << cmd <<
"\n";
895 if (!event.empty()) {
909 nassertv(_lock.debug_is_locked());
915 if (_preferred_button_down_region !=
nullptr) {
916 _preferred_button_down_region->move(param);
925 nassertv(_lock.debug_is_locked());
937 _preferred_button_down_region = _preferred_region;
941 if (_preferred_button_down_region !=
nullptr) {
942 _preferred_button_down_region->press(param);
944 throw_event_pattern(_button_repeat_pattern,
945 _preferred_button_down_region, button);
947 throw_event_pattern(_button_down_pattern,
948 _preferred_button_down_region, button);
955 if (_preferred_region !=
nullptr) {
958 _preferred_region->press(param);
959 consider_keyboard_suppress(_preferred_region);
962 if ((_internal_suppress & MouseWatcherRegion::SF_other_button) == 0) {
967 global_keyboard_press(param);
977 nassertv(_lock.debug_is_locked());
988 if (_preferred_button_down_region !=
nullptr) {
989 param.
set_outside(_preferred_button_down_region != _preferred_region);
990 _preferred_button_down_region->release(param);
991 throw_event_pattern(_button_up_pattern,
992 _preferred_button_down_region, button);
998 bool has_button =
false;
999 for (
size_t i = 0; i < MouseButton::num_mouse_buttons; ++i) {
1000 if (MouseButton::_buttons[i] != button &&
1001 _current_buttons_down.
get_bit(MouseButton::_buttons[i].get_index())) {
1008 _button_down =
false;
1009 _preferred_button_down_region =
nullptr;
1015 if (_preferred_region !=
nullptr) {
1016 _preferred_region->release(param);
1020 global_keyboard_release(param);
1028keystroke(
int keycode) {
1029 nassertv(_lock.debug_is_locked());
1050 consider_keyboard_suppress(region);
1056 group->sort_regions();
1062 consider_keyboard_suppress(region);
1073candidate(
const std::wstring &candidate_string,
size_t highlight_start,
1074 size_t highlight_end,
size_t cursor_pos) {
1075 nassertv(_lock.debug_is_locked());
1078 param.
set_candidate(candidate_string, highlight_start, highlight_end, cursor_pos);
1099 group->sort_regions();
1117 nassertv(_lock.debug_is_locked());
1125 if (region != _preferred_region && region->
get_keyboard()) {
1126 region->
press(param);
1127 consider_keyboard_suppress(region);
1133 group->sort_regions();
1136 if (region != _preferred_region && region->
get_keyboard()) {
1137 region->
press(param);
1138 consider_keyboard_suppress(region);
1150 nassertv(_lock.debug_is_locked());
1158 if (region != _preferred_region && region->
get_keyboard()) {
1165 group->sort_regions();
1168 if (region != _preferred_region && region->
get_keyboard()) {
1181 nassertv(_lock.debug_is_locked());
1184 throw_event_pattern(_enter_pattern, region, ButtonHandle::none());
1185 if (_implicit_click) {
1188 region->
press(param1);
1198 nassertv(_lock.debug_is_locked());
1200 if (_implicit_click) {
1206 throw_event_pattern(_leave_pattern, region, ButtonHandle::none());
1215 nassertv(_lock.debug_is_locked());
1219 if (!_geometry.is_null()) {
1220 _geometry->set_overall_hidden(
true);
1225 clear_current_regions();
1233set_mouse(
const LVecBase2 &xy,
const LVecBase2 &pixel_xy) {
1234 nassertv(_lock.debug_is_locked());
1236 if (!_geometry.is_null()) {
1238 _geometry->set_transform(TransformState::make_pos(LVecBase3(xy[0], 0, xy[1])));
1241 _geometry->set_overall_hidden(
false);
1247 _mouse_pixel = pixel_xy;
1250 get_over_regions(regions, _mouse);
1251 set_current_regions(regions);
1265 _external_suppress |= MouseWatcherRegion::SF_other_button;
1283 bool activity =
false;
1287 _internal_suppress = 0;
1288 _external_suppress = 0;
1292 DCAST_INTO_V(pixel_size, input.
get_data(_pixel_size_input).
get_ptr());
1293 output.
set_data(_pixel_size_output, pixel_size);
1294 _pixel_size = pixel_size;
1306 const LVecBase2 &last_f = _xy->get_value();
1312 if (_display_region !=
nullptr) {
1314 if (constrain_display_region(_display_region, f, p, current_thread)) {
1323 _internal_suppress |= MouseWatcherRegion::SF_mouse_button;
1333 _num_trail_recent = 0;
1334 if (input.
has_data(_pointer_events_input) && (_trail_log_duration > 0.0)) {
1336 DCAST_INTO_V(this_pointer_events, input.
get_data(_pointer_events_input).
get_ptr());
1338 for (
size_t i = 0; i < _num_trail_recent; i++) {
1340 int xpos = this_pointer_events->
get_xpos(i);
1341 int ypos = this_pointer_events->
get_ypos(i);
1343 double time = this_pointer_events->
get_time(i);
1344 _trail_log->add_event(in_win, xpos, ypos, sequence, time);
1347 if (_trail_log->get_num_events() > 0) {
1348 discard_excess_trail_log();
1349 update_trail_node();
1351 if (_num_trail_recent > _trail_log->get_num_events()) {
1352 _num_trail_recent = _trail_log->get_num_events();
1358 if (_preferred_region !=
nullptr) {
1359 _internal_suppress |= _preferred_region->get_suppress_flags();
1365 if (input.
has_data(_button_events_input)) {
1367 DCAST_INTO_V(this_button_events, input.
get_data(_button_events_input).
get_ptr());
1369 for (
int i = 0; i < num_events; i++) {
1374 case ButtonEvent::T_down:
1380 press(be._button,
false);
1387 case ButtonEvent::T_repeat:
1389 press(be._button,
true);
1394 case ButtonEvent::T_up:
1397 release(be._button);
1401 case ButtonEvent::T_keystroke:
1404 keystroke(be._keycode);
1408 case ButtonEvent::T_candidate:
1410 candidate(be._candidate_string, be._highlight_start, be._highlight_end, be._cursor_pos);
1414 case ButtonEvent::T_resume_down:
1420 case ButtonEvent::T_move:
1424 case ButtonEvent::T_raw_down:
1425 case ButtonEvent::T_raw_up:
1442 if (_has_inactivity_timeout) {
1448 double elapsed = now - _last_activity;
1451 if (elapsed > _inactivity_timeout) {
1452 switch (_inactivity_state) {
1454 _inactivity_state = IS_active_to_inactive;
1460 case IS_active_to_inactive:
1463 case IS_inactive_to_active:
1464 _inactivity_state = IS_inactive;
1471 switch (_inactivity_state) {
1476 case IS_active_to_inactive:
1478 if (tform_cat.is_debug()) {
1480 <<
"MouseWatcher detected " << _inactivity_timeout
1481 <<
" seconds of inactivity; releasing held buttons.\n";
1484 for (
size_t i = 0; i < _current_buttons_down.
get_num_bits(); ++i) {
1485 if (_current_buttons_down.
get_bit(i)) {
1491 _inactivity_state = IS_inactive;
1492 throw_event(_inactivity_timeout_event);
1495 case IS_inactive_to_active:
1498 for (
size_t i = 0; i < _current_buttons_down.
get_num_bits(); ++i) {
1499 if (_current_buttons_down.
get_bit(i)) {
1505 _inactivity_state = IS_active;
1510 (_internal_suppress & MouseWatcherRegion::SF_mouse_position) == 0) {
1512 _xy->set_value(_mouse);
1514 _pixel_xy->set_value(_mouse_pixel);
1519 int suppress_buttons = ((_internal_suppress | _external_suppress) & MouseWatcherRegion::SF_any_button);
1521 _button_events->clear();
1524 for (
int i = 0; i < num_events; i++) {
1526 bool suppress =
true;
1528 if (be._type != ButtonEvent::T_keystroke &&
1530 suppress = ((suppress_buttons & MouseWatcherRegion::SF_mouse_button) != 0);
1532 suppress = ((suppress_buttons & MouseWatcherRegion::SF_other_button) != 0);
1535 if (!suppress || be._type == ButtonEvent::T_up) {
1537 _button_events->add_event(be);
1541 if (_button_events->get_num_events() != 0) {
1554 LVecBase2 &f, LVecBase2 &p,
1555 Thread *current_thread) {
1556 if (!_button_down) {
1557 _button_down_display_region =
nullptr;
1559 if (_button_down_display_region !=
nullptr) {
1563 display_region = _button_down_display_region;
1570 DCAST_INTO_R(stereo_display_region, display_region,
false);
1571 return constrain_display_region(stereo_display_region->
get_left_eye(), f, p, current_thread) ||
1572 constrain_display_region(stereo_display_region->
get_right_eye(), f, p, current_thread);
1577 PN_stdfloat left, right, bottom, top;
1578 dr_reader.get_dimensions(left, right, bottom, top);
1581 PN_stdfloat x = (f[0] + 1.0f) / 2.0f;
1582 PN_stdfloat y = (f[1] + 1.0f) / 2.0f;
1584 if (_button_down_display_region ==
nullptr &&
1585 (x < left || x >= right || y < bottom || y >= top)) {
1592 _button_down_display_region = display_region;
1596 PN_stdfloat xp = (x - left) / (right - left);
1598 PN_stdfloat xpp = (xp * 2.0f) - 1.0f;
1600 PN_stdfloat yp = (y - bottom) / (top - bottom);
1601 PN_stdfloat ypp = (yp * 2.0f) - 1.0f;
1607 p.set(p[0] - xo, p[1] - yo);
void clear_bit(int index)
Sets the nth bit off.
size_t get_num_bits() const
Returns the current number of possibly different bits in this array.
void set_bit(int index)
Sets the nth bit on.
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
This object supervises the traversal of the data graph and the moving of data from one DataNode to it...
Thread * get_current_thread() const
Returns the currently-executing thread object, as passed to the DataGraphTraverser constructor.
Encapsulates the data generated from (or sent into) any particular DataNode.
const EventParameter & get_data(int index) const
Extracts the data for the indicated index, if it has been stored, or the empty parameter if it has no...
void set_data(int index, const EventParameter &data)
Sets the data for the indicated parameter.
bool has_data(int index) const
Returns true if the indicated parameter has been stored, false otherwise.
The fundamental type of node for the data graph.
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
A rectangular subregion within a window for rendering into.
is_stereo
Returns true if this is a StereoDisplayRegion, false otherwise.
void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const
Similar to get_region_pixels(), but returns the upper left corner, and the pixel numbers are numbered...
An optional parameter associated with an event.
TypedWritableReferenceCount * get_ptr() const
Retrieves a pointer to the actual value stored in the parameter.
Defines a series of line strips.
A node that holds Geom objects, renderable pieces of geometry.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A container for geometry primitives.
Similar to MutexHolder, but for a light mutex.
void show_regions(const NodePath &render2d, const std::string &bin_name, int draw_order)
Enables the visualization of all of the regions handled by this MouseWatcherBase.
This represents a collection of MouseWatcherRegions that may be managed as a group.
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
void set_keyrepeat(bool flag)
Sets the state of the "keyrepeat" flag.
void set_mouse(const LPoint2 &mouse)
Sets the mouse position that was current at the time the event was generated.
void set_keycode(int keycode)
Sets the keycode associated with this event, if any.
void set_modifier_buttons(const ModifierButtons &mods)
Sets the modifier buttons that were being held while this event was generated.
void set_candidate(const std::wstring &candidate_string, size_t highlight_start, size_t higlight_end, size_t cursor_pos)
Sets the candidate string associated with this event, if any.
void set_outside(bool flag)
Sets the state of the "outside" flag.
void set_button(const ButtonHandle &button)
Sets the mouse or keyboard button that generated this event, if any.
This is the class that defines a rectangular region on the screen for the MouseWatcher.
virtual void release(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
virtual void keystroke(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever a keystroke is generated by the user.
virtual void exit_region(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever the mouse exits the region.
virtual void press(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
get_suppress_flags
Returns the current suppress_flags.
virtual void enter_region(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever the mouse enters the region.
virtual void candidate(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever an IME candidate is highlighted by the user.
get_keyboard
Returns whether the region is interested in global keyboard events; see set_keyboard().
This TFormer maintains a list of rectangular regions on the screen that are considered special mouse ...
bool add_group(MouseWatcherGroup *group)
Adds the indicated group of regions to the set of regions the MouseWatcher will monitor each frame.
bool remove_group(MouseWatcherGroup *group)
Removes the indicated group from the set of extra groups associated with the MouseWatcher.
void set_trail_log_duration(double duration)
If the duration is nonzero, causes the MouseWatcher to log the mouse's trail.
get_group
Returns the nth group added to the MouseWatcher via add_group().
bool replace_group(MouseWatcherGroup *old_group, MouseWatcherGroup *new_group)
Atomically removes old_group from the MouseWatcher, and replaces it with new_group.
void clear_trail_node()
If you have previously fetched the trail node using get_trail_node, then the MouseWatcher is continua...
void note_activity()
Can be used in conjunction with the inactivity timeout to inform the MouseWatcher that the user has j...
bool remove_region(MouseWatcherRegion *region)
Removes the indicated region from the group.
MouseWatcherRegion * get_over_region() const
Returns the smallest region the mouse is currently over, or NULL if it is over no region.
get_num_groups
Returns the number of separate groups added to the MouseWatcher via add_group().
void output(std::ostream &out) const
Outputs the Namable.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
bool is_empty() const
Returns true if the NodePath contains no nodes.
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
get_value
Retrieves the value stored in the parameter.
Records a set of pointer events that happened recently.
int get_xpos(size_t n) const
Get the x-coordinate of the nth event.
int get_sequence(size_t n) const
Get the sequence number of the nth event.
double get_time(size_t n) const
Get the timestamp of the nth event.
size_t get_num_events() const
Returns the number of events in the list.
int get_ypos(size_t n) const
Get the y-coordinate of the nth event.
bool get_in_window(size_t n) const
Get the in-window flag of the nth event.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
This is a special DisplayRegion wrapper that actually includes a pair of DisplayRegions internally: t...
get_right_eye
Returns a pointer to the right DisplayRegion managed by this stereo object.
get_left_eye
Returns a pointer to the left DisplayRegion managed by this stereo object.
A thread; that is, a lightweight process.
TypeHandle is the identifier used to differentiate C++ class types.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
void push_back(const value_type_0 &key)
Adds the new element to the end of the vector without regard for proper sorting.
void swap(ordered_vector< Key, Compare, Vector > &other)
Exchanges the contents of this vector and the other vector, in constant time (e.g....
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
void clear()
Removes all elements from the ordered vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.