Jelajahi Sumber

Fix LineEdit and TextEdit double-click and triple-click selection

jmb462 4 tahun lalu
induk
melakukan
3f0fe0b8a3
3 mengubah file dengan 14 tambahan dan 7 penghapusan
  1. 9 4
      scene/gui/line_edit.cpp
  2. 3 1
      scene/gui/line_edit.h
  3. 2 2
      scene/gui/text_edit.cpp

+ 9 - 4
scene/gui/line_edit.cpp

@@ -260,24 +260,29 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
 
 			} else {
 				if (selecting_enabled) {
-					if (!b->is_double_click() && (OS::get_singleton()->get_ticks_msec() - selection.last_dblclk) < 600) {
+					const int triple_click_timeout = 600;
+					const int triple_click_tolerance = 5;
+					const bool is_triple_click = !b->is_double_click() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < triple_click_timeout && b->get_position().distance_to(last_dblclk_pos) < triple_click_tolerance;
+
+					if (is_triple_click && text.length()) {
 						// Triple-click select all.
 						selection.enabled = true;
 						selection.begin = 0;
 						selection.end = text.length();
 						selection.double_click = true;
-						selection.last_dblclk = 0;
+						last_dblclk = 0;
 						caret_column = selection.begin;
 					} else if (b->is_double_click()) {
 						// Double-click select word.
+						last_dblclk = OS::get_singleton()->get_ticks_msec();
+						last_dblclk_pos = b->get_position();
 						Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
 						for (int i = 0; i < words.size(); i++) {
-							if (words[i].x < caret_column && words[i].y > caret_column) {
+							if ((words[i].x < caret_column && words[i].y > caret_column) || (i == words.size() - 1 && caret_column == words[i].y)) {
 								selection.enabled = true;
 								selection.begin = words[i].x;
 								selection.end = words[i].y;
 								selection.double_click = true;
-								selection.last_dblclk = OS::get_singleton()->get_ticks_msec();
 								caret_column = selection.end;
 								break;
 							}

+ 3 - 1
scene/gui/line_edit.h

@@ -136,7 +136,6 @@ private:
 		bool creating = false;
 		bool double_click = false;
 		bool drag_attempt = false;
-		uint64_t last_dblclk = 0;
 	} selection;
 
 	struct TextOperation {
@@ -153,6 +152,9 @@ private:
 		bool pressing_inside = false;
 	} clear_button_status;
 
+	uint64_t last_dblclk = 0;
+	Vector2 last_dblclk_pos;
+
 	bool caret_blink_enabled = false;
 	bool caret_force_displayed = false;
 	bool draw_caret = true;

+ 2 - 2
scene/gui/text_edit.cpp

@@ -3689,7 +3689,7 @@ void TextEdit::select_word_under_caret() {
 	int end = 0;
 	const Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
 	for (int i = 0; i < words.size(); i++) {
-		if (words[i].x <= caret.column && words[i].y >= caret.column) {
+		if ((words[i].x < caret.column && words[i].y > caret.column) || (i == words.size() - 1 && caret.column == words[i].y)) {
 			begin = words[i].x;
 			end = words[i].y;
 			break;
@@ -5411,7 +5411,7 @@ void TextEdit::_update_selection_mode_word() {
 	int end = beg;
 	Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
 	for (int i = 0; i < words.size(); i++) {
-		if (words[i].x < caret_pos && words[i].y > caret_pos) {
+		if ((words[i].x < caret_pos && words[i].y > caret_pos) || (i == words.size() - 1 && caret_pos == words[i].y)) {
 			beg = words[i].x;
 			end = words[i].y;
 			break;