mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
fix stopped-chat wordwrap problem
This commit is contained in:
parent
7786bc0915
commit
382f0527eb
@ -99,6 +99,8 @@ open_framework(int &argc, char **&argv) {
|
|||||||
_is_open = true;
|
_is_open = true;
|
||||||
|
|
||||||
reset_frame_rate();
|
reset_frame_rate();
|
||||||
|
|
||||||
|
_event_handler.add_hook("window-event", event_window_event, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -781,8 +783,6 @@ do_enable_default_keys() {
|
|||||||
define_key(",", "change background color", event_comma, this);
|
define_key(",", "change background color", event_comma, this);
|
||||||
define_key("?", "", event_question, this);
|
define_key("?", "", event_question, this);
|
||||||
define_key("shift-/", "", event_question, this);
|
define_key("shift-/", "", event_question, this);
|
||||||
|
|
||||||
_event_handler.add_hook("window-event", event_window_event, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -810,7 +810,7 @@ clear_text() {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_esc
|
// Function: PandaFramework::event_esc
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for ESC or q key: close the current
|
// Description: Default handler for ESC or q key: close the current
|
||||||
// window (and exit the application if that was the last
|
// window (and exit the application if that was the last
|
||||||
// window).
|
// window).
|
||||||
@ -846,7 +846,7 @@ event_esc(CPT_Event event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_f
|
// Function: PandaFramework::event_f
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for f key: report and reset frame
|
// Description: Default handler for f key: report and reset frame
|
||||||
// rate.
|
// rate.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -859,7 +859,7 @@ event_f(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_w
|
// Function: PandaFramework::event_w
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for w key: toggle wireframe.
|
// Description: Default handler for w key: toggle wireframe.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -875,7 +875,7 @@ event_w(CPT_Event event, void *) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_t
|
// Function: PandaFramework::event_t
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for t key: toggle texture.
|
// Description: Default handler for t key: toggle texture.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -891,7 +891,7 @@ event_t(CPT_Event event, void *) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_b
|
// Function: PandaFramework::event_b
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for b key: toggle backface (two-sided
|
// Description: Default handler for b key: toggle backface (two-sided
|
||||||
// rendering).
|
// rendering).
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -908,7 +908,7 @@ event_b(CPT_Event event, void *) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_i
|
// Function: PandaFramework::event_i
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for i key: invert one-sided faces.
|
// Description: Default handler for i key: invert one-sided faces.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -924,7 +924,7 @@ event_i(CPT_Event event, void *) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_l
|
// Function: PandaFramework::event_l
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for l key: toggle lighting.
|
// Description: Default handler for l key: toggle lighting.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -940,7 +940,7 @@ event_l(CPT_Event event, void *) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_c
|
// Function: PandaFramework::event_c
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for c key: center the trackball over
|
// Description: Default handler for c key: center the trackball over
|
||||||
// the scene, or over the highlighted part of the scene.
|
// the scene, or over the highlighted part of the scene.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -963,7 +963,7 @@ event_c(CPT_Event event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_C
|
// Function: PandaFramework::event_C
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for shift-C key: toggle the showing
|
// Description: Default handler for shift-C key: toggle the showing
|
||||||
// of collision solids.
|
// of collision solids.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -983,7 +983,7 @@ event_C(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_B
|
// Function: PandaFramework::event_B
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for shift-B key: describe the
|
// Description: Default handler for shift-B key: describe the
|
||||||
// bounding volume of the currently selected object, or
|
// bounding volume of the currently selected object, or
|
||||||
// the entire scene.
|
// the entire scene.
|
||||||
@ -1002,7 +1002,7 @@ event_B(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_L
|
// Function: PandaFramework::event_L
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for shift-L key: list the contents of
|
// Description: Default handler for shift-L key: list the contents of
|
||||||
// the scene graph, or the highlighted node.
|
// the scene graph, or the highlighted node.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1020,7 +1020,7 @@ event_L(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_h
|
// Function: PandaFramework::event_h
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for h key: toggle highlight mode. In
|
// Description: Default handler for h key: toggle highlight mode. In
|
||||||
// this mode, you can walk the scene graph with the
|
// this mode, you can walk the scene graph with the
|
||||||
// arrow keys to highlight different nodes.
|
// arrow keys to highlight different nodes.
|
||||||
@ -1038,7 +1038,7 @@ event_h(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_arrow_up
|
// Function: PandaFramework::event_arrow_up
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for up arrow key: in highlight mode,
|
// Description: Default handler for up arrow key: in highlight mode,
|
||||||
// move the highlight to the node's parent.
|
// move the highlight to the node's parent.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1056,7 +1056,7 @@ event_arrow_up(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_arrow_down
|
// Function: PandaFramework::event_arrow_down
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for up arrow key: in highlight mode,
|
// Description: Default handler for up arrow key: in highlight mode,
|
||||||
// move the highlight to the node's first child.
|
// move the highlight to the node's first child.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1074,7 +1074,7 @@ event_arrow_down(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_arrow_left
|
// Function: PandaFramework::event_arrow_left
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for up arrow key: in highlight mode,
|
// Description: Default handler for up arrow key: in highlight mode,
|
||||||
// move the highlight to the node's nearest sibling on
|
// move the highlight to the node's nearest sibling on
|
||||||
// the left.
|
// the left.
|
||||||
@ -1106,7 +1106,7 @@ event_arrow_left(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_arrow_right
|
// Function: PandaFramework::event_arrow_right
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for up arrow key: in highlight mode,
|
// Description: Default handler for up arrow key: in highlight mode,
|
||||||
// move the highlight to the node's nearest sibling on
|
// move the highlight to the node's nearest sibling on
|
||||||
// the right.
|
// the right.
|
||||||
@ -1139,7 +1139,7 @@ event_arrow_right(CPT_Event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_S
|
// Function: PandaFramework::event_S
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for shift-S key: activate stats.
|
// Description: Default handler for shift-S key: activate stats.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -1154,7 +1154,7 @@ event_S(CPT_Event, void *) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_f9
|
// Function: PandaFramework::event_f9
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for f9 key: take screenshot.
|
// Description: Default handler for f9 key: take screenshot.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -1196,7 +1196,7 @@ event_f9(CPT_Event event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_comma
|
// Function: PandaFramework::event_comma
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for comma key: rotate background color.
|
// Description: Default handler for comma key: rotate background color.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -1222,7 +1222,7 @@ event_comma(CPT_Event event, void *) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_question
|
// Function: PandaFramework::event_question
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for ? key: show the available keys.
|
// Description: Default handler for ? key: show the available keys.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PandaFramework::
|
void PandaFramework::
|
||||||
@ -1277,7 +1277,7 @@ event_question(CPT_Event event, void *data) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaFramework::event_window_event
|
// Function: PandaFramework::event_window_event
|
||||||
// Access: Protected, Static
|
// Access: Public, Static
|
||||||
// Description: Default handler for window events: window resized or
|
// Description: Default handler for window events: window resized or
|
||||||
// closed, etc.
|
// closed, etc.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -119,6 +119,7 @@ protected:
|
|||||||
virtual void do_enable_default_keys();
|
virtual void do_enable_default_keys();
|
||||||
bool clear_text();
|
bool clear_text();
|
||||||
|
|
||||||
|
public:
|
||||||
static void event_esc(CPT_Event, void *data);
|
static void event_esc(CPT_Event, void *data);
|
||||||
static void event_f(CPT_Event, void *data);
|
static void event_f(CPT_Event, void *data);
|
||||||
static void event_w(CPT_Event, void *data);
|
static void event_w(CPT_Event, void *data);
|
||||||
|
@ -307,7 +307,15 @@ get_render_2d() {
|
|||||||
const NodePath &WindowFramework::
|
const NodePath &WindowFramework::
|
||||||
get_aspect_2d() {
|
get_aspect_2d() {
|
||||||
if (_aspect_2d.is_empty()) {
|
if (_aspect_2d.is_empty()) {
|
||||||
_aspect_2d = get_render_2d().attach_new_node(new PGTop("aspect_2d"));
|
PGTop *top = new PGTop("aspect_2d");
|
||||||
|
_aspect_2d = get_render_2d().attach_new_node(top);
|
||||||
|
|
||||||
|
// Tell the PGTop about our MouseWatcher object, so the PGui
|
||||||
|
// system can operate.
|
||||||
|
PandaNode *mouse_node = get_mouse().node();
|
||||||
|
if (mouse_node->is_of_type(MouseWatcher::get_class_type())) {
|
||||||
|
top->set_mouse_watcher(DCAST(MouseWatcher, mouse_node));
|
||||||
|
}
|
||||||
|
|
||||||
float this_aspect_ratio = aspect_ratio;
|
float this_aspect_ratio = aspect_ratio;
|
||||||
if (this_aspect_ratio == 0.0f) {
|
if (this_aspect_ratio == 0.0f) {
|
||||||
@ -346,6 +354,9 @@ get_mouse() {
|
|||||||
// display region, if we have one. This means the node we return
|
// display region, if we have one. This means the node we return
|
||||||
// from get_mouse() is actually a MouseWatcher, but since it
|
// from get_mouse() is actually a MouseWatcher, but since it
|
||||||
// presents the same interface as a Mouse, no one should mind.
|
// presents the same interface as a Mouse, no one should mind.
|
||||||
|
|
||||||
|
// Another advantage to using a MouseWatcher is that it the PGTop
|
||||||
|
// of aspect2d likes it better.
|
||||||
PT(MouseWatcher) mw = new MouseWatcher("watcher");
|
PT(MouseWatcher) mw = new MouseWatcher("watcher");
|
||||||
mw->set_display_region(_display_region_3d);
|
mw->set_display_region(_display_region_3d);
|
||||||
_mouse = mouse.attach_new_node(mw);
|
_mouse = mouse.attach_new_node(mw);
|
||||||
|
@ -55,3 +55,21 @@
|
|||||||
|
|
||||||
#end lib_target
|
#end lib_target
|
||||||
|
|
||||||
|
|
||||||
|
#begin test_bin_target
|
||||||
|
#define TARGET test_pgentry
|
||||||
|
|
||||||
|
#define OTHER_LIBS $[OTHER_LIBS] pystub
|
||||||
|
|
||||||
|
#define LOCAL_LIBS \
|
||||||
|
framework putil collide pgraph chan text \
|
||||||
|
pnmimage pnmimagetypes event effects gobj display \
|
||||||
|
mathutil putil express dgraph device tform \
|
||||||
|
linmath pstatclient panda
|
||||||
|
|
||||||
|
#define UNIX_SYS_LIBS m
|
||||||
|
|
||||||
|
#define SOURCES \
|
||||||
|
test_pgentry.cxx
|
||||||
|
|
||||||
|
#end test_bin_target
|
||||||
|
@ -42,10 +42,6 @@ ConfigureFn(config_pgui) {
|
|||||||
// powerful but somewhat slower.
|
// powerful but somewhat slower.
|
||||||
const bool pgui_quick = config_pgui.GetBool("pgui-quick", true);
|
const bool pgui_quick = config_pgui.GetBool("pgui-quick", true);
|
||||||
|
|
||||||
// Temporary variable to support old-style button press/release for
|
|
||||||
// pgentries, before keystrokes were implemented.
|
|
||||||
const bool use_keystrokes = config_pgui.GetBool("use-keystrokes", true);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: init_libpgui
|
// Function: init_libpgui
|
||||||
|
@ -26,7 +26,6 @@ NotifyCategoryDecl(pgui, EXPCL_PANDA, EXPTP_PANDA);
|
|||||||
|
|
||||||
// Configure variables for pgui package.
|
// Configure variables for pgui package.
|
||||||
extern const bool pgui_quick;
|
extern const bool pgui_quick;
|
||||||
extern const bool use_keystrokes;
|
|
||||||
|
|
||||||
extern EXPCL_PANDA void init_libpgui();
|
extern EXPCL_PANDA void init_libpgui();
|
||||||
|
|
||||||
|
@ -250,95 +250,6 @@ press(const MouseWatcherParameter ¶m, bool background) {
|
|||||||
_cursor_position = _wtext.length();
|
_cursor_position = _wtext.length();
|
||||||
_cursor_stale = true;
|
_cursor_stale = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!use_keystrokes && button.has_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)) {
|
|
||||||
// A normal visible character. Add a new character to the
|
|
||||||
// text entry, if there's room.
|
|
||||||
|
|
||||||
if (get_max_chars() > 0 && (int)_wtext.length() >= get_max_chars()) {
|
|
||||||
overflow(param);
|
|
||||||
} else {
|
|
||||||
wstring new_text =
|
|
||||||
_wtext.substr(0, _cursor_position) + key +
|
|
||||||
_wtext.substr(_cursor_position);
|
|
||||||
|
|
||||||
// Get a string to measure its length. In normal mode,
|
|
||||||
// we measure the text itself. In obscure mode, we
|
|
||||||
// measure a string of n asterisks.
|
|
||||||
wstring measure_text;
|
|
||||||
if (_obscure_mode) {
|
|
||||||
measure_text = get_display_wtext() + (wchar_t)'*';
|
|
||||||
} else {
|
|
||||||
measure_text = new_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the length.
|
|
||||||
bool too_long = false;
|
|
||||||
if (_max_width > 0.0f) {
|
|
||||||
TextNode *text_node = get_text_def(S_focus);
|
|
||||||
text_node->set_wtext(measure_text);
|
|
||||||
text_node->set_wordwrap(_max_width);
|
|
||||||
text_node->set_preserve_trailing_whitespace(true);
|
|
||||||
text_node->set_max_rows(_num_lines);
|
|
||||||
|
|
||||||
too_long = text_node->has_overflow();
|
|
||||||
|
|
||||||
if (!too_long) {
|
|
||||||
// We must also ensure that the last line is not too
|
|
||||||
// long (it might be, because of additional
|
|
||||||
// whitespace on the end).
|
|
||||||
wstring ww_text = text_node->get_wordwrapped_wtext();
|
|
||||||
size_t last_line_start = ww_text.rfind('\n');
|
|
||||||
if (last_line_start == string::npos) {
|
|
||||||
last_line_start = 0;
|
|
||||||
}
|
|
||||||
wstring last_line = ww_text.substr(last_line_start);
|
|
||||||
float last_line_width = text_node->calc_width(last_line);
|
|
||||||
if (text_node->get_num_rows() == _num_lines) {
|
|
||||||
// Mainly we only care about this if we're on
|
|
||||||
// the very last line.
|
|
||||||
too_long = (last_line_width > _max_width);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// If we're not on the very last line, the width
|
|
||||||
// is still important, just so we don't allow an
|
|
||||||
// infinite number of spaces to accumulate.
|
|
||||||
// However, we must allow at least *one* space
|
|
||||||
// on the end of a line.
|
|
||||||
if (_wtext.length() >= 1 &&
|
|
||||||
_wtext[_wtext.length() - 1] == ' ') {
|
|
||||||
if (last_line_width > _max_width) {
|
|
||||||
// In this case, however, it's not exactly
|
|
||||||
// an overflow; we just want to reject the
|
|
||||||
// space.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (too_long) {
|
|
||||||
overflow(param);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_wtext = new_text;
|
|
||||||
if (_obscure_mode) {
|
|
||||||
_obscured_wtext = measure_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cursor_position++;
|
|
||||||
_cursor_stale = true;
|
|
||||||
_text_geom_stale = true;
|
|
||||||
type(param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,8 +269,6 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
|||||||
if (param.has_keycode()) {
|
if (param.has_keycode()) {
|
||||||
int keycode = param.get_keycode();
|
int keycode = param.get_keycode();
|
||||||
|
|
||||||
if (use_keystrokes) {
|
|
||||||
|
|
||||||
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.
|
||||||
@ -370,15 +279,19 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
|||||||
wstring new_char(1, (wchar_t)keycode);
|
wstring new_char(1, (wchar_t)keycode);
|
||||||
|
|
||||||
if (get_max_chars() > 0 && (int)_wtext.length() >= get_max_chars()) {
|
if (get_max_chars() > 0 && (int)_wtext.length() >= get_max_chars()) {
|
||||||
|
// In max_chars mode, we consider it an overflow after we
|
||||||
|
// have exceeded a fixed number of characters, irrespective
|
||||||
|
// of the formatted width of those characters.
|
||||||
overflow(param);
|
overflow(param);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_cursor_position = min(_cursor_position, (int)_wtext.length());
|
_cursor_position = min(_cursor_position, (int)_wtext.length());
|
||||||
wstring new_text =
|
wstring new_text =
|
||||||
_wtext.substr(0, _cursor_position) + new_char +
|
_wtext.substr(0, _cursor_position) + new_char +
|
||||||
_wtext.substr(_cursor_position);
|
_wtext.substr(_cursor_position);
|
||||||
|
|
||||||
// Get a string to measure its length. In normal mode,
|
// Get the new string to measure its length. In normal
|
||||||
// we measure the text itself. In obscure mode, we
|
// mode, we measure the text itself. In obscure mode, we
|
||||||
// measure a string of n asterisks.
|
// measure a string of n asterisks.
|
||||||
wstring measure_text;
|
wstring measure_text;
|
||||||
if (_obscure_mode) {
|
if (_obscure_mode) {
|
||||||
@ -387,7 +300,7 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
|||||||
measure_text = new_text;
|
measure_text = new_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the length.
|
// Now check the length.
|
||||||
bool too_long = false;
|
bool too_long = false;
|
||||||
if (_max_width > 0.0f) {
|
if (_max_width > 0.0f) {
|
||||||
TextNode *text_node = get_text_def(S_focus);
|
TextNode *text_node = get_text_def(S_focus);
|
||||||
@ -398,10 +311,11 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
|||||||
|
|
||||||
too_long = text_node->has_overflow();
|
too_long = text_node->has_overflow();
|
||||||
|
|
||||||
if (!too_long) {
|
if (!too_long && (text_node->get_num_rows() == _num_lines)) {
|
||||||
// We must also ensure that the last line is not too
|
// If we've filled up all of the available lines, we
|
||||||
// long (it might be, because of additional
|
// must also ensure that the last line is not too long
|
||||||
// whitespace on the end).
|
// (it might be, because of additional whitespace on
|
||||||
|
// the end).
|
||||||
wstring ww_text = text_node->get_wordwrapped_wtext();
|
wstring ww_text = text_node->get_wordwrapped_wtext();
|
||||||
size_t last_line_start = ww_text.rfind('\n');
|
size_t last_line_start = ww_text.rfind('\n');
|
||||||
if (last_line_start == string::npos) {
|
if (last_line_start == string::npos) {
|
||||||
@ -409,23 +323,72 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
|||||||
}
|
}
|
||||||
wstring 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 (text_node->get_num_rows() == _num_lines) {
|
|
||||||
// Mainly we only care about this if we're on
|
|
||||||
// the very last line.
|
|
||||||
too_long = (last_line_width > _max_width);
|
|
||||||
|
|
||||||
} else {
|
too_long = (last_line_width > _max_width);
|
||||||
// If we're not on the very last line, the width
|
}
|
||||||
// is still important, just so we don't allow an
|
|
||||||
|
if (!too_long && keycode == ' ') {
|
||||||
|
// Even if we haven't filled up all of the available
|
||||||
|
// lines, we should reject a space that's typed at the
|
||||||
|
// end of the current line if it would make that line
|
||||||
|
// exceed the maximum width, just so we don't allow an
|
||||||
// infinite number of spaces to accumulate.
|
// infinite number of spaces to accumulate.
|
||||||
// However, we must allow at least *one* space
|
|
||||||
// on the end of a line.
|
// First, we need to figure out our current position
|
||||||
if (_wtext.length() >= 1 &&
|
// within the wordwrapped text, by skipping past the
|
||||||
_wtext[_wtext.length() - 1] == ' ') {
|
// newlines.
|
||||||
if (last_line_width > _max_width) {
|
wstring ww_text = text_node->get_wordwrapped_wtext();
|
||||||
// In this case, however, it's not exactly
|
int i = 0;
|
||||||
// an overflow; we just want to reject the
|
int current_pos = 0;
|
||||||
// space.
|
while (i < _cursor_position) {
|
||||||
|
nassertv(current_pos < (int)ww_text.length());
|
||||||
|
if (ww_text[current_pos] != '\n') {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
current_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the user typing at the end of the line? Scan for
|
||||||
|
// the next character that's not a space following the
|
||||||
|
// current position.
|
||||||
|
int p = current_pos + 1;
|
||||||
|
while (p < (int)ww_text.length() && ww_text[p] == ' ') {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p >= (int)ww_text.length() || ww_text[p] == '\n') {
|
||||||
|
// The user is typing at the end of the line. But we
|
||||||
|
// must allow at least one space at the end of the
|
||||||
|
// line, so we only make any of the following checks
|
||||||
|
// if there are already multiple spaces at the end of
|
||||||
|
// the line.
|
||||||
|
if (p - 2 >= 0 && ww_text[p - 2] == ' ') {
|
||||||
|
// Ok, the user is putting multiple spaces on the
|
||||||
|
// end of a line; we need to make sure the line does
|
||||||
|
// not grow too wide. Get the beginning of the line
|
||||||
|
// and measure its width.
|
||||||
|
int q = current_pos;
|
||||||
|
while (q >= 0 && ww_text[q] != '\n') {
|
||||||
|
q--;
|
||||||
|
}
|
||||||
|
|
||||||
|
wstring current_line = ww_text.substr(q + 1, p - (q + 1));
|
||||||
|
float current_line_width = text_node->calc_width(current_line);
|
||||||
|
|
||||||
|
if (current_line_width > _max_width) {
|
||||||
|
// We have to reject the space, but we don't treat
|
||||||
|
// it as an overflow condition.
|
||||||
|
|
||||||
|
// If the user is typing over existing space
|
||||||
|
// characters, we act as if the right-arrow key
|
||||||
|
// were pressed instead, and advance the cursor to
|
||||||
|
// the next position. Otherwise, we just quietly
|
||||||
|
// eat the space character.
|
||||||
|
if (_cursor_position < (int)_wtext.length() &&
|
||||||
|
_wtext[_cursor_position] == ' ') {
|
||||||
|
_cursor_position++;
|
||||||
|
_cursor_stale = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,7 +414,6 @@ keystroke(const MouseWatcherParameter ¶m, bool background) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
PGItem::keystroke(param, background);
|
PGItem::keystroke(param, background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
48
panda/src/pgui/test_pgentry.cxx
Normal file
48
panda/src/pgui/test_pgentry.cxx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Filename: test_pgentry.cxx
|
||||||
|
// Created by: drose (30Apr04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "pandaFramework.h"
|
||||||
|
#include "pgEntry.h"
|
||||||
|
|
||||||
|
PandaFramework framework;
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[]) {
|
||||||
|
framework.open_framework(argc, argv);
|
||||||
|
framework.set_window_title("Panda Viewer");
|
||||||
|
|
||||||
|
WindowFramework *window = framework.open_window();
|
||||||
|
if (window != (WindowFramework *)NULL) {
|
||||||
|
window->enable_keyboard();
|
||||||
|
|
||||||
|
NodePath aspect2d = window->get_aspect_2d();
|
||||||
|
PGEntry *entry = new PGEntry("entry");
|
||||||
|
NodePath entry_np = aspect2d.attach_new_node(entry);
|
||||||
|
entry_np.set_scale(0.1);
|
||||||
|
entry_np.set_pos(-0.5, 0, 0.2);
|
||||||
|
|
||||||
|
entry->setup(10, 4);
|
||||||
|
|
||||||
|
framework.define_key("escape", "close window",
|
||||||
|
PandaFramework::event_esc, &framework);
|
||||||
|
|
||||||
|
framework.main_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
@ -565,6 +565,11 @@ wordwrap_text(const TextAssembler::TextString &text,
|
|||||||
// No characters got in at all. This could only happen if the
|
// No characters got in at all. This could only happen if the
|
||||||
// wordwrap width is narrower than a single character, or if we
|
// wordwrap width is narrower than a single character, or if we
|
||||||
// have a substantial number of leading spaces in a line.
|
// have a substantial number of leading spaces in a line.
|
||||||
|
|
||||||
|
if (initial_width == 0.0f) {
|
||||||
|
// There was no leading whitespace on the line, so the
|
||||||
|
// character itself didn't fit within the margins. Let it in
|
||||||
|
// anyway; what else can we do?
|
||||||
q++;
|
q++;
|
||||||
next_start++;
|
next_start++;
|
||||||
while (next_start < text.size() &&
|
while (next_start < text.size() &&
|
||||||
@ -572,6 +577,7 @@ wordwrap_text(const TextAssembler::TextString &text,
|
|||||||
next_start++;
|
next_start++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (needs_newline) {
|
if (needs_newline) {
|
||||||
if (max_rows > 0 && _num_rows >= max_rows) {
|
if (max_rows > 0 && _num_rows >= max_rows) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user