2
0
Эх сурвалжийг харах

Merge pull request #14973 from poke1024/docs-word-selection

Double-click word selection for RichTextLabel (i.e. docs)
Noshyaar 7 жил өмнө
parent
commit
a6328011d8

+ 34 - 0
core/ustring.cpp

@@ -56,6 +56,40 @@
 #define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
 #define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
 #define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
 #define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
 
 
+bool is_symbol(CharType c) {
+	return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' ');
+}
+
+bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
+
+	const String &s = p_s;
+	int beg = CLAMP(p_col, 0, s.length());
+	int end = beg;
+
+	if (s[beg] > 32 || beg == s.length()) {
+
+		bool symbol = beg < s.length() && is_symbol(s[beg]);
+
+		while (beg > 0 && s[beg - 1] > 32 && (symbol == is_symbol(s[beg - 1]))) {
+			beg--;
+		}
+		while (end < s.length() && s[end + 1] > 32 && (symbol == is_symbol(s[end + 1]))) {
+			end++;
+		}
+
+		if (end < s.length())
+			end += 1;
+
+		r_beg = beg;
+		r_end = end;
+
+		return true;
+	} else {
+
+		return false;
+	}
+}
+
 /** STRING **/
 /** STRING **/
 
 
 bool CharString::operator<(const CharString &p_right) const {
 bool CharString::operator<(const CharString &p_right) const {

+ 3 - 0
core/ustring.h

@@ -318,4 +318,7 @@ String TTR(const String &);
 //tool or regular translate
 //tool or regular translate
 String RTR(const String &);
 String RTR(const String &);
 
 
+bool is_symbol(CharType c);
+bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end);
+
 #endif
 #endif

+ 1 - 1
editor/editor_help.cpp

@@ -613,7 +613,7 @@ void EditorHelp::_class_desc_input(const Ref<InputEvent> &p_input) {
 
 
 	Ref<InputEventMouseButton> mb = p_input;
 	Ref<InputEventMouseButton> mb = p_input;
 
 
-	if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == 1) {
+	if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == 1 && !mb->is_doubleclick()) {
 		class_desc->set_selection_enabled(false);
 		class_desc->set_selection_enabled(false);
 		class_desc->set_selection_enabled(true);
 		class_desc->set_selection_enabled(true);
 	}
 	}

+ 28 - 0
scene/gui/rich_text_label.cpp

@@ -815,7 +815,35 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
 							}
 							}
 						}
 						}
 					}
 					}
+				} else if (b->is_pressed() && b->is_doubleclick() && selection.enabled) {
 
 
+					//doubleclick: select word
+					int line = 0;
+					Item *item = NULL;
+					bool outside;
+
+					_find_click(main, b->get_position(), &item, &line, &outside);
+
+					while (item && item->type != ITEM_TEXT) {
+
+						item = _get_next_item(item, true);
+					}
+
+					if (item && item->type == ITEM_TEXT) {
+
+						String itext = static_cast<ItemText *>(item)->text;
+
+						int beg, end;
+						if (select_word(itext, line, beg, end)) {
+
+							selection.from = item;
+							selection.to = item;
+							selection.from_char = beg;
+							selection.to_char = end - 1;
+							selection.active = true;
+							update();
+						}
+					}
 				} else if (!b->is_pressed()) {
 				} else if (!b->is_pressed()) {
 
 
 					selection.click = NULL;
 					selection.click = NULL;

+ 9 - 37
scene/gui/text_edit.cpp

@@ -42,14 +42,14 @@
 
 
 #define TAB_PIXELS
 #define TAB_PIXELS
 
 
-static bool _is_text_char(CharType c) {
+inline bool _is_symbol(CharType c) {
 
 
-	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
+	return is_symbol(c);
 }
 }
 
 
-static bool _is_symbol(CharType c) {
+static bool _is_text_char(CharType c) {
 
 
-	return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' ');
+	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
 }
 }
 
 
 static bool _is_whitespace(CharType c) {
 static bool _is_whitespace(CharType c) {
@@ -1956,7 +1956,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
 
 
 				} else if (mb->is_doubleclick() && text[cursor.line].length()) {
 				} else if (mb->is_doubleclick() && text[cursor.line].length()) {
 
 
-					//doubleclick select world
+					//doubleclick select word
 					selection.selecting_mode = Selection::MODE_WORD;
 					selection.selecting_mode = Selection::MODE_WORD;
 					_update_selection_mode_word();
 					_update_selection_mode_word();
 					last_dblclk = OS::get_singleton()->get_ticks_msec();
 					last_dblclk = OS::get_singleton()->get_ticks_msec();
@@ -5212,12 +5212,8 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
 	String s = text[row];
 	String s = text[row];
 	if (s.length() == 0)
 	if (s.length() == 0)
 		return "";
 		return "";
-	int beg = CLAMP(col, 0, s.length());
-	int end = beg;
-
-	if (s[beg] > 32 || beg == s.length()) {
-
-		bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
+	int beg, end;
+	if (select_word(s, col, beg, end)) {
 
 
 		bool inside_quotes = false;
 		bool inside_quotes = false;
 		int qbegin = 0, qend = 0;
 		int qbegin = 0, qend = 0;
@@ -5236,16 +5232,6 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
 			}
 			}
 		}
 		}
 
 
-		while (beg > 0 && s[beg - 1] > 32 && (symbol == _is_symbol(s[beg - 1]))) {
-			beg--;
-		}
-		while (end < s.length() && s[end + 1] > 32 && (symbol == _is_symbol(s[end + 1]))) {
-			end++;
-		}
-
-		if (end < s.length())
-			end += 1;
-
 		return s.substr(beg, end - beg);
 		return s.substr(beg, end - beg);
 	}
 	}
 
 
@@ -5262,22 +5248,8 @@ String TextEdit::get_tooltip(const Point2 &p_pos) const {
 	String s = text[row];
 	String s = text[row];
 	if (s.length() == 0)
 	if (s.length() == 0)
 		return Control::get_tooltip(p_pos);
 		return Control::get_tooltip(p_pos);
-	int beg = CLAMP(col, 0, s.length());
-	int end = beg;
-
-	if (s[beg] > 32 || beg == s.length()) {
-
-		bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
-
-		while (beg > 0 && s[beg - 1] > 32 && (symbol == _is_symbol(s[beg - 1]))) {
-			beg--;
-		}
-		while (end < s.length() && s[end + 1] > 32 && (symbol == _is_symbol(s[end + 1]))) {
-			end++;
-		}
-
-		if (end < s.length())
-			end += 1;
+	int beg, end;
+	if (select_word(s, col, beg, end)) {
 
 
 		String tt = tooltip_obj->call(tooltip_func, s.substr(beg, end - beg), tooltip_ud);
 		String tt = tooltip_obj->call(tooltip_func, s.substr(beg, end - beg), tooltip_ud);