#include #include #include #include #include #include #include using namespace NXKit; std::vector> getRecognizerHierachyFromView(std::shared_ptr view) { std::vector> recognizers; while (view) { for (const auto& recognizer : *view->gestureRecognizers()) recognizers.push_back(recognizer); view = view->superview().lock(); } return recognizers; } UIWindow::UIWindow() { _focusSystem = new_shared(); _focusSystem->_rootWindow = weak_from_base(); setBackgroundColor(UIColor::systemBackground); setTintColor(UIColor::systemBlue); // yoga->setEnabled(false); } UIWindow::~UIWindow() { _presentedViewControllers.clear(); } std::shared_ptr UIWindow::window() { return shared_from_base(); } void UIWindow::setRootViewController(std::shared_ptr rootViewController) { if (_rootViewController) { _rootViewController->view()->removeFromSuperview(); } _rootViewController = std::move(rootViewController); } void UIWindow::makeKeyAndVisible() { // self.safeAreaInsets = UIWindow.getSafeAreaInsets() auto window = std::static_pointer_cast(shared_from_this()); // window->setBounds(UIRenderer::main()->bounds()); UIApplication::shared->keyWindow = window; auto viewController = _rootViewController; if (viewController) { viewController->loadViewIfNeeded(); viewController->view()->setFrame(this->bounds()); viewController->viewWillAppear(false); addSubview(viewController->view()); viewController->viewDidAppear(false); updateFocus(); } } void UIWindow::updateFocus() { _focusSystem->updateFocus(); } void UIWindow::sendEvent(const std::shared_ptr& event) { focusSystem()->sendEvent(event); if (auto pevent = std::dynamic_pointer_cast(event)) { sendPressEvent(pevent); } else { sendTouchEvent(event); } } void UIWindow::sendTouchEvent(std::shared_ptr event) { for (auto& touch: event->allTouches()) { _inputType = UIWindowInputType::touch; // _focusSystem->setActive(false); auto wHitView = touch->view(); if (wHitView.expired()) wHitView = hitTest(touch->locationIn(nullptr), nullptr); if (wHitView.expired()) continue; auto hitView = wHitView.lock(); switch (touch->phase()) { case UITouchPhase::began: { touch->_view = hitView; touch->_gestureRecognizers = getRecognizerHierachyFromView(hitView); touch->runTouchActionOnRecognizerHierachy([touch, event](auto gestureRecognizer) { gestureRecognizer->touchesBegan({ touch }, event); }); if (!touch->hasBeenCancelledByAGestureRecognizer()) { hitView->touchesBegan(event->allTouches(), event); } break; } case UITouchPhase::moved: { touch->runTouchActionOnRecognizerHierachy([touch, event](auto gestureRecognizer) { gestureRecognizer->touchesMoved({ touch }, event); }); if (!touch->hasBeenCancelledByAGestureRecognizer()) { hitView->touchesMoved(event->allTouches(), event); } break; } case UITouchPhase::ended: { // compute the value before ending the touch on the recognizer hierachy // otherwise `hasBeenCancelledByAGestureRecognizer` will be false because the state was reset already auto hasBeenCancelledByAGestureRecognizer = touch->hasBeenCancelledByAGestureRecognizer(); touch->runTouchActionOnRecognizerHierachy([touch, event](auto gestureRecognizer) { gestureRecognizer->touchesEnded({ touch }, event); }); if (!hasBeenCancelledByAGestureRecognizer) { hitView->touchesEnded(event->allTouches(), event); } break; } } } } void UIWindow::sendPressEvent(const std::shared_ptr& event) { _inputType = UIWindowInputType::focus; // _focusSystem->setActive(true); for (auto& press: event->allPresses()) { if (press->responder().expired()) continue; switch (press->phase()) { case UIPressPhase::began: { press->responder().lock()->pressesBegan({ press }, event); break; } case UIPressPhase::ended: { press->responder().lock()->pressesEnded({ press }, event); break; } default: break; } } } void UIWindow::layoutSubviews() { setSafeAreaInsets(SkiaCtx::main()->deviceSafeAreaInsets()); if (_rootViewController) { _rootViewController->view()->setFrame(this->bounds()); } for(auto& vc: _presentedViewControllers) { vc->view()->setFrame(this->bounds()); } UIView::layoutSubviews(); } void UIWindow::addPresentedViewController(const std::shared_ptr& controller) { _presentedViewControllers.push_back(controller); } void UIWindow::removePresentedViewController(const std::shared_ptr& controller) { _presentedViewControllers.erase(std::remove(_presentedViewControllers.begin(), _presentedViewControllers.end(), controller), _presentedViewControllers.end()); } void UIWindow::pressesBegan(std::set> pressees, std::shared_ptr event) { UIView::pressesBegan(pressees, event); } void UIWindow::pressesChanged(std::set> pressees, std::shared_ptr event) { UIView::pressesChanged(pressees, event); // focusSystem()->sendEvent(event); } void UIWindow::pressesEnded(std::set> pressees, std::shared_ptr event) { UIView::pressesEnded(pressees, event); } void UIWindow::pressesCancelled(std::set> pressees, std::shared_ptr event) { UIView::pressesCancelled(pressees, event); // focusSystem()->sendEvent(event); } void UIWindow::traitCollectionDidChange(std::shared_ptr previousTraitCollection) { UITraitEnvironment::traitCollectionDidChange(previousTraitCollection); if (!rootViewController()) return; rootViewController()->_traitCollection = _traitCollection; rootViewController()->traitCollectionDidChange(previousTraitCollection); }