438 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			438 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Drawing;
 | |
| 
 | |
| namespace DevComponents.DotNetBar
 | |
| {
 | |
| 	/// <summary>
 | |
| 	/// Provides layout for Side-Bar control.
 | |
| 	/// </summary>
 | |
| 	[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
 | |
| 		/// <summary>
 | |
| 		/// Creates new instance of SideBarContainerItem class.
 | |
| 		/// </summary>
 | |
| 		public SideBarContainerItem()
 | |
| 		{
 | |
| 			m_IsContainer=true;
 | |
| 			m_SystemItem=true;
 | |
| 			m_SupportedOrientation=eSupportedOrientation.Horizontal;
 | |
|             m_AllowOnlyOneSubItemExpanded = false;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Returns copy of SideBarContainerItem item
 | |
| 		/// </summary>
 | |
| 		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);
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Recalculates the size of the item
 | |
| 		/// </summary>
 | |
| 		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<m_SubItems.Count;i++)
 | |
| 					{
 | |
| 						BaseItem item=m_SubItems[i];
 | |
| 						if(item.Visible)
 | |
| 						{
 | |
| 							item.TopInternal=iOffsetTop;
 | |
| 							iOffsetTop+=(item.HeightInternal+m_ItemSpacing);
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			base.RecalcSize();
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Paints this base container
 | |
| 		/// </summary>
 | |
| 		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;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Occurs when sub item expanded state has changed.
 | |
| 		/// </summary>
 | |
| 		/// <param name="item">Sub item affected.</param>
 | |
| 		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;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// 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.
 | |
| 		/// </summary>
 | |
| 		[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;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Occurs when the mouse pointer is over the item and a mouse button is pressed. This is used by internal implementation only.
 | |
| 		/// </summary>
 | |
| 		[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);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Sets input focus to next visible item in Explorer Bar.
 | |
| 		/// </summary>
 | |
| 		/// <returns>True if focus was set to next visible item otherwise false.</returns>
 | |
| 		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;
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Sets input focus to previous visible item in Explorer Bar.
 | |
| 		/// </summary>
 | |
| 		/// <returns>True if focus was set to previous visible item otherwise false.</returns>
 | |
| 		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
 | |
| 	}
 | |
| }
 |