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