Widgets/Canvas: Improve mouse owner system
This commit is contained in:
parent
86071eae88
commit
b20897a2fb
|
|
@ -42,6 +42,8 @@ namespace Nz
|
||||||
inline bool IsKeyboardOwner(std::size_t canvasIndex) const;
|
inline bool IsKeyboardOwner(std::size_t canvasIndex) const;
|
||||||
inline bool IsMouseOwner(std::size_t canvasIndex) const;
|
inline bool IsMouseOwner(std::size_t canvasIndex) const;
|
||||||
|
|
||||||
|
inline std::size_t GetMouseEventTarget() const;
|
||||||
|
|
||||||
inline void NotifyWidgetBoxUpdate(std::size_t index);
|
inline void NotifyWidgetBoxUpdate(std::size_t index);
|
||||||
inline void NotifyWidgetCursorUpdate(std::size_t index);
|
inline void NotifyWidgetCursorUpdate(std::size_t index);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,14 @@ namespace Nz
|
||||||
return m_mouseOwner == canvasIndex;
|
return m_mouseOwner == canvasIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::size_t Canvas::GetMouseEventTarget() const
|
||||||
|
{
|
||||||
|
if (m_mouseOwner != InvalidCanvasIndex)
|
||||||
|
return m_mouseOwner;
|
||||||
|
else
|
||||||
|
return m_hoveredWidget;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Canvas::NotifyWidgetBoxUpdate(std::size_t index)
|
inline void Canvas::NotifyWidgetBoxUpdate(std::size_t index)
|
||||||
{
|
{
|
||||||
WidgetEntry& entry = m_widgetEntries[index];
|
WidgetEntry& entry = m_widgetEntries[index];
|
||||||
|
|
@ -88,12 +96,9 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Canvas::SetMouseOwner(std::size_t canvasIndex)
|
inline void Canvas::SetMouseOwner(std::size_t canvasIndex)
|
||||||
{
|
|
||||||
if (m_mouseOwner != canvasIndex)
|
|
||||||
{
|
{
|
||||||
m_mouseOwner = canvasIndex;
|
m_mouseOwner = canvasIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#include <Nazara/Widgets/DebugOff.hpp>
|
#include <Nazara/Widgets/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -91,12 +91,12 @@ namespace Nz
|
||||||
{
|
{
|
||||||
UpdateHoveredWidget(event.x, event.y);
|
UpdateHoveredWidget(event.x, event.y);
|
||||||
|
|
||||||
if (m_hoveredWidget != InvalidCanvasIndex)
|
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||||
{
|
{
|
||||||
WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget];
|
WidgetEntry& targetWidget = m_widgetEntries[targetWidgetIndex];
|
||||||
|
|
||||||
int x = static_cast<int>(std::round(event.x - hoveredWidget.box.x));
|
int x = static_cast<int>(std::round(event.x - targetWidget.box.x));
|
||||||
int y = static_cast<int>(std::round(m_size.y - event.y - hoveredWidget.box.y));
|
int y = static_cast<int>(std::round(m_size.y - event.y - targetWidget.box.y));
|
||||||
|
|
||||||
if (event.clickCount == 2)
|
if (event.clickCount == 2)
|
||||||
targetWidget.widget->OnMouseButtonDoublePress(x, y, event.button);
|
targetWidget.widget->OnMouseButtonDoublePress(x, y, event.button);
|
||||||
|
|
@ -112,14 +112,14 @@ namespace Nz
|
||||||
|
|
||||||
void Canvas::OnEventMouseButtonRelease(const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
|
void Canvas::OnEventMouseButtonRelease(const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
|
||||||
{
|
{
|
||||||
if (m_hoveredWidget != InvalidCanvasIndex)
|
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||||
{
|
{
|
||||||
WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget];
|
WidgetEntry& targetWidget = m_widgetEntries[targetWidgetIndex];
|
||||||
|
|
||||||
int x = static_cast<int>(std::round(event.x - hoveredWidget.box.x));
|
int x = static_cast<int>(std::round(event.x - targetWidget.box.x));
|
||||||
int y = static_cast<int>(std::round(m_size.y - event.y - hoveredWidget.box.y));
|
int y = static_cast<int>(std::round(m_size.y - event.y - targetWidget.box.y));
|
||||||
|
|
||||||
hoveredWidget.widget->OnMouseButtonRelease(x, y, event.button);
|
targetWidget.widget->OnMouseButtonRelease(x, y, event.button);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mouseOwnerButtons[event.button] = false;
|
m_mouseOwnerButtons[event.button] = false;
|
||||||
|
|
@ -132,18 +132,34 @@ namespace Nz
|
||||||
void Canvas::OnEventMouseEntered(const EventHandler* eventHandler)
|
void Canvas::OnEventMouseEntered(const EventHandler* eventHandler)
|
||||||
{
|
{
|
||||||
// Keep previous mouse states but not new ones
|
// Keep previous mouse states but not new ones
|
||||||
|
if (m_mouseOwner != InvalidCanvasIndex)
|
||||||
|
{
|
||||||
|
WidgetEntry& ownerWidget = m_widgetEntries[m_mouseOwner];
|
||||||
|
|
||||||
for (std::size_t i = 0; i < Mouse::ButtonCount; ++i)
|
for (std::size_t i = 0; i < Mouse::ButtonCount; ++i)
|
||||||
m_mouseOwnerButtons[i] = m_mouseOwnerButtons[i] && Mouse::IsButtonPressed(static_cast<Mouse::Button>(i));
|
{
|
||||||
|
if (m_mouseOwnerButtons[i])
|
||||||
|
{
|
||||||
|
if (!Mouse::IsButtonPressed(static_cast<Mouse::Button>(i)))
|
||||||
|
{
|
||||||
|
ownerWidget.widget->OnMouseButtonRelease(-1, -1, static_cast<Mouse::Button>(i));
|
||||||
|
m_mouseOwnerButtons[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_mouseOwnerButtons.none())
|
if (m_mouseOwnerButtons.none())
|
||||||
SetMouseOwner(InvalidCanvasIndex);
|
SetMouseOwner(InvalidCanvasIndex);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_mouseOwnerButtons.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void Canvas::OnEventMouseLeft(const EventHandler* /*eventHandler*/)
|
void Canvas::OnEventMouseLeft(const EventHandler* /*eventHandler*/)
|
||||||
{
|
{
|
||||||
if (m_hoveredWidget != InvalidCanvasIndex && m_mouseOwner == InvalidCanvasIndex)
|
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||||
{
|
{
|
||||||
m_widgetEntries[m_hoveredWidget].widget->OnMouseExit();
|
m_widgetEntries[targetWidgetIndex].widget->OnMouseExit();
|
||||||
m_hoveredWidget = InvalidCanvasIndex;
|
m_hoveredWidget = InvalidCanvasIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,27 +169,27 @@ namespace Nz
|
||||||
// Don't update hovered widget while the user doesn't release its mouse
|
// Don't update hovered widget while the user doesn't release its mouse
|
||||||
UpdateHoveredWidget(event.x, event.y);
|
UpdateHoveredWidget(event.x, event.y);
|
||||||
|
|
||||||
if (m_hoveredWidget != InvalidCanvasIndex)
|
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||||
{
|
{
|
||||||
WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget];
|
WidgetEntry& targetWidget = m_widgetEntries[targetWidgetIndex];
|
||||||
|
|
||||||
int x = static_cast<int>(std::round(event.x - hoveredWidget.box.x));
|
int x = static_cast<int>(std::round(event.x - targetWidget.box.x));
|
||||||
int y = static_cast<int>(std::round(m_size.y - event.y - hoveredWidget.box.y));
|
int y = static_cast<int>(std::round(m_size.y - event.y - targetWidget.box.y));
|
||||||
|
|
||||||
hoveredWidget.widget->OnMouseMoved(x, y, event.deltaX, -event.deltaY);
|
targetWidget.widget->OnMouseMoved(x, y, event.deltaX, -event.deltaY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::OnEventMouseWheelMoved(const EventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& event)
|
void Canvas::OnEventMouseWheelMoved(const EventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& event)
|
||||||
{
|
{
|
||||||
if (m_hoveredWidget != InvalidCanvasIndex)
|
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||||
{
|
{
|
||||||
WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget];
|
WidgetEntry& targetWidget = m_widgetEntries[targetWidgetIndex];
|
||||||
|
|
||||||
int x = static_cast<int>(std::round(event.x - hoveredWidget.box.x));
|
int x = static_cast<int>(std::round(event.x - targetWidget.box.x));
|
||||||
int y = static_cast<int>(std::round(m_size.y - event.y - hoveredWidget.box.y));
|
int y = static_cast<int>(std::round(m_size.y - event.y - targetWidget.box.y));
|
||||||
|
|
||||||
hoveredWidget.widget->OnMouseWheelMoved(x, y, event.delta);
|
targetWidget.widget->OnMouseWheelMoved(x, y, event.delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,9 +273,6 @@ namespace Nz
|
||||||
|
|
||||||
void Canvas::UpdateHoveredWidget(int x, int y)
|
void Canvas::UpdateHoveredWidget(int x, int y)
|
||||||
{
|
{
|
||||||
if (m_mouseOwner != InvalidCanvasIndex)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::size_t bestEntry = InvalidCanvasIndex;
|
std::size_t bestEntry = InvalidCanvasIndex;
|
||||||
float bestEntryArea = std::numeric_limits<float>::infinity();
|
float bestEntryArea = std::numeric_limits<float>::infinity();
|
||||||
|
|
||||||
|
|
@ -279,6 +292,10 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a mouse owner, only allow to hover it or not
|
||||||
|
if (m_mouseOwner != InvalidCanvasIndex && bestEntry != m_mouseOwner)
|
||||||
|
bestEntry = InvalidCanvasIndex;
|
||||||
|
|
||||||
if (bestEntry != InvalidCanvasIndex)
|
if (bestEntry != InvalidCanvasIndex)
|
||||||
{
|
{
|
||||||
if (m_hoveredWidget != bestEntry)
|
if (m_hoveredWidget != bestEntry)
|
||||||
|
|
@ -292,7 +309,7 @@ namespace Nz
|
||||||
m_hoveredWidget = bestEntry;
|
m_hoveredWidget = bestEntry;
|
||||||
m_widgetEntries[m_hoveredWidget].widget->OnMouseEnter();
|
m_widgetEntries[m_hoveredWidget].widget->OnMouseEnter();
|
||||||
|
|
||||||
if (m_cursorController)
|
if (m_cursorController && m_mouseOwner == InvalidCanvasIndex)
|
||||||
m_cursorController->UpdateCursor(Cursor::Get(m_widgetEntries[m_hoveredWidget].cursor));
|
m_cursorController->UpdateCursor(Cursor::Get(m_widgetEntries[m_hoveredWidget].cursor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -301,7 +318,7 @@ namespace Nz
|
||||||
m_widgetEntries[m_hoveredWidget].widget->OnMouseExit();
|
m_widgetEntries[m_hoveredWidget].widget->OnMouseExit();
|
||||||
m_hoveredWidget = InvalidCanvasIndex;
|
m_hoveredWidget = InvalidCanvasIndex;
|
||||||
|
|
||||||
if (m_cursorController)
|
if (m_cursorController && m_mouseOwner == InvalidCanvasIndex)
|
||||||
m_cursorController->UpdateCursor(Cursor::Get(SystemCursor::Default));
|
m_cursorController->UpdateCursor(Cursor::Get(SystemCursor::Default));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue