Beispiel #1
0
        /// <summary>Get the bounds of a dock site in parent (DockContainer or containing Branch) space</summary>
        public Rect ChildBounds(EDockSite location)
        {
            var display_rect = new Rect(RenderSize);

            display_rect.Width  = Math.Max(0, display_rect.Width);
            display_rect.Height = Math.Max(0, display_rect.Height);
            return(DockContainer.DockSiteBounds(location, display_rect, DockedMask, DockSizes));
        }
Beispiel #2
0
        /// <summary>Add branches to the tree until 'rest' is empty.</summary>
        private Branch GrowBranches(IEnumerable <EDockSite> address, out EDockSite last_ds)
        {
            var ds   = address.First();
            var rest = address.Skip(1);

            Debug.Assert(ds >= EDockSite.Centre && ds < EDockSite.None, "Invalid dock site");

            // Note: When rest is empty, the site at 'ds' does not have a branch added.
            // This is deliberate so that dock addresses (arrays of EDockSite) can be
            // used to grow the tree to the point where a dock pane should be added.
            if (!rest.Any())
            {
                // If we've reached the end of the dock address, but there are still branches
                // keep going down the centre dock site until a null or dock pane is reached
                var b = this;
                for (; b.Descendants[ds].Item is Branch cb; b = cb, ds = EDockSite.Centre)
                {
                }

                Debug.Assert(ValidateTree());

                last_ds = ds;
                return(b);
            }

            // No child at 'ds' add a branch
            if (Descendants[ds].Item == null)
            {
                var new_branch = new Branch(DockContainer, ds == EDockSite.Centre ? DockSizeData.Quarters : DockSizeData.Halves);
                Descendants[ds].Item = new_branch;
                return(new_branch.GrowBranches(rest, out last_ds));
            }

            // If there's a dock pane at 'ds' swap it with a branch
            // containing that dock pane as the centre child
            if (Descendants[ds].Item is DockPane)
            {
                // Detach from the current location
                var existing = Descendants[ds].Item;
                Descendants[ds].Item = null;

                // Create a new branch with 'existing' in the centre
                var new_branch = new Branch(DockContainer, DockSizeData.Halves);
                new_branch.Descendants[EDockSite.Centre].Item = existing;

                // Replace in the current location
                Descendants[ds].Item = new_branch;
                return(new_branch.GrowBranches(rest, out last_ds));
            }
            else
            {
                // Existing branch, recursive call into it
                var branch = (Branch?)Descendants[ds].Item ?? throw new Exception("Branch expected");
                return(branch.GrowBranches(rest, out last_ds));
            }
        }
Beispiel #3
0
        public void ChildSize(EDockSite location, double value, EDockResizeMode resize_mode)
        {
            if (value < 0 || double.IsNaN(value))
            {
                throw new Exception($"Invalid child size ({value}) for {location}");
            }
            if (RenderSize.Width == 0 || RenderSize.Height == 0)
            {
                throw new Exception($"Invalid size for this branch, can't determine dock size for {location}");
            }

            DockSizes.SetSize(location, DisplayRectangle, value, resize_mode);
        }
        /// <summary>Convert an 'EDockSite' to a DockPanel dock location</summary>
        public static Dock ToDock(this EDockSite docksite)
        {
            switch (docksite)
            {
            default:
                throw new Exception($"Unknown dock site value {docksite}");

            case EDockSite.Centre:
            case EDockSite.None:
                throw new Exception($"No equivalent of {docksite} for DockPanel.Dock values");

            case EDockSite.Left: return(Dock.Left);

            case EDockSite.Top: return(Dock.Top);

            case EDockSite.Right: return(Dock.Right);

            case EDockSite.Bottom: return(Dock.Bottom);
            }
        }
 /// <summary>True if this dock site is Top or Bottom</summary>
 public static bool IsHorizontal(this EDockSite ds)
 {
     return(ds == EDockSite.Top || ds == EDockSite.Bottom);
 }
 /// <summary>True if this dock site is Left or Right</summary>
 public static bool IsVertical(this EDockSite ds)
 {
     return(ds == EDockSite.Left || ds == EDockSite.Right);
 }
 /// <summary>True if this dock site is a edge</summary>
 public static bool IsEdge(this EDockSite ds)
 {
     return(ds == EDockSite.Left || ds == EDockSite.Top || ds == EDockSite.Right || ds == EDockSite.Bottom);
 }
