Widgets/Canvas: Add mouse unhandled signals

This commit is contained in:
SirLynix 2023-12-07 18:28:11 +01:00
parent 1615bc4229
commit 3514ac6340
2 changed files with 35 additions and 13 deletions

View File

@ -32,6 +32,10 @@ namespace Nz
Canvas& operator=(const Canvas&) = delete;
Canvas& operator=(Canvas&&) = delete;
NazaraSignal(OnUnhandledMouseButtonPressed, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/);
NazaraSignal(OnUnhandledMouseButtonReleased, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/);
NazaraSignal(OnUnhandledMouseMoved, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseMoveEvent& /*event*/);
NazaraSignal(OnUnhandledMouseWheelMoved, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& /*event*/);
NazaraSignal(OnUnhandledKeyPressed, const WindowEventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
NazaraSignal(OnUnhandledKeyReleased, const WindowEventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
@ -55,7 +59,7 @@ namespace Nz
void UnregisterWidget(std::size_t index);
private:
template<typename F> void DispatchEvent(std::size_t widgetIndex, F&& functor);
template<typename F> bool DispatchEvent(std::size_t widgetIndex, F&& functor);
void OnEventMouseButtonPressed(const WindowEventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event);
void OnEventMouseButtonRelease(const WindowEventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event);

View File

@ -91,28 +91,29 @@ namespace Nz
}
template<typename F>
void Canvas::DispatchEvent(std::size_t widgetIndex, F&& functor)
bool Canvas::DispatchEvent(std::size_t widgetIndex, F&& functor)
{
for (;;)
{
WidgetEntry& targetWidget = m_widgetEntries[widgetIndex];
if (functor(targetWidget))
return;
return true;
if (!targetWidget.widget->m_parentWidget)
return;
return false;
widgetIndex = targetWidget.widget->m_parentWidget->m_canvasIndex;
}
}
void Canvas::OnEventMouseButtonPressed(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
void Canvas::OnEventMouseButtonPressed(const WindowEventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event)
{
UpdateHoveredWidget(event.x, event.y);
bool handled = false;
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
{
DispatchEvent(targetWidgetIndex, [&](WidgetEntry& widgetEntry)
handled = DispatchEvent(targetWidgetIndex, [&](WidgetEntry& widgetEntry)
{
int x = static_cast<int>(std::round(event.x - widgetEntry.box.x));
int y = static_cast<int>(std::round(m_size.y - event.y - widgetEntry.box.y));
@ -128,13 +129,17 @@ namespace Nz
SetMouseOwner(m_hoveredWidget);
m_mouseOwnerButtons[event.button] = true;
if (!handled)
OnUnhandledMouseButtonPressed(eventHandler, event);
}
void Canvas::OnEventMouseButtonRelease(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
void Canvas::OnEventMouseButtonRelease(const WindowEventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event)
{
bool handled = false;
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
{
DispatchEvent(targetWidgetIndex, [&](WidgetEntry& widgetEntry)
handled = DispatchEvent(targetWidgetIndex, [&](WidgetEntry& widgetEntry)
{
int x = static_cast<int>(std::round(event.x - widgetEntry.box.x));
int y = static_cast<int>(std::round(m_size.y - event.y - widgetEntry.box.y));
@ -148,6 +153,9 @@ namespace Nz
SetMouseOwner(InvalidCanvasIndex);
UpdateHoveredWidget(event.x, event.y);
if (!handled)
OnUnhandledMouseButtonReleased(eventHandler, event);
}
void Canvas::OnEventMouseEntered(const WindowEventHandler* /*eventHandler*/)
@ -185,7 +193,7 @@ namespace Nz
}
}
void Canvas::OnEventMouseMoved(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseMoveEvent& event)
void Canvas::OnEventMouseMoved(const WindowEventHandler* eventHandler, const WindowEvent::MouseMoveEvent& event)
{
// Don't update hovered widget while the user doesn't release its mouse
UpdateHoveredWidget(event.x, event.y);
@ -197,15 +205,19 @@ namespace Nz
int x = static_cast<int>(std::round(event.x - targetWidget.box.x));
int y = static_cast<int>(std::round(m_size.y - event.y - targetWidget.box.y));
targetWidget.widget->OnMouseMoved(x, y, event.deltaX, -event.deltaY);
if (targetWidget.widget->OnMouseMoved(x, y, event.deltaX, -event.deltaY))
return;
}
OnUnhandledMouseMoved(eventHandler, event);
}
void Canvas::OnEventMouseWheelMoved(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& event)
void Canvas::OnEventMouseWheelMoved(const WindowEventHandler* eventHandler, const WindowEvent::MouseWheelEvent& event)
{
bool handled = false;
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
{
DispatchEvent(targetWidgetIndex, [&](WidgetEntry& widgetEntry)
handled = DispatchEvent(targetWidgetIndex, [&](WidgetEntry& widgetEntry)
{
int x = static_cast<int>(std::round(event.x - widgetEntry.box.x));
int y = static_cast<int>(std::round(m_size.y - event.y - widgetEntry.box.y));
@ -213,6 +225,9 @@ namespace Nz
return widgetEntry.widget->OnMouseWheelMoved(x, y, event.delta);
});
}
if (!handled)
OnUnhandledMouseWheelMoved(eventHandler, event);
}
void Canvas::OnEventKeyPressed(const WindowEventHandler* eventHandler, const WindowEvent::KeyEvent& event)
@ -276,7 +291,10 @@ namespace Nz
void Canvas::OnEventKeyReleased(const WindowEventHandler* eventHandler, const WindowEvent::KeyEvent& event)
{
if (m_keyboardOwner != InvalidCanvasIndex)
m_widgetEntries[m_keyboardOwner].widget->OnKeyReleased(event);
{
if (m_widgetEntries[m_keyboardOwner].widget->OnKeyReleased(event))
return;
}
OnUnhandledKeyReleased(eventHandler, event);
}