open_toontown_panda3d/panda/src/display/graphicsWindowInputDevice.cxx

349 lines
14 KiB
C++

// Filename: graphicsWindowInputDevice.cxx
// Created by: drose (24May00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "graphicsWindowInputDevice.h"
#include "mouseButton.h"
#include "keyboardButton.h"
#define EXPCL EXPCL_PANDA_DISPLAY
#define EXPTP EXPTP_PANDA_DISPLAY
#define TYPE GraphicsWindowInputDevice
#define NAME vector_GraphicsWindowInputDevice
#include "vector_src.cxx"
// Tell GCC that we'll take care of the instantiation explicitly here.
#ifdef __GNUC__
#pragma implementation
#endif
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::Constructor
// Access: Private
// Description: Defines a new InputDevice for the window. Most
// windows will have exactly one InputDevice: a
// keyboard/mouse pair. Some may also add joystick
// data, or additional mice or something.
//
// This private constructor is only used internally by
// the named constructors, below.
////////////////////////////////////////////////////////////////////
GraphicsWindowInputDevice::
GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, int flags) :
_host(host),
_name(name),
_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)
{
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::pointer_only
// Access: Public
// Description: This named constructor returns an input device that
// only has a pointing device, no keyboard.
////////////////////////////////////////////////////////////////////
GraphicsWindowInputDevice GraphicsWindowInputDevice::
pointer_only(GraphicsWindow *host, const string &name) {
return GraphicsWindowInputDevice(host, name, IDF_has_pointer);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::keyboard_only
// Access: Public
// Description: This named constructor returns an input device that
// only has a keyboard, no pointing device.
////////////////////////////////////////////////////////////////////
GraphicsWindowInputDevice GraphicsWindowInputDevice::
keyboard_only(GraphicsWindow *host, const string &name) {
return GraphicsWindowInputDevice(host, name, IDF_has_keyboard);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::pointer_and_keyboard
// Access: Public
// Description: This named constructor returns an input device that
// has both a keyboard and pointer.
////////////////////////////////////////////////////////////////////
GraphicsWindowInputDevice GraphicsWindowInputDevice::
pointer_and_keyboard(GraphicsWindow *host, const string &name) {
return
GraphicsWindowInputDevice(host, name, IDF_has_pointer | IDF_has_keyboard);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
GraphicsWindowInputDevice::
GraphicsWindowInputDevice(const GraphicsWindowInputDevice &copy)
{
*this = copy;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
operator = (const GraphicsWindowInputDevice &copy)
{
LightMutexHolder holder(_lock);
LightMutexHolder holder1(copy._lock);
_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;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
GraphicsWindowInputDevice::
~GraphicsWindowInputDevice() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::has_button_event
// Access: Public
// Description: Returns true if this device has a pending button
// event (a mouse button or keyboard button down/up),
// false otherwise. If this returns true, the
// particular event may be extracted via
// get_button_event().
////////////////////////////////////////////////////////////////////
bool GraphicsWindowInputDevice::
has_button_event() const {
LightMutexHolder holder(_lock);
return !_button_events.empty();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::get_button_event
// Access: Public
// Description: Assuming a previous call to has_button_event()
// returned true, this returns the pending button event.
////////////////////////////////////////////////////////////////////
ButtonEvent GraphicsWindowInputDevice::
get_button_event() {
LightMutexHolder holder(_lock);
ButtonEvent be = _button_events.front();
_button_events.pop_front();
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 {
LightMutexHolder holder(_lock);
return (_pointer_events != 0);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::get_pointer_events
// Access: Public
// Description: Returns a PointerEventList containing all the recent
// pointer events.
////////////////////////////////////////////////////////////////////
PT(PointerEventList) GraphicsWindowInputDevice::
get_pointer_events() {
LightMutexHolder holder(_lock);
PT(PointerEventList) result = _pointer_events;
_pointer_events = 0;
return result;
}
////////////////////////////////////////////////////////////////////
// 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) {
LightMutexHolder holder(_lock);
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() {
LightMutexHolder holder(_lock);
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) {
LightMutexHolder holder(_lock);
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++;
if (_pointer_events == 0) {
_pointer_events = new PointerEventList();
}
_pointer_events->add_event(_mouse_data._in_window,
_mouse_data._xpos,
_mouse_data._ypos,
seq, time);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::button_down
// Access: Public
// Description: Records that the indicated button has been depressed.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
button_down(ButtonHandle button, double time) {
LightMutexHolder holder(_lock);
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_down, time));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::button_resume_down
// Access: Public
// Description: Records that the indicated button was depressed
// earlier, and we only just detected the event after
// the fact. This is mainly useful for tracking the
// state of modifier keys.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
button_resume_down(ButtonHandle button, double time) {
LightMutexHolder holder(_lock);
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_resume_down, time));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::button_up
// Access: Public
// Description: Records that the indicated button has been released.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
button_up(ButtonHandle button, double time) {
LightMutexHolder holder(_lock);
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_up, time));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::keystroke
// Access: Public
// Description: Records that the indicated keystroke has been
// generated.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
keystroke(int keycode, double time) {
LightMutexHolder holder(_lock);
_button_events.push_back(ButtonEvent(keycode, time));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::candidate
// Access: Public
// Description: Records that the indicated candidate string has been
// highlighted. This is used to implement IME support
// for typing in international languages, especially
// Chinese/Japanese/Korean.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
candidate(const wstring &candidate_string, size_t highlight_start,
size_t highlight_end, size_t cursor_pos) {
LightMutexHolder holder(_lock);
_button_events.push_back(ButtonEvent(candidate_string,
highlight_start, highlight_end,
cursor_pos));
}