Beispiel #8
0
 /// <summary>Get/Set the size for a dock site in this branch (in pixels)</summary>
 public double ChildSize(EDockSite location)
 {
     return(DockSizes.GetSize(location, DisplayRectangle, DockedMask));
 }
Beispiel #9
0
 public DockPane DockPane(EDockSite ds)
 {
     return(DockPane(new[] { ds }));
 }
        // Notes:
        //  - An auto hide panel is a panel that pops out from the edges of the dock container.
        //  - It is basically a root branch with a single centre dock pane. The tab strip from the
        //    dock pane is used for the auto-hide tab strip displayed around the edges of the control.
        // Other behaviours:
        //  - Click pin on the pane only pins the active content
        //  - Clicking a tab makes that dockable the active content
        //  - 'Root' only uses the centre dock site

        public AutoHidePanel(DockContainer dc, EDockSite ds)
        {
            InitializeComponent();
            Visibility = Visibility.Collapsed;
            Canvas.SetZIndex(this, 1);

            DockContainer = dc;
            DockSite      = ds;
            PoppedOut     = false;

            var splitter_size = 5.0;
            var splitter      = new GridSplitter
            {
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment   = VerticalAlignment.Stretch,
                Background          = SystemColors.ControlBrush,
                BorderBrush         = new SolidColorBrush(Color.FromRgb(0xc0, 0xc0, 0xc0)),
                BorderThickness     = DockSite.IsVertical() ? new Thickness(1, 0, 1, 0) : new Thickness(0, 1, 0, 1),
            };

            // Create a grid to contain the root branch and the splitter
            switch (DockSite)
            {
            default: throw new Exception($"Auto hide panels cannot be docked to {ds}");

            case EDockSite.Left:
            case EDockSite.Right:
            {
                // Vertical auto hide panel
                ColumnDefinitions.Add(new ColumnDefinition {
                        Width = new GridLength(DockSite == EDockSite.Left ? 1 : 2, GridUnitType.Star), MinWidth = 10
                    });
                ColumnDefinitions.Add(new ColumnDefinition {
                        Width = new GridLength(0, GridUnitType.Auto)
                    });
                ColumnDefinitions.Add(new ColumnDefinition {
                        Width = new GridLength(DockSite == EDockSite.Right ? 1 : 2, GridUnitType.Star), MinWidth = 10
                    });

                // Add the root branch to the appropriate column
                Root = Children.Add2(new Branch(dc, DockSizeData.Quarters));
                Grid.SetColumn(Root, DockSite == EDockSite.Left ? 0 : 2);

                // Add the splitter to the centre column
                splitter.Width = splitter_size;
                Children.Add2(splitter);
                Grid.SetColumn(splitter, 1);
                break;
            }

            case EDockSite.Top:
            case EDockSite.Bottom:
            {
                // Horizontal auto hide panel
                RowDefinitions.Add(new RowDefinition {
                        Height = new GridLength(DockSite == EDockSite.Top ? 1 : 2, GridUnitType.Star), MinHeight = 10
                    });
                RowDefinitions.Add(new RowDefinition {
                        Height = new GridLength(0, GridUnitType.Auto)
                    });
                RowDefinitions.Add(new RowDefinition {
                        Height = new GridLength(DockSite == EDockSite.Bottom ? 1 : 2, GridUnitType.Star), MinHeight = 10
                    });

                // Add the root branch to the appropriate row
                Root = Children.Add2(new Branch(dc, DockSizeData.Quarters));
                Grid.SetRow(Root, DockSite == EDockSite.Top ? 0 : 2);

                // Add the splitter to the centre row
                splitter.Height = splitter_size;
                Children.Add2(splitter);
                Grid.SetRow(splitter, 1);
                break;
            }
            }

            // Remove the tab strip from the dock pane child so we can use
            // it as the auto hide tab strip for this auto hide panel
            TabStrip = DockPane.TabStrip;
            TabStrip.Detach();
            TabStrip.AHPanel = this;
        }