diff --git a/source/Components/AvalonDock/Controls/DragService.cs b/source/Components/AvalonDock/Controls/DragService.cs index 0b7ca91a..d08f8e34 100644 --- a/source/Components/AvalonDock/Controls/DragService.cs +++ b/source/Components/AvalonDock/Controls/DragService.cs @@ -1,4 +1,4 @@ -/************************************************************************ +/************************************************************************ AvalonDock Copyright (C) 2007-2013 Xceed Software Inc. @@ -85,13 +85,14 @@ public DragService(LayoutFloatingWindowControl floatingWindow) internal void UpdateMouseLocation(Point dragPosition) { ////var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; + // TODO - pass in without DPI adjustment, screen co-ords, adjust inside the target window - var newHost = _overlayWindowHosts.FirstOrDefault(oh => oh.HitTest(dragPosition)); + var newHost = _overlayWindowHosts.FirstOrDefault(oh => oh.HitTestScreen(dragPosition)); if (_currentHost != null || _currentHost != newHost) { //is mouse still inside current overlay window host? - if ((_currentHost != null && !_currentHost.HitTest(dragPosition)) || + if ((_currentHost != null && !_currentHost.HitTestScreen(dragPosition)) || _currentHost != newHost) { //esit drop target @@ -125,7 +126,7 @@ internal void UpdateMouseLocation(Point dragPosition) return; if (_currentDropTarget != null && - !_currentDropTarget.HitTest(dragPosition)) + !_currentDropTarget.HitTestScreen(dragPosition)) { _currentWindow.DragLeave(_currentDropTarget); _currentDropTarget = null; @@ -134,8 +135,9 @@ internal void UpdateMouseLocation(Point dragPosition) List areasToRemove = new List(); _currentWindowAreas.ForEach(a => { + //is mouse still inside this area? - if (!a.DetectionRect.Contains(dragPosition)) + if (!a.DetectionRect.Contains(a.TransformToDeviceDPI(dragPosition))) { _currentWindow.DragLeave(a); areasToRemove.Add(a); @@ -146,7 +148,7 @@ internal void UpdateMouseLocation(Point dragPosition) _currentWindowAreas.Remove(a)); var areasToAdd = - _currentHost.GetDropAreas(_floatingWindow).Where(cw => !_currentWindowAreas.Contains(cw) && cw.DetectionRect.Contains(dragPosition)).ToList(); + _currentHost.GetDropAreas(_floatingWindow).Where(cw => !_currentWindowAreas.Contains(cw) && cw.DetectionRect.Contains(cw.TransformToDeviceDPI(dragPosition))).ToList(); _currentWindowAreas.AddRange(areasToAdd); @@ -160,7 +162,7 @@ internal void UpdateMouseLocation(Point dragPosition) if (_currentDropTarget != null) return; - _currentDropTarget = _currentWindow.GetTargets().FirstOrDefault(dt => dt.HitTest(dragPosition)); + _currentDropTarget = _currentWindow.GetTargets().FirstOrDefault(dt => dt.HitTestScreen(dragPosition)); if (_currentDropTarget != null) { @@ -185,6 +187,7 @@ internal void UpdateMouseLocation(Point dragPosition) /// is docked into a new visual tree position). internal void Drop(Point dropLocation, out bool dropHandled) { + // TODO - pass in without DPI adjustment, screen co-ords, adjust inside the target window dropHandled = false; UpdateMouseLocation(dropLocation); diff --git a/source/Components/AvalonDock/Controls/DropArea.cs b/source/Components/AvalonDock/Controls/DropArea.cs index 12e8ab80..6d90ca5a 100644 --- a/source/Components/AvalonDock/Controls/DropArea.cs +++ b/source/Components/AvalonDock/Controls/DropArea.cs @@ -1,4 +1,4 @@ -/************************************************************************ +/************************************************************************ AvalonDock Copyright (C) 2007-2013 Xceed Software Inc. @@ -36,6 +36,8 @@ public interface IDropArea /// Gets the type of drop area for this drop target. DropAreaType Type { get; } + + Point TransformToDeviceDPI(Point dragPosition); } /// @@ -70,6 +72,11 @@ internal DropArea(T areaElement, DropAreaType type) /// public DropAreaType Type { get; } + public Point TransformToDeviceDPI(Point dragPosition) + { + return AreaElement.TransformToDeviceDPI(dragPosition); + } + #endregion IDropArea #region Properties diff --git a/source/Components/AvalonDock/Controls/DropTarget.cs b/source/Components/AvalonDock/Controls/DropTarget.cs index c1c31ca3..26fa86ed 100644 --- a/source/Components/AvalonDock/Controls/DropTarget.cs +++ b/source/Components/AvalonDock/Controls/DropTarget.cs @@ -1,4 +1,4 @@ -/************************************************************************ +/************************************************************************ AvalonDock Copyright (C) 2007-2013 Xceed Software Inc. @@ -106,6 +106,11 @@ protected virtual void Drop(LayoutDocumentFloatingWindow floatingWindow) #region Public Methods + public bool HitTestScreen(Point dragPoint) + { + return HitTest(_targetElement.TransformToDeviceDPI(dragPoint)); + } + public void Drop(LayoutFloatingWindow floatingWindow) { var root = floatingWindow.Root; diff --git a/source/Components/AvalonDock/Controls/IDropTarget.cs b/source/Components/AvalonDock/Controls/IDropTarget.cs index 6a3ed90d..32e4df9b 100644 --- a/source/Components/AvalonDock/Controls/IDropTarget.cs +++ b/source/Components/AvalonDock/Controls/IDropTarget.cs @@ -1,4 +1,4 @@ -/************************************************************************ +/************************************************************************ AvalonDock Copyright (C) 2007-2013 Xceed Software Inc. @@ -48,7 +48,7 @@ internal interface IDropTarget /// Determines whether the is part of this drop target or not. /// The point to test. /// true if it is inside the target. - bool HitTest(Point dragPoint); + bool HitTestScreen(Point dragPoint); /// /// Method is invoked to complete a drag & drop operation with a (new) docking position diff --git a/source/Components/AvalonDock/Controls/IOverlayWindowHost.cs b/source/Components/AvalonDock/Controls/IOverlayWindowHost.cs index 2d3ca146..effded0f 100644 --- a/source/Components/AvalonDock/Controls/IOverlayWindowHost.cs +++ b/source/Components/AvalonDock/Controls/IOverlayWindowHost.cs @@ -1,4 +1,4 @@ -/************************************************************************ +/************************************************************************ AvalonDock Copyright (C) 2007-2013 Xceed Software Inc. @@ -36,7 +36,7 @@ internal interface IOverlayWindowHost /// /// The point to test. /// true if inside window, otherwise false. - bool HitTest(Point dragPoint); + bool HitTestScreen(Point dragPoint); /// /// Is invoked by the of a diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index a32aa039..73c3aa3c 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -1,4 +1,4 @@ -/************************************************************************ +/************************************************************************ AvalonDock Copyright (C) 2007-2013 Xceed Software Inc. @@ -140,7 +140,12 @@ public override void DisableBindings() #region IOverlayWindowHost - bool IOverlayWindowHost.HitTest(Point dragPoint) + bool IOverlayWindowHost.HitTestScreen(Point dragPoint) + { + return HitTest(this.TransformToDeviceDPI(dragPoint)); + } + + bool HitTest(Point dragPoint) { var detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); return detectionRect.Contains(dragPoint); @@ -151,12 +156,13 @@ void IOverlayWindowHost.HideOverlayWindow() _dropAreas = null; _overlayWindow.Owner = null; _overlayWindow.HideDropTargets(); + _overlayWindow.Close(); + _overlayWindow = null; } IOverlayWindow IOverlayWindowHost.ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow) { CreateOverlayWindow(); - _overlayWindow.Owner = draggingWindow; _overlayWindow.EnableDropTargets(); _overlayWindow.Show(); return _overlayWindow; @@ -292,6 +298,7 @@ private void _model_IsVisibleChanged(object sender, EventArgs e) private void CreateOverlayWindow() { if (_overlayWindow == null) _overlayWindow = new OverlayWindow(this); + _overlayWindow.Owner = Window.GetWindow(this); var rectWindow = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); _overlayWindow.Left = rectWindow.Left; _overlayWindow.Top = rectWindow.Top; diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index 8cb81a9d..db93a0f1 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -210,7 +210,12 @@ protected override void OnClosing(System.ComponentModel.CancelEventArgs e) base.OnClosing(e); } - bool IOverlayWindowHost.HitTest(Point dragPoint) + bool IOverlayWindowHost.HitTestScreen(Point dragPoint) + { + return HitTest(this.TransformToDeviceDPI(dragPoint)); + } + + bool HitTest(Point dragPoint) { var detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); return detectionRect.Contains(dragPoint); @@ -223,6 +228,7 @@ bool IOverlayWindowHost.HitTest(Point dragPoint) private void CreateOverlayWindow() { if (_overlayWindow == null) _overlayWindow = new OverlayWindow(this); + _overlayWindow.Owner = Window.GetWindow(this); var rectWindow = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); _overlayWindow.Left = rectWindow.Left; _overlayWindow.Top = rectWindow.Top; @@ -233,7 +239,6 @@ private void CreateOverlayWindow() IOverlayWindow IOverlayWindowHost.ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow) { CreateOverlayWindow(); - _overlayWindow.Owner = draggingWindow; _overlayWindow.EnableDropTargets(); _overlayWindow.Show(); return _overlayWindow; @@ -244,6 +249,8 @@ public void HideOverlayWindow() _dropAreas = null; _overlayWindow.Owner = null; _overlayWindow.HideDropTargets(); + _overlayWindow.Close(); + _overlayWindow = null; } public IEnumerable GetDropAreas(LayoutFloatingWindowControl draggingWindow) diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs index c88158a6..670aa25b 100644 --- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -364,7 +364,7 @@ protected virtual IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntP if (_dragService != null) { - var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition()); + var mousePosition = (Win32Helper.GetMousePosition()); _dragService.Drop(mousePosition, out var dropFlag); _dragService = null; SetIsDragging(false); @@ -606,13 +606,24 @@ private void OnActivated(object sender, EventArgs e) var windowHandle = new WindowInteropHelper(this).Handle; var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this)); + var area = this.GetScreenArea(); + // BugFix Issue #6 // This code is initializes the drag when content (document or toolwindow) is dragged // A second chance back up plan if DragDelta is not set if (DragDelta == default) DragDelta = new Point(3, 3); Left = mousePosition.X - DragDelta.X; // BugFix Issue #6 Top = mousePosition.Y - DragDelta.Y; + + if (this.GetScreenArea().Size != area.Size) // setting the top/left co-ordinates has changed the size - this means moving to a screen with a different DPI. Recalculate mouse position based on new DPI to avoid wrong drag location + { + mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this)); + Left = mousePosition.X - DragDelta.X; + Top = mousePosition.Y - DragDelta.Y; + } + _attachDrag = false; + Show(); var lParam = new IntPtr(((int)mousePosition.X & 0xFFFF) | ((int)mousePosition.Y << 16)); Win32Helper.SendMessage(windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr(Win32Helper.HT_CAPTION), lParam); } @@ -657,7 +668,7 @@ private void UpdateDragPosition() _dragService = new DragService(this); SetIsDragging(true); } - var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition()); + var mousePosition = (Win32Helper.GetMousePosition()); _dragService.UpdateMouseLocation(mousePosition); } diff --git a/source/Components/AvalonDock/Controls/LayoutGridControl.cs b/source/Components/AvalonDock/Controls/LayoutGridControl.cs index efde9b3b..cd339085 100644 --- a/source/Components/AvalonDock/Controls/LayoutGridControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutGridControl.cs @@ -637,7 +637,7 @@ private void ShowResizerOverlayWindow(LayoutGridResizerControl splitter) Left = ptTopLeftScreen.X, Top = ptTopLeftScreen.Y, ShowActivated = false, - //Owner = Window.GetWindow(this), + Owner = Window.GetWindow(this), Content = panelHostResizer }; _resizerWindowHost.Loaded += (s, e) => _resizerWindowHost.SetParentToMainWindowOf(this); diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs index 87ae7090..7e7a6b7b 100644 --- a/source/Components/AvalonDock/DockingManager.cs +++ b/source/Components/AvalonDock/DockingManager.cs @@ -1408,7 +1408,12 @@ private void ClearLogicalChildrenList() #region IOverlayWindowHost Interface /// - bool IOverlayWindowHost.HitTest(Point dragPoint) + bool IOverlayWindowHost.HitTestScreen(Point dragPoint) + { + return HitTest(this.TransformToDeviceDPI(dragPoint)); + } + + bool HitTest(Point dragPoint) { try { @@ -1430,7 +1435,6 @@ bool IOverlayWindowHost.HitTest(Point dragPoint) IOverlayWindow IOverlayWindowHost.ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow) { CreateOverlayWindow(); - _overlayWindow.Owner = draggingWindow; _overlayWindow.EnableDropTargets(); _overlayWindow.Show(); return _overlayWindow; @@ -1442,6 +1446,8 @@ void IOverlayWindowHost.HideOverlayWindow() _areas = null; _overlayWindow.Owner = null; _overlayWindow.HideDropTargets(); + _overlayWindow.Close(); + _overlayWindow = null; } /// @@ -2090,7 +2096,11 @@ private void SetupAutoHideWindow() private void CreateOverlayWindow() { if (_overlayWindow == null) + { _overlayWindow = new OverlayWindow(this); + } + _overlayWindow.Owner = Window.GetWindow(this); + var rectWindow = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); _overlayWindow.Left = rectWindow.Left; _overlayWindow.Top = rectWindow.Top;