#include "Screen.h" #include "../GPU.h" #include "../UserInterface/Engine/Scale.h" #include "UserInterface/Engine/Geometry.h" #include "Widgets/Widget.h" #include UI::Thickness Screen::safeInsets; Screen::Screen(std::unique_ptr rootWidget) : rootWidget(std::move(rootWidget)), dirtyManager(this->rootWidget.get()), inputRouter(this->rootWidget.get()) { } Screen::~Screen() = default; void Screen::OnActivate() { if (rootWidget) { rootWidget->SetPadding(safeInsets); } } void Screen::OnDeactivate() { } void Screen::SetSafeAreaInsets(const UI::Thickness& insets) { if (insets == safeInsets) { return; } safeInsets = insets; } void Screen::UpdateLayout(UI::Size viewportSize) { dirtyManager.UpdateLayout(viewportSize); } void Screen::ProcessPointerHover(UI::Point screenPoint) { inputRouter.ProcessPointerHover(screenPoint); } bool Screen::ProcessPointerStream(const std::shared_ptr& stream) { return inputRouter.ProcessPointerStream(stream); } void Screen::Render() { if (rootWidget) { static UI::Thickness lastSafeAreaInsets; if (lastSafeAreaInsets != safeInsets) { lastSafeAreaInsets = safeInsets; rootWidget->SetPadding(safeInsets); } int width, height; SDL_GetWindowSizeInPixels(GPU::GetWindow(), &width, &height); UI::Size size; size.width = UI::PixelsToUnits(static_cast(width)); size.height = UI::PixelsToUnits(static_cast(height)); if (size != screenSize) { screenSize = size; rootWidget->MarkDirty(UI::DirtyFlags::Layout); UpdateLayout(size); } const uint64_t nowNanos = SDL_GetTicksNS(); const float deltaSeconds = lastUpdateNanos == 0 ? 0.0f : std::min(0.05f, static_cast(nowNanos - lastUpdateNanos) / 1.0e9f); lastUpdateNanos = nowNanos; rootWidget->Update(deltaSeconds); // TODO: support update/draw only when we need to draw instead of always every frame rootWidget->Draw(); } }