Imports System.Collections.Generic
Imports System.Text
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Diagnostics

Public Class ToolStripSimpleRenderer
    Inherits ToolStripSystemRenderer

    Public MenuLight As Color = Color.White
    Public MenuDark As Color = Color.FromArgb(&HE2, &HE3, &HE3)
    Public MenuHighlight As Color = Color.LightSkyBlue
    Public MenuHighlightSouth As Color = Color.FromArgb(102, MenuHighlight)
    Public MenuHighlightNorth As Color = Color.FromArgb(25, MenuHighlight)

    Protected Overridable Sub InitializeToolStripMenuItem(ByVal item As ToolStripMenuItem)
        item.AutoSize = False
        item.Height = 26

        For Each i As ToolStripItem In item.DropDownItems
            If TypeOf i Is ToolStripMenuItem Then
                InitializeToolStripMenuItem(DirectCast(i, ToolStripMenuItem))
            End If
        Next
    End Sub

    Protected Overloads Overrides Sub Initialize(ByVal ts As ToolStrip)
        MyBase.Initialize(ts)

        ts.Padding = New Padding(5, ts.Padding.Top, ts.Padding.Right, ts.Padding.Bottom)
        ts.AutoSize = False
        ts.Height = 32
        ts.GripStyle = ToolStripGripStyle.Hidden
    End Sub

    Protected Overloads Overrides Sub InitializeItem(ByVal item As ToolStripItem)
        MyBase.InitializeItem(item)

        item.AutoSize = False
        item.Height = 26

        If TypeOf item Is ToolStripMenuItem Then
            InitializeToolStripMenuItem(DirectCast(item, ToolStripMenuItem))
        End If

        If TypeOf item Is ToolStripSplitButton Then
            Dim btn = DirectCast(item, ToolStripSplitButton)
            btn.DropDownButtonWidth = 18

            For Each i As ToolStripItem In btn.DropDownItems
                If TypeOf i Is ToolStripMenuItem Then
                    InitializeToolStripMenuItem(TryCast(i, ToolStripMenuItem))
                End If
            Next
        End If

        If TypeOf item Is ToolStripDropDownButton Then
            Dim btn = DirectCast(item, ToolStripDropDownButton)

            For Each i As ToolStripItem In btn.DropDownItems
                If TypeOf i Is ToolStripMenuItem Then
                    InitializeToolStripMenuItem(TryCast(i, ToolStripMenuItem))
                End If
            Next
        End If
    End Sub

    Protected Overrides Sub OnRenderToolStripBorder(ByVal e As ToolStripRenderEventArgs)
        ControlPaint.DrawBorder(e.Graphics, e.AffectedBounds, Color.FromArgb(160, 175, 195), ButtonBorderStyle.Solid)
    End Sub

    Protected Overrides Sub OnRenderToolStripBackground(ByVal e As ToolStripRenderEventArgs)
        If TypeOf e.ToolStrip Is ToolStripDropDownMenu Then
            Exit Sub
        End If

        Dim r As New Rectangle(-1, -1, e.AffectedBounds.Width, e.AffectedBounds.Height)

        'win7 commandbar
        'Dim c1 = Color.FromArgb(248, 251, 254)
        'Dim c2 = Color.FromArgb(237, 242, 250)
        'Dim c3 = Color.FromArgb(215, 228, 244)
        'Dim c4 = Color.FromArgb(193, 210, 232)

        'Office 2007 Black
        Dim c1 = Color.FromArgb(248, 248, 249)
        Dim c2 = Color.FromArgb(223, 226, 228)
        Dim c3 = Color.FromArgb(199, 203, 209)
        Dim c4 = Color.FromArgb(219, 222, 226)

        e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear
        e.Graphics.CompositingQuality = CompositingQuality.HighQuality
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality
        e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit

        Dim cb As New ColorBlend()
        cb.Colors = New Color() {c1, c2, c3, c4}
        cb.Positions = New Single() {0.0F, 0.5F, 0.5F, 1.0F}

        Using b As New LinearGradientBrush(r, c1, c4, 90)
            b.InterpolationColors = cb
            e.Graphics.FillRectangle(b, r)
        End Using
    End Sub

    Private Sub DrawMenuBackground(ByVal g As Graphics, ByVal r As Rectangle, ByVal highlighted As Boolean, ByVal ownerIsMainStrip As Boolean)
        Dim left = 22

        'vertical line
        If Not ownerIsMainStrip Then
            Using p As New Pen(MenuDark)
                g.DrawLine(p, New Point(r.Left + left, r.Top), New Point(r.Left + left, r.Height - 2))
            End Using

            Using p As New Pen(MenuLight)
                g.DrawLine(p, New Point(r.Left + left + 1, r.Top), New Point(r.Left + left + 1, r.Height - 2))
            End Using
        End If

        'rectangle
        If highlighted Then
            Using path = CreateRoundRectangle(New Rectangle(r.X + 3, r.Y + 1, r.Width - 6, r.Height - 3), 3)
                Using b As New LinearGradientBrush(New Point(0, 2), New Point(0, r.Height - 2), MenuHighlightNorth, MenuHighlightSouth)
                    g.FillPath(b, path)
                End Using

                Using p As New Pen(MenuHighlight)
                    g.DrawPath(p, path)
                End Using
            End Using
        End If
    End Sub

    Protected Overloads Overrides Sub OnRenderItemText(ByVal e As ToolStripItemTextRenderEventArgs)
        If TypeOf e.Item Is ToolStripButton Then
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit
        End If

        If TypeOf e.Item Is ToolStripMenuItem AndAlso Not (TypeOf e.Item.Owner Is MenuStrip) Then
            Dim r = e.TextRectangle  'TextAlign don't work
            e.TextRectangle = New Rectangle(r.X, (e.Item.Height - r.Height) \ 2, r.Width, r.Height)
        End If

        MyBase.OnRenderItemText(e)
    End Sub

    Protected Overloads Overrides Sub OnRenderMenuItemBackground(ByVal e As ToolStripItemRenderEventArgs)
        e.Item.ForeColor = Color.Black
        DrawMenuBackground(e.Graphics, New Rectangle(Point.Empty, e.Item.Size), e.Item.Selected, TypeOf e.Item.Owner Is MenuStrip)
    End Sub

    Protected Overloads Overrides Sub OnRenderArrow(ByVal e As ToolStripArrowRenderEventArgs)
        e.ArrowColor = Color.Black
        MyBase.OnRenderArrow(e)
    End Sub

    Protected Overloads Overrides Sub OnRenderSeparator(ByVal e As ToolStripSeparatorRenderEventArgs)
        If e.Item.IsOnDropDown Then
            Dim left = 20
            Dim right = e.Item.Width - 3
            Dim top = e.Item.Height \ 2
            top -= 1

            Using p As New Pen(MenuDark)
                e.Graphics.DrawLine(p, New Point(left, top), New Point(right, top))
            End Using

            Using p As New Pen(MenuLight)
                e.Graphics.DrawLine(p, New Point(left, top + 1), New Point(right, top + 1))
            End Using
        End If
    End Sub

    Public Function CreateRoundRectangle(ByVal rectangle As Rectangle, ByVal radius As Integer) As GraphicsPath
        Dim path As New GraphicsPath()

        Dim l As Integer = rectangle.Left
        Dim t As Integer = rectangle.Top
        Dim w As Integer = rectangle.Width
        Dim h As Integer = rectangle.Height
        Dim d As Integer = radius << 1

        path.AddArc(l, t, d, d, 180, 90)
        ' topleft
        path.AddLine(l + radius, t, l + w - radius, t)
        ' top
        path.AddArc(l + w - d, t, d, d, 270, 90)
        ' topright
        path.AddLine(l + w, t + radius, l + w, t + h - radius)
        ' right
        path.AddArc(l + w - d, t + h - d, d, d, 0, 90)
        ' bottomright
        path.AddLine(l + w - radius, t + h, l + radius, t + h)
        ' bottom
        path.AddArc(l, t + h - d, d, d, 90, 90)
        ' bottomleft
        path.AddLine(l, t + h - radius, l, t + radius)
        ' left
        path.CloseFigure()

        Return path
    End Function
End Class