mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-04 07:31:16 +00:00 
			
		
		
		
	TextEdit respects content margin from StyleBox
Now TextEdit adjusts x & y offset according to the corresponding StyleBox when in normal or read-only mode. In order to handle bottom content margin, wrapped lines that are entirely outside the stylebox content area are not drawn.
This commit is contained in:
		
							parent
							
								
									68624f32b0
								
							
						
					
					
						commit
						100fc26f39
					
				
					 1 changed files with 35 additions and 10 deletions
				
			
		| 
						 | 
					@ -977,6 +977,16 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int top_limit_y = 0;
 | 
				
			||||||
 | 
								int bottom_limit_y = get_size().height;
 | 
				
			||||||
 | 
								if (readonly) {
 | 
				
			||||||
 | 
									top_limit_y += cache.style_readonly->get_margin(SIDE_TOP);
 | 
				
			||||||
 | 
									bottom_limit_y -= cache.style_readonly->get_margin(SIDE_BOTTOM);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									top_limit_y += cache.style_normal->get_margin(SIDE_TOP);
 | 
				
			||||||
 | 
									bottom_limit_y -= cache.style_normal->get_margin(SIDE_BOTTOM);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// draw main text
 | 
								// draw main text
 | 
				
			||||||
			int row_height = get_row_height();
 | 
								int row_height = get_row_height();
 | 
				
			||||||
			int line = first_visible_line;
 | 
								int line = first_visible_line;
 | 
				
			||||||
| 
						 | 
					@ -1019,17 +1029,33 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
					const String &str = wrap_rows[line_wrap_index];
 | 
										const String &str = wrap_rows[line_wrap_index];
 | 
				
			||||||
					int char_margin = xmargin_beg - cursor.x_ofs;
 | 
										int char_margin = xmargin_beg - cursor.x_ofs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					int ofs_readonly = 0;
 | 
					 | 
				
			||||||
					int ofs_x = 0;
 | 
										int ofs_x = 0;
 | 
				
			||||||
 | 
										int ofs_y = 0;
 | 
				
			||||||
					if (readonly) {
 | 
										if (readonly) {
 | 
				
			||||||
						ofs_readonly = cache.style_readonly->get_offset().y / 2;
 | 
					 | 
				
			||||||
						ofs_x = cache.style_readonly->get_offset().x / 2;
 | 
											ofs_x = cache.style_readonly->get_offset().x / 2;
 | 
				
			||||||
 | 
											ofs_x -= cache.style_normal->get_offset().x / 2;
 | 
				
			||||||
 | 
											ofs_y = cache.style_readonly->get_offset().y / 2;
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											ofs_y = cache.style_normal->get_offset().y / 2;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					int ofs_y = (i * row_height + cache.line_spacing / 2) + ofs_readonly;
 | 
										ofs_y += i * row_height + cache.line_spacing / 2;
 | 
				
			||||||
					ofs_y -= cursor.wrap_ofs * row_height;
 | 
										ofs_y -= cursor.wrap_ofs * row_height;
 | 
				
			||||||
					ofs_y -= get_v_scroll_offset() * row_height;
 | 
										ofs_y -= get_v_scroll_offset() * row_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										bool clipped = false;
 | 
				
			||||||
 | 
										if (ofs_y + row_height < top_limit_y) {
 | 
				
			||||||
 | 
											// Line is outside the top margin, clip current line.
 | 
				
			||||||
 | 
											// Still need to go through the process to prepare color changes for next lines.
 | 
				
			||||||
 | 
											clipped = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (ofs_y > bottom_limit_y) {
 | 
				
			||||||
 | 
											// Line is outside the bottom margin, clip any remaining text.
 | 
				
			||||||
 | 
											i = draw_amount;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (text.is_marked(line)) {
 | 
										if (text.is_marked(line)) {
 | 
				
			||||||
						if (rtl) {
 | 
											if (rtl) {
 | 
				
			||||||
							RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), cache.mark_color);
 | 
												RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), cache.mark_color);
 | 
				
			||||||
| 
						 | 
					@ -1147,7 +1173,7 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
						char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x;
 | 
											char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection
 | 
										if (!clipped && selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection
 | 
				
			||||||
						int sel_from = (line > selection.from_line) ? TS->shaped_text_get_range(rid).x : selection.from_column;
 | 
											int sel_from = (line > selection.from_line) ? TS->shaped_text_get_range(rid).x : selection.from_column;
 | 
				
			||||||
						int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column;
 | 
											int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column;
 | 
				
			||||||
						Vector<Vector2> sel = TS->shaped_text_get_selection(rid, sel_from, sel_to);
 | 
											Vector<Vector2> sel = TS->shaped_text_get_selection(rid, sel_from, sel_to);
 | 
				
			||||||
| 
						 | 
					@ -1167,7 +1193,7 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					int start = TS->shaped_text_get_range(rid).x;
 | 
										int start = TS->shaped_text_get_range(rid).x;
 | 
				
			||||||
					if (!search_text.is_empty()) { // Search highhlight
 | 
										if (!clipped && !search_text.is_empty()) { // Search highhlight
 | 
				
			||||||
						int search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0);
 | 
											int search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0);
 | 
				
			||||||
						while (search_text_col != -1) {
 | 
											while (search_text_col != -1) {
 | 
				
			||||||
							Vector<Vector2> sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text.length() + start);
 | 
												Vector<Vector2> sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text.length() + start);
 | 
				
			||||||
| 
						 | 
					@ -1190,7 +1216,7 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight
 | 
										if (!clipped && highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight
 | 
				
			||||||
						int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
 | 
											int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
 | 
				
			||||||
						while (highlighted_text_col != -1) {
 | 
											while (highlighted_text_col != -1) {
 | 
				
			||||||
							Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text.length() + start);
 | 
												Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text.length() + start);
 | 
				
			||||||
| 
						 | 
					@ -1212,7 +1238,7 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word
 | 
										if (!clipped && select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word
 | 
				
			||||||
						if (_is_char(highlighted_word[0]) || highlighted_word[0] == '.') {
 | 
											if (_is_char(highlighted_word[0]) || highlighted_word[0] == '.') {
 | 
				
			||||||
							int highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
 | 
												int highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
 | 
				
			||||||
							while (highlighted_word_col != -1) {
 | 
												while (highlighted_word_col != -1) {
 | 
				
			||||||
| 
						 | 
					@ -1297,7 +1323,7 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						for (int k = 0; k < glyphs[j].repeat; k++) {
 | 
											for (int k = 0; k < glyphs[j].repeat; k++) {
 | 
				
			||||||
							if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
 | 
												if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
 | 
				
			||||||
								if (glyphs[j].font_rid != RID()) {
 | 
													if (glyphs[j].font_rid != RID()) {
 | 
				
			||||||
									TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color);
 | 
														TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color);
 | 
				
			||||||
								} else if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
 | 
													} else if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
 | 
				
			||||||
| 
						 | 
					@ -1327,7 +1353,7 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
					int caret_width = 1;
 | 
										int caret_width = 1;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
					if (cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) {
 | 
										if (!clipped && cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) {
 | 
				
			||||||
						is_cursor_line_visible = true;
 | 
											is_cursor_line_visible = true;
 | 
				
			||||||
						cursor_pos.y = line_top_offset_y;
 | 
											cursor_pos.y = line_top_offset_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1444,7 +1470,6 @@ void TextEdit::_notification(int p_what) {
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					ofs_y += ldata->get_line_descent(line_wrap_index);
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue