mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
Code to record a mouse trail added
This commit is contained in:
parent
d480af74a0
commit
f64547dd1b
@ -40,11 +40,13 @@ MouseAndKeyboard(GraphicsWindow *window, int device, const string &name) :
|
||||
_pixel_size_output = define_output("pixel_size", EventStoreVec2::get_class_type());
|
||||
_xy_output = define_output("xy", EventStoreVec2::get_class_type());
|
||||
_button_events_output = define_output("button_events", ButtonEventList::get_class_type());
|
||||
_pointer_events_output = define_output("pointer_events", PointerEventList::get_class_type());
|
||||
|
||||
_pixel_xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_pixel_size = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_button_events = new ButtonEventList;
|
||||
_pointer_events = new PointerEventList;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -60,6 +62,26 @@ set_source(GraphicsWindow *window, int device) {
|
||||
_device = device;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseAndKeyboard::get_source_window
|
||||
// Access: Public
|
||||
// Description: Returns the associated source window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsWindow) MouseAndKeyboard::
|
||||
get_source_window() const {
|
||||
return _window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseAndKeyboard::get_source_device
|
||||
// Access: Public
|
||||
// Description: Returns the associated source device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int MouseAndKeyboard::
|
||||
get_source_device() const {
|
||||
return _device;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseAndKeyboard::do_transmit_data
|
||||
// Access: Protected, Virtual
|
||||
@ -85,6 +107,15 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
|
||||
}
|
||||
output.set_data(_button_events_output, EventParameter(_button_events));
|
||||
}
|
||||
if (_window->has_pointer_event(_device)) {
|
||||
// Fill up the pointer events.
|
||||
_pointer_events->clear();
|
||||
while (_window->has_pointer_event(_device)) {
|
||||
PointerEvent be = _window->get_pointer_event(_device);
|
||||
_pointer_events->add_event(be);
|
||||
}
|
||||
output.set_data(_pointer_events_output, EventParameter(_pointer_events));
|
||||
}
|
||||
|
||||
// Get the window size.
|
||||
WindowProperties properties = _window->get_properties();
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "dataNode.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "pointerEventList.h"
|
||||
#include "linmath_events.h"
|
||||
#include "pointerTo.h"
|
||||
#include "graphicsWindow.h"
|
||||
@ -52,6 +53,10 @@ PUBLISHED:
|
||||
MouseAndKeyboard(GraphicsWindow *window, int device, const string &name);
|
||||
void set_source(GraphicsWindow *window, int device);
|
||||
|
||||
public:
|
||||
PT(GraphicsWindow) get_source_window() const;
|
||||
int get_source_device() const;
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
virtual void do_transmit_data(DataGraphTraverser *trav,
|
||||
@ -64,11 +69,13 @@ private:
|
||||
int _pixel_size_output;
|
||||
int _xy_output;
|
||||
int _button_events_output;
|
||||
int _pointer_events_output;
|
||||
|
||||
PT(EventStoreVec2) _pixel_xy;
|
||||
PT(EventStoreVec2) _pixel_size;
|
||||
PT(EventStoreVec2) _xy;
|
||||
PT(ButtonEventList) _button_events;
|
||||
PT(PointerEventList) _pointer_events;
|
||||
|
||||
PT(GraphicsWindow) _window;
|
||||
int _device;
|
||||
|
@ -44,7 +44,14 @@ is_fullscreen() const {
|
||||
return _properties.get_fullscreen();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::add_input_device
|
||||
// Access: Protected
|
||||
// Description: Adds a GraphicsWindowInputDevice to the vector.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindow::
|
||||
add_input_device(const GraphicsWindowInputDevice &device) {
|
||||
_input_devices.push_back(device);
|
||||
_input_devices.back().set_device_index(_input_devices.size()-1);
|
||||
}
|
||||
|
||||
|
@ -337,6 +337,54 @@ has_keyboard(int device) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::enable_pointer_events
|
||||
// Access: Published
|
||||
// Description: Turn on the generation of pointer events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindow::
|
||||
enable_pointer_events(int device) {
|
||||
MutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].enable_pointer_events();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::disable_pointer_events
|
||||
// Access: Published
|
||||
// Description: Turn off the generation of pointer events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindow::
|
||||
disable_pointer_events(int device) {
|
||||
MutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].disable_pointer_events();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::enable_pointer_mode
|
||||
// Access: Published
|
||||
// Description: See GraphicsWindowInputDevice::enable_pointer_mode
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindow::
|
||||
enable_pointer_mode(int device, double speed) {
|
||||
MutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].enable_pointer_mode(speed);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::disable_pointer_events
|
||||
// Access: Published
|
||||
// Description: See GraphicsWindowInputDevice::disable_pointer_mode
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindow::
|
||||
disable_pointer_mode(int device) {
|
||||
MutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].disable_pointer_mode();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_pointer
|
||||
// Access: Published
|
||||
@ -418,6 +466,43 @@ get_button_event(int device) {
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::has_pointer_event
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated device has a pending
|
||||
// pointer event (a mouse movement). If this returns
|
||||
// true, the particular event may be extracted via
|
||||
// get_pointer_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsWindow::
|
||||
has_pointer_event(int device) const {
|
||||
bool result;
|
||||
{
|
||||
MutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
|
||||
result = _input_devices[device].has_pointer_event();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_pointer_event
|
||||
// Access: Public
|
||||
// Description: Assuming a previous call to has_pointer_event()
|
||||
// returned true, this returns the pending pointer event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PointerEvent GraphicsWindow::
|
||||
get_pointer_event(int device) {
|
||||
PointerEvent result;
|
||||
{
|
||||
MutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), PointerEvent());
|
||||
nassertr(_input_devices[device].has_pointer_event(), PointerEvent());
|
||||
result = _input_devices[device].get_pointer_event();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::verify_window_sizes
|
||||
// Access: Public, Virtual
|
||||
|
@ -73,6 +73,11 @@ PUBLISHED:
|
||||
bool has_keyboard(int device) const;
|
||||
|
||||
|
||||
void enable_pointer_events(int device);
|
||||
void disable_pointer_events(int device);
|
||||
void enable_pointer_mode(int device, double speed);
|
||||
void disable_pointer_mode(int device);
|
||||
|
||||
MouseData get_pointer(int device) const;
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
virtual void close_ime();
|
||||
@ -81,6 +86,8 @@ public:
|
||||
// No need to publish these.
|
||||
bool has_button_event(int device) const;
|
||||
ButtonEvent get_button_event(int device);
|
||||
bool has_pointer_event(int device) const;
|
||||
PointerEvent get_pointer_event(int device);
|
||||
|
||||
virtual int verify_window_sizes(int numsizes, int *dimen);
|
||||
|
||||
@ -115,6 +122,7 @@ private:
|
||||
static unsigned int parse_color_mask(const string &word);
|
||||
|
||||
protected:
|
||||
INLINE void add_input_device(const GraphicsWindowInputDevice &device);
|
||||
typedef vector_GraphicsWindowInputDevice InputDevices;
|
||||
InputDevices _input_devices;
|
||||
Mutex _input_lock;
|
||||
|
@ -67,6 +67,51 @@ get_pointer() const {
|
||||
return _mouse_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::get_raw_pointer
|
||||
// Access: Public
|
||||
// Description: Returns the MouseData associated with the input
|
||||
// device's pointer, in raw form (ie, prior to any
|
||||
// pointer_mode interpretation).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const MouseData &GraphicsWindowInputDevice::
|
||||
get_raw_pointer() const {
|
||||
return _true_mouse_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::set_device_index
|
||||
// Access: Public
|
||||
// Description: Set the device index. This is reported in pointer
|
||||
// events. The device index will be equal to the position
|
||||
// of the GraphicsWindowInputDevice in the window's list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_device_index(int index) {
|
||||
_device_index = index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::enable_pointer_events
|
||||
// Access: Public
|
||||
// Description: Enables the generation of mouse-movement events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
enable_pointer_events() {
|
||||
_enable_pointer_events = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::disable_pointer_events
|
||||
// Access: Public
|
||||
// Description: Disables the generation of mouse-movement events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
disable_pointer_events() {
|
||||
_enable_pointer_events = false;
|
||||
_pointer_events.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::set_pointer_in_window
|
||||
// Access: Public
|
||||
@ -75,10 +120,8 @@ get_pointer() const {
|
||||
// the given pixel coordinates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_pointer_in_window(int x, int y) {
|
||||
_mouse_data._in_window = true;
|
||||
_mouse_data._xpos = x;
|
||||
_mouse_data._ypos = y;
|
||||
set_pointer_in_window(int x, int y, double time) {
|
||||
set_pointer(true, x, y, time);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -89,8 +132,8 @@ set_pointer_in_window(int x, int y) {
|
||||
// window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_pointer_out_of_window() {
|
||||
_mouse_data._in_window = false;
|
||||
set_pointer_out_of_window(double time) {
|
||||
set_pointer(false, _mouse_data._xpos, _mouse_data._ypos, time);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -45,9 +45,17 @@
|
||||
// the named constructors, below.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice::
|
||||
GraphicsWindowInputDevice(const string &name, int flags) :
|
||||
GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, int flags) :
|
||||
_host(host),
|
||||
_name(name),
|
||||
_flags(flags)
|
||||
_flags(flags),
|
||||
_device_index(0),
|
||||
_event_sequence(0),
|
||||
_pointer_mode_enable(false),
|
||||
_pointer_speed(1.0),
|
||||
_pointer_true_x(0.0),
|
||||
_pointer_true_y(0.0),
|
||||
_enable_pointer_events(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -58,8 +66,8 @@ GraphicsWindowInputDevice(const string &name, int flags) :
|
||||
// only has a pointing device, no keyboard.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice GraphicsWindowInputDevice::
|
||||
pointer_only(const string &name) {
|
||||
return GraphicsWindowInputDevice(name, IDF_has_pointer);
|
||||
pointer_only(GraphicsWindow *host, const string &name) {
|
||||
return GraphicsWindowInputDevice(host, name, IDF_has_pointer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -69,8 +77,8 @@ pointer_only(const string &name) {
|
||||
// only has a keyboard, no pointing device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice GraphicsWindowInputDevice::
|
||||
keyboard_only(const string &name) {
|
||||
return GraphicsWindowInputDevice(name, IDF_has_keyboard);
|
||||
keyboard_only(GraphicsWindow *host, const string &name) {
|
||||
return GraphicsWindowInputDevice(host, name, IDF_has_keyboard);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -80,9 +88,9 @@ keyboard_only(const string &name) {
|
||||
// has both a keyboard and pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice GraphicsWindowInputDevice::
|
||||
pointer_and_keyboard(const string &name) {
|
||||
pointer_and_keyboard(GraphicsWindow *host, const string &name) {
|
||||
return
|
||||
GraphicsWindowInputDevice(name, IDF_has_pointer | IDF_has_keyboard);
|
||||
GraphicsWindowInputDevice(host, name, IDF_has_pointer | IDF_has_keyboard);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -92,10 +100,20 @@ pointer_and_keyboard(const string &name) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice::
|
||||
GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©) :
|
||||
_host(copy._host),
|
||||
_name(copy._name),
|
||||
_flags(copy._flags),
|
||||
_device_index(copy._device_index),
|
||||
_event_sequence(copy._event_sequence),
|
||||
_pointer_mode_enable(copy._pointer_mode_enable),
|
||||
_pointer_speed(copy._pointer_speed),
|
||||
_pointer_true_x(copy._pointer_true_x),
|
||||
_pointer_true_y(copy._pointer_true_y),
|
||||
_enable_pointer_events(copy._enable_pointer_events),
|
||||
_mouse_data(copy._mouse_data),
|
||||
_button_events(copy._button_events)
|
||||
_true_mouse_data(copy._true_mouse_data),
|
||||
_button_events(copy._button_events),
|
||||
_pointer_events(copy._pointer_events)
|
||||
{
|
||||
}
|
||||
|
||||
@ -106,10 +124,20 @@ GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
operator = (const GraphicsWindowInputDevice ©) {
|
||||
_host = copy._host;
|
||||
_name = copy._name;
|
||||
_flags = copy._flags;
|
||||
_device_index = copy._device_index;
|
||||
_event_sequence = copy._event_sequence;
|
||||
_pointer_mode_enable = copy._pointer_mode_enable;
|
||||
_pointer_speed = copy._pointer_speed;
|
||||
_pointer_true_x = copy._pointer_true_x;
|
||||
_pointer_true_y = copy._pointer_true_y;
|
||||
_enable_pointer_events = copy._enable_pointer_events;
|
||||
_mouse_data = copy._mouse_data;
|
||||
_true_mouse_data = copy._true_mouse_data;
|
||||
_button_events = copy._button_events;
|
||||
_pointer_events = copy._pointer_events;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -148,6 +176,112 @@ get_button_event() {
|
||||
return be;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::has_pointer_event
|
||||
// Access: Public
|
||||
// Description: Returns true if this device has a pending pointer
|
||||
// event (a mouse movement), or false otherwise. If
|
||||
// this returns true, the particular event may be
|
||||
// extracted via get_pointer_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsWindowInputDevice::
|
||||
has_pointer_event() const {
|
||||
return !_pointer_events.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::get_pointer_event
|
||||
// Access: Public
|
||||
// Description: Assuming a previous call to has_pointer_event()
|
||||
// returned true, this returns the pending pointer event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PointerEvent GraphicsWindowInputDevice::
|
||||
get_pointer_event() {
|
||||
PointerEvent be = _pointer_events.front();
|
||||
_pointer_events.pop_front();
|
||||
return be;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::enable_pointer_mode
|
||||
// Access: Public
|
||||
// Description: There are two modes: raw mode, and pointer mode.
|
||||
// In pointer mode, the mouse stops when it reaches the
|
||||
// edges of the window. In raw mode, the mouse ignores
|
||||
// the screen boundaries and can continue indefinitely,
|
||||
// even into negative coordinates. In raw mode, each
|
||||
// "blip" from the mouse hardware corresponds to a
|
||||
// change of 1 unit in the mouse's (x,y) coordinate.
|
||||
// In pointer mode, a variety of speed adjustment factors
|
||||
// and concepts like "mouse acceleration" may be applied.
|
||||
//
|
||||
// Mouse zero represents the system mouse pointer. This
|
||||
// is by definition a pointer, not a raw mouse. It is
|
||||
// an error to try to enable or disable pointer mode on
|
||||
// mouse zero.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
enable_pointer_mode(double speed) {
|
||||
nassertv(_device_index != 0);
|
||||
_pointer_mode_enable = true;
|
||||
_pointer_speed = speed;
|
||||
_pointer_true_x = _host->get_x_size() * 0.5;
|
||||
_pointer_true_y = _host->get_y_size() * 0.5;
|
||||
_mouse_data._in_window = true;
|
||||
_mouse_data._xpos = int(_pointer_true_x + 0.5);
|
||||
_mouse_data._ypos = int(_pointer_true_y + 0.5);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::disable_pointer_mode
|
||||
// Access: Public
|
||||
// Description: see enable_pointer_mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
disable_pointer_mode() {
|
||||
nassertv(_device_index != 0);
|
||||
_pointer_mode_enable = false;
|
||||
_pointer_speed = 1.0;
|
||||
_pointer_true_x = 0.0;
|
||||
_pointer_true_y = 0.0;
|
||||
_mouse_data = _true_mouse_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::set_pointer
|
||||
// Access: Public
|
||||
// Description: Records that a mouse movement has taken place.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
set_pointer(bool inwin, int x, int y, double time) {
|
||||
int delta_x = x - _true_mouse_data._xpos;
|
||||
int delta_y = y - _true_mouse_data._ypos;
|
||||
_true_mouse_data._in_window = inwin;
|
||||
_true_mouse_data._xpos = x;
|
||||
_true_mouse_data._ypos = y;
|
||||
|
||||
if (_pointer_mode_enable) {
|
||||
_pointer_true_x += (delta_x * _pointer_speed);
|
||||
_pointer_true_y += (delta_y * _pointer_speed);
|
||||
double xhi = _host->get_x_size();
|
||||
double yhi = _host->get_y_size();
|
||||
if (_pointer_true_x < 0.0) _pointer_true_x = 0.0;
|
||||
if (_pointer_true_y < 0.0) _pointer_true_y = 0.0;
|
||||
if (_pointer_true_x > xhi) _pointer_true_x = xhi;
|
||||
if (_pointer_true_y > yhi) _pointer_true_y = yhi;
|
||||
_mouse_data._in_window = true;
|
||||
_mouse_data._xpos = int(_pointer_true_x + 0.5);
|
||||
_mouse_data._ypos = int(_pointer_true_y + 0.5);
|
||||
} else {
|
||||
_mouse_data = _true_mouse_data;
|
||||
}
|
||||
|
||||
if (_enable_pointer_events) {
|
||||
int seq = _event_sequence ++;
|
||||
_pointer_events.push_back(PointerEvent(_device_index, _mouse_data, seq, time));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::button_down
|
||||
// Access: Public
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "buttonEvent.h"
|
||||
#include "pointerEvent.h"
|
||||
#include "mouseData.h"
|
||||
#include "clockObject.h"
|
||||
|
||||
@ -38,26 +39,37 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DISPLAY GraphicsWindowInputDevice {
|
||||
private:
|
||||
GraphicsWindowInputDevice(const string &name, int flags);
|
||||
GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, int flags);
|
||||
|
||||
public:
|
||||
static GraphicsWindowInputDevice pointer_only(const string &name);
|
||||
static GraphicsWindowInputDevice keyboard_only(const string &name);
|
||||
static GraphicsWindowInputDevice pointer_and_keyboard(const string &name);
|
||||
|
||||
static GraphicsWindowInputDevice pointer_only(GraphicsWindow *host, const string &name);
|
||||
static GraphicsWindowInputDevice keyboard_only(GraphicsWindow *host, const string &name);
|
||||
static GraphicsWindowInputDevice pointer_and_keyboard(GraphicsWindow *host, const string &name);
|
||||
|
||||
INLINE GraphicsWindowInputDevice();
|
||||
GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©);
|
||||
void operator = (const GraphicsWindowInputDevice ©);
|
||||
~GraphicsWindowInputDevice();
|
||||
|
||||
|
||||
INLINE string get_name() const;
|
||||
INLINE bool has_pointer() const;
|
||||
INLINE bool has_keyboard() const;
|
||||
|
||||
INLINE void set_device_index(int index);
|
||||
|
||||
INLINE const MouseData &get_pointer() const;
|
||||
|
||||
INLINE const MouseData &get_raw_pointer() const;
|
||||
|
||||
INLINE void enable_pointer_events();
|
||||
INLINE void disable_pointer_events();
|
||||
|
||||
INLINE void enable_pointer_mode(double speed);
|
||||
INLINE void disable_pointer_mode();
|
||||
|
||||
bool has_button_event() const;
|
||||
ButtonEvent get_button_event();
|
||||
bool has_pointer_event() const;
|
||||
PointerEvent get_pointer_event();
|
||||
|
||||
public:
|
||||
// The following interface is for the various kinds of
|
||||
@ -69,8 +81,9 @@ public:
|
||||
void candidate(const wstring &candidate_string, size_t highlight_start,
|
||||
size_t higlight_end, size_t cursor_pos);
|
||||
|
||||
INLINE void set_pointer_in_window(int x, int y);
|
||||
INLINE void set_pointer_out_of_window();
|
||||
INLINE void set_pointer_in_window(int x, int y, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
INLINE void set_pointer_out_of_window(double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
void set_pointer(bool inwin, int x, int y, double time);
|
||||
|
||||
public:
|
||||
// We need these methods to make VC++ happy when we try to
|
||||
@ -86,11 +99,25 @@ private:
|
||||
IDF_has_keyboard = 0x02
|
||||
};
|
||||
typedef pdeque<ButtonEvent> ButtonEvents;
|
||||
|
||||
typedef pdeque<PointerEvent> PointerEvents;
|
||||
|
||||
GraphicsWindow *_host;
|
||||
|
||||
string _name;
|
||||
int _flags;
|
||||
int _device_index;
|
||||
int _event_sequence;
|
||||
|
||||
bool _pointer_mode_enable;
|
||||
double _pointer_speed;
|
||||
double _pointer_true_x;
|
||||
double _pointer_true_y;
|
||||
|
||||
bool _enable_pointer_events;
|
||||
MouseData _mouse_data;
|
||||
MouseData _true_mouse_data;
|
||||
ButtonEvents _button_events;
|
||||
PointerEvents _pointer_events;
|
||||
};
|
||||
|
||||
#include "graphicsWindowInputDevice.I"
|
||||
|
@ -24,7 +24,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PointerEvent::
|
||||
PointerEvent() :
|
||||
_pointer(-1),
|
||||
_device(-1),
|
||||
_sequence(0),
|
||||
_time(0.0)
|
||||
{
|
||||
}
|
||||
@ -35,9 +36,10 @@ PointerEvent() :
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PointerEvent::
|
||||
PointerEvent(int pointer, const MouseData &data, double time) :
|
||||
_pointer(pointer),
|
||||
PointerEvent(int dev, const MouseData &data, int seq, double time) :
|
||||
_device(dev),
|
||||
_data(data),
|
||||
_sequence(seq),
|
||||
_time(time)
|
||||
{
|
||||
}
|
||||
@ -49,8 +51,9 @@ PointerEvent(int pointer, const MouseData &data, double time) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PointerEvent::
|
||||
PointerEvent(const PointerEvent ©) :
|
||||
_pointer(copy._pointer),
|
||||
_device(copy._device),
|
||||
_data(copy._data),
|
||||
_sequence(copy._sequence),
|
||||
_time(copy._time)
|
||||
{
|
||||
}
|
||||
@ -62,8 +65,9 @@ PointerEvent(const PointerEvent ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PointerEvent::
|
||||
operator = (const PointerEvent ©) {
|
||||
_pointer = copy._pointer;
|
||||
_device = copy._device;
|
||||
_data = copy._data;
|
||||
_sequence = copy._sequence;
|
||||
_time = copy._time;
|
||||
}
|
||||
|
||||
@ -75,9 +79,10 @@ operator = (const PointerEvent ©) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PointerEvent::
|
||||
operator == (const PointerEvent &other) const {
|
||||
return (_pointer == other._pointer &&
|
||||
return (_device == other._device &&
|
||||
_data._xpos == other._data._xpos &&
|
||||
_data._ypos == other._data._ypos &&
|
||||
_sequence == other._sequence &&
|
||||
_data._in_window == other._data._in_window);
|
||||
}
|
||||
|
||||
@ -98,8 +103,11 @@ operator != (const PointerEvent &other) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PointerEvent::
|
||||
operator < (const PointerEvent &other) const {
|
||||
if (_pointer != other._pointer) {
|
||||
return _pointer < other._pointer;
|
||||
if (_device != other._device) {
|
||||
return _device < other._device;
|
||||
}
|
||||
if (_sequence != other._sequence) {
|
||||
return _sequence < other._sequence;
|
||||
}
|
||||
if (_data._xpos != other._data._xpos) {
|
||||
return _data._xpos < other._data._xpos;
|
||||
|
@ -27,9 +27,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PointerEvent::
|
||||
output(ostream &out) const {
|
||||
out << "pointer " << _pointer << " to "
|
||||
<< _data._xpos << "," << _data._ypos
|
||||
<< (_data._in_window ? " in" : " out");
|
||||
out << (_data._in_window ? "In@" : "Out@")
|
||||
<< _data._xpos << "," << _data._ypos << " ";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -39,10 +38,11 @@ output(ostream &out) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PointerEvent::
|
||||
write_datagram(Datagram &dg) const {
|
||||
dg.add_int8(_pointer);
|
||||
dg.add_int8(_device);
|
||||
dg.add_bool(_data._in_window);
|
||||
dg.add_int32(_data._xpos);
|
||||
dg.add_int32(_data._ypos);
|
||||
dg.add_int32(_sequence);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -52,9 +52,10 @@ write_datagram(Datagram &dg) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PointerEvent::
|
||||
read_datagram(DatagramIterator &scan) {
|
||||
_pointer = scan.get_int8();
|
||||
_device = scan.get_int8();
|
||||
_data._in_window = scan.get_bool();
|
||||
_data._xpos = scan.get_int32();
|
||||
_data._ypos = scan.get_int32();
|
||||
_sequence = scan.get_int32();
|
||||
_time = 0.0;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
INLINE PointerEvent();
|
||||
INLINE PointerEvent(const PointerEvent ©);
|
||||
INLINE PointerEvent(int pointer, const MouseData &data, double time);
|
||||
INLINE PointerEvent(int dev, const MouseData &data, int seq, double time);
|
||||
INLINE void operator = (const PointerEvent ©);
|
||||
|
||||
INLINE bool operator == (const PointerEvent &other) const;
|
||||
@ -47,8 +47,9 @@ public:
|
||||
void read_datagram(DatagramIterator &scan);
|
||||
|
||||
public:
|
||||
int _pointer;
|
||||
int _device;
|
||||
MouseData _data;
|
||||
int _sequence;
|
||||
double _time;
|
||||
};
|
||||
|
||||
|
@ -59,7 +59,7 @@ add_event(const PointerEvent &event) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::get_num_events
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the number of events in the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PointerEventList::
|
||||
@ -67,6 +67,61 @@ get_num_events() const {
|
||||
return _events.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::get_x
|
||||
// Access: Published
|
||||
// Description: Get the x-coordinate of the nth event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PointerEventList::
|
||||
get_x(int evt) const {
|
||||
nassertr((evt >= 0) && (evt < (int)_events.size()), 0);
|
||||
return _events[evt]._data._xpos;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::get_y
|
||||
// Access: Published
|
||||
// Description: Get the y-coordinate of the nth event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PointerEventList::
|
||||
get_y(int evt) const {
|
||||
nassertr((evt >= 0) && (evt < (int)_events.size()), 0);
|
||||
return _events[evt]._data._ypos;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::get_in_window
|
||||
// Access: Published
|
||||
// Description: Get the in-window flag of the nth event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PointerEventList::
|
||||
get_in_window(int evt) const {
|
||||
nassertr((evt >= 0) && (evt < (int)_events.size()), 0);
|
||||
return _events[evt]._data._in_window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::get_sequence
|
||||
// Access: Published
|
||||
// Description: Get the sequence number of the nth event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PointerEventList::
|
||||
get_sequence(int evt) const {
|
||||
nassertr((evt >= 0) && (evt < (int)_events.size()), 0);
|
||||
return _events[evt]._sequence;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::get_time
|
||||
// Access: Published
|
||||
// Description: Get the timestamp of the nth event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double PointerEventList::
|
||||
get_time(int evt) const {
|
||||
nassertr((evt >= 0) && (evt < (int)_events.size()), 0);
|
||||
return _events[evt]._time;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::get_event
|
||||
// Access: Public
|
||||
@ -93,3 +148,13 @@ INLINE void PointerEventList::
|
||||
clear() {
|
||||
_events.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerEventList::pop_front
|
||||
// Access: Public
|
||||
// Description: Discards the first event on the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PointerEventList::
|
||||
pop_front() {
|
||||
_events.pop_front();
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ TypeHandle PointerEventList::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PointerEventList::
|
||||
add_events(const PointerEventList &other) {
|
||||
_events.reserve(_events.size() + other._events.size());
|
||||
Events::const_iterator ei;
|
||||
for (ei = other._events.begin(); ei != other._events.end(); ++ei) {
|
||||
_events.push_back(*ei);
|
||||
@ -138,7 +137,6 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
|
||||
int num_events = scan.get_uint16();
|
||||
_events.clear();
|
||||
_events.reserve(num_events);
|
||||
for (int i = 0; i < num_events; i++) {
|
||||
PointerEvent event;
|
||||
event.read_datagram(scan);
|
||||
|
@ -39,15 +39,23 @@ class DatagramIterator;
|
||||
// is desired.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_EVENT PointerEventList : public EventStoreValueBase {
|
||||
PUBLISHED:
|
||||
INLINE int get_num_events() const;
|
||||
INLINE int get_x(int n) const;
|
||||
INLINE int get_y(int n) const;
|
||||
INLINE bool get_in_window(int n) const;
|
||||
INLINE int get_sequence(int n) const;
|
||||
INLINE double get_time(int n) const;
|
||||
|
||||
public:
|
||||
INLINE PointerEventList();
|
||||
INLINE PointerEventList(const PointerEventList ©);
|
||||
INLINE void operator = (const PointerEventList ©);
|
||||
|
||||
INLINE void add_event(const PointerEvent &event);
|
||||
INLINE int get_num_events() const;
|
||||
INLINE const PointerEvent &get_event(int n) const;
|
||||
INLINE void clear();
|
||||
INLINE void pop_front();
|
||||
|
||||
void add_events(const PointerEventList &other);
|
||||
|
||||
@ -55,7 +63,7 @@ public:
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
typedef pvector<PointerEvent> Events;
|
||||
typedef pdeque<PointerEvent> Events;
|
||||
Events _events;
|
||||
|
||||
public:
|
||||
|
@ -79,8 +79,8 @@ glxGraphicsWindow(GraphicsPipe *pipe,
|
||||
_net_wm_state_remove = glx_pipe->_net_wm_state_remove;
|
||||
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse");
|
||||
_input_devices.push_back(device);
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard/mouse");
|
||||
add_input_device(device);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1080,8 +1080,8 @@ open_raw_mice()
|
||||
inf._io_buffer = "";
|
||||
_mouse_device_info.push_back(inf);
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_only(full_id);
|
||||
_input_devices.push_back(device);
|
||||
GraphicsWindowInputDevice::pointer_only(this, full_id);
|
||||
add_input_device(device);
|
||||
glxdisplay_cat.info() << "Raw mouse " <<
|
||||
inf._input_device_index << " detected: " << full_id << "\n";
|
||||
any_mice = true;
|
||||
@ -1150,8 +1150,8 @@ poll_raw_mice()
|
||||
}
|
||||
const input_event *events = (const input_event *)(inf._io_buffer.c_str());
|
||||
GraphicsWindowInputDevice &dev = _input_devices[inf._input_device_index];
|
||||
int x = dev.get_pointer().get_x();
|
||||
int y = dev.get_pointer().get_y();
|
||||
int x = _input_devices[i].get_raw_pointer().get_x();
|
||||
int y = _input_devices[i].get_raw_pointer().get_y();
|
||||
for (int i=0; i<nevents; i++) {
|
||||
if (events[i].type == EV_REL) {
|
||||
if (events[i].code == REL_X) x += events[i].value;
|
||||
|
@ -25,8 +25,8 @@
|
||||
INLINE MouseData::
|
||||
MouseData() {
|
||||
_in_window = false;
|
||||
_xpos = 0;
|
||||
_ypos = 0;
|
||||
_xpos = 0.0;
|
||||
_ypos = 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,8 +43,8 @@ PUBLISHED:
|
||||
|
||||
public:
|
||||
bool _in_window;
|
||||
int _xpos;
|
||||
int _ypos;
|
||||
double _xpos;
|
||||
double _ypos;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const MouseData &md);
|
||||
|
@ -619,3 +619,34 @@ without_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m) {
|
||||
region->without_region(param);
|
||||
throw_event_pattern(_without_pattern, region, ButtonHandle::none());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::get_trail_log
|
||||
// Access: Published
|
||||
// Description: Obtain the mouse trail log. This is a PointerEventList.
|
||||
// Does not make a copy, therefore, this PointerEventList
|
||||
// will be updated each time process_events gets called.
|
||||
//
|
||||
// To use trail logging, you need to enable the
|
||||
// generation of pointer events in the
|
||||
// GraphicsWindowInputDevice and set the trail log
|
||||
// duration in the MouseWatcher. Otherwise, the
|
||||
// trail log will be empty.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(PointerEventList) MouseWatcher::
|
||||
get_trail_log() const {
|
||||
return _trail_log;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::num_trail_recent
|
||||
// Access: Published
|
||||
// Description: This counter indicates how many events were added
|
||||
// to the trail log this frame. The trail log is
|
||||
// updated once per frame, during the process_events
|
||||
// operation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int MouseWatcher::
|
||||
num_trail_recent() const {
|
||||
return _num_trail_recent;
|
||||
}
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include "dataNodeTransmit.h"
|
||||
#include "transformState.h"
|
||||
#include "displayRegion.h"
|
||||
#include "geomVertexWriter.h"
|
||||
#include "geomLinestrips.h"
|
||||
#include "geomPoints.h"
|
||||
#include "dcast.h"
|
||||
#include "indent.h"
|
||||
#include "mutexHolder.h"
|
||||
@ -51,6 +54,7 @@ MouseWatcher(const string &name) :
|
||||
_pixel_size_input = define_input("pixel_size", EventStoreVec2::get_class_type());
|
||||
_xy_input = define_input("xy", EventStoreVec2::get_class_type());
|
||||
_button_events_input = define_input("button_events", ButtonEventList::get_class_type());
|
||||
_pointer_events_input = define_input("pointer_events", PointerEventList::get_class_type());
|
||||
|
||||
_pixel_xy_output = define_output("pixel_xy", EventStoreVec2::get_class_type());
|
||||
_pixel_size_output = define_output("pixel_size", EventStoreVec2::get_class_type());
|
||||
@ -59,6 +63,7 @@ MouseWatcher(const string &name) :
|
||||
|
||||
_pixel_xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_pixel_size = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
|
||||
_button_events = new ButtonEventList;
|
||||
|
||||
_has_mouse = false;
|
||||
@ -68,20 +73,24 @@ MouseWatcher(const string &name) :
|
||||
_button_down = false;
|
||||
_eh = (EventHandler *)NULL;
|
||||
_display_region = (DisplayRegion *)NULL;
|
||||
|
||||
|
||||
_inactivity_timeout = inactivity_timeout;
|
||||
_has_inactivity_timeout = !IS_NEARLY_ZERO(_inactivity_timeout);
|
||||
|
||||
_num_trail_recent = 0;
|
||||
_trail_log_duration = 0.0;
|
||||
_trail_log = new PointerEventList();
|
||||
|
||||
_inactivity_timeout_event = "inactivity_timeout";
|
||||
_last_activity = 0.0;
|
||||
_inactivity_state = IS_active;
|
||||
|
||||
|
||||
// When this flag is true, the mouse pointer is allowed to be
|
||||
// "entered" into multiple regions simultaneously; when false, it
|
||||
// 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.
|
||||
@ -344,6 +353,128 @@ get_group(int n) const {
|
||||
return _groups[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::set_trail_log_duration
|
||||
// Access: Published
|
||||
// Description: If the duration is nonzero, causes the MouseWatcher
|
||||
// to log the mouse's trail. Events older than the
|
||||
// specified duration are discarded. If the duration is
|
||||
// zero, logging is disabled.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcher::
|
||||
set_trail_log_duration(double duration) {
|
||||
if (duration < 0.0) {
|
||||
duration = 0.0;
|
||||
}
|
||||
_trail_log_duration = duration;
|
||||
discard_excess_trail_log();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::discard_excess_trail_log
|
||||
// Access: Private
|
||||
// Description: Discards trail log events whose age exceed the
|
||||
// desired log duration. Keeps one event that is beyond
|
||||
// the specified age, because otherwise, it is not always
|
||||
// possible to determine where the mouse was for the
|
||||
// full logging duration. If the duration is zero, this
|
||||
// method discards all trail events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcher::
|
||||
discard_excess_trail_log() {
|
||||
if (_trail_log_duration == 0.0) {
|
||||
_trail_log->clear();
|
||||
} else {
|
||||
if (_trail_log->get_num_events() >= 2) {
|
||||
double old = ClockObject::get_global_clock()->get_frame_time() - _trail_log_duration;
|
||||
while ((_trail_log->get_num_events() >= 2)&&
|
||||
(_trail_log->get_time(0) <= old)&&
|
||||
(_trail_log->get_time(1) <= old)) {
|
||||
_trail_log->pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::get_trail_node
|
||||
// Access: Published
|
||||
// Description: Returns a GeomNode that represents the mouse trail.
|
||||
// The intent is that you should reparent this GeomNode
|
||||
// to Render2D, and then forget about it. The
|
||||
// MouseWatcher will continually update the trail node.
|
||||
// There is only one trail node, it does not create a
|
||||
// new one each time you call get_trail_node.
|
||||
//
|
||||
// This is not a particularly beautiful way to render
|
||||
// a mouse trail. It is intended more for debugging
|
||||
// purposes than for finished applications. Even so,
|
||||
// It is suggested that you might want to apply a line
|
||||
// thickness and antialias mode to the line --- doing
|
||||
// so makes it look a lot better.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GeomNode) MouseWatcher::
|
||||
get_trail_node() {
|
||||
if (_trail_node == 0) {
|
||||
_trail_node = new GeomNode("Mouse Trail Node");
|
||||
update_trail_node();
|
||||
}
|
||||
return _trail_node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::clear_trail_node
|
||||
// Access: Published
|
||||
// Description: If you have previously fetched the trail node
|
||||
// using get_trail_node, then the MouseWatcher is
|
||||
// continually updating the trail node every frame.
|
||||
// Using clear_trail_node causes the MouseWatcher to
|
||||
// forget the trail node and stop updating it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcher::
|
||||
clear_trail_node() {
|
||||
_trail_node = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::update_trail_node
|
||||
// Access: Private
|
||||
// Description: Causes the trail node to represent the mouse trail.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcher::
|
||||
update_trail_node() {
|
||||
if (_trail_node == 0) {
|
||||
return;
|
||||
}
|
||||
_trail_node->remove_all_geoms();
|
||||
|
||||
if (_trail_log->get_num_events() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
PT(GeomVertexData) data = new GeomVertexData
|
||||
("mouseTrailSegs", GeomVertexFormat::get_v3(), Geom::UH_static);
|
||||
|
||||
GeomVertexWriter vertex(data, InternalName::get_vertex());
|
||||
|
||||
PT(GeomLinestrips) lines = new GeomLinestrips(Geom::UH_static);
|
||||
|
||||
double xscale = 2.0 / _pixel_size->get_value().get_x();
|
||||
double yscale = 2.0 / _pixel_size->get_value().get_y();
|
||||
|
||||
for (int i=0; i<(int)_trail_log->get_num_events(); i++) {
|
||||
double x = (_trail_log->get_x(i) * xscale) - 1.0;
|
||||
double y = (_trail_log->get_y(i) * yscale) - 1.0;
|
||||
vertex.add_data3f(LVecBase3f(x,0.0,-y));
|
||||
lines->add_vertex(i);
|
||||
}
|
||||
lines->close_primitive();
|
||||
|
||||
PT(Geom) l_geom = new Geom(data);
|
||||
l_geom->add_primitive(lines);
|
||||
_trail_node->add_geom(l_geom);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::note_activity
|
||||
// Access: Published
|
||||
@ -1242,6 +1373,12 @@ do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input,
|
||||
_internal_suppress = 0;
|
||||
_external_suppress = 0;
|
||||
|
||||
// We always pass the pixel_size data through.
|
||||
EventStoreVec2 *pixel_size;
|
||||
DCAST_INTO_V(pixel_size, input.get_data(_pixel_size_input).get_ptr());
|
||||
output.set_data(_pixel_size_output, pixel_size);
|
||||
_pixel_size = pixel_size;
|
||||
|
||||
if (!input.has_data(_xy_input)) {
|
||||
// No mouse in the window.
|
||||
set_no_mouse();
|
||||
@ -1305,6 +1442,24 @@ do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input,
|
||||
}
|
||||
}
|
||||
|
||||
// Code for recording the mouse trail.
|
||||
_num_trail_recent = 0;
|
||||
if (input.has_data(_pointer_events_input) && (_trail_log_duration > 0.0)) {
|
||||
const PointerEventList *this_pointer_events;
|
||||
DCAST_INTO_V(this_pointer_events, input.get_data(_pointer_events_input).get_ptr());
|
||||
_num_trail_recent = this_pointer_events->get_num_events();
|
||||
for (int i = 0; i < _num_trail_recent; i++) {
|
||||
_trail_log->add_event(this_pointer_events->get_event(i));
|
||||
}
|
||||
}
|
||||
if (_trail_log->get_num_events() > 0) {
|
||||
discard_excess_trail_log();
|
||||
update_trail_node();
|
||||
}
|
||||
if (_num_trail_recent > _trail_log->get_num_events()) {
|
||||
_num_trail_recent = _trail_log->get_num_events();
|
||||
}
|
||||
|
||||
// If the mouse is over a particular region, or still considered
|
||||
// owned by a region because of a recent button-down event, that
|
||||
// region determines whether we suppress events below us.
|
||||
@ -1481,7 +1636,4 @@ do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input,
|
||||
if (_button_events->get_num_events() != 0) {
|
||||
output.set_data(_button_events_output, EventParameter(_button_events));
|
||||
}
|
||||
|
||||
// We always pass the pixel_size data through.
|
||||
output.set_data(_pixel_size_output, input.get_data(_pixel_size_input));
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "modifierButtons.h"
|
||||
#include "buttonHandle.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "pointerEvent.h"
|
||||
#include "pointerEventList.h"
|
||||
#include "linmath_events.h"
|
||||
#include "bitArray.h"
|
||||
#include "clockObject.h"
|
||||
@ -130,7 +132,13 @@ PUBLISHED:
|
||||
|
||||
INLINE void set_inactivity_timeout_event(const string &event);
|
||||
INLINE const string &get_inactivity_timeout_event() const;
|
||||
|
||||
|
||||
INLINE CPT(PointerEventList) get_trail_log() const;
|
||||
INLINE int num_trail_recent() const;
|
||||
void set_trail_log_duration(double duration);
|
||||
PT(GeomNode) get_trail_node();
|
||||
void clear_trail_node();
|
||||
|
||||
void note_activity();
|
||||
|
||||
public:
|
||||
@ -184,7 +192,9 @@ protected:
|
||||
|
||||
private:
|
||||
void consider_keyboard_suppress(const MouseWatcherRegion *region);
|
||||
|
||||
void discard_excess_trail_log();
|
||||
void update_trail_node();
|
||||
|
||||
private:
|
||||
// This wants to be a set, but because you cannot export sets across
|
||||
// dlls in windows, we will make it a vector instead
|
||||
@ -198,6 +208,11 @@ private:
|
||||
LPoint2f _mouse_pixel;
|
||||
BitArray _current_buttons_down;
|
||||
|
||||
PT(PointerEventList) _trail_log;
|
||||
int _num_trail_recent;
|
||||
double _trail_log_duration;
|
||||
PT(GeomNode) _trail_node;
|
||||
|
||||
Regions _current_regions;
|
||||
PT(MouseWatcherRegion) _preferred_region;
|
||||
PT(MouseWatcherRegion) _preferred_button_down_region;
|
||||
@ -215,7 +230,7 @@ private:
|
||||
string _without_pattern;
|
||||
|
||||
PT(PandaNode) _geometry;
|
||||
|
||||
|
||||
EventHandler *_eh;
|
||||
ModifierButtons _mods;
|
||||
DisplayRegion *_display_region;
|
||||
@ -251,6 +266,7 @@ private:
|
||||
int _pixel_size_input;
|
||||
int _xy_input;
|
||||
int _button_events_input;
|
||||
int _pointer_events_input;
|
||||
|
||||
// outputs
|
||||
int _pixel_xy_output;
|
||||
@ -260,6 +276,7 @@ private:
|
||||
|
||||
PT(EventStoreVec2) _pixel_xy;
|
||||
PT(EventStoreVec2) _xy;
|
||||
PT(EventStoreVec2) _pixel_size;
|
||||
PT(ButtonEventList) _button_events;
|
||||
|
||||
public:
|
||||
|
@ -459,8 +459,8 @@ initialize_input_devices() {
|
||||
// Clear the handle array, and set up the system keyboard/mouse
|
||||
memset(_input_device_handle, 0, sizeof(_input_device_handle));
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse");
|
||||
_input_devices.push_back(device);
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard/mouse");
|
||||
add_input_device(device);
|
||||
|
||||
// Try initializing the Raw Input function pointers.
|
||||
if (pRegisterRawInputDevices==0) {
|
||||
@ -517,9 +517,9 @@ initialize_input_devices() {
|
||||
}
|
||||
if (pound2) *pound2 = '.';
|
||||
_input_device_handle[_input_devices.size()] = pRawInputDeviceList[i].hDevice;
|
||||
GraphicsWindowInputDevice device = GraphicsWindowInputDevice::pointer_only(psName);
|
||||
GraphicsWindowInputDevice device = GraphicsWindowInputDevice::pointer_only(this, psName);
|
||||
device.set_pointer_in_window(0,0);
|
||||
_input_devices.push_back(device);
|
||||
add_input_device(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2183,8 +2183,8 @@ handle_raw_input(HRAWINPUT hraw) {
|
||||
if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
|
||||
_input_devices[i].set_pointer_in_window(adjx, adjy);
|
||||
} else {
|
||||
int oldx = _input_devices[i].get_pointer().get_x();
|
||||
int oldy = _input_devices[i].get_pointer().get_y();
|
||||
int oldx = _input_devices[i].get_raw_pointer().get_x();
|
||||
int oldy = _input_devices[i].get_raw_pointer().get_y();
|
||||
_input_devices[i].set_pointer_in_window(oldx + adjx, oldy + adjy);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user