public Dictionary<RectRate, Rectangle> GetSplitPaneRect(Rectangle pane, DockDirection dire, double splitRate) { Dictionary<RectRate, Rectangle> dictionary = new Dictionary<RectRate, Rectangle>(); Rectangle rectA = new Rectangle(pane.Location, pane.Size); Rectangle rectB = new Rectangle(pane.Location, pane.Size); switch (dire) { case DockDirection.Top: rectA.Height = (int)(pane.Height * splitRate); rectB.Height -= rectA.Height; rectB.Location = new Point(rectA.Left, rectA.Bottom); break; case DockDirection.Bottom: rectA.Height = (int)(pane.Height * splitRate); rectB.Height -= rectA.Height; rectA.Location = new Point(rectB.Left, rectB.Bottom); break; case DockDirection.Left: rectA.Width = (int)(pane.Width * splitRate); rectB.Width -= rectA.Width; rectB.Location = new Point(rectA.Right, rectA.Top); break; case DockDirection.Right: rectA.Width = (int)(pane.Width * splitRate); rectB.Width -= rectA.Width; rectA.Location = new Point(rectB.Right, rectB.Top); break; } dictionary.Add(RectRate.SmallRect, rectA); dictionary.Add(RectRate.LargeRect, rectB); return dictionary; }
public virtual void Add(DockPaneLayoutEngine pane, DockDirection align, int i) { _children.Insert(i, pane); pane.Removed += pane_Removed; AddEngine(pane); OnPaneAdded(new LayoutEngineAddedEventArgs(this, pane, align, i)); }
private Rect GetDockPreviewRect(DockDirection dockDirection, FrameworkElement adornedElement, ViewElement element) { Rect rect1 = new Rect(); Orientation orientation = Orientation.Horizontal; ViewElement viewElement = adornedElement.DataContext as ViewElement; SplitterLength itemLength = new SplitterLength(); if (dockDirection == DockDirection.FirstValue || dockDirection == DockDirection.Bottom) { orientation = Orientation.Vertical; itemLength = element.DockedHeight; } else if (dockDirection == DockDirection.Left || dockDirection == DockDirection.Right) { orientation = Orientation.Horizontal; itemLength = element.DockedWidth; } Rect rect2; if (dockDirection != DockDirection.Fill) { SplitterPanel panel = (SplitterPanel)null; int targetIndex = -1; this.GetPreviewSplitterPanel(out panel, out targetIndex, dockDirection, viewElement, adornedElement, orientation); rect2 = panel == null || orientation != panel.Orientation ? this.PreviewDockCounterOrientation(dockDirection, adornedElement, viewElement, itemLength, orientation) : this.PreviewDockSameOrientation(dockDirection, panel, viewElement, itemLength, orientation, targetIndex); } else { rect2 = this.PreviewDockFill(adornedElement); } return(rect2); }
private Rect PreviewDockCounterOrientation(DockDirection dockDirection, FrameworkElement adornedElement, ViewElement viewElement, SplitterLength itemLength, Orientation orientation) { List <UIElement> list = new List <UIElement>(); Point point1 = new Point(0.0, 0.0); SplitterItem splitterItem1 = new SplitterItem(); int index = 0; Size availableSize = new Size(adornedElement.ActualWidth, adornedElement.ActualHeight); SplitterItem splitterItem2 = new SplitterItem(); list.Add((UIElement)splitterItem2); if (dockDirection == DockDirection.Right || dockDirection == DockDirection.Bottom) { index = 1; } list.Insert(index, (UIElement)splitterItem1); SplitterLength splitterLength = !(viewElement is MainSite) ? (orientation == Orientation.Horizontal ? viewElement.DockedWidth : viewElement.DockedHeight) : new SplitterLength(1.0, SplitterUnitType.Fill); SplitterPanel.SetSplitterLength((UIElement)splitterItem2, splitterLength); SplitterPanel.SetSplitterLength((UIElement)splitterItem1, itemLength); Point point2 = DpiHelper.DeviceToLogicalUnits(adornedElement.PointToScreen(new Point(0.0, 0.0))); Rect[] elementBounds; SplitterPanel.Measure(availableSize, orientation, (IEnumerable)list, false, out elementBounds, (SplitterPanel)null); Rect rect = elementBounds[index]; rect.Offset(point2.X, point2.Y); return(rect); }
public override void AddPane(DockPaneBase pane, DockDirection dire, double splitRate) { if (pane.Neigh.Owner != null) pane.Remove(); Neigh.Add(pane, dire); _layoutEngine.AddPane(pane, dire, splitRate); }
private void UpdateDockPreview(DragAbsoluteEventArgs args, FloatingElement floatingElement) { DockManager.DockSiteHitTestResult hitElement = this.FindHitElement(args.ScreenPoint, (Predicate <DockManager.DockSite>)(s => s.Visual != floatingElement)); if (hitElement != null) { DockSiteAdorner ancestorOrSelf1 = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestorOrSelf <DockSiteAdorner>(hitElement.VisualHit); DockAdornerWindow ancestorOrSelf2 = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestorOrSelf <DockAdornerWindow>(hitElement.VisualHit); DockTarget ancestorOrSelf3 = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestorOrSelf <DockTarget>(hitElement.VisualHit); FloatSite floatSite = floatingElement.Content as FloatSite; DockDirection dockDirection = DockDirection.Fill; FrameworkElement adornedElement = (FrameworkElement)null; if (floatSite == null) { throw new InvalidOperationException("Dragging element must be a FloatSite"); } if (floatSite.Child == null) { throw new InvalidOperationException("floatSite must have at least one child."); } ViewElement child = floatSite.Child; if (this.IsValidFillPreviewOperation(ancestorOrSelf3, child)) { dockDirection = DockDirection.Fill; adornedElement = ancestorOrSelf3.AdornmentTarget == null ? (FrameworkElement)ancestorOrSelf3 : ancestorOrSelf3.AdornmentTarget; } if (ancestorOrSelf1 != null && ancestorOrSelf2 != null && ancestorOrSelf2.AdornedElement != null) { dockDirection = ancestorOrSelf1.DockDirection; adornedElement = ancestorOrSelf2.AdornedElement; if (!ancestorOrSelf1.CreatesDocumentGroup && dockDirection != DockDirection.Fill && adornedElement.DataContext is DocumentGroup) { adornedElement = (FrameworkElement)Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestor <DocumentGroupContainerControl>((Visual)adornedElement); } } if (adornedElement != null) { Rect dockPreviewRect = this.GetDockPreviewRect(dockDirection, adornedElement, child); this.DockPreviewWindow.Left = dockPreviewRect.Left; this.DockPreviewWindow.Top = dockPreviewRect.Top; this.DockPreviewWindow.Width = dockPreviewRect.Width; this.DockPreviewWindow.Height = dockPreviewRect.Height; this.OnDockPreviewWindowShowing(this.DockPreviewWindow, dockDirection); this.DockPreviewWindow.Show(); } else { this.HideDockPreview(); } } else { this.HideDockPreview(); } }
public DockAdornerWindow GetAdornerLayer(DockDirection type) { DockAdornerWindow dockAdornerWindow; if (!this.adorners.TryGetValue(type, out dockAdornerWindow)) { dockAdornerWindow = new DockAdornerWindow(this.Handle); this.adorners[type] = dockAdornerWindow; } return(dockAdornerWindow); }
public override void AddPane(DockBayBase bay, DockDirection dire) { var config = bay.GetConfig(); var pane = bay.Neigh.Children[0]; AddPane(pane, dire); for (int i = config.ChildNode.Count - 1; i > 0; i--) { var child = (DockPaneConfig)config.ChildNode[i]; pane.AddPane((DockPaneBase)child.Node, child.Direction, child.SplitRate); AddChildPane(child); } base.AddChildPane(config.ChildNode[0]); }
public void AddPanesOf(DockBayBase bay, DockDirection align, DockLength size) { var bayConf = bay.GetConfig(); var pneConf = bayConf.Children.FirstOrDefault(); foreach (var p in ((DockBayLayoutEngine)bay.LayoutEngine).DockPanes .Select(l => (DockPaneBase)l.Target).ToArray()) p.Remove(); var pne = (DockPaneBase)pneConf.Target.Target; pne.Length = size; pne.Align = align; Items.Add(pne); foreach (var pConf in bayConf.Children .Skip(1).Reverse() .Concat(pneConf.Children)) { var pane = (DockPaneBase)pConf.Target.Target; pane.Align = pConf.Align; pane.Length = pConf.Size; pneConf.Target.Target.Items.Add(pane); pane.ApplyConfig(pConf); } }
private Rect PreviewDockSameOrientation(DockDirection dockDirection, SplitterPanel panel, ViewElement viewElement, SplitterLength itemLength, Orientation orientation, int originalIndex) { List <UIElement> list = new List <UIElement>(); Point point1 = new Point(0.0, 0.0); SplitterItem splitterItem1 = new SplitterItem(); Size availableSize = new Size(); availableSize.Width = panel.ActualWidth; availableSize.Height = panel.ActualHeight; SplitterItem splitterItem2 = (SplitterItem)null; foreach (SplitterItem splitterItem3 in panel.Children) { list.Add((UIElement)splitterItem3); if (splitterItem3.Content == viewElement) { splitterItem2 = splitterItem3; panel.Children.IndexOf((UIElement)splitterItem2); } } int index = splitterItem2 != null?list.IndexOf((UIElement)splitterItem2) : originalIndex; if (dockDirection == DockDirection.Right || dockDirection == DockDirection.Bottom) { ++index; } list.Insert(index, (UIElement)splitterItem1); SplitterPanel.SetSplitterLength((UIElement)splitterItem1, itemLength); Point point2 = DpiHelper.DeviceToLogicalUnits(panel.PointToScreen(new Point(0.0, 0.0))); Rect[] elementBounds; SplitterPanel.Measure(availableSize, orientation, (IEnumerable)list, false, out elementBounds, panel); Rect rect = elementBounds[index]; rect.Offset(point2.X, point2.Y); return(rect); }
public void PerformDrop(DragAbsoluteEventArgs args) { DragUndockHeader dragUndockHeader = args.OriginalSource as DragUndockHeader; FloatingWindow floatingWindow = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestor <FloatingWindow>((Visual)dragUndockHeader); DockManager.DockSiteHitTestResult hitElement = this.FindHitElement(args.ScreenPoint, (Predicate <DockManager.DockSite>)(s => s.Visual != floatingWindow)); if (hitElement != null) { DockSiteAdorner ancestorOrSelf1 = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestorOrSelf <DockSiteAdorner>(hitElement.VisualHit); DockAdornerWindow ancestorOrSelf2 = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestorOrSelf <DockAdornerWindow>(hitElement.VisualHit); DockTarget dockTarget = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestorOrSelf <DockTarget>(hitElement.VisualHit); DockDirection dockDirection = DockDirection.Fill; bool flag = false; bool createDocumentGroup = false; if (floatingWindow != null && this.IsValidFillPreviewOperation(dockTarget, dragUndockHeader.ViewElement)) { dockDirection = DockDirection.Fill; flag = true; } if (ancestorOrSelf1 != null && ancestorOrSelf2 != null && ancestorOrSelf2.AdornedElement != null) { dockDirection = ancestorOrSelf1.DockDirection; dockTarget = ancestorOrSelf2.AdornedElement as DockTarget; if (DockOperations.AreDockRestrictionsFulfilled(dragUndockHeader.ViewElement, dockTarget.TargetElement)) { flag = true; createDocumentGroup = ancestorOrSelf1.CreatesDocumentGroup; } } if (flag) { PerformanceUtility.MeasurePerformanceUntilRender(PerformanceEvent.DockPalette); dockTarget.RaiseEvent((RoutedEventArgs) new FloatingElementDockedEventArgs(DockManager.FloatingElementDockedEvent, dragUndockHeader.ViewElement, dockDirection, createDocumentGroup)); } } this.ClearAdorners(); }
public DockEventArgs(DockPaneBase pane, DockDirection align) { DockPane = pane; Align = align; }
public PaneAddedEventArgs(DockBase addedpane, DockPaneBase pane, DockDirection dire) : base(pane, dire) { AddedPane = addedpane; }
public sealed override void Add(DockPaneBase pane, DockDirection dire) { pane._neigh.Owner = Owner; pane._neigh.Parent = Node; Children.Add(pane); switch (dire) { case DockDirection.Top: pane.Neigh.Top = Top; pane.Neigh.Left = Left; pane.Neigh.Right = Right; pane.Neigh.Top.Inners.Remove(Node); pane.Neigh.Top.Inners.Add(pane); pane.Neigh.Left.Inners.Add(pane); pane.Neigh.Right.Inners.Add(pane); pane.Neigh.Bottom = DockBaseNeigh.DireInfo.Initialize(pane); Top = DockBaseNeigh.DireInfo.Initialize(Node); pane.Neigh.Bottom.Outers = Top.Inners; Top.Outers = pane.Neigh.Bottom.Inners; break; case DockDirection.Bottom: pane.Neigh.Bottom = Bottom; pane.Neigh.Right = Right; pane.Neigh.Left = Left; pane.Neigh.Bottom.Inners.Remove(Node); Bottom.Inners.Add(pane); Left.Inners.Add(pane); Right.Inners.Add(pane); pane.Neigh.Top = DockBaseNeigh.DireInfo.Initialize(pane); Bottom = DockBaseNeigh.DireInfo.Initialize(Node); Bottom.Outers = pane.Neigh.Top.Inners; pane.Neigh.Top.Outers = Bottom.Inners; break; case DockDirection.Left: pane.Neigh.Bottom = Bottom; pane.Neigh.Left = Left; pane.Neigh.Top = Top; pane.Neigh.Left.Inners.Remove(Node); pane.Neigh.Left.Inners.Add(pane); pane.Neigh.Top.Inners.Add(pane); pane.Neigh.Bottom.Inners.Add(pane); pane.Neigh.Right = DockBaseNeigh.DireInfo.Initialize(pane); Left = DockBaseNeigh.DireInfo.Initialize(Node); Left.Outers = pane.Neigh.Right.Inners; pane.Neigh.Right.Outers = Left.Inners; break; case DockDirection.Right: pane.Neigh.Bottom = Bottom; pane.Neigh.Right = Right; pane.Neigh.Top = Top; pane.Neigh.Right.Inners.Remove(Node); pane.Neigh.Right.Inners.Add(pane); pane.Neigh.Top.Inners.Add(pane); pane.Neigh.Bottom.Inners.Add(pane); pane.Neigh.Left = DockBaseNeigh.DireInfo.Initialize(pane); Right = DockBaseNeigh.DireInfo.Initialize(Node); Right.Outers = pane.Neigh.Left.Inners; pane.Neigh.Left.Outers = Right.Inners; break; default: throw new ApplicationException("direの値が異常です。"); } pane._neigh.Align = dire; OnPaneAdded(new DockEventArgs(pane, dire)); }
public abstract void AddPane(DockPaneBase pane, DockDirection dire, double rate);
public DireInfo GetDireInfoOf(DockDirection dire) { DireInfo res; switch (dire) { case DockDirection.Top: res = Top; break; case DockDirection.Bottom: res = Bottom; break; case DockDirection.Left: res = Left; break; case DockDirection.Right: res = Right; break; default: throw new ArgumentException("引数direが異常です。"); } return res; }
protected virtual void OnDockPreviewWindowShowing(IDockPreviewWindow dockPreviewWindow, DockDirection dockDirection) { }
protected override void OnDockPreviewWindowShowing(IDockPreviewWindow dockPreviewWindow, DockDirection dockDirection) { ((ExpressionDockPreviewWindow)dockPreviewWindow).IsFillPreview = dockDirection == DockDirection.Fill; }
/// <summary> /// MoveSplitter用。Gridリサイズ時に内部のGridの分割サイズを /// 調整することによって内部がそのまま縮小される現象を回避します /// </summary> /// <param name="align">引数distance分だけサイズを増やしていくGridの方向</param> void ResizeNodes(DockDirection align, double distance, double parentSize) { if (align == DockDirection.None) throw new ArgumentException("引数alignをDockDirection.Noneにする事はできません。"); var pane = (DockPaneLayoutEngine)LayoutEngine; var paneNode = this; var isFillNode = ((DockPaneLayoutEngine)LayoutEngine).Parent is DockBayLayoutEngine && ((DockPaneLayoutEngine)LayoutEngine).Parent.Children.First() == LayoutEngine; if ((Align == align || Align == ~align) && !isFillNode) { var actualSz = paneNode.Length.GetSize(parentSize); switch (Align) { case DockDirection.Top: case DockDirection.Bottom: paneNode.Length = new DockLength( (paneNode.ActualHeight + distance) / parentSize, paneNode.Length.Pixel == double.PositiveInfinity ? double.PositiveInfinity : paneNode.ActualHeight + distance); break; case DockDirection.Left: case DockDirection.Right: paneNode.Length = new DockLength( (paneNode.ActualWidth + distance) / parentSize, paneNode.Length.Pixel == double.PositiveInfinity ? double.PositiveInfinity : paneNode.ActualWidth + distance); break; } } var baseSz = (align == DockDirection.Top || align == DockDirection.Bottom ? ItemsPanelSize.Height : ItemsPanelSize.Width) + distance; foreach (var child in pane.Children) { var childNode = (DockPaneBase)child.Target; var childDistance = child.Align == ~align ? 0 : distance; childNode.ResizeNodes(align, childDistance, baseSz); if (child.Align == align || child.Align == ~align) //itemのResize分だけ子要素の展開可能Sizeを更新 baseSz -= (align == DockDirection.Top || align == DockDirection.Bottom ? childNode.ActualHeight : childNode.ActualWidth) + childDistance; //リサイズ方向と同AlignなPaneが見つかったら、以後のPaneの内部 //サイズが変化することは無いため。よってループは終了する。 if (child.Align == align) break; } }
protected void MoveSplitter(DockDirection align, double distance, DockPaneLayoutEngine splitPane) { var pane = (DockPaneLayoutEngine)LayoutEngine; //isFamilyがtrueの時はouterに自Nodeがある //Bayへはまだ未対応Parent.Childrenを弄る必要がある var isFamily = splitPane.OwnNodes.Contains(pane) ? 1 : -1; //splitPaneの子要素Sizeの再計算を行うために親要素での自身が展開可能な最大サイズを出す。 var splitPaneParent = (DockNode)splitPane.Parent.Target; var baseSz = (align == DockDirection.Top || align == DockDirection.Bottom ? splitPaneParent.ItemsPanelSize.Height : splitPaneParent.ItemsPanelSize.Width) - splitPane.Parent.PaneVisualTree .TakeWhile(l => l != splitPane) .Where(l => l.Align == align || l.Align == ~align) .Select(l => l.Align == DockDirection.Top || l.Align == DockDirection.Bottom ? l.Target.ActualHeight : l.Target.ActualWidth) .Sum(); var outer = (DockPaneBase)splitPane.Target; var index = Array.IndexOf(splitPane.Parent.PaneVisualTree.ToArray(), splitPane); var inners = splitPane.Parent.PaneVisualTree .Skip(index + 1) .Take(splitPane.Parent.PaneVisualTree .Skip(index + 1) .TakeWhile(l => l.Align != ~align) .Count() + 1); //CheckResizableSize distance = ResizableDistance(align, isFamily * distance); //Resize outer.ResizeNodes(align, distance * isFamily, baseSz); baseSz -= (align == DockDirection.Top || align == DockDirection.Bottom ? outer.ActualHeight : outer.ActualWidth) + distance; foreach (var item in inners) { //alignはResizePaneのResize方向が入ってる。よって、alignは仕組み上、innersに //とってはResizePaneの存在する反対方向を指し示す値が入る。そのため、innersの //ResizePaneと接しておらず、Resize不要の反対alignPaneは"item.Align == align" //がtrueになる。これを利用してResize量を出す var childDistance = item.Align == align ? 0 : distance; ((DockPaneBase)item.Target).ResizeNodes(~align, childDistance * -isFamily, baseSz); //itemのResize分だけ子要素の展開可能Sizeを更新 if (item.Align == align || item.Align == ~align) baseSz -= (align == DockDirection.Top || align == DockDirection.Bottom ? item.Target.ActualHeight : item.Target.ActualWidth) + childDistance; } }
public void Add(DockDirection direction) { _route.Insert(0, direction); }
private void GetPreviewSplitterPanel(out SplitterPanel panel, out int targetIndex, DockDirection dockDirection, ViewElement viewElement, FrameworkElement adornedElement, Orientation orientation) { targetIndex = -1; panel = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestor <SplitterPanel>((Visual)adornedElement); if (panel != null) { SplitterItem ancestor = Microsoft.VisualStudio.PlatformUI.ExtensionMethods.FindAncestor <SplitterItem>((Visual)adornedElement); targetIndex = SplitterPanel.GetIndex((UIElement)ancestor); } MainSite mainSite = viewElement as MainSite; if (mainSite == null) { return; } DockGroup dockGroup = mainSite.Child as DockGroup; if (dockGroup == null || dockGroup.Orientation != orientation) { return; } panel = (SplitterPanel)null; DependencyObject reference = (DependencyObject)adornedElement; while (panel == null && reference != null) { reference = VisualTreeHelper.GetChild(reference, 0); panel = reference as SplitterPanel; } if (panel == null) { return; } if (dockDirection == DockDirection.Left || dockDirection == DockDirection.FirstValue) { targetIndex = 0; } else { targetIndex = panel.Children.Count - 1; } }
internal void DockForm(Panel panel, CSSDockableForm form, DockDirection direction, bool loadingLayout) { if (AtLeastOneFormDocked == false) { AtLeastOneFormDocked = true; basePanel.Show (); basePanel.Controls.Add (CreateTabControlPanel ()); direction = DockDirection.Center; } DockTabControlPanel tabControlPanel = null; TabPage tab = null; if (direction == DockDirection.Center) { //dock center, just add to the tab control tabControlPanel = (DockTabControlPanel) panel.Controls [0]; } else { //not dock center, do a lot of things SplitContainer split = new SplitContainer (); //the new splitcontainer that will hold the old and new stuff split.TabStop = false; split.MouseUp += onSplitMouseUp; split.SplitterMoved += onSplitterMoved; split.Dock = DockStyle.Fill; SplitterPanel oldPanel = null; SplitterPanel newPanel = null; //set orientation and references based on direction if (direction == DockDirection.Top) { split.Orientation = Orientation.Horizontal; oldPanel = split.Panel2; newPanel = split.Panel1; } else if (direction == DockDirection.Bottom) { split.Orientation = Orientation.Horizontal; oldPanel = split.Panel1; newPanel = split.Panel2; } else if (direction == DockDirection.Left) { split.Orientation = Orientation.Vertical; oldPanel = split.Panel2; newPanel = split.Panel1; } else if (direction == DockDirection.Right) { split.Orientation = Orientation.Vertical; oldPanel = split.Panel1; newPanel = split.Panel2; } oldPanel.Controls.Add (panel.Controls [0]); //add the panel's current controls to the "old" panel of the new split tabControlPanel = CreateTabControlPanel (); newPanel.Controls.Add (tabControlPanel); //add the new form's controls to the "new" panel of the new split if (oldPanel.Controls [0] is DockTabControlPanel) { //add the "old" panel to the dockable panels only if it has a tab control panel DockablePanels.Add (oldPanel); } DockablePanels.Add (newPanel); //add the "new" panel to the dockable panels if (panel != DockablePanels [0]) { //if the target panel is not the first panel DockablePanels.Remove (panel); //remove the target panel from the dockable panels since it now contains a split } panel.Controls.Add (split); //the target panel now contains the split instead of its original tab control panel } tab = new TabPage (form.Text); foreach (Control c in form.Controls) { tab.Controls.Add (c); } tabControlPanel.TabControl.TabPages.Add (tab); tabControlPanel.TabControl.SelectedTab = tab; form.Hide (); form.Docked = true; form.TabVisible = true; form.TabControlPanel = tabControlPanel; form.TabControl = tabControlPanel.TabControl; form.TabPage = tab; form.TabIndex = form.TabControl.SelectedIndex; if (AutoSaveLayout && loadingLayout == false) { SaveLayout (); } }
public override void AddPane(DockPaneBase pane, DockDirection dire) { double splitRate = 0.25; AddPane(pane, dire, splitRate); }
public override void AddPane(DockPaneBase pane, DockDirection dire, double rate) { var dictionary = GetSplitPaneRect(_pane.Bounds, dire, rate); Rectangle rectangle2 = dictionary[DockLayoutEngineBase.RectRate.SmallRect]; Rectangle rectangle = dictionary[DockLayoutEngineBase.RectRate.LargeRect]; _pane.Size = rectangle.Size; _pane.Location = rectangle.Location; pane.Size = rectangle2.Size; pane.Location = rectangle2.Location; }
public FloatingElementDockedEventArgs(RoutedEvent routedEvent, ViewElement content, DockDirection dockDirection, bool createDocumentGroup) : base(routedEvent, content) { this.DockDirection = dockDirection; this.CreateDocumentGroup = createDocumentGroup; }
internal void Initialize(DockNodeLayoutEngine parent, DockBayLayoutEngine owner, DockDirection align) { Initialize(parent, owner); Align = align; }
public void OnDockPaneAddedTest() { var target = new DockBayLayoutEngine(new DockBayBase()); var neighA = new DockPaneLayoutEngine(new DockPaneBase()); var neighB = new DockPaneLayoutEngine(new DockPaneBase()); var idx_logger = 0; var logger = new DockDirection[2]; target.PaneAddedInBay += (sender, e) => { logger[idx_logger++] = e.Align; if (idx_logger > 2) Assert.Fail("DockPaneAddedの呼び出し回数が多すぎです"); }; target.Add(neighA, DockDirection.Top); neighA.Add(neighB, DockDirection.Left); Assert.AreEqual<int>(idx_logger, 2, "DockPaneAddedの呼び出し回数が少なすぎです。"); }
/// <summary>Splitterを持つDockPaneBaseにおいて、拡縮可能なサイズを計算します。</summary> /// <param name="align">拡縮する方向</param> /// <param name="distance">真の値の時は拡大。負の値の時は縮小です。</param> /// <returns></returns> double ResizableDistance(DockDirection align, double distance) { double res; var pane = (DockPaneLayoutEngine)LayoutEngine; DockPaneLayoutEngine splitPane; switch (align) { case DockDirection.Top: case DockDirection.Bottom: splitPane = align == DockDirection.Top ? pane.Top : pane.Bottom; if (distance > 0) res = splitPane.Parent.GetChildrenOf(~align, splitPane.Parent.PaneVisualTree.TakeWhile(l => l != splitPane).Count() + 1) .Min(l => ((DockPaneBase)l.Target).ContentHeight); else res = -splitPane.GetChildrenOf(align) .Min(l => ((DockPaneBase)l.Target).ContentHeight); break; case DockDirection.Left: case DockDirection.Right: splitPane = align == DockDirection.Left ? pane.Left : pane.Right; if (distance > 0) res = splitPane.Parent.GetChildrenOf(~align, splitPane.Parent.PaneVisualTree.TakeWhile(l => l != splitPane).Count() + 1) .Min(l => ((DockPaneBase)l.Target).ContentWidth); else res = -splitPane.GetChildrenOf(align) .Min(l => ((DockPaneBase)l.Target).ContentWidth); break; default: throw new ArgumentException( "引数AlignをDockDirection.Noneにすることはできません。"); } return Math.Abs(distance) < Math.Abs(res) ? distance : res; }
internal override IEnumerable<DockPaneLayoutEngine> GetChildrenOf(DockDirection align, int skip = 0, bool deep = true) { var flg = DockDirection.None; var enumer = Children .Skip(skip) .Where(n => { //初回実行にはflgを初期化 if (Children[skip] == n) flg = DockDirection.None; return n.Align != ~align; }) .TakeWhile(n => { var tmp = flg != align; if (tmp) flg = n.Align; return tmp; }); if (deep) enumer = enumer.SelectMany(n => n.GetChildrenOf(align)); enumer = enumer.Concat(new object[] { null } .Where(o => flg != align) .Select(b => this)); return enumer; }
public void MoveSplitter(DockDirection align, double distance) { var pane = (DockPaneLayoutEngine)LayoutEngine; DockPaneLayoutEngine splitPane; switch (align) { case DockDirection.Top: splitPane = pane.Top; break; case DockDirection.Bottom: splitPane = pane.Bottom; break; case DockDirection.Left: splitPane = pane.Left; break; case DockDirection.Right: splitPane = pane.Right; break; default: throw new ArgumentException( "引数alignはDockDirection.Top, Bottom, Left, Right以外入れることはできません。"); } MoveSplitter(align, distance, splitPane); }
/// <summary>子ノード郡の間に新しいPaneを挿入します</summary> /// <param name="idx">後輩ノードになるPaneのインデックス</param> public override void Add(DockPaneLayoutEngine pane, DockDirection align, int idx) { if (pane == null) throw new ArgumentNullException("第1引数のneighをnullにする事はできません。"); if (pane.Owner != null) throw new ArgumentException("第1引数のneighは使用中です。"); if (align == DockDirection.None) throw new ArgumentException("第2引数のalignをDockDirection.Noneにすることはできません。"); if (idx < 0 || idx > Children.Count) throw new ArgumentOutOfRangeException("第3引数のinsertIndexが有効範囲外です。"); if (align != DockDirection.Top) { var btm = GetChildrenOf(DockDirection.Bottom, idx).FirstOrDefault(); if (btm != null) foreach (var e in pane.GetChildrenOf(DockDirection.Bottom)) e.Bottom = btm.Bottom; } if (align != DockDirection.Bottom) { var top = GetChildrenOf(DockDirection.Top, idx).FirstOrDefault(); if (top != null) foreach (var e in pane.GetChildrenOf(DockDirection.Top)) e.Top = top.Top; } if (align != DockDirection.Left) { var rgh = GetChildrenOf(DockDirection.Right, idx).FirstOrDefault(); if (rgh != null) foreach (var e in pane.GetChildrenOf(DockDirection.Right)) e.Right = rgh.Right; } if (align != DockDirection.Right) { var lft = GetChildrenOf(DockDirection.Left, idx).FirstOrDefault(); if (lft != null) foreach (var e in pane.GetChildrenOf(DockDirection.Left)) e.Left = lft.Left; } switch (align) { case DockDirection.Top: foreach (var paneInner in pane.GetChildrenOf(~align)) paneInner.Bottom = pane; foreach (var thisInner in GetChildrenOf(align, idx)) thisInner.Top = pane; break; case DockDirection.Bottom: foreach (var paneInner in pane.GetChildrenOf(~align)) paneInner.Top = pane; foreach (var thisInner in GetChildrenOf(align, idx)) thisInner.Bottom = pane; break; case DockDirection.Left: foreach (var paneInner in pane.GetChildrenOf(~align)) paneInner.Right = pane; foreach (var thisInner in GetChildrenOf(align, idx)) thisInner.Left = pane; break; case DockDirection.Right: foreach (var paneInner in pane.GetChildrenOf(~align)) paneInner.Left = pane; foreach (var thisInner in GetChildrenOf(align, idx)) thisInner.Right = pane; break; } pane.Initialize(this, Owner, align); //base.Addを初めに呼びだしてしまうと、Childrenが更新されるために //GetChildrenOfの挙動に以上が生じる。そのため、base.Addは最後に呼ぶ base.Add(pane, align, idx); }
private Panel LoadLayout(Panel panel, DockDirection direction, XmlNode node) { Panel returnPanel = null; XmlNode node1 = node.ChildNodes [0]; XmlNode node2 = node.ChildNodes [1]; if (node1.Name == "tabControl") { List <string> formNames = node1.Attributes ["forms"].InnerText.Split (',').ToList (); formNames.RemoveAll (name => GetForm (name) == null); if (formNames.Count > 0) { dockManager.DockForm (panel, GetForm (formNames [0]), direction, true); returnPanel = GetDockablePanel (formNames [0]); for (int i = 1; i < formNames.Count; i++) { dockManager.DockForm (returnPanel, GetForm (formNames [i]), DockDirection.Center, true); } SplitContainer split = GetForm (formNames [0]).TabControlPanel.Parent.Parent as SplitContainer; if (split != null) { split.SplitterDistance = int.Parse (node.Attributes ["d"].InnerText); } } } else { returnPanel = LoadLayout (panel, direction, node1); } direction = (node.Attributes ["orientation"].InnerText == "Vertical") ? DockDirection.Right : DockDirection.Bottom; if (node2.Name == "tabControl") { List <string> formNames = node2.Attributes ["forms"].InnerText.Split (',').ToList (); formNames.RemoveAll (name => GetForm (name) == null); if (formNames.Count > 0) { dockManager.DockForm (returnPanel, GetForm (formNames [0]), direction, true); for (int i = 1; i < formNames.Count; i++) { dockManager.DockForm (GetDockablePanel (formNames [0]), GetForm (formNames [i]), DockDirection.Center, true); } SplitContainer split = GetForm (formNames [0]).TabControlPanel.Parent.Parent as SplitContainer; if (split != null) { split.SplitterDistance = int.Parse (node.Attributes ["d"].InnerText); } } } else { LoadLayout (returnPanel, direction, node2); } return returnPanel; }
public override void AddPane(DockPaneBase pane, DockDirection dire, double rate) { var dictionary = GetSplitPaneRect(_bay.Bounds, dire, rate); Rectangle rectangle = dictionary[DockLayoutEngineBase.RectRate.LargeRect]; Rectangle rectangle2 = dictionary[DockLayoutEngineBase.RectRate.SmallRect]; if (_bay.Panes.Count < 2) { rectangle = new Rectangle(); rectangle2 = new Rectangle(new Point(0, 0), _bay.Size); } else { foreach (var child in _bay._panes) { if (child != pane) { ResizeRate rate2 = _rateOf_paneSize[child]; Rectangle rectangle3 = new Rectangle(((int)(((rectangle.Width - 1) * rate2.X) + 0.5)) + ((dire == DockDirection.Left) ? rectangle2.Width : 0), ((int)(((rectangle.Height - 1) * rate2.Y) + 0.5)) + ((dire == DockDirection.Top) ? rectangle2.Height : 0), (int)((rectangle.Width * rate2.Width) + 0.5), (int)((rectangle.Height * rate2.Height) + 0.5)); child.Bounds = rectangle3; } } } pane.Bounds = rectangle2; }
public abstract void Add(DockPaneBase pane, DockDirection dire);
private Rectangle GetSplitCursorClip(DockDirection dire) { Rectangle rect; int num = int.MaxValue; int height, width, left, top; switch (dire) { case DockDirection.Bottom: left = height = int.MaxValue; top = int.MinValue; width = 0; if (!_neigh.Bottom.Outers.Contains(_neigh.Owner)) { foreach (DockBase pane in _neigh.Bottom.Outers) height = Math.Min(height, pane.Height); } else height = 0; foreach (DockBase pane in _neigh.Bottom.Inners) { width += pane.Width; num = Math.Min(num, pane.Height); left = Math.Min(left, pane.Left); top = Math.Max(top, pane.Top); } rect = new Rectangle(new Point(left, top), new Size(width, num + height)); break; case DockDirection.Right: left = int.MinValue; top = width = int.MaxValue; height = 0; if (!_neigh.Right.Outers.Contains(_neigh.Owner)) { foreach (DockBase pane in _neigh.Right.Outers) width = Math.Min(width, pane.Width); } else width = 0; foreach (DockBase pane in _neigh.Right.Inners) { height += pane.Height; num = Math.Min(num, pane.Width); left = Math.Max(left, pane.Left); top = Math.Min(top, pane.Top); } rect = new Rectangle(new Point(left, top), new Size(num + width, height)); break; default: throw new ArgumentException("引数direの値が異常です。このメソッドはdireのRightとBottomしか使えません。"); } return _neigh.Owner.RectangleToScreen(rect); }
public abstract void AddPane(DockBayBase bay, DockDirection align);
void SplitPane(DockPaneBase pane, DockDirection dire) { if ((dire == DockDirection.Top) || (dire == DockDirection.Bottom)) { DockBaseNeigh.DireInfo pairInfoA; DockBaseNeigh.DireInfo pairInfoB; pane.Neigh.Left = Left.Outers[0].Neigh.Left; pane.Neigh.Left.Inners.Add(pane); pane.Neigh.Right = Right.Outers[0].Neigh.Right; pane.Neigh.Right.Inners.Add(pane); if (dire == DockDirection.Top) { pane.Neigh.Bottom = Top; pane.Neigh.Bottom.Inners.Remove(Node); pane.Neigh.Bottom.Inners.Add(pane); pairInfoA = Top = DockBaseNeigh.DireInfo.Initialize(Node); pairInfoB = pane.Neigh.Top = DockBaseNeigh.DireInfo.Initialize(pane); } else { pane.Neigh.Top = Bottom; pane.Neigh.Top.Inners.Remove(Node); pane.Neigh.Top.Inners.Add(pane); pairInfoA = Bottom = DockBaseNeigh.DireInfo.Initialize(Node); pairInfoB = pane.Neigh.Bottom = DockBaseNeigh.DireInfo.Initialize(pane); } pairInfoA.Outers = pairInfoB.Inners; pairInfoB.Outers = pairInfoA.Inners; } else if ((dire == DockDirection.Left) || (dire == DockDirection.Right)) { DockBaseNeigh.DireInfo pairInfoA; DockBaseNeigh.DireInfo pairInfoB; pane.Neigh.Top = Top.Outers[0].Neigh.Top; pane.Neigh.Top.Inners.Add(pane); pane.Neigh.Bottom = Bottom.Outers[0].Neigh.Bottom; pane.Neigh.Bottom.Inners.Add(pane); if (dire == DockDirection.Left) { pane.Neigh.Right = Left; pane.Neigh.Right.Inners.Remove(Node); pane.Neigh.Right.Inners.Add(pane); pairInfoA = Left = DockBaseNeigh.DireInfo.Initialize(Node); pairInfoB = pane.Neigh.Left = DockBaseNeigh.DireInfo.Initialize(pane); } else { pane.Neigh.Left = Right; pane.Neigh.Left.Inners.Remove(Node); pane.Neigh.Left.Inners.Add(pane); pairInfoA = Right = DockBaseNeigh.DireInfo.Initialize(Node); pairInfoB = pane.Neigh.Right = DockBaseNeigh.DireInfo.Initialize(pane); } pairInfoA.Outers = pairInfoB.Inners; pairInfoB.Outers = pairInfoA.Inners; } }
public sealed override void Add(DockPaneBase pane, DockDirection dire) { ((DockPaneBase.DockNeigh)pane.Neigh).Owner = Node as DockBayBase; ((DockPaneBase.DockNeigh)pane.Neigh).Parent = Node; var node = (DockBayBase)Node; if (node.Panes.Count > 0) SplitPane(pane, dire); else { pane.Neigh.Top.Outers = Top.Inners; pane.Neigh.Bottom.Outers = Bottom.Inners; pane.Neigh.Left.Outers = Left.Inners; pane.Neigh.Right.Outers = Right.Inners; pane.Neigh.Top.Inners = Top.Outers; pane.Neigh.Bottom.Inners = Bottom.Outers; pane.Neigh.Left.Inners = Left.Outers; pane.Neigh.Right.Inners = Right.Outers; pane.Neigh.Top.Inners.Add(pane); pane.Neigh.Bottom.Inners.Add(pane); pane.Neigh.Left.Inners.Add(pane); pane.Neigh.Right.Inners.Add(pane); pane.Neigh.Top.Inners.Remove(Node); pane.Neigh.Bottom.Inners.Remove(Node); pane.Neigh.Left.Inners.Remove(Node); pane.Neigh.Right.Inners.Remove(Node); } Children.Add(pane); ((DockPaneBase.DockNeigh)pane.Neigh).Align = dire; OnPaneAdded(new DockEventArgs(pane, dire)); }
private Cursor CreateSplitBar(DockDirection dire, Color mesh, double width) { int clipWidth; int clipHeight; Rectangle splitCursorClip = GetSplitCursorClip(dire); Point position = Cursor.Position; Point hotSpot = Cursor.HotSpot; Size size = Cursor.Size; switch (dire) { case DockDirection.Top: case DockDirection.Bottom: clipWidth = Math.Max(size.Width, splitCursorClip.Width); clipHeight = size.Height; break; case DockDirection.Left: case DockDirection.Right: clipHeight = Math.Max(size.Height, splitCursorClip.Height); clipWidth = size.Width; break; default: throw new ArgumentException("direの値が異常です。"); } using (Bitmap bitmap = new Bitmap(clipWidth, clipHeight)) using (Graphics graphics = Graphics.FromImage(bitmap)) using (HatchBrush brush = new HatchBrush(HatchStyle.Percent50, mesh)) using (Pen pen = new Pen(brush, (float)width)) { if ((dire == DockDirection.Top) || (dire == DockDirection.Bottom)) graphics.DrawLine(pen, new Point(0, bitmap.Height / 2), new Point(bitmap.Width, bitmap.Height / 2)); else if ((dire == DockDirection.Left) || (dire == DockDirection.Right)) graphics.DrawLine(pen, new Point(bitmap.Width / 2, 0), new Point(bitmap.Width / 2, bitmap.Height)); using (Icon icon = Icon.FromHandle(bitmap.GetHicon())) { return new Cursor(icon.Handle); } } }