summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Base/res/themes/Basalt.ini2
-rw-r--r--Base/res/themes/Coffee.ini2
-rw-r--r--Base/res/themes/Dark.ini2
-rw-r--r--Base/res/themes/Default.ini2
-rw-r--r--Base/res/themes/Desert.ini2
-rw-r--r--Base/res/themes/Faux Pas.ini2
-rw-r--r--Base/res/themes/Light.ini2
-rw-r--r--Base/res/themes/Nord.ini2
-rw-r--r--Base/res/themes/Plum.ini2
-rw-r--r--Base/res/themes/Redmond 2000.ini2
-rw-r--r--Base/res/themes/Redmond.ini2
-rw-r--r--Base/res/themes/Silver.ini2
-rw-r--r--Base/res/themes/Sunshine.ini2
-rw-r--r--Userland/DevTools/HackStudio/Editor.cpp22
-rw-r--r--Userland/DevTools/HackStudio/Editor.h2
-rw-r--r--Userland/Libraries/LibGUI/TextEditor.cpp66
-rw-r--r--Userland/Libraries/LibGUI/TextEditor.h8
-rw-r--r--Userland/Libraries/LibGfx/Palette.h2
-rw-r--r--Userland/Libraries/LibGfx/SystemTheme.h2
19 files changed, 103 insertions, 25 deletions
diff --git a/Base/res/themes/Basalt.ini b/Base/res/themes/Basalt.ini
index 5c2be3d4e8..794c36d861 100644
--- a/Base/res/themes/Basalt.ini
+++ b/Base/res/themes/Basalt.ini
@@ -47,6 +47,8 @@ Link=#88c
ActiveLink=#c88
VisitedLink=#c8c
PlaceholderText=#171717
+Gutter=#0f0f0f
+GutterBorder=#2f2f2f
Ruler=#0f0f0f
RulerBorder=#2f2f2f
RulerActiveText=white
diff --git a/Base/res/themes/Coffee.ini b/Base/res/themes/Coffee.ini
index 19f3c37a4c..ccbaaff429 100644
--- a/Base/res/themes/Coffee.ini
+++ b/Base/res/themes/Coffee.ini
@@ -43,6 +43,8 @@ RubberBandBorder=#594fbf
Link=#0000ff
ActiveLink=#ee0000
VisitedLink=#551a8b
+Gutter=#aeb2c3
+GutterBorder=#5d6069
Ruler=#aeb2c3
RulerBorder=#5d6069
RulerActiveText=#5d6069
diff --git a/Base/res/themes/Dark.ini b/Base/res/themes/Dark.ini
index 18233c1448..44b8c54bfd 100644
--- a/Base/res/themes/Dark.ini
+++ b/Base/res/themes/Dark.ini
@@ -39,6 +39,8 @@ Link=#88c
ActiveLink=#c88
VisitedLink=#c8c
PlaceholderText=#2e2f30
+Gutter=#505050
+GutterBorder=#666666
Ruler=#505050
RulerBorder=#666666
RulerActiveText=white
diff --git a/Base/res/themes/Default.ini b/Base/res/themes/Default.ini
index 096ec148d8..c628317c77 100644
--- a/Base/res/themes/Default.ini
+++ b/Base/res/themes/Default.ini
@@ -47,6 +47,8 @@ RubberBandBorder=#6e2209
Link=blue
ActiveLink=red
VisitedLink=magenta
+Gutter=#d4d0c8
+GutterBorder=#404040
Ruler=#d4d0c8
RulerBorder=#404040
RulerActiveText=#404040
diff --git a/Base/res/themes/Desert.ini b/Base/res/themes/Desert.ini
index 5e4c3b8507..42233375d9 100644
--- a/Base/res/themes/Desert.ini
+++ b/Base/res/themes/Desert.ini
@@ -47,6 +47,8 @@ RubberBandBorder=#6e2209
Link=blue
ActiveLink=red
VisitedLink=magenta
+Gutter=#d5ccbb
+GutterBorder=#404040
Ruler=#d5ccbb
RulerBorder=#404040
RulerActiveText=#404040
diff --git a/Base/res/themes/Faux Pas.ini b/Base/res/themes/Faux Pas.ini
index 463f301e5b..b5c19639ce 100644
--- a/Base/res/themes/Faux Pas.ini
+++ b/Base/res/themes/Faux Pas.ini
@@ -39,6 +39,8 @@ RubberBandBorder=black
Link=#0000b0
ActiveLink=#2020d0
VisitedLink=#2000b0
+Gutter=#808080
+GutterBorder=black
Ruler=#808080
RulerBorder=black
RulerActiveText=#404040
diff --git a/Base/res/themes/Light.ini b/Base/res/themes/Light.ini
index c3a294c4e3..8a55d0bcb4 100644
--- a/Base/res/themes/Light.ini
+++ b/Base/res/themes/Light.ini
@@ -47,6 +47,8 @@ RubberBandBorder=#598dc6
Link=blue
ActiveLink=red
VisitedLink=magenta
+Gutter=#d4d0c8
+GutterBorder=#404040
Ruler=#d4d0c8
RulerBorder=#404040
RulerActiveText=#404040
diff --git a/Base/res/themes/Nord.ini b/Base/res/themes/Nord.ini
index d28b7eb246..693a85e86f 100644
--- a/Base/res/themes/Nord.ini
+++ b/Base/res/themes/Nord.ini
@@ -39,6 +39,8 @@ RubberBandBorder=#4c566a
Link=#7e9dbc
ActiveLink=#95adc5
VisitedLink=#3b4e68
+Gutter=#434c5e
+GutterBorder=#3b4252
Ruler=#434c5e
RulerBorder=#3b4252
RulerActiveText=#95adc5
diff --git a/Base/res/themes/Plum.ini b/Base/res/themes/Plum.ini
index 7726f244a8..4c11a21435 100644
--- a/Base/res/themes/Plum.ini
+++ b/Base/res/themes/Plum.ini
@@ -47,6 +47,8 @@ RubberBandBorder=#50096e
Link=blue
ActiveLink=red
VisitedLink=magenta
+Gutter=#d4d0c8
+GutterBorder=#404040
Ruler=#d4d0c8
RulerBorder=#404040
RulerActiveText=#404040
diff --git a/Base/res/themes/Redmond 2000.ini b/Base/res/themes/Redmond 2000.ini
index fa94580974..e12ae2f2de 100644
--- a/Base/res/themes/Redmond 2000.ini
+++ b/Base/res/themes/Redmond 2000.ini
@@ -43,6 +43,8 @@ RubberBandBorder=#09226e
Link=blue
ActiveLink=red
VisitedLink=magenta
+Gutter=#d4d0c8
+GutterBorder=#404040
Ruler=#d4d0c8
RulerBorder=#404040
RulerActiveText=#404040
diff --git a/Base/res/themes/Redmond.ini b/Base/res/themes/Redmond.ini
index 7fc008ed1b..7125974d61 100644
--- a/Base/res/themes/Redmond.ini
+++ b/Base/res/themes/Redmond.ini
@@ -43,6 +43,8 @@ RubberBandBorder=black
Link=blue
ActiveLink=red
VisitedLink=magenta
+Gutter=#d4d0c8
+GutterBorder=#404040
Ruler=#d4d0c8
RulerBorder=#404040
RulerActiveText=#404040
diff --git a/Base/res/themes/Silver.ini b/Base/res/themes/Silver.ini
index 6c1a4f1804..d9bf711e17 100644
--- a/Base/res/themes/Silver.ini
+++ b/Base/res/themes/Silver.ini
@@ -39,6 +39,8 @@ RubberBandBorder=#6e2209
Link=blue
ActiveLink=red
VisitedLink=magenta
+Gutter=#d4d0c8
+GutterBorder=#404040
Ruler=#d4d0c8
RulerBorder=#404040
RulerActiveText=#404040
diff --git a/Base/res/themes/Sunshine.ini b/Base/res/themes/Sunshine.ini
index 08c03795ec..1107247823 100644
--- a/Base/res/themes/Sunshine.ini
+++ b/Base/res/themes/Sunshine.ini
@@ -43,6 +43,8 @@ RubberBandBorder=#007f7f
Link=#88c
ActiveLink=#c88
VisitedLink=#c8c
+Gutter=#aeb2c3
+GutterBorder=#5d6069
Ruler=#aeb2c3
RulerBorder=#5d6069
RulerActiveText=#5d6069
diff --git a/Userland/DevTools/HackStudio/Editor.cpp b/Userland/DevTools/HackStudio/Editor.cpp
index cd3a3a61b0..0ae83188e7 100644
--- a/Userland/DevTools/HackStudio/Editor.cpp
+++ b/Userland/DevTools/HackStudio/Editor.cpp
@@ -66,6 +66,8 @@ Editor::Editor()
});
add_custom_context_menu_action(*m_evaluate_expression_action);
add_custom_context_menu_action(*m_move_execution_to_line_action);
+
+ set_gutter_visible(true);
}
Editor::~Editor()
@@ -95,15 +97,9 @@ void Editor::focusout_event(GUI::FocusEvent& event)
GUI::TextEditor::focusout_event(event);
}
-Gfx::IntRect Editor::breakpoint_icon_rect(size_t line_number) const
+Gfx::IntRect Editor::gutter_icon_rect(size_t line_number) const
{
- auto ruler_line_rect = ruler_content_rect(line_number);
-
- auto scroll_value = vertical_scrollbar().value();
- ruler_line_rect = ruler_line_rect.translated({ 0, -scroll_value });
- auto center = ruler_line_rect.center().translated({ ruler_line_rect.width() - 10, -line_spacing() - 3 });
- constexpr int size = 32;
- return { center.x() - size / 2, center.y() - size / 2, size, size };
+ return gutter_content_rect(line_number).translated(ruler_width() + gutter_width() + frame_thickness(), -vertical_scrollbar().value());
}
void Editor::paint_event(GUI::PaintEvent& event)
@@ -122,7 +118,7 @@ void Editor::paint_event(GUI::PaintEvent& event)
painter.draw_rect(rect, palette().selection());
}
- if (ruler_visible()) {
+ if (gutter_visible()) {
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();
for (size_t line : breakpoint_lines()) {
@@ -130,11 +126,11 @@ void Editor::paint_event(GUI::PaintEvent& event)
continue;
}
const auto& icon = breakpoint_icon_bitmap();
- painter.blit(breakpoint_icon_rect(line).center(), icon, icon.rect());
+ painter.blit(gutter_icon_rect(line).top_left(), icon, icon.rect());
}
if (execution_position().has_value()) {
const auto& icon = current_position_icon_bitmap();
- painter.blit(breakpoint_icon_rect(execution_position().value()).center(), icon, icon.rect());
+ painter.blit(gutter_icon_rect(execution_position().value()).top_left(), icon, icon.rect());
}
}
}
@@ -379,7 +375,7 @@ void Editor::set_execution_position(size_t line_number)
{
code_document().set_execution_position(line_number);
scroll_position_into_view({ line_number, 0 });
- update(breakpoint_icon_rect(line_number));
+ update(gutter_icon_rect(line_number));
}
void Editor::clear_execution_position()
@@ -389,7 +385,7 @@ void Editor::clear_execution_position()
}
size_t previous_position = execution_position().value();
code_document().clear_execution_position();
- update(breakpoint_icon_rect(previous_position));
+ update(gutter_icon_rect(previous_position));
}
const Gfx::Bitmap& Editor::breakpoint_icon_bitmap()
diff --git a/Userland/DevTools/HackStudio/Editor.h b/Userland/DevTools/HackStudio/Editor.h
index 036287f97b..be66ca7839 100644
--- a/Userland/DevTools/HackStudio/Editor.h
+++ b/Userland/DevTools/HackStudio/Editor.h
@@ -68,7 +68,7 @@ private:
void on_navigatable_link_click(const GUI::TextDocumentSpan&);
void on_identifier_click(const GUI::TextDocumentSpan&);
- Gfx::IntRect breakpoint_icon_rect(size_t line_number) const;
+ Gfx::IntRect gutter_icon_rect(size_t line_number) const;
static const Gfx::Bitmap& breakpoint_icon_bitmap();
static const Gfx::Bitmap& current_position_icon_bitmap();
diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp
index cd475d994c..5801d9185a 100644
--- a/Userland/Libraries/LibGUI/TextEditor.cpp
+++ b/Userland/Libraries/LibGUI/TextEditor.cpp
@@ -127,7 +127,7 @@ void TextEditor::update_content_size()
content_width = max(frame_inner_rect().width(), content_width);
set_content_size({ content_width, content_height });
- set_size_occupied_by_fixed_elements({ ruler_width(), 0 });
+ set_size_occupied_by_fixed_elements({ ruler_width() + gutter_width(), 0 });
}
TextPosition TextEditor::text_position_at_content_position(const Gfx::IntPoint& content_position) const
@@ -195,7 +195,7 @@ TextPosition TextEditor::text_position_at(const Gfx::IntPoint& widget_position)
{
auto content_position = widget_position;
content_position.translate_by(horizontal_scrollbar().value(), vertical_scrollbar().value());
- content_position.translate_by(-(m_horizontal_content_padding + ruler_width()), 0);
+ content_position.translate_by(-(m_horizontal_content_padding + ruler_width() + gutter_width()), 0);
content_position.translate_by(-frame_thickness(), -frame_thickness());
return text_position_at_content_position(content_position);
}
@@ -339,10 +339,17 @@ int TextEditor::ruler_width() const
if (!m_ruler_visible)
return 0;
int line_count_digits = static_cast<int>(log10(line_count())) + 1;
- constexpr size_t padding = 20;
+ constexpr size_t padding = 5;
return line_count() < 10 ? (line_count_digits + 1) * font().glyph_width('x') + padding : line_count_digits * font().glyph_width('x') + padding;
}
+int TextEditor::gutter_width() const
+{
+ if (!m_gutter_visible)
+ return 0;
+ return line_height(); // square gutter
+}
+
Gfx::IntRect TextEditor::ruler_content_rect(size_t line_index) const
{
if (!m_ruler_visible)
@@ -355,9 +362,26 @@ Gfx::IntRect TextEditor::ruler_content_rect(size_t line_index) const
};
}
+Gfx::IntRect TextEditor::gutter_content_rect(size_t line_index) const
+{
+ if (!m_gutter_visible)
+ return {};
+ return {
+ 0 - ruler_width() - gutter_width() + horizontal_scrollbar().value(),
+ line_content_rect(line_index).y(),
+ gutter_width(),
+ line_content_rect(line_index).height()
+ };
+}
+
Gfx::IntRect TextEditor::ruler_rect_in_inner_coordinates() const
{
- return { 0, 0, ruler_width(), height() - height_occupied_by_horizontal_scrollbar() };
+ return { gutter_width(), 0, ruler_width(), height() - height_occupied_by_horizontal_scrollbar() };
+}
+
+Gfx::IntRect TextEditor::gutter_rect_in_inner_coordinates() const
+{
+ return { 0, 0, gutter_width(), height() - height_occupied_by_horizontal_scrollbar() };
}
Gfx::IntRect TextEditor::visible_text_rect_in_inner_coordinates() const
@@ -398,16 +422,22 @@ void TextEditor::paint_event(PaintEvent& event)
painter.translate(frame_thickness(), frame_thickness());
- auto ruler_rect = ruler_rect_in_inner_coordinates();
+ if (m_gutter_visible) {
+ auto gutter_rect = gutter_rect_in_inner_coordinates();
+ painter.fill_rect(gutter_rect, palette().gutter());
+ if (!m_ruler_visible)
+ painter.draw_line(gutter_rect.top_right(), gutter_rect.bottom_right(), palette().gutter_border());
+ }
if (m_ruler_visible) {
+ auto ruler_rect = ruler_rect_in_inner_coordinates();
painter.fill_rect(ruler_rect, palette().ruler());
painter.draw_line(ruler_rect.top_right(), ruler_rect.bottom_right(), palette().ruler_border());
}
painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value());
- if (m_ruler_visible)
- painter.translate(ruler_width(), 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 last_visible_line = text_position_at(event.rect().bottom_right()).line();
@@ -428,14 +458,19 @@ void TextEditor::paint_event(PaintEvent& event)
}
}
+ auto text_left = 0;
+ if (m_ruler_visible)
+ text_left = ruler_rect_in_inner_coordinates().right() + 1;
+ else if (m_gutter_visible)
+ text_left = gutter_rect_in_inner_coordinates().right() + 1;
+ text_left += frame_thickness();
+
Gfx::IntRect text_clip_rect {
- (m_ruler_visible ? (ruler_rect_in_inner_coordinates().right() + frame_thickness() + 1) : frame_thickness()),
+ 0,
frame_thickness(),
- width() - width_occupied_by_vertical_scrollbar() - ruler_width(),
+ width() - width_occupied_by_vertical_scrollbar() - text_left,
height() - height_occupied_by_horizontal_scrollbar()
};
- if (m_ruler_visible)
- text_clip_rect.translate_by(-ruler_width(), 0);
text_clip_rect.translate_by(horizontal_scrollbar().value(), vertical_scrollbar().value());
painter.add_clip_rect(text_clip_rect);
@@ -1860,6 +1895,15 @@ void TextEditor::set_ruler_visible(bool visible)
update();
}
+void TextEditor::set_gutter_visible(bool visible)
+{
+ if (m_gutter_visible == visible)
+ return;
+ m_gutter_visible = visible;
+ recompute_all_visual_lines();
+ update();
+}
+
void TextEditor::undo()
{
clear_selection();
diff --git a/Userland/Libraries/LibGUI/TextEditor.h b/Userland/Libraries/LibGUI/TextEditor.h
index 72f6a46b5a..591bff461f 100644
--- a/Userland/Libraries/LibGUI/TextEditor.h
+++ b/Userland/Libraries/LibGUI/TextEditor.h
@@ -90,6 +90,9 @@ public:
bool is_ruler_visible() const { return m_ruler_visible; }
void set_ruler_visible(bool);
+ bool is_gutter_visible() const { return m_gutter_visible; }
+ void set_gutter_visible(bool);
+
void set_icon(const Gfx::Bitmap*);
const Gfx::Bitmap* icon() const { return m_icon; }
@@ -209,11 +212,14 @@ protected:
virtual void theme_change_event(ThemeChangeEvent&) override;
virtual void cursor_did_change() { }
Gfx::IntRect ruler_content_rect(size_t line) const;
+ Gfx::IntRect gutter_content_rect(size_t line) const;
TextPosition text_position_at(const Gfx::IntPoint&) const;
bool ruler_visible() const { return m_ruler_visible; }
+ bool gutter_visible() const { return m_gutter_visible; }
Gfx::IntRect content_rect_for_position(const TextPosition&) const;
int ruler_width() const;
+ int gutter_width() const;
private:
friend class TextDocumentLine;
@@ -272,6 +278,7 @@ private:
void delete_selection();
int content_x_for_position(const TextPosition&) const;
Gfx::IntRect ruler_rect_in_inner_coordinates() const;
+ Gfx::IntRect gutter_rect_in_inner_coordinates() const;
Gfx::IntRect visible_text_rect_in_inner_coordinates() const;
void recompute_all_visual_lines();
void ensure_cursor_is_valid();
@@ -302,6 +309,7 @@ private:
bool m_cursor_state { true };
bool m_in_drag_select { false };
bool m_ruler_visible { false };
+ bool m_gutter_visible { false };
bool m_has_pending_change_notification { false };
bool m_automatic_indentation_enabled { false };
WrappingMode m_wrapping_mode { WrappingMode::NoWrap };
diff --git a/Userland/Libraries/LibGfx/Palette.h b/Userland/Libraries/LibGfx/Palette.h
index fe4cb726fb..f60b698c76 100644
--- a/Userland/Libraries/LibGfx/Palette.h
+++ b/Userland/Libraries/LibGfx/Palette.h
@@ -92,6 +92,8 @@ public:
Color hover_highlight() const { return color(ColorRole::HoverHighlight); }
Color rubber_band_fill() const { return color(ColorRole::RubberBandFill); }
Color rubber_band_border() const { return color(ColorRole::RubberBandBorder); }
+ Color gutter() const { return color(ColorRole::Gutter); }
+ Color gutter_border() const { return color(ColorRole::Gutter); }
Color ruler() const { return color(ColorRole::Ruler); }
Color ruler_border() const { return color(ColorRole::RulerBorder); }
Color ruler_active_text() const { return color(ColorRole::RulerActiveText); }
diff --git a/Userland/Libraries/LibGfx/SystemTheme.h b/Userland/Libraries/LibGfx/SystemTheme.h
index 8c1eca5132..f155bd9a1b 100644
--- a/Userland/Libraries/LibGfx/SystemTheme.h
+++ b/Userland/Libraries/LibGfx/SystemTheme.h
@@ -27,6 +27,8 @@ namespace Gfx {
C(ButtonText) \
C(DesktopBackground) \
C(FocusOutline) \
+ C(Gutter) \
+ C(GutterBorder) \
C(HighlightWindowBorder1) \
C(HighlightWindowBorder2) \
C(HighlightWindowTitle) \