9#include "sml/events/system_events.h" 
   15    Scene::Scene(int32_t width, int32_t height) : m_Width(width), m_Height(height) {}
 
   19        if (m_Root == 
nullptr) { 
return; }
 
   21        m_Root->setLayoutX(0);
 
   22        m_Root->setLayoutY(0);
 
   23        m_Root->setLayoutWidth(m_Width);
 
   24        m_Root->setLayoutHeight(m_Height);
 
   29        for (ContextMenu* contextMenu : m_ContextMenus)
 
   31            contextMenu->setLayoutWidth(contextMenu->computePrefWidth());
 
   32            contextMenu->setLayoutHeight(contextMenu->computePrefHeight());
 
   34            Component* source = contextMenu->getSource();
 
   35            if (source == 
nullptr)
 
   37                Sml::Rectangle<int32_t> centeredPos = Sml::centerRegion(getLayoutRegion(),
 
   38                                                                        contextMenu->getOriginBounds());
 
   40                contextMenu->setLayoutX(centeredPos.pos.x);
 
   41                contextMenu->setLayoutY(centeredPos.pos.y);
 
   45                Sml::Vec2i bottomLeftCorner = source->computeScenePos();
 
   46                bottomLeftCorner.y += source->getLayoutHeight();
 
   48                contextMenu->setLayoutX(bottomLeftCorner.x);
 
   49                contextMenu->setLayoutY(bottomLeftCorner.y);
 
   52            contextMenu->layout();
 
   53            contextMenu->prerender();
 
   57    void Scene::render(
const Sml::Rectangle<int32_t>& targetRegion)
 
   59        if (m_Root != 
nullptr)
 
   61            m_Root->render(targetRegion);
 
   64        for (ContextMenu* contextMenu : m_ContextMenus)
 
   66            contextMenu->render(targetRegion);
 
   70    void Scene::proccessEvent(Sml::Event* event)
 
   74        if (event->isInCategory(Sml::MouseEvent::getStaticCategory()))
 
   76            proccessMouseEvent(
dynamic_cast<Sml::MouseEvent*
>(event));
 
   78        else if (event->isInCategory(Sml::KeyEvent::getStaticCategory()))
 
   80            proccessKeyboardEvent(
dynamic_cast<Sml::KeyEvent*
>(event));
 
   84    Sml::EventDispatchChain* Scene::buildEventDispatchChain(Sml::EventDispatchChain* chain)
 
   88        chain->prependDispatcher(&m_Dispatcher);
 
   94    Sml::Rectangle<int32_t> Scene::getLayoutRegion()
 const { 
return {{0, 0}, m_Width, m_Height}; }
 
   96    int32_t Scene::getWidth()
 const { 
return m_Width; }
 
   97    void Scene::setWidth(int32_t width) { m_Width = width; }
 
   99    int32_t Scene::getHeight()
 const { 
return m_Height; }
 
  100    void Scene::setHeight(int32_t height) { m_Height = height; }
 
  102    Parent* Scene::getRoot() { 
return m_Root; }
 
  103    void Scene::setRoot(Parent* root) { m_Root = root; m_Root->setScene(
this); }
 
  105    Component* Scene::getFocusOwner() { 
return m_FocusOwner; }
 
  107    void Scene::requestFocus(Component* component)
 
  109        if (m_FocusOwner != component)
 
  111            Component* prevFocus = m_FocusOwner;
 
  112            Component* newFocus  = component;
 
  114            if (m_FocusOwner != 
nullptr)
 
  116                FocusLostEvent focusEvent{newFocus, prevFocus};
 
  117                m_FocusOwner->m_Focused = 
false;
 
  121            if (component != 
nullptr)
 
  123                FocusReceivedEvent focusEvent{prevFocus, newFocus};
 
  124                component->m_Focused = 
