/// <summary> /// Creates a new DockEventArgs object. /// </summary> /// <param name="point">The point where to dock the window.</param> /// <param name="dockType">The needed target container type.</param> /// <param name="release">The state of the dock process. True, if dock is finally performed.</param> public DockEventArgs(Point point, DockContainerType dockType, bool release) { this.point = point; this.dockType = dockType; this.release = release; this.target = null; }
/// <summary> /// Invokes the drag event and adjusts the size and location if a valid docking position was received. /// This method is only used by explicit drag windows (see flag). /// </summary> internal void MoveWindow() { if ((this.DragWindow != null) && isDragWindow) { dragTarget = null; DockEventArgs e = new DockEventArgs(new Point(MousePosition.X, MousePosition.Y), this.dockType, false); this.DragWindow(this, e); dragTarget = e.Target; if (dragTarget != null) { this.Size = dragTarget.Size; if (dragTarget.Parent != null) this.Location = dragTarget.RectangleToScreen(dragTarget.ClientRectangle).Location; else this.Location = dragTarget.Location; } } }
/// <summary> /// Retrieves a container that matches a specific mouse location, when a window is dragged. /// </summary> /// <param name="type">The target container type.</param> /// <param name="pt">The target position.</param> /// <returns>A valid container or null, if no suitable container was found.</returns> protected DockContainer GetTarget(Size srcSize, DockContainerType type, Point pt) { // Prepare rectangles. Rectangle rcClient = RectangleToScreen(this.ClientRectangle); Rectangle rcDock = new Rectangle(rcClient.Left+this.DockPadding.Left, rcClient.Top+this.DockPadding.Top, rcClient.Width-this.DockPadding.Left-this.DockPadding.Right, rcClient.Height-this.DockPadding.Top-this.DockPadding.Bottom); // Test on split. if (rcDock.Contains(pt)) { DockContainer cont = null; if (pt.X-rcDock.Left <= dockBorder) { // Split left. cont = new DockContainer(); cont.DockType = type; cont.Dock = DockStyle.Left; if (srcSize.Width > this.Width/2) cont.Width = this.Width/2; else cont.Width = srcSize.Width; cont.Height = this.Height; cont.Location = new Point(rcClient.X, rcClient.Y); } else if (rcDock.Right-pt.X <= dockBorder) { // Split right. cont = new DockContainer(); cont.DockType = type; cont.Dock = DockStyle.Right; if (srcSize.Width > this.Width/2) cont.Width = this.Width/2; else cont.Width = srcSize.Width; cont.Height = this.Height; cont.Location = new Point(rcClient.X+this.Width-cont.Width, rcClient.Y); } else if (pt.Y-rcDock.Top <= dockBorder) { // Split top. cont = new DockContainer(); cont.DockType = type; cont.Dock = DockStyle.Top; if (srcSize.Height > this.Height/2) cont.Height = this.Height/2; else cont.Height = srcSize.Height; cont.Width = this.Width; cont.Location = new Point(rcClient.X, rcClient.Y); } else if (rcDock.Bottom-pt.Y <= dockBorder) { // Split bottom. cont = new DockContainer(); cont.DockType = type; cont.Dock = DockStyle.Bottom; if (srcSize.Height > this.Height/2) cont.Height = this.Height/2; else cont.Height = srcSize.Height; cont.Width = this.Width; cont.Location = new Point(rcClient.X, rcClient.Y+this.Height-cont.Height); } return cont; } // Test on add to own panel list. if (rcClient.Contains(pt)) { if ((pt.Y <= rcClient.Top+this.DockPadding.Top) && (dockType == type)) return this; else if ((dockType == type) && (dockType == DockContainerType.ToolWindow) && (panelList.Count > 1) && (pt.Y > rcClient.Top+this.Height-this.DockPadding.Bottom)) return this; } return null; }
public DockContainer GetNextChild(DockContainerType type, DockContainer last) { DockContainer ret = null; foreach (DockContainer cont in containerList) { ret = cont.GetNextChild(type, last); if (ret != null) return ret; } if ((containerList.Count == 0) && (dockType == type) && (this != last)) ret = last; return ret; }
/// <summary> /// The DragWindow event handler for dockable windows. /// Used to enable a DockWindow to send its position changes to this container. /// Calls recursively all DragWindow event handlers of the child containers. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">An DockEventArgs that contains the docking data.</param> public void DragWindow(object sender, DockEventArgs e) { try { // First, check if the given point is in the current tree. if (!HitTest(e.Point)) return; // Then, check if the container is dockable at all. if (e.DockType == DockContainerType.None) return; // Then test all containers. foreach (DockContainer c in containerList) { c.DragWindow(sender, e); if (e.Target != null) return; } if (containerList.Count != 0) return; // Then test itself. DockWindow wnd = sender as DockWindow; e.Target = GetTarget(wnd.Size, e.DockType, e.Point); if ((e.Target != null) && (e.Release)) { if (panelList.Contains(wnd.ControlContainer) && (panelList.Count == 1)) { e.Target = this; return; } // Dock the container, if needed. if (!containerList.Contains(e.Target) && (e.Target != this)) { // Create new container and fill it with own panels or containers. DockContainer cont = new DockContainer(); cont.removeable = removeable; removeable = true; cont.DockBorder = dockBorder; cont.DockType = dockType; disableOnControlRemove = true; while (containerList.Count > 0) cont.Controls.Add(containerList[0] as DockContainer); disableOnControlRemove = false; containerList.Add(cont); DockPanel temp = ActivePanel; while (panelList.Count > 0) cont.Controls.Add(panelList[0] as DockPanel); cont.ActivePanel = temp; this.Controls.Add(cont); cont.Dock = DockStyle.Fill; // Add the container to the list object. containerList.Add(e.Target); this.Controls.Add(e.Target); } // Add the panel. e.Target.AddPanel(wnd, e.Point); // Set focus. this.TopLevelControl.BringToFront(); this.TopLevelControl.Invalidate(true); e.Target.ActivePanel.Focus(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
/// <summary> /// The MouseUp event handler of the drag panel. /// Used to handle resizing of the container. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">A MouseEventArgs that contains the mouse data.</param> private void dragPanel_MouseUp(object sender, MouseEventArgs e) { // If resizing, release dummy and set new size. if (resizing) { resizing = false; // Release dummy. Parent.Controls.Remove(dragDummy); Parent.Invalidate(); dragDummy.Dispose(); dragDummy = null; // Set new size according to the actual state. ptStart = new Point(e.X+dragPanel.Left, e.Y+dragPanel.Top); if (this.Dock == DockStyle.Left) { if (ptStart.X < dockBorder*3) ptStart.X = dockBorder*3; else if (ptStart.X > this.Parent.Width-dockBorder*3) ptStart.X = this.Parent.Width-dockBorder*3; } else if (this.Dock == DockStyle.Right) { if (ptStart.X > this.Width-dockBorder*3) ptStart.X = this.Width-dockBorder*3; else if (ptStart.X < this.Width-this.Parent.Width+dockBorder*3) ptStart.X = this.Width-this.Parent.Width+dockBorder*3; } else if (this.Dock == DockStyle.Top) { if (ptStart.Y < dockBorder*3) ptStart.Y = dockBorder*3; else if (ptStart.Y > this.Parent.Height-dockBorder*3) ptStart.Y = this.Parent.Height-dockBorder*3; } else if (this.Dock == DockStyle.Bottom) { if (ptStart.Y > this.Height-dockBorder*3) ptStart.Y = this.Height-dockBorder*3; else if (ptStart.Y < this.Height-this.Parent.Height+dockBorder*3) ptStart.Y = this.Height-this.Parent.Height+dockBorder*3; } switch (this.Dock) { case DockStyle.Left: if (ptStart.X < 40) this.Width = 40; else this.Width = ptStart.X; break; case DockStyle.Right: int x = 0; if (this.Width - ptStart.X < 40) x = this.Width - 40; else x = ptStart.X; this.Location = new Point(this.Location.X+x, this.Location.Y); this.Width -= x; break; case DockStyle.Top: if (ptStart.Y < 60) this.Height = 60; else this.Height = ptStart.Y; break; case DockStyle.Bottom: int y = 0; if (this.Height - ptStart.Y < 60) y = this.Height - 60; else y = ptStart.Y; this.Location = new Point(this.Location.X, this.Location.Y+y); this.Height -= y; break; } } }
/// <summary> /// The MouseDown event handler of the drag panel. /// Used to handle resizing of the container. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">A MouseEventArgs that contains the mouse data.</param> private void dragPanel_MouseDown(object sender, MouseEventArgs e) { // Copy last point. ptStart = new Point(e.X+dragPanel.Left, e.Y+dragPanel.Top); // Create dummy container. dragDummy = new DockContainer(); dragDummy.isDragContainer = true; // Set size and location. if ((this.Dock == DockStyle.Left) || (this.Dock == DockStyle.Right)) { dragDummy.Location = new Point(this.Location.X+ptStart.X-2, this.Location.Y); dragDummy.Size = new Size(4, this.Height); } else { dragDummy.Location = new Point(this.Location.X, this.Location.Y+ptStart.Y-2); dragDummy.Size = new Size(this.Width, 4); } // Add container to parent and resizing flag. Parent.Controls.Add(dragDummy); dragDummy.BringToFront(); resizing = true; }
/// <summary> /// Removes a child container from the internal list and disposes it. /// The other container will be transferred back to the host container at the call of the OnControlRemoved method. /// </summary> /// <param name="cont">The DockContainer that is to be removed.</param> protected void RemoveContainer(DockContainer cont) { if (this.Controls.Contains(cont)) { this.Controls.Remove(cont); cont.Dispose(); cont = null; } }