mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 07:52:45 +00:00 
			
		
		
		
	GTextEditor: Let's use a Vector for the line backing store.
I'm eventually gonna want to replace this with something more clever, like a automagically splicing vector or something, but for now, at least we move away from immutable Strings.
This commit is contained in:
		
							parent
							
								
									a21ecd440a
								
							
						
					
					
						commit
						ce35cddb1b
					
				
					 4 changed files with 36 additions and 17 deletions
				
			
		|  | @ -112,7 +112,7 @@ void GTextEditor::paint_event(GPaintEvent& event) | ||||||
|         line_rect.set_width(exposed_width); |         line_rect.set_width(exposed_width); | ||||||
|         if (i == m_cursor.line() && is_focused()) |         if (i == m_cursor.line() && is_focused()) | ||||||
|             painter.fill_rect(line_rect, Color(230, 230, 230)); |             painter.fill_rect(line_rect, Color(230, 230, 230)); | ||||||
|         painter.draw_text(line_rect, line.text(), TextAlignment::CenterLeft, Color::Black); |         painter.draw_text(line_rect, line.characters(), line.length(), TextAlignment::CenterLeft, Color::Black); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (is_focused() && m_cursor_state) |     if (is_focused() && m_cursor_state) | ||||||
|  | @ -176,9 +176,17 @@ void GTextEditor::keydown_event(GKeyEvent& event) | ||||||
|         set_cursor(line_count() - 1, m_lines[line_count() - 1].length()); |         set_cursor(line_count() - 1, m_lines[line_count() - 1].length()); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     if (!event.text().is_empty()) | ||||||
|  |         insert_at_cursor(event.text()[0]); | ||||||
|  | 
 | ||||||
|     return GWidget::keydown_event(event); |     return GWidget::keydown_event(event); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void GTextEditor::insert_at_cursor(char ch) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Rect GTextEditor::visible_content_rect() const | Rect GTextEditor::visible_content_rect() const | ||||||
| { | { | ||||||
|     return { |     return { | ||||||
|  | @ -194,7 +202,7 @@ Rect GTextEditor::cursor_content_rect() const | ||||||
|     if (!m_cursor.is_valid()) |     if (!m_cursor.is_valid()) | ||||||
|         return { }; |         return { }; | ||||||
|     ASSERT(!m_lines.is_empty()); |     ASSERT(!m_lines.is_empty()); | ||||||
|     ASSERT(m_cursor.column() <= (current_line().text().length() + 1)); |     ASSERT(m_cursor.column() <= (current_line().length() + 1)); | ||||||
|     return { m_cursor.column() * glyph_width(), m_cursor.line() * line_height(), 1, line_height() }; |     return { m_cursor.column() * glyph_width(), m_cursor.line() * line_height(), 1, line_height() }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -280,17 +288,20 @@ void GTextEditor::timer_event(GTimerEvent&) | ||||||
|         update_cursor(); |         update_cursor(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | GTextEditor::Line::Line() | ||||||
|  | { | ||||||
|  |     m_text.append(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void GTextEditor::Line::set_text(const String& text) | void GTextEditor::Line::set_text(const String& text) | ||||||
| { | { | ||||||
|     if (text == m_text) |     if (text.length() == length() && !memcmp(text.characters(), characters(), length())) | ||||||
|         return; |         return; | ||||||
|     m_text = text; |     m_text.resize(text.length() + 1); | ||||||
|     m_cached_width = -1; |     memcpy(m_text.data(), text.characters(), text.length() + 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int GTextEditor::Line::width(const Font& font) const | int GTextEditor::Line::width(const Font& font) const | ||||||
| { | { | ||||||
|     if (m_cached_width < 0) |     return font.glyph_width('x') * length(); | ||||||
|         m_cached_width = font.width(m_text); |  | ||||||
|     return m_cached_width; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -57,18 +57,20 @@ private: | ||||||
|     virtual void timer_event(GTimerEvent&) override; |     virtual void timer_event(GTimerEvent&) override; | ||||||
|     virtual bool accepts_focus() const override { return true; } |     virtual bool accepts_focus() const override { return true; } | ||||||
| 
 | 
 | ||||||
|  |     void insert_at_cursor(char); | ||||||
|  | 
 | ||||||
|     class Line { |     class Line { | ||||||
|     public: |     public: | ||||||
|         Line() { } |         Line(); | ||||||
| 
 | 
 | ||||||
|         String text() const { return m_text; } |         const char* characters() const { return m_text.data(); } | ||||||
|         int length() const { return m_text.length(); } |         int length() const { return m_text.size() - 1; } | ||||||
|         int width(const Font&) const; |         int width(const Font&) const; | ||||||
|         void set_text(const String&); |         void set_text(const String&); | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         String m_text; |         // NOTE: This vector is null terminated.
 | ||||||
|         mutable int m_cached_width { -1 }; |         Vector<char> m_text; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     void update_scrollbar_ranges(); |     void update_scrollbar_ranges(); | ||||||
|  |  | ||||||
|  | @ -323,7 +323,7 @@ void Painter::blit(const Point& position, const GraphicsBitmap& source, const Re | ||||||
|     draw_bitmap(point, font().glyph_bitmap(ch), color); |     draw_bitmap(point, font().glyph_bitmap(ch), color); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alignment, Color color) | void Painter::draw_text(const Rect& rect, const char* text, int length, TextAlignment alignment, Color color) | ||||||
| { | { | ||||||
|     Point point; |     Point point; | ||||||
| 
 | 
 | ||||||
|  | @ -343,8 +343,8 @@ void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alig | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     int space_width = font().glyph_width(' ') + font().glyph_spacing(); |     int space_width = font().glyph_width(' ') + font().glyph_spacing(); | ||||||
|     for (ssize_t i = 0; i < text.length(); ++i) { |     for (ssize_t i = 0; i < length; ++i) { | ||||||
|         byte ch = text[i]; |         char ch = text[i]; | ||||||
|         if (ch == ' ') { |         if (ch == ' ') { | ||||||
|             point.move_by(space_width, 0); |             point.move_by(space_width, 0); | ||||||
|             continue; |             continue; | ||||||
|  | @ -354,6 +354,11 @@ void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alig | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alignment, Color color) | ||||||
|  | { | ||||||
|  |     draw_text(rect, text.characters(), text.length(), alignment, color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Painter::set_pixel(const Point& p, Color color) | void Painter::set_pixel(const Point& p, Color color) | ||||||
| { | { | ||||||
|     auto point = p; |     auto point = p; | ||||||
|  |  | ||||||
|  | @ -35,6 +35,7 @@ public: | ||||||
|     void blit(const Point&, const GraphicsBitmap&, const Rect& src_rect); |     void blit(const Point&, const GraphicsBitmap&, const Rect& src_rect); | ||||||
|     void blit_with_opacity(const Point&, const GraphicsBitmap&, const Rect& src_rect, float opacity); |     void blit_with_opacity(const Point&, const GraphicsBitmap&, const Rect& src_rect, float opacity); | ||||||
| 
 | 
 | ||||||
|  |     void draw_text(const Rect&, const char* text, int length, TextAlignment = TextAlignment::TopLeft, Color = Color()); | ||||||
|     void draw_text(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, Color = Color()); |     void draw_text(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, Color = Color()); | ||||||
|     void draw_glyph(const Point&, char, Color); |     void draw_glyph(const Point&, char, Color); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling