浏览代码

LibGUI+TextEditor: Add a relative line number option for TextEditor

This adds an option for displaying relative line numbers in the ruler,
the line numbers are still absolute by default.
Snow 2 年之前
父节点
当前提交
0049dfd717

+ 13 - 0
Userland/Applications/TextEditor/MainWidget.cpp

@@ -538,6 +538,19 @@ void MainWidget::initialize_menubar(GUI::Window& window)
 
     view_menu.add_action(*m_cursor_line_highlighting_action);
 
+    m_relative_line_number_action = GUI::Action::create_checkable("R&elative Line Number", [&](auto& action) {
+        m_editor->set_relative_line_number(action.is_checked());
+        Config::write_bool("TextEditor"sv, "View"sv, "RelativeLineNumber"sv, action.is_checked());
+    });
+
+    auto show_relative_line_number = Config::read_bool("TextEditor"sv, "View"sv, "RelativeLineNumber"sv, false);
+    m_relative_line_number_action->set_checked(show_relative_line_number);
+    m_editor->set_relative_line_number(show_relative_line_number);
+
+    m_relative_line_number_action->set_status_tip("Set relative line number");
+
+    view_menu.add_action(*m_relative_line_number_action);
+
     view_menu.add_separator();
     view_menu.add_action(*m_no_preview_action);
     view_menu.add_action(*m_markdown_preview_action);

+ 1 - 0
Userland/Applications/TextEditor/MainWidget.h

@@ -115,6 +115,7 @@ private:
     RefPtr<GUI::Action> m_visualize_trailing_whitespace_action;
     RefPtr<GUI::Action> m_visualize_leading_whitespace_action;
     RefPtr<GUI::Action> m_cursor_line_highlighting_action;
+    RefPtr<GUI::Action> m_relative_line_number_action;
 
     GUI::ActionGroup m_soft_tab_width_actions;
     RefPtr<GUI::Action> m_soft_tab_1_width_action;

+ 13 - 1
Userland/Libraries/LibGUI/TextEditor.cpp

@@ -488,9 +488,10 @@ void TextEditor::paint_event(PaintEvent& event)
             if (ruler_line_rect.height() > line_height)
                 ruler_line_rect.set_height(line_height);
             // NOTE: Use Painter::draw_text() directly here, as we want to always draw the line numbers in clear text.
+            size_t const line_number = is_relative_line_number() && !is_current_line ? max(i, m_cursor.line()) - min(i, m_cursor.line()) : i + 1;
             painter.draw_text(
                 ruler_line_rect.shrunken(2, 0),
-                DeprecatedString::number(i + 1),
+                DeprecatedString::number(line_number),
                 is_current_line ? font().bold_variant() : font(),
                 Gfx::TextAlignment::CenterRight,
                 is_current_line ? palette().ruler_active_text() : palette().ruler_inactive_text());
@@ -1427,6 +1428,8 @@ void TextEditor::set_cursor(TextPosition const& a_position)
         on_cursor_change();
     if (m_highlighter)
         m_highlighter->cursor_did_change();
+    if (m_relative_line_number)
+        update();
 }
 
 void TextEditor::focusin_event(FocusEvent& event)
@@ -2258,6 +2261,15 @@ int TextEditor::number_of_visible_lines() const
     return visible_content_rect().height() / line_height();
 }
 
+void TextEditor::set_relative_line_number(bool relative)
+{
+    if (m_relative_line_number == relative)
+        return;
+    m_relative_line_number = relative;
+    recompute_all_visual_lines();
+    update();
+}
+
 void TextEditor::set_ruler_visible(bool visible)
 {
     if (m_ruler_visible == visible)

+ 4 - 0
Userland/Libraries/LibGUI/TextEditor.h

@@ -97,6 +97,9 @@ public:
 
     void set_editing_cursor();
 
+    bool is_relative_line_number() const { return m_relative_line_number; }
+    void set_relative_line_number(bool);
+
     bool is_ruler_visible() const { return m_ruler_visible; }
     void set_ruler_visible(bool);
 
@@ -375,6 +378,7 @@ private:
     Gfx::TextAlignment m_text_alignment { Gfx::TextAlignment::CenterLeft };
     bool m_cursor_state { true };
     bool m_in_drag_select { false };
+    bool m_relative_line_number { false };
     bool m_ruler_visible { false };
     bool m_gutter_visible { false };
     bool m_needs_rehighlight { false };