2026-04-19 04:36:52 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "State/EditorSession.h"
|
|
|
|
|
|
2026-04-22 18:42:46 +08:00
|
|
|
#include <XCEngine/UI/Types.h>
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2026-04-19 04:36:52 +08:00
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-22 18:42:46 +08:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-19 04:36:52 +08:00
|
|
|
} // namespace XCEngine::UI::Editor::App
|