support keystrokes in addition to button up/down
This commit is contained in:
parent
5f67b022d8
commit
6739d86101
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ press(const MouseWatcherParameter ¶m, 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 ¶m, 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 ¶m, 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
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
const AllTransitionsWrapper &trans);
|
||||
|
||||
virtual void press(const MouseWatcherParameter ¶m, bool background);
|
||||
virtual void keystroke(const MouseWatcherParameter ¶m, bool background);
|
||||
|
||||
virtual void accept(const MouseWatcherParameter ¶m);
|
||||
virtual void overflow(const MouseWatcherParameter ¶m);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -349,6 +349,22 @@ release(const MouseWatcherParameter ¶m, 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 ¶m, 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 ¶m) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::background_keystroke
|
||||
// Access: Public, Static
|
||||
// Description: Calls keystroke() on all the PGItems with background
|
||||
// focus.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
background_keystroke(const MouseWatcherParameter ¶m) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -81,9 +81,11 @@ public:
|
|||
virtual void focus_out();
|
||||
virtual void press(const MouseWatcherParameter ¶m, bool background);
|
||||
virtual void release(const MouseWatcherParameter ¶m, bool background);
|
||||
virtual void keystroke(const MouseWatcherParameter ¶m, bool background);
|
||||
|
||||
static void background_press(const MouseWatcherParameter ¶m);
|
||||
static void background_release(const MouseWatcherParameter ¶m);
|
||||
static void background_keystroke(const MouseWatcherParameter ¶m);
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -66,3 +66,14 @@ void PGMouseWatcherBackground::
|
|||
release(const MouseWatcherParameter ¶m) {
|
||||
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 ¶m) {
|
||||
PGItem::background_keystroke(param);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ PUBLISHED:
|
|||
|
||||
virtual void press(const MouseWatcherParameter ¶m);
|
||||
virtual void release(const MouseWatcherParameter ¶m);
|
||||
virtual void keystroke(const MouseWatcherParameter ¶m);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -138,3 +138,16 @@ release(const MouseWatcherParameter ¶m) {
|
|||
_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 ¶m) {
|
||||
if (_item != (PGItem *)NULL) {
|
||||
_item->keystroke(param, false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public:
|
|||
virtual void without(const MouseWatcherParameter ¶m);
|
||||
virtual void press(const MouseWatcherParameter ¶m);
|
||||
virtual void release(const MouseWatcherParameter ¶m);
|
||||
virtual void keystroke(const MouseWatcherParameter ¶m);
|
||||
|
||||
private:
|
||||
PGItem *_item;
|
||||
|
|
|
|||
|
|
@ -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 ©) :
|
||||
_button(copy._button),
|
||||
_down(copy._down)
|
||||
_keycode(copy._keycode),
|
||||
_type(copy._type)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +77,8 @@ ButtonEvent(const ButtonEvent ©) :
|
|||
INLINE void ButtonEvent::
|
||||
operator = (const ButtonEvent ©) {
|
||||
_button = copy._button;
|
||||
_down = copy._down;
|
||||
_keycode = copy._keycode;
|
||||
_type = copy._type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -72,7 +89,8 @@ operator = (const ButtonEvent ©) {
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const ButtonEvent ©);
|
||||
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ¶m) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::global_keyboard_release
|
||||
// Access: Protected
|
||||
|
|
@ -745,6 +775,38 @@ global_keyboard_release(const MouseWatcherParameter ¶m) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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 ¶m) {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -135,8 +135,10 @@ protected:
|
|||
|
||||
void press(ButtonHandle button);
|
||||
void release(ButtonHandle button);
|
||||
void keystroke(int keycode);
|
||||
void global_keyboard_press(const MouseWatcherParameter ¶m);
|
||||
void global_keyboard_release(const MouseWatcherParameter ¶m);
|
||||
void global_keystroke(const MouseWatcherParameter ¶m);
|
||||
|
||||
INLINE void within_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m);
|
||||
INLINE void without_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ MouseWatcherParameter() {
|
|||
INLINE MouseWatcherParameter::
|
||||
MouseWatcherParameter(const MouseWatcherParameter ©) :
|
||||
_button(copy._button),
|
||||
_keycode(copy._keycode),
|
||||
_mods(copy._mods),
|
||||
_mouse(copy._mouse),
|
||||
_flags(copy._flags)
|
||||
|
|
@ -49,6 +50,7 @@ MouseWatcherParameter(const MouseWatcherParameter ©) :
|
|||
INLINE void MouseWatcherParameter::
|
||||
operator = (const MouseWatcherParameter ©) {
|
||||
_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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 &) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ public:
|
|||
virtual void without(const MouseWatcherParameter ¶m);
|
||||
virtual void press(const MouseWatcherParameter ¶m);
|
||||
virtual void release(const MouseWatcherParameter ¶m);
|
||||
virtual void keystroke(const MouseWatcherParameter ¶m);
|
||||
|
||||
private:
|
||||
LVecBase4f _frame;
|
||||
|
|
|
|||
Loading…
Reference in New Issue