using System; using System.Drawing; namespace DevComponents.DotNetBar { /// /// Provides layout for Side-Bar control. /// [System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)] public class SideBarContainerItem:ImageItem, IDesignTimeProvider { #region Private Variables private eSideBarAppearance m_Appearance=eSideBarAppearance.Traditional; private bool m_ProcessingExpanded=false; private int m_ItemSpacing=1; #endregion #region Internal Implementation /// /// Creates new instance of SideBarContainerItem class. /// public SideBarContainerItem() { m_IsContainer=true; m_SystemItem=true; m_SupportedOrientation=eSupportedOrientation.Horizontal; m_AllowOnlyOneSubItemExpanded = false; } /// /// Returns copy of SideBarContainerItem item /// public override BaseItem Copy() { SideBarContainerItem objCopy=new SideBarContainerItem(); this.CopyToItem(objCopy); return objCopy; } protected override void CopyToItem(BaseItem copy) { SideBarContainerItem objCopy=copy as SideBarContainerItem; base.CopyToItem(objCopy); } /// /// Recalculates the size of the item /// public override void RecalcSize() { // This container will always have one and only one item expanded at the time. // Recalculation of the size for this item is different then rest of the DotNetBar. // This container always takes the size assigned by the Control and never changes // the Size by itself. int iUnexpandItemsHeight=0; int iTotalHeight=0; bool bOverflow=false; // Too many items so there is no need to stretch the expanded since it can't fit if(m_SubItems!=null) { SideBarPanelItem expanded=null; foreach(BaseItem item in m_SubItems) { if(item.Visible) { if(iTotalHeight>this.HeightInternal) { item.Displayed=false; bOverflow=true; continue; } // Give it our maximum size item.WidthInternal=this.WidthInternal; item.HeightInternal=0; item.RecalcSize(); if(item.WidthInternal!=this.WidthInternal) item.WidthInternal=this.WidthInternal; if(item.Expanded && item is SideBarPanelItem && expanded==null) expanded=item as SideBarPanelItem; // Set item position item.LeftInternal=m_Rect.Left; item.TopInternal=m_Rect.Top+iTotalHeight; iTotalHeight+=m_ItemSpacing; // Needed to set the expanded item height and to reposition other items... if(!item.Expanded) iUnexpandItemsHeight+=(item.HeightInternal+m_ItemSpacing); // Remember Total Height iTotalHeight+=item.HeightInternal; item.Displayed=true; } } if(expanded!=null && !bOverflow) { // Expanded item is always "stretched" to fill the space... expanded.HeightInternal=m_Rect.Height-iUnexpandItemsHeight; expanded.RecalcSize(); int iOffsetTop = expanded.DisplayRectangle.Bottom + m_ItemSpacing; if(m_Appearance==eSideBarAppearance.Flat) iOffsetTop--; // Move the items after the expanded item to bottom for(int i=m_SubItems.IndexOf(expanded)+1;i /// Paints this base container /// public override void Paint(ItemPaintArgs pa) { if(this.SuspendLayout) return; System.Drawing.Graphics g=pa.Graphics; if(m_NeedRecalcSize) RecalcSize(); if(m_SubItems==null) return; foreach(BaseItem item in m_SubItems) { if(item.Visible && item.Displayed) { item.Paint(pa); } } } [System.ComponentModel.Browsable(false)] public override eOrientation Orientation { get { return eOrientation.Horizontal; } set { return; } } /// /// Occurs when sub item expanded state has changed. /// /// Sub item affected. protected internal override void OnSubItemExpandChange(BaseItem item) { // Prevent re-entrancy if(m_ProcessingExpanded) return; m_ProcessingExpanded=true; try { // We have to make sure that only one item is always expanded at a time if(item.Expanded) { foreach(BaseItem subitem in m_SubItems) { if(subitem.Expanded && subitem!=item) subitem.Expanded=false; } } else { bool bOneExpanded=false; foreach(BaseItem subitem in m_SubItems) { if(subitem.Expanded) { bOneExpanded=true; break; } } if(!bOneExpanded) item.Expanded=true; } this.RecalcSize(); System.Windows.Forms.Control container=this.ContainerControl as System.Windows.Forms.Control; if(container!=null) container.Refresh(); } finally { m_ProcessingExpanded=false; } } internal eSideBarAppearance Appearance { get {return m_Appearance;} set { if(m_Appearance!=value) { m_Appearance=value; if(m_Appearance==eSideBarAppearance.Flat) m_ItemSpacing=-1; else m_ItemSpacing=1; foreach(SideBarPanelItem item in this.SubItems) { item.Appearance=value; } } } } /// /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not. /// [System.ComponentModel.Browsable(false),System.ComponentModel.DefaultValue(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public override bool Expanded { get { return base.Expanded; } set { if(!value) { foreach(BaseItem item in m_SubItems) { if(item is SideBarPanelItem) { foreach(BaseItem popup in item.SubItems) { if(popup is PopupItem && item.Expanded) popup.Expanded=false; } } } } base.Expanded=value; } } /// /// Occurs when the mouse pointer is over the item and a mouse button is pressed. This is used by internal implementation only. /// [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public override void InternalMouseDown(System.Windows.Forms.MouseEventArgs objArg) { base.InternalMouseDown(objArg); if(this.DesignMode) { if(this.ItemAtLocation(objArg.X,objArg.Y)==null) { IOwner owner=this.GetOwner() as IOwner; if(owner!=null) owner.SetFocusItem(null); } } } /// /// Sets input focus to next visible item in Explorer Bar. /// /// True if focus was set to next visible item otherwise false. public bool FocusNextItem() { bool bBaseCall=true; BaseItem focusItem=((IOwner)this.GetOwner()).GetFocusItem(); bool bFocusNext=false; if(focusItem==null) bFocusNext=true; int iLoopCount=0; while(iLoopCount<2) { foreach(BaseItem item in this.SubItems) { if(item==focusItem) bFocusNext=true; else if(item.Visible && bFocusNext) { ((IOwner)this.GetOwner()).SetFocusItem(item); iLoopCount=2; bBaseCall=false; break; } if(item.Expanded && item.Visible) { foreach(BaseItem child in item.SubItems) { if(child==focusItem) bFocusNext=true; else if(item.Visible && bFocusNext) { ((IOwner)this.GetOwner()).SetFocusItem(child); iLoopCount=2; bBaseCall=false; break; } } if(iLoopCount==2) break; } } iLoopCount++; } return bBaseCall; } /// /// Sets input focus to previous visible item in Explorer Bar. /// /// True if focus was set to previous visible item otherwise false. public bool FocusPreviousItem() { bool bBaseCall=true; BaseItem focusItem=((IOwner)this.GetOwner()).GetFocusItem(); bool bFocusNext=false; if(focusItem==null) bFocusNext=true; int iLoopCount=0; while(iLoopCount<2) { for(int groupIndex=this.SubItems.Count-1;groupIndex>=0;groupIndex--) { BaseItem item=this.SubItems[groupIndex]; if(item.Expanded && item.Visible) { for(int index=item.SubItems.Count-1;index>=0;index--) { BaseItem child=item.SubItems[index]; if(child==focusItem) bFocusNext=true; else if(item.Visible && bFocusNext) { ((IOwner)this.GetOwner()).SetFocusItem(child); iLoopCount=2; bBaseCall=false; break; } } if(iLoopCount==2) break; } if(item==focusItem) bFocusNext=true; else if(item.Visible && bFocusNext) { ((IOwner)this.GetOwner()).SetFocusItem(item); iLoopCount=2; bBaseCall=false; break; } } iLoopCount++; } return bBaseCall; } protected internal override void OnItemAdded(BaseItem item) { base.OnItemAdded(item); NeedRecalcSize=true; if(this.ContainerControl is SideBar && item is SideBarPanelItem) { SideBarPanelItem panel=item as SideBarPanelItem; panel.Appearance=((SideBar)this.ContainerControl).Appearance; panel.RefreshItemStyleSystemColors(); //if(panel.Appearance==eSideBarAppearance.Flat && this.DesignMode) //{ // if(!panel.HasFlatStyle) // SideBar.ApplyColorScheme((SideBarPanelItem)item,((SideBar)this.ContainerControl).PredefinedColorScheme); //} } if(m_SubItems.Count==1) item.Expanded=true; if(this.DesignMode) this.Refresh(); } protected internal override void OnAfterItemRemoved(BaseItem item, int itemIndex) { base.OnAfterItemRemoved(item, itemIndex); NeedRecalcSize=true; if(this.DesignMode) this.Refresh(); } protected internal override void OnSubItemsClear() { base.OnSubItemsClear(); NeedRecalcSize=true; if(this.DesignMode) this.Refresh(); } #endregion #region IDesignTimeProvider Implementation InsertPosition IDesignTimeProvider.GetInsertPosition(Point pScreen, BaseItem dragItem) { foreach(BaseItem panel in this.SubItems) { if(!panel.Visible) continue; if(panel is IDesignTimeProvider) { InsertPosition pos=((IDesignTimeProvider)panel).GetInsertPosition(pScreen, dragItem); if(pos!=null) { return pos; } } } return null; } void IDesignTimeProvider.DrawReversibleMarker(int iPos, bool Before){} void IDesignTimeProvider.InsertItemAt(BaseItem objItem, int iPos, bool Before){} #endregion } }