Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a caret width editor setting #58700

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Calinou
Copy link
Member

@Calinou Calinou commented Mar 2, 2022

Follow-up to #54956.

This can be used to improve caret visibility in LineEdits and TextEdits used by the editor (including the script editor).

For reference, Windows 10 allows increasing the caret width up to 20:

image

However, I limited the setting to 6 as Godot does not draw an inverted version of the character behind the caret. This makes large caret sizes not very useful to have.

Note: For this to be backported to 3.x, #54956 needs to be backported first.
WIP 3.x backport: https://github.com/Calinou/godot/tree/editor-add-caret-width-setting-3.x

Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

caret_width is also used for mid-grapheme caret indicator (6 * width line on top of caret, to indicate caret position is not praise) and IME input underline carets (1 * width and 3 * width).
Screenshot 2022-03-03 at 08 44 50
Screenshot 2022-03-03 at 08 46 59
Underlines probably should not be affected by the settings, and mid-grapheme indicator probably should use the width of the grapheme.

Also, for the large caret width, should we adjust caret position to center?
Like this:
Screenshot 2022-03-03 at 08 42 40
instead of this:
Screenshot 2022-03-03 at 08 52 37
I'm not sure which is better.

Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this:

diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index c17469a815..f5418c5981 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -868,7 +868,8 @@ void LineEdit::_notification(int p_what) {
 					} else {
 						if (caret.l_caret != Rect2() && caret.l_dir == TextServer::DIRECTION_AUTO) {
 							// Draw extra marker on top of mid caret.
-							Rect2 trect = Rect2(caret.l_caret.position.x - 3 * caret_width, caret.l_caret.position.y, 6 * caret_width, caret_width);
+							Size2 gr_bounds = TS->shaped_text_get_grapheme_bounds(text_rid, caret_column);
+							Rect2 trect = Rect2(gr_bounds.x, caret.l_caret.position.y, gr_bounds.y - gr_bounds.x, get_theme_default_base_scale());
 							trect.position += ofs;
 							RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
 						}
@@ -897,7 +898,7 @@ void LineEdit::_notification(int p_what) {
 							} else if (rect.position.x + rect.size.x > ofs_max) {
 								rect.size.x = ofs_max - rect.position.x;
 							}
-							rect.size.y = caret_width;
+							rect.size.y = get_theme_default_base_scale();
 							RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, caret_color);
 						}
 					}
@@ -915,7 +916,7 @@ void LineEdit::_notification(int p_what) {
 							} else if (rect.position.x + rect.size.x > ofs_max) {
 								rect.size.x = ofs_max - rect.position.x;
 							}
-							rect.size.y = caret_width * 3;
+							rect.size.y = 3 * get_theme_default_base_scale();
 							RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, caret_color);
 						}
 					}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 7e5ae5cf6a..16800107b6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1298,10 +1298,10 @@ void TextEdit::_notification(int p_what) {
 								int h = font->get_height(font_size);
 								if (rtl) {
 									ts_caret.l_dir = TextServer::DIRECTION_RTL;
-									ts_caret.l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h));
+									ts_caret.l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(4 * get_theme_default_base_scale(), h));
 								} else {
 									ts_caret.l_dir = TextServer::DIRECTION_LTR;
-									ts_caret.l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h));
+									ts_caret.l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(4 * get_theme_default_base_scale(), h));
 								}
 							}
 
