### Author Topic: Simple GUI program displaying analog clock  (Read 2255 times)

#### jalih

• Posts: 90
##### Simple GUI program displaying analog clock
« on: December 11, 2019, 12:01:46 PM »
To compare how easy it is to write simple GUI programs with different tools, I propose a little coding challenge to write a simple program displaying resizable analog clock.

Here is my old analog clock included in 8th samples:

Code: [Select]
`\ Draws a clock on the screen.  Original code by jalih:\   https://8th-dev.com/forum/index.php/topic,1573.msg8661.html\\ Adapted and refactored a bit.needs math/trigdtrue app:isgui !var ycentervar xcentervar radius["3","2","1","12","11","10","9","8","7","6","5","4"] constant hours: circleptx  \ x r deg  n:cosd n:* n:+ ;: circlepty \ y r deg  n:sind n:* n:- ;: onsize  2dup  2 n:/ ycenter !  2 n:/ xcenter !  n:min 2 n:/ 8 n:- radius ! ;: xc-rad \ n -- m  xcenter @ radius @ rot n:* ;: yc-rad \ n -- m  ycenter @ radius @ rot n:* ;: xcyc \ -- x y  xcenter @ ycenter @ ;: draw-indicator \ gui width size --  -rot g:line-width  xcyc g:moveto  over xc-rad r@ circleptx  rot yc-rad r> circlepty  g:lineto g:stroke ;: draw-clock  \ get current time (just HH MM SS):  d:new d:/ 3 3 a:slice a:open  -rot swap over  \ hour: (hour min)  >r 90 swap 5 n:* r> 10 n:/ n:+ 6 n:* n:- >r  \ minutes:  90 swap 6 n:* n:- >r  \ seconds:  90 swap 6 n:* n:- >r  xcyc radius @ 0 360 g:arc  "black" g:scolor 2 g:line-width  g:stroke  "black" g:fcolor  (    >r    0.95 xc-rad r@ 360 60 n:*/ circleptx    0.95 yc-rad r> 360 60 n:*/ circlepty    2 0 360 g:arc  ) 0 59 loop  "20" g:setfont  g:c-text  (    >r    0.95 xc-rad r@ 360 12 n:*/ circleptx    0.95 yc-rad r@ 360 12 n:*/ circlepty    4 0 360 g:arc    0.80 xc-rad r@ 360 12 n:*/ circleptx    0.80 yc-rad r@ 360 12 n:*/ circlepty    hours r> caseof g:draw-text-at  ) 0 11 loop  g:fill  2 0.90 draw-indicator  6 0.85 draw-indicator  10 0.65 draw-indicator  xcyc 10 0 360 g:arc  g:fill ;{  kind: "win",  title: "Simple Analog Clock",  wide: 300,  high: 300,  min-wide: 300,  min-high: 300,  max-wide: 500,  max-high: 500,  center: true,  bg: "white",  resize-corner: 20,  font: "Arial 10",  draw: "draw-clock",  timer: ' g:invalidate  ,  size: "onsize",  timer-period: 1000} var, gui-desc: app:main  gui-desc @ g:new ;`
« Last Edit: December 13, 2019, 10:06:24 AM by jalih »

#### John

• Forum Support / SB Dev
• Posts: 3006
##### Re: Simple GUI program displaying analog clock
« Reply #1 on: December 12, 2019, 07:01:54 PM »

#### John

• Forum Support / SB Dev
• Posts: 3006
##### Re: Simple GUI program displaying analog clock
« Reply #2 on: December 12, 2019, 11:26:01 PM »
Jalih,

I suggest the following  change,

From:

["03","02","01","12","11","10","09","08","07","06","05","04"]

To:

[" 3"," 2"," 1","12","11","10"," 9"," 8"," 7"," 6"," 5"," 4"]

#### jalih

• Posts: 90
##### Re: Simple GUI program displaying analog clock
« Reply #3 on: December 13, 2019, 10:07:09 AM »
Jalih,

I suggest the following  change,

From:

["03","02","01","12","11","10","09","08","07","06","05","04"]

To:

[" 3"," 2"," 1","12","11","10"," 9"," 8"," 7"," 6"," 5"," 4"]

You are right, it does look better! Source modified...

#### AIR

• BASIC Developer
• Posts: 782
##### Re: Simple GUI program displaying analog clock
« Reply #4 on: December 13, 2019, 08:12:35 PM »
I didn't code this, but I thought it was an interesting approach.

