add generic ButtonThrower events: track keystrokes, too

This commit is contained in:
David Rose 2006-01-13 00:21:17 +00:00
parent 8c5504212e
commit cb9e5f2dad
13 changed files with 394 additions and 29 deletions

View File

@ -107,12 +107,13 @@ PT(GraphicsBuffer) wdxGraphicsPipe9::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size) {
if (support_render_texture && gsg->get_supports_render_texture ( )) {
// if (support_render_texture && gsg->get_supports_render_texture ( )) {
return new wdxGraphicsBuffer9(this, gsg, name, x_size, y_size);
}
/* }
else {
return NULL;
}
*/
}
////////////////////////////////////////////////////////////////////

View File

@ -35,6 +35,7 @@ ConfigureFn(config_event) {
EventStoreInt::init_type("EventStoreInt");
EventStoreDouble::init_type("EventStoreDouble");
EventStoreString::init_type("EventStoreString");
EventStoreWstring::init_type("EventStoreWstring");
ButtonEventList::register_with_read_factory();
EventStoreInt::register_with_read_factory();

View File

@ -76,6 +76,14 @@ EventParameter(double value) : _ptr(new EventStoreDouble(value)) { }
INLINE EventParameter::
EventParameter(const string &value) : _ptr(new EventStoreString(value)) { }
////////////////////////////////////////////////////////////////////
// Function: EventParameter::Wstring constructor
// Access: Public
// Description: Defines an EventParameter that stores a wstring value.
////////////////////////////////////////////////////////////////////
INLINE EventParameter::
EventParameter(const wstring &value) : _ptr(new EventStoreWstring(value)) { }
////////////////////////////////////////////////////////////////////
// Function: EventParameter::Copy constructor
@ -192,6 +200,33 @@ get_string_value() const {
return ((const EventStoreString *)_ptr.p())->get_value();
}
////////////////////////////////////////////////////////////////////
// Function: EventParameter::is_wstring
// Access: Public
// Description: Returns true if the EventParameter stores a wstring
// value, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool EventParameter::
is_wstring() const {
if (is_empty()) {
return false;
}
return _ptr->is_of_type(EventStoreWstring::get_class_type());
}
////////////////////////////////////////////////////////////////////
// Function: EventParameter::get_wstring_value
// Access: Public
// Description: Retrieves the value stored in the EventParameter. It
// is only valid to call this if is_wstring() has already
// returned true.
////////////////////////////////////////////////////////////////////
INLINE wstring EventParameter::
get_wstring_value() const {
nassertr(is_wstring(), wstring());
return ((const EventStoreWstring *)_ptr.p())->get_value();
}
////////////////////////////////////////////////////////////////////
// Function: EventParameter::get_ptr
// Access: Public

View File

@ -46,6 +46,7 @@ PUBLISHED:
INLINE EventParameter(int value);
INLINE EventParameter(double value);
INLINE EventParameter(const string &value);
INLINE EventParameter(const wstring &value);
INLINE EventParameter(const EventParameter &copy);
INLINE EventParameter &operator = (const EventParameter &copy);
@ -62,6 +63,8 @@ PUBLISHED:
INLINE double get_double_value() const;
INLINE bool is_string() const;
INLINE string get_string_value() const;
INLINE bool is_wstring() const;
INLINE wstring get_wstring_value() const;
INLINE TypedWritableReferenceCount *get_ptr() const;
@ -160,10 +163,12 @@ private:
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue<int>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue<double>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue<std::string>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue<std::wstring>);
typedef EventStoreValue<int> EventStoreInt;
typedef EventStoreValue<double> EventStoreDouble;
typedef EventStoreValue<string> EventStoreString;
typedef EventStoreValue<wstring> EventStoreWstring;
#include "eventParameter.I"

View File

@ -481,3 +481,8 @@ INLINE void
generic_write_datagram(Datagram &dest, const string &value) {
dest.add_string(value);
}
INLINE void
generic_write_datagram(Datagram &dest, const wstring &value) {
dest.add_wstring(value);
}

View File

@ -84,6 +84,23 @@ dump_hex(ostream &out) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: Datagram::add_wstring
// Access: Public
// Description: Adds a variable-length wstring to the datagram.
////////////////////////////////////////////////////////////////////
void Datagram::
add_wstring(const wstring &str) {
// By convention, wstrings are marked with 32-bit lengths.
add_uint32(str.length());
// Now append each character in the string. We store each code
// little-endian, for no real good reason.
wstring::const_iterator ci;
for (ci = str.begin(); ci != str.end(); ++ci) {
add_uint16(*ci);
}
}
////////////////////////////////////////////////////////////////////
// Function: Datagram::pad_bytes

