mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 11:12: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); | ||||
|         if (i == m_cursor.line() && is_focused()) | ||||
|             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) | ||||
|  | @ -176,9 +176,17 @@ void GTextEditor::keydown_event(GKeyEvent& event) | |||
|         set_cursor(line_count() - 1, m_lines[line_count() - 1].length()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (!event.text().is_empty()) | ||||
|         insert_at_cursor(event.text()[0]); | ||||
| 
 | ||||
|     return GWidget::keydown_event(event); | ||||
| } | ||||
| 
 | ||||
| void GTextEditor::insert_at_cursor(char ch) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| Rect GTextEditor::visible_content_rect() const | ||||
| { | ||||
|     return { | ||||
|  | @ -194,7 +202,7 @@ Rect GTextEditor::cursor_content_rect() const | |||
|     if (!m_cursor.is_valid()) | ||||
|         return { }; | ||||
|     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() }; | ||||
| } | ||||
| 
 | ||||
|  | @ -280,17 +288,20 @@ void GTextEditor::timer_event(GTimerEvent&) | |||
|         update_cursor(); | ||||
| } | ||||
| 
 | ||||
| GTextEditor::Line::Line() | ||||
| { | ||||
|     m_text.append(0); | ||||
| } | ||||
| 
 | ||||
| void GTextEditor::Line::set_text(const String& text) | ||||
| { | ||||
|     if (text == m_text) | ||||
|     if (text.length() == length() && !memcmp(text.characters(), characters(), length())) | ||||
|         return; | ||||
|     m_text = text; | ||||
|     m_cached_width = -1; | ||||
|     m_text.resize(text.length() + 1); | ||||
|     memcpy(m_text.data(), text.characters(), text.length() + 1); | ||||
| } | ||||
| 
 | ||||
| int GTextEditor::Line::width(const Font& font) const | ||||
| { | ||||
|     if (m_cached_width < 0) | ||||
|         m_cached_width = font.width(m_text); | ||||
|     return m_cached_width; | ||||
|     return font.glyph_width('x') * length(); | ||||
| } | ||||
|  |  | |||
|  | @ -57,18 +57,20 @@ private: | |||
|     virtual void timer_event(GTimerEvent&) override; | ||||
|     virtual bool accepts_focus() const override { return true; } | ||||
| 
 | ||||
|     void insert_at_cursor(char); | ||||
| 
 | ||||
|     class Line { | ||||
|     public: | ||||
|         Line() { } | ||||
|         Line(); | ||||
| 
 | ||||
|         String text() const { return m_text; } | ||||
|         int length() const { return m_text.length(); } | ||||
|         const char* characters() const { return m_text.data(); } | ||||
|         int length() const { return m_text.size() - 1; } | ||||
|         int width(const Font&) const; | ||||
|         void set_text(const String&); | ||||
| 
 | ||||
|     private: | ||||
|         String m_text; | ||||
|         mutable int m_cached_width { -1 }; | ||||
|         // NOTE: This vector is null terminated.
 | ||||
|         Vector<char> m_text; | ||||
|     }; | ||||
| 
 | ||||
|     void update_scrollbar_ranges(); | ||||
|  |  | |||
|  | @ -323,10 +323,10 @@ void Painter::blit(const Point& position, const GraphicsBitmap& source, const Re | |||
|     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; | ||||
|      | ||||
| 
 | ||||
|     if (alignment == TextAlignment::TopLeft) { | ||||
|         point = rect.location(); | ||||
|     } else if (alignment == TextAlignment::CenterLeft) { | ||||
|  | @ -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(); | ||||
|     for (ssize_t i = 0; i < text.length(); ++i) { | ||||
|         byte ch = text[i]; | ||||
|     for (ssize_t i = 0; i < length; ++i) { | ||||
|         char ch = text[i]; | ||||
|         if (ch == ' ') { | ||||
|             point.move_by(space_width, 0); | ||||
|             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) | ||||
| { | ||||
|     auto point = p; | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ public: | |||
|     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 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_glyph(const Point&, char, Color); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling