aboutsummaryrefslogtreecommitdiff
path: root/ShiftOS/ProgressBarEX.vb
blob: 6bf1c1b53271cef27aa92396660f02a6e6d17403 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
Public Class ProgressBarEX

#Region " Properties "

    Private _Value As Integer = 0
    Public Property Value() As Integer
        Get
            Return _Value
        End Get
        Set(ByVal value As Integer)
            If value >= Me.MinValue And value <= Me.MaxValue Then
                _Value = value
                Me.Invalidate()
            Else
                Throw New ArgumentOutOfRangeException("The value must be between the minimum and maximum values.")
            End If
        End Set
    End Property

    Private _Step As Integer = 10
    Public Property [Step]() As Integer
        Get
            Return _Step
        End Get
        Set(ByVal value As Integer)
            _Step = value
        End Set
    End Property

    Private _Orientation As ProgressBarOrientation
    Public Property Orientation() As ProgressBarOrientation
        Get
            Return _Orientation
        End Get
        Set(ByVal value As ProgressBarOrientation)
            _Orientation = value
        End Set
    End Property

    Private _MinValue As Integer = 0
    Public Property MinValue() As Integer
        Get
            Return _MinValue
        End Get
        Set(ByVal value As Integer)
            If value < Me.MaxValue Then
                _MinValue = value
            Else
                Throw New ArgumentOutOfRangeException("The minimum value must be less than the maximum value.")
            End If
        End Set
    End Property

    Private _MaxValue As Integer = 100
    Public Property MaxValue() As Integer
        Get
            Return _MaxValue
        End Get
        Set(ByVal value As Integer)
            If value > Me.MinValue Then
                _MaxValue = value
            Else
                Throw New ArgumentOutOfRangeException("The maximum value must be more than the minimum value.")
            End If
        End Set
    End Property

    Private _Color As Color = Color.Lime
    Public Property Color() As Color
        Get
            Return _Color
        End Get
        Set(ByVal value As Color)
            _Color = value
        End Set
    End Property

    Private _ShowValue As Boolean = True
    Public Property ShowValue() As Boolean
        Get
            Return _ShowValue
        End Get
        Set(ByVal value As Boolean)
            _ShowValue = value
        End Set
    End Property

    Private _Style As ProgressBarExStyle
    Public Property Style() As ProgressBarExStyle
        Get
            Return _Style
        End Get
        Set(ByVal value As ProgressBarExStyle)
            _Style = value
        End Set
    End Property

    Private _BlockWidth As Integer = 5
    Public Property BlockWidth() As Integer
        Get
            Return _BlockWidth
        End Get
        Set(ByVal value As Integer)
            _BlockWidth = value
        End Set
    End Property

    Private _BlockSeparation As Integer = 3
    Public Property BlockSeparation() As Integer
        Get
            Return _BlockSeparation
        End Get
        Set(ByVal value As Integer)
            _BlockSeparation = value
        End Set
    End Property

#End Region

#Region " Enums, Variables "

    Public Enum ProgressBarOrientation
        Horizontal = 0
        Vertical = 1
    End Enum

    Public Enum ProgressBarExStyle
        Blocks = 0
        Continuous = 1
        Marquee = 2
    End Enum

#End Region

#Region " Events "

    Public Event PaintBackground(ByVal sender As Object, ByVal e As PaintEventArgs)
    Public Event PaintProcess(ByVal sender As Object, ByVal e As ProgressBarProcessPaintEventArgs)

    Public Class ProgressBarProcessPaintEventArgs
        Inherits EventArgs

        Public Sub New(ByVal bounds As Rectangle, ByVal g As Graphics, Optional ByVal blocks() As Rectangle = Nothing)
            _Bounds = bounds
            _Graphics = g
            If blocks Is Nothing Then
                _Blocks = New Rectangle() {}
            Else
                _Blocks = blocks
            End If
        End Sub

        Private _Bounds As Rectangle
        Public ReadOnly Property Bounds() As Rectangle
            Get
                Return _Bounds
            End Get
        End Property

        Private _Blocks As Rectangle()
        Public ReadOnly Property Blocks() As Rectangle()
            Get
                Return _Blocks
            End Get
        End Property

        Private _Graphics As Graphics
        Public ReadOnly Property Graphics() As Graphics
            Get
                Return _Graphics
            End Get
        End Property

    End Class

#End Region

#Region " Methods "

    Public Sub PerformStep()
        If Me.Step > 0 Then
            Me.Value = Math.Min(Me.Value + Me.Step, Me.MaxValue)
        Else
            Me.Value = Math.Max(Me.Value + Me.Step, Me.MinValue)
        End If
    End Sub

    Public Sub Increment(ByVal value As Integer)
        If value > 0 Then
            Me.Value = Math.Min(Me.Value + value, Me.MaxValue)
        Else
            Me.Value = Math.Max(Me.Value + value, Me.MinValue)
        End If
    End Sub

#End Region

#Region " Process Logic "

    Private Function GetProcessRect() As Rectangle
        Dim w As Integer = Me.Width
        Dim h As Integer = Me.Height
        Dim valRel As Integer = GetRelativeValue()
        Return New Rectangle(0, 0, w * valRel \ 100, h)
    End Function

    Private Function GetBlocks() As Rectangle()
        Dim b As New List(Of Rectangle)

        Dim w As Integer = Me.BlockWidth
        Dim h As Integer = Me.Height
        Dim r As Rectangle

        Dim x As Integer = 0
        Dim stopX As Integer = CInt((GetRelativeValue() / 100) * Me.Width)
        While (x + w <= stopX)
            r = New Rectangle(x, 0, w, h)
            b.Add(r)

            x += Me.BlockWidth + Me.BlockSeparation
        End While

        Return b.ToArray
    End Function

    Private Function GetRelativeValue() As Integer
        Return CInt(100 * Me.Value / (Me.MaxValue - Me.MinValue))
    End Function

#End Region

#Region " Drawing "

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        DoPaintBackground(e.Graphics)
        DoPaintProcess(e.Graphics)
        If Me.ShowValue Then DoPaintValue(e.Graphics)
    End Sub

    Private Sub DoPaintBackground(ByVal g As Graphics)
        RaiseEvent PaintBackground(Me, New PaintEventArgs(g, Me.ClientRectangle))
    End Sub

    Private Sub DoPaintProcess(ByVal g As Graphics)
        Dim rect As Rectangle = GetProcessRect()
        Dim blocks() As Rectangle = GetBlocks()
        Using brush As New SolidBrush(Me.Color)
            If Me.Style = ProgressBarExStyle.Continuous Then
                g.FillRectangle(brush, rect)
            ElseIf Me.Style = ProgressBarExStyle.Blocks Then
                For Each b As Rectangle In blocks
                    g.FillRectangle(brush, b)
                Next
            End If
        End Using

        Dim e As New ProgressBarProcessPaintEventArgs(rect, g, blocks)
        RaiseEvent PaintProcess(Me, e)
    End Sub

    Private Sub DoPaintValue(ByVal g As Graphics)
        Dim valStr As String = GetRelativeValue.ToString & "&#37;"
        Dim sf As New StringFormat()
        sf.Alignment = StringAlignment.Center
        Dim s As SizeF = g.MeasureString(valStr, Me.Font)

        g.DrawString(valStr, Me.Font, New SolidBrush(Me.ForeColor), (Me.Width - s.Width) / 2, (Me.Height - s.Height) / 2)
    End Sub

#End Region

End Class