Skip to content

Commit

Permalink
Merge pull request #25 from Dirkster99/2ndMonitor_Support
Browse files Browse the repository at this point in the history
2nd monitor support
  • Loading branch information
Dirkster99 authored May 2, 2019
2 parents c1e5893 + fbf3b7e commit 3522efc
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 5 deletions.
14 changes: 11 additions & 3 deletions source/Components/Xceed.Wpf.AvalonDock/DockingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,20 @@ protected virtual void OnLayoutChanged( LayoutRoot oldLayout, LayoutRoot newLayo

foreach( var fw in _fwList )
{
//fw.Owner = Window.GetWindow(this);
//fw.SetParentToMainWindowOf(this);
var window = fw.Model as LayoutAnchorableFloatingWindow;
if (window != null && window.RootPanel.IsMaximized)
{
fw.WindowState = WindowState.Normal;
fw.Show();
fw.WindowState = WindowState.Maximized;
}
else
fw.Show();
//fw.Owner = Window.GetWindow(this);
//fw.SetParentToMainWindowOf(this);
}
}


if( newLayout != null )
{
newLayout.PropertyChanged += new PropertyChangedEventHandler( OnLayoutRootPropertyChanged );
Expand Down
9 changes: 8 additions & 1 deletion source/Components/Xceed.Wpf.AvalonDock/Layout/Extentions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,14 @@ public static AnchorSide GetSide( this ILayoutElement element )

#region Internal Methods

internal static void KeepInsideNearestMonitor( this ILayoutElementForFloatingWindow paneInsideFloatingWindow )
/// <summary>
/// Removed with Issue 20 since Win32 definition seems to be buggy here
/// (GetMonitorInfo always returns false on rectangle returned from Win32Helper.MonitorFromRect())
///
/// <see cref="ILayoutElementForFloatingWindowExtension"/> for replacement candidate.
/// </summary>
/// <param name="paneInsideFloatingWindow"></param>
internal static void KeepInsideNearestMonitor_Issue20( this ILayoutElementForFloatingWindow paneInsideFloatingWindow )
{
Win32Helper.RECT r = new Win32Helper.RECT();
r.Left = ( int )paneInsideFloatingWindow.FloatingLeft;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
namespace Xceed.Wpf.AvalonDock.Layout
{
using System.Runtime.InteropServices;
using System.Windows;

/// <summary>
/// SetWindowPlacement won't correct placement for WPF tool windows
///
/// https://stackoverflow.com/questions/19203031/setwindowplacement-wont-correct-placement-for-wpf-tool-windows
/// </summary>
public static class ILayoutElementForFloatingWindowExtension
{
// RECT structure required by WINDOWPLACEMENT structure
[StructLayout(LayoutKind.Sequential)]
internal struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;

public RECT(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}

internal static void KeepInsideNearestMonitor(this ILayoutElementForFloatingWindow paneInsideFloatingWindow)
{
RECT normalPosition = new RECT();
normalPosition.Left = (int)paneInsideFloatingWindow.FloatingLeft;
normalPosition.Top = (int)paneInsideFloatingWindow.FloatingTop;
normalPosition.Bottom = normalPosition.Top + (int)paneInsideFloatingWindow.FloatingHeight;
normalPosition.Right = normalPosition.Left + (int)paneInsideFloatingWindow.FloatingWidth;

// Are we using only one monitor?
if (SystemParameters.PrimaryScreenWidth == SystemParameters.VirtualScreenWidth &&
SystemParameters.PrimaryScreenHeight == SystemParameters.VirtualScreenHeight)
{
RECT primaryscreen = new RECT(0,0, (int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight);

if (!RectanglesIntersect(normalPosition, primaryscreen))
{
normalPosition = PlaceOnScreen(primaryscreen, normalPosition);

paneInsideFloatingWindow.FloatingLeft = normalPosition.Left;
paneInsideFloatingWindow.FloatingTop = normalPosition.Top;
paneInsideFloatingWindow.FloatingHeight = normalPosition.Bottom - normalPosition.Top;
paneInsideFloatingWindow.FloatingWidth = normalPosition.Right - normalPosition.Left;
}

return;
}
else
{
RECT primaryscreen = new RECT(0, 0, (int)SystemParameters.VirtualScreenWidth, (int)SystemParameters.VirtualScreenHeight);

if (!RectanglesIntersect(normalPosition, primaryscreen))
{
normalPosition = PlaceOnScreen(primaryscreen, normalPosition);

paneInsideFloatingWindow.FloatingLeft = normalPosition.Left;
paneInsideFloatingWindow.FloatingTop = normalPosition.Top;
paneInsideFloatingWindow.FloatingHeight = normalPosition.Bottom - normalPosition.Top;
paneInsideFloatingWindow.FloatingWidth = normalPosition.Right - normalPosition.Left;
}

return;
}
}

/// <summary>
/// Determine whether <paramref name="a"/> and <paramref name="b"/>
/// have an intersection or not.
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private static bool RectanglesIntersect(RECT a, RECT b)
{
if (a.Left > b.Right || a.Right < b.Left)
{
return false;
}

if (a.Top > b.Bottom || a.Bottom < b.Top)
{
return false;
}

return true;
}

/// <summary>
/// Determine the place where <paramref name="windowRect"/> should be placed
/// inside the <paramref name="monitorRect"/>.
/// </summary>
/// <param name="monitorRect"></param>
/// <param name="windowRect"></param>
/// <returns></returns>
private static RECT PlaceOnScreen(RECT monitorRect, RECT windowRect)
{
int monitorWidth = monitorRect.Right - monitorRect.Left;
int monitorHeight = monitorRect.Bottom - monitorRect.Top;

if (windowRect.Right < monitorRect.Left)
{
// Off left side
int width = windowRect.Right - windowRect.Left;
if (width > monitorWidth)
{
width = monitorWidth;
}

windowRect.Left = monitorRect.Left;
windowRect.Right = windowRect.Left + width;
}
else if (windowRect.Left > monitorRect.Right)
{
// Off right side
int width = windowRect.Right - windowRect.Left;
if (width > monitorWidth)
{
width = monitorWidth;
}

windowRect.Right = monitorRect.Right;
windowRect.Left = windowRect.Right - width;
}

if (windowRect.Bottom < monitorRect.Top)
{
// Off top
int height = windowRect.Bottom - windowRect.Top;
if (height > monitorHeight)
{
height = monitorHeight;
}

windowRect.Top = monitorRect.Top;
windowRect.Bottom = windowRect.Top + height;
}
else if (windowRect.Top > monitorRect.Bottom)
{
// Off bottom
int height = windowRect.Bottom - windowRect.Top;
if (height > monitorHeight)
{
height = monitorHeight;
}

windowRect.Bottom = monitorRect.Bottom;
windowRect.Top = windowRect.Bottom - height;
}

return windowRect;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
Expand Down Expand Up @@ -158,6 +158,7 @@
<Compile Include="Layout\ILayoutControl.cs" />
<Compile Include="Layout\ILayoutDocumentPane.cs" />
<Compile Include="Layout\ILayoutElement.cs" />
<Compile Include="Layout\ILayoutElementForFloatingWindowExtension.cs" />
<Compile Include="Layout\ILayoutElementWithVisibility.cs" />
<Compile Include="Layout\ILayoutGroup.cs" />
<Compile Include="Layout\ILayoutOrientableElement.cs" />
Expand Down

0 comments on commit 3522efc

Please sign in to comment.