*** empty log message ***

This commit is contained in:
David Rose 2001-01-09 00:26:00 +00:00
parent aa00622e56
commit 7a110a31cd
4 changed files with 209 additions and 30 deletions

View File

@ -15,7 +15,7 @@
INLINE void ChatInput:: INLINE void ChatInput::
set_max_chars(int max_chars) { set_max_chars(int max_chars) {
_max_chars = max_chars; _max_chars = max_chars;
_has_max_chars = true; _flags |= F_max_chars;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -26,7 +26,7 @@ set_max_chars(int max_chars) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void ChatInput:: INLINE void ChatInput::
clear_max_chars() { clear_max_chars() {
_has_max_chars = false; _flags &= ~F_max_chars;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -37,7 +37,7 @@ clear_max_chars() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE bool ChatInput:: INLINE bool ChatInput::
has_max_chars() const { has_max_chars() const {
return _has_max_chars; return (_flags & F_max_chars) != 0;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -52,6 +52,111 @@ get_max_chars() const {
return _max_chars; return _max_chars;
} }
////////////////////////////////////////////////////////////////////
// Function: ChatInput::set_max_lines
// Access: Public
// Description: Sets a limit on the number of lines the user is
// allowed to type. This makes sense only when wordwrap
// is enabled on the TextNode; otherwise, it will always
// be only one line. When this limit is exceeded, no
// more characters will be accepted, and the event
// "chat_overflow" is thrown.
////////////////////////////////////////////////////////////////////
INLINE void ChatInput::
set_max_lines(int max_lines) {
_max_lines = max_lines;
_flags |= F_max_lines;
}
////////////////////////////////////////////////////////////////////
// Function: ChatInput::clear_max_lines
// Access: Public
// Description: Removes the limit on the maximum number of
// characters.
////////////////////////////////////////////////////////////////////
INLINE void ChatInput::
clear_max_lines() {
_flags &= ~F_max_lines;
}
////////////////////////////////////////////////////////////////////
// Function: ChatInput::has_max_lines
// Access: Public
// Description: Returns true if the maximum number of characters has
// been set by a call to set_max_lines().
////////////////////////////////////////////////////////////////////
INLINE bool ChatInput::
has_max_lines() const {
return (_flags & F_max_lines) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: ChatInput::get_max_lines
// Access: Public
// Description: If has_max_lines() returns true, this will return the
// maximum number of characters that was set.
////////////////////////////////////////////////////////////////////
INLINE int ChatInput::
get_max_lines() const {
nassertr(has_max_lines(), 0);
return _max_lines;
}
////////////////////////////////////////////////////////////////////
// Function: ChatInput::set_max_width
// Access: Public
// Description: Sets a limit on the total width of the line the user
// is allowed to type. When this limit is exceeded, no
// more characters will be accepted, and the event
// "chat_overflow" is thrown.
//
// This is different than set_max_chars(), as some
// letters use more width than others; capital W, for
// instance, takes up more space than a lowercase i. It
// only makes sense to set this option when wordwrap is
// *off* for the TextNode. To limit the text length
// with wordwrap on, use set_max_lines().
////////////////////////////////////////////////////////////////////
INLINE void ChatInput::
set_max_width(float max_width) {
_max_width = max_width;
_flags |= F_max_width;
}
////////////////////////////////////////////////////////////////////
// Function: ChatInput::clear_max_width
// Access: Public
// Description: Removes the limit on the maximum number of
// characters.
////////////////////////////////////////////////////////////////////
INLINE void ChatInput::
clear_max_width() {
_flags &= ~F_max_width;
}
////////////////////////////////////////////////////////////////////
// Function: ChatInput::has_max_width
// Access: Public
// Description: Returns true if the maximum number of characters has
// been set by a call to set_max_width().
////////////////////////////////////////////////////////////////////
INLINE bool ChatInput::
has_max_width() const {
return (_flags & F_max_width) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: ChatInput::get_max_width
// Access: Public
// Description: If has_max_width() returns true, this will return the
// maximum number of characters that was set.
////////////////////////////////////////////////////////////////////
INLINE float ChatInput::
get_max_width() const {
nassertr(has_max_width(), 0.0);
return _max_width;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: ChatInput::get_string // Function: ChatInput::get_string
// Access: Public // Access: Public

View File

@ -26,12 +26,14 @@ TypeHandle ChatInput::_button_events_type;
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
ChatInput::ChatInput(TextNode* text_node, ChatInput::
const string& name) : DataNode(name) { ChatInput(TextNode* text_node, const string& name) : DataNode(name) {
assert(text_node != NULL); assert(text_node != NULL);
_text_node = text_node; _text_node = text_node;
_max_chars = 0; _max_chars = 0;
_has_max_chars = false; _max_lines = 0;
_max_width = 0.0;
_flags = 0;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -51,9 +53,8 @@ reset() {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void ChatInput::transmit_data(NodeAttributes &data) { void ChatInput::
bool changed = false; transmit_data(NodeAttributes &data) {
// Look for keyboard events. // Look for keyboard events.
const ButtonEventDataAttribute *b; const ButtonEventDataAttribute *b;
if (get_attribute_into(b, data, _button_events_type)) { if (get_attribute_into(b, data, _button_events_type)) {
@ -66,28 +67,23 @@ void ChatInput::transmit_data(NodeAttributes &data) {
throw_event("chat_exit"); throw_event("chat_exit");
} else if (be._button == KeyboardButton::backspace()) { } else if (be._button == KeyboardButton::backspace()) {
_str = _str.substr(0, _str.length()-1); if (!_str.empty()) {
changed = true; _str = _str.substr(0, _str.length()-1);
_text_node->set_text(_str);
}
} else if (be._button.has_ascii_equivalent()) { } else if (be._button.has_ascii_equivalent()) {
char ch = be._button.get_ascii_equivalent(); char ch = be._button.get_ascii_equivalent();
if (isprint(ch)) { if (isprint(ch)) {
if (has_max_chars() && (int)_str.size() >= get_max_chars()) { if (!append_character(ch)) {
throw_event("chat_overflow"); throw_event("chat_overflow");
} else {
_str += ch;
changed = true;
} }
} }
} }
} }
} }
} }
if (changed) {
_text_node->set_text(_str);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -95,7 +91,8 @@ void ChatInput::transmit_data(NodeAttributes &data) {
// Access: // Access:
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void ChatInput::init_type(void) { void ChatInput::
init_type(void) {
DataNode::init_type(); DataNode::init_type();
register_type(_type_handle, "ChatInput", register_type(_type_handle, "ChatInput",
DataNode::get_class_type()); DataNode::get_class_type());
@ -107,10 +104,68 @@ void ChatInput::init_type(void) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: append // Function: append
// Access: // Access: Public
// Description: // Description: Appends the indicated string to the end of the
// currently typed string, as if it were typed by the
// user. No bounds checking is performed.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void ChatInput::append(const string &str) { void ChatInput::
append(const string &str) {
_str += str; _str += str;
_text_node->set_text(_str); _text_node->set_text(_str);
} }
////////////////////////////////////////////////////////////////////
// Function: append_character
// Access: Public
// Description: Adds the indicated character to the end of the
// string, as if it were typed. Bounds checking is
// performed; the character must fit within the limits
// set by set_max_chars(), set_max_width(), and
// set_max_lines(). Returns true if the character fit
// (and was appended correctly), or false if it did not
// fit (in which case nothing is changed).
////////////////////////////////////////////////////////////////////
bool ChatInput::
append_character(char ch) {
if (has_max_chars() && (int)_str.size() >= get_max_chars()) {
// This is an easy test.
return false;
}
string text = _str + ch;
if (_text_node->has_wordwrap()) {
text =
_text_node->wordwrap_to(text, _text_node->get_wordwrap());
}
if (has_max_width()) {
nassertr(!_text_node->has_wordwrap(), false);
float width = _text_node->calc_width(text);
if (width > get_max_width()) {
return false;
}
}
if (has_max_lines()) {
// Count up the number of lines in the text. This is one more
// than the number of newline characters.
int num_lines = 1;
string::const_iterator pi;
for (pi = text.begin(); pi != text.end(); ++pi) {
if (*pi == '\n') {
++num_lines;
}
}
if (num_lines > get_max_lines()) {
return false;
}
}
_str += ch;
_text_node->set_text(_str);
return true;
}

View File

@ -34,6 +34,16 @@ PUBLISHED:
INLINE bool has_max_chars() const; INLINE bool has_max_chars() const;
INLINE int get_max_chars() const; INLINE int get_max_chars() const;
INLINE void set_max_lines(int max_lines);
INLINE void clear_max_lines();
INLINE bool has_max_lines() const;
INLINE int get_max_lines() const;
INLINE void set_max_width(float max_width);
INLINE void clear_max_width();
INLINE bool has_max_width() const;
INLINE float get_max_width() const;
INLINE const string &get_string() const; INLINE const string &get_string() const;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -44,6 +54,7 @@ public:
transmit_data(NodeAttributes &data); transmit_data(NodeAttributes &data);
void append(const string &str); void append(const string &str);
bool append_character(char ch);
NodeAttributes _attrib; NodeAttributes _attrib;
@ -51,10 +62,18 @@ public:
static TypeHandle _button_events_type; static TypeHandle _button_events_type;
protected: protected:
PT(TextNode) _text_node; PT(TextNode) _text_node;
string _str; string _str;
int _max_chars; int _max_chars;
bool _has_max_chars; int _max_lines;
float _max_width;
enum Flags {
F_max_chars = 0x001,
F_max_lines = 0x002,
F_max_width = 0x004,
};
int _flags;
public: public:
virtual TypeHandle get_type() const { virtual TypeHandle get_type() const {

View File

@ -172,7 +172,7 @@ wordwrap_to(const string &text, float wordwrap_width) const {
float width = 0.0; float width = 0.0;
while (q < text.length() && text[q] != '\n' && width <= wordwrap_width) { while (q < text.length() && text[q] != '\n' && width <= wordwrap_width) {
if (isspace(text[q])) { if (isspace(text[q])) {
any_spaces = true; any_spaces = true;
} }
width += calc_width(text[q]); width += calc_width(text[q]);
@ -184,7 +184,7 @@ wordwrap_to(const string &text, float wordwrap_width) const {
// back up to the end of the last complete word. // back up to the end of the last complete word.
while (q > p && !isspace(text[q])) { while (q > p && !isspace(text[q])) {
q--; q--;
} }
} }
@ -205,7 +205,7 @@ wordwrap_to(const string &text, float wordwrap_width) const {
q++; q++;
next_start++; next_start++;
while (next_start < text.length() && isblank(text[next_start])) { while (next_start < text.length() && isblank(text[next_start])) {
next_start++; next_start++;
} }
} }