#pragma once #include "State/EditorSession.h" #include #include namespace XCEngine::UI::Editor::App { class EditorCommandFocusService { public: EditorActionRoute GetExplicitRoute() const { return m_explicitRoute; } bool HasExplicitRoute() const { return m_explicitRoute != EditorActionRoute::None; } EditorActionRoute ResolveRoute( EditorActionRoute fallbackRoute = EditorActionRoute::None) const { return HasExplicitRoute() ? m_explicitRoute : fallbackRoute; } bool ClaimFocus(EditorActionRoute route) { if (route == EditorActionRoute::None) { return false; } const bool changed = m_explicitRoute != route; m_explicitRoute = route; return changed; } void ClearFocus(EditorActionRoute route = EditorActionRoute::None) { if (route == EditorActionRoute::None || m_explicitRoute == route) { m_explicitRoute = EditorActionRoute::None; } } private: EditorActionRoute m_explicitRoute = EditorActionRoute::None; }; inline bool ShouldClaimHostedPanelCommandFocus( const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, const ::XCEngine::UI::UIRect& bounds, bool allowInteraction) { for (const ::XCEngine::UI::UIInputEvent& event : inputEvents) { if (event.type == ::XCEngine::UI::UIInputEventType::FocusGained) { return true; } if (!allowInteraction || event.type != ::XCEngine::UI::UIInputEventType::PointerButtonDown) { continue; } if (event.position.x >= bounds.x && event.position.x <= bounds.x + bounds.width && event.position.y >= bounds.y && event.position.y <= bounds.y + bounds.height) { return true; } } return false; } inline bool TryClaimHostedPanelCommandFocus( EditorCommandFocusService* service, EditorActionRoute route, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, const ::XCEngine::UI::UIRect& bounds, bool allowInteraction) { return service != nullptr && ShouldClaimHostedPanelCommandFocus( inputEvents, bounds, allowInteraction) && service->ClaimFocus(route); } } // namespace XCEngine::UI::Editor::App