protected override void OnPaint()

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