diff --git a/SDK/include/NDK/BaseWidget.hpp b/SDK/include/NDK/BaseWidget.hpp index 2494f37f4..9ec7ef7a9 100644 --- a/SDK/include/NDK/BaseWidget.hpp +++ b/SDK/include/NDK/BaseWidget.hpp @@ -80,7 +80,7 @@ namespace Ndk }; protected: - EntityHandle CreateEntity(); + const EntityHandle& CreateEntity(); void DestroyEntity(Entity* entity); virtual void Layout(); void InvalidateNode() override; diff --git a/SDK/include/NDK/Canvas.hpp b/SDK/include/NDK/Canvas.hpp index f37ad3cda..bcafc1680 100644 --- a/SDK/include/NDK/Canvas.hpp +++ b/SDK/include/NDK/Canvas.hpp @@ -39,7 +39,7 @@ namespace Ndk std::size_t RegisterWidget(BaseWidget* widget); - inline void SetKeyboardOwner(BaseWidget* widget); + inline void SetKeyboardOwner(std::size_t canvasIndex); void UnregisterWidget(std::size_t index); @@ -67,10 +67,10 @@ namespace Ndk NazaraSlot(Nz::EventHandler, OnMouseLeft, m_mouseLeftSlot); NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot); + std::size_t m_keyboardOwner; + std::size_t m_hoveredWidget; std::vector m_widgetBoxes; Nz::CursorControllerHandle m_cursorController; - const WidgetBox* m_hoveredWidget; - BaseWidget* m_keyboardOwner; WorldHandle m_world; }; } diff --git a/SDK/include/NDK/Canvas.inl b/SDK/include/NDK/Canvas.inl index f3a8dea88..1d64621f2 100644 --- a/SDK/include/NDK/Canvas.inl +++ b/SDK/include/NDK/Canvas.inl @@ -8,9 +8,9 @@ namespace Ndk { inline Canvas::Canvas(WorldHandle world, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController) : + m_hoveredWidget(InvalidCanvasIndex), + m_keyboardOwner(InvalidCanvasIndex), m_cursorController(cursorController), - m_hoveredWidget(nullptr), - m_keyboardOwner(nullptr), m_world(std::move(world)) { m_canvas = this; @@ -61,12 +61,12 @@ namespace Ndk WidgetBox& entry = m_widgetBoxes[index]; entry.cursor = entry.widget->GetCursor(); - if (m_cursorController && m_hoveredWidget == &entry) + if (m_cursorController && m_hoveredWidget == index) m_cursorController->UpdateCursor(Nz::Cursor::Get(entry.cursor)); } - inline void Ndk::Canvas::SetKeyboardOwner(BaseWidget* widget) + inline void Canvas::SetKeyboardOwner(std::size_t canvasIndex) { - m_keyboardOwner = widget; + m_keyboardOwner = canvasIndex; } } diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 7368558d3..aad8c56c6 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -87,7 +87,7 @@ namespace Ndk void BaseWidget::GrabKeyboard() { - m_canvas->SetKeyboardOwner(this); + m_canvas->SetKeyboardOwner(m_canvasIndex); } void BaseWidget::SetBackgroundColor(const Nz::Color& color) @@ -133,9 +133,9 @@ namespace Ndk } } - EntityHandle BaseWidget::CreateEntity() + const Ndk::EntityHandle& BaseWidget::CreateEntity() { - EntityHandle newEntity = m_world->CreateEntity(); + const EntityHandle& newEntity = m_world->CreateEntity(); newEntity->Enable(m_visible); m_entities.emplace_back(newEntity); diff --git a/SDK/src/NDK/Canvas.cpp b/SDK/src/NDK/Canvas.cpp index 81f5ea994..c3b2862c4 100644 --- a/SDK/src/NDK/Canvas.cpp +++ b/SDK/src/NDK/Canvas.cpp @@ -28,18 +28,25 @@ namespace Ndk { WidgetBox& entry = m_widgetBoxes[index]; - if (m_hoveredWidget == &entry) - m_hoveredWidget = nullptr; + if (m_hoveredWidget == index) + m_hoveredWidget = InvalidCanvasIndex; - if (m_keyboardOwner == entry.widget) - m_keyboardOwner = nullptr; + if (m_keyboardOwner == index) + m_keyboardOwner = InvalidCanvasIndex; if (m_widgetBoxes.size() > 1U) { WidgetBox& lastEntry = m_widgetBoxes.back(); + std::size_t lastEntryIndex = m_widgetBoxes.size() - 1; entry = std::move(lastEntry); entry.widget->UpdateCanvasIndex(index); + + if (m_hoveredWidget == lastEntryIndex) + m_hoveredWidget = index; + + if (m_keyboardOwner == lastEntryIndex) + m_keyboardOwner = index; } m_widgetBoxes.pop_back(); @@ -47,70 +54,78 @@ namespace Ndk void Canvas::OnEventMouseButtonPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event) { - if (m_hoveredWidget) + if (m_hoveredWidget != InvalidCanvasIndex) { - int x = static_cast(std::round(event.x - m_hoveredWidget->box.x)); - int y = static_cast(std::round(event.y - m_hoveredWidget->box.y)); + WidgetBox& hoveredWidget = m_widgetBoxes[m_hoveredWidget]; - m_hoveredWidget->widget->OnMouseButtonPress(x, y, event.button); + int x = static_cast(std::round(event.x - hoveredWidget.box.x)); + int y = static_cast(std::round(event.y - hoveredWidget.box.y)); + + hoveredWidget.widget->OnMouseButtonPress(x, y, event.button); } } void Canvas::OnEventMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent & event) { - if (m_hoveredWidget) + if (m_hoveredWidget != InvalidCanvasIndex) { - int x = static_cast(std::round(event.x - m_hoveredWidget->box.x)); - int y = static_cast(std::round(event.y - m_hoveredWidget->box.y)); + WidgetBox& hoveredWidget = m_widgetBoxes[m_hoveredWidget]; - m_hoveredWidget->widget->OnMouseButtonRelease(x, y, event.button); + int x = static_cast(std::round(event.x - hoveredWidget.box.x)); + int y = static_cast(std::round(event.y - hoveredWidget.box.y)); + + hoveredWidget.widget->OnMouseButtonRelease(x, y, event.button); } } void Canvas::OnEventMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event) { - const WidgetBox* bestEntry = nullptr; + std::size_t bestEntry = InvalidCanvasIndex; float bestEntryArea = std::numeric_limits::infinity(); Nz::Vector3f mousePos(float(event.x), float(event.y), 0.f); - for (const WidgetBox& entry : m_widgetBoxes) + for (std::size_t i = 0; i < m_widgetBoxes.size(); ++i) { - const Nz::Boxf& box = entry.box; + const Nz::Boxf& box = m_widgetBoxes[i].box; if (box.Contains(mousePos)) { float area = box.width * box.height; if (area < bestEntryArea) { - bestEntry = &entry; + bestEntry = i; bestEntryArea = area; } } } - if (bestEntry) + if (bestEntry != InvalidCanvasIndex) { if (m_hoveredWidget != bestEntry) { - if (m_hoveredWidget) - m_hoveredWidget->widget->OnMouseExit(); + if (m_hoveredWidget != InvalidCanvasIndex) + { + WidgetBox& previouslyHovered = m_widgetBoxes[m_hoveredWidget]; + previouslyHovered.widget->OnMouseExit(); + } m_hoveredWidget = bestEntry; - m_hoveredWidget->widget->OnMouseEnter(); + m_widgetBoxes[m_hoveredWidget].widget->OnMouseEnter(); if (m_cursorController) - m_cursorController->UpdateCursor(Nz::Cursor::Get(m_hoveredWidget->cursor)); + m_cursorController->UpdateCursor(Nz::Cursor::Get(m_widgetBoxes[m_hoveredWidget].cursor)); } - int x = static_cast(std::round(event.x - m_hoveredWidget->box.x)); - int y = static_cast(std::round(event.y - m_hoveredWidget->box.y)); + WidgetBox& hoveredWidget = m_widgetBoxes[m_hoveredWidget]; - bestEntry->widget->OnMouseMoved(x, y, event.deltaX, event.deltaY); + int x = static_cast(std::round(event.x - hoveredWidget.box.x)); + int y = static_cast(std::round(event.y - hoveredWidget.box.y)); + hoveredWidget.widget->OnMouseMoved(x, y, event.deltaX, event.deltaY); } - else if (m_hoveredWidget) + else if (m_hoveredWidget != InvalidCanvasIndex) { - m_hoveredWidget->widget->OnMouseExit(); - m_hoveredWidget = nullptr; + m_widgetBoxes[m_hoveredWidget].widget->OnMouseExit(); + m_hoveredWidget = InvalidCanvasIndex; if (m_cursorController) m_cursorController->UpdateCursor(Nz::Cursor::Get(Nz::SystemCursor_Default)); @@ -119,28 +134,28 @@ namespace Ndk void Canvas::OnEventMouseLeft(const Nz::EventHandler* /*eventHandler*/) { - if (m_hoveredWidget) + if (m_hoveredWidget != InvalidCanvasIndex) { - m_hoveredWidget->widget->OnMouseExit(); - m_hoveredWidget = nullptr; + m_widgetBoxes[m_hoveredWidget].widget->OnMouseExit(); + m_hoveredWidget = InvalidCanvasIndex; } } void Canvas::OnEventKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) { - if (m_keyboardOwner) - m_keyboardOwner->OnKeyPressed(event); + if (m_keyboardOwner != InvalidCanvasIndex) + m_widgetBoxes[m_hoveredWidget].widget->OnKeyPressed(event); } void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) { - if (m_keyboardOwner) - m_keyboardOwner->OnKeyReleased(event); + if (m_keyboardOwner != InvalidCanvasIndex) + m_widgetBoxes[m_hoveredWidget].widget->OnKeyReleased(event); } void Canvas::OnEventTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event) { - if (m_keyboardOwner) - m_keyboardOwner->OnTextEntered(event.character, event.repeated); + if (m_keyboardOwner != InvalidCanvasIndex) + m_widgetBoxes[m_hoveredWidget].widget->OnTextEntered(event.character, event.repeated); } }