PGEntry should use wstring internally

This commit is contained in:
David Rose 2002-02-16 19:37:06 +00:00
parent 79c241b0d9
commit 64ddb25aed
7 changed files with 208 additions and 103 deletions

View File

@ -21,25 +21,30 @@
// Function: PGEntry::set_text // Function: PGEntry::set_text
// Access: Published // Access: Published
// Description: Changes the text currently displayed within the // Description: Changes the text currently displayed within the
// entry. // entry. This uses the Unicode encoding currently
// specified for the "focus" TextNode; therefore, the
// TextNode must exist before calling set_text().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void PGEntry:: INLINE void PGEntry::
set_text(const string &text) { set_text(const string &text) {
_text = text; TextNode *text_node = get_text_def(S_focus);
_text_geom_stale = true; nassertv(text_node != (TextNode *)NULL);
_cursor_stale = true; set_wtext(text_node->decode_text(text));
_blink_start = ClockObject::get_global_clock()->get_frame_time();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PGEntry::get_text // Function: PGEntry::get_text
// Access: Published // Access: Published
// Description: Returns the text currently displayed within the // Description: Returns the text currently displayed within the
// entry. // entry. This uses the Unicode encoding currently
// specified for the "focus" TextNode; therefore, the
// TextNode must exist before calling get_text().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE const string &PGEntry:: INLINE string PGEntry::
get_text() const { get_text() const {
return _text; TextNode *text_node = get_text_def(S_focus);
nassertr(text_node != (TextNode *)NULL, string());
return text_node->encode_wtext(get_wtext());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -352,3 +357,28 @@ INLINE string PGEntry::
get_erase_event() const { get_erase_event() const {
return "erase-" + get_id(); return "erase-" + get_id();
} }
////////////////////////////////////////////////////////////////////
// Function: PGEntry::set_wtext
// Access: Public
// Description: Changes the text currently displayed within the
// entry.
////////////////////////////////////////////////////////////////////
INLINE void PGEntry::
set_wtext(const wstring &wtext) {
_wtext = wtext;
_text_geom_stale = true;
_cursor_stale = true;
_blink_start = ClockObject::get_global_clock()->get_frame_time();
}
////////////////////////////////////////////////////////////////////
// Function: PGEntry::get_wtext
// Access: Public
// Description: Returns the text currently displayed within the
// entry.
////////////////////////////////////////////////////////////////////
INLINE const wstring &PGEntry::
get_wtext() const {
return _wtext;
}

View File

@ -82,8 +82,8 @@ PGEntry::
PGEntry:: PGEntry::
PGEntry(const PGEntry &copy) : PGEntry(const PGEntry &copy) :
PGItem(copy), PGItem(copy),
_text(copy._text), _wtext(copy._wtext),
_obscured_text(copy._obscured_text), _obscured_wtext(copy._obscured_wtext),
_cursor_position(copy._cursor_position), _cursor_position(copy._cursor_position),
_max_chars(copy._max_chars), _max_chars(copy._max_chars),
_max_width(copy._max_width), _max_width(copy._max_width),
@ -106,8 +106,8 @@ PGEntry(const PGEntry &copy) :
void PGEntry:: void PGEntry::
operator = (const PGEntry &copy) { operator = (const PGEntry &copy) {
PGItem::operator = (copy); PGItem::operator = (copy);
_text = copy._text; _wtext = copy._wtext;
_obscured_text = copy._obscured_text; _obscured_wtext = copy._obscured_wtext;
_cursor_position = copy._cursor_position; _cursor_position = copy._cursor_position;
_max_chars = copy._max_chars; _max_chars = copy._max_chars;
_max_width = copy._max_width; _max_width = copy._max_width;
@ -179,7 +179,7 @@ press(const MouseWatcherParameter &param, bool background) {
} else if ((!background && get_focus()) || } else if ((!background && get_focus()) ||
(background && get_background_focus())) { (background && get_background_focus())) {
// Keyboard button. // Keyboard button.
_cursor_position = min(_cursor_position, (int)_text.length()); _cursor_position = min(_cursor_position, (int)_wtext.length());
_blink_start = ClockObject::get_global_clock()->get_frame_time(); _blink_start = ClockObject::get_global_clock()->get_frame_time();
if (button == KeyboardButton::enter()) { if (button == KeyboardButton::enter()) {
// Enter. Accept the entry. // Enter. Accept the entry.
@ -188,10 +188,10 @@ press(const MouseWatcherParameter &param, bool background) {
} else if (button == KeyboardButton::backspace()) { } else if (button == KeyboardButton::backspace()) {
// Backspace. Remove the character to the left of the cursor. // Backspace. Remove the character to the left of the cursor.
if (_cursor_position > 0) { if (_cursor_position > 0) {
if (_obscure_mode && _obscured_text.length() == _text.length()) { if (_obscure_mode && _obscured_wtext.length() == _wtext.length()) {
_obscured_text.erase(_obscured_text.begin() + _obscured_text.length() - 1); _obscured_wtext.erase(_obscured_wtext.begin() + _obscured_wtext.length() - 1);
} }
_text.erase(_text.begin() + _cursor_position - 1); _wtext.erase(_wtext.begin() + _cursor_position - 1);
_cursor_position--; _cursor_position--;
_cursor_stale = true; _cursor_stale = true;
_text_geom_stale = true; _text_geom_stale = true;
@ -200,11 +200,11 @@ press(const MouseWatcherParameter &param, bool background) {
} else if (button == KeyboardButton::del()) { } else if (button == KeyboardButton::del()) {
// Delete. Remove the character to the right of the cursor. // Delete. Remove the character to the right of the cursor.
if (_cursor_position < (int)_text.length()) { if (_cursor_position < (int)_wtext.length()) {
if (_obscure_mode && _obscured_text.length() == _text.length()) { if (_obscure_mode && _obscured_wtext.length() == _wtext.length()) {
_obscured_text.erase(_obscured_text.begin() + _obscured_text.length() - 1); _obscured_wtext.erase(_obscured_wtext.begin() + _obscured_wtext.length() - 1);
} }
_text.erase(_text.begin() + _cursor_position); _wtext.erase(_wtext.begin() + _cursor_position);
_text_geom_stale = true; _text_geom_stale = true;
erase(param); erase(param);
} }
@ -219,7 +219,7 @@ press(const MouseWatcherParameter &param, bool background) {
} else if (button == KeyboardButton::right()) { } else if (button == KeyboardButton::right()) {
if (_cursor_keys_active) { if (_cursor_keys_active) {
// Right arrow. Move the cursor position to the right. // Right arrow. Move the cursor position to the right.
_cursor_position = min(_cursor_position + 1, (int)_text.length()); _cursor_position = min(_cursor_position + 1, (int)_wtext.length());
_cursor_stale = true; _cursor_stale = true;
} }
@ -233,29 +233,32 @@ press(const MouseWatcherParameter &param, bool background) {
} else if (button == KeyboardButton::end()) { } else if (button == KeyboardButton::end()) {
if (_cursor_keys_active) { if (_cursor_keys_active) {
// End. Move the cursor position to the end. // End. Move the cursor position to the end.
_cursor_position = _text.length(); _cursor_position = _wtext.length();
_cursor_stale = true; _cursor_stale = true;
} }
} else if (!use_keystrokes && button.has_ascii_equivalent()) { } else if (!use_keystrokes && button.has_ascii_equivalent()) {
char key = button.get_ascii_equivalent(); // This part of the code is deprecated and will be removed
// soon. It only supports the old button up/down method of
// sending keystrokes, instead of the new keystroke method.
wchar_t key = button.get_ascii_equivalent();
if (isprint(key)) { if (isprint(key)) {
// A normal visible character. Add a new character to the // A normal visible character. Add a new character to the
// text entry, if there's room. // text entry, if there's room.
if (get_max_chars() > 0 && (int)_text.length() >= get_max_chars()) { if (get_max_chars() > 0 && (int)_wtext.length() >= get_max_chars()) {
overflow(param); overflow(param);
} else { } else {
string new_text = wstring new_text =
_text.substr(0, _cursor_position) + key + _wtext.substr(0, _cursor_position) + key +
_text.substr(_cursor_position); _wtext.substr(_cursor_position);
// Get a string to measure its length. In normal mode, // Get a string to measure its length. In normal mode,
// we measure the text itself. In obscure mode, we // we measure the text itself. In obscure mode, we
// measure a string of n asterisks. // measure a string of n asterisks.
string measure_text; wstring measure_text;
if (_obscure_mode) { if (_obscure_mode) {
measure_text = get_display_text() + '*'; measure_text = get_display_wtext() + (wchar_t)'*';
} else { } else {
measure_text = new_text; measure_text = new_text;
} }
@ -273,7 +276,7 @@ press(const MouseWatcherParameter &param, bool background) {
// If we have multiple lines, we have to check the // If we have multiple lines, we have to check the
// length by wordwrapping it and counting up the // length by wordwrapping it and counting up the
// number of lines. // number of lines.
string ww_text = text_node->wordwrap_to(measure_text, _max_width, true); wstring ww_text = text_node->wordwrap_to(measure_text, _max_width, true);
int num_lines = 1; int num_lines = 1;
size_t last_line_start = 0; size_t last_line_start = 0;
for (size_t p = 0; for (size_t p = 0;
@ -290,7 +293,7 @@ press(const MouseWatcherParameter &param, bool background) {
// We must also ensure that the last line is not too // We must also ensure that the last line is not too
// long (it might be, because of additional // long (it might be, because of additional
// whitespace on the end). // whitespace on the end).
string last_line = ww_text.substr(last_line_start); wstring last_line = ww_text.substr(last_line_start);
float last_line_width = text_node->calc_width(last_line); float last_line_width = text_node->calc_width(last_line);
if (num_lines == _num_lines) { if (num_lines == _num_lines) {
// Mainly we only care about this if we're on // Mainly we only care about this if we're on
@ -303,8 +306,8 @@ press(const MouseWatcherParameter &param, bool background) {
// infinite number of spaces to accumulate. // infinite number of spaces to accumulate.
// However, we must allow at least *one* space // However, we must allow at least *one* space
// on the end of a line. // on the end of a line.
if (_text.length() >= 1 && if (_wtext.length() >= 1 &&
_text[_text.length() - 1] == ' ') { _wtext[_wtext.length() - 1] == ' ') {
if (last_line_width > _max_width) { if (last_line_width > _max_width) {
// In this case, however, it's not exactly // In this case, however, it's not exactly
// an overflow; we just want to reject the // an overflow; we just want to reject the
@ -321,9 +324,9 @@ press(const MouseWatcherParameter &param, bool background) {
overflow(param); overflow(param);
} else { } else {
_text = new_text; _wtext = new_text;
if (_obscure_mode) { if (_obscure_mode) {
_obscured_text = measure_text; _obscured_wtext = measure_text;
} }
_cursor_position++; _cursor_position++;
@ -356,26 +359,22 @@ keystroke(const MouseWatcherParameter &param, bool background) {
if (!isascii(keycode) || isprint(keycode)) { if (!isascii(keycode) || isprint(keycode)) {
// A normal visible character. Add a new character to the // A normal visible character. Add a new character to the
// text entry, if there's room. // text entry, if there's room.
wstring new_char(1, (wchar_t)keycode);
// Encode the character. This might expand it to two or if (get_max_chars() > 0 && (int)_wtext.length() >= get_max_chars()) {
// three bytes, or it might remain a one-byte character.
TextNode *text_node = get_text_def(S_focus);
string new_char = text_node->encode_wchar(keycode);
if (get_max_chars() > 0 && (int)_text.length() >= get_max_chars()) {
overflow(param); overflow(param);
} else { } else {
_cursor_position = min(_cursor_position, (int)_text.length()); _cursor_position = min(_cursor_position, (int)_wtext.length());
string new_text = wstring new_text =
_text.substr(0, _cursor_position) + new_char + _wtext.substr(0, _cursor_position) + new_char +
_text.substr(_cursor_position); _wtext.substr(_cursor_position);
// Get a string to measure its length. In normal mode, // Get a string to measure its length. In normal mode,
// we measure the text itself. In obscure mode, we // we measure the text itself. In obscure mode, we
// measure a string of n asterisks. // measure a string of n asterisks.
string measure_text; wstring measure_text;
if (_obscure_mode) { if (_obscure_mode) {
measure_text = get_display_text() + '*'; measure_text = get_display_wtext() + (wchar_t)'*';
} else { } else {
measure_text = new_text; measure_text = new_text;
} }
@ -393,7 +392,7 @@ keystroke(const MouseWatcherParameter &param, bool background) {
// If we have multiple lines, we have to check the // If we have multiple lines, we have to check the
// length by wordwrapping it and counting up the // length by wordwrapping it and counting up the
// number of lines. // number of lines.
string ww_text = text_node->wordwrap_to(measure_text, _max_width, true); wstring ww_text = text_node->wordwrap_to(measure_text, _max_width, true);
int num_lines = 1; int num_lines = 1;
size_t last_line_start = 0; size_t last_line_start = 0;
for (size_t p = 0; for (size_t p = 0;
@ -410,7 +409,7 @@ keystroke(const MouseWatcherParameter &param, bool background) {
// We must also ensure that the last line is not too // We must also ensure that the last line is not too
// long (it might be, because of additional // long (it might be, because of additional
// whitespace on the end). // whitespace on the end).
string last_line = ww_text.substr(last_line_start); wstring last_line = ww_text.substr(last_line_start);
float last_line_width = text_node->calc_width(last_line); float last_line_width = text_node->calc_width(last_line);
if (num_lines == _num_lines) { if (num_lines == _num_lines) {
// Mainly we only care about this if we're on // Mainly we only care about this if we're on
@ -423,8 +422,8 @@ keystroke(const MouseWatcherParameter &param, bool background) {
// infinite number of spaces to accumulate. // infinite number of spaces to accumulate.
// However, we must allow at least *one* space // However, we must allow at least *one* space
// on the end of a line. // on the end of a line.
if (_text.length() >= 1 && if (_wtext.length() >= 1 &&
_text[_text.length() - 1] == ' ') { _wtext[_wtext.length() - 1] == ' ') {
if (last_line_width > _max_width) { if (last_line_width > _max_width) {
// In this case, however, it's not exactly // In this case, however, it's not exactly
// an overflow; we just want to reject the // an overflow; we just want to reject the
@ -441,9 +440,9 @@ keystroke(const MouseWatcherParameter &param, bool background) {
overflow(param); overflow(param);
} else { } else {
_text = new_text; _wtext = new_text;
if (_obscure_mode) { if (_obscure_mode) {
_obscured_text = measure_text; _obscured_wtext = measure_text;
} }
_cursor_position += new_char.length(); _cursor_position += new_char.length();
@ -561,16 +560,16 @@ setup(float width, int num_lines) {
frame[3] = max(max(ll[2], ur[2]), max(lr[2], ul[2])); frame[3] = max(max(ll[2], ur[2]), max(lr[2], ul[2]));
switch (text_node->get_align()) { switch (text_node->get_align()) {
case TM_ALIGN_LEFT: case TextNode::A_left:
// The default case. // The default case.
break; break;
case TM_ALIGN_CENTER: case TextNode::A_center:
frame[0] = -width / 2.0; frame[0] = -width / 2.0;
frame[1] = width / 2.0; frame[1] = width / 2.0;
break; break;
case TM_ALIGN_RIGHT: case TextNode::A_right:
frame[0] = -width; frame[0] = -width;
frame[1] = 0.0f; frame[1] = 0.0f;
break; break;
@ -676,30 +675,30 @@ set_focus(bool focus) {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PGEntry::get_display_text // Function: PGEntry::get_display_wtext
// Access: Private // Access: Private
// Description: Returns the string that should be displayed within // Description: Returns the string that should be displayed within
// the entry. This is normally _text, but it may be // the entry. This is normally _wtext, but it may be
// _obscured_text. // _obscured_wtext.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
const string &PGEntry:: const wstring &PGEntry::
get_display_text() { get_display_wtext() {
if (_obscure_mode) { if (_obscure_mode) {
// If obscure mode is enabled, we should just display a bunch of // If obscure mode is enabled, we should just display a bunch of
// asterisks. // asterisks.
if (_obscured_text.length() != _text.length()) { if (_obscured_wtext.length() != _wtext.length()) {
_obscured_text = ""; _obscured_wtext = wstring();
string::const_iterator ti; wstring::const_iterator ti;
for (ti = _text.begin(); ti != _text.end(); ++ti) { for (ti = _wtext.begin(); ti != _wtext.end(); ++ti) {
_obscured_text += '*'; _obscured_wtext += (wchar_t)'*';
} }
} }
return _obscured_text; return _obscured_wtext;
} else { } else {
// In normal, non-obscure mode, we display the actual text. // In normal, non-obscure mode, we display the actual text.
return _text; return _wtext;
} }
} }
@ -728,20 +727,20 @@ update_text() {
nassertv(node != (TextNode *)NULL); nassertv(node != (TextNode *)NULL);
if (_text_geom_stale || node != _last_text_def) { if (_text_geom_stale || node != _last_text_def) {
const string &display_text = get_display_text(); const wstring &display_wtext = get_display_wtext();
// We need to regenerate. // We need to regenerate.
_last_text_def = node; _last_text_def = node;
if (_max_width > 0.0f && _num_lines > 1) { if (_max_width > 0.0f && _num_lines > 1) {
// Fold the text into multiple lines. // Fold the text into multiple lines.
string ww_text = wstring ww_text =
_last_text_def->wordwrap_to(display_text, _max_width, true); _last_text_def->wordwrap_to(display_wtext, _max_width, true);
// And chop the lines up into pieces. // And chop the lines up into pieces.
_ww_lines.clear(); _ww_lines.clear();
size_t p = 0; size_t p = 0;
size_t q = ww_text.find('\n'); size_t q = ww_text.find((wchar_t)'\n');
while (q != string::npos) { while (q != string::npos) {
_ww_lines.push_back(WWLine()); _ww_lines.push_back(WWLine());
WWLine &line = _ww_lines.back(); WWLine &line = _ww_lines.back();
@ -749,8 +748,8 @@ update_text() {
// Get the left edge of the text at this line. // Get the left edge of the text at this line.
line._left = 0.0f; line._left = 0.0f;
if (_last_text_def->get_align() != TM_ALIGN_LEFT) { if (_last_text_def->get_align() != TextNode::A_left) {
_last_text_def->set_text(line._str); _last_text_def->set_wtext(line._str);
line._left = _last_text_def->get_left(); line._left = _last_text_def->get_left();
} }
@ -763,21 +762,21 @@ update_text() {
// Get the left edge of the text at this line. // Get the left edge of the text at this line.
line._left = 0.0f; line._left = 0.0f;
if (_last_text_def->get_align() != TM_ALIGN_LEFT) { if (_last_text_def->get_align() != TextNode::A_left) {
_last_text_def->set_text(line._str); _last_text_def->set_wtext(line._str);
line._left = _last_text_def->get_left(); line._left = _last_text_def->get_left();
} }
_last_text_def->set_text(ww_text); _last_text_def->set_wtext(ww_text);
} else { } else {
// Only one line. // Only one line.
_ww_lines.clear(); _ww_lines.clear();
_ww_lines.push_back(WWLine()); _ww_lines.push_back(WWLine());
WWLine &line = _ww_lines.back(); WWLine &line = _ww_lines.back();
line._str = display_text; line._str = display_wtext;
_last_text_def->set_text(display_text); _last_text_def->set_wtext(display_wtext);
line._left = _last_text_def->get_left(); line._left = _last_text_def->get_left();
} }
@ -804,7 +803,7 @@ update_cursor() {
if (_cursor_stale || node != _last_text_def) { if (_cursor_stale || node != _last_text_def) {
update_text(); update_text();
_cursor_position = min(_cursor_position, (int)_text.length()); _cursor_position = min(_cursor_position, (int)_wtext.length());
// Determine the row and column of the cursor. // Determine the row and column of the cursor.
int row = 0; int row = 0;

View File

@ -33,6 +33,14 @@
// Description : This is a particular kind of PGItem that handles // Description : This is a particular kind of PGItem that handles
// simple one-line text entries, of the sort where the // simple one-line text entries, of the sort where the
// user can type any string. // user can type any string.
//
// A PGEntry does all of its internal manipulation on a
// wide string, so it can store the full Unicode
// character set. The interface can support either the
// wide string getters and setters, or the normal 8-bit
// string getters and setters, which use whatever
// encoding method is specified by the associated
// TextNode.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class EXPCL_PANDA PGEntry : public PGItem { class EXPCL_PANDA PGEntry : public PGItem {
PUBLISHED: PUBLISHED:
@ -66,7 +74,7 @@ PUBLISHED:
void setup(float width, int num_lines); void setup(float width, int num_lines);
INLINE void set_text(const string &text); INLINE void set_text(const string &text);
INLINE const string &get_text() const; INLINE string get_text() const;
INLINE void set_cursor_position(int position); INLINE void set_cursor_position(int position);
INLINE int get_cursor_position() const; INLINE int get_cursor_position() const;
@ -106,16 +114,21 @@ PUBLISHED:
INLINE string get_type_event() const; INLINE string get_type_event() const;
INLINE string get_erase_event() const; INLINE string get_erase_event() const;
public:
INLINE void set_wtext(const wstring &wtext);
INLINE const wstring &get_wtext() const;
private: private:
const string &get_display_text(); const wstring &get_display_wtext();
void slot_text_def(int state); void slot_text_def(int state);
void update_text(); void update_text();
void update_cursor(); void update_cursor();
void show_hide_cursor(bool visible); void show_hide_cursor(bool visible);
void update_state(); void update_state();
string _text; wstring _wtext;
string _obscured_text; wstring _obscured_wtext;
int _cursor_position; int _cursor_position;
bool _cursor_stale; bool _cursor_stale;
bool _cursor_visible; bool _cursor_visible;
@ -142,7 +155,7 @@ private:
// to compute the correct cursor position. // to compute the correct cursor position.
class WWLine { class WWLine {
public: public:
string _str; wstring _str;
float _left; float _left;
}; };
typedef pvector<WWLine> WWLines; typedef pvector<WWLine> WWLines;

View File

@ -56,7 +56,7 @@ ConfigureFn(config_text) {
const bool text_flatten = config_text.GetBool("text-flatten", true); const bool text_flatten = config_text.GetBool("text-flatten", true);
const bool text_update_cleared_glyphs = config_text.GetBool("text-update-cleared-glyphs", false); const bool text_update_cleared_glyphs = config_text.GetBool("text-update-cleared-glyphs", false);
const bool text_mipmap = config_text.GetBool("text-mipmap", true); const bool text_mipmap = config_text.GetBool("text-mipmap", false);
const int text_anisotropic_degree = config_text.GetInt("text-anisotropic-degree", 1); const int text_anisotropic_degree = config_text.GetInt("text-anisotropic-degree", 1);
const int text_texture_margin = config_text.GetInt("text-texture-margin", 2); const int text_texture_margin = config_text.GetInt("text-texture-margin", 2);
const float text_poly_margin = config_text.GetFloat("text-poly-margin", 1.0f); const float text_poly_margin = config_text.GetFloat("text-poly-margin", 1.0f);

View File

@ -1022,6 +1022,19 @@ get_coordinate_system() const {
return _coordinate_system; return _coordinate_system;
} }
////////////////////////////////////////////////////////////////////
// Function: TextNode::set_text
// Access: Published
// Description: Changes the text that is displayed under the
// TextNode.
////////////////////////////////////////////////////////////////////
INLINE void TextNode::
set_text(const string &text) {
_text = text;
_wtext = decode_text(text);
rebuild(true);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextNode::clear_text // Function: TextNode::clear_text
// Access: Published // Access: Published
@ -1225,3 +1238,58 @@ INLINE int TextNode::
get_num_rows() const { get_num_rows() const {
return _num_rows; return _num_rows;
} }
////////////////////////////////////////////////////////////////////
// Function: TextNode::set_wtext
// Access: Public
// Description: Changes the text that is displayed under the
// TextNode, with a wide text. This automatically sets
// the string reported by get_text() to the 8-bit
// encoded version of the same string.
////////////////////////////////////////////////////////////////////
INLINE void TextNode::
set_wtext(const wstring &wtext) {
_wtext = wtext;
_text = encode_wtext(wtext);
rebuild(true);
}
////////////////////////////////////////////////////////////////////
// Function: TextNode::get_wtext
// Access: Public
// Description: Returns the text associated with the TextNode, as a
// wide-character string.
////////////////////////////////////////////////////////////////////
INLINE const wstring &TextNode::
get_wtext() const {
return _wtext;
}
////////////////////////////////////////////////////////////////////
// Function: TextNode::calc_width
// Access: Published
// Description: Returns the width of a line of text of arbitrary
// characters. The line should not include the newline
// character.
////////////////////////////////////////////////////////////////////
INLINE float TextNode::
calc_width(const wstring &line) const {
nassertr(_font != (TextFont *)NULL, 0.0);
return _font->calc_width(line);
}
////////////////////////////////////////////////////////////////////
// Function: TextNode::wordwrap_to
// Access: Published
// Description: Inserts newlines into the given text at the
// appropriate places in order to make each line be the
// longest possible line that is not longer than
// wordwrap_width (and does not break any words, if
// possible). Returns the new string.
////////////////////////////////////////////////////////////////////
wstring TextNode::
wordwrap_to(const wstring &wtext, float wordwrap_width,
bool preserve_trailing_whitespace) const {
nassertr(_font != (TextFont *)NULL, wtext);
return _font->wordwrap_to(wtext, wordwrap_width, preserve_trailing_whitespace);
}

View File

@ -92,19 +92,6 @@ TextNode::
~TextNode() { ~TextNode() {
} }
////////////////////////////////////////////////////////////////////
// Function: TextNode::set_text
// Access: Published
// Description: Changes the text that is displayed under the
// TextNode.
////////////////////////////////////////////////////////////////////
void TextNode::
set_text(const string &text) {
_text = text;
_wtext = decode_text(text);
rebuild(true);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextNode::wordwrap_to // Function: TextNode::wordwrap_to
// Access: Published // Access: Published
@ -439,10 +426,10 @@ encode_wchar(wchar_t ch) const {
// accoding to the current encoding. // accoding to the current encoding.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
string TextNode:: string TextNode::
encode_wtext(const wstring &text) const { encode_wtext(const wstring &wtext) const {
string result; string result;
for (wstring::const_iterator pi = text.begin(); pi != text.end(); ++pi) { for (wstring::const_iterator pi = wtext.begin(); pi != wtext.end(); ++pi) {
result += encode_wchar(*pi); result += encode_wchar(*pi);
} }

View File

@ -186,7 +186,7 @@ PUBLISHED:
INLINE void set_coordinate_system(CoordinateSystem cs); INLINE void set_coordinate_system(CoordinateSystem cs);
INLINE CoordinateSystem get_coordinate_system() const; INLINE CoordinateSystem get_coordinate_system() const;
void set_text(const string &str); INLINE void set_text(const string &text);
INLINE void clear_text(); INLINE void clear_text();
INLINE bool has_text() const; INLINE bool has_text() const;
INLINE string get_text() const; INLINE string get_text() const;
@ -218,8 +218,16 @@ PUBLISHED:
PT_Node generate(); PT_Node generate();
public: public:
// Direct support for wide-character strings.
INLINE void set_wtext(const wstring &wtext);
INLINE const wstring &get_wtext() const;
INLINE float calc_width(const wstring &line) const;
INLINE wstring wordwrap_to(const wstring &wtext, float wordwrap_width,
bool preserve_trailing_whitespace) const;
string encode_wchar(wchar_t ch) const; string encode_wchar(wchar_t ch) const;
string encode_wtext(const wstring &text) const; string encode_wtext(const wstring &wtext) const;
wstring decode_text(const string &text) const; wstring decode_text(const string &text) const;
private: private: