PageRenderTime 43ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/Source Code/ExperimentalProjection/GDI/GdiProjector.vb

#
Visual Basic | 209 lines | 125 code | 64 blank | 20 comment | 1 complexity | f5c5fbb506d7381976e14fdb50df2dca MD5 | raw file
  1. Imports System.Drawing
  2. Imports System.Drawing.Imaging
  3. Public NotInheritable Class GdiProjector
  4. Inherits BaseProjector
  5. Private FControl As Control = Nothing
  6. Private Shared FMatrices As ImageAttributes() = PrecomputeMatrices()
  7. Private Shared Function PrecomputeMatrices() As ImageAttributes()
  8. Dim Result As New List(Of ImageAttributes)
  9. For Index As Integer = 0 To 255
  10. ' Create the next matrix
  11. Dim Values As Single()() = {New Single() {1, 0, 0, 0, 0}, _
  12. New Single() {0, 1, 0, 0, 0}, _
  13. New Single() {0, 0, 1, 0, 0}, _
  14. New Single() {0, 0, 0, Index / 255, 0}, _
  15. New Single() {0, 0, 0, 0, 1}}
  16. Dim Matrix As New ColorMatrix(Values)
  17. ' Add to the list of available alpha-blending matrices
  18. Dim Attributes As New ImageAttributes
  19. Attributes.SetColorMatrix(Matrix)
  20. Result.Add(Attributes)
  21. Next
  22. Return Result.ToArray
  23. End Function
  24. Friend Sub New(ByVal control As Control)
  25. FControl = control
  26. End Sub
  27. Private FCanvas As Bitmap = Nothing
  28. Private FCanvasGraphics As Graphics = Nothing
  29. Public Overrides Sub RenderFrame()
  30. ' Detect when the control has been resized
  31. If FCanvasGraphics IsNot Nothing AndAlso (FCanvas.Width <> FControl.Width OrElse FCanvas.Height <> FControl.Height) Then
  32. HandleControlResized()
  33. End If
  34. ' If we haven't already, create a context in which to draw on
  35. If FCanvas Is Nothing Then FCanvas = New Bitmap(FControl.Width, FControl.Height, PixelFormat.Format32bppPArgb)
  36. If FCanvasGraphics Is Nothing Then FCanvasGraphics = Graphics.FromImage(FCanvas)
  37. ' Render each of the projectlets onto a buffered canvas
  38. ' TODO: Resolve
  39. FCanvasGraphics.Clear(Color.DarkBlue)
  40. For Each Projectlet As GdiProjectlet In _Projectlets
  41. Dim ActualOpacity As Double = Projectlet.Opacity
  42. Dim Visible As Boolean = Projectlet.VisibleWhenNotFading
  43. ' Animate if an animation is defined
  44. Dim Animation As GdiProjectletAnimation = Projectlet.PeekNextAnimation
  45. If Animation IsNot Nothing Then
  46. If Animation.StartTick = 0 Then Animation.StartTick = Now.Ticks
  47. Visible = True
  48. Select Case Animation.AnimationType
  49. Case FadeEffect.FadeIn
  50. ActualOpacity = Animation.PercentageThrough * Projectlet.Opacity
  51. Case FadeEffect.FadeOut
  52. ActualOpacity = Projectlet.Opacity - (Animation.PercentageThrough * Projectlet.Opacity)
  53. End Select
  54. If Animation.IsFinished Then Projectlet.RemoveNextAnimation()
  55. End If
  56. ' Draw the projectlet image
  57. If Visible Then
  58. Dim X As Integer = FControl.Width * Projectlet.Area.Left
  59. Dim Y As Integer = FControl.Height * Projectlet.Area.Top
  60. Dim Width As Integer = FControl.Width * Projectlet.Area.Width
  61. Dim Height As Integer = FControl.Height * Projectlet.Area.Height
  62. FCanvasGraphics.DrawImage(Projectlet.Bitmap, _
  63. New Rectangle(X, Y, Width, Height), _
  64. 0, 0, Projectlet.Bitmap.Width, Projectlet.Bitmap.Height, _
  65. GraphicsUnit.Pixel, _
  66. FMatrices(CInt(ActualOpacity)))
  67. End If
  68. Next
  69. ' Draw the buffer image onto the assigned control
  70. FControl.CreateGraphics.DrawImageUnscaled(FCanvas, 0, 0)
  71. End Sub
  72. Public Overloads Overrides Sub ShowProjectlet(ByVal name As String)
  73. Dim Projectlet As GdiProjectlet = GetProjectlet(name)
  74. Projectlet.ClearAnimations()
  75. Projectlet.VisibleWhenNotFading = True
  76. End Sub
  77. Public Overloads Overrides Sub ShowProjectlet(ByVal name As String, _
  78. ByVal animationMethod As FadeEffect, _
  79. ByVal duration As System.TimeSpan)
  80. Dim Projectlet As GdiProjectlet = GetProjectlet(name)
  81. Projectlet.AddAnimation(New GdiProjectletAnimation(animationMethod, duration.Ticks))
  82. Projectlet.VisibleWhenNotFading = True
  83. End Sub
  84. Public Overloads Overrides Sub HideProjectlet(ByVal name As String)
  85. Dim Projectlet As GdiProjectlet = GetProjectlet(name)
  86. Projectlet.ClearAnimations()
  87. Projectlet.VisibleWhenNotFading = False
  88. End Sub
  89. Public Overloads Overrides Sub HideProjectlet(ByVal name As String, _
  90. ByVal animationMethod As FadeEffect, _
  91. ByVal duration As System.TimeSpan)
  92. Dim Projectlet As GdiProjectlet = GetProjectlet(name)
  93. Projectlet.AddAnimation(New GdiProjectletAnimation(animationMethod, duration.Ticks))
  94. Projectlet.VisibleWhenNotFading = False
  95. End Sub
  96. #Region " Methods for Creating and Updating Projectlets "
  97. Friend Overrides Function CreateProjectlet(ByVal details As ProjectletDetails) As BaseProjectlet
  98. ' Create the projectlet
  99. Dim Result As New GdiProjectlet(details.Name, details)
  100. UpdateProjectlet(Result)
  101. Return Result
  102. End Function
  103. Friend Overloads Overrides Function CreateProjectlet(ByVal name As String, _
  104. ByVal area As AgnosticRectangle, _
  105. ByVal bitmapImage As Object) As BaseProjectlet
  106. Dim Result As New GdiProjectlet(name)
  107. Result.Bitmap = bitmapImage
  108. ' TODO: Need to fix this - are you going to use integers or doubles? Also, need to include width and height
  109. Result.Area = New RectangleF(area.Left, area.Top, area.Width, area.Height)
  110. Return Result
  111. End Function
  112. Private Sub UpdateProjectlet(ByVal projectlet As GdiProjectlet)
  113. ' Are there details for us to be able to update the projectlet?
  114. If projectlet.Details IsNot Nothing Then
  115. ' Extract the details
  116. Dim Details As ProjectletDetails = projectlet.Details
  117. ' Define the area
  118. projectlet.Area = New RectangleF(Details.Area.Left, Details.Area.Top, Details.Area.Width, Details.Area.Height)
  119. ' Determine the actual font size to use
  120. Dim ActualFontSize As Double = Details.FontSizeRatio * FControl.Width
  121. ' Determine the actual font style to use
  122. Dim ActualFontStyle As FontStyle = FontStyle.Regular
  123. If (Details.FontStyle And AgnosticFontStyle.Bold) = AgnosticFontStyle.Bold Then ActualFontStyle += FontStyle.Bold
  124. If (Details.FontStyle And AgnosticFontStyle.Italic) = AgnosticFontStyle.Italic Then ActualFontStyle += FontStyle.Italic
  125. If (Details.FontStyle And AgnosticFontStyle.Underline) = AgnosticFontStyle.Underline Then ActualFontStyle += FontStyle.Underline
  126. ' Create the bitmap
  127. Dim ControlSize As New Size(FControl.Width, FControl.Height)
  128. Dim Font As New Font(Details.FontName, CInt(ActualFontSize), ActualFontStyle)
  129. projectlet.Bitmap = CreateTextBitmap(ControlSize, Font, Details.Effect, Color.Blue, Color.White, Details.Alignment, Details.Text)
  130. End If
  131. End Sub
  132. #End Region
  133. Private Sub HandleControlResized()
  134. ' Dispose the canvas
  135. FCanvas.Dispose()
  136. FCanvas = Nothing
  137. ' Dispose the canvas graphics
  138. FCanvasGraphics.Dispose()
  139. FCanvasGraphics = Nothing
  140. ' Recreate all the projectlet bitmaps
  141. For Each Projectlet As GdiProjectlet In _Projectlets
  142. UpdateProjectlet(Projectlet)
  143. Next
  144. End Sub
  145. End Class