mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
bug fixes
This commit is contained in:
parent
1c7347f28e
commit
55ae74b3d1
@ -361,10 +361,11 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
||||
// 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);
|
||||
} else {
|
||||
_cursor_position = min(_cursor_position, (int)_text.length());
|
||||
string new_text =
|
||||
_text.substr(0, _cursor_position) + new_char +
|
||||
_text.substr(_cursor_position);
|
||||
@ -378,7 +379,7 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
||||
} else {
|
||||
measure_text = new_text;
|
||||
}
|
||||
|
||||
|
||||
// Check the length.
|
||||
bool too_long = false;
|
||||
if (_max_width > 0.0f) {
|
||||
@ -435,7 +436,7 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (too_long) {
|
||||
overflow(param);
|
||||
|
||||
@ -445,7 +446,7 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
||||
_obscured_text = measure_text;
|
||||
}
|
||||
|
||||
_cursor_position += new_char.size();
|
||||
_cursor_position += new_char.length();
|
||||
_cursor_stale = true;
|
||||
_text_geom_stale = true;
|
||||
type(param);
|
||||
|
@ -258,11 +258,14 @@ write(ostream &out, int indent_level) const {
|
||||
// code, as well as an optional scaling parameter that
|
||||
// should be applied to the glyph's geometry and advance
|
||||
// parameters. Returns true if the glyph exists, false
|
||||
// if it does not.
|
||||
// if it does not. Even if the return value is false,
|
||||
// the value for glyph might be filled in with a
|
||||
// printable glyph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DynamicTextFont::
|
||||
get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) {
|
||||
if (!_is_valid) {
|
||||
glyph = (TextGlyph *)NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,9 @@ write(ostream &out, int indent_level) const {
|
||||
// code, as well as an optional scaling parameter that
|
||||
// should be applied to the glyph's geometry and advance
|
||||
// parameters. Returns true if the glyph exists, false
|
||||
// if it does not.
|
||||
// if it does not. Even if the return value is false,
|
||||
// the value for glyph might be filled in with a
|
||||
// printable glyph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool StaticTextFont::
|
||||
get_glyph(int character, const TextGlyph *&glyph, float &glyph_scale) {
|
||||
|
@ -33,6 +33,16 @@ isblank(int ch) {
|
||||
return (ch == ' ' || ch == '\t');
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: isspacew
|
||||
// Description: An internal function that works like isspace() but is
|
||||
// safe to call for a wide character.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool
|
||||
isspacew(int ch) {
|
||||
return isascii(ch) && isspace(ch);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextFont::Constructor
|
||||
// Access: Public
|
||||
@ -69,7 +79,8 @@ calc_width(int character) {
|
||||
|
||||
const TextGlyph *glyph;
|
||||
float glyph_scale;
|
||||
if (!get_glyph(character, glyph, glyph_scale)) {
|
||||
get_glyph(character, glyph, glyph_scale);
|
||||
if (glyph == (TextGlyph *)NULL) {
|
||||
// Unknown character.
|
||||
return 0.0f;
|
||||
}
|
||||
@ -266,7 +277,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
||||
|
||||
// Preserve any initial whitespace and newlines.
|
||||
float initial_width = 0.0f;
|
||||
while (p < text.length() && isspace(text[p])) {
|
||||
while (p < text.length() && isspacew(text[p])) {
|
||||
if (text[p] == '\n') {
|
||||
initial_width = 0.0f;
|
||||
} else {
|
||||
@ -278,7 +289,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
||||
bool needs_newline = false;
|
||||
|
||||
while (p < text.length()) {
|
||||
nassertr(!isspace(text[p]), wstring());
|
||||
nassertr(!isspacew(text[p]), wstring());
|
||||
|
||||
// Scan the next n characters, until the end of the string or an
|
||||
// embedded newline character, or we exceed wordwrap_width.
|
||||
@ -289,7 +300,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
||||
|
||||
float width = initial_width;
|
||||
while (q < text.length() && text[q] != '\n') {
|
||||
if (isspace(text[q])) {
|
||||
if (isspacew(text[q])) {
|
||||
any_spaces = true;
|
||||
}
|
||||
|
||||
@ -303,11 +314,11 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (overflow && any_spaces) {
|
||||
// If we stopped because we exceeded the wordwrap width, then
|
||||
// back up to the end of the last complete word.
|
||||
while (q > p && !isspace(text[q])) {
|
||||
while (q > p && !isspacew(text[q])) {
|
||||
q--;
|
||||
}
|
||||
}
|
||||
@ -319,7 +330,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
||||
}
|
||||
|
||||
// Trim off any more blanks on the end.
|
||||
while (q > p && isspace(text[q - 1])) {
|
||||
while (q > p && isspacew(text[q - 1])) {
|
||||
q--;
|
||||
}
|
||||
|
||||
@ -356,7 +367,7 @@ wordwrap_to(const wstring &text, float wordwrap_width,
|
||||
|
||||
// Preserve any initial whitespace and newlines.
|
||||
initial_width = 0.0f;
|
||||
while (p < text.length() && isspace(text[p])) {
|
||||
while (p < text.length() && isspacew(text[p])) {
|
||||
if (text[p] == '\n') {
|
||||
initial_width = 0.0f;
|
||||
} else {
|
||||
|
@ -1078,22 +1078,6 @@ calc_width(const string &line) const {
|
||||
return _font->calc_width(decode_text(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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string TextNode::
|
||||
wordwrap_to(const string &text, float wordwrap_width,
|
||||
bool preserve_trailing_whitespace) const {
|
||||
nassertr(_font != (TextFont *)NULL, text);
|
||||
return encode_wtext(_font->wordwrap_to(decode_text(text), wordwrap_width, preserve_trailing_whitespace));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::rebuild
|
||||
// Access: Published
|
||||
|
@ -105,6 +105,25 @@ set_text(const string &text) {
|
||||
rebuild(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string TextNode::
|
||||
wordwrap_to(const string &text, float wordwrap_width,
|
||||
bool preserve_trailing_whitespace) const {
|
||||
nassertr(_font != (TextFont *)NULL, text);
|
||||
wstring decoded = decode_text(text);
|
||||
wstring wrapped =
|
||||
_font->wordwrap_to(decoded, wordwrap_width, preserve_trailing_whitespace);
|
||||
return encode_wtext(wrapped);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextNode::write
|
||||
@ -797,7 +816,7 @@ measure_row(wstring::iterator &si, const wstring::iterator &send) {
|
||||
|
||||
if (character == ' ') {
|
||||
// A space is a special case.
|
||||
xpos += 0.25f;
|
||||
xpos += _font->get_space_advance();
|
||||
|
||||
} else {
|
||||
// A printable character.
|
||||
|
@ -193,8 +193,8 @@ PUBLISHED:
|
||||
|
||||
INLINE float calc_width(int character) const;
|
||||
INLINE float calc_width(const string &line) const;
|
||||
INLINE string wordwrap_to(const string &text, float wordwrap_width,
|
||||
bool preserve_trailing_whitespace) const;
|
||||
string wordwrap_to(const string &text, float wordwrap_width,
|
||||
bool preserve_trailing_whitespace) const;
|
||||
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
|
@ -1199,7 +1199,9 @@ void wglGraphicsWindow::handle_reshape() {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wglGraphicsWindow::handle_mouse_motion(int x, int y) {
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
if (!_input_devices.empty()) {
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1209,7 +1211,9 @@ void wglGraphicsWindow::handle_mouse_motion(int x, int y) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wglGraphicsWindow::handle_mouse_entry(int state) {
|
||||
if (state == MOUSE_EXITED) {
|
||||
_input_devices[0].set_pointer_out_of_window();
|
||||
if (!_input_devices.empty()) {
|
||||
_input_devices[0].set_pointer_out_of_window();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1220,9 +1224,11 @@ void wglGraphicsWindow::handle_mouse_entry(int state) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wglGraphicsWindow::
|
||||
handle_keypress(ButtonHandle key, int x, int y) {
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_down(key);
|
||||
if (!_input_devices.empty()) {
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_down(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1234,7 +1240,9 @@ handle_keypress(ButtonHandle key, int x, int y) {
|
||||
void wglGraphicsWindow::
|
||||
handle_keyrelease(ButtonHandle key) {
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_up(key);
|
||||
if (!_input_devices.empty()) {
|
||||
_input_devices[0].button_up(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1647,31 +1655,35 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
|
||||
case WM_IME_COMPOSITION:
|
||||
if (lparam & GCS_RESULTSTR) {
|
||||
HIMC hIMC = ImmGetContext(hwnd);
|
||||
nassertr(hIMC != 0, 0);
|
||||
|
||||
static const int max_ime_result = 128;
|
||||
static char ime_result[max_ime_result];
|
||||
|
||||
// There's a rumor that ImmGetCompositionStringW() doesn't
|
||||
// work for Win95 or Win98; for these OS's we must use
|
||||
// ImmGetCompositionStringA(). How does this affect the
|
||||
// returning of multibyte characters?
|
||||
DWORD result_size =
|
||||
ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
|
||||
ime_result, max_ime_result);
|
||||
ImmReleaseContext(hwnd, hIMC);
|
||||
|
||||
// Add this string into the text buffer of the application.
|
||||
|
||||
// ImmGetCompositionStringW() returns a string, but it's
|
||||
// filled in with wstring data: every two characters defines a
|
||||
// 16-bit unicode char. The docs aren't clear on the
|
||||
// endianness of this. I guess it's safe to assume all Win32
|
||||
// machines are little-endian.
|
||||
for (DWORD i = 0; i < result_size; i += 2) {
|
||||
int result = ((int)ime_result[i + 1] << 8) | ime_result[i];
|
||||
_input_devices[0].keystroke(result);
|
||||
if (!_input_devices.empty()) {
|
||||
HIMC hIMC = ImmGetContext(hwnd);
|
||||
nassertr(hIMC != 0, 0);
|
||||
|
||||
static const int max_ime_result = 128;
|
||||
static char ime_result[max_ime_result];
|
||||
|
||||
// There's a rumor that ImmGetCompositionStringW() doesn't
|
||||
// work for Win95 or Win98; for these OS's we must use
|
||||
// ImmGetCompositionStringA(). How does this affect the
|
||||
// returning of multibyte characters?
|
||||
DWORD result_size =
|
||||
ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
|
||||
ime_result, max_ime_result);
|
||||
ImmReleaseContext(hwnd, hIMC);
|
||||
|
||||
// Add this string into the text buffer of the application.
|
||||
|
||||
// ImmGetCompositionStringW() returns a string, but it's
|
||||
// filled in with wstring data: every two characters defines a
|
||||
// 16-bit unicode char. The docs aren't clear on the
|
||||
// endianness of this. I guess it's safe to assume all Win32
|
||||
// machines are little-endian.
|
||||
for (DWORD i = 0; i < result_size; i += 2) {
|
||||
int result =
|
||||
((int)(unsigned char)ime_result[i + 1] << 8) |
|
||||
(unsigned char)ime_result[i];
|
||||
_input_devices[0].keystroke(result);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user