internal void SetDockState(_DockState state, bool onStartDrag = false) { //AOutput.Write(this, Name); var gp = this as _Panel; if (state == _DockState.LastVisible) { if (!this.IsHidden) { if (this.IsTabbedPanel) { gp.ParentTab.SetDockState(_DockState.LastVisible); if (this.IsDocked) { gp.ParentTab.SetActiveItem(gp); } } if (this.ParentControl is _Float gf) { ((AWnd)gf).EnsureInScreen(); } return; } state = this.SavedVisibleDockState; } var prevState = this.DockState; if (state == prevState) { return; } if (this.ParentSplit == null && state == _DockState.Docked) //new panel { ADialog.ShowInfo("How to dock floating panels", "Alt+drag and drop.", owner: _manager); return; } bool isTab = gp == null; _Tab gt = null, gtParent = null; if (isTab) { gt = this as _Tab; } else { gtParent = gp.ParentTab; } this.DockState = state; //get RECT for floating now, because later this.ParentControl will change and even may be destroyed RECT rect = default; if (state == _DockState.Floating) { if (!onStartDrag && !SavedFloatingBounds.IsEmptyRect()) { if (SavedFloatingBounds.X == int.MinValue) //specified only width and height { var mp = AMouse.XY; rect = new RECT(mp.x - 15, mp.y - 15, SavedFloatingBounds.Width, SavedFloatingBounds.Height); } else { rect = SavedFloatingBounds; } rect.EnsureInScreen(); } else if (this.ParentSplit != null) { rect = this.RectangleInScreen; AWnd.More.WindowRectFromClientRect(ref rect, WS.POPUP | WS.THICKFRAME, WS2.TOOLWINDOW); } else //new panel, empty bounds { var mp = AMouse.XY; rect = new RECT(mp.x - 15, mp.y - 15, 300, 150); rect.EnsureInScreen(); } } var panels = isTab ? gt.Items.FindAll(v => v.IsDocked) : new List <_Panel>(1) { gp }; //(isTab ? gt.ActiveItem : gp)?.Content.Hide(); var gtp = isTab ? gt.ActiveItem : gp; if (gtp != null) { if (state != _DockState.Docked && _manager.ZFocusControlOnUndockEtc != null && gtp.Content.ContainsFocus) { _manager.ZFocusControlOnUndockEtc.Focus(); } gtp.Content.Hide(); } Action postAction = null; switch (prevState) { case _DockState.Docked: if (gtParent != null) { gtParent.OnItemUndocked(gp, out postAction); } else { this.ParentSplit.OnChildUndocked(this); } _manager.Invalidate(this.Bounds, true); //some controls don't redraw properly, eg ToolStripTextBox break; case _DockState.Floating: //case _DockState.AutoHide: var f = this.ParentControl as _Float; var parent = (gtParent != null) ? gtParent.ParentControl : _manager; _parentControl = parent; foreach (var v in panels) { _ChangeParent(v, parent); } if (prevState == _DockState.Floating) { this.SavedFloatingBounds = f.Bounds; } f.Close(); break; } switch (state) { case _DockState.Docked: if (gtParent != null) { gtParent.OnItemDocked(gp); } else { this.ParentSplit.OnChildDocked(this); } break; case _DockState.Floating: var f = new _Float(_manager, this); this._parentControl = f; foreach (var v in panels) { _ChangeParent(v, f); } f.Bounds = rect; f.Show(_manager.TopLevelControl); break; //case _DockState.AutoHide: // break; case _DockState.Hidden: this.SavedVisibleDockState = prevState; break; } if (state != _DockState.Hidden) { (isTab ? gt.ActiveItem : gp)?.Content.Show(); } postAction?.Invoke(); //_manager.Invalidate(true); if (prevState != _DockState.Hidden) { _manager._OnMouseLeave_Common(this.ParentControl); //calls _UnhiliteTabButton and _HideTooltip } }