mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
define mouseInterfaceNode
This commit is contained in:
parent
37ea14ed18
commit
081122fe3b
@ -66,6 +66,39 @@ operator < (const ModifierButtons &other) const {
|
|||||||
return _state < other._state;
|
return _state < other._state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: ModifierButtons::operator &
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new ModifierButtons object for which
|
||||||
|
// is_down() will be true only if it is true on both
|
||||||
|
// source objects. The set of buttons reported by
|
||||||
|
// has_button() is not completely defined if both source
|
||||||
|
// objects have a different set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE ModifierButtons ModifierButtons::
|
||||||
|
operator & (const ModifierButtons &other) const {
|
||||||
|
ModifierButtons result = *this;
|
||||||
|
result &= other;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: ModifierButtons::operator |
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new ModifierButtons object for which
|
||||||
|
// is_down() will be true if it is true on either of the
|
||||||
|
// source objects. The set of buttons reported by
|
||||||
|
// has_button() is not completely defined if both source
|
||||||
|
// objects have a different set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE ModifierButtons ModifierButtons::
|
||||||
|
operator | (const ModifierButtons &other) const {
|
||||||
|
ModifierButtons result = *this;
|
||||||
|
result |= other;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ModifierButtons::get_num_buttons
|
// Function: ModifierButtons::get_num_buttons
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -29,7 +29,7 @@ ModifierButtons::
|
|||||||
ModifierButtons() :
|
ModifierButtons() :
|
||||||
_state(0)
|
_state(0)
|
||||||
{
|
{
|
||||||
_button_list= PTA(ButtonHandle)::empty_array(0);
|
_button_list = PTA(ButtonHandle)::empty_array(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -53,6 +53,97 @@ ModifierButtons::
|
|||||||
~ModifierButtons() {
|
~ModifierButtons() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: ModifierButtons::operator &=
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets is_down() true for any button that is already
|
||||||
|
// true for this object and the other object.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void ModifierButtons::
|
||||||
|
operator &= (const ModifierButtons &other) {
|
||||||
|
if (_button_list == other._button_list) {
|
||||||
|
// Trivially easy case: if the button lists are the same, we can
|
||||||
|
// do this using a bitmask operation.
|
||||||
|
_state &= other._state;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// More complicated case: if the button lists are different, we
|
||||||
|
// have to iterate through the buttons and compare them
|
||||||
|
// case-by-case. This becomes an n^2 operation, but fortunately
|
||||||
|
// there won't be more than a handful of buttons.
|
||||||
|
int num_buttons = get_num_buttons();
|
||||||
|
for (int i = 0; i < num_buttons; i++) {
|
||||||
|
if (is_down(i) && !other.is_down(get_button(i))) {
|
||||||
|
_state &= ~((BitmaskType)1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: ModifierButtons::operator |=
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets is_down() true for any button that is already
|
||||||
|
// true for this object and the other object. Adds
|
||||||
|
// whatever buttons are necessary to the list to make
|
||||||
|
// this so
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void ModifierButtons::
|
||||||
|
operator |= (const ModifierButtons &other) {
|
||||||
|
if (_button_list == other._button_list) {
|
||||||
|
// Trivially easy case: if the button lists are the same, we can
|
||||||
|
// do this using a bitmask operation.
|
||||||
|
_state |= other._state;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// More complicated case: if the button lists are different, we
|
||||||
|
// have to iterate through the buttons and compare them
|
||||||
|
// case-by-case. This becomes an n^2 operation, but fortunately
|
||||||
|
// there won't be more than a handful of buttons.
|
||||||
|
int num_buttons = other.get_num_buttons();
|
||||||
|
for (int i = 0; i < num_buttons; i++) {
|
||||||
|
if (other.is_down(i)) {
|
||||||
|
add_button(other.get_button(i));
|
||||||
|
button_down(other.get_button(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: ModifierButtons::set_button_list
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the list of buttons to watch to be the same as
|
||||||
|
// that of the other ModifierButtons object. This makes
|
||||||
|
// the lists pointer equivalent (until one or the other
|
||||||
|
// is later modified).
|
||||||
|
//
|
||||||
|
// This will preserve the state of any button that was
|
||||||
|
// on the original list and is also on the new lists.
|
||||||
|
// Any other buttons will get reset to the default state
|
||||||
|
// of "up".
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void ModifierButtons::
|
||||||
|
set_button_list(const ModifierButtons &other) {
|
||||||
|
if (_button_list != other._button_list) {
|
||||||
|
if (_state != 0) {
|
||||||
|
// If we have some buttons already down, we have to copy them to
|
||||||
|
// the new state.
|
||||||
|
BitmaskType new_state = 0;
|
||||||
|
int num_buttons = other.get_num_buttons();
|
||||||
|
for (int i = 0; i < num_buttons; i++) {
|
||||||
|
if (is_down(other.get_button(i))) {
|
||||||
|
new_state |= ((BitmaskType)1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_state = new_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
_button_list = other._button_list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ModifierButtons::matches
|
// Function: ModifierButtons::matches
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -41,6 +41,14 @@ PUBLISHED:
|
|||||||
INLINE bool operator != (const ModifierButtons &other) const;
|
INLINE bool operator != (const ModifierButtons &other) const;
|
||||||
INLINE bool operator < (const ModifierButtons &other) const;
|
INLINE bool operator < (const ModifierButtons &other) const;
|
||||||
|
|
||||||
|
INLINE ModifierButtons operator & (const ModifierButtons &other) const;
|
||||||
|
INLINE ModifierButtons operator | (const ModifierButtons &other) const;
|
||||||
|
|
||||||
|
void operator &= (const ModifierButtons &other);
|
||||||
|
void operator |= (const ModifierButtons &other);
|
||||||
|
|
||||||
|
void set_button_list(const ModifierButtons &other);
|
||||||
|
|
||||||
bool matches(const ModifierButtons &other) const;
|
bool matches(const ModifierButtons &other) const;
|
||||||
|
|
||||||
bool add_button(ButtonHandle button);
|
bool add_button(ButtonHandle button);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
buttonThrower.I buttonThrower.h \
|
buttonThrower.I buttonThrower.h \
|
||||||
config_tform.h \
|
config_tform.h \
|
||||||
driveInterface.I driveInterface.h \
|
driveInterface.I driveInterface.h \
|
||||||
|
mouseInterfaceNode.I mouseInterfaceNode.h \
|
||||||
mouseWatcher.I mouseWatcher.h \
|
mouseWatcher.I mouseWatcher.h \
|
||||||
mouseWatcherGroup.h \
|
mouseWatcherGroup.h \
|
||||||
mouseWatcherParameter.I mouseWatcherParameter.h \
|
mouseWatcherParameter.I mouseWatcherParameter.h \
|
||||||
@ -24,6 +25,7 @@
|
|||||||
buttonThrower.cxx \
|
buttonThrower.cxx \
|
||||||
config_tform.cxx \
|
config_tform.cxx \
|
||||||
driveInterface.cxx \
|
driveInterface.cxx \
|
||||||
|
mouseInterfaceNode.cxx \
|
||||||
mouseWatcher.cxx \
|
mouseWatcher.cxx \
|
||||||
mouseWatcherGroup.cxx \
|
mouseWatcherGroup.cxx \
|
||||||
mouseWatcherParameter.cxx mouseWatcherRegion.cxx \
|
mouseWatcherParameter.cxx mouseWatcherRegion.cxx \
|
||||||
@ -33,6 +35,7 @@
|
|||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
buttonThrower.I buttonThrower.h \
|
buttonThrower.I buttonThrower.h \
|
||||||
driveInterface.I driveInterface.h \
|
driveInterface.I driveInterface.h \
|
||||||
|
mouseInterfaceNode.I mouseInterfaceNode.h \
|
||||||
mouseWatcher.I mouseWatcher.h \
|
mouseWatcher.I mouseWatcher.h \
|
||||||
mouseWatcherGroup.h \
|
mouseWatcherGroup.h \
|
||||||
mouseWatcherParameter.I mouseWatcherParameter.h \
|
mouseWatcherParameter.I mouseWatcherParameter.h \
|
||||||
|
@ -46,6 +46,7 @@ const double drive_horizontal_ramp_down_time = config_tform.GetDouble("drive-hor
|
|||||||
ConfigureFn(config_tform) {
|
ConfigureFn(config_tform) {
|
||||||
DriveInterface::init_type();
|
DriveInterface::init_type();
|
||||||
ButtonThrower::init_type();
|
ButtonThrower::init_type();
|
||||||
|
MouseInterfaceNode::init_type();
|
||||||
MouseWatcher::init_type();
|
MouseWatcher::init_type();
|
||||||
MouseWatcherGroup::init_type();
|
MouseWatcherGroup::init_type();
|
||||||
MouseWatcherRegion::init_type();
|
MouseWatcherRegion::init_type();
|
||||||
|
@ -104,7 +104,7 @@ operator < (const DriveInterface::KeyHeld &other) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
DriveInterface::
|
DriveInterface::
|
||||||
DriveInterface(const string &name) :
|
DriveInterface(const string &name) :
|
||||||
DataNode(name)
|
MouseInterfaceNode(name)
|
||||||
{
|
{
|
||||||
_xy_input = define_input("xy", EventStoreVec2::get_class_type());
|
_xy_input = define_input("xy", EventStoreVec2::get_class_type());
|
||||||
_button_events_input = define_input("button_events", ButtonEventList::get_class_type());
|
_button_events_input = define_input("button_events", ButtonEventList::get_class_type());
|
||||||
@ -138,9 +138,7 @@ DriveInterface(const string &name) :
|
|||||||
_force_mouse = false;
|
_force_mouse = false;
|
||||||
_stop_this_frame = false;
|
_stop_this_frame = false;
|
||||||
|
|
||||||
_mods.add_button(MouseButton::one());
|
watch_button(MouseButton::one());
|
||||||
_mods.add_button(MouseButton::two());
|
|
||||||
_mods.add_button(MouseButton::three());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -168,8 +166,6 @@ reset() {
|
|||||||
_down_arrow.clear();
|
_down_arrow.clear();
|
||||||
_left_arrow.clear();
|
_left_arrow.clear();
|
||||||
_right_arrow.clear();
|
_right_arrow.clear();
|
||||||
|
|
||||||
_mods.all_buttons_up();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -398,13 +394,17 @@ apply(double x, double y, bool any_button) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void DriveInterface::
|
void DriveInterface::
|
||||||
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
||||||
|
// First, update our modifier buttons.
|
||||||
|
bool required_buttons_match;
|
||||||
|
const ButtonEventList *button_events = check_button_events(input, required_buttons_match);
|
||||||
|
|
||||||
// Look for mouse activity.
|
// Look for mouse activity.
|
||||||
double x = 0.0f;
|
double x = 0.0f;
|
||||||
double y = 0.0f;
|
double y = 0.0f;
|
||||||
|
|
||||||
bool got_mouse = false;
|
bool got_mouse = false;
|
||||||
|
|
||||||
if (input.has_data(_xy_input)) {
|
if (required_buttons_match && input.has_data(_xy_input)) {
|
||||||
const EventStoreVec2 *xy;
|
const EventStoreVec2 *xy;
|
||||||
DCAST_INTO_V(xy, input.get_data(_xy_input).get_ptr());
|
DCAST_INTO_V(xy, input.get_data(_xy_input).get_ptr());
|
||||||
const LVecBase2f &p = xy->get_value();
|
const LVecBase2f &p = xy->get_value();
|
||||||
@ -415,9 +415,7 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look for keyboard events.
|
// Look for keyboard events.
|
||||||
if (input.has_data(_button_events_input)) {
|
if (required_buttons_match && button_events != (const ButtonEventList *)NULL) {
|
||||||
const ButtonEventList *button_events;
|
|
||||||
DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
|
|
||||||
|
|
||||||
int num_events = button_events->get_num_events();
|
int num_events = button_events->get_num_events();
|
||||||
for (int i = 0; i < num_events; i++) {
|
for (int i = 0; i < num_events; i++) {
|
||||||
@ -425,19 +423,6 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
|||||||
if (be._type != ButtonEvent::T_keystroke) {
|
if (be._type != ButtonEvent::T_keystroke) {
|
||||||
bool down = (be._type == ButtonEvent::T_down);
|
bool down = (be._type == ButtonEvent::T_down);
|
||||||
|
|
||||||
if (down) {
|
|
||||||
// We only trap button down events if (a) the mouse is in the
|
|
||||||
// window, and (b) we aren't set to ignore the mouse.
|
|
||||||
if (got_mouse && !_ignore_mouse) {
|
|
||||||
be.update_mods(_mods);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// However, we always trap button up events, so we don't get
|
|
||||||
// confused and believe a button is still being held down when
|
|
||||||
// it is not.
|
|
||||||
be.update_mods(_mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (be._button == KeyboardButton::up()) {
|
if (be._button == KeyboardButton::up()) {
|
||||||
_up_arrow.set_key(down);
|
_up_arrow.set_key(down);
|
||||||
} else if (be._button == KeyboardButton::down()) {
|
} else if (be._button == KeyboardButton::down()) {
|
||||||
@ -451,7 +436,7 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(x, y, _mods.is_any_down());
|
apply(x, y, !_ignore_mouse && is_down(MouseButton::one()));
|
||||||
_transform = TransformState::make_pos_hpr(_xyz, _hpr);
|
_transform = TransformState::make_pos_hpr(_xyz, _hpr);
|
||||||
_velocity->set_value(_vel);
|
_velocity->set_value(_vel);
|
||||||
output.set_data(_transform_output, EventParameter(_transform));
|
output.set_data(_transform_output, EventParameter(_transform));
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
|
|
||||||
#include "dataNode.h"
|
#include "mouseInterfaceNode.h"
|
||||||
#include "modifierButtons.h"
|
#include "modifierButtons.h"
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
#include "linmath_events.h"
|
#include "linmath_events.h"
|
||||||
@ -35,7 +35,7 @@
|
|||||||
// The basic motion is on a horizontal plane, as if
|
// The basic motion is on a horizontal plane, as if
|
||||||
// driving a vehicle.
|
// driving a vehicle.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class EXPCL_PANDA DriveInterface : public DataNode {
|
class EXPCL_PANDA DriveInterface : public MouseInterfaceNode {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
DriveInterface(const string &name = "");
|
DriveInterface(const string &name = "");
|
||||||
~DriveInterface();
|
~DriveInterface();
|
||||||
@ -136,9 +136,6 @@ private:
|
|||||||
// This is only used to return a temporary value in get_mat().
|
// This is only used to return a temporary value in get_mat().
|
||||||
LMatrix4f _mat;
|
LMatrix4f _mat;
|
||||||
|
|
||||||
// Remember which mouse buttons are being held down.
|
|
||||||
ModifierButtons _mods;
|
|
||||||
|
|
||||||
// Remember which arrow keys are being held down and which aren't,
|
// Remember which arrow keys are being held down and which aren't,
|
||||||
// and at what point they last changed state.
|
// and at what point they last changed state.
|
||||||
class KeyHeld {
|
class KeyHeld {
|
||||||
@ -187,9 +184,9 @@ public:
|
|||||||
return _type_handle;
|
return _type_handle;
|
||||||
}
|
}
|
||||||
static void init_type() {
|
static void init_type() {
|
||||||
DataNode::init_type();
|
MouseInterfaceNode::init_type();
|
||||||
register_type(_type_handle, "DriveInterface",
|
register_type(_type_handle, "DriveInterface",
|
||||||
DataNode::get_class_type());
|
MouseInterfaceNode::get_class_type());
|
||||||
}
|
}
|
||||||
virtual TypeHandle get_type() const {
|
virtual TypeHandle get_type() const {
|
||||||
return get_class_type();
|
return get_class_type();
|
||||||
|
30
panda/src/tform/mouseInterfaceNode.I
Normal file
30
panda/src/tform/mouseInterfaceNode.I
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Filename: mouseInterfaceNode.I
|
||||||
|
// Created by: drose (11Jun04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::is_down
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Returns true if the indicated button (which must have
|
||||||
|
// been specified in a previous call to watch_button())
|
||||||
|
// is known to be held down, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool MouseInterfaceNode::
|
||||||
|
is_down(ButtonHandle button) const {
|
||||||
|
return _current_button_state.is_down(button);
|
||||||
|
}
|
155
panda/src/tform/mouseInterfaceNode.cxx
Normal file
155
panda/src/tform/mouseInterfaceNode.cxx
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
// Filename: mouseInterfaceNode.cxx
|
||||||
|
// Created by: drose (11Jun04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#include "trackball.h"
|
||||||
|
#include "buttonEvent.h"
|
||||||
|
#include "buttonEventList.h"
|
||||||
|
#include "dataNodeTransmit.h"
|
||||||
|
#include "mouseData.h"
|
||||||
|
|
||||||
|
TypeHandle MouseInterfaceNode::_type_handle;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MouseInterfaceNode::
|
||||||
|
MouseInterfaceNode(const string &name) :
|
||||||
|
DataNode(name)
|
||||||
|
{
|
||||||
|
_button_events_input = define_input("button_events", ButtonEventList::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::Destructor
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MouseInterfaceNode::
|
||||||
|
~MouseInterfaceNode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::require_button
|
||||||
|
// Access: Published
|
||||||
|
// Description: Indicates that the indicated button must be in the
|
||||||
|
// required state (either up or down) in order for this
|
||||||
|
// particular MouseInterfaceNode to do anything. For
|
||||||
|
// instance, this may be called to make a Trackball
|
||||||
|
// object respect mouse input only when the control key
|
||||||
|
// is held down.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MouseInterfaceNode::
|
||||||
|
require_button(const ButtonHandle &button, bool is_down) {
|
||||||
|
_required_buttons_mask.add_button(button);
|
||||||
|
_required_buttons_state.set_button_list(_required_buttons_mask);
|
||||||
|
_current_button_state.set_button_list(_required_buttons_mask);
|
||||||
|
|
||||||
|
_required_buttons_mask.button_down(button);
|
||||||
|
if (is_down) {
|
||||||
|
_required_buttons_state.button_down(button);
|
||||||
|
} else {
|
||||||
|
_required_buttons_state.button_up(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::clear_button
|
||||||
|
// Access: Published
|
||||||
|
// Description: Removes any requirement on the indicated button set
|
||||||
|
// by an earlier call to require_button().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MouseInterfaceNode::
|
||||||
|
clear_button(const ButtonHandle &button) {
|
||||||
|
_required_buttons_mask.button_up(button);
|
||||||
|
_required_buttons_state.button_up(button);
|
||||||
|
|
||||||
|
// The _required_buttons_mask and state must always keep the buttons
|
||||||
|
// that are listed in _watched_buttons.
|
||||||
|
|
||||||
|
if (!_watched_buttons.has_button(button)) {
|
||||||
|
_required_buttons_mask.remove_button(button);
|
||||||
|
_required_buttons_state.set_button_list(_required_buttons_mask);
|
||||||
|
_current_button_state.set_button_list(_required_buttons_mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::clear_all_button
|
||||||
|
// Access: Published
|
||||||
|
// Description: Removes all requirements on buttons set by an earlier
|
||||||
|
// call to require_button().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MouseInterfaceNode::
|
||||||
|
clear_all_buttons() {
|
||||||
|
_required_buttons_mask.all_buttons_up();
|
||||||
|
_required_buttons_state.all_buttons_up();
|
||||||
|
|
||||||
|
_required_buttons_mask.set_button_list(_watched_buttons);
|
||||||
|
_required_buttons_state.set_button_list(_watched_buttons);
|
||||||
|
_current_button_state.set_button_list(_watched_buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::watch_button
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Indicates that the derived class would like to know
|
||||||
|
// the state of the given button.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MouseInterfaceNode::
|
||||||
|
watch_button(const ButtonHandle &button) {
|
||||||
|
_watched_buttons.add_button(button);
|
||||||
|
|
||||||
|
// We also add the button to _required_buttons_mask and
|
||||||
|
// _required_buttons_state, but it's left 'up' in these two.
|
||||||
|
_required_buttons_mask.add_button(button);
|
||||||
|
_required_buttons_state.set_button_list(_required_buttons_mask);
|
||||||
|
_current_button_state.set_button_list(_required_buttons_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MouseInterfaceNode::check_button_events
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Gets the button events from the data graph and
|
||||||
|
// updates the ModifierButtons objects appropriately.
|
||||||
|
//
|
||||||
|
// Sets required_buttons_match to true if the required
|
||||||
|
// combination of buttons are being held down, or false
|
||||||
|
// otherwise.
|
||||||
|
//
|
||||||
|
// The return value is the list of button events
|
||||||
|
// processed this frame, or NULL if there are no button
|
||||||
|
// events.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const ButtonEventList *MouseInterfaceNode::
|
||||||
|
check_button_events(const DataNodeTransmit &input,
|
||||||
|
bool &required_buttons_match) {
|
||||||
|
const ButtonEventList *button_events = NULL;
|
||||||
|
|
||||||
|
if (input.has_data(_button_events_input)) {
|
||||||
|
DCAST_INTO_R(button_events, input.get_data(_button_events_input).get_ptr(), false);
|
||||||
|
button_events->update_mods(_current_button_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
required_buttons_match =
|
||||||
|
(_current_button_state & _required_buttons_mask) == _required_buttons_state;
|
||||||
|
|
||||||
|
return button_events;
|
||||||
|
}
|
84
panda/src/tform/mouseInterfaceNode.h
Normal file
84
panda/src/tform/mouseInterfaceNode.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Filename: mouseInterfaceNode.h
|
||||||
|
// Created by: drose (11Jun04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MOUSEINTERFACENODE_H
|
||||||
|
#define MOUSEINTERFACENODE_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "dataNode.h"
|
||||||
|
#include "modifierButtons.h"
|
||||||
|
|
||||||
|
class ButtonEventList;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : MouseInterfaceNode
|
||||||
|
// Description : This is the base class for some classes that monitor
|
||||||
|
// the mouse and keyboard input and perform some action
|
||||||
|
// due to their state.
|
||||||
|
//
|
||||||
|
// It collects together some common interface; in
|
||||||
|
// particular, the require_button() and related methods.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA MouseInterfaceNode : public DataNode {
|
||||||
|
public:
|
||||||
|
MouseInterfaceNode(const string &name);
|
||||||
|
virtual ~MouseInterfaceNode();
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
void require_button(const ButtonHandle &button, bool is_down);
|
||||||
|
void clear_button(const ButtonHandle &button);
|
||||||
|
void clear_all_buttons();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void watch_button(const ButtonHandle &button);
|
||||||
|
const ButtonEventList *check_button_events(const DataNodeTransmit &input,
|
||||||
|
bool &required_buttons_match);
|
||||||
|
|
||||||
|
INLINE bool is_down(ButtonHandle button) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModifierButtons _current_button_state;
|
||||||
|
ModifierButtons _watched_buttons;
|
||||||
|
ModifierButtons _required_buttons_mask;
|
||||||
|
ModifierButtons _required_buttons_state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _button_events_input;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
DataNode::init_type();
|
||||||
|
register_type(_type_handle, "MouseInterfaceNode",
|
||||||
|
DataNode::get_class_type());
|
||||||
|
}
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "mouseInterfaceNode.I"
|
||||||
|
|
||||||
|
#endif
|
@ -1,4 +1,6 @@
|
|||||||
#include "buttonThrower.cxx"
|
#include "buttonThrower.cxx"
|
||||||
#include "config_tform.cxx"
|
#include "config_tform.cxx"
|
||||||
#include "driveInterface.cxx"
|
#include "driveInterface.cxx"
|
||||||
|
#include "mouseInterfaceNode.cxx"
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,10 +38,9 @@ TypeHandle Trackball::_type_handle;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
Trackball::
|
Trackball::
|
||||||
Trackball(const string &name) :
|
Trackball(const string &name) :
|
||||||
DataNode(name)
|
MouseInterfaceNode(name)
|
||||||
{
|
{
|
||||||
_pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
|
_pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
|
||||||
_button_events_input = define_input("button_events", ButtonEventList::get_class_type());
|
|
||||||
|
|
||||||
_transform_output = define_output("transform", TransformState::get_class_type());
|
_transform_output = define_output("transform", TransformState::get_class_type());
|
||||||
|
|
||||||
@ -59,9 +58,10 @@ Trackball(const string &name) :
|
|||||||
_invert = true;
|
_invert = true;
|
||||||
_cs = default_coordinate_system;
|
_cs = default_coordinate_system;
|
||||||
|
|
||||||
_mods.add_button(MouseButton::one());
|
// We want to track the state of these buttons.
|
||||||
_mods.add_button(MouseButton::two());
|
watch_button(MouseButton::one());
|
||||||
_mods.add_button(MouseButton::three());
|
watch_button(MouseButton::two());
|
||||||
|
watch_button(MouseButton::three());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -535,14 +535,11 @@ recompute() {
|
|||||||
void Trackball::
|
void Trackball::
|
||||||
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
||||||
// First, update our modifier buttons.
|
// First, update our modifier buttons.
|
||||||
if (input.has_data(_button_events_input)) {
|
bool required_buttons_match;
|
||||||
const ButtonEventList *button_events;
|
check_button_events(input, required_buttons_match);
|
||||||
DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
|
|
||||||
button_events->update_mods(_mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, check for mouse motion.
|
// Now, check for mouse motion.
|
||||||
if (input.has_data(_pixel_xy_input)) {
|
if (required_buttons_match && input.has_data(_pixel_xy_input)) {
|
||||||
const EventStoreVec2 *pixel_xy;
|
const EventStoreVec2 *pixel_xy;
|
||||||
DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
|
DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
|
||||||
const LVecBase2f &p = pixel_xy->get_value();
|
const LVecBase2f &p = pixel_xy->get_value();
|
||||||
@ -550,13 +547,13 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
|||||||
float this_y = p[1];
|
float this_y = p[1];
|
||||||
int this_button = 0;
|
int this_button = 0;
|
||||||
|
|
||||||
if (_mods.is_down(MouseButton::one())) {
|
if (is_down(MouseButton::one())) {
|
||||||
this_button |= B1_MASK;
|
this_button |= B1_MASK;
|
||||||
}
|
}
|
||||||
if (_mods.is_down(MouseButton::two())) {
|
if (is_down(MouseButton::two())) {
|
||||||
this_button |= B2_MASK;
|
this_button |= B2_MASK;
|
||||||
}
|
}
|
||||||
if (_mods.is_down(MouseButton::three())) {
|
if (is_down(MouseButton::three())) {
|
||||||
this_button |= B3_MASK;
|
this_button |= B3_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
|
|
||||||
#include "dataNode.h"
|
#include "mouseInterfaceNode.h"
|
||||||
#include "nodePath.h"
|
#include "nodePath.h"
|
||||||
#include "modifierButtons.h"
|
#include "modifierButtons.h"
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
@ -41,7 +41,7 @@
|
|||||||
// it to actually transform objects (or cameras) in the
|
// it to actually transform objects (or cameras) in the
|
||||||
// world.
|
// world.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class EXPCL_PANDA Trackball : public DataNode {
|
class EXPCL_PANDA Trackball : public MouseInterfaceNode {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
Trackball(const string &name);
|
Trackball(const string &name);
|
||||||
~Trackball();
|
~Trackball();
|
||||||
@ -88,7 +88,7 @@ PUBLISHED:
|
|||||||
void set_invert(bool flag);
|
void set_invert(bool flag);
|
||||||
bool get_invert() const;
|
bool get_invert() const;
|
||||||
|
|
||||||
void set_rel_to(const NodePath &_rel_to);
|
void set_rel_to(const NodePath &rel_to);
|
||||||
const NodePath &get_rel_to() const;
|
const NodePath &get_rel_to() const;
|
||||||
|
|
||||||
void set_coordinate_system(CoordinateSystem cs);
|
void set_coordinate_system(CoordinateSystem cs);
|
||||||
@ -118,10 +118,6 @@ private:
|
|||||||
NodePath _rel_to;
|
NodePath _rel_to;
|
||||||
CoordinateSystem _cs;
|
CoordinateSystem _cs;
|
||||||
|
|
||||||
// Remember which mouse buttons are being held down.
|
|
||||||
ModifierButtons _mods;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited from DataNode
|
// Inherited from DataNode
|
||||||
virtual void do_transmit_data(const DataNodeTransmit &input,
|
virtual void do_transmit_data(const DataNodeTransmit &input,
|
||||||
@ -130,7 +126,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
// inputs
|
// inputs
|
||||||
int _pixel_xy_input;
|
int _pixel_xy_input;
|
||||||
int _button_events_input;
|
|
||||||
|
|
||||||
// outputs
|
// outputs
|
||||||
int _transform_output;
|
int _transform_output;
|
||||||
@ -142,9 +137,9 @@ public:
|
|||||||
return _type_handle;
|
return _type_handle;
|
||||||
}
|
}
|
||||||
static void init_type() {
|
static void init_type() {
|
||||||
DataNode::init_type();
|
MouseInterfaceNode::init_type();
|
||||||
register_type(_type_handle, "Trackball",
|
register_type(_type_handle, "Trackball",
|
||||||
DataNode::get_class_type());
|
MouseInterfaceNode::get_class_type());
|
||||||
}
|
}
|
||||||
virtual TypeHandle get_type() const {
|
virtual TypeHandle get_type() const {
|
||||||
return get_class_type();
|
return get_class_type();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user