浏览代码

GTextEditor: Add GTextEditor::on_change callback for when content changes.

Andreas Kling 6 年之前
父节点
当前提交
151b7149e6
共有 2 个文件被更改,包括 24 次插入6 次删除
  1. 21 6
      LibGUI/GTextEditor.cpp
  2. 3 0
      LibGUI/GTextEditor.h

+ 21 - 6
LibGUI/GTextEditor.cpp

@@ -33,6 +33,7 @@ void GTextEditor::set_text(const String& text)
     if (is_single_line() && text.length() == m_lines[0]->length() && !memcmp(text.characters(), m_lines[0]->characters(), text.length()))
     if (is_single_line() && text.length() == m_lines[0]->length() && !memcmp(text.characters(), m_lines[0]->characters(), text.length()))
         return;
         return;
 
 
+    m_selection.clear();
     m_lines.clear();
     m_lines.clear();
     int start_of_current_line = 0;
     int start_of_current_line = 0;
 
 
@@ -414,8 +415,8 @@ void GTextEditor::do_delete()
     if (m_cursor.column() < current_line().length()) {
     if (m_cursor.column() < current_line().length()) {
         // Delete within line
         // Delete within line
         current_line().remove(m_cursor.column());
         current_line().remove(m_cursor.column());
-        update_content_size();
         update_cursor();
         update_cursor();
+        did_change();
         return;
         return;
     }
     }
     if (m_cursor.column() == current_line().length() && m_cursor.line() != line_count() - 1) {
     if (m_cursor.column() == current_line().length() && m_cursor.line() != line_count() - 1) {
@@ -424,9 +425,9 @@ void GTextEditor::do_delete()
         int previous_length = current_line().length();
         int previous_length = current_line().length();
         current_line().append(next_line.characters(), next_line.length());
         current_line().append(next_line.characters(), next_line.length());
         m_lines.remove(m_cursor.line() + 1);
         m_lines.remove(m_cursor.line() + 1);
-        update_content_size();
         update();
         update();
         set_cursor(m_cursor.line(), previous_length);
         set_cursor(m_cursor.line(), previous_length);
+        did_change();
         return;
         return;
     }
     }
 }
 }
@@ -451,18 +452,18 @@ void GTextEditor::insert_at_cursor(char ch)
         }
         }
         if (at_tail || at_head) {
         if (at_tail || at_head) {
             m_lines.insert(m_cursor.line() + (at_tail ? 1 : 0), make<Line>());
             m_lines.insert(m_cursor.line() + (at_tail ? 1 : 0), make<Line>());
-            update_content_size();
             update();
             update();
             set_cursor(m_cursor.line() + 1, 0);
             set_cursor(m_cursor.line() + 1, 0);
+            did_change();
             return;
             return;
         }
         }
         auto new_line = make<Line>();
         auto new_line = make<Line>();
         new_line->append(current_line().characters() + m_cursor.column(), current_line().length() - m_cursor.column());
         new_line->append(current_line().characters() + m_cursor.column(), current_line().length() - m_cursor.column());
         current_line().truncate(m_cursor.column());
         current_line().truncate(m_cursor.column());
         m_lines.insert(m_cursor.line() + 1, move(new_line));
         m_lines.insert(m_cursor.line() + 1, move(new_line));
-        update_content_size();
         update();
         update();
         set_cursor(m_cursor.line() + 1, 0);
         set_cursor(m_cursor.line() + 1, 0);
+        did_change();
         return;
         return;
     }
     }
     if (ch == '\t') {
     if (ch == '\t') {
@@ -471,15 +472,15 @@ void GTextEditor::insert_at_cursor(char ch)
         for (int i = 0; i < spaces_to_insert; ++i) {
         for (int i = 0; i < spaces_to_insert; ++i) {
             current_line().insert(m_cursor.column(), ' ');
             current_line().insert(m_cursor.column(), ' ');
         }
         }
-        update_content_size();
         set_cursor(m_cursor.line(), next_soft_tab_stop);
         set_cursor(m_cursor.line(), next_soft_tab_stop);
         update_cursor();
         update_cursor();
+        did_change();
         return;
         return;
     }
     }
     current_line().insert(m_cursor.column(), ch);
     current_line().insert(m_cursor.column(), ch);
-    update_content_size();
     set_cursor(m_cursor.line(), m_cursor.column() + 1);
     set_cursor(m_cursor.line(), m_cursor.column() + 1);
     update_cursor();
     update_cursor();
+    did_change();
 }
 }
 
 
 Rect GTextEditor::cursor_content_rect() const
 Rect GTextEditor::cursor_content_rect() const
@@ -772,6 +773,7 @@ void GTextEditor::delete_selection()
     m_selection.clear();
     m_selection.clear();
     set_cursor(selection.start());
     set_cursor(selection.start());
     update();
     update();
+    did_change();
 }
 }
 
 
 void GTextEditor::insert_at_cursor_or_replace_selection(const String& text)
 void GTextEditor::insert_at_cursor_or_replace_selection(const String& text)
@@ -814,3 +816,16 @@ void GTextEditor::leave_event(GEvent&)
     ASSERT(window());
     ASSERT(window());
     window()->set_override_cursor(GStandardCursor::None);
     window()->set_override_cursor(GStandardCursor::None);
 }
 }
+
+void GTextEditor::did_change()
+{
+    update_content_size();
+    if (!m_have_pending_change_notification) {
+        m_have_pending_change_notification = true;
+        deferred_invoke([this] (auto&) {
+            if (on_change)
+                on_change();
+            m_have_pending_change_notification = false;
+        });
+    }
+}

+ 3 - 0
LibGUI/GTextEditor.h

@@ -96,6 +96,7 @@ public:
     void do_delete();
     void do_delete();
     void delete_current_line();
     void delete_current_line();
 
 
+    Function<void()> on_change;
     Function<void(GTextEditor&)> on_return_pressed;
     Function<void(GTextEditor&)> on_return_pressed;
     Function<void(GTextEditor&)> on_escape_pressed;
     Function<void(GTextEditor&)> on_escape_pressed;
 
 
@@ -116,6 +117,7 @@ private:
 
 
     void paint_ruler(Painter&);
     void paint_ruler(Painter&);
     void update_content_size();
     void update_content_size();
+    void did_change();
 
 
     class Line {
     class Line {
         friend class GTextEditor;
         friend class GTextEditor;
@@ -163,6 +165,7 @@ private:
     bool m_cursor_state { true };
     bool m_cursor_state { true };
     bool m_in_drag_select { false };
     bool m_in_drag_select { false };
     bool m_ruler_visible { true };
     bool m_ruler_visible { true };
+    bool m_have_pending_change_notification { false };
     int m_line_spacing { 4 };
     int m_line_spacing { 4 };
     int m_soft_tab_width { 4 };
     int m_soft_tab_width { 4 };
     int m_horizontal_content_padding { 2 };
     int m_horizontal_content_padding { 2 };