#pragma once #include #include #include #include #include namespace XCEngine::UI::Editor { struct UIEditorMenuPopupState { std::string popupId = {}; std::string menuId = {}; std::string itemId = {}; [[nodiscard]] bool IsRootPopup() const { return itemId.empty(); } }; struct UIEditorMenuSessionMutationResult { bool changed = false; std::string openRootMenuId = {}; std::string openedPopupId = {}; std::vector closedPopupIds = {}; ::XCEngine::UI::Widgets::UIPopupDismissReason dismissReason = ::XCEngine::UI::Widgets::UIPopupDismissReason::None; [[nodiscard]] bool HasOpenMenu() const { return !openRootMenuId.empty(); } }; class UIEditorMenuSession { public: const ::XCEngine::UI::Widgets::UIPopupOverlayModel& GetPopupOverlayModel() const { return m_popupOverlayModel; } const std::vector& GetPopupStates() const { return m_popupStates; } const std::vector& GetOpenSubmenuItemIds() const { return m_openSubmenuItemIds; } std::string_view GetOpenRootMenuId() const { return m_openRootMenuId; } [[nodiscard]] bool HasOpenMenu() const { return !m_openRootMenuId.empty(); } [[nodiscard]] bool IsMenuOpen(std::string_view menuId) const { return !m_openRootMenuId.empty() && m_openRootMenuId == menuId; } [[nodiscard]] bool IsPopupOpen(std::string_view popupId) const; const UIEditorMenuPopupState* FindPopupState(std::string_view popupId) const; void Reset(); UIEditorMenuSessionMutationResult OpenRootMenu( std::string_view menuId, ::XCEngine::UI::Widgets::UIPopupOverlayEntry entry); UIEditorMenuSessionMutationResult OpenMenuBarRoot( std::string_view menuId, ::XCEngine::UI::Widgets::UIPopupOverlayEntry entry); UIEditorMenuSessionMutationResult HoverMenuBarRoot( std::string_view menuId, ::XCEngine::UI::Widgets::UIPopupOverlayEntry entry); UIEditorMenuSessionMutationResult HoverSubmenu( std::string_view itemId, ::XCEngine::UI::Widgets::UIPopupOverlayEntry entry); UIEditorMenuSessionMutationResult CloseAll( ::XCEngine::UI::Widgets::UIPopupDismissReason dismissReason = ::XCEngine::UI::Widgets::UIPopupDismissReason::Programmatic); UIEditorMenuSessionMutationResult DismissFromEscape(); UIEditorMenuSessionMutationResult DismissFromPointerDown( const UIInputPath& hitPath); UIEditorMenuSessionMutationResult DismissFromFocusLoss( const UIInputPath& focusedPath); private: UIEditorMenuSessionMutationResult BuildResult( const ::XCEngine::UI::Widgets::UIPopupOverlayMutationResult& mutation) const; void RemoveClosedPopupStates(const std::vector& closedPopupIds); void RebuildDerivedState(); std::string m_openRootMenuId = {}; ::XCEngine::UI::Widgets::UIPopupOverlayModel m_popupOverlayModel = {}; std::vector m_popupStates = {}; std::vector m_openSubmenuItemIds = {}; }; } // namespace XCEngine::UI::Editor