in frontend/windows/WBControls/CollapsingPanel.cs [276:635]
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
bool showHeader = (DisplayMode != CollapsingPanelDisplayMode.TabsOnly) &&
(DisplayMode != CollapsingPanelDisplayMode.NoHeader);
bool showTabs = (DisplayMode == CollapsingPanelDisplayMode.HeaderAndTab) ||
(DisplayMode == CollapsingPanelDisplayMode.HeaderWithTabs) ||
(DisplayMode == CollapsingPanelDisplayMode.TabsOnly);
// Draw the header background
if (showHeader)
{
if (style != CollapsingPanelStyle.Flat ||
DisplayMode == CollapsingPanelDisplayMode.HeaderWithTabs)
{
Bitmap headerBg = style == CollapsingPanelStyle.Convex ?
Resources.collapsing_panel_header_bg : Resources.collapsing_panel_header_bg_flat;
g.DrawImageUnscaledAndClipped(headerBg,
new Rectangle(0, 0, Width + 30, headerBg.Height));
}
else
{
using (SolidBrush background = new SolidBrush(Color.FromArgb(245, 245, 245)))
g.FillRectangle(background, new Rectangle(0, 0, Width, headerHeight));
// Draw tab action buttons
if (displayTabActionButtons)
{
g.DrawImageUnscaledAndClipped(Resources.collapsing_panel_header_tab_add,
new Rectangle(Width - Resources.collapsing_panel_header_tab_add.Width -
Resources.collapsing_panel_header_tab_del.Width,
0,
Resources.collapsing_panel_header_tab_add.Width,
Resources.collapsing_panel_header_tab_add.Height));
g.DrawImageUnscaledAndClipped(Resources.collapsing_panel_header_tab_del,
new Rectangle(Width - Resources.collapsing_panel_header_tab_del.Width,
0,
Resources.collapsing_panel_header_tab_del.Width,
Resources.collapsing_panel_header_tab_del.Height));
}
// Draw tab action buttons
if (displayCustomButtons)
{
foreach (CustomButton button in customButtons)
button.Paint(g, activeCustomButton == button);
}
}
}
// If the header is expanded
if (Expanded)
{
// Draw the Minus icon
if (!disableExpansionIcon && !disableExpansion && showHeader)
{
Bitmap icon = (style == CollapsingPanelStyle.Convex) ?
Resources.collapsing_panel_minus : Resources.collapsing_panel_minus_flat;
g.DrawImageUnscaled(icon, 10, (headerHeight - icon.Height) / 2);
}
// Draw shadow
if (showHeader)
{
// If the tabs are not displayed, draw the background of the shadow
if (DisplayMode != CollapsingPanelDisplayMode.HeaderAndTab &&
DisplayMode != CollapsingPanelDisplayMode.TabsOnly &&
style != CollapsingPanelStyle.Flat)
{
g.FillRectangle(SystemBrushes.ButtonFace, 0, headerHeight, Width, Padding.Top + headerSpace);
}
else if (DisplayMode == CollapsingPanelDisplayMode.HeaderAndTab)
{
// If there are tabs below the header, draw their background
if (style == CollapsingPanelStyle.Convex)
g.FillRectangle(SystemBrushes.ButtonFace, 0, headerHeight, Width, Padding.Top + tabsHeight);
else
using (SolidBrush background = new SolidBrush(Color.FromArgb(242, 242, 242)))
g.FillRectangle(background, 0, headerHeight, Width, Padding.Top + tabsHeight);
g.DrawLine(SystemPens.ControlDark, 0, headerHeight + Padding.Top + tabsHeight - 1,
Width, headerHeight + Padding.Top + tabsHeight - 1);
}
// Draw shadow image
if (style != CollapsingPanelStyle.Flat)
{
Rectangle shadowRect = new Rectangle(0, headerHeight,
Width + 30, Resources.collapsing_panel_header_shadow.Height);
g.DrawImageUnscaledAndClipped(Resources.collapsing_panel_header_shadow,
shadowRect);
}
}
}
else
// Draw the Plus icon
if (!disableExpansionIcon && !disableExpansion && showHeader)
g.DrawImageUnscaled(style == CollapsingPanelStyle.Convex ?
Resources.collapsing_panel_plus : Resources.collapsing_panel_plus_flat, 10, 6);
// If tabs should be displayed
if (Expanded && showTabs)
{
// Draw the tab header background for TabsOnly
if (DisplayMode == CollapsingPanelDisplayMode.TabsOnly)
{
if (style == CollapsingPanelStyle.Convex)
g.FillRectangle(SystemBrushes.ButtonFace, 0, 0, Width, headerHeightTabsOnly);
else
using (SolidBrush background = new SolidBrush(Color.FromArgb(242, 242, 242)))
g.FillRectangle(background, 0, 0, Width, headerHeightTabsOnly);
g.DrawLine(SystemPens.ControlDark, 0, headerHeightTabsOnly - 1,
Width, headerHeightTabsOnly - 1);
g.DrawImageUnscaledAndClipped(Resources.collapsing_panel_bg,
new Rectangle(0, 0, Width + 30, Resources.collapsing_panel_bg.Height));
}
// Get the current number of tabs.
int tabCount;
if (TabCountNeeded != null)
tabCount = TabCountNeeded(this);
else
tabCount = 2;
cachedTabWidths.Clear();
// The X position of the current item
int itemPos = tabPaintOffset + ((DisplayMode == CollapsingPanelDisplayMode.HeaderWithTabs) ?
(disableExpansion ? 0 : 32) : 8);
// The Y helper position
int y = (DisplayMode == CollapsingPanelDisplayMode.TabsOnly) ?
7 : headerHeight + Padding.Top;
// Loop over the tab headers and draw them
for (int i = 0; i < tabCount; i++)
{
int x = itemPos;
int itemWidth = 0;
string caption = "", description = "";
int iconId = -1;
bool drawIcon = false;
float captionWidth = 0, descriptionWidth = 0;
try
{
if (TabInfoNeeded != null)
{
if (!TabInfoNeeded(this, i, out iconId, out caption, out description))
continue;
}
else
{
caption = "Caption";
description = "Description";
}
if (DisplayMode == CollapsingPanelDisplayMode.HeaderWithTabs)
{
// Get caption width
captionWidth = g.MeasureString(caption, HeaderFont).Width;
// Check if the is the selected tab
if (i == selectedTabIndex)
{
Bitmap tabLeft = style == CollapsingPanelStyle.Convex ?
Resources.collapsing_panel_header_tab_left :
Resources.collapsing_panel_header_tab_left_flat;
Bitmap tabMiddle = style == CollapsingPanelStyle.Convex ?
Resources.collapsing_panel_header_tab_middle :
Resources.collapsing_panel_header_tab_middle_flat;
Bitmap tabRight = style == CollapsingPanelStyle.Convex ?
Resources.collapsing_panel_header_tab_right :
Resources.collapsing_panel_header_tab_right_flat;
if (DisableExpansion && i > 0)
{
g.DrawImageUnscaled(tabLeft, x, 0);
x += tabLeft.Width;
itemWidth += tabLeft.Width;
}
g.DrawImageUnscaledAndClipped(tabMiddle, new Rectangle(x, 0,
Convert.ToInt16(captionWidth) + 16, tabMiddle.Height));
x += 8;
itemWidth += 8;
// Draw the header caption
if (style == CollapsingPanelStyle.Convex)
g.DrawString(caption, HeaderFont, Brushes.Black,
x, Expanded ? 3 : 1);
else
{
g.DrawString(caption, HeaderFont, fontDarkBrush,
x, 2);
g.DrawString(caption, HeaderFont, Brushes.White,
x, 1);
}
x += Convert.ToInt16(captionWidth) + 8;
itemWidth += Convert.ToInt16(captionWidth) + 8;
g.DrawImageUnscaled(tabRight, x, 0);
itemWidth += tabRight.Width;
}
// if the tab is not selected
else
{
Bitmap sep = style == CollapsingPanelStyle.Convex ?
Resources.collapsing_panel_header_tab_separator :
Resources.collapsing_panel_header_tab_separator_flat;
// Draw first separator
if (!DisableExpansion && i == 0)
{
g.DrawImageUnscaled(sep, x, 0);
itemWidth = sep.Width;
x += itemWidth;
}
// space to last separator
itemWidth += 8;
x += 8;
// Draw the header caption
g.DrawString(caption, HeaderFont, style == CollapsingPanelStyle.Convex ?
Brushes.White : fontDarkBrush, x, 1);
// Add caption width
x += Convert.ToInt16(captionWidth) + 8;
itemWidth += Convert.ToInt16(captionWidth) + 8;
// Draw ending separator only if the next tab is not selected
if (i != selectedTabIndex - 1)
{
g.DrawImageUnscaled(sep, x, 0);
itemWidth += sep.Width;
}
}
}
else
{
// Check if an icon is assigned to this tab
if (tabHeaderImageList != null &&
iconId >= 0 && iconId < tabHeaderImageList.Images.Count)
{
drawIcon = true;
// Add icon width and spacing
itemWidth = tabHeaderImageList.ImageSize.Width + 16;
}
// Get caption and description width
if (!caption.Equals(""))
captionWidth = g.MeasureString(caption, tabHeaderCaptionFont).Width;
if (!description.Equals(""))
descriptionWidth = g.MeasureString(description, tabHeaderDescriptionFont).Width;
// Add the longer text with to the itemWidth
itemWidth += (int)Math.Ceiling(Math.Max(captionWidth, descriptionWidth));
// If there was a text at all, add spacing
if (captionWidth + descriptionWidth > 0)
if (drawIcon)
itemWidth += 6;
else
itemWidth += 16;
// if there is nothing to draw, continue
if (itemWidth == 0)
continue;
// Check if the is the selected tab
if (i == selectedTabIndex)
{
// Get rectangle for the middle image
Rectangle middleRect = new Rectangle(
itemPos + Resources.collapsing_panel_tab_left.Width,
y, itemWidth -
Resources.collapsing_panel_tab_left.Width -
Resources.collapsing_panel_tab_right.Width + 1,
Resources.collapsing_panel_tab_middle.Height);
// Draw the left border, middle image and right border
g.DrawImageUnscaled(Resources.collapsing_panel_tab_left, itemPos,
y);
g.DrawImageUnscaledAndClipped(Resources.collapsing_panel_tab_middle,
middleRect);
g.DrawImage(Resources.collapsing_panel_tab_right,
itemPos + itemWidth - Resources.collapsing_panel_tab_right.Width,
y);
}
// indent for the icon or text
x += 8;
// Draw the icon
if (drawIcon)
{
g.DrawImageUnscaled(tabHeaderImageList.Images[iconId],
x, (!showHeader ? 0 : headerHeight + Padding.Top) +
(((!showHeader) ? headerHeightTabsOnly : tabsHeight) -
tabHeaderImageList.Images[iconId].Height) / 2);
x += tabHeaderImageList.ImageSize.Width + 6;
}
// Draw the caption
if (!caption.Equals(""))
g.DrawString(caption, tabHeaderCaptionFont, Brushes.Black,
x, y + 15);
// Draw the description
if (!description.Equals(""))
g.DrawString(description, tabHeaderDescriptionFont, Brushes.Gray,
x, y + 15 + 16 + descriptionSpace);
}
itemPos += itemWidth;
// Don't try to optimize painting here by dropping out early if the available space
// is filled up. The paint code also computes the cachedTabWidths array.
}
finally
{
cachedTabWidths.Add(itemWidth);
}
}
// Draw popup button as overlay. Compute its position here too (for hit testing).
popupButtonBounds.Width = Resources.DockPaneCaption_Options1.Width;
popupButtonBounds.Height = Resources.DockPaneCaption_Options1.Height;
popupButtonBounds.X = Width - Resources.DockPaneCaption_Options1.Width - 4;
popupButtonBounds.Y = headerHeight + (showHeader ? tabsHeight : 0) - popupButtonBounds.Height;
g.DrawImageUnscaled(Resources.DockPaneCaption_Options1, popupButtonBounds.X, popupButtonBounds.Y);
// Draw the background of the shadow below the tab header
using (SolidBrush b = new SolidBrush(BackColor))
g.FillRectangle(b, 0, headerHeight + Padding.Top + tabsHeight, Width, headerSpace);
}
if (showHeader)
{
float h = g.MeasureString(HeaderCaption, HeaderFont).Height;
// Draw the header caption
g.DrawString(HeaderCaption, HeaderFont,
style == CollapsingPanelStyle.Convex ? Brushes.White : fontDarkBrush,
(disableExpansion ? 6 : 30), Convert.ToInt16((headerHeight - h) / 2));
}
}