mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-03 23:25:20 +00:00
LibWeb: Move mouse event and label logic from layout to painting tree
Input events have nothing to do with layout, so let's not send them to layout nodes. The job of Paintable starts to become clear. It represents a paintable item that can be rendered into the viewport, which means it can also be targeted by the mouse cursor.
This commit is contained in:
@@ -27,93 +27,6 @@ RadioButton::~RadioButton()
|
||||
{
|
||||
}
|
||||
|
||||
void RadioButton::handle_mousedown(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned)
|
||||
{
|
||||
if (button != GUI::MouseButton::Primary || !dom_node().enabled())
|
||||
return;
|
||||
|
||||
m_being_pressed = true;
|
||||
set_needs_display();
|
||||
|
||||
m_tracking_mouse = true;
|
||||
browsing_context().event_handler().set_mouse_event_tracking_layout_node(this);
|
||||
}
|
||||
|
||||
void RadioButton::handle_mouseup(Badge<EventHandler>, const Gfx::IntPoint& position, unsigned button, unsigned)
|
||||
{
|
||||
if (!m_tracking_mouse || button != GUI::MouseButton::Primary || !dom_node().enabled())
|
||||
return;
|
||||
|
||||
// NOTE: Changing the checked state of the DOM node may run arbitrary JS, which could disappear this node.
|
||||
NonnullRefPtr protect = *this;
|
||||
|
||||
bool is_inside_node_or_label = enclosing_int_rect(paint_box()->absolute_rect()).contains(position);
|
||||
if (!is_inside_node_or_label)
|
||||
is_inside_node_or_label = Label::is_inside_associated_label(*this, position);
|
||||
|
||||
if (is_inside_node_or_label)
|
||||
set_checked_within_group();
|
||||
|
||||
m_being_pressed = false;
|
||||
m_tracking_mouse = false;
|
||||
browsing_context().event_handler().set_mouse_event_tracking_layout_node(nullptr);
|
||||
}
|
||||
|
||||
void RadioButton::handle_mousemove(Badge<EventHandler>, const Gfx::IntPoint& position, unsigned, unsigned)
|
||||
{
|
||||
if (!m_tracking_mouse || !dom_node().enabled())
|
||||
return;
|
||||
|
||||
bool is_inside_node_or_label = enclosing_int_rect(paint_box()->absolute_rect()).contains(position);
|
||||
if (!is_inside_node_or_label)
|
||||
is_inside_node_or_label = Label::is_inside_associated_label(*this, position);
|
||||
|
||||
if (m_being_pressed == is_inside_node_or_label)
|
||||
return;
|
||||
|
||||
m_being_pressed = is_inside_node_or_label;
|
||||
set_needs_display();
|
||||
}
|
||||
|
||||
void RadioButton::handle_associated_label_mousedown(Badge<Label>)
|
||||
{
|
||||
m_being_pressed = true;
|
||||
set_needs_display();
|
||||
}
|
||||
|
||||
void RadioButton::handle_associated_label_mouseup(Badge<Label>)
|
||||
{
|
||||
// NOTE: Changing the checked state of the DOM node may run arbitrary JS, which could disappear this node.
|
||||
NonnullRefPtr protect = *this;
|
||||
|
||||
set_checked_within_group();
|
||||
m_being_pressed = false;
|
||||
}
|
||||
|
||||
void RadioButton::handle_associated_label_mousemove(Badge<Label>, bool is_inside_node_or_label)
|
||||
{
|
||||
if (m_being_pressed == is_inside_node_or_label)
|
||||
return;
|
||||
|
||||
m_being_pressed = is_inside_node_or_label;
|
||||
set_needs_display();
|
||||
}
|
||||
|
||||
void RadioButton::set_checked_within_group()
|
||||
{
|
||||
if (dom_node().checked())
|
||||
return;
|
||||
|
||||
dom_node().set_checked(true, HTML::HTMLInputElement::ChangeSource::User);
|
||||
String name = dom_node().name();
|
||||
|
||||
document().for_each_in_inclusive_subtree_of_type<HTML::HTMLInputElement>([&](auto& element) {
|
||||
if (element.checked() && (element.layout_node() != this) && (element.name() == name))
|
||||
element.set_checked(false, HTML::HTMLInputElement::ChangeSource::User);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<Painting::Paintable> RadioButton::create_paintable() const
|
||||
{
|
||||
return Painting::RadioButtonPaintable::create(*this);
|
||||
|
||||
Reference in New Issue
Block a user