/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * * All use of this software is subject to the terms of the revised BSD * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * * @file pgEntry.I * @author drose * @date 2002-03-13 */ /** * Changes the text currently displayed within the entry. This uses the * Unicode encoding currently specified for the "focus" TextNode; therefore, * the TextNode must exist before calling set_text(). * * The return value is true if all the text is accepted, or false if some was * truncated (see set_max_width(), etc.). */ INLINE bool PGEntry:: set_text(const std::string &text) { LightReMutexHolder holder(_lock); TextNode *text_node = get_text_def(S_focus); nassertr(text_node != nullptr, false); return set_wtext(text_node->decode_text(text)); } /** * Returns the text currently displayed within the entry, without any embedded * properties characters. * * This uses the Unicode encoding currently specified for the "focus" * TextNode; therefore, the TextNode must exist before calling get_text(). */ INLINE std::string PGEntry:: get_plain_text() const { LightReMutexHolder holder(_lock); TextNode *text_node = get_text_def(S_focus); nassertr(text_node != nullptr, std::string()); return text_node->encode_wtext(get_plain_wtext()); } /** * Returns the text currently displayed within the entry. This uses the * Unicode encoding currently specified for the "focus" TextNode; therefore, * the TextNode must exist before calling get_text(). */ INLINE std::string PGEntry:: get_text() const { LightReMutexHolder holder(_lock); TextNode *text_node = get_text_def(S_focus); nassertr(text_node != nullptr, std::string()); return text_node->encode_wtext(get_wtext()); } /** * Returns the number of characters of text in the entry. This is the actual * number of visible characters, not counting implicit newlines due to * wordwrapping, or formatted characters for text properties changes. If * there is an embedded TextGraphic object, it counts as one character. * * This is also the length of the string returned by get_plain_text(). */ INLINE int PGEntry:: get_num_characters() const { LightReMutexHolder holder(_lock); return _text.get_num_characters(); } /** * Returns the character at the indicated position in the entry. If the * object at this position is a graphic object instead of a character, returns * 0. */ INLINE wchar_t PGEntry:: get_character(int n) const { LightReMutexHolder holder(_lock); return _text.get_character(n); } /** * Returns the graphic object at the indicated position in the pre-wordwrapped * string. If the object at this position is a character instead of a graphic * object, returns NULL. */ INLINE const TextGraphic *PGEntry:: get_graphic(int n) const { LightReMutexHolder holder(_lock); return _text.get_graphic(n); } /** * Returns the TextProperties in effect for the object at the indicated * position in the pre-wordwrapped string. */ INLINE const TextProperties &PGEntry:: get_properties(int n) const { LightReMutexHolder holder(_lock); return _text.get_properties(n); } /** * Sets the current position of the cursor. This is the position within the * text at which the next letter typed by the user will be inserted; normally * it is the same as the length of the text. */ INLINE void PGEntry:: set_cursor_position(int position) { LightReMutexHolder holder(_lock); if (_cursor_position != position) { _cursor_position = position; _cursor_stale = true; _blink_start = ClockObject::get_global_clock()->get_frame_time(); } } /** * Returns the current position of the cursor. */ INLINE int PGEntry:: get_cursor_position() const { LightReMutexHolder holder(_lock); return _cursor_position; } /** * Returns the node position x of the cursor */ INLINE PN_stdfloat PGEntry:: get_cursor_X() const { LightReMutexHolder holder(_lock); return _cursor_def.get_x(); } /** * Returns the node position y of the cursor */ INLINE PN_stdfloat PGEntry:: get_cursor_Y() const { LightReMutexHolder holder(_lock); return _cursor_def.get_y(); } /** * Sets the maximum number of characters that may be typed into the entry. * This is a limit on the number of characters, as opposed to the width of the * entry; see also set_max_width(). * * If this is 0, there is no limit. */ INLINE void PGEntry:: set_max_chars(int max_chars) { LightReMutexHolder holder(_lock); _max_chars = max_chars; } /** * Returns the current maximum number of characters that may be typed into the * entry, or 0 if there is no limit. See set_max_chars(). */ INLINE int PGEntry:: get_max_chars() const { LightReMutexHolder holder(_lock); return _max_chars; } /** * Sets the maximum width of all characters that may be typed into the entry. * This is a limit on the width of the formatted text, not a fixed limit on * the number of characters; also set_max_chars(). * * If this is 0, there is no limit. * * If _num_lines is more than 1, rather than being a fixed width on the whole * entry, this becomes instead the wordwrap width (and the width limit on the * entry is essentially _max_width * _num_lines). */ INLINE void PGEntry:: set_max_width(PN_stdfloat max_width) { LightReMutexHolder holder(_lock); _max_width = max_width; _text_geom_stale = true; } /** * Returns the current maximum width of the characters that may be typed into * the entry, or 0 if there is no limit. See set_max_width(). */ INLINE PN_stdfloat PGEntry:: get_max_width() const { LightReMutexHolder holder(_lock); return _max_width; } /** * Sets the number of lines of text the PGEntry will use. This only has * meaning if _max_width is not 0; _max_width indicates the wordwrap width of * each line. */ INLINE void PGEntry:: set_num_lines(int num_lines) { LightReMutexHolder holder(_lock); nassertv(num_lines >= 1); _num_lines = num_lines; _text_geom_stale = true; update_text(); } /** * Returns the number of lines of text the PGEntry will use, if _max_width is * not 0. See set_num_lines(). */ INLINE int PGEntry:: get_num_lines() const { LightReMutexHolder holder(_lock); return _num_lines; } /** * Sets the number of times per second the cursor will blink while the entry * has keyboard focus. * * If this is 0, the cursor does not blink, but is held steady. */ INLINE void PGEntry:: set_blink_rate(PN_stdfloat blink_rate) { LightReMutexHolder holder(_lock); _blink_rate = blink_rate; } /** * Returns the number of times per second the cursor will blink, or 0 if the * cursor is not to blink. */ INLINE PN_stdfloat PGEntry:: get_blink_rate() const { LightReMutexHolder holder(_lock); return _blink_rate; } /** * Returns the Node that will be rendered to represent the cursor. You can * attach suitable cursor geometry to this node. */ INLINE NodePath PGEntry:: get_cursor_def() { LightReMutexHolder holder(_lock); return _cursor_def; } /** * Removes all the children from the cursor_def node, in preparation for * adding a new definition. */ INLINE void PGEntry:: clear_cursor_def() { LightReMutexHolder holder(_lock); _cursor_def.remove_node(); _cursor_def = _cursor_scale.attach_new_node("cursor"); } /** * Sets whether the arrow keys (and home/end) control movement of the cursor. * If true, they are active; if false, they are ignored. */ INLINE void PGEntry:: set_cursor_keys_active(bool flag) { LightReMutexHolder holder(_lock); _cursor_keys_active = flag; } /** * Returns whether the arrow keys are currently set to control movement of the * cursor; see set_cursor_keys_active(). */ INLINE bool PGEntry:: get_cursor_keys_active() const { LightReMutexHolder holder(_lock); return _cursor_keys_active; } /** * Specifies whether obscure mode should be enabled. In obscure mode, a * string of asterisks is displayed instead of the literal text, e.g. for * entering passwords. * * In obscure mode, the width of the text is computed based on the width of * the string of asterisks, not on the width of the actual text. This has * implications on the maximum length of text that may be entered if max_width * is in effect. */ INLINE void PGEntry:: set_obscure_mode(bool flag) { LightReMutexHolder holder(_lock); if (_obscure_mode != flag) { _obscure_mode = flag; _text_geom_stale = true; } } /** * Specifies whether obscure mode is enabled. See set_obscure_mode(). */ INLINE bool PGEntry:: get_obscure_mode() const { LightReMutexHolder holder(_lock); return _obscure_mode; } /** * Specifies whether overflow mode should be enabled. In overflow mode, text * can overflow the boundaries of the Entry element horizontally. * * Overflow mode only works when the number of lines is 1. */ INLINE void PGEntry:: set_overflow_mode(bool flag) { LightReMutexHolder holder(_lock); if (_overflow_mode != flag) { _overflow_mode = flag; _text_geom_stale = true; _cursor_stale = true; } } /** * Specifies whether overflow mode is enabled. See set_overflow_mode(). */ INLINE bool PGEntry:: get_overflow_mode() const { LightReMutexHolder holder(_lock); return _overflow_mode; } /** * Specifies the name of the TextProperties structure added to the * TextPropertiesManager that will be used to render candidate strings from * the IME, used for typing characters in east Asian languages. Each * candidate string represents one possible way to interpret the sequence of * keys the user has just entered; it should not be considered typed yet, but * it is important for the user to be able to see what he is considering * entering. * * This particular method sets the properties for the subset of the current * candidate string that the user can actively scroll through. */ INLINE void PGEntry:: set_candidate_active(const std::string &candidate_active) { LightReMutexHolder holder(_lock); _candidate_active = candidate_active; } /** * See set_candidate_active(). */ INLINE const std::string &PGEntry:: get_candidate_active() const { LightReMutexHolder holder(_lock); return _candidate_active; } /** * Specifies the name of the TextProperties structure added to the * TextPropertiesManager that will be used to render candidate strings from * the IME, used for typing characters in east Asian languages. Each * candidate string represents one possible way to interpret the sequence of * keys the user has just entered; it should not be considered typed yet, but * it is important for the user to be able to see what he is considering * entering. * * This particular method sets the properties for the subset of the current * candidate string that the user is not actively scrolling through. */ INLINE void PGEntry:: set_candidate_inactive(const std::string &candidate_inactive) { LightReMutexHolder holder(_lock); _candidate_inactive = candidate_inactive; } /** * See set_candidate_inactive(). */ INLINE const std::string &PGEntry:: get_candidate_inactive() const { LightReMutexHolder holder(_lock); return _candidate_inactive; } /** * Returns the prefix that is used to define the accept event for all * PGEntries. The accept event is the concatenation of this string followed * by get_id(). */ INLINE std::string PGEntry:: get_accept_prefix() { return "accept-"; } /** * Returns the prefix that is used to define the accept failed event for all * PGEntries. This event is the concatenation of this string followed by * get_id(). */ INLINE std::string PGEntry:: get_accept_failed_prefix() { return "acceptfailed-"; } /** * Returns the prefix that is used to define the overflow event for all * PGEntries. The overflow event is the concatenation of this string followed * by get_id(). */ INLINE std::string PGEntry:: get_overflow_prefix() { return "overflow-"; } /** * Returns the prefix that is used to define the type event for all PGEntries. * The type event is the concatenation of this string followed by get_id(). */ INLINE std::string PGEntry:: get_type_prefix() { return "type-"; } /** * Returns the prefix that is used to define the erase event for all * PGEntries. The erase event is the concatenation of this string followed by * get_id(). */ INLINE std::string PGEntry:: get_erase_prefix() { return "erase-"; } /** * Returns the prefix that is used to define the cursor event for all * PGEntries. The cursor event is the concatenation of this string followed * by get_id(). */ INLINE std::string PGEntry:: get_cursormove_prefix() { return "cursormove-"; } /** * Returns the event name that will be thrown when the entry is accepted * normally. */ INLINE std::string PGEntry:: get_accept_event(const ButtonHandle &button) const { return get_accept_prefix() + button.get_name() + "-" + get_id(); } /** * Returns the event name that will be thrown when the entry cannot accept an * input */ INLINE std::string PGEntry:: get_accept_failed_event(const ButtonHandle &button) const { return get_accept_failed_prefix() + button.get_name() + "-" + get_id(); } /** * Returns the event name that will be thrown when too much text is attempted * to be entered into the PGEntry, exceeding either the limit set via * set_max_chars() or via set_max_width(). */ INLINE std::string PGEntry:: get_overflow_event() const { return get_overflow_prefix() + get_id(); } /** * Returns the event name that will be thrown whenever the user extends the * text by typing. */ INLINE std::string PGEntry:: get_type_event() const { return get_type_prefix() + get_id(); } /** * Returns the event name that will be thrown whenever the user erases * characters in the text. */ INLINE std::string PGEntry:: get_erase_event() const { return get_erase_prefix() + get_id(); } /** * Returns the event name that will be thrown whenever the cursor moves */ INLINE std::string PGEntry:: get_cursormove_event() const { return get_cursormove_prefix() + get_id(); } /** * Changes the text currently displayed within the entry. * * The return value is true if all the text is accepted, or false if some was * truncated (see set_max_width(), etc.). */ INLINE bool PGEntry:: set_wtext(const std::wstring &wtext) { LightReMutexHolder holder(_lock); bool ret = _text.set_wtext(wtext); if (_obscure_mode) { ret = _obscure_text.set_wtext(std::wstring(_text.get_num_characters(), '*')); } _text_geom_stale = true; set_cursor_position(std::min(_cursor_position, _text.get_num_characters())); return ret; } /** * Returns the text currently displayed within the entry, without any embedded * properties characters. */ INLINE std::wstring PGEntry:: get_plain_wtext() const { LightReMutexHolder holder(_lock); return _text.get_plain_wtext(); } /** * Returns the text currently displayed within the entry. */ INLINE std::wstring PGEntry:: get_wtext() const { LightReMutexHolder holder(_lock); return _text.get_wtext(); } /** * Sets whether the input may be accepted--use to disable submission by the * user */ INLINE void PGEntry:: set_accept_enabled(bool enabled) { LightReMutexHolder holder(_lock); _accept_enabled = enabled; }