Code: XML
1. <?xml version="1.0"?>
2. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" width="400" height="400" version="1.0">
3.   <defs>
4.     <linearGradient id="a" x1="0%" y1="100%" x2="0%" y2="0%">
5.       <stop offset="0%" style="stop-color:#777799"/>
6.       <stop offset="100%" style="stop-color:#ffffff"/>
8.     <linearGradient id="b" x1="0%" y1="100%" x2="0%" y2="0%">
9.       <stop offset="0%" style="stop-color:#ffffff"/>
10.       <stop offset="25%" style="stop-color:#b6b6cc"/>
11.       <stop offset="40%" style="stop-color:#515177"/>
12.       <stop offset="48%" style="stop-color:#ffffff"/>
13.       <stop offset="56%" style="stop-color:#ffffff"/>
14.       <stop offset="75%" style="stop-color:#8b8baa"/>
15.       <stop offset="98%" style="stop-color:#efeff4"/>
16.       <stop offset="100%" style="stop-color:#fbfbfc"/>
18.     <linearGradient id="c" x1="0%" y1="100%" x2="0%" y2="0%">
19.       <stop offset="0%" style="stop-color:#ffffff"/>
20.       <stop offset="100%" style="stop-color:#777799"/>
22.     <radialGradient id="d" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
23.       <stop offset="0%" style="stop-color:#ffffff"/>
24.       <stop offset="40%" style="stop-color:#ffffff"/>
25.       <stop offset="70%" style="stop-color:#e6e6ee"/>
26.       <stop offset="92%" style="stop-color:#b6b6cc"/>
27.       <stop offset="100%" style="stop-color:#636388"/>
29.     <radialGradient id="e" cx="50%" cy="150%" r="200%" fx="50%" fy="150%">
30.       <stop offset="0%" style="stop-color:#ffffff;stop-opacity:0"/>
31.       <stop offset="59%" style="stop-color:#ffffff;stop-opacity:0"/>
32.       <stop offset="60%" style="stop-color:#ffffff;stop-opacity:0.6"/>
33.       <stop offset="70%" style="stop-color:#ffffff;stop-opacity:0.3"/>
34.       <stop offset="100%" style="stop-color:#ffffff;stop-opacity:0.0"/>
36.   </defs>
37.   <g transform="translate(200 200)">
38.     <circle cx="0" cy="0" r="200" fill="#cecedd"/>
39.     <circle cx="0" cy="0" r="196" stroke="url(#a)" stroke-width="5" fill="url(#b)"/>
40.     <circle cx="0" cy="0" r="170" stroke="url(#c)" stroke-width="4" fill="url(#d)"/>
41.     <circle cx="0" cy="0" r="172" stroke="#ffffff" stroke-width="0.5" fill="none"/>
42.     <circle cx="0" cy="0" r="193.5" stroke="#ffffff" stroke-width="0.5" fill="none"/>
43.     <g id="O">
44.       <polygon points="4,155 4,130 -4,130 -4,155" style="fill:#777799;stroke:#313155;stroke-width:1"/>
45.       <polygon points="4,-155 4,-130 -4,-130 -4,-155" style="fill:#777799;stroke:#313155;stroke-width:1"/>
46.     </g>
47.     <g transform="rotate(30)"><use xlink:href="#O"/></g>
48.     <g transform="rotate(60)"><use xlink:href="#O"/></g>
49.     <g transform="rotate(90)"><use xlink:href="#O"/></g>
50.     <g transform="rotate(120)"><use xlink:href="#O"/></g>
51.     <g transform="rotate(150)"><use xlink:href="#O"/></g>
52.     <polygon id="h" points="6,-80 6,18 -6,18 -6,-80" style="fill:#232344">
53.       <animateTransform id="ht" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="86400s" repeatCount="indefinite"/>
54.     </polygon>
55.     <polygon id="m" points="3.5,-140 3.5,23 -3.5,23 -3.5,-140" style="fill:#232344">
56.       <animateTransform id="mt" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="3600s" repeatCount="indefinite"/>
57.     </polygon>
58.     <polygon id="s" points="2,-143 2,25 -2,25 -2,-143" style="fill:#232344">
59.       <animateTransform id="st" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="60s" repeatCount="indefinite"/>
60.     </polygon>
61.     <circle cx="0" cy="0" r="163" fill="url(#e)"/>
62.   </g>
63.   <script type="text/javascript"><![CDATA[
64.    var d = new Date();
65.    var s = d.getSeconds();
66.    var m = d.getMinutes() + s/60;
67.    var h = (d.getHours() % 12) + m/60 + s/3600;
68.    document.getElementById('st').setAttribute('from',s*6);
69.    document.getElementById('mt').setAttribute('from',m*6);
70.    document.getElementById('ht').setAttribute('from',h*30);
71.    document.getElementById('st').setAttribute('to',360+s*6);
72.    document.getElementById('mt').setAttribute('to',360+m*6);
73.    document.getElementById('ht').setAttribute('to',360+h*30);
74.  ]]></script>
75. </svg>
76.
77.

Save that to a file called "clock.svg" and open in your browser....

AIR.

#### John

• Forum Support / SB Dev
• Posts: 3006
##### Re: Simple GUI program displaying analog clock
« Reply #5 on: December 13, 2019, 09:44:45 PM »
Sweet!

#### AIR

• BASIC Developer
• Posts: 782
##### Re: Simple GUI program displaying analog clock
« Reply #6 on: December 16, 2019, 06:57:18 PM »
You know, for someone who has been coding for as long as I have, I freaking hate math.

I had to scour the net to get some of the math involved in calculating a lot of this; so this is what I have right now using Python:

