1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:07:46 +00:00

LibGUI+HackStudio: Simplify TextEditor gutter & ruler calculations

- Make gutter/ruler_content_rect() return rectangles relative to the
  TextEditor widget.
- Re-order painting code to translate the Painter after the gutter/ruler
  has been painted, to use those coordinates.
- Consistently put gutter before ruler in code, because that's the order
  they physically appear.
This commit is contained in:
Sam Atkins 2023-02-19 16:14:16 +00:00 committed by Andreas Kling
parent 3676f5085e
commit 1a5159df73
3 changed files with 32 additions and 31 deletions

View file

@ -121,7 +121,7 @@ void Editor::focusout_event(GUI::FocusEvent& event)
Gfx::IntRect Editor::gutter_icon_rect(size_t line_number) const Gfx::IntRect Editor::gutter_icon_rect(size_t line_number) const
{ {
return gutter_content_rect(line_number).translated(ruler_width() + gutter_width() + frame_thickness(), -vertical_scrollbar().value()); return gutter_content_rect(line_number).translated(frame_thickness(), 0);
} }
void Editor::paint_event(GUI::PaintEvent& event) void Editor::paint_event(GUI::PaintEvent& event)

View file

@ -2,6 +2,7 @@
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, networkException <networkexception@serenityos.org> * Copyright (c) 2021, networkException <networkexception@serenityos.org>
* Copyright (c) 2022, the SerenityOS developers. * Copyright (c) 2022, the SerenityOS developers.
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -137,7 +138,7 @@ void TextEditor::update_content_size()
content_width = max(frame_inner_rect().width(), content_width); content_width = max(frame_inner_rect().width(), content_width);
set_content_size({ content_width, content_height }); set_content_size({ content_width, content_height });
set_size_occupied_by_fixed_elements({ ruler_width() + gutter_width(), 0 }); set_size_occupied_by_fixed_elements({ gutter_width() + ruler_width(), 0 });
} }
TextPosition TextEditor::text_position_at_content_position(Gfx::IntPoint content_position) const TextPosition TextEditor::text_position_at_content_position(Gfx::IntPoint content_position) const
@ -201,7 +202,7 @@ TextPosition TextEditor::text_position_at(Gfx::IntPoint widget_position) const
{ {
auto content_position = widget_position; auto content_position = widget_position;
content_position.translate_by(horizontal_scrollbar().value(), vertical_scrollbar().value()); content_position.translate_by(horizontal_scrollbar().value(), vertical_scrollbar().value());
content_position.translate_by(-(m_horizontal_content_padding + ruler_width() + gutter_width()), 0); content_position.translate_by(-(m_horizontal_content_padding + gutter_width() + ruler_width()), 0);
content_position.translate_by(-frame_thickness(), -frame_thickness()); content_position.translate_by(-frame_thickness(), -frame_thickness());
content_position.translate_by(0, -height_occupied_by_banner_widget()); content_position.translate_by(0, -height_occupied_by_banner_widget());
return text_position_at_content_position(content_position); return text_position_at_content_position(content_position);
@ -358,33 +359,28 @@ int TextEditor::gutter_width() const
return line_height(); // square gutter return line_height(); // square gutter
} }
Gfx::IntRect TextEditor::ruler_content_rect(size_t line_index) const
{
if (!m_ruler_visible)
return {};
return {
0 - ruler_width() + horizontal_scrollbar().value(),
line_content_rect(line_index).y(),
ruler_width(),
line_content_rect(line_index).height()
};
}
Gfx::IntRect TextEditor::gutter_content_rect(size_t line_index) const Gfx::IntRect TextEditor::gutter_content_rect(size_t line_index) const
{ {
if (!m_gutter_visible) if (!m_gutter_visible)
return {}; return {};
return { return {
0 - ruler_width() - gutter_width() + horizontal_scrollbar().value(), 0,
line_content_rect(line_index).y(), line_content_rect(line_index).y() - vertical_scrollbar().value(),
gutter_width(), gutter_width(),
line_content_rect(line_index).height() line_content_rect(line_index).height()
}; };
} }
Gfx::IntRect TextEditor::ruler_rect_in_inner_coordinates() const Gfx::IntRect TextEditor::ruler_content_rect(size_t line_index) const
{ {
return { gutter_width(), 0, ruler_width(), widget_inner_rect().height() }; if (!m_ruler_visible)
return {};
return {
gutter_width(),
line_content_rect(line_index).y() - vertical_scrollbar().value(),
ruler_width(),
line_content_rect(line_index).height()
};
} }
Gfx::IntRect TextEditor::gutter_rect_in_inner_coordinates() const Gfx::IntRect TextEditor::gutter_rect_in_inner_coordinates() const
@ -392,12 +388,17 @@ Gfx::IntRect TextEditor::gutter_rect_in_inner_coordinates() const
return { 0, 0, gutter_width(), widget_inner_rect().height() }; return { 0, 0, gutter_width(), widget_inner_rect().height() };
} }
Gfx::IntRect TextEditor::ruler_rect_in_inner_coordinates() const
{
return { gutter_width(), 0, ruler_width(), widget_inner_rect().height() };
}
Gfx::IntRect TextEditor::visible_text_rect_in_inner_coordinates() const Gfx::IntRect TextEditor::visible_text_rect_in_inner_coordinates() const
{ {
return { return {
m_horizontal_content_padding + ruler_width() + gutter_width(), m_horizontal_content_padding + gutter_width() + ruler_width(),
0, 0,
frame_inner_rect().width() - (m_horizontal_content_padding * 2) - width_occupied_by_vertical_scrollbar() - ruler_width() - gutter_width(), frame_inner_rect().width() - (m_horizontal_content_padding * 2) - width_occupied_by_vertical_scrollbar() - gutter_width() + ruler_width(),
frame_inner_rect().height() - height_occupied_by_horizontal_scrollbar() frame_inner_rect().height() - height_occupied_by_horizontal_scrollbar()
}; };
} }
@ -462,13 +463,6 @@ void TextEditor::paint_event(PaintEvent& event)
painter.draw_line(ruler_rect.top_right(), ruler_rect.bottom_right(), palette().ruler_border()); painter.draw_line(ruler_rect.top_right(), ruler_rect.bottom_right(), palette().ruler_border());
} }
auto horizontal_scrollbar_value = horizontal_scrollbar().value();
painter.translate(-horizontal_scrollbar_value, -vertical_scrollbar().value());
if (m_icon && horizontal_scrollbar_value > 0)
painter.translate(min(icon_size() + icon_padding(), horizontal_scrollbar_value), 0);
painter.translate(gutter_width(), 0);
painter.translate(ruler_width(), 0);
size_t first_visible_line = text_position_at(event.rect().top_left()).line(); size_t first_visible_line = text_position_at(event.rect().top_left()).line();
size_t last_visible_line = text_position_at(event.rect().bottom_right()).line(); size_t last_visible_line = text_position_at(event.rect().bottom_right()).line();
@ -494,7 +488,13 @@ void TextEditor::paint_event(PaintEvent& event)
} }
} }
auto horizontal_scrollbar_value = horizontal_scrollbar().value();
painter.translate(-horizontal_scrollbar_value, -vertical_scrollbar().value());
if (m_icon && horizontal_scrollbar_value > 0)
painter.translate(min(icon_size() + icon_padding(), horizontal_scrollbar_value), 0);
auto gutter_ruler_width = gutter_width() + ruler_width(); auto gutter_ruler_width = gutter_width() + ruler_width();
painter.translate(gutter_ruler_width, 0);
Gfx::IntRect text_clip_rect { 0, 0, widget_inner_rect().width() - gutter_ruler_width, widget_inner_rect().height() }; Gfx::IntRect text_clip_rect { 0, 0, widget_inner_rect().width() - gutter_ruler_width, widget_inner_rect().height() };
text_clip_rect.translate_by(horizontal_scrollbar().value(), vertical_scrollbar().value()); text_clip_rect.translate_by(horizontal_scrollbar().value(), vertical_scrollbar().value());
painter.add_clip_rect(text_clip_rect); painter.add_clip_rect(text_clip_rect);