@@ -1339,19 +1339,19 @@ void TextEdit::_notification(int p_what) {
 												// Adjust for actual line dimensions.
 												if (overtype_mode) {
 													ts_caret.l_caret.position.y = TS->shaped_text_get_descent(rid);
-													ts_caret.l_caret.size.y = caret_width;
+													ts_caret.l_caret.size.y = get_theme_default_base_scale();
 												} else {
 													ts_caret.l_caret.position.y = -TS->shaped_text_get_ascent(rid);
 													ts_caret.l_caret.size.y = h;
 												}
 											} else if (overtype_mode) {
 												ts_caret.l_caret.position.y += ts_caret.l_caret.size.y;
-												ts_caret.l_caret.size.y = caret_width;
+												ts_caret.l_caret.size.y = get_theme_default_base_scale();
 											}
 											if (ts_caret.l_caret.position.x >= TS->shaped_text_get_size(rid).x) {
 												ts_caret.l_caret.size.x = font->get_char_size('m', 0, font_size).x;
 											} else {
-												ts_caret.l_caret.size.x = 3 * caret_width;
+												ts_caret.l_caret.size.x = 3 * get_theme_default_base_scale();
 											}
 											ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
 											if (ts_caret.l_dir == TextServer::DIRECTION_RTL) {
@@ -1363,7 +1363,8 @@ void TextEdit::_notification(int p_what) {
 										// Normal caret.
 										if (ts_caret.l_caret != Rect2() && ts_caret.l_dir == TextServer::DIRECTION_AUTO) {
 											// Draw extra marker on top of mid caret.
-											Rect2 trect = Rect2(ts_caret.l_caret.position.x - 3 * caret_width, ts_caret.l_caret.position.y, 6 * caret_width, caret_width);
+											Size2 gr_bounds = TS->shaped_text_get_grapheme_bounds(rid, caret.column);
+											Rect2 trect = Rect2(gr_bounds.x, caret.l_caret.position.y, gr_bounds.y - gr_bounds.x, get_theme_default_base_scale());
 											trect.position += Vector2(char_margin + ofs_x, ofs_y);
 											RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
 										}
@@ -1394,7 +1395,7 @@ void TextEdit::_notification(int p_what) {
 									} else if (rect.position.x + rect.size.x > xmargin_end) {
 										rect.size.x = xmargin_end - rect.position.x;
 									}
-									rect.size.y = caret_width;
+									rect.size.y = get_theme_default_base_scale();
 									draw_rect(rect, caret_color);
 									caret.draw_pos.x = rect.position.x;
 								}
@@ -1413,7 +1414,7 @@ void TextEdit::_notification(int p_what) {
 									} else if (rect.position.x + rect.size.x > xmargin_end) {
 										rect.size.x = xmargin_end - rect.position.x;
 									}
-									rect.size.y = caret_width * 3;
+									rect.size.y = 3 * get_theme_default_base_scale();
 									draw_rect(rect, caret_color);
 									caret.draw_pos.x = rect.position.x;
 								}

For TextEdit block caret height, it might be worth adding an extra setting.

@YuriSizov YuriSizov modified the milestones: 4.0, 4.1 Feb 9, 2023
@YuriSizov YuriSizov modified the milestones: 4.1, 4.2 Jun 14, 2023
@Calinou
Copy link
Member Author

Calinou commented Jul 17, 2023

Something like this:

I've tried to apply this patch on master, but in text_edit.cpp, caret.column is undefined:

In file included from scene/gui/scu/scu_scene_gui_5.gen.cpp:7:
./scene/gui/text_edit.cpp: In member function 'void TextEdit::_notification(int)':
./scene/gui/text_edit.cpp:1414:156: error: 'caret' was not declared in this scope; did you mean 'Caret'?
 1414 |                                                                                                 Size2 gr_bounds = TS->shaped_text_get_grapheme_bounds(rid, caret.column);
      |                                                                                                                                                            ^~~~~
      |                                                                                                                                                            Caret

This can be used to improve caret visibility in LineEdits and TextEdits
used by the editor (including the script editor).

In the process, LineEdit and TextEdit's IME markers were made so that
they're no longer affected by the caret width theme constant.
@Calinou Calinou force-pushed the editor-add-caret-width-setting branch from 57ba7bc to 21553b5 Compare July 17, 2023 08:49
@Calinou Calinou requested a review from a team as a code owner July 17, 2023 08:49
@AThousandShips AThousandShips modified the milestones: 4.2, 4.3 Oct 26, 2023
@akien-mga akien-mga modified the milestones: 4.3, 4.x Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants