Skip to content

Commit

Permalink
Merge pull request #164 from Dirkster99/Issue_136_CanDock
Browse files Browse the repository at this point in the history
Implemented CanDock property to lock layout as descriped in #136
  • Loading branch information
Dirkster99 authored Jun 9, 2020
2 parents 3838ea7 + 9923762 commit 6b611fa
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 12 deletions.
20 changes: 17 additions & 3 deletions source/Components/AvalonDock/Controls/DragService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,25 @@ internal void Abort()

#region Private Methods

/// <summary>
/// Adds <see cref="IOverlayWindowHost"/>s into a private collection of possible
/// drop target hosts that can show a drop target button to drop a dragged
/// <see cref="LayoutAnchorableFloatingWindowControl"/> or
/// <see cref="LayoutDocumentFloatingWindowControl"/> into it.
/// </summary>
private void GetOverlayWindowHosts()
{
_overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType<LayoutAnchorableFloatingWindowControl>().Where(fw => fw != _floatingWindow && fw.IsVisible));
_overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType<LayoutDocumentFloatingWindowControl>().Where(fw => fw != _floatingWindow && fw.IsVisible));
_overlayWindowHosts.Add(_manager);
if (_manager.Layout.RootPanel.CanDock)
{
// Add LayoutFloatingWindowControls as drop target hosts
// 1) Don't drop a floating window on to itself
// 2) Use this Drop target if its visible
_overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType<LayoutAnchorableFloatingWindowControl>().Where(fw => fw != _floatingWindow && fw.IsVisible));
_overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType<LayoutDocumentFloatingWindowControl>().Where(fw => fw != _floatingWindow && fw.IsVisible));

// Add dockingManager itself as a drop target host
_overlayWindowHosts.Add(_manager);
}
}

#endregion Private Methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ internal LayoutAnchorableFloatingWindowControl(LayoutAnchorableFloatingWindow mo

#region Properties

/// <inheritdoc />
public override ILayoutElement Model => _model;

#region SingleContentLayoutItem

/// <summary><see cref="SingleContentLayoutItem"/> dependency property.</summary>
Expand Down Expand Up @@ -176,10 +179,6 @@ IEnumerable<IDropArea> IOverlayWindowHost.GetDropAreas(LayoutFloatingWindowContr
#endregion Public Methods

#region Overrides

/// <inheritdoc />
public override ILayoutElement Model => _model;

/// <inheritdoc />
protected override void OnInitialized(EventArgs e)
{
Expand Down
4 changes: 4 additions & 0 deletions source/Components/AvalonDock/Controls/OverlayWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ IEnumerable<IDropTarget> IOverlayWindow.GetTargets()
{
case DropAreaType.DockingManager:
{
// Dragging over DockingManager -> Add DropTarget Area
var dropAreaDockingManager = visibleArea as DropArea<DockingManager>;
yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetLeft.GetScreenArea(), DropTargetType.DockingManagerDockLeft);
yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetTop.GetScreenArea(), DropTargetType.DockingManagerDockTop);
Expand All @@ -365,6 +366,7 @@ IEnumerable<IDropTarget> IOverlayWindow.GetTargets()
break;
case DropAreaType.AnchorablePane:
{
// Dragging over AnchorablePane -> Add DropTarget Area
var dropAreaAnchorablePane = visibleArea as DropArea<LayoutAnchorablePaneControl>;
yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetLeft.GetScreenArea(), DropTargetType.AnchorablePaneDockLeft);
yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetTop.GetScreenArea(), DropTargetType.AnchorablePaneDockTop);
Expand Down Expand Up @@ -399,6 +401,7 @@ IEnumerable<IDropTarget> IOverlayWindow.GetTargets()
break;
case DropAreaType.DocumentPane:
{
// Dragging over DocumentPane -> Add DropTarget Area
bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow;
if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null)
{
Expand Down Expand Up @@ -483,6 +486,7 @@ IEnumerable<IDropTarget> IOverlayWindow.GetTargets()
break;
case DropAreaType.DocumentPaneGroup:
{
// Dragging over DocumentPaneGroup -> Add DropTarget Area
var dropAreaDocumentPane = visibleArea as DropArea<LayoutDocumentPaneGroupControl>;
if (_documentPaneDropTargetInto.IsVisible)
yield return new DocumentPaneGroupDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneGroupDockInside);
Expand Down
4 changes: 3 additions & 1 deletion source/Components/AvalonDock/Layout/LayoutAnchorable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ public bool CanDockAsTabbedDocument
}
}

/// <summary>Gets/sets whether a document can be dragged (to be dropped in a different location) or not. Use this property in conjunction with <see cref="CanMove"/> and <see cref="CanClose"/> to lock a document in its layout position.</summary>
/// <summary>Gets/sets whether a document can be dragged (to be dropped in a different location) or not.
/// Use this property in conjunction with <see cref="CanMove"/> and <see cref="CanClose"/> and <see cref="LayoutPanel.CanDock"/>
/// to lock an anchorable in its layout position.</summary>
public bool CanMove
{
get => _canMove;
Expand Down
4 changes: 3 additions & 1 deletion source/Components/AvalonDock/Layout/LayoutDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class LayoutDocument : LayoutContent

#region Properties

/// <summary>Gets/sets whether a document can be dragged (to be dropped in a different location) or not. Use this property in conjunction with <see cref="CanMove"/> and <see cref="CanClose"/> to lock a document in its layout position.</summary>
/// <summary>Gets/sets whether a document can be dragged (to be dropped in a different location) or not.
/// Use this property in conjunction with <see cref="CanMove"/> and <see cref="CanClose"/> and <see cref="LayoutPanel.CanDock"/>
/// to lock a document in its layout position.</summary>
public bool CanMove
{
get => _canMove;
Expand Down
41 changes: 41 additions & 0 deletions source/Components/AvalonDock/Layout/LayoutPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This program is provided to you under the terms of the Microsoft Public
using System.Linq;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Windows;

namespace AvalonDock.Layout
{
Expand Down Expand Up @@ -52,6 +53,32 @@ public Orientation Orientation
}
}

#region CanDock
/// <summary>
/// Using a DependencyProperty as the backing store for thhe <see cref="CanDock"/> property.
/// </summary>
public static readonly DependencyProperty CanDockProperty =
DependencyProperty.Register("CanDock", typeof(bool),
typeof(LayoutPanel), new PropertyMetadata(true));

/// <summary>
/// Gets/sets dependency property that determines whether docking of dragged items
/// is enabled or not. This property can be used disable/enable docking of
/// dragged FloatingWindowControls.
///
/// This property should only be set to false if:
/// <see cref="LayoutAnchorable.CanMove"/> and <see cref="LayoutDocument.CanMove"/>
/// are false since users will otherwise be able to:
/// 1) Drag an item away
/// 2) But won't be able to dock it agin.
/// </summary>
public bool CanDock
{
get { return (bool)GetValue(CanDockProperty); }
set { SetValue(CanDockProperty, value); }
}
#endregion CanDock

#endregion Properties

#region Overrides
Expand All @@ -63,14 +90,28 @@ public Orientation Orientation
public override void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteAttributeString(nameof(Orientation), Orientation.ToString());

if (CanDock == false)
writer.WriteAttributeString(nameof(CanDock), CanDock.ToString());

base.WriteXml(writer);
}

/// <inheritdoc />
/// <summary>
/// This method is never invoked - <see cref="LayoutRoot"/>.ReadRootPanel()
/// for implementation of this reader.
/// </summary>
public override void ReadXml(System.Xml.XmlReader reader)
{
if (reader.MoveToAttribute(nameof(Orientation)))
Orientation = (Orientation)Enum.Parse(typeof(Orientation), reader.Value, true);
if (reader.MoveToAttribute(nameof(CanDock)))
{
var canDockStr = reader.GetAttribute("CanDock");
if (canDockStr != null)
CanDock = bool.Parse(canDockStr);
}
base.ReadXml(reader);
}

Expand Down
22 changes: 19 additions & 3 deletions source/Components/AvalonDock/Layout/LayoutRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -548,10 +548,10 @@ void IXmlSerializable.ReadXml(XmlReader reader)
return;
}

var layoutPanelElements = ReadRootPanel(reader, out var orientation);
var layoutPanelElements = ReadRootPanel(reader, out var orientation, out var canDock);
if (layoutPanelElements != null)
{
RootPanel = new LayoutPanel { Orientation = orientation };
RootPanel = new LayoutPanel { Orientation = orientation, CanDock = canDock };
//Add all children to RootPanel
foreach (var panel in layoutPanelElements) RootPanel.Children.Add(panel);
}
Expand Down Expand Up @@ -786,9 +786,20 @@ private void FillLayoutAnchorSide(XmlReader reader, LayoutAnchorSide layoutAncho
}
}

private List<ILayoutPanelElement> ReadRootPanel(XmlReader reader, out Orientation orientation)
/// <summary>
/// Reads all properties of the <see cref="LayoutPanel"/> and returns them.
/// </summary>
/// <param name="reader"></param>
/// <param name="orientation"></param>
/// <param name="canDock"></param>
/// <returns></returns>
private List<ILayoutPanelElement> ReadRootPanel(XmlReader reader
, out Orientation orientation
, out bool canDock)
{
orientation = Orientation.Horizontal;
canDock = true;

var result = new List<ILayoutPanelElement>();
var startElementName = reader.LocalName;
reader.Read();
Expand All @@ -799,6 +810,11 @@ private List<ILayoutPanelElement> ReadRootPanel(XmlReader reader, out Orientatio
if (reader.LocalName.Equals(nameof(RootPanel)))
{
orientation = (Orientation)Enum.Parse(typeof(Orientation),reader.GetAttribute(nameof(Orientation)), true);

var canDockStr = reader.GetAttribute("CanDock");
if (canDockStr != null)
canDock = bool.Parse(canDockStr);

reader.Read();
while (true)
{
Expand Down

0 comments on commit 6b611fa

Please sign in to comment.