You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
18 KiB
336 lines
18 KiB
/*************************************************************************************
|
|
|
|
Extended WPF Toolkit
|
|
|
|
Copyright (C) 2007-2013 Xceed Software Inc.
|
|
|
|
This program is provided to you under the terms of the Microsoft Public
|
|
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
|
|
|
|
For more features, controls, and fast professional support,
|
|
pick up the Plus Edition at http://xceed.com/wpf_toolkit
|
|
|
|
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|
|
|
***********************************************************************************/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using Xceed.Wpf.AvalonDock.Layout;
|
|
|
|
namespace Xceed.Wpf.AvalonDock.Controls
|
|
{
|
|
internal class AnchorablePaneDropTarget : DropTarget<LayoutAnchorablePaneControl>
|
|
{
|
|
internal AnchorablePaneDropTarget(LayoutAnchorablePaneControl paneControl, Rect detectionRect, DropTargetType type)
|
|
: base(paneControl, detectionRect, type)
|
|
{
|
|
_targetPane = paneControl;
|
|
}
|
|
|
|
internal AnchorablePaneDropTarget(LayoutAnchorablePaneControl paneControl, Rect detectionRect, DropTargetType type, int tabIndex)
|
|
: base(paneControl, detectionRect, type)
|
|
{
|
|
_targetPane = paneControl;
|
|
_tabIndex = tabIndex;
|
|
}
|
|
|
|
|
|
LayoutAnchorablePaneControl _targetPane;
|
|
|
|
int _tabIndex = -1;
|
|
|
|
protected override void Drop(LayoutAnchorableFloatingWindow floatingWindow)
|
|
{
|
|
ILayoutAnchorablePane targetModel = _targetPane.Model as ILayoutAnchorablePane;
|
|
LayoutAnchorable anchorableActive = floatingWindow.Descendents().OfType<LayoutAnchorable>().FirstOrDefault();
|
|
|
|
switch (Type)
|
|
{
|
|
case DropTargetType.AnchorablePaneDockBottom:
|
|
#region DropTargetType.AnchorablePaneDockBottom
|
|
{
|
|
var parentModel = targetModel.Parent as ILayoutGroup;
|
|
var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
|
|
int insertToIndex = parentModel.IndexOfChild(targetModel);
|
|
|
|
if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical &&
|
|
parentModel.ChildrenCount == 1)
|
|
parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical;
|
|
|
|
if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical)
|
|
{
|
|
var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup;
|
|
if (layoutAnchorablePaneGroup != null &&
|
|
(layoutAnchorablePaneGroup.Children.Count == 1 ||
|
|
layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical))
|
|
{
|
|
var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray();
|
|
for (int i = 0; i < anchorablesToMove.Length; i++)
|
|
parentModel.InsertChildAt(insertToIndex + 1 + i, anchorablesToMove[i]);
|
|
}
|
|
else
|
|
parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel);
|
|
}
|
|
else
|
|
{
|
|
var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
|
|
var newOrientedPanel = new LayoutAnchorablePaneGroup()
|
|
{
|
|
Orientation = System.Windows.Controls.Orientation.Vertical,
|
|
DockWidth = targetModelAsPositionableElement.DockWidth,
|
|
DockHeight = targetModelAsPositionableElement.DockHeight,
|
|
};
|
|
|
|
parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
|
|
newOrientedPanel.Children.Add(targetModel);
|
|
newOrientedPanel.Children.Add(floatingWindow.RootPanel);
|
|
|
|
}
|
|
}
|
|
break;
|
|
#endregion
|
|
case DropTargetType.AnchorablePaneDockTop:
|
|
#region DropTargetType.AnchorablePaneDockTop
|
|
{
|
|
var parentModel = targetModel.Parent as ILayoutGroup;
|
|
var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
|
|
int insertToIndex = parentModel.IndexOfChild(targetModel);
|
|
|
|
if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical &&
|
|
parentModel.ChildrenCount == 1)
|
|
parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical;
|
|
|
|
if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical)
|
|
{
|
|
var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup;
|
|
if (layoutAnchorablePaneGroup != null &&
|
|
(layoutAnchorablePaneGroup.Children.Count == 1 ||
|
|
layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical))
|
|
{
|
|
var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray();
|
|
for (int i = 0; i < anchorablesToMove.Length; i++)
|
|
parentModel.InsertChildAt(insertToIndex + i, anchorablesToMove[i]);
|
|
}
|
|
else
|
|
parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel);
|
|
}
|
|
else
|
|
{
|
|
var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
|
|
var newOrientedPanel = new LayoutAnchorablePaneGroup()
|
|
{
|
|
Orientation = System.Windows.Controls.Orientation.Vertical,
|
|
DockWidth = targetModelAsPositionableElement.DockWidth,
|
|
DockHeight = targetModelAsPositionableElement.DockHeight,
|
|
};
|
|
|
|
parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
|
|
//the floating window must be added after the target modal as it could be raise a CollectGarbage call
|
|
newOrientedPanel.Children.Add(targetModel);
|
|
newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel);
|
|
|
|
}
|
|
}
|
|
break;
|
|
#endregion
|
|
case DropTargetType.AnchorablePaneDockLeft:
|
|
#region DropTargetType.AnchorablePaneDockLeft
|
|
{
|
|
var parentModel = targetModel.Parent as ILayoutGroup;
|
|
var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
|
|
int insertToIndex = parentModel.IndexOfChild(targetModel);
|
|
|
|
if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal &&
|
|
parentModel.ChildrenCount == 1)
|
|
parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal;
|
|
|
|
if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal)
|
|
{
|
|
var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup;
|
|
if (layoutAnchorablePaneGroup != null &&
|
|
(layoutAnchorablePaneGroup.Children.Count == 1 ||
|
|
layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal))
|
|
{
|
|
var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray();
|
|
for (int i = 0; i < anchorablesToMove.Length; i++)
|
|
parentModel.InsertChildAt(insertToIndex + i, anchorablesToMove[i]);
|
|
}
|
|
else
|
|
parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel);
|
|
}
|
|
else
|
|
{
|
|
var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
|
|
var newOrientedPanel = new LayoutAnchorablePaneGroup()
|
|
{
|
|
Orientation = System.Windows.Controls.Orientation.Horizontal,
|
|
DockWidth = targetModelAsPositionableElement.DockWidth,
|
|
DockHeight = targetModelAsPositionableElement.DockHeight,
|
|
};
|
|
|
|
parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
|
|
//the floating window must be added after the target modal as it could be raise a CollectGarbage call
|
|
newOrientedPanel.Children.Add(targetModel);
|
|
newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel);
|
|
|
|
}
|
|
}
|
|
break;
|
|
#endregion
|
|
case DropTargetType.AnchorablePaneDockRight:
|
|
#region DropTargetType.AnchorablePaneDockRight
|
|
{
|
|
var parentModel = targetModel.Parent as ILayoutGroup;
|
|
var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
|
|
int insertToIndex = parentModel.IndexOfChild(targetModel);
|
|
|
|
if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal &&
|
|
parentModel.ChildrenCount == 1)
|
|
parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal;
|
|
|
|
if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal)
|
|
{
|
|
var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup;
|
|
if (layoutAnchorablePaneGroup != null &&
|
|
(layoutAnchorablePaneGroup.Children.Count == 1 ||
|
|
layoutAnchorablePaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal))
|
|
{
|
|
var anchorablesToMove = layoutAnchorablePaneGroup.Children.ToArray();
|
|
for (int i = 0; i < anchorablesToMove.Length; i++)
|
|
parentModel.InsertChildAt(insertToIndex + 1 + i, anchorablesToMove[i]);
|
|
}
|
|
else
|
|
parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel);
|
|
}
|
|
else
|
|
{
|
|
var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
|
|
var newOrientedPanel = new LayoutAnchorablePaneGroup()
|
|
{
|
|
Orientation = System.Windows.Controls.Orientation.Horizontal,
|
|
DockWidth = targetModelAsPositionableElement.DockWidth,
|
|
DockHeight = targetModelAsPositionableElement.DockHeight,
|
|
};
|
|
|
|
parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
|
|
newOrientedPanel.Children.Add(targetModel);
|
|
newOrientedPanel.Children.Add(floatingWindow.RootPanel);
|
|
|
|
}
|
|
}
|
|
break;
|
|
#endregion
|
|
|
|
|
|
case DropTargetType.AnchorablePaneDockInside:
|
|
#region DropTargetType.AnchorablePaneDockInside
|
|
{
|
|
var paneModel = targetModel as LayoutAnchorablePane;
|
|
var layoutAnchorablePaneGroup = floatingWindow.RootPanel as LayoutAnchorablePaneGroup;
|
|
|
|
int i = _tabIndex == -1 ? 0 : _tabIndex;
|
|
foreach (var anchorableToImport in
|
|
layoutAnchorablePaneGroup.Descendents().OfType<LayoutAnchorable>().ToArray())
|
|
{
|
|
paneModel.Children.Insert(i, anchorableToImport);
|
|
i++;
|
|
}
|
|
|
|
}
|
|
break;
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
anchorableActive.IsActive = true;
|
|
|
|
base.Drop(floatingWindow);
|
|
}
|
|
|
|
public override System.Windows.Media.Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel)
|
|
{
|
|
//var anchorablePaneDropTarget = target as AnchorablePaneDropTarget;
|
|
var anchorableFloatingWindowModel = floatingWindowModel as LayoutAnchorableFloatingWindow;
|
|
var layoutAnchorablePane = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElement;
|
|
var layoutAnchorablePaneWithActualSize = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElementWithActualSize;
|
|
|
|
switch (Type)
|
|
{
|
|
case DropTargetType.AnchorablePaneDockBottom:
|
|
{
|
|
var targetScreenRect = TargetElement.GetScreenArea();
|
|
targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top);
|
|
|
|
targetScreenRect.Offset(0.0, targetScreenRect.Height / 2.0);
|
|
targetScreenRect.Height /= 2.0;
|
|
|
|
return new RectangleGeometry(targetScreenRect);
|
|
}
|
|
case DropTargetType.AnchorablePaneDockTop:
|
|
{
|
|
var targetScreenRect = TargetElement.GetScreenArea();
|
|
targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top);
|
|
|
|
targetScreenRect.Height /= 2.0;
|
|
|
|
return new RectangleGeometry(targetScreenRect);
|
|
}
|
|
case DropTargetType.AnchorablePaneDockLeft:
|
|
{
|
|
var targetScreenRect = TargetElement.GetScreenArea();
|
|
targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top);
|
|
|
|
targetScreenRect.Width /= 2.0;
|
|
|
|
return new RectangleGeometry(targetScreenRect);
|
|
}
|
|
case DropTargetType.AnchorablePaneDockRight:
|
|
{
|
|
var targetScreenRect = TargetElement.GetScreenArea();
|
|
targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top);
|
|
|
|
targetScreenRect.Offset(targetScreenRect.Width / 2.0, 0.0);
|
|
targetScreenRect.Width /= 2.0;
|
|
|
|
return new RectangleGeometry(targetScreenRect);
|
|
}
|
|
case DropTargetType.AnchorablePaneDockInside:
|
|
{
|
|
var targetScreenRect = TargetElement.GetScreenArea();
|
|
targetScreenRect.Offset(-overlayWindow.Left, -overlayWindow.Top);
|
|
|
|
if (_tabIndex == -1)
|
|
{
|
|
return new RectangleGeometry(targetScreenRect);
|
|
}
|
|
else
|
|
{
|
|
var translatedDetectionRect = new Rect(DetectionRects[0].TopLeft, DetectionRects[0].BottomRight);
|
|
translatedDetectionRect.Offset(-overlayWindow.Left, -overlayWindow.Top);
|
|
var pathFigure = new PathFigure();
|
|
pathFigure.StartPoint = targetScreenRect.TopLeft;
|
|
pathFigure.Segments.Add(new LineSegment() { Point = new Point(targetScreenRect.Left, translatedDetectionRect.Top) });
|
|
pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.TopLeft });
|
|
pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.BottomLeft });
|
|
pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.BottomRight });
|
|
pathFigure.Segments.Add(new LineSegment() { Point = translatedDetectionRect.TopRight });
|
|
pathFigure.Segments.Add(new LineSegment() { Point = new Point(targetScreenRect.Right, translatedDetectionRect.Top) });
|
|
pathFigure.Segments.Add(new LineSegment() { Point = targetScreenRect.TopRight });
|
|
pathFigure.IsClosed = true;
|
|
pathFigure.IsFilled = true;
|
|
pathFigure.Freeze();
|
|
return new PathGeometry(new PathFigure[] { pathFigure });
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|