true;
 
  129        m_FocusOwner = component;
 
  132    Component* Scene::getDragOwner() { 
return m_DragOwner; }
 
  134    void Scene::requestDrag(Component* component)
 
  140        m_DragOwner = component;
 
  142        DragStartEvent dragStartEvent{Sml::MouseState::getMouseState().x,
 
  143                                      Sml::MouseState::getMouseState().y,
 
  148    void Scene::finishDrag()
 
  150        if (m_DragOwner != 
nullptr)
 
  152            DragEndEvent dragEndEvent{Sml::MouseState::getMouseState().x,
 
  153                                      Sml::MouseState::getMouseState().y,
 
  157            m_DragOwner = 
nullptr;
 
  161    void Scene::registerContextMenu(ContextMenu* contextMenu)
 
  164        m_ContextMenus.push_back(contextMenu);
 
  167    void Scene::detachContextMenu(ContextMenu* contextMenu)
 
  170        m_ContextMenus.remove(contextMenu);
 
  173    Component* Scene::findHitComponentInContextMenus(int32_t x, int32_t y, ContextMenu** menu)
 
  175        Component* hitComponent = 
nullptr;
 
  176        ContextMenu* hitMenu = 
nullptr;
 
  178        for (ContextMenu* contextMenu : m_ContextMenus)
 
  180            hitComponent = contextMenu->getHitComponent(x, y);
 
  181            if (hitComponent != 
nullptr)
 
  183                hitMenu = contextMenu;
 
  196    Component* Scene::findHitComponentInRoot(int32_t x, int32_t y)
 
  198        if (m_Root != 
nullptr)
 
  200            return m_Root->getHitComponent(x, y);
 
  206    void Scene::updateHoverOwner(Component* newHoverOwner, int32_t mouseX, int32_t mouseY)
 
  208        if (m_HoverOwner != newHoverOwner)
 
  210            if (m_HoverOwner != 
nullptr)
 
  212                MouseExitedEvent mouseExitedEvent{mouseX, mouseY, m_HoverOwner};
 
  213                m_HoverOwner->m_Hovered = 
false;
 
  217            if (newHoverOwner != 
nullptr)
 
  219                MouseEnteredEvent mouseEnteredEvent{mouseX, mouseY, newHoverOwner};
 
  220                newHoverOwner->m_Hovered = 
true;
 
  225        m_HoverOwner = newHoverOwner;
 
  228    void Scene::proccessKeyboardEvent(Sml::KeyEvent* keyEvent)
 
  235    void Scene::proccessMouseEvent(Sml::MouseEvent* mouseEvent)
 
  239        if (m_Root == 
nullptr)
 
  244        ContextMenu* hitMenu = 
nullptr;
 
  245        Component* newHoverOwner = findHitComponentInContextMenus(mouseEvent->getX(), mouseEvent->getY(),
 
  248        if (newHoverOwner == 
nullptr)
 
  250            newHoverOwner = findHitComponentInRoot(mouseEvent->getX(), mouseEvent->getY());
 
  253        updateHoverOwner(newHoverOwner, mouseEvent->getX(), mouseEvent->getY());
 
  255        if (mouseEvent->isInCategory(Sml::SystemEventCategory::EVENT_CATEGORY_MOUSE_BUTTON))
 
  260        if (mouseEvent->getType() == Sml::MouseButtonPressedEvent::getStaticType())
 
  262            requestFocus(newHoverOwner);
 
  265        if (mouseEvent->getType() == Sml::MouseMovedEvent::getStaticType() && m_DragOwner != 
nullptr)
 
  267            Sml::MouseMovedEvent* mouseMovedEvent = 
dynamic_cast<Sml::MouseMovedEvent*
>(mouseEvent);
 
  268            DragMoveEvent dragMoveEvent{mouseMovedEvent->getX(), mouseMovedEvent->getY(),
 
  269                                        mouseMovedEvent->getDeltaX(), mouseMovedEvent->getDeltaY(),
 
  275        if (newHoverOwner != 
nullptr)
 
  277            mouseEvent->setTarget(newHoverOwner);
 
Sml::Event * fireEvent(Sml::Event *event)
Fire the event from the specified.