📄 outlookbar.cs
字号:
top = new Point(viewPortRect.Right-5, y - 6);
if ( hit == HitTestType.DropLineLastItem )
bottom = new Point(viewPortRect.Right-5, y+1);
else
bottom = new Point(viewPortRect.Right-5, y + 6);
middle = new Point(viewPortRect.Right-11, y);
points.SetValue(top, 0);
points.SetValue(middle, 1);
points.SetValue(bottom, 2);
g.FillPolygon(brush, points);
if ( !drawLine )
{
brush.Dispose();
pen.Dispose();
}
}
void HighlightHeader(int index)
{
if ( lastHighlightedHeader == index ) return;
Graphics g = Graphics.FromHwnd(Handle);
Rectangle rc;
if ( lastHighlightedHeader >= 0 )
{
rc = GetHeaderRect(lastHighlightedHeader);
DrawHeader(g, lastHighlightedHeader, rc, Border3DStyle.RaisedInner);
}
lastHighlightedHeader = index;
if ( lastHighlightedHeader >= 0 )
{
rc = GetHeaderRect(lastHighlightedHeader);
DrawHeader(g, lastHighlightedHeader, rc, Border3DStyle.Raised);
}
}
void OnHighlightHeader(Object timeObject, EventArgs eventArgs)
{
Point mousePos = Control.MousePosition;
mousePos = PointToClient(mousePos);
Rectangle rc = ClientRectangle;
if ( !rc.Contains(mousePos) )
{
HighlightHeader(-1);
HighlightItem(-1, false);
highlightTimer.Stop();
}
}
void HighlightItem(int index, bool pressed)
{
// Exit if item state has not changed
if ( lastHighlightedItem == index && previousPressed == pressed ) return;
// Remember if we were pressed or not
previousPressed = pressed;
if ( lastHighlightedItem >= 0 )
{
// Draw the previously highlighted item in normal state
using ( Graphics g = Graphics.FromHwnd(Handle) )
{
Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], lastHighlightedItem, Rectangle.Empty);
DrawItem(g, lastHighlightedItem, itemRect, false, false, Rectangle.Empty, null);
}
}
lastHighlightedItem = index;
if ( lastHighlightedItem >= 0 )
{
// Draw this item hightlighed
using ( Graphics g = Graphics.FromHwnd(Handle) )
{
Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], lastHighlightedItem, Rectangle.Empty);
DrawItem(g, lastHighlightedItem, itemRect, true, pressed, Rectangle.Empty, null);
}
}
}
void ForceHighlightItem(Graphics g, int index)
{
// Draw this item hightlighed
Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], index, Rectangle.Empty);
DrawItem(g, index, itemRect, true, false, Rectangle.Empty, null);
}
public void PerformClick(int index)
{
FireItemClicked(index);
}
void FirePropertyChanged(OutlookBarProperty property)
{
if ( PropertyChanged != null )
PropertyChanged(bands[currentBandIndex], property);
}
void FireItemClicked(int index)
{
if ( ItemClicked != null )
{
if ( currentBandIndex == -1)
SetCurrentBand(0);
if ( index >= 0 && index < bands[currentBandIndex].Items.Count )
ItemClicked(bands[currentBandIndex], bands[currentBandIndex].Items[index]);
}
}
void FireItemDropped(int index)
{
if ( ItemDropped != null )
{
if ( currentBandIndex == -1)
SetCurrentBand(0);
if ( index >= 0 && index < bands[currentBandIndex].Items.Count )
ItemDropped(bands[currentBandIndex], bands[currentBandIndex].Items[index]);
}
}
Rectangle GetWorkRect()
{
Rectangle rc = ClientRectangle;
if ( borderType != BorderType.None )
rc.Inflate(-2,-2);
return rc;
}
Rectangle GetViewPortRect()
{
// This is the area of the control minus
// the bands headers
Rectangle rect = GetWorkRect();
if ( bands.Count > 0 )
{
// Decrease the client area by the number of headers
int top = rect.Top + 1 + BAND_HEADER_HEIGHT * (currentBandIndex + 1);
int bottom = rect.Bottom - 1 - BAND_HEADER_HEIGHT * (bands.Count - currentBandIndex - 1);
return new Rectangle(rect.Left, top, rect.Width, bottom - top);
}
return rect;
}
Rectangle GetHeaderRect(int index)
{
// Make sure we are within bounds
Debug.Assert((index >= 0 && index <= bands.Count-1), "Invalid Header Index");
Rectangle rect = GetWorkRect();
int top = rect.Top;
int bottom = rect.Bottom;
int max = bands.Count;
if ( index > currentBandIndex )
{
top = rect.Bottom - 1 - (max - index) * BAND_HEADER_HEIGHT;
bottom = rect.Bottom - 1 - (max - index - 1) * BAND_HEADER_HEIGHT;
}
else
{
top = rect.Top + 1 + index * BAND_HEADER_HEIGHT;
bottom = rect.Top + 1 + (index+1) * BAND_HEADER_HEIGHT;
}
return new Rectangle(rect.Left, top, rect.Width, bottom-top);
}
void DrawBackground(Graphics g)
{
Rectangle rc = ClientRectangle;
// If we don't have any bands, just fill the rectangle
// with the System Control Color
if ( bands.Count == 0 || currentBandIndex == -1 )
{
g.FillRectangle(SystemBrushes.Control, rc);
return;
}
if ( backgroundBitmap == null )
{
if ( currentBandIndex >= 0 && bands[currentBandIndex] != null )
{
using ( SolidBrush b = new SolidBrush(bands[currentBandIndex].Background) )
{
// If there is a child control clip the area where the child
// control will be drawn to avoid flickering
if ( HasChild() )
{
Rectangle clipRect = GetViewPortRect();
g.ExcludeClip(clipRect);
}
g.FillRectangle(b, rc);
}
}
}
else
{
// Draw custom background bitmap
// -- I don't know why but the bitmap is not painted properly if using the right size
// I use the WindowsAPI to work around the problem
GDIUtil.StrechBitmap(g, rc, backgroundBitmap);
if ( needBackgroundBitmapResize )
{
needBackgroundBitmapResize = false;
backgroundBitmap = GDIUtil.GetStrechedBitmap(g, rc, backgroundBitmap);
}
}
}
void DrawBorder(Graphics g)
{
Rectangle rc = ClientRectangle;
if ( borderType == BorderType.FixedSingle )
{
g.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
}
else if ( borderType == BorderType.Fixed3D )
{
ControlPaint.DrawBorder3D(g, rc, Border3DStyle.Sunken);
}
else if ( borderType == BorderType.Custom )
{
Pen p1 = new Pen(leftTopColor);
Pen p2 = new Pen(RightBottomColor);
g.DrawRectangle(p1, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
g.DrawRectangle(p2, rc.Left+1, rc.Top+1, rc.Width-3, rc.Height-3);
p1.Dispose();
p2.Dispose();
}
}
void DrawHeaders(Graphics g)
{
Rectangle rc;
for (int i = 0; i < bands.Count; i++)
{
rc = GetHeaderRect(i);
DrawHeader(g, i, rc, Border3DStyle.RaisedInner);
}
}
void DrawHeader(Graphics g, int index, Rectangle rc, Border3DStyle style)
{
string bandName = bands[index].Text;
using ( Brush b = new SolidBrush(ColorUtil.VSNetControlColor) )
{
g.FillRectangle(b, rc);
}
if ( ColorUtil.UsingCustomColor )
{
Pen p;
if ( style == Border3DStyle.RaisedInner )
{
p = new Pen(ColorUtil.VSNetBorderColor);
g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
}
else
{
using ( Brush fillColor = new SolidBrush(ColorUtil.VSNetSelectionColor))
{
g.FillRectangle(fillColor, rc);
}
p = new Pen(ColorUtil.VSNetBorderColor);
g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
}
p.Dispose();
}
else
{
ControlPaint.DrawBorder3D(g, rc, style);
}
StringFormat stringFormat = new StringFormat();
stringFormat.LineAlignment = StringAlignment.Center;
stringFormat.Alignment = StringAlignment.Center;
g.DrawString(bandName, Font, SystemBrushes.WindowText, rc, stringFormat);
}
void DrawArrowButtons(Graphics g)
{
// If we don't have any bands just return
if ( bands.Count == 0 ) return;
int first, last;
GetVisibleRange(g, out first, out last);
Rectangle rc = GetViewPortRect();
upArrowRect = new Rectangle(0, 0, SystemInformation.VerticalScrollBarWidth,
SystemInformation.VerticalScrollBarWidth);
downArrowRect = upArrowRect;
upArrowRect.Offset(rc.Right - ARROW_BUTTON_MARGIN - SystemInformation.VerticalScrollBarWidth,
rc.Top + ARROW_BUTTON_MARGIN);
downArrowRect.Offset(rc.Right - ARROW_BUTTON_MARGIN - SystemInformation.VerticalScrollBarWidth,
rc.Bottom - ARROW_BUTTON_MARGIN - SystemInformation.VerticalScrollBarWidth);
// Do we need to show top scroll button
if ( first > 0 )
{
if ( flatArrowButtons )
DrawFlatArrowButton(g, upArrowRect, true, UpFlatArrowState);
else
{
if ( upArrowPressed )
ControlPaint.DrawScrollButton(g, upArrowRect, ScrollButton.Up, ButtonState.Pushed);
else
ControlPaint.DrawScrollButton(g, upArrowRect, ScrollButton.Up, ButtonState.Normal);
}
upArrowVisible = true;
}
else
{
upArrowVisible = false;
UpFlatArrowState = DrawState.Normal;
}
// Do we need to show bottom scroll button
if ( last < bands[currentBandIndex].Items.Count -1 )
{
if ( flatArrowButtons )
DrawFlatArrowButton(g, downArrowRect, false, DownFlatArrowState);
else
{
if ( downArrowPressed )
ControlPaint.DrawScrollButton(g, downArrowRect, ScrollButton.Down, ButtonState.Pushed);
else
ControlPaint.DrawScrollButton(g, downArrowRect, ScrollButton.Down, ButtonState.Normal);
}
downArrowVisible = true;
}
else
{
downArrowVisible = false;
DownFlatArrowState = DrawState.Normal;
}
}
void DrawFlatArrowButton(Graphics g, Rectangle rc, bool up, DrawState state)
{
if ( HasChild() )
{
// Dont' draw flat button if there is a band with a child control
return;
}
Brush b;
if ( state == DrawState.Hot )
{
b = new SolidBrush(ColorUtil.VSNetCheckedColor);
}
else
{
b = new SolidBrush(ColorUtil.VSNetControlColor);
}
g.FillRectangle(b, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
b.Dispose();
using ( Pen p = new Pen(ColorUtil.VSNetBorderColor) )
{
if ( state == DrawState.Hot )
g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-2, rc.Height-2);
GDIUtil.DrawArrowGlyph(g, rc, 7, 4, up, Brushes.Black);
}
// Remember last state of the flat arrow button
if ( up )
{
UpFlatArrowState = state;
}
else
{
DownFlatArrowState = state;
}
}
void DrawArrowButton(Rectangle buttonRect, ButtonState state)
{
if ( HasChild() )
{
// No drawing buttons if there is a child control in the current band
return;
}
// Directly draw the arrow button
Graphics g = Graphics.FromHwnd(Handle);
bool up = true;
ScrollButton buttonType = ScrollButton.Up;
if ( buttonRect.Equals(downArrowRect ))
{
buttonType = ScrollButton.Down;
up = false;
}
if ( flatArrowButtons && !HasChild() )
{
int first;
int last;
GetVisibleRange(g, out first, out last);
if ( up && first == 0 )
{
// up arrow is not visible no need to pain it
return;
}
else if ( up == false && last == bands[currentBandIndex].Items.Count -1)
{
// down arrow is not visible no need to pain it
return;
}
// If using flat button and the mouse is still over the button
// then don't allow drawing it without the hightlight
Point pos = Control.MousePosition;
pos = PointToClient(pos);
if ( buttonRect.Contains(pos) )
{
if ( up )
UpFlatArrowState = DrawState.Hot;
else
DownFlatArrowState = DrawState.Hot;
DrawFlatArrowButton(g, buttonRect, up, DrawState.Hot);
}
else
{
if ( up )
UpFlatArrowState = DrawState.Normal;
else
DownFlatArrowState = DrawState.Normal;
DrawFlatArrowButton(g, buttonRect, up, DrawState.Normal);
}
}
else
ControlPaint.DrawScrollButton(g, buttonRect, buttonType, state);
g.Dispose();
}
void DrawItems(Graphics g, Rectangle targetRect, OutlookBarBand drawBand)
{
// If we don't have any bands just return
if ( bands.Count == 0 ) return;
Rectangle rc = GetViewPortRect();
OutlookBarBand band = bands[currentBandIndex];
if ( drawBand != null ) band = drawBand;
Debug.Assert(band != null);
for ( int i = firstItem; i < band.Items.Count; i++ )
{
Rectangle itemRect = GetItemRect(g, band, i, targetRect);
if ( itemRect.Top > rc.Bottom )
break;
else
DrawItem(g, i, itemRect, false, false, targetRect, drawBand);
}
}
void DrawItem(Graphics g, int index, Rectangle itemRect, bool hot, bool pressed, Rectangle targetRect, OutlookBarBand drawingBand)
{
OutlookBarBand band = bands[currentBandIndex];
if ( drawingBand != null ) band = drawingBand;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -