コード例 #1
0
        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;
        }
コード例 #2
0
 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));
 }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
 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();
     }
 }
コード例 #7
0
            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);
            }
コード例 #8
0
 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]);
 }
コード例 #9
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);
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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();
        }
コード例 #12
0
 public DockEventArgs(DockPaneBase pane, DockDirection align)
 {
     DockPane = pane;
     Align = align;
 }
コード例 #13
0
 public PaneAddedEventArgs(DockBase addedpane, DockPaneBase pane, DockDirection dire)
     : base(pane, dire)
 {
     AddedPane = addedpane;
 }
コード例 #14
0
            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));
            }
コード例 #15
0
 public abstract void AddPane(DockPaneBase pane, DockDirection dire, double rate);
コード例 #16
0
        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;
        }
コード例 #17
0
 protected virtual void OnDockPreviewWindowShowing(IDockPreviewWindow dockPreviewWindow, DockDirection dockDirection)
 {
 }
コード例 #18
0
 protected override void OnDockPreviewWindowShowing(IDockPreviewWindow dockPreviewWindow, DockDirection dockDirection)
 {
     ((ExpressionDockPreviewWindow)dockPreviewWindow).IsFillPreview = dockDirection == DockDirection.Fill;
 }
コード例 #19
0
        /// <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;
            }
        }
コード例 #20
0
        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;
            }
        }
コード例 #21
0
ファイル: DockingRoute.cs プロジェクト: pedone/DockingLibrary
 public void Add(DockDirection direction)
 {
     _route.Insert(0, direction);
 }
コード例 #22
0
        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;
            }
        }
コード例 #23
0
        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 ();
            }
        }
コード例 #24
0
 public override void AddPane(DockPaneBase pane, DockDirection dire)
 {
     double splitRate = 0.25;
     AddPane(pane, dire, splitRate);
 }
コード例 #25
0
 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;
 }
コード例 #26
0
 public FloatingElementDockedEventArgs(RoutedEvent routedEvent, ViewElement content, DockDirection dockDirection, bool createDocumentGroup)
     : base(routedEvent, content)
 {
     this.DockDirection       = dockDirection;
     this.CreateDocumentGroup = createDocumentGroup;
 }
コード例 #27
0
 internal void Initialize(DockNodeLayoutEngine parent, DockBayLayoutEngine owner, DockDirection align)
 {
     Initialize(parent, owner);
     Align = align;
 }
コード例 #28
0
        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の呼び出し回数が少なすぎです。");
        }
コード例 #29
0
        /// <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;
        }
コード例 #30
0
 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;
 }
コード例 #31
0
 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);
 }
コード例 #32
0
        /// <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);
        }
コード例 #33
0
        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;
        }
コード例 #34
0
 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;
 }
コード例 #35
0
 public abstract void Add(DockPaneBase pane, DockDirection dire);
コード例 #36
0
        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);
        }
コード例 #37
0
 public abstract void AddPane(DockBayBase bay, DockDirection align);
コード例 #38
0
 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;
     }
 }
コード例 #39
0
            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));
            }
コード例 #40
0
        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);
                            }
                        }
        }