Instantly share code, notes, and snippets.
Last active
July 21, 2022 04:15
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save ahmedosama007/d40ec7c1a742b831b1a69f5ce776db7a to your computer and use it in GitHub Desktop.
Custom Form control buttons that support the Visual Studio 2019 theme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Region "References" | |
Imports System.ComponentModel | |
Imports System.Drawing.Drawing2D | |
#End Region | |
Namespace Controls | |
<ToolboxItem(True)> <ToolboxBitmap(GetType(Button))> Public Class FormControlButton | |
Inherits NoFocusCueButton | |
#Region "Private Members" | |
Private _theme As UITheme = UITheme.VS2019LightBlue | |
Private _iconPen As Pen | |
Private _iconBrush As Brush | |
Private _iconColor As Color = Color.FromArgb(30, 30, 30) | |
Private _buttonType As ControlButtonType = ControlButtonType.Close | |
Private _isMouseDown, _isMouseEntered As Boolean | |
#End Region | |
#Region "Constructor" | |
Public Sub New() | |
SetStyle(ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw, True) | |
BackColor = Color.FromArgb(251, 251, 251) | |
End Sub | |
#End Region | |
#Region "Enumerations" | |
Public Enum ControlButtonType | |
''' <summary> | |
''' Button to close the Form | |
''' </summary> | |
Close | |
''' <summary> | |
''' Button to maximize the Form | |
''' </summary> | |
Maximize | |
''' <summary> | |
''' Button to minimize the Form | |
''' </summary> | |
Minimize | |
''' <summary> | |
''' Button to show the app settings/options | |
''' </summary> | |
Menu | |
End Enum | |
#End Region | |
#Region "Public Properties" | |
<Category("Appearance")> <Description("The background color of the Control Button in the Normal state.")> | |
<DefaultValue(GetType(Color), "251, 251, 251")> Public Overrides Property BackColor As Color | |
Get | |
Return MyBase.BackColor | |
End Get | |
Set(value As Color) | |
MyBase.BackColor = value | |
End Set | |
End Property | |
<EditorBrowsable(EditorBrowsableState.Always)> | |
<Browsable(True)> <DefaultValue(GetType(ControlButtonType), "0")> | |
<Category("Appearance")> <Description("The Control Button type.")> | |
Public Property ButtonType As ControlButtonType | |
Get | |
Return _buttonType | |
End Get | |
Set(value As ControlButtonType) | |
_buttonType = value | |
Invalidate() | |
End Set | |
End Property | |
<EditorBrowsable(EditorBrowsableState.Always)> | |
<Browsable(True)> <DefaultValue(GetType(Color), "255, 255, 255")> | |
<Category("Appearance")> <Description("The background color of the Control Button when the mouse enters the button.")> | |
Public Property MouseHoverBackColor As Color = Color.FromArgb(255, 255, 255) | |
<EditorBrowsable(EditorBrowsableState.Always)> | |
<Browsable(True)> <DefaultValue(GetType(Color), "0, 122, 204")> | |
<Category("Appearance")> <Description("The background color of the Control Button when the button is clicked.")> | |
Public Property MouseDownBackColor As Color = Color.FromArgb(0, 122, 204) | |
<EditorBrowsable(EditorBrowsableState.Always)> | |
<Browsable(True)> <DefaultValue(GetType(Color), "30, 30, 30")> | |
<Category("Appearance")> <Description("The Control Button icon color.")> | |
Public Property IconColor As Color | |
Get | |
Return _iconColor | |
End Get | |
Set(value As Color) | |
_iconColor = value | |
Invalidate() | |
End Set | |
End Property | |
<EditorBrowsable(EditorBrowsableState.Always)> | |
<Browsable(True)> <DefaultValue(GetType(Color), "0, 122, 204")> | |
<Category("Appearance")> <Description("The color of the Control Button icon when the mouse enters the button.")> | |
Public Property MouseHoverIconColor As Color = Color.FromArgb(0, 122, 204) | |
<EditorBrowsable(EditorBrowsableState.Always)> | |
<Browsable(True)> <DefaultValue(GetType(Color), "255, 255, 255")> | |
<Category("Appearance")> <Description("The color of the Control Button icon when the button is clicked.")> | |
Public Property MouseDownIconColor As Color = Color.FromArgb(255, 255, 255) | |
<Category("Appearance")> <Description("The theme to apply to the Control Button.")> <DefaultValue(GetType(UITheme), "1")> Public Property Theme As UITheme | |
Get | |
Return _theme | |
End Get | |
Set(value As UITheme) | |
_theme = value | |
If _theme = UITheme.VS2019DarkBlue Then | |
BackColor = Color.FromArgb(37, 37, 38) | |
If _buttonType = ControlButtonType.Close Then | |
MouseHoverBackColor = Color.FromArgb(232, 17, 35) | |
MouseDownBackColor = Color.FromArgb(241, 112, 122) | |
MouseHoverIconColor = Color.FromArgb(255, 255, 255) | |
Else | |
MouseHoverBackColor = Color.FromArgb(63, 63, 64) | |
MouseDownBackColor = Color.FromArgb(0, 122, 204) | |
MouseHoverIconColor = Color.FromArgb(255, 255, 255) | |
End If | |
IconColor = Color.FromArgb(241, 241, 241) | |
MouseDownIconColor = Color.FromArgb(255, 255, 255) | |
ElseIf _theme = UITheme.VS2019LightBlue Then | |
BackColor = Color.FromArgb(251, 251, 251) | |
If _buttonType = ControlButtonType.Close Then | |
MouseHoverBackColor = Color.FromArgb(232, 17, 35) | |
MouseDownBackColor = Color.FromArgb(241, 112, 122) | |
MouseHoverIconColor = Color.FromArgb(255, 255, 255) | |
Else | |
MouseHoverBackColor = Color.FromArgb(255, 255, 255) | |
MouseDownBackColor = Color.FromArgb(0, 122, 204) | |
MouseHoverIconColor = Color.FromArgb(0, 122, 204) | |
End If | |
IconColor = Color.FromArgb(30, 30, 30) | |
MouseDownIconColor = Color.FromArgb(255, 255, 255) | |
End If | |
Invalidate() | |
End Set | |
End Property | |
Protected Overrides ReadOnly Property DefaultSize As Size | |
Get | |
Return New Size(46, 30) | |
End Get | |
End Property | |
#End Region | |
#Region "Private Properties" | |
Private ReadOnly Property ActiveBackColor As Color | |
Get | |
If _isMouseDown Then Return MouseDownBackColor | |
If _isMouseEntered Then Return MouseHoverBackColor | |
Return BackColor | |
End Get | |
End Property | |
Private ReadOnly Property ActiveIconColor As Color | |
Get | |
If _isMouseDown Then Return MouseDownIconColor | |
If _isMouseEntered Then Return MouseHoverIconColor | |
Return IconColor | |
End Get | |
End Property | |
#End Region | |
#Region "Overriden Methods" | |
Protected Overrides Sub OnClick(e As EventArgs) | |
If _buttonType <> ControlButtonType.Menu Then | |
Dim frm As Form = FindForm() | |
If frm IsNot Nothing Then | |
If _buttonType = ControlButtonType.Close Then | |
frm.Close() | |
ElseIf _buttonType = ControlButtonType.Maximize Then | |
frm.WindowState = If(frm.WindowState = FormWindowState.Maximized, FormWindowState.Normal, FormWindowState.Maximized) | |
Else | |
frm.WindowState = FormWindowState.Minimized | |
End If | |
End If | |
End If | |
MyBase.OnClick(e) | |
End Sub | |
Protected Overrides Sub OnPaint(pevent As PaintEventArgs) | |
Using sb = New SolidBrush(ActiveBackColor) | |
pevent.Graphics.FillRectangle(sb, pevent.ClipRectangle) | |
End Using | |
pevent.Graphics.SmoothingMode = SmoothingMode.HighQuality | |
_iconBrush?.Dispose() | |
_iconPen?.Dispose() | |
_iconBrush = New SolidBrush(ActiveIconColor) | |
_iconPen = New Pen(_iconBrush, 1.0F) | |
If _buttonType = ControlButtonType.Close Then | |
DrawCloseIcon(pevent) | |
ElseIf _buttonType = ControlButtonType.Maximize Then | |
DrawMaximizeIcon(pevent) | |
ElseIf _buttonType = ControlButtonType.Minimize Then | |
DrawMinimizeIcon(pevent) | |
ElseIf _buttonType = ControlButtonType.Menu Then | |
DrawMenuIcon(pevent) | |
End If | |
End Sub | |
Protected Overrides Sub OnMouseEnter(e As EventArgs) | |
MyBase.OnMouseEnter(e) | |
If Not DesignMode Then _isMouseEntered = True | |
End Sub | |
Protected Overrides Sub OnMouseLeave(e As EventArgs) | |
MyBase.OnMouseLeave(e) | |
If Not DesignMode Then _isMouseEntered = False | |
End Sub | |
Protected Overrides Sub OnMouseDown(mevent As MouseEventArgs) | |
MyBase.OnMouseDown(mevent) | |
If Not DesignMode Then _isMouseDown = True | |
End Sub | |
Protected Overrides Sub OnMouseUp(mevent As MouseEventArgs) | |
MyBase.OnMouseUp(mevent) | |
If Not DesignMode Then _isMouseDown = False | |
End Sub | |
#End Region | |
#Region "Private Methods" | |
Private Sub DrawCloseIcon(e As PaintEventArgs) | |
Dim drawRect = ClientRectangle | |
e.Graphics.DrawLine(_iconPen, CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2) - 5), CInt(drawRect.X + (drawRect.Width / 2) + 5), CInt(drawRect.Y + (drawRect.Height / 2) + 5)) | |
e.Graphics.DrawLine(_iconPen, CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2) + 5), CInt(drawRect.X + (drawRect.Width / 2) + 5), CInt(drawRect.Y + (drawRect.Height / 2) - 5)) | |
End Sub | |
Private Sub DrawMaximizeIcon(e As PaintEventArgs) | |
Dim drawRect = ClientRectangle | |
Dim frm = FindForm() | |
If frm IsNot Nothing Then | |
If frm.WindowState = FormWindowState.Maximized Then | |
e.Graphics.DrawRectangle(_iconPen, New Rectangle(CInt(drawRect.X + (drawRect.Width / 2) - 3), CInt(drawRect.Y + (drawRect.Height / 2) - 5), 8, 8)) | |
Dim rect As New Rectangle(CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2) - 3), 8, 8) | |
Using sb = New SolidBrush(ActiveBackColor) | |
e.Graphics.FillRectangle(sb, rect) | |
End Using | |
e.Graphics.DrawRectangle(_iconPen, rect) | |
Else | |
e.Graphics.DrawRectangle(_iconPen, New Rectangle(CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2) - 5), 10, 10)) | |
End If | |
End If | |
End Sub | |
Private Sub DrawMinimizeIcon(e As PaintEventArgs) | |
Dim drawRect = ClientRectangle | |
e.Graphics.DrawLine(_iconPen, CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2)), CInt(drawRect.X + (drawRect.Width / 2) + 5), CInt(drawRect.Y + (drawRect.Height / 2))) | |
End Sub | |
Private Sub DrawMenuIcon(e As PaintEventArgs) | |
Dim drawRect = ClientRectangle | |
Dim vMargin As Integer = 4 | |
e.Graphics.DrawLine(_iconPen, CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2) - vMargin), CInt(drawRect.X + (drawRect.Width / 2) + 5), CInt(drawRect.Y + (drawRect.Height / 2) - vMargin)) | |
e.Graphics.DrawLine(_iconPen, CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2)), CInt(drawRect.X + (drawRect.Width / 2) + 5), CInt(drawRect.Y + (drawRect.Height / 2))) | |
e.Graphics.DrawLine(_iconPen, CInt(drawRect.X + (drawRect.Width / 2) - 5), CInt(drawRect.Y + (drawRect.Height / 2) + vMargin), CInt(drawRect.X + (drawRect.Width / 2) + 5), CInt(drawRect.Y + (drawRect.Height / 2) + vMargin)) | |
End Sub | |
#End Region | |
End Class | |
End Namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Namespace Controls | |
<ToolboxBitmap(GetType(Button))> Public Class NoFocusCueButton | |
Inherits Button | |
#Region "Constructor" | |
Public Sub New() | |
MyBase.New() | |
SetStyle(ControlStyles.Selectable, False) | |
End Sub | |
#End Region | |
#Region "Overrides" | |
Protected Overrides ReadOnly Property ShowFocusCues As Boolean | |
Get | |
Return False | |
End Get | |
End Property | |
Public Overrides Sub NotifyDefault(value As Boolean) | |
MyBase.NotifyDefault(False) | |
End Sub | |
#End Region | |
End Class | |
End Namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Public Enum UITheme As Integer | |
''' <summary> | |
''' User defined theme | |
''' </summary> | |
Custom = -1 | |
''' <summary> | |
''' Visual Studio 2019 Dark Blue theme | |
''' </summary> | |
VS2019DarkBlue = 0 | |
''' <summary> | |
''' Visual Studio 2019 Light Blue theme | |
''' </summary> | |
VS2019LightBlue = 1 | |
End Enum |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment