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.