Files
overtime-guard/AnalogClock.bas
2024-12-28 13:09:34 +01:00

204 lines
7.3 KiB
QBasic

B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=13
@EndOfDesignText@
Sub Class_Globals
Private xui As XUI
Private pnlClock As Panel ' Pannello in cui disegnare l'orologio
Private cvsClock As B4XCanvas ' Canvas per disegnare l'orologio
Private clockDiameter As Float ' Diametro dell'orologio (in pixel)
Private centerX As Float ' Coordinata X del centro dell'orologio
Private centerY As Float ' Coordinata Y del centro dell'orologio
Private intervals As List ' Lista degli intervalli da disegnare
' Parametri di spessore
Private quadrantStrokeWidth As Float = 5dip
Private hourTickStrokeWidth As Float = 5dip
Private minuteTickStrokeWidth As Float = 2dip
Private intervalArcStrokeWidth As Float = 5dip
Private hourHandStrokeWidth As Float = 8dip
Private minuteHandStrokeWidth As Float = 5dip
Private intervals As List
End Sub
' Inizializza l'orologio
Public Sub Initialize(ParentPanel As Panel, PercentageOfWidth As Float)
pnlClock = ParentPanel
cvsClock.Initialize(pnlClock)
intervals.Initialize
Dim interval As Map
interval.Initialize
interval.Put("startHour", 8)
interval.Put("startMinute", 0)
interval.Put("endHour", 12)
interval.Put("endMinute", 0)
interval.Put("color", Colors.Magenta)
interval.Put("radius",(clockDiameter/2 +25dip))
interval.Put("strokeWidth", 5dip)
interval.Put("period", "mattino")
intervals.Add(interval)
interval.Initialize
interval.Put("startHour", 13)
interval.Put("startMinute", 0)
interval.Put("endHour", 17)
interval.Put("endMinute", 0)
interval.Put("color", Colors.Green)
interval.Put("radius", (clockDiameter/2 )+25dip)
interval.Put("strokeWidth", 5dip)
interval.Put("period", "pomeriggio")
intervals.Add(interval)
SetClockSize(PercentageOfWidth)
End Sub
' Imposta la dimensione dell'orologio come percentuale della larghezza del pannello
Public Sub SetClockSize(PercentageOfWidth As Float)
clockDiameter = pnlClock.Width * PercentageOfWidth / 100
centerX = pnlClock.Width / 2
centerY = pnlClock.Height / 2
DrawClock
End Sub
' Imposta lo spessore delle varie linee
Public Sub SetStrokeWidths(quadrantWidth As Float, hourTickWidth As Float, minuteTickWidth As Float, intervalArcWidth As Float, hourHandWidth As Float, minuteHandWidth As Float)
quadrantStrokeWidth = quadrantWidth
hourTickStrokeWidth = hourTickWidth
minuteTickStrokeWidth = minuteTickWidth
intervalArcStrokeWidth = intervalArcWidth
hourHandStrokeWidth = hourHandWidth
minuteHandStrokeWidth = minuteHandWidth
DrawClock
End Sub
' Cancella il canvas riempiendolo con un colore specifico
Private Sub ClearCanvas(color As Int)
cvsClock.DrawRect(cvsClock.TargetRect, color, True, 0)
cvsClock.Invalidate
End Sub
' Disegna l'orologio
Public Sub DrawClock
cvsClock.Initialize(pnlClock)
' Cancella il canvas
ClearCanvas(Colors.White)
' Disegna il cerchio esterno
cvsClock.DrawCircle(centerX, centerY, clockDiameter / 2, Colors.Black, False, quadrantStrokeWidth)
' Disegna le tacche delle ore e dei minuti
DrawTicks
' Disegna gli intervalli
For Each interval As Map In intervals
DrawInterval(interval.Get("startHour"), interval.Get("startMinute"), interval.Get("endHour"), interval.Get("endMinute"), interval.Get("color"), interval.Get("radius"), interval.Get("strokeWidth"))
Next
' Disegna le lancette
Dim now As Long = DateTime.Now
Dim Hours As Int = DateTime.GetHour(now) Mod 12
Dim Minutes As Int = DateTime.GetMinute(now)
Dim Seconds As Int = DateTime.GetSecond(now)
' Lancetta ore
Dim HourAngle As Float = -90 + Hours * 30 + Minutes / 2
DrawHand(centerX, centerY, clockDiameter * 0.25, HourAngle, hourHandStrokeWidth, Colors.Black)
' Lancetta minuti
Dim MinuteAngle As Float = -90 + Minutes * 6
DrawHand(centerX, centerY, clockDiameter * 0.4, MinuteAngle, minuteHandStrokeWidth, Colors.Blue)
' Lancetta secondi
Dim SecondAngle As Float = -90 + Seconds * 6
DrawHand(centerX, centerY, clockDiameter * 0.45, SecondAngle, 2dip, Colors.Red)
' Aggiorna il pannello
pnlClock.Invalidate
End Sub
' Disegna una singola lancetta
Private Sub DrawHand(x As Float, y As Float, length As Float, angle As Float, width As Float, color As Int)
Dim endX As Float = x + length * CosD(angle)
Dim endY As Float = y + length * SinD(angle)
cvsClock.DrawLine(x, y, endX, endY, color, width)
End Sub
' Disegna le tacche delle ore e dei minuti
Private Sub DrawTicks
For i = 0 To 59
Dim angle As Float = -90 + i * 6
Dim startX As Float
Dim startY As Float
Dim endX As Float
Dim endY As Float
If i Mod 5 = 0 Then
' Tacca delle ore
startX = centerX + (clockDiameter / 2 - 20dip) * CosD(angle)
startY = centerY + (clockDiameter / 2 - 20dip) * SinD(angle)
endX = centerX + (clockDiameter / 2 - 5dip) * CosD(angle)
endY = centerY + (clockDiameter / 2 - 5dip) * SinD(angle)
cvsClock.DrawLine(startX, startY, endX, endY, Colors.Black, hourTickStrokeWidth)
Else
' Tacca dei minuti
startX = centerX + (clockDiameter / 2 - 10dip) * CosD(angle)
startY = centerY + (clockDiameter / 2 - 10dip) * SinD(angle)
endX = centerX + (clockDiameter / 2 - 5dip) * CosD(angle)
endY = centerY + (clockDiameter / 2 - 5dip) * SinD(angle)
cvsClock.DrawLine(startX, startY, endX, endY, Colors.Black, minuteTickStrokeWidth)
End If
Next
End Sub
' Aggiunge un intervallo da disegnare
Public Sub AddInterval(startHour As Int, startMinute As Int, endHour As Int, endMinute As Int, tipo As String)
Dim interval As Map
interval.Initialize
interval.Put("startHour", startHour)
interval.Put("startMinute", startMinute)
interval.Put("endHour", endHour)
interval.Put("endMinute", endMinute)
Select tipo.ToLowerCase
Case "mattino"
interval.Put("color", Colors.Blue)
interval.Put("radius", clockDiameter / 2 - 15dip)
interval.Put("strokeWidth", intervalArcStrokeWidth)
Case "pomeriggio"
interval.Put("color", Colors.Green)
interval.Put("radius", clockDiameter / 2 - 25dip)
interval.Put("strokeWidth", intervalArcStrokeWidth)
Case Else
Log("Tipo di intervallo non riconosciuto: " & tipo)
Return
End Select
intervals.Add(interval)
DrawClock
End Sub
' Disegna un intervallo sul quadrante
Private Sub DrawInterval(startHour As Int, startMinute As Int, endHour As Int, endMinute As Int, color As Int, radius As Float, strokeWidth As Float)
Dim startAngle As Float = (startHour Mod 12 + startMinute / 60) * 30 - 90
Dim endAngle As Float = (endHour Mod 12 + endMinute / 60) * 30 - 90
Dim sweepAngle As Float = endAngle - startAngle
If sweepAngle < 0 Then sweepAngle = sweepAngle + 360
Dim path As B4XPath
path.InitializeArc(centerX, centerY, radius, startAngle, sweepAngle)
cvsClock.DrawPath(path, color, False, strokeWidth)
End Sub
' Aggiorna l'orologio ogni secondo
Public Sub StartClock
Dim timer As Timer
timer.Initialize("timer", 1000)
timer.Enabled = True
End Sub
' Evento del timer per aggiornare l'orologio
Private Sub timer_Tick
DrawClock
End Sub