fix(new_editor/docking): restore cross-window drop preview
This commit is contained in:
@@ -65,6 +65,17 @@ const std::string& EditorShellRuntime::GetBuiltInIconError() const {
|
||||
return m_builtInIcons.GetLastError();
|
||||
}
|
||||
|
||||
void EditorShellRuntime::SetExternalDockHostDropPreview(
|
||||
const Widgets::UIEditorDockHostDropPreviewState& preview) {
|
||||
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState
|
||||
.dockHostState.dropPreview = preview;
|
||||
}
|
||||
|
||||
void EditorShellRuntime::ClearExternalDockHostDropPreview() {
|
||||
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState
|
||||
.dockHostState.dropPreview = {};
|
||||
}
|
||||
|
||||
ProjectPanel::CursorKind EditorShellRuntime::GetHostedContentCursorKind() const {
|
||||
return m_projectPanel.GetCursorKind();
|
||||
}
|
||||
|
||||
@@ -53,6 +53,9 @@ public:
|
||||
const std::vector<HierarchyPanel::Event>& GetHierarchyPanelEvents() const;
|
||||
const std::vector<ProjectPanel::Event>& GetProjectPanelEvents() const;
|
||||
const std::string& GetBuiltInIconError() const;
|
||||
void SetExternalDockHostDropPreview(
|
||||
const Widgets::UIEditorDockHostDropPreviewState& preview);
|
||||
void ClearExternalDockHostDropPreview();
|
||||
|
||||
ProjectPanel::CursorKind GetHostedContentCursorKind() const;
|
||||
Widgets::UIEditorDockHostCursorKind GetDockCursorKind() const;
|
||||
|
||||
@@ -60,6 +60,9 @@ public:
|
||||
const UIEditorShellInteractionState& GetShellInteractionState() const;
|
||||
::XCEngine::UI::UIPoint ConvertScreenPixelsToClientDips(const POINT& screenPoint) const;
|
||||
void InvalidateHostWindow() const;
|
||||
void SetExternalDockHostDropPreview(
|
||||
const Widgets::UIEditorDockHostDropPreviewState& preview);
|
||||
void ClearExternalDockHostDropPreview();
|
||||
|
||||
void AttachHwnd(HWND hwnd);
|
||||
void MarkDestroyed();
|
||||
|
||||
@@ -77,6 +77,15 @@ const UIEditorShellInteractionState& EditorWindow::GetShellInteractionState() co
|
||||
return m_composition.shellRuntime.GetShellInteractionState();
|
||||
}
|
||||
|
||||
void EditorWindow::SetExternalDockHostDropPreview(
|
||||
const Widgets::UIEditorDockHostDropPreviewState& preview) {
|
||||
m_composition.shellRuntime.SetExternalDockHostDropPreview(preview);
|
||||
}
|
||||
|
||||
void EditorWindow::ClearExternalDockHostDropPreview() {
|
||||
m_composition.shellRuntime.ClearExternalDockHostDropPreview();
|
||||
}
|
||||
|
||||
void EditorWindow::AttachHwnd(HWND hwnd) {
|
||||
m_window.hwnd = hwnd;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ private:
|
||||
std::string panelWindowId = {};
|
||||
std::string sourceNodeId = {};
|
||||
std::string panelId = {};
|
||||
std::string previewWindowId = {};
|
||||
POINT screenPoint = {};
|
||||
POINT dragHotspot = {};
|
||||
};
|
||||
@@ -121,6 +122,8 @@ private:
|
||||
std::string_view panelId,
|
||||
const POINT& screenPoint,
|
||||
POINT& outDragHotspot) const;
|
||||
void ClearGlobalTabDragDropPreview();
|
||||
void UpdateGlobalTabDragDropPreview();
|
||||
void UpdateGlobalTabDragOwnerWindowPosition();
|
||||
EditorWindow* FindTopmostWindowAtScreenPoint(
|
||||
const POINT& screenPoint,
|
||||
|
||||
@@ -19,7 +19,7 @@ struct CrossWindowDockDropTarget {
|
||||
std::size_t insertionIndex = Widgets::UIEditorTabStripInvalidIndex;
|
||||
};
|
||||
|
||||
bool TryResolveCrossWindowDockDropTarget(
|
||||
inline bool TryResolveCrossWindowDockDropTarget(
|
||||
const Widgets::UIEditorDockHostLayout& layout,
|
||||
const ::XCEngine::UI::UIPoint& point,
|
||||
CrossWindowDockDropTarget& outTarget) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "EditorWindowManager.h"
|
||||
|
||||
#include "Platform/Win32/EditorWindowManagerCrossWindowDropSupport.h"
|
||||
#include "State/EditorContext.h"
|
||||
#include "EditorWindow.h"
|
||||
|
||||
@@ -10,6 +11,9 @@ namespace XCEngine::UI::Editor::App {
|
||||
|
||||
namespace {
|
||||
|
||||
using EditorWindowManagerCrossWindowDropSupport::CrossWindowDockDropTarget;
|
||||
using EditorWindowManagerCrossWindowDropSupport::TryResolveCrossWindowDockDropTarget;
|
||||
|
||||
constexpr LONG kFallbackDragHotspotX = 40;
|
||||
constexpr LONG kFallbackDragHotspotY = 12;
|
||||
|
||||
@@ -134,11 +138,67 @@ void EditorWindowManager::UpdateGlobalTabDragOwnerWindowPosition() {
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
void EditorWindowManager::ClearGlobalTabDragDropPreview() {
|
||||
if (m_globalTabDragSession.previewWindowId.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorWindow* previewWindow = FindWindow(m_globalTabDragSession.previewWindowId);
|
||||
previewWindow != nullptr) {
|
||||
previewWindow->ClearExternalDockHostDropPreview();
|
||||
previewWindow->InvalidateHostWindow();
|
||||
}
|
||||
m_globalTabDragSession.previewWindowId.clear();
|
||||
}
|
||||
|
||||
void EditorWindowManager::UpdateGlobalTabDragDropPreview() {
|
||||
if (!m_globalTabDragSession.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditorWindow* targetWindow = FindTopmostWindowAtScreenPoint(
|
||||
m_globalTabDragSession.screenPoint,
|
||||
m_globalTabDragSession.panelWindowId);
|
||||
if (targetWindow == nullptr || targetWindow->GetHwnd() == nullptr) {
|
||||
ClearGlobalTabDragDropPreview();
|
||||
return;
|
||||
}
|
||||
|
||||
const ::XCEngine::UI::UIPoint targetPoint =
|
||||
targetWindow->ConvertScreenPixelsToClientDips(m_globalTabDragSession.screenPoint);
|
||||
const Widgets::UIEditorDockHostLayout& targetLayout =
|
||||
targetWindow->GetShellFrame().workspaceInteractionFrame.dockHostFrame.layout;
|
||||
CrossWindowDockDropTarget dropTarget = {};
|
||||
if (!TryResolveCrossWindowDockDropTarget(targetLayout, targetPoint, dropTarget) ||
|
||||
!dropTarget.valid) {
|
||||
ClearGlobalTabDragDropPreview();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_globalTabDragSession.previewWindowId.empty() &&
|
||||
m_globalTabDragSession.previewWindowId != targetWindow->GetWindowId()) {
|
||||
ClearGlobalTabDragDropPreview();
|
||||
}
|
||||
|
||||
Widgets::UIEditorDockHostDropPreviewState preview = {};
|
||||
preview.visible = true;
|
||||
preview.sourceNodeId = m_globalTabDragSession.sourceNodeId;
|
||||
preview.sourcePanelId = m_globalTabDragSession.panelId;
|
||||
preview.targetNodeId = dropTarget.nodeId;
|
||||
preview.placement = dropTarget.placement;
|
||||
preview.insertionIndex = dropTarget.insertionIndex;
|
||||
targetWindow->SetExternalDockHostDropPreview(preview);
|
||||
targetWindow->InvalidateHostWindow();
|
||||
m_globalTabDragSession.previewWindowId = std::string(targetWindow->GetWindowId());
|
||||
}
|
||||
|
||||
void EditorWindowManager::EndGlobalTabDragSession() {
|
||||
if (!m_globalTabDragSession.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClearGlobalTabDragDropPreview();
|
||||
|
||||
if (EditorWindow* ownerWindow = FindWindow(m_globalTabDragSession.panelWindowId);
|
||||
ownerWindow != nullptr) {
|
||||
if (GetCapture() == ownerWindow->GetHwnd()) {
|
||||
@@ -164,6 +224,7 @@ bool EditorWindowManager::HandleGlobalTabDragPointerMove(HWND hwnd) {
|
||||
if (GetCursorPos(&screenPoint)) {
|
||||
m_globalTabDragSession.screenPoint = screenPoint;
|
||||
UpdateGlobalTabDragOwnerWindowPosition();
|
||||
UpdateGlobalTabDragDropPreview();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user