484 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			484 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Drawing;
 | |
| 
 | |
| namespace DevComponents.DotNetBar
 | |
| {
 | |
| 	/// <summary>
 | |
| 	/// Provides layout for Explorer-Bar control.
 | |
| 	/// </summary>
 | |
| 	[System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)]
 | |
| 	public class ExplorerBarContainerItem:ImageItem,IDesignTimeProvider
 | |
| 	{
 | |
| 		#region Internal Implementation
 | |
| 		internal int m_ItemSpacing=15;
 | |
| 		/// <summary>
 | |
| 		/// Creates new instance of ExplorerBarContainerItem class.
 | |
| 		/// </summary>
 | |
| 		public ExplorerBarContainerItem()
 | |
| 		{
 | |
| 			m_IsContainer=true;
 | |
| 			m_SystemItem=true;
 | |
| 			m_SupportedOrientation=eSupportedOrientation.Horizontal;
 | |
| 			m_AllowOnlyOneSubItemExpanded=false;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Returns copy of ExplorerBarContainerItem item
 | |
| 		/// </summary>
 | |
| 		public override BaseItem Copy()
 | |
| 		{
 | |
| 			ExplorerBarContainerItem objCopy=new ExplorerBarContainerItem();
 | |
| 			this.CopyToItem(objCopy);
 | |
| 			return objCopy;
 | |
| 		}
 | |
| 		protected override void CopyToItem(BaseItem copy)
 | |
| 		{
 | |
| 			ExplorerBarContainerItem objCopy=copy as ExplorerBarContainerItem;
 | |
| 			base.CopyToItem(objCopy);
 | |
| 		}
 | |
| 
 | |
| 		/// <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 ExplorerBarGroupItem)
 | |
| 						{
 | |
| 							foreach(BaseItem popup in item.SubItems)
 | |
| 							{
 | |
| 								if(popup is PopupItem && item.Expanded)
 | |
| 									popup.Expanded=false;
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				base.Expanded=value;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Recalculates the size of the item
 | |
| 		/// </summary>
 | |
| 		public override void RecalcSize()
 | |
| 		{
 | |
| 			// Explorer Container can have none or one or more panels expanded at a time
 | |
| 			// The Control itself is displaying the scroll-bars and handling the
 | |
| 			// case when this container is oversized. It is only possible to have
 | |
| 			// vertical oversize. The items are always made to fit horizontally
 | |
| 			int iY=m_Rect.Top;
 | |
| 			if(m_SubItems!=null)
 | |
| 			{
 | |
| 				foreach(BaseItem item in m_SubItems)
 | |
| 				{
 | |
| 					if(item.Visible)
 | |
| 					{
 | |
| 						// Give it our maximum size
 | |
| 						item.WidthInternal=this.WidthInternal;
 | |
| 						item.HeightInternal=0;
 | |
| 						// Set item position
 | |
| 						item.LeftInternal=m_Rect.Left;
 | |
| 						item.TopInternal=iY;
 | |
| 
 | |
| 						item.RecalcSize();
 | |
| 						if(item.WidthInternal!=this.WidthInternal)
 | |
| 							item.WidthInternal=this.WidthInternal;
 | |
| 						
 | |
| 						iY+=(item.HeightInternal+m_ItemSpacing);
 | |
| 
 | |
| 						item.Displayed=true;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			iY-=m_ItemSpacing;
 | |
| 			this.HeightInternal=iY;
 | |
| 			base.RecalcSize();
 | |
| 		}
 | |
| 
 | |
| 		protected override void OnTopLocationChanged(int oldValue)
 | |
| 		{
 | |
| 			int iDiff=m_Rect.Top-oldValue;
 | |
| 			if(m_SubItems!=null)
 | |
| 			{
 | |
| 				foreach(BaseItem item in m_SubItems)
 | |
| 				{
 | |
| 					if(item.Visible)
 | |
| 					{
 | |
| 						// Set item position
 | |
| 						item.TopInternal+=iDiff;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <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)
 | |
| 				{
 | |
|                     if (item is ExplorerBarGroupItem)
 | |
|                     {
 | |
|                         if (((ExplorerBarGroupItem)item).WordWrapSubItems)
 | |
|                         {
 | |
|                             pa.ButtonStringFormat = pa.ButtonStringFormat & ~(pa.ButtonStringFormat & eTextFormat.SingleLine);
 | |
|                             pa.ButtonStringFormat |= eTextFormat.WordBreak;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             pa.ButtonStringFormat |= eTextFormat.SingleLine;
 | |
|                             pa.ButtonStringFormat = pa.ButtonStringFormat & ~(pa.ButtonStringFormat & eTextFormat.WordBreak);
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         pa.ButtonStringFormat = pa.ButtonStringFormat & ~(pa.ButtonStringFormat & eTextFormat.SingleLine);
 | |
|                         pa.ButtonStringFormat |= eTextFormat.WordBreak;
 | |
|                     }
 | |
| 					item.Paint(pa);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		[System.ComponentModel.Browsable(false)]
 | |
| 		public override eOrientation Orientation
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				return eOrientation.Horizontal;
 | |
| 			}
 | |
| 			set
 | |
| 			{
 | |
| 				return;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/// <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>
 | |
| 		/// Occurs when the mouse pointer is over the item and a mouse button is released. This is used by internal implementation only.
 | |
| 		/// </summary>
 | |
| 		[System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
 | |
| 		public override void InternalMouseUp(System.Windows.Forms.MouseEventArgs objArg)
 | |
| 		{
 | |
| 			if(m_HotSubItem!=null)
 | |
| 			{
 | |
| 				m_HotSubItem.InternalMouseUp(objArg);
 | |
| 			}
 | |
| 			else
 | |
| 				base.InternalMouseUp(objArg);
 | |
| 		}
 | |
| 
 | |
| 		/// <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(item is ExplorerBarGroupItem)
 | |
| 				((ExplorerBarGroupItem)item).VisualPropertyChanged();
 | |
| 			if(this.DesignMode)
 | |
| 			{
 | |
| 				//ExplorerBar bar=this.ContainerControl as ExplorerBar; 
 | |
| 				//this.Refresh();
 | |
| 				ExplorerBar bar=this.ContainerControl as ExplorerBar; 
 | |
| 				if(bar!=null)
 | |
| 					bar.RecalcLayout();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
|         protected internal override void OnAfterItemRemoved(BaseItem item, int itemIndex)
 | |
| 		{
 | |
| 			base.OnAfterItemRemoved(item, itemIndex);
 | |
| 			NeedRecalcSize=true;
 | |
| 			if(this.DesignMode)
 | |
| 			{
 | |
| 				ExplorerBar bar=this.ContainerControl as ExplorerBar; 
 | |
| 				if(bar!=null)
 | |
| 					bar.RecalcLayout();
 | |
| 				//this.Refresh();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		protected internal override void OnSubItemsClear()
 | |
| 		{
 | |
| 			base.OnSubItemsClear();
 | |
| 			NeedRecalcSize=true;
 | |
| 			if(this.DesignMode)
 | |
| 			{
 | |
| 				//this.Refresh();
 | |
| 				ExplorerBar bar=this.ContainerControl as ExplorerBar; 
 | |
| 				if(bar!=null)
 | |
| 					bar.RecalcLayout();
 | |
| 			}
 | |
| 		}
 | |
| 		internal bool _Animating=false;
 | |
| 		protected internal override void OnSubItemExpandChange(BaseItem objChildItem)
 | |
| 		{
 | |
| 			base.OnSubItemExpandChange(objChildItem);
 | |
| 			ExplorerBar exbar=this.ContainerControl as ExplorerBar;
 | |
| 			try
 | |
| 			{
 | |
| 				if(exbar!=null && exbar.AnimationEnabled)
 | |
| 				{
 | |
| 					TimeSpan totalAnimationTime = new TimeSpan(0, 0, 0, 0, exbar.AnimationTime);
 | |
| 					_Animating=true;
 | |
| 					int iStep=1;
 | |
| 					DateTime startTime=DateTime.Now;
 | |
| 					if(objChildItem.Expanded)
 | |
| 					{
 | |
| 						int initalHeight=objChildItem.HeightInternal;
 | |
| 						objChildItem.RecalcSize();
 | |
| 						int targetHeight=objChildItem.HeightInternal;
 | |
| 						for(int i=initalHeight;i<targetHeight;i+=iStep)
 | |
| 						{
 | |
| 							DateTime startPerMove = DateTime.Now;
 | |
| 							objChildItem.HeightInternal=i;
 | |
| 							foreach(BaseItem item in objChildItem.SubItems)
 | |
| 							{
 | |
| 								if(!objChildItem.DisplayRectangle.Contains(item.DisplayRectangle))
 | |
| 									item.Displayed=false;
 | |
| 								else
 | |
| 									item.Displayed=true;
 | |
| 							}
 | |
| 							for(int pos=this.SubItems.IndexOf(objChildItem)+1;pos<this.SubItems.Count;pos++)
 | |
| 								this.SubItems[pos].TopInternal+=iStep;
 | |
| 							
 | |
| //							float perc=(float)i/targetHeight+1;
 | |
| //							iStep=(int)Math.Exp(perc);
 | |
| 							exbar.Refresh();
 | |
| 
 | |
| 							TimeSpan elapsedPerMove = DateTime.Now - startPerMove;
 | |
| 							TimeSpan elapsedTime = DateTime.Now - startTime;
 | |
|                             int totalMs = (int)(totalAnimationTime - elapsedTime).TotalMilliseconds;
 | |
| 							if (totalMs <= 0)
 | |
| 							{
 | |
| 								iStep=targetHeight-i;
 | |
| 							}
 | |
|                             else if (totalMs == 0)
 | |
| 								iStep=1;
 | |
| 							else
 | |
| 							{
 | |
| 								iStep=(targetHeight-i)*(int)elapsedPerMove.TotalMilliseconds / totalMs;
 | |
| 								if(iStep<=0) iStep=1;
 | |
| 
 | |
| 							}
 | |
| 							if(iStep<=0)
 | |
| 								iStep=targetHeight-i;
 | |
| 						}
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						int initalHeight=objChildItem.HeightInternal;
 | |
| 						objChildItem.RecalcSize();
 | |
| 						int targetHeight=objChildItem.HeightInternal;
 | |
| 						for(int i=initalHeight;i>targetHeight;i-=iStep)
 | |
| 						{
 | |
| 							DateTime startPerMove = DateTime.Now;
 | |
| 							objChildItem.HeightInternal=i;
 | |
| 							foreach(BaseItem item in objChildItem.SubItems)
 | |
| 							{
 | |
| 								if(!objChildItem.DisplayRectangle.Contains(item.DisplayRectangle))
 | |
| 									item.Displayed=false;
 | |
| 								else
 | |
| 									item.Displayed=true;
 | |
| 							}
 | |
| 							for(int pos=this.SubItems.IndexOf(objChildItem)+1;pos<this.SubItems.Count;pos++)
 | |
| 								this.SubItems[pos].TopInternal-=iStep;
 | |
| //							float perc=(float)targetHeight/i+1;
 | |
| //							iStep=(int)Math.Exp(perc);
 | |
| 							exbar.Refresh();
 | |
| 
 | |
| 							TimeSpan elapsedPerMove = DateTime.Now - startPerMove;
 | |
| 							TimeSpan elapsedTime = DateTime.Now - startTime;
 | |
| 							if ((totalAnimationTime - elapsedTime).TotalMilliseconds <= 0)
 | |
| 							{
 | |
| 								iStep=i-targetHeight;
 | |
| 							}
 | |
| 							else if((totalAnimationTime - elapsedTime).TotalMilliseconds==0)
 | |
| 								iStep=1;
 | |
| 							else
 | |
| 							{
 | |
| 								iStep=(i-targetHeight)*(int)elapsedPerMove.TotalMilliseconds / Math.Max(1,(int)((totalAnimationTime - elapsedTime).TotalMilliseconds));
 | |
| 								if(iStep<=0) iStep=1;
 | |
| 							}
 | |
| 							if(iStep<=0)
 | |
| 								iStep=i-targetHeight;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			finally
 | |
| 			{
 | |
| 				_Animating=false;
 | |
| 			}
 | |
| 			if(exbar!=null)
 | |
| 				exbar.RecalcLayout();
 | |
| 		}
 | |
| 		#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
 | |
| 	}
 | |
| }
 |