|
@@ -26,12 +26,14 @@ TypeHandle ChatInput::_button_events_type;
|
|
|
// Access: Public
|
|
// Access: Public
|
|
|
// Description:
|
|
// Description:
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-ChatInput::ChatInput(TextNode* text_node,
|
|
|
|
|
- const string& name) : DataNode(name) {
|
|
|
|
|
|
|
+ChatInput::
|
|
|
|
|
+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) {
|
|
|
|
|
- bool changed = false;
|
|
|
|
|
-
|
|
|
|
|
|
|
+void ChatInput::
|
|
|
|
|
+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);
|
|
|
|
|
- changed = true;
|
|
|
|
|
|
|
+ if (!_str.empty()) {
|
|
|
|
|
+ _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:
|
|
|
|
|
-// Description:
|
|
|
|
|
|
|
+// Access: Public
|
|
|
|
|
+// 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;
|
|
|
|
|
+}
|