mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-10 18:19:03 +00:00
LibWeb: Draw a scrollbar gutter when the scrollbar is enlarged
This commit is contained in:
parent
126be42cfa
commit
66e422b4f1
Notes:
github-actions[bot]
2025-04-22 15:30:14 +00:00
Author: https://github.com/trflynn89
Commit: 66e422b4f1
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4417
7 changed files with 53 additions and 35 deletions
|
@ -403,14 +403,15 @@ struct PaintNestedDisplayList {
|
|||
};
|
||||
|
||||
struct PaintScrollBar {
|
||||
int scroll_frame_id;
|
||||
Gfx::IntRect rect;
|
||||
int scroll_frame_id { 0 };
|
||||
Gfx::IntRect gutter_rect;
|
||||
Gfx::IntRect thumb_rect;
|
||||
CSSPixelFraction scroll_size;
|
||||
bool vertical;
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset)
|
||||
{
|
||||
rect.translate_by(offset);
|
||||
thumb_rect.translate_by(offset);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -69,10 +69,10 @@ void DisplayListPlayer::execute_impl(DisplayList& display_list, ScrollStateSnaps
|
|||
auto scroll_offset = scroll_state.own_offset_for_frame_with_id(paint_scroll_bar.scroll_frame_id);
|
||||
if (paint_scroll_bar.vertical) {
|
||||
auto offset = scroll_offset.y() * paint_scroll_bar.scroll_size;
|
||||
paint_scroll_bar.rect.translate_by(0, -offset.to_int() * device_pixels_per_css_pixel);
|
||||
paint_scroll_bar.thumb_rect.translate_by(0, -offset.to_int() * device_pixels_per_css_pixel);
|
||||
} else {
|
||||
auto offset = scroll_offset.x() * paint_scroll_bar.scroll_size;
|
||||
paint_scroll_bar.rect.translate_by(-offset.to_int() * device_pixels_per_css_pixel, 0);
|
||||
paint_scroll_bar.thumb_rect.translate_by(-offset.to_int() * device_pixels_per_css_pixel, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -993,16 +993,23 @@ void DisplayListPlayerSkia::paint_nested_display_list(PaintNestedDisplayList con
|
|||
|
||||
void DisplayListPlayerSkia::paint_scrollbar(PaintScrollBar const& command)
|
||||
{
|
||||
auto rect = to_skia_rect(command.rect);
|
||||
auto radius = rect.width() / 2;
|
||||
auto rrect = SkRRect::MakeRectXY(rect, radius, radius);
|
||||
auto gutter_rect = to_skia_rect(command.gutter_rect);
|
||||
|
||||
auto thumb_rect = to_skia_rect(command.thumb_rect);
|
||||
auto radius = thumb_rect.width() / 2;
|
||||
auto thumb_rrect = SkRRect::MakeRectXY(thumb_rect, radius, radius);
|
||||
|
||||
auto& canvas = surface().canvas();
|
||||
|
||||
auto fill_color = Color(Color::NamedColor::DarkGray).with_alpha(128);
|
||||
SkPaint fill_paint;
|
||||
fill_paint.setColor(to_skia_color(fill_color));
|
||||
canvas.drawRRect(rrect, fill_paint);
|
||||
auto gutter_fill_color = Color(Color::NamedColor::WarmGray).with_alpha(192);
|
||||
SkPaint gutter_fill_paint;
|
||||
gutter_fill_paint.setColor(to_skia_color(gutter_fill_color));
|
||||
canvas.drawRect(gutter_rect, gutter_fill_paint);
|
||||
|
||||
auto thumb_fill_color = Color(Color::NamedColor::DarkGray).with_alpha(gutter_rect.isEmpty() ? 128 : 192);
|
||||
SkPaint thumb_fill_paint;
|
||||
thumb_fill_paint.setColor(to_skia_color(thumb_fill_color));
|
||||
canvas.drawRRect(thumb_rrect, thumb_fill_paint);
|
||||
|
||||
auto stroke_color = Color(Color::NamedColor::LightGray).with_alpha(128);
|
||||
SkPaint stroke_paint;
|
||||
|
@ -1010,7 +1017,7 @@ void DisplayListPlayerSkia::paint_scrollbar(PaintScrollBar const& command)
|
|||
stroke_paint.setStrokeWidth(1);
|
||||
stroke_paint.setAntiAlias(true);
|
||||
stroke_paint.setColor(to_skia_color(stroke_color));
|
||||
canvas.drawRRect(rrect, stroke_paint);
|
||||
canvas.drawRRect(thumb_rrect, stroke_paint);
|
||||
}
|
||||
|
||||
void DisplayListPlayerSkia::apply_opacity(ApplyOpacity const& command)
|
||||
|
|
|
@ -404,11 +404,12 @@ void DisplayListRecorder::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a
|
|||
.thickness = thickness });
|
||||
}
|
||||
|
||||
void DisplayListRecorder::paint_scrollbar(int scroll_frame_id, Gfx::IntRect rect, CSSPixelFraction scroll_size, bool vertical)
|
||||
void DisplayListRecorder::paint_scrollbar(int scroll_frame_id, Gfx::IntRect gutter_rect, Gfx::IntRect thumb_rect, CSSPixelFraction scroll_size, bool vertical)
|
||||
{
|
||||
append(PaintScrollBar {
|
||||
.scroll_frame_id = scroll_frame_id,
|
||||
.rect = rect,
|
||||
.gutter_rect = gutter_rect,
|
||||
.thumb_rect = thumb_rect,
|
||||
.scroll_size = scroll_size,
|
||||
.vertical = vertical });
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ public:
|
|||
|
||||
void draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness);
|
||||
|
||||
void paint_scrollbar(int scroll_frame_id, Gfx::IntRect, CSSPixelFraction scroll_size, bool vertical);
|
||||
void paint_scrollbar(int scroll_frame_id, Gfx::IntRect gutter_rect, Gfx::IntRect thumb_rect, CSSPixelFraction scroll_size, bool vertical);
|
||||
|
||||
void apply_opacity(float opacity);
|
||||
void apply_compositing_and_blending_operator(Gfx::CompositingAndBlendingOperator compositing_and_blending_operator);
|
||||
|
|
|
@ -414,16 +414,22 @@ Optional<PaintableBox::ScrollbarData> PaintableBox::compute_scrollbar_data(Scrol
|
|||
auto min_thumb_length = min(scrollbar_rect_length, 24);
|
||||
auto thumb_length = max(scrollbar_rect_length * (scrollport_size / scroll_overflow_size), min_thumb_length);
|
||||
|
||||
CSSPixelFraction scroll_size = 0;
|
||||
if (scroll_overflow_size > scrollport_size)
|
||||
scroll_size = (scrollbar_rect_length - thumb_length) / (scroll_overflow_size - scrollport_size);
|
||||
CSSPixelRect rect;
|
||||
if (is_horizontal)
|
||||
rect = { padding_rect.left(), padding_rect.bottom() - thickness, thumb_length, thickness };
|
||||
else
|
||||
rect = { padding_rect.right() - thickness, padding_rect.top(), thickness, thumb_length };
|
||||
ScrollbarData scrollbar_data;
|
||||
|
||||
return PaintableBox::ScrollbarData { rect, scroll_size };
|
||||
if (scroll_overflow_size > scrollport_size)
|
||||
scrollbar_data.scroll_length = (scrollbar_rect_length - thumb_length) / (scroll_overflow_size - scrollport_size);
|
||||
|
||||
if (is_horizontal) {
|
||||
if (m_draw_enlarged_horizontal_scrollbar)
|
||||
scrollbar_data.gutter_rect = { padding_rect.left(), padding_rect.bottom() - thickness, padding_rect.width(), thickness };
|
||||
scrollbar_data.thumb_rect = { padding_rect.left(), padding_rect.bottom() - thickness, thumb_length, thickness };
|
||||
} else {
|
||||
if (m_draw_enlarged_vertical_scrollbar)
|
||||
scrollbar_data.gutter_rect = { padding_rect.right() - thickness, padding_rect.top(), thickness, padding_rect.height() };
|
||||
scrollbar_data.thumb_rect = { padding_rect.right() - thickness, padding_rect.top(), thickness, thumb_length };
|
||||
}
|
||||
|
||||
return scrollbar_data;
|
||||
}
|
||||
|
||||
void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
|
||||
|
@ -473,15 +479,17 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
|
|||
}
|
||||
}
|
||||
|
||||
if (g_paint_viewport_scrollbars || !is_viewport()) {
|
||||
auto scrollbar_width = computed_values().scrollbar_width();
|
||||
if (phase == PaintPhase::Overlay && scrollbar_width != CSS::ScrollbarWidth::None) {
|
||||
if (phase == PaintPhase::Overlay && (g_paint_viewport_scrollbars || !is_viewport()) && computed_values().scrollbar_width() != CSS::ScrollbarWidth::None) {
|
||||
if (auto scrollbar_data = compute_scrollbar_data(ScrollDirection::Vertical); scrollbar_data.has_value()) {
|
||||
context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), context.rounded_device_rect(scrollbar_data->thumb_rect).to_type<int>(), scrollbar_data->scroll_length, true);
|
||||
auto gutter_rect = context.rounded_device_rect(scrollbar_data->gutter_rect).to_type<int>();
|
||||
auto thumb_rect = context.rounded_device_rect(scrollbar_data->thumb_rect).to_type<int>();
|
||||
context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), gutter_rect, thumb_rect, scrollbar_data->scroll_length, true);
|
||||
}
|
||||
|
||||
if (auto scrollbar_data = compute_scrollbar_data(ScrollDirection::Horizontal); scrollbar_data.has_value()) {
|
||||
context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), context.rounded_device_rect(scrollbar_data->thumb_rect).to_type<int>(), scrollbar_data->scroll_length, false);
|
||||
}
|
||||
auto gutter_rect = context.rounded_device_rect(scrollbar_data->gutter_rect).to_type<int>();
|
||||
auto thumb_rect = context.rounded_device_rect(scrollbar_data->thumb_rect).to_type<int>();
|
||||
context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), gutter_rect, thumb_rect, scrollbar_data->scroll_length, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -258,8 +258,9 @@ protected:
|
|||
virtual CSSPixelRect compute_absolute_paint_rect() const;
|
||||
|
||||
struct ScrollbarData {
|
||||
CSSPixelRect gutter_rect;
|
||||
CSSPixelRect thumb_rect;
|
||||
CSSPixelFraction scroll_length;
|
||||
CSSPixelFraction scroll_length { 0 };
|
||||
};
|
||||
enum class ScrollDirection {
|
||||
Horizontal,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue