From cb9e5f2dada6a49686a4fc66d6e53dfe1899de2b Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 13 Jan 2006 00:21:17 +0000 Subject: [PATCH] add generic ButtonThrower events: track keystrokes, too --- panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 5 +- panda/src/event/config_event.cxx | 1 + panda/src/event/eventParameter.I | 35 +++++ panda/src/event/eventParameter.h | 5 + panda/src/express/datagram.I | 5 + panda/src/express/datagram.cxx | 17 +++ panda/src/express/datagram.h | 3 + panda/src/express/datagramIterator.I | 5 + panda/src/express/datagramIterator.cxx | 24 +++ panda/src/express/datagramIterator.h | 3 + panda/src/tform/buttonThrower.I | 195 +++++++++++++++++++++++-- panda/src/tform/buttonThrower.cxx | 95 +++++++++++- panda/src/tform/buttonThrower.h | 30 +++- 13 files changed, 394 insertions(+), 29 deletions(-) diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 2231fb3786..049803d771 100755 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -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; } + */ } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/event/config_event.cxx b/panda/src/event/config_event.cxx index a6c9d3f0a2..fcc4804d3b 100644 --- a/panda/src/event/config_event.cxx +++ b/panda/src/event/config_event.cxx @@ -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(); diff --git a/panda/src/event/eventParameter.I b/panda/src/event/eventParameter.I index 2d833e8de4..3b2ee70bcf 100644 --- a/panda/src/event/eventParameter.I +++ b/panda/src/event/eventParameter.I @@ -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 diff --git a/panda/src/event/eventParameter.h b/panda/src/event/eventParameter.h index f17a41e104..d92b3e8fbe 100644 --- a/panda/src/event/eventParameter.h +++ b/panda/src/event/eventParameter.h @@ -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 ©); INLINE EventParameter &operator = (const EventParameter ©); @@ -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); EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue); EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue); +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, EventStoreValue); typedef EventStoreValue EventStoreInt; typedef EventStoreValue EventStoreDouble; typedef EventStoreValue EventStoreString; +typedef EventStoreValue EventStoreWstring; #include "eventParameter.I" diff --git a/panda/src/express/datagram.I b/panda/src/express/datagram.I index 89bd584beb..7cfc6e6483 100644 --- a/panda/src/express/datagram.I +++ b/panda/src/express/datagram.I @@ -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); +} diff --git a/panda/src/express/datagram.cxx b/panda/src/express/datagram.cxx index 663e8b5b41..b5fb570ba5 100644 --- a/panda/src/express/datagram.cxx +++ b/panda/src/express/datagram.cxx @@ -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 diff --git a/panda/src/express/datagram.h b/panda/src/express/datagram.h index 3ae866afa7..96fd898a00 100644 --- a/panda/src/express/datagram.h +++ b/panda/src/express/datagram.h @@ -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" diff --git a/panda/src/express/datagramIterator.I b/panda/src/express/datagramIterator.I index 63bf56d1f0..e2ff00f81a 100644 --- a/panda/src/express/datagramIterator.I +++ b/panda/src/express/datagramIterator.I @@ -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(); +} + diff --git a/panda/src/express/datagramIterator.cxx b/panda/src/express/datagramIterator.cxx index 741a0515e3..ab1fe3e7e8 100644 --- a/panda/src/express/datagramIterator.cxx +++ b/panda/src/express/datagramIterator.cxx @@ -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 diff --git a/panda/src/express/datagramIterator.h b/panda/src/express/datagramIterator.h index eb19dfd653..b2aabf5ca0 100644 --- a/panda/src/express/datagramIterator.h +++ b/panda/src/express/datagramIterator.h @@ -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" diff --git a/panda/src/tform/buttonThrower.I b/panda/src/tform/buttonThrower.I index ee373ff9ba..39d36c2270 100644 --- a/panda/src/tform/buttonThrower.I +++ b/panda/src/tform/buttonThrower.I @@ -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 diff --git a/panda/src/tform/buttonThrower.cxx b/panda/src/tform/buttonThrower.cxx index bafa79883d..624b3e7900 100644 --- a/panda/src/tform/buttonThrower.cxx +++ b/panda/src/tform/buttonThrower.cxx @@ -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, ""); } } } diff --git a/panda/src/tform/buttonThrower.h b/panda/src/tform/buttonThrower.h index bced313a94..186536af18 100644 --- a/panda/src/tform/buttonThrower.h +++ b/panda/src/tform/buttonThrower.h @@ -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 ParameterList; ParameterList _parameters;