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 {