mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:37:35 +00:00
LibWeb: Paint positioned elements after non-positioned ones
Within the same stacking context, positioned elements must be painted after non-positioned ones. I added a Layout::Node::for_each_child_in_paint_order() to help with this since it's also needed for hit testing.
This commit is contained in:
parent
85a1bd6803
commit
c953e5d98a
3 changed files with 20 additions and 11 deletions
|
@ -106,9 +106,7 @@ HitTestResult Box::hit_test(const Gfx::IntPoint& position, HitTestType type) con
|
||||||
// parts of the layout tree, but currently we can't just check
|
// parts of the layout tree, but currently we can't just check
|
||||||
// m_rect.contains() since inline text rects can't be trusted..
|
// m_rect.contains() since inline text rects can't be trusted..
|
||||||
HitTestResult result { absolute_rect().contains(position.x(), position.y()) ? this : nullptr };
|
HitTestResult result { absolute_rect().contains(position.x(), position.y()) ? this : nullptr };
|
||||||
for_each_child([&](auto& child) {
|
for_each_child_in_paint_order([&](auto& child) {
|
||||||
if (is<Box>(child) && downcast<Box>(child).stacking_context())
|
|
||||||
return;
|
|
||||||
auto child_result = child.hit_test(position, type);
|
auto child_result = child.hit_test(position, type);
|
||||||
if (child_result.layout_node)
|
if (child_result.layout_node)
|
||||||
result = child_result;
|
result = child_result;
|
||||||
|
|
|
@ -93,9 +93,7 @@ void Node::paint(PaintContext& context, PaintPhase phase)
|
||||||
|
|
||||||
before_children_paint(context, phase);
|
before_children_paint(context, phase);
|
||||||
|
|
||||||
for_each_child([&](auto& child) {
|
for_each_child_in_paint_order([&](auto& child) {
|
||||||
if (child.is_box() && downcast<Box>(child).stacking_context())
|
|
||||||
return;
|
|
||||||
child.paint(context, phase);
|
child.paint(context, phase);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -105,11 +103,7 @@ void Node::paint(PaintContext& context, PaintPhase phase)
|
||||||
HitTestResult Node::hit_test(const Gfx::IntPoint& position, HitTestType type) const
|
HitTestResult Node::hit_test(const Gfx::IntPoint& position, HitTestType type) const
|
||||||
{
|
{
|
||||||
HitTestResult result;
|
HitTestResult result;
|
||||||
for_each_child([&](auto& child) {
|
for_each_child_in_paint_order([&](auto& child) {
|
||||||
// Skip over children that establish their own stacking context.
|
|
||||||
// The outer loop who called us will take care of those.
|
|
||||||
if (is<Box>(child) && downcast<Box>(child).stacking_context())
|
|
||||||
return;
|
|
||||||
auto child_result = child.hit_test(position, type);
|
auto child_result = child.hit_test(position, type);
|
||||||
if (child_result.layout_node)
|
if (child_result.layout_node)
|
||||||
result = child_result;
|
result = child_result;
|
||||||
|
|
|
@ -177,6 +177,23 @@ public:
|
||||||
SelectionState selection_state() const { return m_selection_state; }
|
SelectionState selection_state() const { return m_selection_state; }
|
||||||
void set_selection_state(SelectionState state) { m_selection_state = state; }
|
void set_selection_state(SelectionState state) { m_selection_state = state; }
|
||||||
|
|
||||||
|
template<typename Callback>
|
||||||
|
void for_each_child_in_paint_order(Callback callback) const
|
||||||
|
{
|
||||||
|
for_each_child([&](auto& child) {
|
||||||
|
if (is<Box>(child) && downcast<Box>(child).stacking_context())
|
||||||
|
return;
|
||||||
|
if (!child.is_positioned())
|
||||||
|
callback(child);
|
||||||
|
});
|
||||||
|
for_each_child([&](auto& child) {
|
||||||
|
if (is<Box>(child) && downcast<Box>(child).stacking_context())
|
||||||
|
return;
|
||||||
|
if (child.is_positioned())
|
||||||
|
callback(child);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Node(DOM::Document&, DOM::Node*);
|
Node(DOM::Document&, DOM::Node*);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue