vbAccelerator - Contents of code file: ButtonListBar_ButtonListBarTestCS_ButtonListBar.csusing System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace vbAccelerator.Controls.ListBar
{
#region Event Argument Classes
public class SelectionChangedEventArgs
{
private ButtonListBarItem m_item = null;
public ButtonListBarItem Item
{
get
{
return this.m_item;
}
}
public SelectionChangedEventArgs(
ButtonListBarItem item
)
{
this.m_item = item;
}
}
public class ItemClickEventArgs
{
private ButtonListBarItem m_item = null;
private Point m_ptClick;
private MouseButtons m_button = MouseButtons.None;
public ButtonListBarItem Item
{
get
{
return this.m_item;
}
}
public int X
{
get
{
return m_ptClick.X;
}
}
public int Y
{
get
{
return m_ptClick.Y;
}
}
public MouseButtons Button
{
get
{
return this.m_button;
}
}
public ItemClickEventArgs(
ButtonListBarItem item,
Point ptClick,
MouseButtons button
)
{
m_ptClick = ptClick;
m_item = item;
m_button = button;
}
}
#endregion
#region Event Delegates
public delegate void ItemClickEventHandler(object sender, ItemClickEventArgs
e);
public delegate void SelectionChangedEventHandler(object sender,
SelectionChangedEventArgs e);
#endregion
#region ButtonListBar
/// <summary>
/// Summary description for ButtonListBar.
/// </summary>
public class ButtonListBar : System.Windows.Forms.UserControl
{
#region Member Variables
private bool m_isXp = false;
private ImageList m_imageList = null;
private ToolTip m_toolTip = null;
private ButtonListBarItems m_items = null;
private int m_buttonWidth = 96;
private int m_lastButtonWidth = 0;
private bool m_showScroll = false;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
#endregion
#region Events
public event ItemClickEventHandler ItemClick;
public event MouseEventHandler BarClick ;
public event SelectionChangedEventHandler SelectionChanged ;
#endregion
#region Unmanaged Code
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public override string ToString()
{
return String.Format("({0},{1})-({2},{3})", left, top, right,
bottom);
}
}
[StructLayout(LayoutKind.Sequential)]
private struct SIZEAPI
{
public int cx;
public int cy;
public override string ToString()
{
return String.Format("{0} x {1}", cx, cy);
}
}
[DllImport("gdi32")]
private extern static IntPtr SelectObject(
IntPtr hDC,
IntPtr hObject);
[DllImport("gdi32")]
private extern static int DeleteObject(
IntPtr hObject);
[DllImport("user32")]
private extern static int GetSystemMetrics(
int nIndex);
private const int SM_CXVSCROLL = 2;
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static IntPtr OpenThemeData(
IntPtr hWnd,
string pszClassList
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int CloseThemeData(
IntPtr hTheme);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int DrawThemeBackground(
IntPtr hTheme,
IntPtr hDC,
int iPartId,
int iStateId,
ref RECT pRect,
ref RECT pClipRect
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int DrawThemeParentBackground(
IntPtr hTheme,
IntPtr hDC,
ref RECT prc
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int GetThemeBackgroundContentRect(
IntPtr hTheme,
IntPtr hDC,
int iPartId,
int iStateId,
ref RECT pBoundingRect,
ref RECT pContentRect
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int DrawThemeText(
IntPtr hTheme,
IntPtr hDC,
int iPartId,
int iStateId,
string pszText,
int iCharCount,
int dwTextFlag,
int dwTextFlags2,
ref RECT pRect
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int DrawThemeIcon(
IntPtr hTheme,
IntPtr hDC,
int iPartId,
int iStateId,
ref RECT pRect,
IntPtr hIml,
int iImageIndex
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int GetThemePartSize(
IntPtr hTheme,
IntPtr hDC,
int iPartId,
int iStateId,
ref RECT pRect,
int iSize,
ref SIZEAPI pSz
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int GetThemeTextExtent(
IntPtr hTheme,
IntPtr hDC,
int iPartId,
int iStateId,
string pszText,
int iCharCount,
int dwTextFlags,
ref RECT pBoundingRect,
ref RECT pExtentRect
);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private extern static int DrawThemeBackground(
IntPtr hTheme,
IntPtr hDC,
int iPartId,
int iStateId,
ref RECT pDestRect,
int uEdge,
int uFlags,
ref RECT pContentRect
);
private const int S_OK = 0;
private const int HWND_DESKTOP = 0;
// THEMESIZE
private const int TS_MIN = 0; //// minimum size
private const int TS_TRUE = 1; //// size without stretching
private const int TS_DRAW = 2; //// size that theme mgr will
use to draw part
// Button class
private const string UXTHEMEBUTTONCLASS = "Button";
private const string UXTHEMETOOLBARCLASS = "Toolbar";
// Button part
private const int TP_BUTTON = 1;
private const int BP_PUSHBUTTON = 1;
// Button states
private const int TS_NORMAL = 1;
private const int TS_HOT = 2;
private const int TS_PRESSED = 3;
private const int TS_DISABLED = 4;
private const int TS_CHECKED = 5;
private const int TS_HOTCHECKED = 6;
private const int PBS_DISABLED = 4;
// DrawTextFlags
private const int DT_TOP = 0x0;
private const int DT_LEFT = 0x0;
private const int DT_CENTER = 0x1;
private const int DT_RIGHT = 0x2;
private const int DT_VCENTER = 0x4;
private const int DT_BOTTOM = 0x8;
private const int DT_WORDBREAK = 0x10;
private const int DT_SINGLELINE = 0x20;
private const int DT_EXPANDTABS = 0x40;
private const int DT_TABSTOP = 0x80;
private const int DT_NOCLIP = 0x100;
private const int DT_EXTERNALLEADING = 0x200;
private const int DT_CALCRECT = 0x400;
private const int DT_NOPREFIX = 0x800;
private const int DT_INTERNAL = 0x1000;
private const int DT_EDITCONTROL = 0x2000;
private const int DT_PATH_ELLIPSIS = 0x4000;
private const int DT_END_ELLIPSIS = 0x8000;
private const int DT_MODIFYSTRING = 0x10000;
private const int DT_RTLREADING = 0x20000;
private const int DT_WORD_ELLIPSIS = 0x40000;
private const int DT_NOFULLWIDTHCHARBREAK = 0x80000;
private const int DT_HIDEPREFIX = 0x100000;
private const int DT_PREFIXONLY = 0x200000;
// UxTheme DrawText Additional Flag
private const int DTT_GRAYED = 0x1; //// draw a grayed-out
string
#endregion
public ButtonListBar()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitForm call
base.TabStop = true;
base.SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer |
ControlStyles.ResizeRedraw,
true);
m_items = CreateItemCollection();
Version ver = System.Environment.OSVersion.Version;
if (ver.Major > 5)
{
m_isXp = true;
}
else
{
if (ver.Major == 5)
{
if (ver.Minor >= 1)
{
m_isXp = true;
}
}
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
#region Properties and Methods
public System.Windows.Forms.ImageList ImageList
{
get
{
return m_imageList;
}
set
{
m_imageList = value;
}
}
public System.Windows.Forms.ToolTip ToolTip
{
get
{
return m_toolTip;
}
set
{
m_toolTip = value;
}
}
public ButtonListBarItems Items
{
get
{
return m_items;
}
}
public int ButtonWidth
{
get
{
return m_buttonWidth;
}
set
{
m_buttonWidth = value;
OnItemChanged(null);
}
}
public ButtonListBarItem SelectedItem
{
get
{
ButtonListBarItem ret = null;
foreach (ButtonListBarItem item in m_items)
{
if (item.Selected)
{
ret = item;
break;
}
}
return ret;
}
}
#endregion
internal bool OnSelectItem(
ButtonListBarItem item,
bool value
)
{
if (value)
{
for (int i = 0; i < m_items.Count; i++)
{
if (m_items[i] != item)
{
if (m_items[i].Selected)
{
m_items[i].Selected = false;
}
}
}
SelectionChangedEventArgs e = new SelectionChangedEventArgs(item);
OnSelectionChanged(e);
return value;
}
else
{
return value;
}
}
internal void OnItemChanged(
ButtonListBarItem item
)
{
int minHeight = 0;
if (m_items != null)
{
if (m_items.Count > 0)
{
// Measure all the items & evaluate the overall height
bool useXpStyles = m_isXp;
IntPtr hTheme = IntPtr.Zero;
if (useXpStyles)
{
hTheme = OpenThemeData(
this.Handle,
UXTHEMEBUTTONCLASS);
if (hTheme.Equals(IntPtr.Zero))
{
useXpStyles = false;
}
}
ButtonListBarItem lastBarItem = null;
int iconSize = 0;
Graphics gfx = Graphics.FromHwnd(this.Handle);
if (m_imageList != null)
{
iconSize = m_imageList.ImageSize.Height;
}
if (useXpStyles)
{
RECT tTextR = new RECT();
RECT tTextBoundR = new RECT();
int lR = 0;
IntPtr hdc = gfx.GetHdc();
IntPtr hFont = this.Font.ToHfont();
IntPtr hFontOld = SelectObject(hdc, hFont);
foreach (ButtonListBarItem barItem in m_items)
{
string itemText = barItem.Text;
tTextR.top = 0;
tTextR.bottom = 1280;
tTextR.left = 6;
tTextR.right = m_buttonWidth - 12;
tTextBoundR.top = 0;
tTextBoundR.bottom = 1280;
tTextBoundR.left = 3;
tTextBoundR.right = m_buttonWidth - 12;
lR = GetThemeTextExtent(
hTheme,
hdc,
TP_BUTTON,
TS_NORMAL,
itemText, -1,
DT_CENTER | DT_WORDBREAK,
ref tTextBoundR, ref tTextR);
//Console.WriteLine("GetThemeTextExtent {0}, {1}, {2}",
lR, barItem.Text, tTextR.ToString())
if (lastBarItem == null)
{
barItem.Start = 4;
}
else
{
barItem.Start = lastBarItem.Start + lastBarItem.Extent
+ 4;
}
barItem.Extent = tTextR.bottom - tTextR.top + 4 + iconSize
+ 6;
minHeight = barItem.Start + barItem.Extent;
lastBarItem = barItem;
}
SelectObject(hdc, hFontOld);
DeleteObject(hFont);
gfx.ReleaseHdc(hdc);
CloseThemeData(hTheme);
}
else
{
StringFormat fmt = new StringFormat();
fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Near;
fmt.Trimming = StringTrimming.None;
fmt.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
foreach (ButtonListBarItem barItem in m_items)
{
string itemText = barItem.Text;
int itemHeight = (int)gfx.MeasureString(
itemText,
this.Font,
m_buttonWidth - 12,
fmt).Height;
//Console.WriteLine("GDI+ String Height {0}, {1}",
itemText, itemHeight)
if (lastBarItem == null)
{
barItem.Start = 4;
}
else
{
barItem.Start = lastBarItem.Start + lastBarItem.Extent
+ 4;
}
barItem.Extent = itemHeight + 4 + iconSize + 6;
minHeight = barItem.Start + barItem.Extent;
lastBarItem = barItem;
}
fmt.Dispose();
}
gfx.Dispose();
minHeight = minHeight + 3;
}
}
bool showScroll = false;
if (minHeight > this.Height)
{
showScroll = true;
}
this.AutoScrollMinSize = new Size(0, minHeight);
if (
((m_showScroll != showScroll)) |
((m_lastButtonWidth != m_buttonWidth))
)
{
if (showScroll)
{
this.Width = m_buttonWidth + GetSystemMetrics(SM_CXVSCROLL);
}
else
{
this.Width = m_buttonWidth;
}
m_showScroll = showScroll;
m_lastButtonWidth = m_buttonWidth;
}
else
{
this.Invalidate();
}
}
protected override void OnPaint(
System.Windows.Forms.PaintEventArgs e)
{
// Clear the background
Brush br = new SolidBrush(this.BackColor);
e.Graphics.FillRectangle(br, e.ClipRectangle);
br.Dispose();
if ((m_items == null) || (m_items.Count == 0))
{
return;
}
// Paint the buttons:
bool useXpStyles = m_isXp;
IntPtr hTheme = IntPtr.Zero;
if (useXpStyles)
{
hTheme = OpenThemeData(this.Handle, UXTHEMETOOLBARCLASS);
if (hTheme.Equals(IntPtr.Zero))
{
useXpStyles = false;
}
}
int iconSize = 0;
if (m_imageList != null)
{
iconSize = m_imageList.ImageSize.Height;
}
int iStateId = 0;
string itemText = "";
if (useXpStyles)
{
// Drawing using XP Styles
IntPtr hDC = e.Graphics.GetHdc();
RECT tR = new RECT();
tR.left = 0;
tR.right = m_buttonWidth;
tR.top = 0;
tR.bottom = this.Height;
RECT tItemR = new RECT();
RECT tContentR = new RECT();
RECT tIconR = new RECT();
IntPtr hFontOld = IntPtr.Zero;
IntPtr hFont = this.Font.ToHfont();
hFontOld = SelectObject(hDC, hFont);
int textAlign = DT_CENTER | DT_WORDBREAK;
foreach (ButtonListBarItem barItem in m_items)
{
tItemR.left = tR.left + 3;
tItemR.right = tR.right - 3;
tItemR.top = barItem.Start + this.AutoScrollPosition.Y;
tItemR.bottom = barItem.Start + barItem.Extent +
this.AutoScrollPosition.Y;
if (barItem.Enabled) {
if (barItem.MouseDown) {
if (barItem.MouseOver){
if (barItem.Selected) {
iStateId = TS_HOTCHECKED; }
else {
iStateId = TS_PRESSED; }
}
else {
if (barItem.Selected) {
iStateId = TS_CHECKED; }
else {
iStateId = TS_HOT; }
}
}
else {
if (barItem.MouseOver) {
if (barItem.Selected) {
iStateId = TS_HOTCHECKED; }
else {
iStateId = TS_HOT;}
}
else {
if (barItem.Selected) {
iStateId = TS_CHECKED; }
else {
iStateId = TS_NORMAL; }
}
}
}
else
{
iStateId = TS_DISABLED;
}
DrawThemeBackground(hTheme, hDC, TP_BUTTON, iStateId,
ref tItemR, ref tItemR);
GetThemeBackgroundContentRect(hTheme, hDC, TP_BUTTON, iStateId,
ref tItemR, ref tContentR);
if (iStateId == TS_DISABLED)
{
CloseThemeData(hTheme);
hTheme = OpenThemeData(this.Handle, UXTHEMEBUTTONCLASS);
iStateId = PBS_DISABLED;
}
tIconR = tContentR;
tIconR.left = tContentR.left + (tContentR.right - tContentR.left
- iconSize) / 2;
tIconR.right = tIconR.left + iconSize;
tIconR.top += 4;
tIconR.bottom = tIconR.top + iconSize;
if (iStateId == TS_PRESSED)
{
tIconR.left += 1;
tIconR.top += 1;
}
if (m_imageList != null)
{
SelectObject(hDC, hFontOld);
DeleteObject(hFont);
e.Graphics.ReleaseHdc(hDC);
if (barItem.Enabled)
{
e.Graphics.DrawImage(
m_imageList.Images[barItem.IconIndex],
tIconR.left, tIconR.top);
}
else
{
ControlPaint.DrawImageDisabled(
e.Graphics,
m_imageList.Images[barItem.IconIndex],
tIconR.left,
tIconR.top,
this.BackColor);
}
hDC = e.Graphics.GetHdc();
hFont = this.Font.ToHfont();
hFontOld = SelectObject(hDC, hFont);
}
tContentR.top = tContentR.top + 4 + iconSize;
tContentR.left += 3;
tContentR.right -= 3;
if (iStateId == TS_PRESSED)
{
tContentR.left += 1;
tContentR.top += 1;
tContentR.right += 1;
tContentR.bottom += 1;
}
itemText = barItem.Text;
DrawThemeText(hTheme, hDC, BP_PUSHBUTTON, iStateId,
itemText, -1,
textAlign,
(barItem.Enabled ? 0 : DTT_GRAYED),
ref tContentR);
if (iStateId == TS_DISABLED)
{
CloseThemeData(hTheme);
hTheme = OpenThemeData(this.Handle, UXTHEMETOOLBARCLASS);
}
}
CloseThemeData(hTheme);
SelectObject(hDC, hFontOld);
DeleteObject(hFont);
e.Graphics.ReleaseHdc(hDC);
}
else
{
// Drawing using .NET Framework
StringFormat fmt = new StringFormat();
fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Near;
fmt.Trimming = StringTrimming.None;
fmt.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
Brush brText = new SolidBrush(this.ForeColor);
foreach (ButtonListBarItem barItem in m_items)
{
if (barItem.Enabled)
{
if (barItem.MouseDown)
{
if (barItem.MouseOver)
{
if (barItem.Selected)
{
iStateId = TS_HOTCHECKED; }
else
{
iStateId = TS_PRESSED; }
}
else
{
if (barItem.Selected)
{
iStateId = TS_CHECKED; }
else
{
iStateId = TS_HOT; }
}
}
else
{
if (barItem.MouseOver)
{
if (barItem.Selected)
{
iStateId = TS_HOTCHECKED; }
else
{
iStateId = TS_HOT;}
}
else
{
if (barItem.Selected)
{
iStateId = TS_CHECKED; }
else
{
iStateId = TS_NORMAL; }
}
}
}
else
{
iStateId = TS_DISABLED;
}
Rectangle itemRect = new Rectangle(3, barItem.Start,
m_buttonWidth - 6, barItem.Extent);
itemRect.Offset(0, this.AutoScrollPosition.Y);
// Draw background to item (if necessary);
if (iStateId == TS_CHECKED)
{
e.Graphics.FillRectangle(SystemBrushes.Control, itemRect);
}
// Draw border:
if ((iStateId == TS_HOTCHECKED) || (iStateId == TS_CHECKED) )
{
// DrawEdgeAPI(m_cMemDC.hDC, tItemR, BDR_SUNKEN, BF_RECT Or
BF_SOFT)
ControlPaint.DrawBorder3D(e.Graphics, itemRect,
Border3DStyle.Sunken, Border3DSide.All);
}
else if (iStateId == TS_HOT)
{
// DrawEdgeAPI(m_cMemDC.hDC, tItemR, BDR_RAISED, BF_RECT Or
BF_SOFT)
ControlPaint.DrawBorder3D(e.Graphics, itemRect,
Border3DStyle.Raised, Border3DSide.All);
}
else if (iStateId == TS_PRESSED)
{
// DrawEdgeAPI(m_cMemDC.hDC, tItemR, BDR_SUNKEN, BF_RECT Or
BF_SOFT)
ControlPaint.DrawBorder3D(e.Graphics, itemRect,
Border3DStyle.Sunken, Border3DSide.All);
}
itemRect.Inflate(-2, -2);
Rectangle iconRect = new Rectangle(
itemRect.X + (itemRect.Width - iconSize) / 2,
itemRect.Y + 4,
iconSize,
iconSize);
if (iStateId == TS_PRESSED)
{
iconRect.Offset(1, 1);
}
if (m_imageList != null)
{
if (barItem.Enabled)
{
e.Graphics.DrawImage(
m_imageList.Images[barItem.IconIndex],
iconRect.X, iconRect.Y);
}
else
{
ControlPaint.DrawImageDisabled(
e.Graphics,
m_imageList.Images[barItem.IconIndex],
iconRect.X,
iconRect.Y,
this.BackColor);
}
}
itemRect.Y = itemRect.Y + iconSize + 4;
// itemRect.Inflate(-6, 0)
if (iStateId == TS_PRESSED)
{
itemRect.Offset(1, 1);
}
RectangleF textRect = new RectangleF(itemRect.X, itemRect.Y,
itemRect.Width, itemRect.Height);
itemText = barItem.Text;
if (iStateId == TS_DISABLED)
{
ControlPaint.DrawStringDisabled(e.Graphics,
itemText, this.Font,
Color.FromKnownColor(KnownColor.ControlDark),
textRect, fmt);
}
else
{
e.Graphics.DrawString(
itemText, this.Font, brText,
textRect, fmt);
}
}
brText.Dispose();
fmt.Dispose();
}
}
protected virtual ButtonListBarItems CreateItemCollection()
{
return new ButtonListBarItems(this);
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (m_items != null)
{
if (m_items.Count > 0)
{
int lNewIndex = -1;
int lCurrentIndex = -1;
int lMouseOverIndex = -1;
bool bFound = false;
for (int i = 0; i < m_items.Count; i++)
{
if (m_items[i].MouseOver)
{
lMouseOverIndex = i;
}
if (m_items[i].Selected)
{
lCurrentIndex = i;
}
}
if (lMouseOverIndex > 0)
{
lCurrentIndex = lMouseOverIndex;
}
switch (e.KeyCode)
{
case Keys.Up:
lNewIndex = selectNext(lCurrentIndex, -1);
break;
case Keys.Down:
lNewIndex = selectNext(lCurrentIndex, 1);
break;
case Keys.PageUp:
lNewIndex = selectNext(lCurrentIndex, -4);
break;
case Keys.PageDown:
lNewIndex = selectNext(lCurrentIndex, 4);
break;
case Keys.Home:
lNewIndex = 1;
while (!bFound)
{
if (m_items[lNewIndex].Enabled)
{
bFound = true;
}
else
{
lNewIndex++;
if (lNewIndex >= m_items.Count)
{
bFound = true;
}
}
}
break;
case Keys.End:
lNewIndex = m_items.Count - 1;
while (!bFound)
{
if (m_items[lNewIndex].Enabled)
{
bFound = true;
}
else
{
lNewIndex--;
if (lNewIndex < 0)
{
bFound = true;
}
}
}
break;
case Keys.Enter:
if (lMouseOverIndex >= 0)
{
m_items[lMouseOverIndex].Selected = true;
m_items[lMouseOverIndex].MouseOver = false;
for (int i = 0; i < m_items.Count; i++)
{
m_items[i].MouseOver = false;
}
ensureVisible(lMouseOverIndex);
ItemClickEventArgs itemClickArgs = new
ItemClickEventArgs(
m_items[lMouseOverIndex],
new Point(0,0),
MouseButtons.None);
OnItemClick(itemClickArgs);
}
break;
}
if ((lNewIndex != lCurrentIndex) &&
(lNewIndex > -1) &&
(lNewIndex < m_items.Count))
{
for (int i = 0; i < m_items.Count; i++)
{
if (i == lNewIndex)
{
m_items[i].MouseOver = true;
}
else
{
m_items[i].MouseOver = false;
}
}
ensureVisible(lNewIndex);
this.Invalidate();
}
}
}
}
private int selectNext(
int lCurrent,
int lDir
)
{
bool bFound = false;
int lNewIndex = -1;
int lLastChecked = -1;
lLastChecked = lCurrent;
while (!bFound)
{
lNewIndex = lLastChecked + lDir;
if ((lNewIndex < 0) || (lNewIndex >= m_items.Count))
{
if (Math.Abs(lDir) > 1)
{
// equivalent to hitting Home or End:
if (Math.Sign(lDir) == 1)
{
// End
lNewIndex = m_items.Count - 1;
while (!bFound)
{
if (m_items[lNewIndex].Enabled)
{
bFound = true;
}
else
{
lNewIndex --;
if (lNewIndex < 0)
{
bFound = true;
}
}
}
}
else
{
// Home
lNewIndex = 0;
while (!bFound)
{
if (m_items[lNewIndex].Enabled)
{
bFound = true;
}
else
{
lNewIndex ++;
if (lNewIndex >= m_items.Count)
{
bFound = true;
}
}
}
}
}
bFound = true;
}
else
{
lLastChecked = lNewIndex;
if (m_items[lNewIndex].Enabled)
{
bFound = true;
}
lDir = Math.Sign(lDir);
}
}
return lNewIndex;
}
protected override bool IsInputKey(
System.Windows.Forms.Keys keyData)
{
bool ret = base.IsInputKey(keyData);
switch (keyData)
{
case Keys.Up:
case Keys.Down:
case Keys.Right:
case Keys.Left:
case Keys.Enter:
ret = true;
break;
}
return ret;
}
protected override void OnMouseLeave(
System.EventArgs e )
{
base.OnMouseLeave(e);
int index = -1;
for (int i = 0; i < m_items.Count; i++)
{
if (m_items[i].MouseDown)
{
return;
}
else
{
if (m_items[i].MouseOver)
{
index = i;
}
}
}
if ((index >= 0) && (m_items.Count > 0))
{
if (HitTest() < 0)
{
setToolTip("");
m_items[index].MouseOver = false;
this.Invalidate();
}
}
}
protected override void OnMouseDown(
System.Windows.Forms.MouseEventArgs e
)
{
base.OnMouseDown(e);
ItemClickEventArgs itemEventArgs = null;
int index = HitTest();
if (index > -1)
{
if (e.Button == MouseButtons.Left)
{
m_items[index].MouseDown = true;
this.Invalidate();
}
else if (e.Button == MouseButtons.Right)
{
itemEventArgs = new ItemClickEventArgs(
m_items[index],
new Point(e.X, e.Y),
MouseButtons.Right);
OnItemClick(itemEventArgs);
}
}
else if (e.Button == MouseButtons.Right)
{
OnBarClick(e);
}
}
private void setToolTip(
string sToolTip
)
{
if (m_toolTip != null)
{
m_toolTip.SetToolTip(this, sToolTip);
}
}
protected override void OnMouseMove(
System.Windows.Forms.MouseEventArgs e
)
{
base.OnMouseMove(e);
bool changed = false;
int index = HitTest();
for (int i = 0; i < m_items.Count; i++)
{
if (i == index)
{
if (!m_items[i].MouseOver)
{
setToolTip(m_items[i].ToolTip);
m_items[i].MouseOver = true;
changed = true;
}
}
else
{
if (m_items[i].MouseOver)
{
m_items[i].MouseOver = false;
changed = true;
}
}
}
if (index == -1)
{
setToolTip("");
}
if (changed)
{
this.Invalidate();
}
}
protected override void OnMouseUp(
System.Windows.Forms.MouseEventArgs e
)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left)
{
bool changed = false;
for (int i = 0; i < m_items.Count; i++)
{
if (m_items[i].MouseDown)
{
if (HitTest() == i)
{
if (m_items[i].Enabled)
{
// Click
m_items[i].MouseDown = false;
m_items[i].Selected = true;
ensureVisible(i);
this.Invalidate();
ItemClickEventArgs itemEventArgs = new
ItemClickEventArgs(
m_items[i],
new Point(e.X, e.Y),
MouseButtons.Left);
OnItemClick(itemEventArgs);
}
else
{
m_items[i].MouseDown = false;
}
}
else
{
// no click
m_items[i].MouseDown = false;
changed = true;
}
}
}
if (changed)
{
this.Invalidate();
}
}
}
private void ensureVisible(
int lIndex )
{
int lOffset = this.AutoScrollPosition.Y;
int lTop = m_items[lIndex].Start + lOffset - 3;
int lNewValue = 0;
if (lTop < 0)
{
// need to scroll up
lNewValue = (-lOffset) + lTop;
if (lNewValue <= 2)
{
lNewValue = 0;
}
pScrollTo(lNewValue);
}
else
{
int lBottom = 0;
lBottom = m_items[lIndex].Start + lOffset - 3 +
m_items[lIndex].Extent;
if (lBottom > this.ClientSize.Height)
{
// need to scroll down
lNewValue = -this.AutoScrollPosition.Y + (lBottom -
this.ClientSize.Height) + 6;
if (lNewValue >= this.AutoScrollMinSize.Height - 4)
{
lNewValue = this.AutoScrollMinSize.Height;
}
pScrollTo(lNewValue);
}
}
}
private void pScrollTo(
int lNewPos )
{
int lNow = 0;
int lStepSize = 0;
bool bComplete = false;
int lNewValue = 0;
lNow = - this.AutoScrollPosition.Y;
if (lNewPos > lNow)
{
lStepSize = 1;
}
else
{
lStepSize = -1;
}
while (!bComplete)
{
lNewValue = lNow + lStepSize;
if (lStepSize < 0)
{
if (lNewValue < lNewPos)
{
lNewValue = lNewPos;
bComplete = true;
}
}
else
{
if (lNewValue > lNewPos)
{
lNewValue = lNewPos;
bComplete = true;
}
}
this.AutoScrollPosition = new Point(0, Math.Abs(lNewValue));
lStepSize = lStepSize * 2;
}
}
protected override bool ProcessMnemonic(
Char charCode )
{
string itemText = "";
int pos;
int index = -1;
string compareText = "&" + Char.ToUpper(charCode);
bool ret = false;
for (int i = 0 ; i < m_items.Count; i++)
{
itemText = m_items[i].Text.ToUpper();
pos = itemText.IndexOf(compareText);
if (pos > 0)
{
index = i;
ret = true;
break;
}
}
if (index > -1)
{
m_items[index].Selected = true;
ensureVisible(index);
ItemClickEventArgs itemClickArgs = new ItemClickEventArgs(
m_items[index], new Point(0,0), MouseButtons.None);
OnItemClick(itemClickArgs);
}
return ret;
}
protected virtual void OnItemClick(
ItemClickEventArgs e )
{
if (ItemClick != null)
{
ItemClick(this, e);
}
}
protected virtual void OnBarClick(
MouseEventArgs e )
{
if (BarClick != null)
{
BarClick(this, e);
}
}
protected virtual void OnSelectionChanged(
SelectionChangedEventArgs e)
{
if (SelectionChanged != null)
{
SelectionChanged(this, e);
}
}
protected override void OnResize(
System.EventArgs e )
{
base.OnResize(e);
OnItemChanged(null);
}
private int HitTest()
{
Point p = new Point(Cursor.Position.X, Cursor.Position.Y);
p = this.PointToClient(p);
return HitTestPoint(p.X, p.Y);
}
private int HitTestPoint(
int x ,
int y )
{
int ret = -1;
if ((x >= 3) && (x <= m_buttonWidth - 6))
{
if ((y >= 0) && (y <= this.ClientSize.Height))
{
ButtonListBarItem barItem = null;
for (int i = 0; i < m_items.Count; i++)
{
barItem = m_items[i];
if (y >= barItem.Start + this.AutoScrollPosition.Y)
{
if (y < barItem.Start + barItem.Extent +
this.AutoScrollPosition.Y)
{
ret = i;
break;
}
}
}
}
}
return ret;
}
}
#endregion
#region ButtonListBarItems
public class ButtonListBarItems :
CollectionBase
{
private ButtonListBar m_owner = null;
public void Add(ButtonListBarItem item)
{
item.Owner = m_owner;
this.InnerList.Add(item);
m_owner.OnItemChanged(item);
}
public void Add(ButtonListBarItem[] items)
{
foreach(ButtonListBarItem item in items)
{
if (item != null)
{
item.Owner = m_owner;
this.InnerList.Add(item);
}
}
m_owner.OnItemChanged(null);
}
public void Insert(
int index,
ButtonListBarItem item
)
{
item.Owner = m_owner;
this.InnerList.Insert(index, item);
m_owner.OnItemChanged(item);
}
public ButtonListBarItem this[int index]
{
get
{
return (ButtonListBarItem)this.InnerList[index];
}
}
public ButtonListBarItems(
ButtonListBar owner
)
{
m_owner = owner;
}
public ButtonListBarItems(
ButtonListBar owner,
ButtonListBarItem[] items
) : this(owner)
{
foreach (ButtonListBarItem barItem in items)
{
barItem.Owner = m_owner;
this.InnerList.Add(barItem);
}
m_owner.OnItemChanged(null);
}
public ButtonListBarItems(
ButtonListBar owner,
ButtonListBarItems items
) : this(owner)
{
foreach (ButtonListBarItem item in items)
{
ButtonListBarItem newItem = (ButtonListBarItem)item.Clone();
newItem.Owner = m_owner;
this.InnerList.Add(newItem);
}
m_owner.OnItemChanged(null);
}
protected override void OnRemoveComplete(
int index,
object value
)
{
base.OnRemoveComplete(index, value);
m_owner.OnItemChanged(null);
}
protected override void OnClearComplete()
{
base.OnClearComplete();
m_owner.OnItemChanged(null);
}
protected override void OnInsertComplete(
int index,
object value
)
{
base.OnInsertComplete(index, value);
ButtonListBarItem item = (ButtonListBarItem)value;
item.Owner = m_owner;
m_owner.OnItemChanged(item);
}
protected override void OnSetComplete(
int index,
object oldValue,
object newValue
)
{
base.OnSetComplete(index, oldValue, newValue);
ButtonListBarItem item = (ButtonListBarItem)newValue;
item.Owner = m_owner;
m_owner.OnItemChanged(null);
}
}
#endregion
#region ButtonListBarItem
public class ButtonListBarItem :
ICloneable
{
private string m_caption = "";
private string m_toolTip = "";
private object m_tag = null;
private int m_iconIndex = -1;
private bool m_enabled = true;
private int m_start = 0;
private int m_extent = 0;
private ButtonListBar m_owner = null;
private bool m_mouseDown = false;
private bool m_mouseOver = false;
private bool m_selected = false;
public string Text
{
get
{
return m_caption;
}
set
{
m_caption = value;
if (m_owner != null)
{
m_owner.OnItemChanged(this);
}
}
}
public string ToolTip
{
get
{
return m_toolTip;
}
set
{
m_toolTip = value;
}
}
public object Tag
{
get
{
return m_tag;
}
set
{
m_tag = value;
}
}
public int IconIndex
{
get
{
return m_iconIndex;
}
set
{
m_iconIndex = value;
if (m_owner != null)
{
m_owner.OnItemChanged(this);
}
}
}
public bool Enabled
{
get
{
return m_enabled;
}
set
{
m_enabled = value;
if (m_owner != null)
{
m_owner.OnItemChanged(this);
}
}
}
internal ButtonListBar Owner
{
get
{
return m_owner;
}
set
{
m_owner = value;
}
}
internal int Start
{
get
{
return m_start;
}
set
{
m_start = value;
}
}
internal int Extent
{
get
{
return m_extent;
}
set
{
m_extent = value;
}
}
public bool Selected
{
get
{
return m_selected;
}
set
{
if (value != m_selected)
{
if (m_owner != null)
{
m_selected = m_owner.OnSelectItem(this, value);
m_owner.OnItemChanged(this);
}
}
}
}
internal bool MouseDown
{
get
{
return m_mouseDown;
}
set
{
m_mouseDown = value;
}
}
internal bool MouseOver
{
get
{
return m_mouseOver;
}
set
{
m_mouseOver = value;
}
}
public object Clone()
{
ButtonListBarItem myClone = new ButtonListBarItem(
m_caption,
m_iconIndex,
m_toolTip,
m_enabled
);
myClone.Tag = m_tag;
return myClone;
}
public ButtonListBarItem() : base()
{
}
public ButtonListBarItem(
string text
) : base()
{
m_caption = text;
}
public ButtonListBarItem(
string text,
int iconIndex
) : this(text)
{
m_iconIndex = iconIndex;
}
public ButtonListBarItem(
string text,
int iconIndex,
string toolTip
) : this(text, iconIndex)
{
m_toolTip = toolTip;
}
public ButtonListBarItem(
string text,
int iconIndex,
string toolTip,
bool enabled
) : this(text, iconIndex, toolTip)
{
m_enabled = enabled;
}
}
#endregion
}
|
|