#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<Cursor> CursorUpdate;
|
|
// icons
|
private Dictionary<string, TextureBrush> iconsBrushes;
|
|
private Dictionary<string, TextureBrush> iconsSelectedBrushes;
|
private Dictionary<string, Rectangle> 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<string>().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<string>().ToArray();
|
}
|
|
UpdateTabRects();
|
preProcessIcons();
|
|
Refresh();
|
Invalidate();
|
}
|
}
|
}
|
|
[Category("Behavior")]
|
public System.Windows.Forms.TabPage[] DrawerNonClickTabPage { get; set; } = new List<System.Windows.Forms.TabPage>().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<string, TextureBrush>(_showTabControl.TabPages.Count);
|
iconsSelectedBrushes = new Dictionary<string, TextureBrush>(_showTabControl.TabPages.Count);
|
iconsSize = new Dictionary<string, Rectangle>(_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<Rectangle> _drawerItemRects;
|
private List<GraphicsPath> _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<Rectangle>();
|
_drawerItemPaths = new List<GraphicsPath>();
|
return;
|
}
|
|
if (_drawerItemRects.Count != _showTabControl.TabCount)
|
{
|
_drawerItemRects = new List<Rectangle>(_showTabControl.TabCount);
|
_drawerItemPaths = new List<GraphicsPath>(_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
|
}
|