2022-03-10 18:46:35 -03:00
|
|
|
/*
|
2024-10-04 08:19:50 -03:00
|
|
|
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
|
2022-03-14 20:05:55 -03:00
|
|
|
* Copyright (c) 2022, sin-ack <sin-ack@protonmail.com>
|
2022-03-10 18:46:35 -03:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
2026-01-27 08:42:33 -03:00
|
|
|
#include <LibWeb/DOM/NodeList.h>
|
2022-03-14 20:05:55 -03:00
|
|
|
#include <LibWeb/HTML/BrowsingContext.h>
|
2026-01-27 08:42:33 -03:00
|
|
|
#include <LibWeb/HTML/HTMLElement.h>
|
2025-10-16 10:07:09 -03:00
|
|
|
#include <LibWeb/HTML/Navigable.h>
|
2022-03-10 18:46:35 -03:00
|
|
|
#include <LibWeb/Painting/LabelablePaintable.h>
|
2024-06-02 14:00:42 -03:00
|
|
|
#include <LibWeb/UIEvents/MouseButton.h>
|
2022-03-10 18:46:35 -03:00
|
|
|
|
|
|
|
|
namespace Web::Painting {
|
|
|
|
|
|
2026-01-27 08:42:33 -03:00
|
|
|
static bool is_inside_associated_label(HTML::FormAssociatedElement& control, CSSPixelPoint position)
|
|
|
|
|
{
|
|
|
|
|
auto labels = control.form_associated_element_to_html_element().labels();
|
|
|
|
|
if (!labels)
|
|
|
|
|
return false;
|
|
|
|
|
for (u32 i = 0; i < labels->length(); ++i) {
|
|
|
|
|
if (auto* paintable_box = as_if<PaintableBox>(labels->item(i)->paintable())) {
|
|
|
|
|
if (paintable_box->absolute_rect().contains(position))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-14 20:05:55 -03:00
|
|
|
LabelablePaintable::LabelablePaintable(Layout::LabelableNode const& layout_node)
|
|
|
|
|
: PaintableBox(layout_node)
|
2022-03-10 18:46:35 -03:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-14 20:05:55 -03:00
|
|
|
void LabelablePaintable::set_being_pressed(bool being_pressed)
|
2022-03-10 18:46:35 -03:00
|
|
|
{
|
2022-03-14 20:05:55 -03:00
|
|
|
if (m_being_pressed == being_pressed)
|
|
|
|
|
return;
|
|
|
|
|
m_being_pressed = being_pressed;
|
|
|
|
|
set_needs_display();
|
2022-03-10 18:46:35 -03:00
|
|
|
}
|
|
|
|
|
|
2022-03-14 20:05:55 -03:00
|
|
|
Layout::FormAssociatedLabelableNode const& LabelablePaintable::layout_box() const
|
|
|
|
|
{
|
2025-10-10 09:05:30 -03:00
|
|
|
return static_cast<Layout::FormAssociatedLabelableNode const&>(layout_node());
|
2022-03-14 20:05:55 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Layout::FormAssociatedLabelableNode& LabelablePaintable::layout_box()
|
|
|
|
|
{
|
2025-10-10 09:05:30 -03:00
|
|
|
return static_cast<Layout::FormAssociatedLabelableNode&>(layout_node());
|
2022-03-14 20:05:55 -03:00
|
|
|
}
|
|
|
|
|
|
2022-11-02 14:35:53 -03:00
|
|
|
LabelablePaintable::DispatchEventOfSameName LabelablePaintable::handle_mousedown(Badge<EventHandler>, CSSPixelPoint, unsigned button, unsigned)
|
2022-03-14 20:05:55 -03:00
|
|
|
{
|
2024-06-02 14:00:42 -03:00
|
|
|
if (button != UIEvents::MouseButton::Primary || !layout_box().dom_node().enabled())
|
2022-03-14 20:05:55 -03:00
|
|
|
return DispatchEventOfSameName::No;
|
|
|
|
|
|
|
|
|
|
set_being_pressed(true);
|
|
|
|
|
m_tracking_mouse = true;
|
2024-04-26 11:59:04 -03:00
|
|
|
navigable()->event_handler().set_mouse_event_tracking_paintable(this);
|
2022-03-14 20:05:55 -03:00
|
|
|
return DispatchEventOfSameName::Yes;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-02 14:35:53 -03:00
|
|
|
LabelablePaintable::DispatchEventOfSameName LabelablePaintable::handle_mouseup(Badge<EventHandler>, CSSPixelPoint position, unsigned button, unsigned)
|
2022-03-14 20:05:55 -03:00
|
|
|
{
|
2024-06-02 14:00:42 -03:00
|
|
|
if (!m_tracking_mouse || button != UIEvents::MouseButton::Primary || !layout_box().dom_node().enabled())
|
2022-03-14 20:05:55 -03:00
|
|
|
return DispatchEventOfSameName::No;
|
|
|
|
|
|
2022-10-31 16:46:55 -03:00
|
|
|
bool is_inside_node_or_label = absolute_rect().contains(position);
|
2022-03-14 20:05:55 -03:00
|
|
|
if (!is_inside_node_or_label)
|
2026-01-27 08:42:33 -03:00
|
|
|
is_inside_node_or_label = is_inside_associated_label(layout_box().dom_node(), position);
|
2022-03-14 20:05:55 -03:00
|
|
|
|
|
|
|
|
set_being_pressed(false);
|
|
|
|
|
m_tracking_mouse = false;
|
2024-04-26 11:59:04 -03:00
|
|
|
navigable()->event_handler().set_mouse_event_tracking_paintable(nullptr);
|
2022-03-14 20:05:55 -03:00
|
|
|
return DispatchEventOfSameName::Yes;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-02 14:35:53 -03:00
|
|
|
LabelablePaintable::DispatchEventOfSameName LabelablePaintable::handle_mousemove(Badge<EventHandler>, CSSPixelPoint position, unsigned, unsigned)
|
2022-03-14 20:05:55 -03:00
|
|
|
{
|
|
|
|
|
if (!m_tracking_mouse || !layout_box().dom_node().enabled())
|
|
|
|
|
return DispatchEventOfSameName::No;
|
|
|
|
|
|
2022-10-31 16:46:55 -03:00
|
|
|
bool is_inside_node_or_label = absolute_rect().contains(position);
|
2022-03-14 20:05:55 -03:00
|
|
|
if (!is_inside_node_or_label)
|
2026-01-27 08:42:33 -03:00
|
|
|
is_inside_node_or_label = is_inside_associated_label(layout_box().dom_node(), position);
|
2022-03-14 20:05:55 -03:00
|
|
|
|
|
|
|
|
set_being_pressed(is_inside_node_or_label);
|
|
|
|
|
return DispatchEventOfSameName::Yes;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 18:46:35 -03:00
|
|
|
}
|