Code: Python
1. #!/usr/bin/env python3
2.
3. from tkinter import *
4. from time import *
5. from math import *
6.
7. def getTime():
8.     t = localtime()
9.     s = t[5]
10.     m = t[4] + s/60
11.     h = t[3] % 12 + m/60
12.     return (s,m,h)
13.
14. def drawFace(w,a,b,c,d,e,f):
15.     w.create_oval(a-b, c-d, a+b, c+d, width=f)
16.
17.     for i in range(1,13):
18.         phi = pi/6 * i
19.         x = a + e * sin(phi)
20.         y = c - e * cos(phi)
21.         w.create_text(x, y, text=str(i), font=("", 20) )
22.
23. def drawHand(w,timeObj,offset,a,b,c,color,hand_width):
24.     phi = pi/offset * timeObj
25.     x = a + c * sin(phi)
26.     y = b - c * cos(phi)
27.     w.create_line(a, b, x, y, arrow=LAST, fill=color, width=hand_width)
28.
29. def Draw_Clock(w, nx, ny):
30.     x0 = nx/2; lx = 9*nx/20
31.     y0 = ny/2; ly = 9*ny/20
32.     r0 = 0.9 * min(lx,ly)
33.     r1 = 0.6 * min(lx,ly)
34.     r2 = 0.8 * min(lx,ly)
35.
36.     drawFace(w,x0,lx,y0,ly,r0,4)
37.     seconds, minutes, hours = getTime()
38.
39.     drawHand(w,hours,6,x0,y0,r1,"black",5)
40.     drawHand(w,minutes,30,x0,y0,r2,"black",4)
41.     drawHand(w,seconds,30,x0,y0,r2,"black",2)
42.
43.
44. def Clock(w, nx, ny):
45.     w.delete(ALL)
46.     Draw_Clock(w, nx, ny)
47.     w.after(10, Clock, w, nx, ny)
48.
49. if __name__ == "__main__":
50.     app = Tk()
51.     app.title("Analog Clock")
52.
53.     nx = 400; ny = 400
54.     window = Canvas(app, width=nx, height=ny, bg = "white")
55.     window.pack(fill='both', expand=True)
56.
57.     Clock(window, nx, ny)
58.
59.     app.eval('tk::PlaceWindow . center')
60.     app.mainloop()

AIR.

#### John

• Forum Support / SB Dev
• Posts: 3006
##### Re: Simple GUI program displaying analog clock
« Reply #7 on: December 16, 2019, 10:18:55 PM »
The Rosetta Code site has a clock challenge.

#### AIR

• BASIC Developer
• Posts: 782
##### Re: Simple GUI program displaying analog clock
« Reply #8 on: December 17, 2019, 11:08:08 AM »
This is a little rough, but wanted to try BlitzMax-NG:

Code: Text
1. Local nx=400,ny=400,i
2. Graphics nx+16,ny+16
3.
4. Global rad_fix:Float = 0.0174532925199432957692369076848861
5.
6. Local phi:Float, x: Float, y: Float
7.
8. Local x0 = nx/2, lx = 9*nx/20, y0 = ny/2, ly = 9*ny/20
9. Local r0 = 0.9 * Min(lx,ly), r1 = 0.6 * Min(lx,ly), r2 = 0.8 * Min(lx,ly)
10. Local f:TImageFont = LoadImageFont("/Library/Fonts/arial.ttf",26,BOLDFONT|SMOOTHFONT)
11.
12. SetImageFont(f)
13.
14. While Not KeyHit(KEY_ESCAPE)
15.     Cls
16.
17.     Local s_array:String[] = CurrentTime\$().split(":")
18.     Local hour = Int(s_array[0]) Mod 12
19.     Local minute = Int(s_array[1])
20.     Local second = Int(s_array[2])
21.
22.     SetColor 255,255,255
23.     DrawOval (x0-lx),(x0-lx),(x0+lx), (x0+lx)
24.
25.     For i = 1 To 12
26.         phi = Pi/6 * i
27.
28.         x = x0 + r0 * Sin(phi/rad_fix)
29.         y = y0 - r0 * Cos(phi/rad_fix)
30.         SetColor 0,0,0
31.         DrawText i, x-8, y-16
32.     Next
33.
34.     ' Hour
35.     phi = Pi/6 * hour
36.     x = x0 + r1 * Sin(phi/rad_fix)
37.     y = y0 - r1 * Cos(phi/rad_fix)
38.     SetLineWidth(5)
39.     DrawLine(x0, y0 , x, y)
40.
41.     ' Minute
42.     phi = Pi/30 * minute
43.     x = x0 + r2 * Sin(phi/rad_fix)
44.     y = y0 - r2 * Cos(phi/rad_fix)
45.     SetLineWidth(4)
46.     DrawLine(x0, y0 , x, y)
47.
48.
49.     ' Seconds
50.     phi = Pi/30 * second
51.     x = x0 + r2 * Sin(phi/rad_fix)
52.     y = y0 - r2 * Cos(phi/rad_fix)
53.     SetLineWidth(2)
54.     DrawLine(x0, y0 , x, y)
55.
56.
57.     Flip
58. Wend
59.
60.

AIR.
« Last Edit: December 17, 2019, 11:11:37 AM by AIR »