'//----------------------------------------------------------------------
'//【デジタルLED表示・コントロール】- NumericLabel
'//
'//
'//                                                       by Masato Hirai         
'//----------------------------------------------------------------------
Imports System
Imports System.Drawing
Imports System.Drawing.Text
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Imports System.Windows.Forms
Imports System.ComponentModel

<ToolboxBitmap(GetType(NumericLabel), "NumericLabelToolbox.bmp")> _
Public Class NumericLabel : Inherits Label
  '//
  '//
  '//
  Private WithEvents Timer1 As New Timer
  Private Const LED_W As Integer = 55
  Private Const LED_H As Integer = 98
  Private Const RM As Integer = 10
  Private bx As Integer = SystemInformation.Border3DSize.Width
  Private by As Integer = SystemInformation.Border3DSize.Height
  Private _ZOOM As ZoomModes = ZoomModes.Normal
  Private LEDBase As Image
  Private LED As Image
  Private zm As Double = 1.0
  Private fp As Integer = 6
  Private col As Color = Color.DimGray
  Private cm() As Imaging.ColorMap _
    = {New ColorMap, New ColorMap, New ColorMap}
  Private att As New ImageAttributes
  Private num As Integer = 0
  Private endTime As Integer = 0

  Public Enum ZoomModes
    Normal = 1
    Large = 2
    Small = 3
    Mini = 4
    SuperMini = 5
  End Enum
  '//
  '// コンストラクタ
  '//
  Public Sub New()
    MyBase.New()
    LEDBase = New Bitmap(GetType(NumericLabel), "NumberPale.bmp")
    LED = New Bitmap(LEDBase.Width, LEDBase.Height)
    cm(0).OldColor = Color.White
    cm(0).NewColor = Color.White
    cm(1).OldColor = Color.Black
    cm(1).NewColor = Color.Black
    cm(2).OldColor = Color.FromArgb(64, 64, 64)
    cm(2).NewColor = Color.DimGray
    att.SetRemapTable(cm)
    Me.BackColor = Color.Black
    Me.ForeColor = Color.White
    Me.SetStyle(ControlStyles.ResizeRedraw _
             Or ControlStyles.Opaque _
             Or ControlStyles.AllPaintingInWmPaint _
             Or ControlStyles.UserPaint _
             Or ControlStyles.DoubleBuffer, True)
    AdjustSize()
    Dim g As Graphics = Graphics.FromImage(LED)
    g.DrawImage(LEDBase, New Rectangle(0, 0, LED.Width, LED.Height), 0, 0, LEDBase.Width, LEDBase.Height, GraphicsUnit.Pixel, att)
    g.Dispose()
  End Sub
  '//
  '// Dispose
  '//
  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
      If Not (LED Is Nothing) Then LED.Dispose()
      If Not (LEDBase Is Nothing) Then LEDBase.Dispose()
    End If
    MyBase.Dispose(disposing)
  End Sub
  '//
  '// ZoomMode プロパティ
  '//
  <Browsable(True), DefaultValue(ZoomModes.Normal)> _
  Public Property ZoomMode() As ZoomModes
    Get
      Return _ZOOM
    End Get
    Set(ByVal Value As ZoomModes)
      _ZOOM = Value
      Select Case _ZOOM
        Case ZoomModes.Large
          zm = 1.2
        Case ZoomModes.Normal
          zm = 1.0
        Case ZoomModes.Small
          zm = 0.8
        Case ZoomModes.Mini
          zm = 0.5
        Case ZoomModes.SuperMini
          zm = 0.33
      End Select
      AdjustSize()
    End Set
  End Property
  '//
  '// UpperPoint プロパティ
  '//
  <Browsable(True), DefaultValue(6)> _
  Public Property UpperPoint() As Integer
    Get
      Return fp
    End Get
    Set(ByVal Value As Integer)
      If Value < 1 Then
        Throw New Exception("1以上です")
      End If
      fp = Value
      AdjustSize()
    End Set
  End Property
  '//
  '// Value プロパティ
  '//
  <Browsable(True), DefaultValue(0)> _
  Public Property Value() As Integer
    Get
      Return num
    End Get
    Set(ByVal V As Integer)
      num = V
      Me.Invalidate()
    End Set
  End Property
  '//
  '// OnPaint イベント
  '//
  Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    '背景の描画
    MyBase.OnPaintBackground(e)
    '3Dボーダーラインの描画
    ControlPaint.DrawBorder3D(e.Graphics, Me.ClientRectangle)
    '表示用の文字列
    Dim moji As String
    If Me.Enabled Then
      moji = num.ToString("0").PadLeft(fp)
    Else
      moji = New String(" ", fp)
    End If
    'LEDの描画
    For k As Integer = 1 To fp
      Dim v As String = moji.Substring(k - 1, 1)
      Dim n As Integer = 10
      Select Case v
        Case "0" To "9"
          n = Integer.Parse(v)
      End Select
      e.Graphics.DrawImage(LED, _
        New Rectangle(((RM + LED_W) * (k - 1) + RM) * zm + bx, RM * zm + by, LED_W * zm, LED_H * zm), _
        New Rectangle(n * LED_W, 0, LED_W, LED_H), GraphicsUnit.Pixel)
    Next
  End Sub
  '//
  '// OnResize イベント
  '//
  Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
    MyBase.OnResize(e)
    AdjustSize()
  End Sub
  '//
  '// 汎用関数
  '//
  Private Sub AdjustSize()
    Me.Size = New Size( _
      ((LED_W + RM) * fp + RM) * zm + bx * 2, _
      (LED_H + RM * 2) * zm + by * 2)
  End Sub
  '//
  '// OnEnabledChanged イベント
  '//
  Protected Overrides Sub OnEnabledChanged(ByVal e As System.EventArgs)
    MyBase.OnEnabledChanged(e)
    Me.Invalidate()
  End Sub
  '//
  '// OnForeColorChanged イベント
  '//
  Protected Overrides Sub OnForeColorChanged(ByVal e As System.EventArgs)
    MyBase.OnForeColorChanged(e)
    cm(0).OldColor = Color.White
    cm(0).NewColor = Me.ForeColor
    att.SetRemapTable(cm)
    Dim g As Graphics = Graphics.FromImage(LED)
    g.DrawImage(LEDBase, _
      New Rectangle(0, 0, LED.Width, LED.Height), _
      0, 0, LEDBase.Width, LEDBase.Height, _
      GraphicsUnit.Pixel, att)
    g.Dispose()
    Me.Invalidate()
  End Sub
  '//
  '// OnBackColorChanged イベント
  '//
  Protected Overrides Sub OnBackColorChanged(ByVal e As System.EventArgs)
    MyBase.OnBackColorChanged(e)
    cm(1).OldColor = Color.Black
    cm(1).NewColor = Me.BackColor
    att.SetRemapTable(cm)
    Dim g As Graphics = Graphics.FromImage(LED)
    g.DrawImage(LEDBase, _
      New Rectangle(0, 0, LED.Width, LED.Height), _
      0, 0, LEDBase.Width, LEDBase.Height, _
      GraphicsUnit.Pixel, att)
    g.Dispose()
    Me.Invalidate()
  End Sub
  '//
  '// MiddleColor プロパティ
  '//
  <Browsable(True), DefaultValue(GetType(Color), "DimGray")> _
  Public Property MiddleColor() As Color
    Get
      Return col
    End Get
    Set(ByVal Value As Color)
      col = Value
      cm(2).OldColor = Color.FromArgb(64, 64, 64)
      cm(2).NewColor = col
      att.SetRemapTable(cm)
      Dim g As Graphics = Graphics.FromImage(LED)
      g.DrawImage(LEDBase, _
        New Rectangle(0, 0, LED.Width, LED.Height), _
        0, 0, LEDBase.Width, LEDBase.Height, _
        GraphicsUnit.Pixel, att)
      g.Dispose()
      Me.Invalidate()
    End Set
  End Property
  '//
  '// Flush メソッド
  '//
  Public Sub Flush(ByVal brink As Integer, ByVal duration As Integer)
    Timer1.Interval = brink
    endTime = Environment.TickCount + duration
    Timer1.Enabled = True
    Me.Enabled = True
    Me.Invalidate()
  End Sub
  '//
  '// Timer_Tickイベント
  '//
  Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    If endTime < Environment.TickCount Then
      Timer1.Enabled = False
      Me.Enabled = True
      Return
    End If
    Me.Enabled = Not Me.Enabled
  End Sub

End Class