View file

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, the SerenityOS developers. * Copyright (c) 2022, the SerenityOS developers.
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -264,15 +265,15 @@ protected:
virtual void resize_event(ResizeEvent&) override; virtual void resize_event(ResizeEvent&) override;
virtual void theme_change_event(ThemeChangeEvent&) override; virtual void theme_change_event(ThemeChangeEvent&) override;
virtual void cursor_did_change(); virtual void cursor_did_change();
Gfx::IntRect ruler_content_rect(size_t line) const;
Gfx::IntRect gutter_content_rect(size_t line) const; Gfx::IntRect gutter_content_rect(size_t line) const;
Gfx::IntRect ruler_content_rect(size_t line) const;
TextPosition text_position_at(Gfx::IntPoint) const; TextPosition text_position_at(Gfx::IntPoint) const;
bool ruler_visible() const { return m_ruler_visible; } bool ruler_visible() const { return m_ruler_visible; }
bool gutter_visible() const { return m_gutter_visible; } bool gutter_visible() const { return m_gutter_visible; }
Gfx::IntRect content_rect_for_position(TextPosition const&) const; Gfx::IntRect content_rect_for_position(TextPosition const&) const;
int ruler_width() const;
int gutter_width() const; int gutter_width() const;
int ruler_width() const;
virtual void highlighter_did_set_spans(Vector<TextDocumentSpan> spans) final { document().set_spans(Syntax::HighlighterClient::span_collection_index, move(spans)); } virtual void highlighter_did_set_spans(Vector<TextDocumentSpan> spans) final { document().set_spans(Syntax::HighlighterClient::span_collection_index, move(spans)); }
@ -346,8 +347,8 @@ private:
Gfx::IntRect line_widget_rect(size_t line_index) const; Gfx::IntRect line_widget_rect(size_t line_index) const;
void delete_selection(); void delete_selection();
int content_x_for_position(TextPosition const&) const; int content_x_for_position(TextPosition const&) const;
Gfx::IntRect ruler_rect_in_inner_coordinates() const;
Gfx::IntRect gutter_rect_in_inner_coordinates() const; Gfx::IntRect gutter_rect_in_inner_coordinates() const;
Gfx::IntRect ruler_rect_in_inner_coordinates() const;
Gfx::IntRect visible_text_rect_in_inner_coordinates() const; Gfx::IntRect visible_text_rect_in_inner_coordinates() const;
void recompute_all_visual_lines(); void recompute_all_visual_lines();
void ensure_cursor_is_valid(); void ensure_cursor_is_valid();