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
|
|
}
|
|
}
|