namespace DevComponents.DotNetBar { using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using DevComponents.DotNetBar.Rendering; #region IDockInfo /// /// Interface used for docking support. /// public interface IDockInfo { /// /// Returns Minimum docked size of the control. /// System.Drawing.Size MinimumDockSize(eOrientation dockOrientation); /// /// Returns Preferrred size of the docked control. /// System.Drawing.Size PreferredDockSize(eOrientation dockOrientation); /// /// Indicated whether control can be docked on top dock site. /// bool CanDockTop {get;} /// /// Indicated whether control can be docked on bottom dock site. /// bool CanDockBottom {get;} /// /// Indicated whether control can be docked on left dock site. /// bool CanDockLeft {get;} /// /// Indicated whether control can be docked on right dock site. /// bool CanDockRight {get;} /// /// Indicates whether control can be docked as document i.e. middle (fill) dock site. /// bool CanDockDocument {get;} /// /// Indicates whether control can be docked as tab to another bar. /// bool CanDockTab {get;} /// /// Indicated whether control can be stretched to fill dock site. /// bool Stretch {get;set;} /// /// Holds the left position (dock offset) of the control. /// int DockOffset {get;set;} /// /// Specifies the dock line for the control. /// int DockLine {get;set;} /// /// Specifies current dock orientation. /// eOrientation DockOrientation {get;set;} /// /// Gets whether control is docked. /// bool Docked {get;} /// /// Returns the dock site of the control. /// System.Windows.Forms.Control DockedSite {get;} /// /// Gets or sets the control dock side. /// eDockSide DockSide{get;set;} /// /// Sets the dock line for the control. Used internaly by dock manager. /// /// New Dock line. void SetDockLine(int iLine); /// /// Gets or sets whether bar is locked to prevent docking below it. /// bool LockDockPosition{get;set;} } #endregion #region DockSiteInfo /// /// Represent the docking information for an control. /// public class DockSiteInfo { /// /// Control dock side. /// public System.Windows.Forms.DockStyle DockSide; /// /// Control dock site. /// public DockSite objDockSite; /// /// Docking offset. /// public int DockOffset; /// /// Docking line. /// public int DockLine; /// /// Docked control width. /// public int DockedWidth; /// /// Docked control height. /// public int DockedHeight; /// /// Control position. /// public int InsertPosition; public bool NewLine; public bool IsEmpty() { if(this.DockSide==System.Windows.Forms.DockStyle.None && this.objDockSite==null && this.DockOffset==0 && this.DockLine==0 && this.DockedWidth==0 && this.DockedHeight==0 && this.InsertPosition==0 && this.NewLine==false) return true; return false; } public Bar TabDockContainer; /// /// Indicates whether to use outline or not /// public bool UseOutline; /// /// Indicates that dock site should change it's Z-Order so it maximizes the space it consumes as related to other dock sites. /// public bool FullSizeDock; /// /// Indicates that dock site should change it's Z-Order so it reduces the amount of space it consumes as related to other dock sites. /// public bool PartialSizeDock; /// /// When either FullSizeDock or PartialSizeDock is set it indicates the new dock site Z-Order index. /// public int DockSiteZOrderIndex; /// /// Returns the bar that mouse is placed over. /// public Bar MouseOverBar; /// /// Returns dock side the mouse is indicating user wants to dock bar at. /// public eDockSide MouseOverDockSide; /// /// Gets the last relative docked to bar. /// public Bar LastRelativeDockToBar; /// /// Gets the last relative docked to document id. /// public long LastRelativeDocumentId; /// /// Returns side of last docked-to dock site. /// public eDockSide LastDockSiteSide; } #endregion /// /// Dock Sites are created by DotNetBar control on each edge of the /// DotNetBar container control and are used for docking purposes. /// If Dock Site does not contain any controls it will be invisible. /// [ToolboxItem(false), DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.DockSiteDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] public class DockSite : System.Windows.Forms.Control { private eOrientation m_DockOrientation; private bool m_Layingout=false; private bool m_OversizeLayout=false; //private int m_DockMargin; private DotNetBarManager m_Owner=null; private bool m_NeedsLayout=false; private bool m_NeedsNormalize=false; // Theme Cache private ThemeRebar m_ThemeRebar=null; private eBackgroundImagePosition m_BackgroundImagePosition=eBackgroundImagePosition.Stretch; private byte m_BackgroundImageAlpha=255; private Color m_BackColor2=Color.Empty; private int m_BackColorGradientAngle=90; private bool m_Disposed=false; private DocumentDockUIManager m_DocumentUIManager=null; private bool m_LayoutSuspended=false; [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool _DesignerLoading = false; private int m_OriginalSize = 0; private bool m_OptimizeLayoutRedraw = true; /// /// Creates new instance of DockSite object with specified dock style. /// /// Specifies the position and manner in which a site is docked. public DockSite(System.Windows.Forms.DockStyle DockSide):this() { this.Dock=DockSide; } protected override AccessibleObject CreateAccessibilityInstance() { return new DockSiteAccessibleObject(this); } /// /// Creates new instance of DockSite object. /// public DockSite() { this.TabStop=false; this.SetStyle(ControlStyles.Selectable,false); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.IsAccessible=true; this.AccessibleRole=AccessibleRole.Window; } protected override void Dispose(bool disposing) { m_Owner=null; m_Disposed=true; base.Dispose(disposing); } protected override void ScaleControl(SizeF factor, BoundsSpecified specified) { if (Dpi.RecordScalePerControl) Dpi.SetScaling(factor); base.ScaleControl(factor, specified); } /// /// Gets or sets whether painting is disabled on dock site while layout of bars is performed. Default value is true. /// You might need to set this property to false if you are expirience vide flashing while using DirectX video animation in Bar controls that are part of the /// dock site. /// [DefaultValue(true), Description("Indicates whether painting is disabled on dock site while layout of bars is performed.")] public bool OptimizeLayoutRedraw { get { return m_OptimizeLayoutRedraw; } set { m_OptimizeLayoutRedraw = value; } } private DocumentDockContainer m_DocumentDockContainer=null; [Browsable(false), DefaultValue(null)] public DocumentDockContainer DocumentDockContainer { get {return m_DocumentDockContainer;} set { m_DocumentDockContainer=value; m_DocumentUIManager=this.GetDocumentUIManager(); m_DocumentUIManager.RootDocumentDockContainer=m_DocumentDockContainer; if (this.Dock != DockStyle.Fill && value!=null) m_DocumentDockContainer.RecordDocumentSize = true; } } /// /// Returns reference to the DocumentDockUIManager object used for interaction with document docking engine. /// /// Reference to the DocumentDockUIManager object. public DocumentDockUIManager GetDocumentUIManager() { if (m_DocumentUIManager == null) { m_DocumentUIManager = new DocumentDockUIManager(this); m_DocumentUIManager.RootDocumentDockContainer = m_DocumentDockContainer; } return m_DocumentUIManager; } /// /// Specifies background image position when container is larger than image. /// [Browsable(true),DevCoBrowsable(true),Category("Appearance"),DefaultValue(eBackgroundImagePosition.Stretch),Description("Specifies background image position when container is larger than image.")] public eBackgroundImagePosition BackgroundImagePosition { get {return m_BackgroundImagePosition;} set { if(m_BackgroundImagePosition!=value) { m_BackgroundImagePosition=value; this.Refresh(); } } } /// /// Saves layout for bars contained by dock site. /// /// Parent XmlElement. public void SaveLayout(System.Xml.XmlElement xmlBars) { if(this.IsDocumentDock || m_DocumentDockContainer!=null) { this.GetDocumentUIManager().SerializeLayout(xmlBars); } else { foreach(Control ctrl in this.Controls) { DevComponents.DotNetBar.Bar bar=ctrl as DevComponents.DotNetBar.Bar; if(bar!=null && bar.Name!="" && bar.SaveLayoutChanges) { System.Xml.XmlElement xmlBar=xmlBars.OwnerDocument.CreateElement("bar"); xmlBars.AppendChild(xmlBar); bar.SerializeLayout(xmlBar); } } } } /// /// Loads layout for the bars. /// /// Parent XmlElement that was passed to SaveLayout method to save layout public void LoadLayout(System.Xml.XmlElement xmlBars) { m_LayoutSuspended=true; try { if(!this.IsDocumentDock && m_DocumentDockContainer==null) { foreach(System.Xml.XmlElement xmlBar in xmlBars.ChildNodes) { DevComponents.DotNetBar.Bar bar=null; if(m_Owner.Bars.Contains(m_Owner.Bars[xmlBar.GetAttribute("name")])) bar=m_Owner.Bars[xmlBar.GetAttribute("name")]; else { bar=new Bar(); m_Owner.Bars.Add(bar); } bar.DeserializeLayout(xmlBar); } } else { this.GetDocumentUIManager().DeserializeLayout((System.Xml.XmlElement)xmlBars.FirstChild); } } finally { m_LayoutSuspended=false; this.RecalcLayout(); } } /// /// Suspends normal layout logic. /// public new void SuspendLayout() { m_LayoutSuspended = true; base.SuspendLayout(); } /// /// Resumes normal layout logic. /// public new void ResumeLayout() { this.ResumeLayout(true); } /// /// Resumes normal layout logic. Optionally forces an immediate layout of pending layout requests. /// public new void ResumeLayout(bool performLayout) { m_LayoutSuspended = false; base.ResumeLayout(performLayout); } /// /// Specifies the transparency of background image. /// [Browsable(true),DevCoBrowsable(true),Category("Appearance"),DefaultValue((byte)255),Description("Specifies the transparency of background image.")] public byte BackgroundImageAlpha { get {return m_BackgroundImageAlpha;} set { if(m_BackgroundImageAlpha!=value) { m_BackgroundImageAlpha=value; this.Refresh(); } } } [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeBackgroundImageAlpha() { return m_BackgroundImageAlpha!=255; } /// /// Gets or sets the target gradient background color. /// [Browsable(true),Description("Indicates the target gradient background color."),Category("Style")] public Color BackColor2 { get {return m_BackColor2;} set { m_BackColor2=value; if(this.DesignMode) this.Refresh(); } } [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeBackColor2() { return !m_BackColor2.IsEmpty; } [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] public void ResetBackColor2() { m_BackColor2=Color.Empty; } /// /// Gets or sets gradient fill angle. /// [Browsable(true),Description("Indicates gradient fill angle."),Category("Style"),DefaultValue(90)] public int BackColorGradientAngle { get {return m_BackColorGradientAngle;} set { if(value!=m_BackColorGradientAngle) { m_BackColorGradientAngle=value; if(this.DesignMode) this.Refresh(); } } } internal bool GetDesignMode() { return this.DesignMode; } // /// // /// Gets the collection of controls contained within the control. // /// // [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),Browsable(false),DevCoBrowsable(false)] // public new Control.ControlCollection Controls // { // get // { // return base.Controls; // } // } //public bool ShouldSerializeControls() //{ // if(this.Dock==DockStyle.Fill) // return true; // else // return false; //} protected override void OnVisibleChanged(EventArgs e) { base.OnVisibleChanged(e); if(this.Visible) { Control.ControlAccessibleObject acc=this.AccessibilityObject as Control.ControlAccessibleObject; if(acc!=null) { acc.NotifyClients(AccessibleEvents.Show); } } } private bool IsToolbarDockSite { get { return !(this.Dock == DockStyle.Fill || m_DocumentDockContainer != null); } } protected override void OnPaintBackground(PaintEventArgs pevent) { if(IsLayoutSuspended) return; if (this.BackgroundImage != null && this.BackgroundImageAlpha == 255 && ((this.BackgroundImagePosition == eBackgroundImagePosition.Stretch || this.BackgroundImagePosition == eBackgroundImagePosition.Tile) || this.BackgroundImage.Width >= this.Width && this.BackgroundImage.Height >= this.Height)) return; if(!m_BackColor2.IsEmpty && !this.BackColor.IsEmpty) { if(this.Width>0 && this.Height>0) { DisplayHelp.FillRectangle(pevent.Graphics, this.ClientRectangle, this.BackColor, this.BackColor2, m_BackColorGradientAngle); return; } } if(this.Controls.Count>0 && this.Controls[0] is Bar && ((Bar)this.Controls[0]).ThemedBackground) { ThemeRebar theme=this.ThemeRebar; theme.DrawBackground(pevent.Graphics,ThemeRebarParts.Background,ThemeRebarStates.Normal,this.ClientRectangle); return; } ColorScheme cs = GetColorScheme(); if (cs != null && this.BackColor != Color.Transparent) { if(this.IsToolbarDockSite && StyleManager.IsVisualStudio2012(StyleManager.Style)) DisplayHelp.FillRectangle(pevent.Graphics, this.ClientRectangle, cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle); else DisplayHelp.FillRectangle(pevent.Graphics, this.ClientRectangle, cs.DockSiteBackColor, cs.DockSiteBackColor2, cs.DockSiteBackColorGradientAngle); } else base.OnPaintBackground(pevent); } private ColorScheme GetColorScheme() { if (m_Owner != null && m_Owner.UseGlobalColorScheme) { if ((m_Owner.Style == eDotNetBarStyle.Office2007 || m_Owner.Style == eDotNetBarStyle.StyleManagerControlled) && GlobalManager.Renderer is Office2007Renderer) { return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.LegacyColors; } return m_Owner.ColorScheme; } else if (this.Controls.Count > 0 && this.Controls[0] is Bar && (((Bar)this.Controls[0]).Style == eDotNetBarStyle.Office2003 || ((Bar)this.Controls[0]).Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(((Bar)this.Controls[0]).Style)) ) { Bar bar = this.Controls[0] as Bar; if (bar.Style == eDotNetBarStyle.StyleManagerControlled && GlobalManager.Renderer is Office2007Renderer) return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.LegacyColors; return bar.GetColorScheme(); } return null; } protected override void OnPaint(PaintEventArgs pevent) { if(IsLayoutSuspended) return; if(this.BackgroundImage!=null) { BarFunctions.PaintBackgroundImage(pevent.Graphics,this.ClientRectangle,this.BackgroundImage,m_BackgroundImagePosition,m_BackgroundImageAlpha); } else base.OnPaint(pevent); } private DevComponents.DotNetBar.ThemeRebar ThemeRebar { get { if(m_ThemeRebar==null) { m_ThemeRebar=new ThemeRebar(this); } return m_ThemeRebar; } } protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); this.RecalcLayout(); } protected override void OnHandleDestroyed(EventArgs e) { if(m_ThemeRebar!=null) { m_ThemeRebar.Dispose(); m_ThemeRebar=null; } base.OnHandleDestroyed(e); } protected override void WndProc(ref Message m) { if(m.Msg==NativeFunctions.WM_THEMECHANGED) { m_ThemeRebar=null; } base.WndProc(ref m); } /// /// Specifies the position and manner in which a site is docked. /// public override System.Windows.Forms.DockStyle Dock { get { return base.Dock; } set { base.Dock=value; if(value==System.Windows.Forms.DockStyle.Top || value==System.Windows.Forms.DockStyle.Bottom || value==DockStyle.Fill) { if(this.Controls.Count==0) this.Height=0; m_DockOrientation=eOrientation.Horizontal; } else { if(this.Controls.Count==0) this.Width=0; m_DockOrientation=eOrientation.Vertical; } } } protected override void OnControlRemoved(ControlEventArgs e) { base.OnControlRemoved(e); // Designer is removing controls directly during Undo operations so resize the site. if (this.DesignMode) RecalcLayout(); } protected override void OnControlAdded(ControlEventArgs e) { base.OnControlAdded(e); IDockInfo pDockInfo=e.Control as IDockInfo; if(pDockInfo==null) { // Refuse controls that does not implement IDockInfo interface this.Controls.Remove(e.Control); throw new System.ArgumentException("Only Bar objects can be added to DockSite through DotNetBar designer."); } //if(IsDocumentDock) UpdateBarsCollection(); } internal bool IsAnyControlVisible { get { foreach (Control c in this.Controls) { if (c is Bar) { if(((Bar)c).IsVisible) return true; } else if ( c.Visible) return true; } return false; } } /// /// Docks the bar to the dock site. /// /// Bar to dock. internal void AddBar(Control objBar) { IDockInfo pDockInfo=objBar as IDockInfo; if(pDockInfo==null) { // Throw exception IDockInfo must be implemented throw new System.ArgumentException("Only Bar objects can be added to DockSite through DotNetBar designer."); } if(!this.Visible) { if(this.Owner==null || this.Owner!=null && !this.Owner.IsLoadingDefinition) { BarFunctions.SetControlVisible(this,true); } } // Set Dock Orientation pDockInfo.DockOrientation=m_DockOrientation; // Find the right place for the control Control objCtrl=null; IDockInfo pCtrlDockInfo=null; bool bAdded=false; for(int i=0;i0) ((Bar)objBar).SyncLineMinHeight(); else if(m_DockOrientation==eOrientation.Vertical && bar.ItemsContainer.MinWidth>0) ((Bar)objBar).SyncLineMinWidth(); } NormalizeBars(); LayoutBars(); } /// /// Dockes the Bar to dock site at specified position. /// /// Bar to dock. /// Bar insert position. internal void AddBar(Control objBar, int iInsertAtPosition) { IDockInfo pDockInfo=objBar as IDockInfo; if(pDockInfo==null) { // Throw exception IDockInfo must be implemented throw new System.ArgumentException("Only Bar objects can be added to DockSite through DotNetBar designer."); } if(!this.Visible) { BarFunctions.SetControlVisible(this,true); } // Set Dock Orientation pDockInfo.DockOrientation=m_DockOrientation; this.Controls.Add(objBar); this.Controls.SetChildIndex(objBar,iInsertAtPosition); if(objBar is Bar && ((Bar)objBar).LayoutType==eLayoutType.DockContainer) { Bar bar=objBar as Bar; if(m_DockOrientation==eOrientation.Horizontal && bar.ItemsContainer.MinHeight>0) ((Bar)objBar).SyncLineMinHeight(); else if(m_DockOrientation==eOrientation.Vertical && bar.ItemsContainer.MinWidth>0) ((Bar)objBar).SyncLineMinWidth(); } NormalizeBars(); LayoutBars(); } internal void SetBarPosition(Control objBar, int iNewIndex) { if(this.Contains(objBar)) { if(this.Controls.GetChildIndex(objBar)!=iNewIndex) { this.Controls.SetChildIndex(objBar,iNewIndex); } LayoutBars(); } } internal void SetBarPosition(Control objBar, int iNewIndex, bool bInNewLine) { if(this.Contains(objBar)) { if(this.Controls.GetChildIndex(objBar)!=iNewIndex) { this.Controls.SetChildIndex(objBar,iNewIndex); } if(bInNewLine) { iNewIndex=this.Controls.IndexOf(objBar); if(iNewIndex>=0) { if(iNewIndex>0) ((IDockInfo)objBar).SetDockLine(((IDockInfo)this.Controls[iNewIndex-1]).DockLine+1); else ((IDockInfo)objBar).SetDockLine(-1); for(int i=iNewIndex+1;i0 && i>this.Controls.GetChildIndex(objBar)) i--; this.Controls.SetChildIndex(objBar,i); return; } else if(pDockInfo.DockLine0) i--; this.Controls.SetChildIndex(objBar,i); return; } } // Set its position to the end this.Controls.SetChildIndex(objBar,this.Controls.Count); } /// /// Relayouts all docked controls in the site. /// public void RecalcLayout() { LayoutBars(); } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public bool NeedsLayout { get {return m_NeedsLayout;} set {m_NeedsLayout=value;} } private void NormalizeBars() { if(IsLayoutSuspended) { m_NeedsNormalize=true; return; } int iDockLine=-1, iLastDockLine=-2; for(int i=0;i 0 && oldBounds.Height > 0) ? oldBounds : this.Bounds, true); this.Parent.Update(); } if(parentZOrder!=-1) this.Parent.Controls.SetChildIndex(this,parentZOrder); return; } IDockInfo pDockInfo=null; Bar objBar=null; Control objCtrl=null; System.Drawing.Size objMinSize; //System.Drawing.Size objOldSize; //System.Drawing.Point objOldLocation; bool bResetOffset=false; Rectangle oldDockSiteSize=this.Bounds; if (this.Parent != null && this.Parent.Visible && m_OptimizeLayoutRedraw) // WARNING: Sending this message when parent is not visible was causing strange effects with layout of native .NET dock controls { if(this.Parent!=null) parentZOrder=this.Parent.Controls.IndexOf(this); NativeFunctions.SendMessage(this.Handle,NativeFunctions.WM_SETREDRAW,0,0); } // Horizontal and vertical spacing is needed for Office2003 style support int iHorSpacing=0, iVerSpacing=0; // Need to know when we have stretched dock containers in the same line int[] lineDockCounts=new int[256]; int[] lineDockProcessed=new int[256]; int[] lineContainerMaxSize=new int[256]; int[] lineDockSize=new int[256]; int[] lineDefHeightCount=new int[256]; ArrayList arrBarsInSameLine=null; for(int i=0;i=0) { lineDockCounts[objBar.DockLine]++; lineDockProcessed[objBar.DockLine]++; if(m_DockOrientation==eOrientation.Horizontal) { if(objBar.SplitDockWidth==0) lineDefHeightCount[objBar.DockLine]++; else lineDockSize[objBar.DockLine]+=objBar.SplitDockWidth; } else { if(objBar.SplitDockHeight==0) lineDefHeightCount[objBar.DockLine]++; else lineDockSize[objBar.DockLine]+=objBar.SplitDockHeight; } } } } if (this.Controls.Count > 0 && this.Controls[0] is Bar && ((Bar)this.Controls[0]).LayoutType == eLayoutType.Toolbar && (((Bar)this.Controls[0]).Style == eDotNetBarStyle.Office2003 || ((Bar)this.Controls[0]).Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(((Bar)this.Controls[0]).Style))) { iHorSpacing=2; iVerSpacing=1; } int iMaxSize=0, iX=0, iY=0; // When in horizontal layout this is max. height, for vertical layout this is max width bool bSameLineDocking=false; int iCurrentLine=0,iLastLine=0; bool bRepeatLayout=false; bool bCurrentLineIncreased=false, bSwitchLine=false; do { iMaxSize=0; // When in horizontal layout this is max. height, for vertical layout this is max width iX=0; iY=0; iCurrentLine=0; iLastLine=0; bRepeatLayout=false; arrBarsInSameLine=new ArrayList(this.Controls.Count); if(this.Controls.Count>0) { pDockInfo=this.Controls[0] as IDockInfo; iLastLine=pDockInfo.DockLine; } bool bLastHidden=false; for(int i=0;i