Microsoft Small Basic

Program Listing: BSP033-4
' World Clock
' Copyright © 2014-2015 Nonki Takahashi. The MIT License.
' Version: 0.5b
' Last update: 2015-02-02
' Program ID: BSP033-4
'
GraphicsWindow.Title = "World Clock 0.5b"
Form()
iCity = ""
Timer.Interval = 500
Timer.Tick = OnTick
Sub Form
bc = "#000000"
colorMorning = "#CCCCCC"
colorDay = "#EEEEEE"
colorNight = "#666666"
colorMidNight = "#333333"
colorHourHand = "#FF9900"
colorText = "#FFFFFF"
gw = 598
gh = 428
gap = 6
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.BackgroundColor = bc
City_Select()
deltaLocal = city[cityLocal]["local"]
GraphicsWindow.FontName = "Trebuchet MS"
width = Math.Floor((gw - 110) / 24)
height = Math.Floor((gh - 60) / nCity)
For i = 1 To nCity
x = 10
y = 50 + (i - 1) * height
GraphicsWindow.BrushColor = colorText
GraphicsWindow.DrawText(x, y + height / 2 - gap, index[i])
x = 100
hourLocal = city[index[i]]["local"] * 1
If hourLocal < 0 Then
hourLocal = hourLocal + 24
EndIf
If 0 < hourLocal - Math.Floor(hourLocal) Then
half = "True"
Else
half = "False"
EndIf
For hourUTC = 0 To 23
hour = hourLocal
SetBandColor()
If (hourUTC = 0) And half Then
GraphicsWindow.FillRectangle(x, y + gap, width / 2 - 1, height - gap * 2)
hour = hourLocal + 0.5
SetBandColor()
GraphicsWindow.FillRectangle(x + width / 2, y + gap, width - 1, height - gap * 2)
ElseIf (hourUTC = 23) And half Then
hour = hourLocal + 0.5
SetBandColor()
GraphicsWindow.FillRectangle(x + width / 2, y + gap, width / 2 - 1, height - gap * 2)
ElseIf half Then
hour = hourLocal + 0.5
SetBandColor()
GraphicsWindow.FillRectangle(x + width / 2, y + gap, width - 1, height - gap * 2)
Else
GraphicsWindow.FillRectangle(x, y + gap, width - 1, height - gap * 2)
EndIf
If half Then
hour = hourLocal + 0.5
SetHourColor()
GraphicsWindow.DrawText(x + width / 2, y + 10, Math.Floor(hour))
Else
hour = hourLocal
SetHourColor()
GraphicsWindow.DrawText(x, y + 10, hourLocal)
EndIf
x = x + width
hourLocal = hourLocal + 1
If 24 <= hourLocal Then
hourLocal = hourLocal - 24
EndIf
EndFor
EndFor
y = 50 + gap
GraphicsWindow.PenColor = colorHourHand
hourHand = Shapes.AddLine(0, 0, 0, nCity * height - 2 * gap)
Shapes.SetOpacity(hourHand, 70)
GraphicsWindow.BrushColor = colorText
objCity = Shapes.Addtext("Local Time")
Shapes.Move(objCity, 10, 10)
GraphicsWindow.DrawText(gw / 2, 10, "UTC")
Program.Delay(200)
GraphicsWindow.FontSize = 30
objLocal = Shapes.AddText("00:00")
Shapes.Move(objLocal, 100, 10)
objUTC = Shapes.AddText("00:00")
Shapes.Move(objUTC, gw / 2 + 90, 10)
GraphicsWindow.PenWidth = 0
GraphicsWindow.BrushColor = "White"
objBar = Shapes.AddRectangle(gw, height)
Shapes.SetOpacity(objBar, 20)
Shapes.HideShape(objBar)
EndSub
Sub GetCity
' get city from mouse pointer
my = GraphicsWindow.MouseY
i = Math.Floor((my - 50) / height + 1)
If 1 <= i And i <= nCity Then
iCity = index[i]
Else
iCity = ""
EndIf
EndSub
Sub GetTime
' param hour, minute
' return time - "hh:mm"
len = Text.GetLength(hour)
time = Text.Append(Text.GetSubTextToEnd("00", len + 1), hour)
time = time + ":"
len = Text.GetLength(minute)
time = time + Text.GetSubTextToEnd("00", len + 1) + minute
EndSub
Sub OnTick
hourUTC = Clock.Hour - city[cityLocal]["local"]
If hourUTC < 0 Then
hourUTC = hourUTC + 24
EndIf
If 24 <= hourUTC Then
hourUTC = hourUTC - 24
EndIf
minute = Clock.Minute
hour = hourUTC
hourUTC = hourUTC + minute / 60
x = 100 + Math.Floor(hourUTC * width)
Shapes.Move(hourHand, x, y)
GetTime()
Shapes.SetText(objUTC, time)
GetCity()
If iCity = "" Then
Shapes.HideShape(objBar)
Shapes.SetText(objCity, "Local Time")
Shapes.SetText(objLocal, "00:00")
Else
_y = 50 + (i - 1) * height
Shapes.Move(objBar, 0, _y)
Shapes.ShowShape(objBar)
Shapes.SetText(objCity, iCity)
hour = hour + city[iCity]["local"]
If hour < 0 Then
hour = hour + 24
ElseIf 23 < hour Then
hour = hour - 24
EndIf
frac = hour - Math.Floor(hour)
If 0 < frac Then
minute = Math.Floor(minute + frac * 60)
hour = Math.Floor(hour - frac)
If 60 <= minute Then
minute = minute - 60
hour = hour + 1
If 23 < hour Then
hour = hour - 24
EndIf
EndIf
EndIf
GetTime()
Shapes.SetText(objLocal, time)
EndIf
EndSub
Sub SetBandColor
' param hour
If 23 < hour Then
hour = hour - 24
EndIf
If 6 <= hour And hour < 12 Then
GraphicsWindow.BrushColor = colorMorning
ElseIf 12 <= hour And hour < 18 Then
GraphicsWindow.BrushColor = colorDay
ElseIf 18 <= hour Then
GraphicsWindow.BrushColor = colorNight
Else
GraphicsWindow.BrushColor = colorMidNight
EndIf
EndSub
Sub SetHourColor
' param hour
If 23 < hour Then
hour = hour - 24
EndIf
If 6 <= hour And hour < 18 Then
GraphicsWindow.BrushColor = colorMidNight
Else
GraphicsWindow.BrushColor = colorDay
EndIf
EndSub
Sub City_CalcDST
' param i - index of cities
If 0 < city[index[i]]["DST"] Then
month = Clock.Month
If city[index[i]]["fromDST"] < city[index[i]]["toDST"] Then
If (city[index[i]]["fromDST"] <= month) And (month <= city[index[i]]["toDST"]) Then
city[index[i]]["local"] = city[index[i]]["local"] + city[index[i]]["DST"]
EndIf
Else
If ((1 <= month) And (month <= city[index[i]]["toDST"])) Or ((city[index[i]]["fromDST"] <= month) And (month <= 12)) Then
city[index[i]]["local"] = city[index[i]]["local"] + city[index[i]]["DST"]
EndIf
EndIf
EndIf
EndSub
Sub City_Select
' time table initialization
city["Sydney"] ="local=+10;DST=+1;fromDST=10;toDST=3;"
city["Tokyo"] = "local=+9;DST=0;"
city["Kolkata"] = "local=+5.5;DST=0;"
city["Colombo"] = "local=+5.5;DST=0;"
city["Cairo"] = "local=+2;DST=+1;fromDST=5;toDST=9;"
city["Istanbul"] = "local=+2;DST=+1;fromDST=4;toDST=10;"
city["Paris"] = "local=+1;DST=+1;fromDST=4;toDST=10;"
city["London"] = "local=0;DST=+1;fromDST=4;toDST=10;"
city["Accra"] = "local=0;DST=0;"
city["Rio de Janeiro"] = "local=-3;DST=+1;fromDST=11;toDST=2;"
city["Buenos Aires"] = "local=-3;DST=0;"
city["Seatle"] = "local=-8;DST=+1;fromDST=3;toDST=10;"
nCity = Array.GetItemCount(city)
index = Array.GetAllIndices(city)
GraphicsWindow.BrushColor = "White"
iX = 260
For i = 1 To nCity
City_CalcDST()
delta = city[index[i]]["local"]
If Text.StartsWith(delta, "+") Or Text.StartsWith(delta, "-") Then
sign = ""
Else
sign = "+"
EndIf
iY = 18 * i
oCity[i] = Shapes.AddText(index[i] + " (" + sign + delta + ")")
Shapes.SetOpacity(oCity[i], 50)
Shapes.Move(oCity[i], iX, iY)
EndFor
bNotSelected = "True"
iLast = 1
GraphicsWindow.MouseMove = City_OnMouseMove
GraphicsWindow.MouseDown = City_OnMouseDown
While bNotSelected
Program.Delay(500)
EndWhile
GraphicsWindow.Clear()
GraphicsWindow.MouseMove = City_DoNothing
GraphicsWindow.MouseDown = City_DoNothing
EndSub
Sub City_DoNothing
EndSub
Sub City_OnMouseDown
i = Math.Floor(GraphicsWindow.MouseY / 18)
If 0 < i And i <= nCity Then
cityLocal = index[i]
bNotSelected = "False"
EndIf
EndSub
Sub City_OnMouseMove
i = Math.Floor(GraphicsWindow.MouseY / 18)
If 0 < i And i <= nCity Then
Shapes.SetOpacity(oCity[iLast], 50)
Shapes.SetOpacity(oCity[i], 100)
iLast = i
EndIf
EndSub