#region Imports using DPumpHydr.WinFrmUI.RLT.Manager; using DPumpHydr.WinFrmUI.RLT.Util; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Drawing.Text; using System.Linq; using System.Windows.Forms; using static DPumpHydr.WinFrmUI.RLT.Helper.MaterialDrawHelper; using static DPumpHydr.WinFrmUI.RLT.Util.MaterialAnimations; #endregion namespace DPumpHydr.WinFrmUI.RLT.Controls { #region MaterialDrawer public class MaterialDrawer : Control, MaterialControlI { private bool _showIconsWhenHidden; [Category("Drawer")] public bool ShowIconsWhenHidden { get => _showIconsWhenHidden; set { if (_showIconsWhenHidden != value) { _showIconsWhenHidden = value; UpdateTabRects(); preProcessIcons(); showHideAnimation(); Paint(new PaintEventArgs(CreateGraphics(), ClientRectangle)); DrawerShowIconsWhenHiddenChanged?.Invoke(this); } } } private bool _isOpen; [Category("Drawer")] public bool IsOpen { get => _isOpen; set { _isOpen = value; if (value) { Show(); } else { Hide(); } } } [Category("Drawer")] public bool AutoHide { get; set; } [Category("Drawer")] public bool AutoShow { get; set; } [Category("Drawer")] private bool _useColors; public bool UseColors { get => _useColors; set { _useColors = value; preProcessIcons(); Invalidate(); } } [Category("Drawer")] private bool _highlightWithAccent; public bool HighlightWithAccent { get => _highlightWithAccent; set { _highlightWithAccent = value; preProcessIcons(); Invalidate(); } } [Category("Drawer")] private bool _backgroundWithAccent; public bool BackgroundWithAccent { get => _backgroundWithAccent; set { _backgroundWithAccent = value; Invalidate(); } } [Category("Drawer")] public int IndicatorWidth { get; set; } [Browsable(false)] public int Depth { get; set; } [Browsable(false)] public MaterialSkinManager SkinManager => MaterialSkinManager.Instance; [Browsable(false)] public MaterialMouseState MouseState { get; set; } public delegate void DrawerStateHandler(object sender); public event DrawerStateHandler DrawerStateChanged; public event DrawerStateHandler DrawerBeginOpen; public event DrawerStateHandler DrawerEndOpen; public event DrawerStateHandler DrawerBeginClose; public event DrawerStateHandler DrawerEndClose; public event DrawerStateHandler DrawerShowIconsWhenHiddenChanged; public event EventHandler CursorUpdate; // icons private Dictionary iconsBrushes; private Dictionary iconsSelectedBrushes; private Dictionary iconsSize; private int prevLocation; private int rippleSize = 0; private MaterialTabControl _baseTabControl; [Category("Behavior")] public MaterialTabControl BaseTabControl { get => _baseTabControl; set { if (value == null) { return; } else { if (_showTabControl == null || _showTabControl != value) { ShowTabControl = value; } if (_baseTabControl == null || _baseTabControl != value) { _baseTabControl = value; } } } } private MaterialTabControl _showTabControl; [Category("Behavior")] public MaterialTabControl ShowTabControl { get => _showTabControl; set { _showTabControl = value; if (_showTabControl == null) { return; } UpdateTabRects(); preProcessIcons(); // Other helpers _previousSelectedTabIndex = _showTabControl.SelectedIndex; _showTabControl.Deselected += (sender, args) => { _previousSelectedTabIndex = _showTabControl.SelectedIndex; }; _showTabControl.SelectedIndexChanged += (sender, args) => { _clickAnimManager.SetProgress(0); _clickAnimManager.StartNewAnimation(AnimationDirection.In); }; _showTabControl.ControlAdded += delegate { Invalidate(); }; _showTabControl.ControlRemoved += delegate { Invalidate(); }; } } private string[] _DrawerHideTabName = new List().ToArray(); [Category("Behavior")] public string[] DrawerHideTabName { get => _DrawerHideTabName; set { _DrawerHideTabName = value; if (_baseTabControl != null) { foreach (System.Windows.Forms.TabPage TB in _baseTabControl.TabPages) { if (!_showTabControl.TabPages.Contains(TB)) { _showTabControl.TabPages.Add(TB); } } if (_DrawerHideTabName.Any()) { foreach (System.Windows.Forms.TabPage TB in _baseTabControl.TabPages) { if (_DrawerHideTabName.Contains(TB.Name)) { if (_showTabControl.TabPages.Contains(TB)) { _showTabControl.TabPages.Remove(TB); } } } } else { _DrawerHideTabName = new List().ToArray(); } UpdateTabRects(); preProcessIcons(); Refresh(); Invalidate(); } } } [Category("Behavior")] public System.Windows.Forms.TabPage[] DrawerNonClickTabPage { get; set; } = new List().ToArray(); private void preProcessIcons() { // pre-process and pre-allocate texture brushes (icons) if (_showTabControl == null || _showTabControl.TabCount == 0 || _showTabControl.ImageList == null || _drawerItemRects == null || _drawerItemRects.Count == 0) { return; } // Calculate lightness and color float l = UseColors ? SkinManager.ColorScheme.TextColor.R / 255 : SkinManager.Theme == MaterialSkinManager.Themes.LIGHT ? 0f : 1f; float r = (_highlightWithAccent ? SkinManager.ColorScheme.AccentColor.R : SkinManager.ColorScheme.PrimaryColor.R) / 255f; float g = (_highlightWithAccent ? SkinManager.ColorScheme.AccentColor.G : SkinManager.ColorScheme.PrimaryColor.G) / 255f; float b = (_highlightWithAccent ? SkinManager.ColorScheme.AccentColor.B : SkinManager.ColorScheme.PrimaryColor.B) / 255f; // Create matrices float[][] matrixGray = { new float[] { 0, 0, 0, 0, 0}, // Red scale factor new float[] { 0, 0, 0, 0, 0}, // Green scale factor new float[] { 0, 0, 0, 0, 0}, // Blue scale factor new float[] { 0, 0, 0, .7f, 0}, // alpha scale factor new float[] { l, l, l, 0, 1}};// offset float[][] matrixColor = { new float[] { 0, 0, 0, 0, 0}, // Red scale factor new float[] { 0, 0, 0, 0, 0}, // Green scale factor new float[] { 0, 0, 0, 0, 0}, // Blue scale factor new float[] { 0, 0, 0, 1, 0}, // alpha scale factor new float[] { r, g, b, 0, 1}};// offset ColorMatrix colorMatrixGray = new(matrixGray); ColorMatrix colorMatrixColor = new(matrixColor); ImageAttributes grayImageAttributes = new(); ImageAttributes colorImageAttributes = new(); // Set color matrices grayImageAttributes.SetColorMatrix(colorMatrixGray, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); colorImageAttributes.SetColorMatrix(colorMatrixColor, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); // Create brushes iconsBrushes = new Dictionary(_showTabControl.TabPages.Count); iconsSelectedBrushes = new Dictionary(_showTabControl.TabPages.Count); iconsSize = new Dictionary(_showTabControl.TabPages.Count); foreach (System.Windows.Forms.TabPage tabPage in _showTabControl.TabPages) { // skip items without image if (string.IsNullOrEmpty(tabPage.ImageKey) || _drawerItemRects == null) { continue; } // Image Rect Rectangle destRect = new(0, 0, _showTabControl.ImageList.Images[tabPage.ImageKey].Width, _showTabControl.ImageList.Images[tabPage.ImageKey].Height); // Create a pre-processed copy of the image (GRAY) Bitmap bgray = new(destRect.Width, destRect.Height); using (Graphics gGray = Graphics.FromImage(bgray)) { gGray.DrawImage(_showTabControl.ImageList.Images[tabPage.ImageKey], new Point[] { new(0, 0), new(destRect.Width, 0), new(0, destRect.Height), }, destRect, GraphicsUnit.Pixel, grayImageAttributes); } // Create a pre-processed copy of the image (PRIMARY COLOR) Bitmap bcolor = new(destRect.Width, destRect.Height); using (Graphics gColor = Graphics.FromImage(bcolor)) { gColor.DrawImage(_showTabControl.ImageList.Images[tabPage.ImageKey], new Point[] { new(0, 0), new(destRect.Width, 0), new(0, destRect.Height), }, destRect, GraphicsUnit.Pixel, colorImageAttributes); } // added processed image to brush for drawing TextureBrush textureBrushGray = new(bgray); TextureBrush textureBrushColor = new(bcolor); textureBrushGray.WrapMode = System.Drawing.Drawing2D.WrapMode.Clamp; textureBrushColor.WrapMode = System.Drawing.Drawing2D.WrapMode.Clamp; // Translate the brushes to the correct positions int currentTabIndex = _showTabControl.TabPages.IndexOf(tabPage); Rectangle iconRect = new( _drawerItemRects[currentTabIndex].X + (drawerItemHeight / 2) - (_showTabControl.ImageList.Images[tabPage.ImageKey].Width / 2), _drawerItemRects[currentTabIndex].Y + (drawerItemHeight / 2) - (_showTabControl.ImageList.Images[tabPage.ImageKey].Height / 2), _showTabControl.ImageList.Images[tabPage.ImageKey].Width, _showTabControl.ImageList.Images[tabPage.ImageKey].Height); textureBrushGray.TranslateTransform(iconRect.X + (iconRect.Width / 2) - (_showTabControl.ImageList.Images[tabPage.ImageKey].Width / 2), iconRect.Y + (iconRect.Height / 2) - (_showTabControl.ImageList.Images[tabPage.ImageKey].Height / 2)); textureBrushColor.TranslateTransform(iconRect.X + (iconRect.Width / 2) - (_showTabControl.ImageList.Images[tabPage.ImageKey].Width / 2), iconRect.Y + (iconRect.Height / 2) - (_showTabControl.ImageList.Images[tabPage.ImageKey].Height / 2)); // add to dictionary string ik = string.Concat(tabPage.ImageKey, "_", tabPage.Name); iconsBrushes.Add(ik, textureBrushGray); iconsSelectedBrushes.Add(ik, textureBrushColor); iconsSize.Add(ik, new Rectangle(0, 0, iconRect.Width, iconRect.Height)); } } private int _previousSelectedTabIndex; private Point _animationSource; private readonly AnimationManager _clickAnimManager; private readonly AnimationManager _showHideAnimManager; private List _drawerItemRects; private List _drawerItemPaths; private const int TAB_HEADER_PADDING = 24; private const int BORDER_WIDTH = 7; private int drawerItemHeight; public int MinWidth; private int _lastMouseY; private int _lastLocationY; public MaterialDrawer() { SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); Height = 120; Width = 250; IndicatorWidth = 0; _isOpen = false; ShowIconsWhenHidden = false; AutoHide = false; AutoShow = false; HighlightWithAccent = true; BackgroundWithAccent = false; _showHideAnimManager = new AnimationManager { AnimationType = AnimationType.EaseInOut, Increment = 0.04 }; _showHideAnimManager.OnAnimationProgress += sender => { Invalidate(); showHideAnimation(); }; _showHideAnimManager.OnAnimationFinished += sender => { if (_showTabControl != null && _drawerItemRects.Count > 0) { rippleSize = _drawerItemRects[_showTabControl.SelectedIndex].Width; } if (_isOpen) { DrawerEndOpen?.Invoke(this); } else { DrawerEndClose?.Invoke(this); } }; SkinManager.ColorSchemeChanged += sender => { preProcessIcons(); }; SkinManager.ThemeChanged += sender => { preProcessIcons(); }; _clickAnimManager = new AnimationManager { AnimationType = AnimationType.EaseOut, Increment = 0.04 }; _clickAnimManager.OnAnimationProgress += sender => Invalidate(); MouseWheel += MaterialDrawer_MouseWheel; } private void MaterialDrawer_MouseWheel(object sender, MouseEventArgs e) { int step = 20; if (e.Delta > 0) { if (Location.Y < 0) { Location = new Point(Location.X, Location.Y + step > 0 ? 0 : Location.Y + step); Height = Location.Y + step > 0 ? Parent.Height : Height - step; } } else { if (Height < (8 + drawerItemHeight) * _drawerItemRects.Count) { Location = new Point(Location.X, Location.Y - step); Height += step; } } } [EditorBrowsable(EditorBrowsableState.Advanced)] protected override void InitLayout() { drawerItemHeight = (TAB_HEADER_PADDING * 2) - (SkinManager.FORM_PADDING / 2); MinWidth = (int)((SkinManager.FORM_PADDING * 1.5) + drawerItemHeight); _showHideAnimManager.SetProgress(_isOpen ? 0 : 1); showHideAnimation(); Invalidate(); base.InitLayout(); } private void showHideAnimation() { double showHideAnimProgress = _showHideAnimManager.GetProgress(); if (_showHideAnimManager.IsAnimating()) { if (ShowIconsWhenHidden) { Location = new Point((int)((-Width + MinWidth) * showHideAnimProgress), Location.Y); } else { Location = new Point((int)(-Width * showHideAnimProgress), Location.Y); } } else { if (_isOpen) { Location = new Point(0, Location.Y); } else { if (ShowIconsWhenHidden) { Location = new Point((int)(-Width + MinWidth), Location.Y); } else { Location = new Point(-Width, Location.Y); } } } UpdateTabRects(); } protected override void OnPaint(PaintEventArgs e) { Paint(e); } private new void Paint(PaintEventArgs e) { Graphics g = e.Graphics; g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; // redraw stuff g.Clear(UseColors ? SkinManager.ColorScheme.PrimaryColor : SkinManager.BackdropColor); if (_showTabControl == null) { return; } if (!_clickAnimManager.IsAnimating() || _drawerItemRects == null || _drawerItemRects.Count != _showTabControl.TabCount) { UpdateTabRects(); } if (_drawerItemRects == null || _drawerItemRects.Count != _showTabControl.TabCount) { return; } // Click Animation double clickAnimProgress = _clickAnimManager.GetProgress(); // Show/Hide Drawer Animation double showHideAnimProgress = _showHideAnimManager.GetProgress(); int rSize = (int)(clickAnimProgress * rippleSize * 1.75); int dx = prevLocation - Location.X; prevLocation = Location.X; // Ripple if (_clickAnimManager.IsAnimating()) { SolidBrush rippleBrush = new(Color.FromArgb((int)(70 - (clickAnimProgress * 70)), UseColors ? SkinManager.ColorScheme.AccentColor : // Using colors SkinManager.Theme == MaterialSkinManager.Themes.LIGHT ? SkinManager.ColorScheme.PrimaryColor : // light theme SkinManager.ColorScheme.LightPrimaryColor)); // dark theme g.SetClip(_drawerItemPaths[_showTabControl.SelectedIndex]); g.FillEllipse(rippleBrush, new Rectangle(_animationSource.X + dx - (rSize / 2), _animationSource.Y - (rSize / 2), rSize, rSize)); g.ResetClip(); rippleBrush.Dispose(); } // Draw menu items foreach (System.Windows.Forms.TabPage tabPage in _showTabControl.TabPages) { int currentTabIndex = _showTabControl.TabPages.IndexOf(tabPage); // Background Brush bgBrush = new SolidBrush(Color.FromArgb(CalculateAlpha(60, 0, currentTabIndex, clickAnimProgress, 1 - showHideAnimProgress), UseColors ? _backgroundWithAccent ? SkinManager.ColorScheme.AccentColor : SkinManager.ColorScheme.LightPrimaryColor : // using colors _backgroundWithAccent ? SkinManager.ColorScheme.AccentColor : // defaul accent SkinManager.Theme == MaterialSkinManager.Themes.LIGHT ? SkinManager.ColorScheme.PrimaryColor : // default light SkinManager.ColorScheme.LightPrimaryColor)); // default dark g.FillPath(bgBrush, _drawerItemPaths[currentTabIndex]); bgBrush.Dispose(); // Text Color textColor = Color.FromArgb(CalculateAlphaZeroWhenClosed(SkinManager.TextHighEmphasisColor.A, UseColors ? SkinManager.TextMediumEmphasisColor.A : 255, currentTabIndex, clickAnimProgress, 1 - showHideAnimProgress), // alpha UseColors ? (currentTabIndex == _showTabControl.SelectedIndex ? (_highlightWithAccent ? SkinManager.ColorScheme.AccentColor : SkinManager.ColorScheme.PrimaryColor) // Use colors - selected : SkinManager.ColorScheme.TextColor) : // Use colors - not selected (currentTabIndex == _showTabControl.SelectedIndex ? (_highlightWithAccent ? SkinManager.ColorScheme.AccentColor : SkinManager.ColorScheme.PrimaryColor) : // selected SkinManager.TextHighEmphasisColor)); IntPtr textFont = SkinManager.GetLogFontByType(MaterialSkinManager.FontType.Subtitle2); Rectangle textRect = _drawerItemRects[currentTabIndex]; textRect.X += _showTabControl.ImageList != null ? drawerItemHeight : (int)(SkinManager.FORM_PADDING * 0.75); textRect.Width -= SkinManager.FORM_PADDING << 2; using (MaterialNativeTextRenderer NativeText = new(g)) { NativeText.DrawTransparentText(tabPage.Text, textFont, textColor, textRect.Location, textRect.Size, MaterialNativeTextRenderer.TextAlignFlags.Left | MaterialNativeTextRenderer.TextAlignFlags.Middle); } // Icons if (_showTabControl.ImageList != null && !string.IsNullOrEmpty(tabPage.ImageKey)) { string ik = string.Concat(tabPage.ImageKey, "_", tabPage.Name); Rectangle iconRect = new( _drawerItemRects[currentTabIndex].X + (drawerItemHeight >> 1) - (iconsSize[ik].Width >> 1), _drawerItemRects[currentTabIndex].Y + (drawerItemHeight >> 1) - (iconsSize[ik].Height >> 1), iconsSize[ik].Width, iconsSize[ik].Height); if (ShowIconsWhenHidden) { iconsBrushes[ik].TranslateTransform(dx, 0); iconsSelectedBrushes[ik].TranslateTransform(dx, 0); } g.FillRectangle(currentTabIndex == _showTabControl.SelectedIndex ? iconsSelectedBrushes[ik] : iconsBrushes[ik], iconRect); } } // Draw divider if not using colors if (!UseColors) { using Pen dividerPen = new(SkinManager.DividersColor, 1); g.DrawLine(dividerPen, Width - 1, 0, Width - 1, Height); } // Animate tab indicator int previousSelectedTabIndexIfHasOne = _previousSelectedTabIndex == -1 ? _showTabControl.SelectedIndex : _previousSelectedTabIndex; Rectangle previousActiveTabRect = _drawerItemRects[previousSelectedTabIndexIfHasOne]; Rectangle activeTabPageRect = _drawerItemRects[_showTabControl.SelectedIndex]; int y = previousActiveTabRect.Y + (int)((activeTabPageRect.Y - previousActiveTabRect.Y) * clickAnimProgress); int x = ShowIconsWhenHidden ? -Location.X : 0; int height = drawerItemHeight; g.FillRectangle(SkinManager.ColorScheme.AccentBrush, x, y, IndicatorWidth, height); } public new void Show() { _isOpen = true; DrawerStateChanged?.Invoke(this); DrawerBeginOpen?.Invoke(this); _showHideAnimManager.StartNewAnimation(AnimationDirection.Out); } public new void Hide() { _isOpen = false; DrawerStateChanged?.Invoke(this); DrawerBeginClose?.Invoke(this); _showHideAnimManager.StartNewAnimation(AnimationDirection.In); } public void Toggle() { if (_isOpen) { Hide(); } else { Show(); } } private int CalculateAlphaZeroWhenClosed(int primaryA, int secondaryA, int tabIndex, double clickAnimProgress, double showHideAnimProgress) { // Drawer is closed if (!_isOpen && !_showHideAnimManager.IsAnimating()) { return 0; } // Active menu (no change) if (tabIndex == _showTabControl.SelectedIndex && (!_clickAnimManager.IsAnimating() || _showHideAnimManager.IsAnimating())) { return (int)(primaryA * showHideAnimProgress); } // Previous menu (changing) if (tabIndex == _previousSelectedTabIndex && !_showHideAnimManager.IsAnimating()) { return primaryA - (int)((primaryA - secondaryA) * clickAnimProgress); } // Inactive menu (no change) if (tabIndex != _showTabControl.SelectedIndex) { return (int)(secondaryA * showHideAnimProgress); } // Active menu (changing) return secondaryA + (int)((primaryA - secondaryA) * clickAnimProgress); } private int CalculateAlpha(int primaryA, int secondaryA, int tabIndex, double clickAnimProgress, double showHideAnimProgress) { if (tabIndex == _showTabControl.SelectedIndex && !_clickAnimManager.IsAnimating()) { return (int)primaryA; } if (tabIndex != _previousSelectedTabIndex && tabIndex != _showTabControl.SelectedIndex) { return secondaryA; } if (tabIndex == _previousSelectedTabIndex) { return primaryA - (int)((primaryA - secondaryA) * clickAnimProgress); } return secondaryA + (int)((primaryA - secondaryA) * clickAnimProgress); } protected override void OnMouseClick(MouseEventArgs e) { base.OnMouseClick(e); if (_drawerItemRects == null) { UpdateTabRects(); } for (int i = 0; i < _drawerItemRects.Count; i++) { if (_drawerItemRects[i].Contains(e.Location) && _lastLocationY == Location.Y) { if (DrawerNonClickTabPage == null || !DrawerNonClickTabPage.Contains(_showTabControl.TabPages[i])) { _showTabControl.SelectedIndex = i; if (AutoHide && !AutoShow) { Hide(); } } } } _animationSource = e.Location; } protected override void OnMouseDown(MouseEventArgs e) { _lastMouseY = e.Y; _lastLocationY = Location.Y; // memorize Y location of drawer base.OnMouseDown(e); if (DesignMode) { return; } MouseState = MaterialMouseState.DOWN; } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (DesignMode) { return; } MouseState = MaterialMouseState.OUT; } protected override void OnMouseMove(MouseEventArgs e) { if (DesignMode) { return; } if (e.Button == MouseButtons.Left && e.Y != _lastMouseY && (Location.Y < 0 || Height < (8 + drawerItemHeight) * _drawerItemRects.Count)) { int diff = e.Y - _lastMouseY; if (diff > 0) { if (Location.Y < 0) { Location = new Point(Location.X, Location.Y + diff > 0 ? 0 : Location.Y + diff); Height = Parent.Height + Math.Abs(Location.Y); } } else { if (Height < (8 + drawerItemHeight) * _drawerItemRects.Count) { Location = new Point(Location.X, Location.Y + diff); Height = Parent.Height + Math.Abs(Location.Y); } } //return; } base.OnMouseMove(e); if (_drawerItemRects == null) { UpdateTabRects(); } Cursor previousCursor = Cursor; for (int i = 0; i < _drawerItemRects.Count; i++) { if (_drawerItemRects[i].Contains(e.Location)) { if (DrawerNonClickTabPage == null || !DrawerNonClickTabPage.Contains(_showTabControl.TabPages[i])) { Cursor = Cursors.Hand; return; } else { Cursor = Cursors.No; return; } } } Cursor = previousCursor; if (e.Location.X + this.Location.X < BORDER_WIDTH) { if (e.Location.Y > this.Height - BORDER_WIDTH) { Cursor = Cursors.SizeNESW; //Bottom Left } else { Cursor = Cursors.SizeWE; //Left } } else if (e.Location.Y > this.Height - BORDER_WIDTH) { Cursor = Cursors.SizeNS; //Bottom } else { if (e.Location.Y < _drawerItemRects[_drawerItemRects.Count - 1].Bottom && (e.Location.X + this.Location.X) >= BORDER_WIDTH) { Cursor = Cursors.Hand; } else { Cursor = Cursors.Default; } } if (previousCursor != Cursor) { CursorUpdate?.Invoke(this, Cursor); } } protected override void OnMouseEnter(EventArgs e) { base.OnMouseEnter(e); if (AutoShow && _isOpen == false) { Show(); } } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); if (MouseState != MaterialMouseState.DOWN) { Cursor = Cursors.Default; CursorUpdate?.Invoke(this, Cursor); } if (AutoShow) { Hide(); } } private void UpdateTabRects() { //If there isn't a base tab control, the rects shouldn't be calculated //or if there aren't tab pages in the base tab control, the list should just be empty if (_showTabControl == null || _showTabControl.TabCount == 0 || SkinManager == null || _drawerItemRects == null) { _drawerItemRects = new List(); _drawerItemPaths = new List(); return; } if (_drawerItemRects.Count != _showTabControl.TabCount) { _drawerItemRects = new List(_showTabControl.TabCount); _drawerItemPaths = new List(_showTabControl.TabCount); for (int i = 0; i < _showTabControl.TabCount; i++) { _drawerItemRects.Add(new Rectangle()); _drawerItemPaths.Add(new GraphicsPath()); } } //Calculate the bounds of each tab header specified in the base tab control for (int i = 0; i < _showTabControl.TabPages.Count; i++) { _drawerItemRects[i] = new Rectangle( (int)(SkinManager.FORM_PADDING * 0.75) - (ShowIconsWhenHidden ? Location.X : 0), (TAB_HEADER_PADDING * 2 * i) + (int)(SkinManager.FORM_PADDING >> 1), Width + (ShowIconsWhenHidden ? Location.X : 0) - (int)(SkinManager.FORM_PADDING * 1.5) - 1, drawerItemHeight); _drawerItemPaths[i] = CreateRoundRect(new RectangleF(_drawerItemRects[i].X - 0.5f, _drawerItemRects[i].Y - 0.5f, _drawerItemRects[i].Width, _drawerItemRects[i].Height), 4); } } } #endregion }