Implement Overtime Guard workflow and localization

This commit is contained in:
2026-06-16 18:51:42 +02:00
parent 9142b3695e
commit 912a2deeaf
34 changed files with 4821 additions and 2444 deletions

View File

@@ -12,7 +12,7 @@ Sub Class_Globals
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
Private segments As List ' Segmenti cronologici registrati
' Parametri di spessore
Private quadrantStrokeWidth As Float = 5dip
@@ -21,40 +21,64 @@ Sub Class_Globals
Private intervalArcStrokeWidth As Float = 5dip
Private hourHandStrokeWidth As Float = 8dip
Private minuteHandStrokeWidth As Float = 5dip
Private intervals As List
Private baseDurationMs As Long
Private activeDurationMs As Long
Private activeColor As Int
Private activeIsPause As Boolean
Private hasActiveSegment As Boolean
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)
segments.Initialize
baseDurationMs = 12 * DateTime.TicksPerHour
SetClockSize(PercentageOfWidth)
End Sub
' Imposta la durata piena del quadrante. Le pause gialle vengono aggiunte a parte.
Public Sub SetBaseDuration(DurationMs As Long)
baseDurationMs = DurationMs
DrawClock
End Sub
' Rimuove tutti i segmenti registrati.
Public Sub ClearSegments
If segments.IsInitialized = False Then segments.Initialize
segments.Clear
hasActiveSegment = False
activeDurationMs = 0
DrawClock
End Sub
' Aggiunge un segmento concluso.
Public Sub AddSegment(DurationMs As Long, SegmentColor As Int, IsPause As Boolean)
If DurationMs <= 0 Then Return
Dim segment As Map
segment.Initialize
segment.Put("duration", DurationMs)
segment.Put("color", SegmentColor)
segment.Put("pause", IsPause)
segments.Add(segment)
DrawClock
End Sub
' Imposta il segmento in corso, non ancora concluso.
Public Sub SetActiveSegment(DurationMs As Long, SegmentColor As Int, IsPause As Boolean)
activeDurationMs = Max(0, DurationMs)
activeColor = SegmentColor
activeIsPause = IsPause
hasActiveSegment = activeDurationMs > 0
DrawClock
End Sub
Public Sub ClearActiveSegment
hasActiveSegment = False
activeDurationMs = 0
DrawClock
End Sub
' Imposta la dimensione dell'orologio come percentuale della larghezza del pannello
Public Sub SetClockSize(PercentageOfWidth As Float)
clockDiameter = pnlClock.Width * PercentageOfWidth / 100
@@ -90,14 +114,12 @@ Public Sub DrawClock
' Disegna il cerchio esterno
cvsClock.DrawCircle(centerX, centerY, clockDiameter / 2, Colors.Black, False, quadrantStrokeWidth)
' Disegna i segmenti di lavoro / pausa / straordinario
DrawSegments
' 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
@@ -120,6 +142,51 @@ Public Sub DrawClock
pnlClock.Invalidate
End Sub
Private Sub DrawSegments
If segments.IsInitialized = False Then Return
Dim totalPauseMs As Long = 0
Dim totalRecordedMs As Long = 0
For Each segment As Map In segments
Dim duration As Long = segment.Get("duration")
totalRecordedMs = totalRecordedMs + duration
If segment.Get("pause") = True Then totalPauseMs = totalPauseMs + duration
Next
If hasActiveSegment Then
totalRecordedMs = totalRecordedMs + activeDurationMs
If activeIsPause Then totalPauseMs = totalPauseMs + activeDurationMs
End If
Dim totalDisplayMs As Long = Max(baseDurationMs, totalRecordedMs)
If totalDisplayMs <= 0 Then Return
Dim startAngle As Float = -90
Dim radius As Float = clockDiameter / 2 - 22dip
For Each segment As Map In segments
Dim sweepAngle As Float = 360 * segment.Get("duration") / totalDisplayMs
DrawPieSegment(startAngle, sweepAngle, segment.Get("color"), radius)
startAngle = startAngle + sweepAngle
Next
If hasActiveSegment Then
Dim activeSweepAngle As Float = 360 * activeDurationMs / totalDisplayMs
DrawPieSegment(startAngle, activeSweepAngle, activeColor, radius)
End If
End Sub
Private Sub DrawPieSegment(startAngle As Float, sweepAngle As Float, color As Int, radius As Float)
If sweepAngle <= 0 Then Return
Dim steps As Int = Max(2, Ceil(sweepAngle / 4))
Dim path As B4XPath
path.Initialize(centerX, centerY)
For i = 0 To steps
Dim angle As Float = startAngle + sweepAngle * i / steps
Dim x As Float = centerX + radius * CosD(angle)
Dim y As Float = centerY + radius * SinD(angle)
path.LineTo(x, y)
Next
path.LineTo(centerX, centerY)
cvsClock.DrawPath(path, color, True, 0)
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)
@@ -152,43 +219,6 @@ Private Sub DrawTicks
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