support keystrokes in addition to button up/down

This commit is contained in:
David Rose 2002-02-16 00:09:53 +00:00
parent 5f67b022d8
commit 6739d86101
28 changed files with 480 additions and 50 deletions

View File

@ -53,7 +53,7 @@ set_button_state(int index, bool down) {
ButtonHandle handle = _buttons[index]._handle;
if (handle != ButtonHandle::none()) {
_button_events->push_back(ButtonEvent(handle, down));
_button_events->push_back(ButtonEvent(handle, down ? ButtonEvent::T_down : ButtonEvent::T_up));
}
}

View File

@ -101,7 +101,7 @@ set_mouse_on(bool flag) {
////////////////////////////////////////////////////////////////////
void VirtualMouse::
press_button(ButtonHandle button) {
_next_button_events->push_back(ButtonEvent(button, true));
_next_button_events->push_back(ButtonEvent(button, ButtonEvent::T_down));
}
////////////////////////////////////////////////////////////////////
@ -112,7 +112,7 @@ press_button(ButtonHandle button) {
////////////////////////////////////////////////////////////////////
void VirtualMouse::
release_button(ButtonHandle button) {
_next_button_events->push_back(ButtonEvent(button, false));
_next_button_events->push_back(ButtonEvent(button, ButtonEvent::T_up));
}
////////////////////////////////////////////////////////////////////

View File

@ -155,7 +155,7 @@ get_button_event() {
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
button_down(ButtonHandle button) {
_button_events.push_back(ButtonEvent(button, true));
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_down));
}
////////////////////////////////////////////////////////////////////
@ -165,5 +165,16 @@ button_down(ButtonHandle button) {
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
button_up(ButtonHandle button) {
_button_events.push_back(ButtonEvent(button, false));
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_up));
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindowInputDevice::keystroke
// Access: Public
// Description: Records that the indicated keystroke has been
// generated.
////////////////////////////////////////////////////////////////////
void GraphicsWindowInputDevice::
keystroke(int keycode) {
_button_events.push_back(ButtonEvent(keycode));
}

View File

@ -63,6 +63,7 @@ public:
// GraphicsWindows to record the data incoming on the device.
void button_down(ButtonHandle button);
void button_up(ButtonHandle button);
void keystroke(int keycode);
INLINE void set_pointer_in_window(int x, int y);
INLINE void set_pointer_out_of_window();

View File

@ -735,6 +735,9 @@ handle_keypress(ButtonHandle key, int x, int y) {
_input_devices[0].set_pointer_in_window(x, y);
if (key != ButtonHandle::none()) {
_input_devices[0].button_down(key);
if (key.has_ascii_equivalent()) {
_input_devices[0].keystroke(key.get_ascii_equivalent());
}
}
}

View File

@ -36,8 +36,15 @@ ConfigureFn(config_pgui) {
init_libpgui();
}
// If this is true, uses a QuickRenderTraverser to render PGItems;
// otherwise, uses a normal DirectRenderTraverser, which is more
// powerful but somewhat slower.
const bool pgui_quick = config_pgui.GetBool("pgui-quick", true);
// Temporary variable to support old-style button press/release for
// pgentries, before keystrokes were implemented.
const bool use_keystrokes = config_pgui.GetBool("use-keystrokes", false);
////////////////////////////////////////////////////////////////////
// Function: init_libpgui

View File

@ -26,6 +26,7 @@ NotifyCategoryDecl(pgui, EXPCL_PANDA, EXPTP_PANDA);
// Configure variables for pgui package.
extern const bool pgui_quick;
extern const bool use_keystrokes;
extern EXPCL_PANDA void init_libpgui();

View File

@ -237,7 +237,7 @@ press(const MouseWatcherParameter &param, bool background) {
_cursor_stale = true;
}
} else if (button.has_ascii_equivalent()) {
} else if (!use_keystrokes && button.has_ascii_equivalent()) {
char key = button.get_ascii_equivalent();
if (isprint(key)) {
// A normal visible character. Add a new character to the
@ -340,6 +340,121 @@ press(const MouseWatcherParameter &param, bool background) {
PGItem::press(param, background);
}
////////////////////////////////////////////////////////////////////
// Function: PGEntry::keystroke
// Access: Public, Virtual
// Description: This is a callback hook function, called whenever
// the user types a key.
////////////////////////////////////////////////////////////////////
void PGEntry::
keystroke(const MouseWatcherParameter &param, bool background) {
if (get_active()) {
if (param.has_keycode()) {
int keycode = param.get_keycode();
if (use_keystrokes) {
if (!isascii(keycode) || isprint(keycode)) {
// A normal visible character. Add a new character to the
// text entry, if there's room.
string new_char(1, (char)keycode);
if (get_max_chars() > 0 && (int)_text.length() >= get_max_chars()) {
overflow(param);
} else {
string new_text =
_text.substr(0, _cursor_position) + new_char +
_text.substr(_cursor_position);
// Get a string to measure its length. In normal mode,
// we measure the text itself. In obscure mode, we
// measure a string of n asterisks.
string measure_text;
if (_obscure_mode) {
measure_text = get_display_text() + '*';
} else {
measure_text = new_text;
}
// Check the length.
bool too_long = false;
if (_max_width > 0.0f) {
TextNode *text_node = get_text_def(S_focus);
if (_num_lines <= 1) {
// If we have only one line, we can check the length
// by simply measuring the width of the text.
too_long = (text_node->calc_width(measure_text) > _max_width);
} else {
// If we have multiple lines, we have to check the
// length by wordwrapping it and counting up the
// number of lines.
string ww_text = text_node->wordwrap_to(measure_text, _max_width, true);
int num_lines = 1;
size_t last_line_start = 0;
for (size_t p = 0;
p < ww_text.length() && !too_long;
++p) {
if (ww_text[p] == '\n') {
last_line_start = p + 1;
num_lines++;
too_long = (num_lines > _num_lines);
}
}
if (!too_long) {
// We must also ensure that the last line is not too
// long (it might be, because of additional
// whitespace on the end).
string last_line = ww_text.substr(last_line_start);
float last_line_width = text_node->calc_width(last_line);
if (num_lines == _num_lines) {
// Mainly we only care about this if we're on
// the very last line.
too_long = (last_line_width > _max_width);
} else {
// If we're not on the very last line, the width
// is still important, just so we don't allow an
// infinite number of spaces to accumulate.
// However, we must allow at least *one* space
// on the end of a line.
if (_text.length() >= 1 &&
_text[_text.length() - 1] == ' ') {
if (last_line_width > _max_width) {
// In this case, however, it's not exactly
// an overflow; we just want to reject the
// space.
return;
}
}
}
}
}
}
if (too_long) {
overflow(param);
} else {
_text = new_text;
if (_obscure_mode) {
_obscured_text = measure_text;
}
_cursor_position += new_char.size();
_cursor_stale = true;
_text_geom_stale = true;
type(param);
}
}
}
}
}
}
PGItem::keystroke(param, background);
}
////////////////////////////////////////////////////////////////////
// Function: PGEntry::accept
// Access: Public, Virtual

View File

@ -49,6 +49,7 @@ public:
const AllTransitionsWrapper &trans);
virtual void press(const MouseWatcherParameter &param, bool background);
virtual void keystroke(const MouseWatcherParameter &param, bool background);
virtual void accept(const MouseWatcherParameter &param);
virtual void overflow(const MouseWatcherParameter &param);

View File

@ -317,6 +317,19 @@ get_release_prefix() {
return "release-";
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::get_keystroke_prefix
// Access: Published, Static
// Description: Returns the prefix that is used to define the
// keystroke event for all PGItems. The keystroke event
// is the concatenation of this string followed by a
// hyphen and get_id().
////////////////////////////////////////////////////////////////////
INLINE string PGItem::
get_keystroke_prefix() {
return "keystroke-";
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::get_enter_event
// Access: Published
@ -418,6 +431,17 @@ get_release_event(const ButtonHandle &button) const {
return get_release_prefix() + button.get_name() + "-" + get_id();
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::get_keystroke_event
// Access: Published
// Description: Returns the event name that will be thrown when the
// item is active and any key is pressed by the user.
////////////////////////////////////////////////////////////////////
INLINE string PGItem::
get_keystroke_event() const {
return get_keystroke_prefix() + "-" + get_id();
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::set_text_node
// Access: Published, Static

View File

@ -349,6 +349,22 @@ release(const MouseWatcherParameter &param, bool background) {
}
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::keystroke
// Access: Public, Virtual
// Description: This is a callback hook function, called whenever
// the user presses a key.
////////////////////////////////////////////////////////////////////
void PGItem::
keystroke(const MouseWatcherParameter &param, bool background) {
if (!background) {
PGMouseWatcherParameter *ep = new PGMouseWatcherParameter(param);
string event = get_keystroke_event();
play_sound(event);
throw_event(event, EventParameter(ep));
}
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::background_press
// Access: Public, Static
@ -383,6 +399,23 @@ background_release(const MouseWatcherParameter &param) {
}
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::background_keystroke
// Access: Public, Static
// Description: Calls keystroke() on all the PGItems with background
// focus.
////////////////////////////////////////////////////////////////////
void PGItem::
background_keystroke(const MouseWatcherParameter &param) {
BackgroundFocus::const_iterator fi;
for (fi = _background_focus.begin(); fi != _background_focus.end(); ++fi) {
PGItem *item = *fi;
if (!item->get_focus()) {
item->keystroke(param, true);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PGItem::set_active
// Access: Published, Virtual

View File

@ -81,9 +81,11 @@ public:
virtual void focus_out();
virtual void press(const MouseWatcherParameter &param, bool background);
virtual void release(const MouseWatcherParameter &param, bool background);
virtual void keystroke(const MouseWatcherParameter &param, bool background);
static void background_press(const MouseWatcherParameter &param);
static void background_release(const MouseWatcherParameter &param);
static void background_keystroke(const MouseWatcherParameter &param);
PUBLISHED:
INLINE void set_frame(float left, float right, float bottom, float top);
@ -127,6 +129,7 @@ PUBLISHED:
INLINE static string get_focus_out_prefix();
INLINE static string get_press_prefix();
INLINE static string get_release_prefix();
INLINE static string get_keystroke_prefix();
INLINE string get_enter_event() const;
INLINE string get_exit_event() const;
@ -136,6 +139,7 @@ PUBLISHED:
INLINE string get_focus_out_event() const;
INLINE string get_press_event(const ButtonHandle &button) const;
INLINE string get_release_event(const ButtonHandle &button) const;
INLINE string get_keystroke_event() const;
#ifdef HAVE_AUDIO
void set_sound(const string &event, AudioSound *sound);

View File

@ -66,3 +66,14 @@ void PGMouseWatcherBackground::
release(const MouseWatcherParameter &param) {
PGItem::background_release(param);
}
////////////////////////////////////////////////////////////////////
// Function: PGMouseWatcherBackground::keystroke
// Access: Public, Virtual
// Description: This is a callback hook function, called whenever
// the user presses a key.
////////////////////////////////////////////////////////////////////
void PGMouseWatcherBackground::
keystroke(const MouseWatcherParameter &param) {
PGItem::background_keystroke(param);
}

View File

@ -37,6 +37,7 @@ PUBLISHED:
virtual void press(const MouseWatcherParameter &param);
virtual void release(const MouseWatcherParameter &param);
virtual void keystroke(const MouseWatcherParameter &param);
public:
static TypeHandle get_class_type() {

View File

@ -138,3 +138,16 @@ release(const MouseWatcherParameter &param) {
_item->release(param, false);
}
}
////////////////////////////////////////////////////////////////////
// Function: PGMouseWatcherRegion::keystroke
// Access: Public, Virtual
// Description: This is a callback hook function, called whenever
// the user presses a key.
////////////////////////////////////////////////////////////////////
void PGMouseWatcherRegion::
keystroke(const MouseWatcherParameter &param) {
if (_item != (PGItem *)NULL) {
_item->keystroke(param, false);
}
}

View File

@ -43,6 +43,7 @@ public:
virtual void without(const MouseWatcherParameter &param);
virtual void press(const MouseWatcherParameter &param);
virtual void release(const MouseWatcherParameter &param);
virtual void keystroke(const MouseWatcherParameter &param);
private:
PGItem *_item;

View File

@ -25,7 +25,8 @@
INLINE ButtonEvent::
ButtonEvent() :
_button(ButtonHandle::none()),
_down(false)
_keycode(0),
_type(T_down)
{
}
@ -35,9 +36,23 @@ ButtonEvent() :
// Description:
////////////////////////////////////////////////////////////////////
INLINE ButtonEvent::
ButtonEvent(ButtonHandle button, bool down) :
ButtonEvent(ButtonHandle button, ButtonEvent::Type type) :
_button(button),
_down(down)
_keycode(0),
_type(type)
{
}
////////////////////////////////////////////////////////////////////
// Function: ButtonEvent::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ButtonEvent::
ButtonEvent(short keycode) :
_button(ButtonHandle::none()),
_keycode(keycode),
_type(T_keystroke)
{
}
@ -49,7 +64,8 @@ ButtonEvent(ButtonHandle button, bool down) :
INLINE ButtonEvent::
ButtonEvent(const ButtonEvent &copy) :
_button(copy._button),
_down(copy._down)
_keycode(copy._keycode),
_type(copy._type)
{
}
@ -61,7 +77,8 @@ ButtonEvent(const ButtonEvent &copy) :
INLINE void ButtonEvent::
operator = (const ButtonEvent &copy) {
_button = copy._button;
_down = copy._down;
_keycode = copy._keycode;
_type = copy._type;
}
////////////////////////////////////////////////////////////////////
@ -72,7 +89,8 @@ operator = (const ButtonEvent &copy) {
INLINE bool ButtonEvent::
operator == (const ButtonEvent &other) const {
return (_button == other._button &&
_down == other._down);
_keycode == other._keycode &&
_type == other._type);
}
////////////////////////////////////////////////////////////////////
@ -95,6 +113,9 @@ operator < (const ButtonEvent &other) const {
if (_button != other._button) {
return _button < other._button;
}
if (_keycode != other._keycode) {
return _keycode < other._keycode;
}
return _down < other._down;
return _type < other._type;
}

View File

@ -25,10 +25,17 @@
////////////////////////////////////////////////////////////////////
void ButtonEvent::
output(ostream &out) const {
out << "button " << _button;
if (_down) {
out << " down";
} else {
out << " up";
switch (_type) {
case T_down:
out << "button " << _button << " down";
break;
case T_up:
out << "button " << _button << " up";
break;
case T_keystroke:
out << "keystroke " << _keycode;
break;
}
}

View File

@ -19,19 +19,47 @@
#ifndef BUTTONEVENT_H
#define BUTTONEVENT_H
#include <pandabase.h>
#include "pandabase.h"
#include "buttonHandle.h"
////////////////////////////////////////////////////////////////////
// Class : ButtonEvent
// Description : Records a transition of one button from up to down or
// vice-versa.
// Description : Records a button event of some kind. This is either
// a keyboard or mouse button (or some other kind of
// button) changing state from up to down, or
// vice-versa, or it is a single "keystroke".
//
// A keystroke is different than a button event in that
// (a) it does not necessarily correspond to a physical
// button on a keyboard, but might be the result of a
// combination of buttons (e.g. "A" is the result of
// shift + "a"); and (b) it does not manage separate
// "up" and "down" events, but is itself an
// instantaneous event.
//
// Normal up/down button events can be used to track the
// state of a particular button on the keyboard, while
// keystroke events are best used to monitor what a user
// is attempting to type.
//
// Button up/down events are defined across all the
// physical keys on the keyboard (and other buttons for
// which there is a corresponding ButtonHandle object),
// while keystroke events are defined across the entire
// Unicode character set.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ButtonEvent {
public:
enum Type {
T_down,
T_up,
T_keystroke
};
INLINE ButtonEvent();
INLINE ButtonEvent(ButtonHandle button, bool down);
INLINE ButtonEvent(ButtonHandle button, Type type);
INLINE ButtonEvent(short keycode);
INLINE ButtonEvent(const ButtonEvent &copy);
INLINE void operator = (const ButtonEvent &copy);
@ -41,8 +69,14 @@ public:
void output(ostream &out) const;
// _button will be filled in if type is T_down or T_up.
ButtonHandle _button;
bool _down;
// _keycode will be filled in if type is T_keystroke. It will be
// the Unicode character that was typed.
short _keycode;
Type _type;
};
INLINE ostream &operator << (ostream &out, const ButtonEvent &be) {

View File

@ -100,10 +100,15 @@ get_button(int index) const {
////////////////////////////////////////////////////////////////////
INLINE bool ModifierButtons::
add_event(const ButtonEvent &event) {
if (event._down) {
switch (event._type) {
case ButtonEvent::T_down:
return button_down(event._button);
} else {
case ButtonEvent::T_up:
return button_up(event._button);
default:
return false;
}
}

View File

@ -335,7 +335,7 @@ transmit_data(AllTransitionsWrapper &data) {
const ButtonEvent &be = (*bi);
string event_name = be._button.get_name();
if (be._down) {
if (be._type == ButtonEvent::T_down) {
// Button down.
if (!_mods.button_down(be._button)) {
// We only prepend modifier names on the button-down events,
@ -356,7 +356,7 @@ transmit_data(AllTransitionsWrapper &data) {
new_b->push_back(be);
}
} else {
} else if (be._type == ButtonEvent::T_up) {
// Button up.
_mods.button_up(be._button);
@ -376,6 +376,14 @@ transmit_data(AllTransitionsWrapper &data) {
}
new_b->push_back(be);
}
} else {
// Some other kind of button event (e.g. keypress). Don't
// throw an event for this, but do pass it down.
if (new_b == (ButtonEventDataTransition *)NULL) {
new_b = new ButtonEventDataTransition;
}
new_b->push_back(be);
}
}
}

View File

@ -435,27 +435,31 @@ transmit_data(AllTransitionsWrapper &data) {
ButtonEventDataTransition::const_iterator bi;
for (bi = b->begin(); bi != b->end(); ++bi) {
const ButtonEvent &be = (*bi);
if (be._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) {
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) {
_mods.add_event(be);
}
} 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.
_mods.add_event(be);
}
} 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.
_mods.add_event(be);
}
if (be._button == KeyboardButton::up()) {
_up_arrow.set_key(be._down);
} else if (be._button == KeyboardButton::down()) {
_down_arrow.set_key(be._down);
} else if (be._button == KeyboardButton::left()) {
_left_arrow.set_key(be._down);
} else if (be._button == KeyboardButton::right()) {
_right_arrow.set_key(be._down);
if (be._button == KeyboardButton::up()) {
_up_arrow.set_key(down);
} else if (be._button == KeyboardButton::down()) {
_down_arrow.set_key(down);
} else if (be._button == KeyboardButton::left()) {
_left_arrow.set_key(down);
} else if (be._button == KeyboardButton::right()) {
_right_arrow.set_key(down);
}
}
}
}

View File

@ -681,6 +681,37 @@ release(ButtonHandle button) {
}
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcher::keystroke
// Access: Protected
// Description: Records that the indicated keystroke has been
// generated.
////////////////////////////////////////////////////////////////////
void MouseWatcher::
keystroke(int keycode) {
MouseWatcherParameter param;
param.set_keycode(keycode);
param.set_modifier_buttons(_mods);
param.set_mouse(_mouse);
// Send the event to every region that wants keyboard buttons,
// regardless of the mouse position.
if (_preferred_region != (MouseWatcherRegion *)NULL) {
// Our current region, the one under the mouse, always get
// all the keyboard events, even if it doesn't set its
// keyboard flag.
_preferred_region->keystroke(param);
}
if ((_suppress_flags & MouseWatcherRegion::SF_other_button) == 0) {
// All the other regions only get the keyboard events if they
// set their global keyboard flag, *and* the current region does
// not suppress keyboard buttons.
param.set_outside(true);
global_keystroke(param);
}
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcher::global_keyboard_press
// Access: Protected
@ -712,7 +743,6 @@ global_keyboard_press(const MouseWatcherParameter &param) {
}
}
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcher::global_keyboard_release
// Access: Protected
@ -745,6 +775,38 @@ global_keyboard_release(const MouseWatcherParameter &param) {
}
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcher::global_keystroke
// Access: Protected
// Description: Calls keystroke() on all regions that are interested
// in receiving global keyboard events, except for the
// current region (which already received this one).
////////////////////////////////////////////////////////////////////
void MouseWatcher::
global_keystroke(const MouseWatcherParameter &param) {
Regions::const_iterator ri;
for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
MouseWatcherRegion *region = (*ri);
if (region != _preferred_region && region->get_keyboard()) {
region->keystroke(param);
}
}
// Also check all of our sub-groups.
Groups::const_iterator gi;
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
MouseWatcherGroup *group = (*gi);
for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
MouseWatcherRegion *region = (*ri);
if (region != _preferred_region && region->get_keyboard()) {
region->keystroke(param);
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcher::enter_region
// Access: Protected
@ -835,10 +897,18 @@ transmit_data(AllTransitionsWrapper &data) {
const ButtonEvent &be = (*bi);
_mods.add_event(be);
if (be._down) {
switch (be._type) {
case ButtonEvent::T_down:
press(be._button);
} else {
break;
case ButtonEvent::T_up:
release(be._button);
break;
case ButtonEvent::T_keystroke:
keystroke(be._keycode);
break;
}
}
}
@ -864,7 +934,8 @@ transmit_data(AllTransitionsWrapper &data) {
const ButtonEvent &be = (*bi);
bool suppress = true;
if (MouseButton::is_mouse_button(be._button)) {
if (be._type != ButtonEvent::T_keystroke &&
MouseButton::is_mouse_button(be._button)) {
suppress = ((suppress_buttons & MouseWatcherRegion::SF_mouse_button) != 0);
} else {
suppress = ((suppress_buttons & MouseWatcherRegion::SF_other_button) != 0);

View File

@ -135,8 +135,10 @@ protected:
void press(ButtonHandle button);
void release(ButtonHandle button);
void keystroke(int keycode);
void global_keyboard_press(const MouseWatcherParameter &param);
void global_keyboard_release(const MouseWatcherParameter &param);
void global_keystroke(const MouseWatcherParameter &param);
INLINE void within_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);
INLINE void without_region(MouseWatcherRegion *region, const MouseWatcherParameter &param);

View File

@ -35,6 +35,7 @@ MouseWatcherParameter() {
INLINE MouseWatcherParameter::
MouseWatcherParameter(const MouseWatcherParameter &copy) :
_button(copy._button),
_keycode(copy._keycode),
_mods(copy._mods),
_mouse(copy._mouse),
_flags(copy._flags)
@ -49,6 +50,7 @@ MouseWatcherParameter(const MouseWatcherParameter &copy) :
INLINE void MouseWatcherParameter::
operator = (const MouseWatcherParameter &copy) {
_button = copy._button;
_keycode = copy._keycode;
_mods = copy._mods;
_mouse = copy._mouse;
_flags = copy._flags;
@ -75,6 +77,17 @@ set_button(const ButtonHandle &button) {
_flags |= F_has_button;
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcherParameter::set_keycode
// Access: Public
// Description: Sets the keycode associated with this event, if any.
////////////////////////////////////////////////////////////////////
INLINE void MouseWatcherParameter::
set_keycode(int keycode) {
_keycode = keycode;
_flags |= F_has_keycode;
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcherParameter::set_modifier_buttons
// Access: Public
@ -138,6 +151,28 @@ get_button() const {
return _button;
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcherParameter::has_keycode
// Access: Published
// Description: Returns true if this parameter has an associated
// keycode, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool MouseWatcherParameter::
has_keycode() const {
return (_flags & F_has_keycode) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcherParameter::get_keycode
// Access: Published
// Description: Returns the keycode associated with this event. If
// has_keycode(), above, returns false, this returns 0.
////////////////////////////////////////////////////////////////////
INLINE int MouseWatcherParameter::
get_keycode() const {
return _keycode;
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcherParameter::get_modifier_buttons
// Access: Published

View File

@ -39,6 +39,7 @@ public:
INLINE ~MouseWatcherParameter();
INLINE void set_button(const ButtonHandle &button);
INLINE void set_keycode(int keycode);
INLINE void set_modifier_buttons(const ModifierButtons &mods);
INLINE void set_mouse(const LPoint2f &mouse);
INLINE void set_outside(bool flag);
@ -47,6 +48,9 @@ PUBLISHED:
INLINE bool has_button() const;
INLINE ButtonHandle get_button() const;
INLINE bool has_keycode() const;
INLINE int get_keycode() const;
INLINE const ModifierButtons &get_modifier_buttons() const;
INLINE bool has_mouse() const;
@ -58,6 +62,7 @@ PUBLISHED:
public:
ButtonHandle _button;
short _keycode;
ModifierButtons _mods;
LPoint2f _mouse;
@ -65,6 +70,7 @@ public:
F_has_button = 0x001,
F_has_mouse = 0x002,
F_is_outside = 0x004,
F_has_keycode = 0x008,
};
int _flags;
};

View File

@ -117,3 +117,13 @@ press(const MouseWatcherParameter &) {
void MouseWatcherRegion::
release(const MouseWatcherParameter &) {
}
////////////////////////////////////////////////////////////////////
// Function: MouseWatcherRegion::keystroke
// Access: Public, Virtual
// Description: This is a callback hook function, called whenever a
// keystroke is generated by the user.
////////////////////////////////////////////////////////////////////
void MouseWatcherRegion::
keystroke(const MouseWatcherParameter &) {
}

View File

@ -76,6 +76,7 @@ public:
virtual void without(const MouseWatcherParameter &param);
virtual void press(const MouseWatcherParameter &param);
virtual void release(const MouseWatcherParameter &param);
virtual void keystroke(const MouseWatcherParameter &param);
private:
LVecBase4f _frame;