mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
// Access: Published
|
||||
|
@ -29,7 +29,7 @@ ModifierButtons::
|
||||
ModifierButtons() :
|
||||
_state(0)
|
||||
{
|
||||
_button_list= PTA(ButtonHandle)::empty_array(0);
|
||||
_button_list = PTA(ButtonHandle)::empty_array(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -53,6 +53,97 @@ 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
|
||||
// Access: Published
|
||||
|
@ -41,6 +41,14 @@ PUBLISHED:
|
||||
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 add_button(ButtonHandle button);
|
||||
|
@ -13,6 +13,7 @@
|
||||
buttonThrower.I buttonThrower.h \
|
||||
config_tform.h \
|
||||
driveInterface.I driveInterface.h \
|
||||
mouseInterfaceNode.I mouseInterfaceNode.h \
|
||||
mouseWatcher.I mouseWatcher.h \
|
||||
mouseWatcherGroup.h \
|
||||
mouseWatcherParameter.I mouseWatcherParameter.h \
|
||||
@ -24,6 +25,7 @@
|
||||
buttonThrower.cxx \
|
||||
config_tform.cxx \
|
||||
driveInterface.cxx \
|
||||
mouseInterfaceNode.cxx \
|
||||
mouseWatcher.cxx \
|
||||
mouseWatcherGroup.cxx \
|
||||
mouseWatcherParameter.cxx mouseWatcherRegion.cxx \
|
||||
@ -33,6 +35,7 @@
|
||||
#define INSTALL_HEADERS \
|
||||
buttonThrower.I buttonThrower.h \
|
||||
driveInterface.I driveInterface.h \
|
||||
mouseInterfaceNode.I mouseInterfaceNode.h \
|
||||
mouseWatcher.I mouseWatcher.h \
|
||||
mouseWatcherGroup.h \
|
||||
mouseWatcherParameter.I mouseWatcherParameter.h \
|
||||
|
@ -46,6 +46,7 @@ const double drive_horizontal_ramp_down_time = config_tform.GetDouble("drive-hor
|
||||
ConfigureFn(config_tform) {
|
||||
DriveInterface::init_type();
|
||||
ButtonThrower::init_type();
|
||||
MouseInterfaceNode::init_type();
|
||||
MouseWatcher::init_type();
|
||||
MouseWatcherGroup::init_type();
|
||||
MouseWatcherRegion::init_type();
|
||||
|
@ -104,7 +104,7 @@ operator < (const DriveInterface::KeyHeld &other) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DriveInterface::
|
||||
DriveInterface(const string &name) :
|
||||
DataNode(name)
|
||||
MouseInterfaceNode(name)
|
||||
{
|
||||
_xy_input = define_input("xy", EventStoreVec2::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;
|
||||
_stop_this_frame = false;
|
||||
|
||||
_mods.add_button(MouseButton::one());
|
||||
_mods.add_button(MouseButton::two());
|
||||
_mods.add_button(MouseButton::three());
|
||||
watch_button(MouseButton::one());
|
||||
}
|
||||
|
||||
|
||||
@ -168,8 +166,6 @@ reset() {
|
||||
_down_arrow.clear();
|
||||
_left_arrow.clear();
|
||||
_right_arrow.clear();
|
||||
|
||||
_mods.all_buttons_up();
|
||||
}
|
||||
|
||||
|
||||
@ -398,13 +394,17 @@ apply(double x, double y, bool any_button) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DriveInterface::
|
||||
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.
|
||||
double x = 0.0f;
|
||||
double y = 0.0f;
|
||||
|
||||
bool got_mouse = false;
|
||||
|
||||
if (input.has_data(_xy_input)) {
|
||||
if (required_buttons_match && input.has_data(_xy_input)) {
|
||||
const EventStoreVec2 *xy;
|
||||
DCAST_INTO_V(xy, input.get_data(_xy_input).get_ptr());
|
||||
const LVecBase2f &p = xy->get_value();
|
||||
@ -415,28 +415,13 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
||||
}
|
||||
|
||||
// Look for keyboard events.
|
||||
if (input.has_data(_button_events_input)) {
|
||||
const ButtonEventList *button_events;
|
||||
DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
|
||||
if (required_buttons_match && button_events != (const ButtonEventList *)NULL) {
|
||||
|
||||
int num_events = button_events->get_num_events();
|
||||
for (int i = 0; i < num_events; i++) {
|
||||
const ButtonEvent &be = button_events->get_event(i);
|
||||
if (be._type != ButtonEvent::T_keystroke) {
|
||||
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()) {
|
||||
_up_arrow.set_key(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);
|
||||
_velocity->set_value(_vel);
|
||||
output.set_data(_transform_output, EventParameter(_transform));
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "dataNode.h"
|
||||
#include "mouseInterfaceNode.h"
|
||||
#include "modifierButtons.h"
|
||||
#include "luse.h"
|
||||
#include "linmath_events.h"
|
||||
@ -35,7 +35,7 @@
|
||||
// The basic motion is on a horizontal plane, as if
|
||||
// driving a vehicle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA DriveInterface : public DataNode {
|
||||
class EXPCL_PANDA DriveInterface : public MouseInterfaceNode {
|
||||
PUBLISHED:
|
||||
DriveInterface(const string &name = "");
|
||||
~DriveInterface();
|
||||
@ -136,9 +136,6 @@ private:
|
||||
// This is only used to return a temporary value in get_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,
|
||||
// and at what point they last changed state.
|
||||
class KeyHeld {
|
||||
@ -187,9 +184,9 @@ public:
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
DataNode::init_type();
|
||||
MouseInterfaceNode::init_type();
|
||||
register_type(_type_handle, "DriveInterface",
|
||||
DataNode::get_class_type());
|
||||
MouseInterfaceNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
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 "config_tform.cxx"
|
||||
#include "driveInterface.cxx"
|
||||
#include "mouseInterfaceNode.cxx"
|
||||
|
||||
|
||||
|
@ -38,10 +38,9 @@ TypeHandle Trackball::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Trackball::
|
||||
Trackball(const string &name) :
|
||||
DataNode(name)
|
||||
MouseInterfaceNode(name)
|
||||
{
|
||||
_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());
|
||||
|
||||
@ -59,9 +58,10 @@ Trackball(const string &name) :
|
||||
_invert = true;
|
||||
_cs = default_coordinate_system;
|
||||
|
||||
_mods.add_button(MouseButton::one());
|
||||
_mods.add_button(MouseButton::two());
|
||||
_mods.add_button(MouseButton::three());
|
||||
// We want to track the state of these buttons.
|
||||
watch_button(MouseButton::one());
|
||||
watch_button(MouseButton::two());
|
||||
watch_button(MouseButton::three());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -535,36 +535,33 @@ recompute() {
|
||||
void Trackball::
|
||||
do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
|
||||
// First, update our modifier buttons.
|
||||
if (input.has_data(_button_events_input)) {
|
||||
const ButtonEventList *button_events;
|
||||
DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
|
||||
button_events->update_mods(_mods);
|
||||
}
|
||||
bool required_buttons_match;
|
||||
check_button_events(input, required_buttons_match);
|
||||
|
||||
// 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;
|
||||
DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
|
||||
const LVecBase2f &p = pixel_xy->get_value();
|
||||
float this_x = p[0];
|
||||
float this_y = p[1];
|
||||
int this_button = 0;
|
||||
|
||||
if (_mods.is_down(MouseButton::one())) {
|
||||
|
||||
if (is_down(MouseButton::one())) {
|
||||
this_button |= B1_MASK;
|
||||
}
|
||||
if (_mods.is_down(MouseButton::two())) {
|
||||
if (is_down(MouseButton::two())) {
|
||||
this_button |= B2_MASK;
|
||||
}
|
||||
if (_mods.is_down(MouseButton::three())) {
|
||||
if (is_down(MouseButton::three())) {
|
||||
this_button |= B3_MASK;
|
||||
}
|
||||
|
||||
|
||||
float x = this_x - _lastx;
|
||||
float y = this_y - _lasty;
|
||||
|
||||
|
||||
apply(x, y, this_button);
|
||||
|
||||
|
||||
_lastx = this_x;
|
||||
_lasty = this_y;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "dataNode.h"
|
||||
#include "mouseInterfaceNode.h"
|
||||
#include "nodePath.h"
|
||||
#include "modifierButtons.h"
|
||||
#include "luse.h"
|
||||
@ -41,7 +41,7 @@
|
||||
// it to actually transform objects (or cameras) in the
|
||||
// world.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Trackball : public DataNode {
|
||||
class EXPCL_PANDA Trackball : public MouseInterfaceNode {
|
||||
PUBLISHED:
|
||||
Trackball(const string &name);
|
||||
~Trackball();
|
||||
@ -88,7 +88,7 @@ PUBLISHED:
|
||||
void set_invert(bool flag);
|
||||
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;
|
||||
|
||||
void set_coordinate_system(CoordinateSystem cs);
|
||||
@ -118,10 +118,6 @@ private:
|
||||
NodePath _rel_to;
|
||||
CoordinateSystem _cs;
|
||||
|
||||
// Remember which mouse buttons are being held down.
|
||||
ModifierButtons _mods;
|
||||
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
virtual void do_transmit_data(const DataNodeTransmit &input,
|
||||
@ -130,7 +126,6 @@ protected:
|
||||
private:
|
||||
// inputs
|
||||
int _pixel_xy_input;
|
||||
int _button_events_input;
|
||||
|
||||
// outputs
|
||||
int _transform_output;
|
||||
@ -142,9 +137,9 @@ public:
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
DataNode::init_type();
|
||||
MouseInterfaceNode::init_type();
|
||||
register_type(_type_handle, "Trackball",
|
||||
DataNode::get_class_type());
|
||||
MouseInterfaceNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
Loading…
x
Reference in New Issue
Block a user