Browse Source

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.
Andreas Kling 6 năm trước cách đây
mục cha
commit
ce35cddb1b
4 tập tin đã thay đổi với 36 bổ sung17 xóa
  1. 19 8
      LibGUI/GTextEditor.cpp
  2. 7 5
      LibGUI/GTextEditor.h
  3. 9 4
      SharedGraphics/Painter.cpp
  4. 1 0
      SharedGraphics/Painter.h

+ 19 - 8
LibGUI/GTextEditor.cpp

@@ -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();
 }

+ 7 - 5
LibGUI/GTextEditor.h

@@ -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();

+ 9 - 4
SharedGraphics/Painter.cpp

@@ -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;

+ 1 - 0
SharedGraphics/Painter.h

@@ -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);