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
| Option Strict On
Imports System.Drawing.Drawing2D
Public Class Form1
Private _FF As New FlipFlop(0.3!, 0.8!, 0.02!)
' Αυτή η κλαση αυξάνει ένα float από το min στο max
' και μετά πάλι πίσω με την τιμή του Step.
' TODO καλύτερα θα ήταν με generic class γιά να υποστηρίζει και άλλους τύπους.
Private Class FlipFlop
Private _Min, _Max, _Step, _Value As Single
Private _bInc As Boolean
Public Sub New(ByVal MinimumValue As Single, ByVal MaximumValue As Single, ByVal StepValue As Single)
Me._Min = MinimumValue
Me._Max = MaximumValue
Me._Step = StepValue
End Sub
Public Function GetValue() As Single
If Me._Value <= Me._Min Then
Me._bInc = True
ElseIf Me._Value >= Me._Max Then
Me._bInc = False
End If
If Me._bInc Then
Me._Value += Me._Step
Else
Me._Value -= Me._Step
End If
' Extra έλεγχοι γιά το Float
If Me._Value < Me._Min Then
Me._Value = Me._Min
ElseIf Me._Value > Me._Max Then
Me._Value = Me._Max
End If
Return Me._Value
End Function
End Class
' Timers γιά εφφεδάκια
Private WithEvents tmrChangeColor As New Timer
Private WithEvents tmrTitleBar As New Timer
Private m_Rounding As Integer = 14 ' >= του 14
Private m_Sigma As Single
Private m_Moveregion As Region = Nothing
Private m_FormColor As System.Drawing.Color = Color.FromArgb(255, 0, 0, 0)
Private m_X As Integer = 0 ' Mouse X
Private m_Y As Integer = 0 ' Mouse Y
Private Action As enmAction = enmAction.None
Private Enum enmAction
None
Move
ResizeWidth
ResizeHeight
End Enum
' πρέπει να βγάλω τα classes.
' TODO κακή διαχείριση μνήμης
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim iheight As Integer = 32
Dim PathTitleBar As New System.Drawing.Drawing2D.GraphicsPath
Dim PathClientArea As New System.Drawing.Drawing2D.GraphicsPath
Dim iMinColor As Integer = Math.Min(Math.Min(255 - m_FormColor.R, 255 - m_FormColor.G), 255 - m_FormColor.B)
Dim br As New LinearGradientBrush(New System.Drawing.PointF(0, 0),
New System.Drawing.PointF(0, iheight),
m_FormColor,
Color.FromArgb(m_FormColor.R + iMinColor,
m_FormColor.G + iMinColor,
m_FormColor.B + iMinColor)
)
' ---------------------------------------------------------
' BEGIN Title Bar
' Top Left Arc
PathTitleBar.AddArc(0, 0,
m_Rounding, m_Rounding,
180, 90)
' Top Right Arc
PathTitleBar.AddArc(Me.ClientSize.Width - 1 - m_Rounding, 0,
m_Rounding, m_Rounding,
270, 90)
' Bottom Line
PathTitleBar.AddLine(Me.ClientSize.Width - 1, iheight,
0, iheight)
' Κλείνωντας το Figure, το path βαζει τις γραμμές αυτόματα.
PathTitleBar.CloseFigure()
' END Title Bar
' ---------------------------------------------------------
' ---------------------------------------------------------
' BEGIN Client Area
PathClientArea.AddArc(0, 0,
m_Rounding, m_Rounding,
180, 90)
PathClientArea.AddArc(Me.ClientSize.Width - 1 - m_Rounding, 0,
m_Rounding, m_Rounding,
270, 90)
PathClientArea.AddArc(Me.ClientSize.Width - 1 - m_Rounding, Me.ClientSize.Height - 1 - m_Rounding,
m_Rounding, m_Rounding,
0, 90)
PathClientArea.AddArc(0, Me.ClientSize.Height - 1 - m_Rounding,
m_Rounding, m_Rounding,
90, 90)
PathClientArea.CloseFigure()
' END Client Area
' ---------------------------------------------------------
m_Moveregion = New Region(PathTitleBar)
''br.SetBlendTriangularShape(m_Sigma)
br.SetSigmaBellShape(m_Sigma)
' Γέμισε το Client Area με άσπρο
e.Graphics.FillPath(Brushes.White, PathClientArea)
' Ζωγράφισε την Title Bar
e.Graphics.FillPath(br, PathTitleBar)
' Φτιάξε ένα μαύρο περίγραμμα που να τα σκεπάζει όλα
e.Graphics.DrawPath(Pens.Black, PathClientArea)
' Μία extra γραμμή κάτω από το Title Bar.
e.Graphics.DrawLine(Pens.Black, Me.ClientSize.Width - 1, iheight, 0, iheight)
' 3D κόλπο. TODO να βγάλω Class.
Dim fnt As New Font("Arial", 12, FontStyle.Bold)
e.Graphics.DrawString(Me.Text, fnt, Brushes.Black, m_Rounding \ 2, (iheight \ 2) - fnt.Height \ 2)
e.Graphics.DrawString(Me.Text, fnt, Brushes.White, m_Rounding \ 2 - 2, (iheight \ 2) - fnt.Height \ 2 - 2)
MyBase.OnPaint(e)
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
If e.X > Me.ClientSize.Width - 5 Then
Action = enmAction.ResizeWidth
ElseIf e.Y > Me.ClientSize.Height - 1 - 5 Then
Action = enmAction.ResizeHeight
ElseIf m_Moveregion.IsVisible(e.X, e.Y) Then
' Αν ο το mouse είναι μέσα στο path με left Click
' τότε ο χρήστης προφανώς θέλει να μετακινήσει την φόρμα.
Me.Action = enmAction.Move
m_X = e.X
m_Y = e.Y
End If
End If
MyBase.OnMouseDown(e)
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
Select Case Action
Case enmAction.None
If e.X > Me.ClientSize.Width - 5 Then
Me.Cursor = Cursors.SizeWE
ElseIf e.Y > Me.ClientSize.Height - 5 Then
Me.Cursor = Cursors.SizeNS
Else
Me.Cursor = Cursors.Default
End If
Case enmAction.Move
Me.Left += e.X - m_X
Me.Top += e.Y - m_Y
Case enmAction.ResizeWidth
Me.Width = e.X
Case enmAction.ResizeHeight
Me.Height = e.Y
End Select
MyBase.OnMouseMove(e)
End Sub
Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
Me.Action = enmAction.None
MyBase.OnMouseUp(e)
End Sub
Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
Me.Invalidate()
MyBase.OnSizeChanged(e)
End Sub
Public Sub New()
InitializeComponent()
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.Text = "Τίτλος"
Me.MinimumSize = New Size(100, 32)
Me.DoubleBuffered = True
Me.BackColor = Color.Magenta
Me.TransparencyKey = Color.Magenta
Me.m_Sigma = Me._FF.GetValue()
Randomize()
AddHandler tmrTitleBar.Tick, AddressOf OnTick
tmrTitleBar.Enabled = True
tmrTitleBar.Interval = 100
AddHandler tmrChangeColor.Tick, AddressOf tmrChangeColor_Tick
tmrChangeColor.Enabled = True
tmrChangeColor.Interval = 2000
End Sub
Private Sub OnTick(ByVal sender As Object, ByVal e As System.EventArgs)
m_Sigma = Me._FF.GetValue
Me.Invalidate(m_Moveregion)
End Sub
Private Sub tmrChangeColor_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim Generated(2) As Integer
For i As Integer = 0 To 2
Generated(i) = CInt(Int((128 * Rnd()) + 0))
Next
m_FormColor = Color.FromArgb(Generated(0), Generated(1), Generated(2))
Me.Invalidate(m_Moveregion)
End Sub
End Class |