Files
XCEngine/new_editor/app/Platform/Win32/EditorWindowManagerTabDrag.cpp

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