146 lines
4.7 KiB
C++
146 lines
4.7 KiB
C++
#include "EditorWindowManager.h"
|
|
|
|
#include "State/EditorContext.h"
|
|
#include "EditorWindow.h"
|
|
|
|
namespace XCEngine::UI::Editor::App {
|
|
|
|
bool EditorWindowManager::IsGlobalTabDragActive() const {
|
|
return m_globalTabDragSession.active;
|
|
}
|
|
|
|
bool EditorWindowManager::OwnsActiveGlobalTabDrag(std::string_view windowId) const {
|
|
return m_globalTabDragSession.active &&
|
|
m_globalTabDragSession.panelWindowId == windowId;
|
|
}
|
|
|
|
void EditorWindowManager::BeginGlobalTabDragSession(
|
|
std::string_view panelWindowId,
|
|
std::string_view sourceNodeId,
|
|
std::string_view panelId,
|
|
const POINT& screenPoint) {
|
|
m_globalTabDragSession.active = true;
|
|
m_globalTabDragSession.panelWindowId = std::string(panelWindowId);
|
|
m_globalTabDragSession.sourceNodeId = std::string(sourceNodeId);
|
|
m_globalTabDragSession.panelId = std::string(panelId);
|
|
m_globalTabDragSession.screenPoint = screenPoint;
|
|
}
|
|
|
|
void EditorWindowManager::EndGlobalTabDragSession() {
|
|
if (!m_globalTabDragSession.active) {
|
|
return;
|
|
}
|
|
|
|
if (EditorWindow* ownerWindow = FindWindow(m_globalTabDragSession.panelWindowId);
|
|
ownerWindow != nullptr) {
|
|
if (GetCapture() == ownerWindow->GetHwnd()) {
|
|
ReleaseCapture();
|
|
}
|
|
ownerWindow->ResetInteractionState();
|
|
}
|
|
|
|
m_globalTabDragSession = {};
|
|
}
|
|
|
|
bool EditorWindowManager::HandleGlobalTabDragPointerMove(HWND hwnd) {
|
|
if (!m_globalTabDragSession.active) {
|
|
return false;
|
|
}
|
|
|
|
const EditorWindow* ownerWindow = FindWindow(m_globalTabDragSession.panelWindowId);
|
|
if (ownerWindow == nullptr || ownerWindow->GetHwnd() != hwnd) {
|
|
return false;
|
|
}
|
|
|
|
POINT screenPoint = {};
|
|
if (GetCursorPos(&screenPoint)) {
|
|
m_globalTabDragSession.screenPoint = screenPoint;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void EditorWindowManager::ProcessPendingGlobalTabDragStarts() {
|
|
if (m_globalTabDragSession.active) {
|
|
return;
|
|
}
|
|
|
|
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
|
|
if (window == nullptr || window->GetHwnd() == nullptr) {
|
|
continue;
|
|
}
|
|
|
|
if (TryStartGlobalTabDrag(*window)) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool EditorWindowManager::TryStartGlobalTabDrag(EditorWindow& sourceWindow) {
|
|
const std::optional<EditorWindowPendingTabDragStart> pending =
|
|
sourceWindow.ConsumePendingTabDragStart();
|
|
if (!pending.has_value()) {
|
|
return false;
|
|
}
|
|
|
|
if (sourceWindow.IsPrimary()) {
|
|
UIEditorWindowWorkspaceController windowWorkspaceController =
|
|
BuildLiveWindowWorkspaceController(sourceWindow.GetWindowId());
|
|
const UIEditorWindowWorkspaceOperationResult result =
|
|
windowWorkspaceController.DetachPanelToNewWindow(
|
|
sourceWindow.GetWindowId(),
|
|
pending->nodeId,
|
|
pending->panelId);
|
|
if (result.status != UIEditorWindowWorkspaceOperationStatus::Changed) {
|
|
LogRuntimeTrace(
|
|
"drag",
|
|
"failed to start global tab drag from primary window: " + result.message);
|
|
return false;
|
|
}
|
|
|
|
if (!SynchronizeWindowsFromController(
|
|
windowWorkspaceController,
|
|
result.targetWindowId,
|
|
pending->screenPoint)) {
|
|
LogRuntimeTrace("drag", "failed to synchronize detached drag window state");
|
|
return false;
|
|
}
|
|
|
|
EditorWindow* detachedWindow = FindWindow(result.targetWindowId);
|
|
if (detachedWindow == nullptr || detachedWindow->GetHwnd() == nullptr) {
|
|
LogRuntimeTrace("drag", "detached drag window was not created.");
|
|
return false;
|
|
}
|
|
|
|
BeginGlobalTabDragSession(
|
|
detachedWindow->GetWindowId(),
|
|
detachedWindow->GetWorkspaceController().GetWorkspace().root.nodeId,
|
|
pending->panelId,
|
|
pending->screenPoint);
|
|
SetCapture(detachedWindow->GetHwnd());
|
|
SetForegroundWindow(detachedWindow->GetHwnd());
|
|
LogRuntimeTrace(
|
|
"drag",
|
|
"started global tab drag by detaching panel '" + pending->panelId +
|
|
"' into window '" + std::string(detachedWindow->GetWindowId()) + "'");
|
|
return true;
|
|
}
|
|
|
|
sourceWindow.ResetInteractionState();
|
|
BeginGlobalTabDragSession(
|
|
sourceWindow.GetWindowId(),
|
|
pending->nodeId,
|
|
pending->panelId,
|
|
pending->screenPoint);
|
|
if (sourceWindow.GetHwnd() != nullptr) {
|
|
SetCapture(sourceWindow.GetHwnd());
|
|
}
|
|
LogRuntimeTrace(
|
|
"drag",
|
|
"started global tab drag from detached window '" +
|
|
std::string(sourceWindow.GetWindowId()) +
|
|
"' panel '" + pending->panelId + "'");
|
|
return true;
|
|
}
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|