LibWeb/Painting: Paint flexbox inspector overlays
This commit is contained in:
parent
d465a5f32f
commit
5b2c649eda
5 changed files with 149 additions and 0 deletions
|
|
@ -674,6 +674,8 @@ void Document::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(m_hovered_node);
|
||||
visitor.visit(m_inspected_node);
|
||||
visitor.visit(m_highlighted_node);
|
||||
for (auto const& flexbox_highlight : m_flexbox_highlights)
|
||||
visitor.visit(flexbox_highlight.node);
|
||||
for (auto const& grid_highlight : m_grid_highlights)
|
||||
visitor.visit(grid_highlight.node);
|
||||
visitor.visit(m_active_favicon);
|
||||
|
|
@ -2671,6 +2673,44 @@ void Document::set_grid_highlighted_node(GC::Ptr<Node> node, Painting::GridInspe
|
|||
node->set_needs_repaint();
|
||||
}
|
||||
|
||||
void Document::set_flexbox_highlighted_node(GC::Ptr<Node> node, Painting::FlexboxInspectorOverlayOptions options)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
for (auto& flexbox_highlight : m_flexbox_highlights) {
|
||||
if (flexbox_highlight.node != node)
|
||||
continue;
|
||||
|
||||
flexbox_highlight.options = options;
|
||||
node->set_needs_repaint();
|
||||
return;
|
||||
}
|
||||
|
||||
m_flexbox_highlights.append({ node, options });
|
||||
node->set_needs_repaint();
|
||||
}
|
||||
|
||||
void Document::clear_flexbox_highlighted_node(GC::Ptr<Node> node)
|
||||
{
|
||||
if (!node) {
|
||||
for (auto const& flexbox_highlight : m_flexbox_highlights) {
|
||||
if (flexbox_highlight.node)
|
||||
flexbox_highlight.node->set_needs_repaint();
|
||||
}
|
||||
m_flexbox_highlights.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
auto old_size = m_flexbox_highlights.size();
|
||||
m_flexbox_highlights.remove_all_matching([&](auto const& flexbox_highlight) {
|
||||
return flexbox_highlight.node == node;
|
||||
});
|
||||
|
||||
if (m_flexbox_highlights.size() != old_size)
|
||||
node->set_needs_repaint();
|
||||
}
|
||||
|
||||
void Document::clear_grid_highlighted_node(GC::Ptr<Node> node)
|
||||
{
|
||||
if (!node) {
|
||||
|
|
@ -8375,6 +8415,16 @@ RefPtr<Painting::DisplayList> Document::record_display_list(HTML::PaintConfig co
|
|||
highlighted_node()->paintable()->paint_inspector_overlay(context);
|
||||
}
|
||||
|
||||
for (auto const& flexbox_highlight : m_flexbox_highlights) {
|
||||
if (!flexbox_highlight.node)
|
||||
continue;
|
||||
auto paintable = flexbox_highlight.node->paintable();
|
||||
auto const* paintable_box = as_if<Painting::PaintableBox>(paintable.ptr());
|
||||
if (!paintable_box)
|
||||
continue;
|
||||
paintable_box->paint_flexbox_inspector_overlay(context, flexbox_highlight.options);
|
||||
}
|
||||
|
||||
for (auto const& grid_highlight : m_grid_highlights) {
|
||||
if (!grid_highlight.node)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include <LibWeb/HTML/SessionHistoryEntry.h>
|
||||
#include <LibWeb/HTML/VisibilityState.h>
|
||||
#include <LibWeb/InvalidateDisplayList.h>
|
||||
#include <LibWeb/Painting/FlexboxInspectorOverlay.h>
|
||||
#include <LibWeb/Painting/GridInspectorOverlay.h>
|
||||
#include <LibWeb/ResizeObserver/ResizeObserver.h>
|
||||
#include <LibWeb/TrustedTypes/InjectionSink.h>
|
||||
|
|
@ -308,6 +309,8 @@ public:
|
|||
GC::Ptr<Node const> highlighted_node() const { return m_highlighted_node; }
|
||||
GC::Ptr<Layout::Node> highlighted_layout_node();
|
||||
GC::Ptr<Layout::Node const> highlighted_layout_node() const { return const_cast<Document*>(this)->highlighted_layout_node(); }
|
||||
void set_flexbox_highlighted_node(GC::Ptr<Node>, Painting::FlexboxInspectorOverlayOptions);
|
||||
void clear_flexbox_highlighted_node(GC::Ptr<Node>);
|
||||
void set_grid_highlighted_node(GC::Ptr<Node>, Painting::GridInspectorOverlayOptions);
|
||||
void clear_grid_highlighted_node(GC::Ptr<Node>);
|
||||
|
||||
|
|
@ -1214,6 +1217,13 @@ private:
|
|||
GC::Ptr<Node> node;
|
||||
Painting::GridInspectorOverlayOptions options;
|
||||
};
|
||||
|
||||
struct FlexboxHighlight {
|
||||
GC::Ptr<Node> node;
|
||||
Painting::FlexboxInspectorOverlayOptions options;
|
||||
};
|
||||
|
||||
Vector<FlexboxHighlight> m_flexbox_highlights;
|
||||
Vector<GridHighlight> m_grid_highlights;
|
||||
|
||||
Optional<Color> m_normal_link_color;
|
||||
|
|
|
|||
17
Libraries/LibWeb/Painting/FlexboxInspectorOverlay.h
Normal file
17
Libraries/LibWeb/Painting/FlexboxInspectorOverlay.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Ladybird contributors
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGfx/Color.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
struct FlexboxInspectorOverlayOptions {
|
||||
Gfx::Color color { 148, 0, 255 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
#include <LibWeb/Painting/ChromeMetrics.h>
|
||||
#include <LibWeb/Painting/DisplayListRecorder.h>
|
||||
#include <LibWeb/Painting/DisplayListRecordingContext.h>
|
||||
#include <LibWeb/Painting/FlexboxInspectorOverlay.h>
|
||||
#include <LibWeb/Painting/GridInspectorOverlay.h>
|
||||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
#include <LibWeb/Painting/ResizeHandle.h>
|
||||
|
|
@ -1320,6 +1321,75 @@ void PaintableBox::paint_grid_inspector_overlay(DisplayListRecordingContext& con
|
|||
});
|
||||
}
|
||||
|
||||
void PaintableBox::paint_flexbox_inspector_overlay(DisplayListRecordingContext& context, FlexboxInspectorOverlayOptions const& options) const
|
||||
{
|
||||
if (!m_flex_layout_data)
|
||||
return;
|
||||
|
||||
paint_with_inspector_overlay_context(context, [&] {
|
||||
auto content_rect = absolute_united_content_rect();
|
||||
auto const origin = content_rect.location();
|
||||
auto const viewport_rect = document().viewport_rect();
|
||||
auto const& color = options.color;
|
||||
auto line_color = color.with_alpha(220);
|
||||
auto container_fill_color = color.with_alpha(28);
|
||||
auto line_fill_color = color.with_alpha(18);
|
||||
auto item_fill_color = color.with_alpha(32);
|
||||
auto line_thickness = CSSPixels(1);
|
||||
auto main_axis_is_horizontal = m_flex_layout_data->flex_direction == CSS::FlexDirection::Row
|
||||
|| m_flex_layout_data->flex_direction == CSS::FlexDirection::RowReverse;
|
||||
|
||||
auto paint_rect = [&](CSSPixelRect const& rect, Gfx::Color rect_color) {
|
||||
auto visible_rect = rect.intersected(viewport_rect);
|
||||
if (visible_rect.is_empty())
|
||||
return;
|
||||
context.display_list_recorder().fill_rect(context.enclosing_device_rect(visible_rect).to_type<int>(), rect_color);
|
||||
};
|
||||
|
||||
auto paint_outline = [&](CSSPixelRect const& rect, Gfx::Color rect_color) {
|
||||
auto visible_rect = rect.intersected(viewport_rect);
|
||||
if (visible_rect.is_empty())
|
||||
return;
|
||||
context.display_list_recorder().draw_rect(context.enclosing_device_rect(visible_rect).to_type<int>(), rect_color);
|
||||
};
|
||||
|
||||
paint_rect(content_rect, container_fill_color);
|
||||
paint_outline(content_rect, line_color);
|
||||
|
||||
for (auto const& line : m_flex_layout_data->lines) {
|
||||
auto line_rect = main_axis_is_horizontal
|
||||
? CSSPixelRect { content_rect.x(), origin.y() + line.cross_start, content_rect.width(), line.cross_size }
|
||||
: CSSPixelRect { origin.x() + line.cross_start, content_rect.y(), line.cross_size, content_rect.height() };
|
||||
|
||||
paint_rect(line_rect, line_fill_color);
|
||||
paint_outline(line_rect, line_color);
|
||||
|
||||
for (auto const& item : line.items) {
|
||||
auto item_rect = item.rect.translated(origin);
|
||||
paint_rect(item_rect, item_fill_color);
|
||||
paint_outline(item_rect, line_color);
|
||||
}
|
||||
}
|
||||
|
||||
// Repaint the container border last so adjacent flex lines and items do not obscure it.
|
||||
paint_outline(content_rect, line_color);
|
||||
|
||||
if (main_axis_is_horizontal) {
|
||||
for (auto const& line : m_flex_layout_data->lines) {
|
||||
auto y = origin.y() + line.cross_start;
|
||||
paint_rect({ content_rect.x(), y, content_rect.width(), line_thickness }, line_color);
|
||||
paint_rect({ content_rect.x(), y + line.cross_size, content_rect.width(), line_thickness }, line_color);
|
||||
}
|
||||
} else {
|
||||
for (auto const& line : m_flex_layout_data->lines) {
|
||||
auto x = origin.x() + line.cross_start;
|
||||
paint_rect({ x, content_rect.y(), line_thickness, content_rect.height() }, line_color);
|
||||
paint_rect({ x + line.cross_size, content_rect.y(), line_thickness, content_rect.height() }, line_color);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void PaintableBox::set_stacking_context(NonnullRefPtr<StackingContext> stacking_context)
|
||||
{
|
||||
m_stacking_context = move(stacking_context);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
namespace Web::Painting {
|
||||
|
||||
struct FlexboxInspectorOverlayOptions;
|
||||
struct GridInspectorOverlayOptions;
|
||||
class ResizeHandle;
|
||||
class Scrollbar;
|
||||
|
|
@ -283,6 +284,7 @@ public:
|
|||
Layout::GridLayoutData const* grid_layout_data() const { return m_grid_layout_data.ptr(); }
|
||||
void set_flex_layout_data(OwnPtr<Layout::FlexLayoutData> flex_layout_data) { m_flex_layout_data = move(flex_layout_data); }
|
||||
Layout::FlexLayoutData const* flex_layout_data() const { return m_flex_layout_data.ptr(); }
|
||||
void paint_flexbox_inspector_overlay(DisplayListRecordingContext&, FlexboxInspectorOverlayOptions const&) const;
|
||||
void paint_grid_inspector_overlay(DisplayListRecordingContext&, GridInspectorOverlayOptions const&) const;
|
||||
|
||||
void set_enclosing_scroll_frame_index(ScrollFrameIndex index) { m_enclosing_scroll_frame_index = index; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue