diff --git a/Changelog.md b/Changelog.md
index b62f18c9..bf848c9e 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -26,6 +26,7 @@
- Code Editor does not join Source, Crop, Resize and Rotation filters automatically (Dendraspis)
- Code Editor can join (in-)active filters only [Don't forget to reset "Edit Menu" in Code Editor!] (Dendraspis)
- Code Editor joined filters have the filter name "Misc" (Dendraspis)
+- Custom checkboxes for better theme experience (Dendraspis)
- SMDegrain 3.1.2.111s
diff --git a/StaxRip.vbproj b/StaxRip.vbproj
index bc31f90c..383cc542 100644
--- a/StaxRip.vbproj
+++ b/StaxRip.vbproj
@@ -225,6 +225,7 @@
True
Resources.resx
+
DataForm.vb
diff --git a/UI/CheckBoxRendererEx.vb b/UI/CheckBoxRendererEx.vb
new file mode 100644
index 00000000..b5137db8
--- /dev/null
+++ b/UI/CheckBoxRendererEx.vb
@@ -0,0 +1,54 @@
+Imports System.Windows.Forms.VisualStyles
+Imports StaxRip.UI
+
+Public Class CheckBoxRendererEx
+
+ Public Shared Sub DrawCheckBox(g As Graphics, glyphLocation As Point, state As CheckBoxState)
+ DrawCheckBox(g, New Rectangle(glyphLocation, GetGlyphSize(g, state)), state)
+ End Sub
+
+ Public Shared Sub DrawCheckBox(g As Graphics, rect As Rectangle, state As CheckBoxState)
+ If ThemeManager.CurrentTheme.Name = ThemeManager.DefaultThemeName OrElse DesignHelp.IsDesignMode Then
+ CheckBoxRenderer.DrawCheckBox(g, rect.Location, state)
+ Return
+ End If
+
+ Dim checked = state = CheckBoxState.CheckedDisabled OrElse state = CheckBoxState.CheckedHot OrElse state = CheckBoxState.CheckedNormal OrElse state = CheckBoxState.CheckedPressed
+ Dim theme = ThemeManager.CurrentTheme.General.Controls.CheckBox
+ Dim backColor = If(checked, theme.BoxCheckedColor, theme.BoxColor)
+ Dim penColor = theme.CheckmarkColor
+
+ Select Case state
+ Case CheckBoxState.CheckedNormal
+ Using brush As New SolidBrush(backColor)
+ g.FillRectangle(brush, rect)
+ End Using
+
+ Dim penStrength = 4
+
+ Dim startX1 = rect.Left + rect.Width / 4.5F
+ Dim startY1 = rect.Top + rect.Height / 2.25F
+ Dim endX1 = rect.Left + rect.Width / 3.0F
+ Dim endY1 = rect.Top + rect.Height / 1.2F
+
+ Dim startX2 = rect.Left + rect.Width / 3.1F
+ Dim startY2 = rect.Top + rect.Height / 1.3F
+ Dim endX2 = rect.Left + rect.Width / 1.2F
+ Dim endY2 = rect.Top + rect.Height / 5.0F
+
+ Using pen As New Pen(penColor, penStrength)
+ g.DrawLine(pen, startX1, startY1, endX1, endY1)
+ g.DrawLine(pen, startX2, startY2, endX2, endY2)
+ End Using
+ Case CheckBoxState.UncheckedNormal
+ Using brush As New SolidBrush(backColor)
+ g.FillRectangle(brush, rect)
+ End Using
+ End Select
+ End Sub
+
+ Public Shared Function GetGlyphSize(g As Graphics, state As CheckBoxState) As Size
+ Return CheckBoxRenderer.GetGlyphSize(g, state)
+ End Function
+
+End Class
diff --git a/UI/Controls/Controls.vb b/UI/Controls/Controls.vb
index 69513b65..e9abfc87 100644
--- a/UI/Controls/Controls.vb
+++ b/UI/Controls/Controls.vb
@@ -706,6 +706,14 @@ Namespace UI
Public Class CheckBoxEx
Inherits CheckBox
+ Private _theme As Theme
+
+ Public ReadOnly Property Theme As Theme
+ Get
+ Return _theme
+ End Get
+ End Property
+
Shadows Property Name() As String
Get
@@ -746,6 +754,8 @@ Namespace UI
End Sub
Sub ApplyTheme(theme As Theme)
+ _theme = theme
+
If DesignHelp.IsDesignMode Then
Exit Sub
End If
@@ -774,17 +784,20 @@ Namespace UI
End Sub
Protected Overrides Sub OnPaint(pevent As PaintEventArgs)
- MyBase.OnPaint(pevent)
+ InvokePaintBackground(Me, pevent)
- 'If Appearance.HasFlag(Appearance.Normal) Then
- ' Dim bColor = If(Checked, Color.Red, Color.Yellow)
- ' Dim diameter = pevent.ClipRectangle.Height - 2
- ' Dim rect = New Rectangle(New Point(0, 1), New Size(diameter, diameter))
- ' ControlPaint.DrawCheckBox(pevent.Graphics, rect, If(Checked, ButtonState.Checked, ButtonState.Normal))
- ' ControlPaint.DrawMixedCheckBox(pevent.Graphics, rect, If(Checked, ButtonState.Checked, ButtonState.Normal))
- ' pevent.Graphics.FillRectangle(New SolidBrush(bColor), rect)
- 'End If
+ pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias
+ Dim state As CheckBoxState = If(CheckState = CheckState.Checked, CheckBoxState.CheckedNormal, CheckBoxState.UncheckedNormal)
+ Dim glyphSize As Size = CheckBoxRendererEx.GetGlyphSize(pevent.Graphics, state)
+ Dim vPos As Integer = (Height - glyphSize.Height) \ 2
+ Dim hPos As Integer = 1
+ Dim glyphLocation As Point = New Point(hPos, vPos)
+ Dim textLocation As Point = New Point(hPos + glyphSize.Width + hPos, Height - (Height - TextRenderer.MeasureText(Text, Font).Height) \ 3)
+ Dim textFlags As TextFormatFlags = TextFormatFlags.SingleLine Or TextFormatFlags.VerticalCenter
+ Dim fColor As ColorHSL = If(MyBase.Checked, _theme.General.Controls.CheckBox.ForeCheckedColor, _theme.General.Controls.CheckBox.ForeColor)
+ CheckBoxRendererEx.DrawCheckBox(pevent.Graphics, glyphLocation, state)
+ TextRenderer.DrawText(pevent.Graphics, Text, Font, textLocation, fColor, textFlags)
End Sub
Protected Overrides Sub OnPaintBackground(pevent As PaintEventArgs)
diff --git a/UI/Controls/ListViewEx.vb b/UI/Controls/ListViewEx.vb
index 4d478f92..8ed33c6a 100644
--- a/UI/Controls/ListViewEx.vb
+++ b/UI/Controls/ListViewEx.vb
@@ -212,7 +212,7 @@ Namespace UI
If CheckBoxes Then
Dim checkedState = If(e.Item.Checked, CheckBoxState.CheckedNormal, CheckBoxState.UncheckedNormal)
- Dim glyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, checkedState)
+ Dim glyphSize = CheckBoxRendererEx.GetGlyphSize(e.Graphics, checkedState)
Dim hPos = (e.Bounds.Height - glyphSize.Height) \ 2
Dim vPos = hPos + e.Bounds.Y
Dim location = New Point(hPos, vPos)
@@ -220,7 +220,7 @@ Namespace UI
rect.X += textOffset
rect.Width -= textOffset
- CheckBoxRenderer.DrawCheckBox(e.Graphics, location, checkedState)
+ CheckBoxRendererEx.DrawCheckBox(e.Graphics, location, checkedState)
End If
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.Font, rect, fc, flags)
diff --git a/UI/Theme.vb b/UI/Theme.vb
index cd08c808..d724ae8c 100644
--- a/UI/Theme.vb
+++ b/UI/Theme.vb
@@ -442,11 +442,16 @@ Public Class Theme
Public Class CheckBoxThemeColors
Public Property BackColor As ColorHSL = SystemColors.Control
+ Public Property BackCheckedColor As ColorHSL = BackColor
Public Property BackHighlightColor As ColorHSL = _defaultBackHighlightColor
Public Property BackHoverColor As ColorHSL = BackColor
Public Property BorderColor As ColorHSL = SystemColors.ActiveBorder
+ Public Property BoxColor As ColorHSL = SystemColors.Control
+ Public Property BoxCheckedColor As ColorHSL = SystemColors.Control
+ Public Property CheckmarkColor As ColorHSL = SystemColors.ControlText
Public Property CheckedBackColor As ColorHSL = SystemColors.Control
Public Property ForeColor As ColorHSL = SystemColors.ControlText
+ Public Property ForeCheckedColor As ColorHSL = ForeColor
Public Property ForeHighlightColor As ColorHSL = ForeColor
End Class
diff --git a/UI/ThemeManager.vb b/UI/ThemeManager.vb
index 646666f0..dbcd8d36 100644
--- a/UI/ThemeManager.vb
+++ b/UI/ThemeManager.vb
@@ -1,4 +1,6 @@
Public NotInheritable Class ThemeManager
+ Private Const _defaultThemeName = "Default"
+
Private Shared _current As Theme
Private Shared _themes As List(Of Theme)
Private Shared ReadOnly _lumaCategories() As KeyValuePair(Of String, Single) = {
@@ -49,6 +51,12 @@
End Get
End Property
+ Public Shared ReadOnly Property DefaultThemeName As String
+ Get
+ Return _defaultThemeName
+ End Get
+ End Property
+
Public Shared ReadOnly Property Themes As List(Of Theme)
Get
_themes = If(_themes, LoadDefaults())
@@ -74,7 +82,7 @@
Private Shared Function LoadDefaults() As List(Of Theme)
Dim defaults = New List(Of Theme) From {
- New Theme("Default")
+ New Theme(_defaultThemeName)
}
For Each lc In _lumaCategories
@@ -86,8 +94,8 @@
Return defaults
End Function
- Public Shared Function SetCurrentTheme(Optional name As String = "Default") As Theme
- If String.IsNullOrWhiteSpace(name) Then name = "Default"
+ Public Shared Function SetCurrentTheme(Optional name As String = _defaultThemeName) As Theme
+ If String.IsNullOrWhiteSpace(name) Then name = _defaultThemeName
Dim theme = Themes?.Where(Function(x) x.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.FirstOrDefault()
If theme IsNot Nothing Then
@@ -176,11 +184,16 @@
},
.CheckBox = New ControlsThemeColors.CheckBoxThemeColors() With {
.BackColor = Color.Empty,
+ .BackCheckedColor = .BackColor,
.BackHighlightColor = _controlBackHighlightColor,
.BackHoverColor = .BackColor.AddLuminance(0.1),
.BorderColor = Color.Transparent,
+ .BoxColor = _foreColor,
+ .BoxCheckedColor = .BoxColor,
.CheckedBackColor = _backColor,
+ .CheckmarkColor = _controlBackColor,
.ForeColor = _foreColor,
+ .ForeCheckedColor = .ForeColor.AddLuminance(0.1F),
.ForeHighlightColor = .ForeColor.AddLuminance(0.15)
},
.ComboBox = New ControlsThemeColors.ComboBoxThemeColors() With {