(phixonline)-->
--
-- demo\rosetta\Clock.exw
-- ======================
--
with javascript_semantics
include pGUI.e
Ihandle dlg, canvas, hTimer
cdCanvas cd_canvas
procedure draw_hand(atom degrees, atom r, baseangle, baselen, cx, cy)
atom a = PI-(degrees+90)*PI/180,
-- tip
x1 = cos(a)*(r),
y1 = sin(a)*(r),
-- base
x2 = cos(a+PI-baseangle)*baselen,
y2 = sin(a+PI-baseangle)*baselen,
x3 = cos(a+PI+baseangle)*baselen,
y3 = sin(a+PI+baseangle)*baselen
cdCanvasSetLineWidth(cd_canvas,1)
cdCanvasLine(cd_canvas,cx+x1,cy+y1,cx+x2,cy+y2)
cdCanvasLine(cd_canvas,cx+x2,cy+y2,cx+x3,cy+y3)
cdCanvasLine(cd_canvas,cx+x3,cy+y3,cx+x1,cy+y1)
cdCanvasBegin(cd_canvas,CD_FILL)
cdCanvasVertex(cd_canvas,cx+x1,cy+y1)
cdCanvasVertex(cd_canvas,cx+x2,cy+y2)
cdCanvasVertex(cd_canvas,cx+x3,cy+y3)
cdCanvasEnd(cd_canvas)
end procedure
procedure draw_clock(atom cx, cy, d)
atom w = 2+floor(d/25)
cdCanvasFont(cd_canvas, "Helvetica", CD_PLAIN, floor(d/15))
cdCanvasSetLineWidth(cd_canvas, w)
cdCanvasArc(cd_canvas, cx, cy, d, d, 0, 360)
d -= w+8
w = 1+floor(d/50)
for i=6 to 360 by 6 do
integer h = remainder(i,30)=0
cdCanvasSetLineWidth(cd_canvas, max(floor(w*(1+h)/3),1))
atom a = PI-(i+90)*PI/180,
x1 = cos(a)*d/2, x2 = cos(a)*(d/2-w*(2+h)*.66),
y1 = sin(a)*d/2, y2 = sin(a)*(d/2-w*(2+h)*.66)
cdCanvasLine(cd_canvas, cx+x1, cy+y1, cx+x2, cy+y2)
if h then
x1 = cos(a)*(d/2-w*4.5)
y1 = sin(a)*(d/2-w*4.5)
cdCanvasText(cd_canvas,cx+x1,cy+y1,sprintf("%d",{i/30}))
end if
end for
atom {hour,mins,secs,msecs} = date(true)[DT_HOUR..DT_MSEC]
if IupGetInt(hTimer,"TIME")<1000 then
-- (if showing once a second, always land on exact
-- seconds, ie completely ignore msecs, otherwise
-- show smooth running (fractional) second hand.)
secs += msecs/1000
end if
mins += secs/60
hour += mins/60
atom r = d/2
draw_hand(hour*360/12,r-w*9,0.3,d/20,cx,cy)
draw_hand(mins*360/60,r-w*2,0.2,d/16,cx,cy)
cdCanvasSetForeground(cd_canvas, CD_RED)
draw_hand(secs*360/60,r-w*2,0.05,d/16,cx,cy)
cdCanvasSetForeground(cd_canvas, CD_BLACK)
end procedure
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE"),
r = floor(min(width,height)*0.9),
cx = floor(width/2),
cy = floor(height/2)
cdCanvasActivate(cd_canvas)
cdCanvasClear(cd_canvas)
draw_clock(cx,cy,r)
cdCanvasFlush(cd_canvas)
return IUP_DEFAULT
end function
function timer_cb(Ihandle /*ih*/)
IupUpdate(canvas)
return IUP_IGNORE
end function
function map_cb(Ihandle ih)
IupGLMakeCurrent(canvas)
if platform()=JS then
cd_canvas = cdCreateCanvas(CD_IUP, canvas)
else
atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
cd_canvas = cdCreateCanvas(CD_GL, "10x10 %g", {res})
end if
cdCanvasSetBackground(cd_canvas, CD_WHITE)
cdCanvasSetForeground(cd_canvas, CD_BLACK)
cdCanvasSetTextAlignment(cd_canvas, CD_CENTER)
return IUP_DEFAULT
end function
function canvas_resize_cb(Ihandle /*canvas*/)
integer {canvas_width, canvas_height} = IupGetIntInt(canvas, "DRAWSIZE")
atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
cdCanvasSetAttribute(cd_canvas, "SIZE", "%dx%d %g", {canvas_width, canvas_height, res})
return IUP_DEFAULT
end function
procedure main()
IupOpen()
canvas = IupGLCanvas("RASTERSIZE=350x350")
IupSetCallbacks(canvas, {"MAP_CB", Icallback("map_cb"),
"ACTION", Icallback("redraw_cb"),
"RESIZE_CB", Icallback("canvas_resize_cb")})
hTimer = IupTimer(Icallback("timer_cb"), 40) -- smooth secs
-- hTimer = IupTimer(Icallback("timer_cb"), 1000) -- tick seconds
dlg = IupDialog(canvas, "TITLE=Clock")
IupShow(dlg)
IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
if platform()!=JS then
IupMainLoop()
IupClose()
end if
end procedure
main()