46 MouseWatcher(
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()) {
337 get_num_groups()
const {
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();
374 discard_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;
424 update_trail_node() {
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:
492 output(std::ostream &out)
const {
494 DataNode::output(out);
500 size_t count = _regions.size();
502 count += group->get_num_regions();
505 out <<
" (" << count <<
" regions)";
512 write(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();
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());
622 param.set_mouse(_mouse);
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);
713 clear_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()) {
728 throw_event_pattern(_leave_pattern, old_region, ButtonHandle::none());
732 _current_regions.
clear();
734 if (_preferred_region !=
nullptr) {
735 _preferred_region->exit_region(param);
736 throw_event_pattern(_leave_pattern, _preferred_region, ButtonHandle::none());
737 _preferred_region =
nullptr;
748 do_show_regions(
const NodePath &render2d,
const string &bin_name,
750 MouseWatcherBase::do_show_regions(render2d, bin_name, draw_order);
751 _show_regions_render2d = render2d;
752 _show_regions_bin_name = bin_name;
753 _show_regions_draw_order = draw_order;
756 group->show_regions(render2d, bin_name, draw_order);
768 MouseWatcherBase::do_hide_regions();
769 _show_regions_render2d =
NodePath();
770 _show_regions_bin_name = string();
771 _show_regions_draw_order = 0;
774 group->hide_regions();
795 Regions::const_iterator a_ri = regions_a.
begin();
796 Regions::const_iterator b_ri = regions_b.
begin();
798 while (a_ri != regions_a.
end() && b_ri != regions_b.
end()) {
799 if ((*a_ri) < (*b_ri)) {
804 }
else if ((*b_ri) < (*a_ri)) {
827 Regions::iterator ri = lower_bound(regions.
begin(), regions.
end(), ptr);
828 if (ri != regions.
end() && (*ri) == ptr) {
845 Regions::const_iterator ri = lower_bound(regions.
begin(), regions.
end(), ptr);
846 return (ri != regions.
end() && (*ri) == ptr);
856 if (pattern.empty()) {
860 if (region !=
nullptr) {
866 if (button != ButtonHandle::none()) {
876 for (
size_t p = 0; p < pattern.size(); ++p) {
877 if (pattern[p] ==
'%') {
878 string cmd = pattern.substr(p + 1, 1);
881 if (region !=
nullptr) {
882 event += region->get_name();
885 }
else if (cmd ==
"b") {
890 <<
"Invalid symbol in event_pattern: %" << cmd <<
"\n";
897 if (!event.empty()) {
911 nassertv(_lock.debug_is_locked());
915 param.set_mouse(_mouse);
917 if (_preferred_button_down_region !=
nullptr) {
918 _preferred_button_down_region->move(param);
927 nassertv(_lock.debug_is_locked());
931 param.set_keyrepeat(keyrepeat);
932 param.set_modifier_buttons(_mods);
933 param.set_mouse(_mouse);
939 _preferred_button_down_region = _preferred_region;
943 if (_preferred_button_down_region !=
nullptr) {
944 _preferred_button_down_region->press(param);
946 throw_event_pattern(_button_repeat_pattern,
947 _preferred_button_down_region, button);
949 throw_event_pattern(_button_down_pattern,
950 _preferred_button_down_region, button);
957 if (_preferred_region !=
nullptr) {
960 _preferred_region->press(param);
961 consider_keyboard_suppress(_preferred_region);
964 if ((_internal_suppress & MouseWatcherRegion::SF_other_button) == 0) {
968 param.set_outside(
true);
969 global_keyboard_press(param);
979 nassertv(_lock.debug_is_locked());
983 param.set_modifier_buttons(_mods);
984 param.set_mouse(_mouse);
993 if (_preferred_button_down_region !=
nullptr) {
994 param.set_outside(_preferred_button_down_region != _preferred_region);
995 _preferred_button_down_region->release(param);
996 throw_event_pattern(_button_up_pattern,
997 _preferred_button_down_region, button);
1000 _button_down =
false;
1001 _preferred_button_down_region =
nullptr;
1006 if (_preferred_region !=
nullptr) {
1007 _preferred_region->release(param);
1010 param.set_outside(
true);
1011 global_keyboard_release(param);
1019 keystroke(
int keycode) {
1020 nassertv(_lock.debug_is_locked());
1024 param.set_modifier_buttons(_mods);
1025 param.set_mouse(_mouse);
1039 param.set_outside(region != _preferred_region);
1041 consider_keyboard_suppress(region);
1047 group->sort_regions();
1051 param.set_outside(region != _preferred_region);
1053 consider_keyboard_suppress(region);
1064 candidate(
const std::wstring &candidate_string,
size_t highlight_start,
1065 size_t highlight_end,
size_t cursor_pos) {
1066 nassertv(_lock.debug_is_locked());
1069 param.
set_candidate(candidate_string, highlight_start, highlight_end, cursor_pos);
1070 param.set_modifier_buttons(_mods);
1071 param.set_mouse(_mouse);
1083 param.set_outside(region != _preferred_region);
1090 group->sort_regions();
1094 param.set_outside(region != _preferred_region);
1108 nassertv(_lock.debug_is_locked());
1116 if (region != _preferred_region && region->
get_keyboard()) {
1117 region->
press(param);
1118 consider_keyboard_suppress(region);
1124 group->sort_regions();
1127 if (region != _preferred_region && region->
get_keyboard()) {
1128 region->
press(param);
1129 consider_keyboard_suppress(region);
1141 nassertv(_lock.debug_is_locked());
1149 if (region != _preferred_region && region->
get_keyboard()) {
1156 group->sort_regions();
1159 if (region != _preferred_region && region->
get_keyboard()) {
1172 nassertv(_lock.debug_is_locked());
1175 throw_event_pattern(_enter_pattern, region, ButtonHandle::none());
1176 if (_implicit_click) {
1179 region->
press(param1);
1189 nassertv(_lock.debug_is_locked());
1191 if (_implicit_click) {
1197 throw_event_pattern(_leave_pattern, region, ButtonHandle::none());
1206 nassertv(_lock.debug_is_locked());
1210 if (!_geometry.is_null()) {
1211 _geometry->set_overall_hidden(
true);
1216 clear_current_regions();
1224 set_mouse(
const LVecBase2 &xy,
const LVecBase2 &pixel_xy) {
1225 nassertv(_lock.debug_is_locked());
1227 if (!_geometry.is_null()) {
1229 _geometry->set_transform(TransformState::make_pos(LVecBase3(xy[0], 0, xy[1])));
1232 _geometry->set_overall_hidden(
false);
1238 _mouse_pixel = pixel_xy;
1241 get_over_regions(regions, _mouse);
1242 set_current_regions(regions);
1256 _external_suppress |= MouseWatcherRegion::SF_other_button;
1274 bool activity =
false;
1278 _internal_suppress = 0;
1279 _external_suppress = 0;
1283 DCAST_INTO_V(pixel_size, input.
get_data(_pixel_size_input).
get_ptr());
1284 output.
set_data(_pixel_size_output, pixel_size);
1285 _pixel_size = pixel_size;
1297 const LVecBase2 &last_f = _xy->get_value();
1303 if (_display_region !=
nullptr) {
1305 if (constrain_display_region(_display_region, f, p, current_thread)) {
1314 _internal_suppress |= MouseWatcherRegion::SF_mouse_button;
1324 _num_trail_recent = 0;
1325 if (input.
has_data(_pointer_events_input) && (_trail_log_duration > 0.0)) {
1327 DCAST_INTO_V(this_pointer_events, input.
get_data(_pointer_events_input).
get_ptr());
1329 for (
size_t i = 0; i < _num_trail_recent; i++) {
1331 int xpos = this_pointer_events->
get_xpos(i);
1332 int ypos = this_pointer_events->
get_ypos(i);
1334 double time = this_pointer_events->
get_time(i);
1335 _trail_log->add_event(in_win, xpos, ypos, sequence, time);
1338 if (_trail_log->get_num_events() > 0) {
1339 discard_excess_trail_log();
1340 update_trail_node();
1342 if (_num_trail_recent > _trail_log->get_num_events()) {
1343 _num_trail_recent = _trail_log->get_num_events();
1349 if (_preferred_region !=
nullptr) {
1350 _internal_suppress |= _preferred_region->get_suppress_flags();
1356 if (input.
has_data(_button_events_input)) {
1358 DCAST_INTO_V(this_button_events, input.
get_data(_button_events_input).
get_ptr());
1360 for (
int i = 0; i < num_events; i++) {
1365 case ButtonEvent::T_down:
1371 press(be._button,
false);
1378 case ButtonEvent::T_repeat:
1380 press(be._button,
true);
1385 case ButtonEvent::T_up:
1388 release(be._button);
1392 case ButtonEvent::T_keystroke:
1395 keystroke(be._keycode);
1399 case ButtonEvent::T_candidate:
1401 candidate(be._candidate_string, be._highlight_start, be._highlight_end, be._cursor_pos);
1405 case ButtonEvent::T_resume_down:
1411 case ButtonEvent::T_move:
1415 case ButtonEvent::T_raw_down:
1416 case ButtonEvent::T_raw_up:
1433 if (_has_inactivity_timeout) {
1439 double elapsed = now - _last_activity;
1442 if (elapsed > _inactivity_timeout) {
1443 switch (_inactivity_state) {
1445 _inactivity_state = IS_active_to_inactive;
1451 case IS_active_to_inactive:
1454 case IS_inactive_to_active:
1455 _inactivity_state = IS_inactive;
1462 switch (_inactivity_state) {
1467 case IS_active_to_inactive:
1469 if (tform_cat.is_debug()) {
1471 <<
"MouseWatcher detected " << _inactivity_timeout
1472 <<
" seconds of inactivity; releasing held buttons.\n";
1475 for (
size_t i = 0; i < _current_buttons_down.
get_num_bits(); ++i) {
1476 if (_current_buttons_down.
get_bit(i)) {
1482 _inactivity_state = IS_inactive;
1483 throw_event(_inactivity_timeout_event);
1486 case IS_inactive_to_active:
1489 for (
size_t i = 0; i < _current_buttons_down.
get_num_bits(); ++i) {
1490 if (_current_buttons_down.
get_bit(i)) {
1496 _inactivity_state = IS_active;
1501 (_internal_suppress & MouseWatcherRegion::SF_mouse_position) == 0) {
1503 _xy->set_value(_mouse);
1505 _pixel_xy->set_value(_mouse_pixel);
1510 int suppress_buttons = ((_internal_suppress | _external_suppress) & MouseWatcherRegion::SF_any_button);
1512 _button_events->clear();
1515 for (
int i = 0; i < num_events; i++) {
1517 bool suppress =
true;
1519 if (be._type != ButtonEvent::T_keystroke &&
1521 suppress = ((suppress_buttons & MouseWatcherRegion::SF_mouse_button) != 0);
1523 suppress = ((suppress_buttons & MouseWatcherRegion::SF_other_button) != 0);
1526 if (!suppress || be._type == ButtonEvent::T_up) {
1528 _button_events->add_event(be);
1532 if (_button_events->get_num_events() != 0) {
1545 LVecBase2 &f, LVecBase2 &p,
1546 Thread *current_thread) {
1547 if (!_button_down) {
1548 _button_down_display_region =
nullptr;
1550 if (_button_down_display_region !=
nullptr) {
1554 display_region = _button_down_display_region;
1561 DCAST_INTO_R(stereo_display_region, display_region,
false);
1562 return constrain_display_region(stereo_display_region->
get_left_eye(), f, p, current_thread) ||
1563 constrain_display_region(stereo_display_region->
get_right_eye(), f, p, current_thread);
1568 PN_stdfloat left, right, bottom, top;
1569 dr_reader.get_dimensions(left, right, bottom, top);
1572 PN_stdfloat x = (f[0] + 1.0f) / 2.0f;
1573 PN_stdfloat y = (f[1] + 1.0f) / 2.0f;
1575 if (_button_down_display_region ==
nullptr &&
1576 (x < left || x >= right || y < bottom || y >= top)) {
1583 _button_down_display_region = display_region;
1587 PN_stdfloat xp = (x - left) / (right - left);
1589 PN_stdfloat xpp = (xp * 2.0f) - 1.0f;
1591 PN_stdfloat yp = (y - bottom) / (top - bottom);
1592 PN_stdfloat ypp = (yp * 2.0f) - 1.0f;
1598 p.set(p[0] - xo, p[1] - yo);
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
size_t get_num_events() const
Returns the number of events in the list.
MouseWatcherRegion * get_over_region() const
Returns the smallest region the mouse is currently over, or NULL if it is over no region.
This TFormer maintains a list of rectangular regions on the screen that are considered special mouse ...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
The fundamental type of node for the data graph.
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
This represents a collection of MouseWatcherRegions that may be managed as a group.
void set_modifier_buttons(const ModifierButtons &mods)
Sets the modifier buttons that were being held while this event was generated.
int get_ypos(size_t n) const
Get the y-coordinate of the nth event.
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.
An optional parameter associated with an event.
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void exit_region(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever the mouse exits the region.
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...
bool is_empty() const
Returns true if the NodePath contains no nodes.
get_keyboard
Returns whether the region is interested in global keyboard events; see set_keyboard().
void clear()
Removes all elements from the ordered vector.
virtual void release(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
get_value
Retrieves the value stored in the parameter.
bool remove_region(MouseWatcherRegion *region)
Removes the indicated region from the group.
void set_trail_log_duration(double duration)
If the duration is nonzero, causes the MouseWatcher to log the mouse's trail.
void set_button(const ButtonHandle &button)
Sets the mouse or keyboard button that generated this event, if any.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
int get_xpos(size_t n) const
Get the x-coordinate of the nth event.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void enter_region(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever the mouse enters the region.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Records a set of pointer events that happened recently.
is_stereo
Returns true if this is a StereoDisplayRegion, false otherwise.
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_sequence(size_t n) const
Get the sequence number of the nth event.
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.
double get_time(size_t n) const
Get the timestamp of the nth event.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_data(int index) const
Returns true if the indicated parameter has been stored, false otherwise.
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
void swap(ordered_vector< Key, Compare, Vector > &other)
Exchanges the contents of this vector and the other vector, in constant time (e.g....
void clear_bit(int index)
Sets the nth bit off.
virtual void press(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
virtual void candidate(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever an IME candidate is highlighted by the user.
void set_data(int index, const EventParameter &data)
Sets the data for the indicated parameter.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
void set_mouse(const LPoint2 &mouse)
Sets the mouse position that was current at the time the event was generated.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Similar to MutexHolder, but for a light mutex.
This is the class that defines a rectangular region on the screen for the MouseWatcher.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
get_group
Returns the nth group added to the MouseWatcher via add_group().
get_suppress_flags
Returns the current suppress_flags.
Thread * get_current_thread() const
Returns the currently-executing thread object, as passed to the DataGraphTraverser constructor.
get_right_eye
Returns a pointer to the right DisplayRegion managed by this stereo object.
void set_keycode(int keycode)
Sets the keycode associated with this event, if any.
TypedWritableReferenceCount * get_ptr() const
Retrieves a pointer to the actual value stored in the parameter.
This is a special DisplayRegion wrapper that actually includes a pair of DisplayRegions internally: t...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void push_back(const value_type_0 &key)
Adds the new element to the end of the vector without regard for proper sorting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_bit(int index)
Sets the nth bit on.
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...
bool add_group(MouseWatcherGroup *group)
Adds the indicated group of regions to the set of regions the MouseWatcher will monitor each frame.
get_active
Returns whether the region is active or not.
virtual void keystroke(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever a keystroke is generated by the user.
PT(GeomNode) MouseWatcher
Returns a GeomNode that represents the mouse trail.
void note_activity()
Can be used in conjunction with the inactivity timeout to inform the MouseWatcher that the user has j...
A thread; that is, a lightweight process.
Defines a series of line strips.
get_left_eye
Returns a pointer to the left DisplayRegion managed by this stereo object.
void clear_trail_node()
If you have previously fetched the trail node using get_trail_node, then the MouseWatcher is continua...
A rectangular subregion within a window for rendering into.
bool remove_group(MouseWatcherGroup *group)
Removes the indicated group from the set of extra groups associated with the MouseWatcher.
size_t get_num_bits() const
Returns the current number of possibly different bits in this array.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that holds Geom objects, renderable pieces of geometry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Encapsulates the data generated from (or sent into) any particular DataNode.
This object supervises the traversal of the data graph and the moving of data from one DataNode to it...
bool replace_group(MouseWatcherGroup *old_group, MouseWatcherGroup *new_group)
Atomically removes old_group from the MouseWatcher, and replaces it with new_group.
bool get_in_window(size_t n) const
Get the in-window flag of the nth event.