GTextEditor.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #pragma once
  2. #include <LibGUI/GWidget.h>
  3. #include <AK/Function.h>
  4. #include <AK/HashMap.h>
  5. class GScrollBar;
  6. class GTextPosition {
  7. public:
  8. GTextPosition() { }
  9. GTextPosition(int line, int column)
  10. : m_line(line)
  11. , m_column(column)
  12. {
  13. }
  14. bool is_valid() const { return m_line >= 0 && m_column >= 0; }
  15. int line() const { return m_line; }
  16. int column() const { return m_column; }
  17. void set_line(int line) { m_line = line; }
  18. void set_column(int column) { m_column = column; }
  19. private:
  20. int m_line { -1 };
  21. int m_column { -1 };
  22. };
  23. class GTextEditor : public GWidget {
  24. public:
  25. explicit GTextEditor(GWidget* parent);
  26. virtual ~GTextEditor() override;
  27. Function<void(GTextEditor&)> on_cursor_change;
  28. void set_text(const String&);
  29. int content_width() const;
  30. int content_height() const;
  31. Rect visible_content_rect() const;
  32. void scroll_cursor_into_view();
  33. int line_count() const { return m_lines.size(); }
  34. int line_spacing() const { return m_line_spacing; }
  35. int line_height() const { return font().glyph_height() + m_line_spacing; }
  36. int padding() const { return 3; }
  37. GTextPosition cursor() const { return m_cursor; }
  38. int glyph_width() const { return font().glyph_width('x'); }
  39. private:
  40. virtual void paint_event(GPaintEvent&) override;
  41. virtual void resize_event(GResizeEvent&) override;
  42. virtual void mousedown_event(GMouseEvent&) override;
  43. virtual void keydown_event(GKeyEvent&) override;
  44. virtual void focusin_event(GEvent&) override;
  45. virtual void focusout_event(GEvent&) override;
  46. virtual void timer_event(GTimerEvent&) override;
  47. virtual bool accepts_focus() const override { return true; }
  48. void insert_at_cursor(char);
  49. class Line {
  50. public:
  51. Line();
  52. const char* characters() const { return m_text.data(); }
  53. int length() const { return m_text.size() - 1; }
  54. int width(const Font&) const;
  55. void set_text(const String&);
  56. private:
  57. // NOTE: This vector is null terminated.
  58. Vector<char> m_text;
  59. };
  60. void update_scrollbar_ranges();
  61. Rect line_content_rect(int item_index) const;
  62. Rect line_widget_rect(int line_index) const;
  63. Rect cursor_content_rect() const;
  64. void update_cursor();
  65. void set_cursor(int line, int column);
  66. Line& current_line() { return m_lines[m_cursor.line()]; }
  67. const Line& current_line() const { return m_lines[m_cursor.line()]; }
  68. GScrollBar* m_vertical_scrollbar { nullptr };
  69. GScrollBar* m_horizontal_scrollbar { nullptr };
  70. Vector<Line> m_lines;
  71. GTextPosition m_cursor;
  72. bool m_cursor_state { true };
  73. int m_line_spacing { 2 };
  74. };