View File

@ -85,6 +85,7 @@ PUBLISHED:
INLINE void add_string32(const string &str);
INLINE void add_z_string(string str);
INLINE void add_fixed_string(const string &str, size_t size);
void add_wstring(const wstring &str);
void pad_bytes(size_t size);
void append_data(const void *data, size_t size);
@ -138,6 +139,8 @@ INLINE void
generic_write_datagram(Datagram &dest, double value);
INLINE void
generic_write_datagram(Datagram &dest, const string &value);
INLINE void
generic_write_datagram(Datagram &dest, const wstring &value);
#include "datagram.I"

View File

@ -556,4 +556,9 @@ generic_read_datagram(string &result, DatagramIterator &source) {
result = source.get_string();
}
INLINE void
generic_read_datagram(wstring &result, DatagramIterator &source) {
result = source.get_wstring();
}

View File

@ -109,6 +109,30 @@ get_fixed_string(size_t size) {
return s.substr(0, zero_byte);
}
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::get_wstring
// Access: Public
// Description: Extracts a variable-length wstring (with a 32-bit
// length field).
////////////////////////////////////////////////////////////////////
wstring DatagramIterator::
get_wstring() {
// First, get the length of the string
PN_uint32 s_len = get_uint32();
nassertr(_datagram != (const Datagram *)NULL, wstring());
nassertr(_current_index + s_len * 2 <= _datagram->get_length(), wstring());
wstring result;
result.reserve(s_len);
while (s_len > 0) {
result += wchar_t(get_uint16());
--s_len;
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::extract_bytes
// Access: Public

View File

@ -65,6 +65,7 @@ PUBLISHED:
string get_string32();
string get_z_string();
string get_fixed_string(size_t size);
wstring get_wstring();
INLINE void skip_bytes(size_t size);
string extract_bytes(size_t size);
@ -98,6 +99,8 @@ INLINE void
generic_read_datagram(double &result, DatagramIterator &source);
INLINE void
generic_read_datagram(string &result, DatagramIterator &source);
INLINE void
generic_read_datagram(wstring &result, DatagramIterator &source);
#include "datagramIterator.I"

View File

@ -17,39 +17,206 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_button_down_event
// Access: Published
// Description: Specifies the generic event that is generated (if
// any) each time a key or button is depressed. Unlike
// the specific events that are unique to each key, this
// same event name is used for *all* button events, and
// the name of the button pressed (possibly with
// modifier prefixes) will be sent as a parameter.
//
// If this string is empty, no event is generated. It
// is possible to generate both generic events and
// specific events for the same button.
//
// See also set_keystroke_event().
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_button_down_event(const string &button_down_event) {
_button_down_event = button_down_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_button_down_event
// Access: Published
// Description: Returns the button_down_event that has been set on
// this ButtonThrower. See set_button_down_event().
////////////////////////////////////////////////////////////////////
INLINE const string &ButtonThrower::
get_button_down_event() const {
return _button_down_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_button_up_event
// Access: Published
// Description: Specifies the generic event that is generated (if
// any) each time a key or button is released. See
// set_button_down_event().
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_button_up_event(const string &button_up_event) {
_button_up_event = button_up_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_button_up_event
// Access: Published
// Description: Returns the button_up_event that has been set on
// this ButtonThrower. See set_button_up_event().
////////////////////////////////////////////////////////////////////
INLINE const string &ButtonThrower::
get_button_up_event() const {
return _button_up_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_keystroke_event
// Access: Published
// Description: Specifies the event that is generated (if any) for
// each keystroke that is received. A keystroke is
// different than a button event: it represents the
// semantic meaning of the sequence of keys that have
// been pressed. For instance, pressing shift and 4
// together will generate the button event "shift-4",
// but it will generate the keystroke "$".
//
// This event is generated with a single wstring
// parameter, which is a one-character string that
// contains the keystroke generated. If this event
// string is empty, no event is generated.
//
// See also set_button_down_event().
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_keystroke_event(const string &keystroke_event) {
_keystroke_event = keystroke_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_keystroke_event
// Access: Published
// Description: Returns the keystroke_event that has been set on this
// ButtonThrower. See set_keystroke_event().
////////////////////////////////////////////////////////////////////
INLINE const string &ButtonThrower::
get_keystroke_event() const {
return _keystroke_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_candidate_event
// Access: Published
// Description: Specifies the event that is generated (if any) for
// each IME candidate string event received. Events of
// this nature are received only when the user is
// entering data using a Microsoft Input Method Editor,
// typically used for Asian languages such as Japanese
// or Korean.
//
// If you are designing a typing user interface, you
// should track this event to support the use of the
// IME. In response to this event, you should display
// the candidate string in the entry box, with the
// appropriate sections highlighted, so the user can
// scroll through the available choices.
//
// This event is generated with four parameters, in
// order: the candidate string, the character at which
// to start the highlight, the character at which to end
// the highlight, and the current cursor position.
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_candidate_event(const string &candidate_event) {
_candidate_event = candidate_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_candidate_event
// Access: Published
// Description: Returns the candidate_event that has been set on this
// ButtonThrower. See set_candidate_event().
////////////////////////////////////////////////////////////////////
INLINE const string &ButtonThrower::
get_candidate_event() const {
return _candidate_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_move_event
// Access: Published
// Description: Specifies the event that is generated (if any) each
// time the mouse is moved within the window.
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_move_event(const string &move_event) {
_move_event = move_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_move_event
// Access: Published
// Description: Returns the move_event that has been set on this
// ButtonThrower. See set_move_event().
////////////////////////////////////////////////////////////////////
INLINE const string &ButtonThrower::
get_move_event() const {
return _move_event;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_prefix
// Access: Published
// Description: Sets the prefix which is prepended to all event names
// thrown by this object.
// Description: Sets the prefix which is prepended to all specific
// event names (that is, event names generated from the
// button name itself, as opposed to the generic event
// names like set_button_down_event) thrown by this
// object.
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_prefix(const string &prefix) {
_prefix = prefix;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::has_prefix
// Access: Published
// Description: Returns true if the ButtonThrower has a prefix set,
// false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool ButtonThrower::
has_prefix() const {
return !_prefix.empty();
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_prefix
// Access: Published
// Description: Returns the prefix that has been set on this
// ButtonThrower. See set_prefix().
////////////////////////////////////////////////////////////////////
INLINE string ButtonThrower::
INLINE const string &ButtonThrower::
get_prefix() const {
return _prefix;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_specific_flag
// Access: Published
// Description: Sets the flag that indicates whether specific events
// (events prefixed by set_prefix, and based on the
// event name) should be generated at all. This is true
// by default, but may be disabled if you are only
// interested in the generic events (for instance,
// events like set_button_down_event).
////////////////////////////////////////////////////////////////////
INLINE void ButtonThrower::
set_specific_flag(bool specific_flag) {
_specific_flag = specific_flag;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::get_specific_flag
// Access: Published
// Description: Returns the flag that indicates whether specific
// events should be generated. See set_specific_flag().
////////////////////////////////////////////////////////////////////
INLINE bool ButtonThrower::
get_specific_flag() const {
return _specific_flag;
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::set_time_flag
// Access: Published

View File

@ -43,6 +43,7 @@ ButtonThrower(const string &name) :
_button_events = new ButtonEventList;
_specific_flag = true;
_time_flag = false;
_throw_buttons_active = false;
}
@ -247,7 +248,7 @@ write(ostream &out, int indent_level) const {
if (_throw_buttons_active) {
indent(out, indent_level)
<< "Processing keys:\n";
// Write the list of buttons that we're processing too.
// Write the list of buttons that we're processing.
ThrowButtons::const_iterator ti;
for (ti = _throw_buttons.begin(); ti != _throw_buttons.end(); ++ti) {
ButtonHandle button = (*ti).first;
@ -258,21 +259,96 @@ write(ostream &out, int indent_level) const {
<< (*di).get_prefix() << button.get_name() << "\n";
}
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::do_throw_event
// Function: ButtonThrower::do_specific_event
// Access: Private
// Description: Generates an event of the indicated name, adding on
// all of the user-requested parameters.
////////////////////////////////////////////////////////////////////
void ButtonThrower::
do_throw_event(const string &event_name, double time) {
Event *event = new Event(_prefix + event_name);
do_specific_event(const string &event_name, double time) {
if (_specific_flag) {
PT(Event) event = new Event(_prefix + event_name);
if (_time_flag) {
event->add_parameter(time);
}
ParameterList::const_iterator pi;
for (pi = _parameters.begin(); pi != _parameters.end(); ++pi) {
event->add_parameter(*pi);
}
throw_event(event);
}
}
////////////////////////////////////////////////////////////////////
// Function: ButtonThrower::do_general_event
// Access: Private
// Description: Generates an appropriate general event, if one is
// configured.
////////////////////////////////////////////////////////////////////
void ButtonThrower::
do_general_event(const ButtonEvent &button_event, const string &button_name) {
string event_name;
switch (button_event._type) {
case ButtonEvent::T_down:
event_name = _button_down_event;
break;
case ButtonEvent::T_resume_down:
break;
case ButtonEvent::T_up:
event_name = _button_up_event;
break;
case ButtonEvent::T_keystroke:
event_name = _keystroke_event;
break;
case ButtonEvent::T_candidate:
event_name = _candidate_event;
break;
case ButtonEvent::T_move:
event_name = _move_event;
break;
}
if (event_name.empty()) {
// This general event is not configured.
return;
}
PT(Event) event = new Event(event_name);
if (_time_flag) {
event->add_parameter(time);
event->add_parameter(button_event._time);
}
// Now add the appropriate parameters.
switch (button_event._type) {
case ButtonEvent::T_down:
case ButtonEvent::T_resume_down:
case ButtonEvent::T_up:
event->add_parameter(button_name);
break;
case ButtonEvent::T_keystroke:
event->add_parameter(wstring(1, button_event._keycode));
break;
case ButtonEvent::T_candidate:
event->add_parameter(button_event._candidate_string);
break;
case ButtonEvent::T_move:
event_name = _move_event;
break;
}
ParameterList::const_iterator pi;
@ -321,7 +397,8 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
if (!_throw_buttons_active || has_throw_button(_mods, be._button)) {
// Process this button.
do_throw_event(event_name, be._time);
do_specific_event(event_name, be._time);
do_general_event(be, event_name);
} else {
// Don't process this button; instead, pass it down to future
@ -344,7 +421,8 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
// definition for the button at all, regardless of the state
// of the modifier keys.
if (!_throw_buttons_active || has_throw_button(be._button)) {
do_throw_event(event_name + "-up", be._time);
do_specific_event(event_name + "-up", be._time);
do_general_event(be, event_name);
}
if (_throw_buttons_active) {
// Now pass the event on to future generations. We always
@ -358,6 +436,7 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
// Some other kind of button event (e.g. keypress). Don't
// throw an event for this, but do pass it down.
_button_events->add_event(be);
do_general_event(be, "");
}
}
}

View File

@ -45,12 +45,25 @@ PUBLISHED:
ButtonThrower(const string &name);
~ButtonThrower();
INLINE void set_button_down_event(const string &button_down_event);
INLINE const string &get_button_down_event() const;
INLINE void set_button_up_event(const string &button_up_event);
INLINE const string &get_button_up_event() const;
INLINE void set_keystroke_event(const string &keystroke_event);
INLINE const string &get_keystroke_event() const;
INLINE void set_candidate_event(const string &candidate_event);
INLINE const string &get_candidate_event() const;
INLINE void set_move_event(const string &move_event);
INLINE const string &get_move_event() const;
INLINE void set_prefix(const string &prefix);
INLINE bool has_prefix() const;
INLINE string get_prefix() const;
INLINE const string &get_prefix() const;
INLINE void set_specific_flag(bool specific_flag);
INLINE bool get_specific_flag() const;
INLINE void set_time_flag(bool time_flag);
INLINE bool get_time_flag() const;
void add_parameter(const EventParameter &obj);
int get_num_parameters() const;
@ -72,13 +85,20 @@ public:
virtual void write(ostream &out, int indent_level = 0) const;
private:
void do_throw_event(const string &event_name, double time);
void do_specific_event(const string &event_name, double time);
void do_general_event(const ButtonEvent &button_event,
const string &event_name);
private:
string _button_down_event;
string _button_up_event;
string _keystroke_event;
string _candidate_event;
string _move_event;
bool _specific_flag;
string _prefix;
ModifierButtons _mods;
bool _time_flag;
ModifierButtons _mods;
typedef pvector<EventParameter> ParameterList;
ParameterList _parameters;