1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
implement Clock;
#
# Subject to the Lucent Public License 1.02
#
include "sys.m";
sys: Sys;
include "draw.m";
draw: Draw;
Display, Image, Point, Rect: import draw;
include "math.m";
math: Math;
include "tk.m";
include "wmclient.m";
wmclient: Wmclient;
Window: import wmclient;
include "daytime.m";
daytime: Daytime;
Tm: import daytime;
Clock: module
{
init: fn(nil: ref Draw->Context, nil: list of string);
};
hrhand: ref Image;
minhand: ref Image;
dots: ref Image;
back: ref Image;
init(ctxt: ref Draw->Context, nil: list of string)
{
sys = load Sys Sys->PATH;
draw = load Draw Draw->PATH;
math = load Math Math->PATH;
daytime = load Daytime Daytime->PATH;
wmclient = load Wmclient Wmclient->PATH;
sys->pctl(Sys->NEWPGRP, nil);
wmclient->init();
w := wmclient->window(ctxt, "clock", Wmclient->Appl); # Plain?
display := w.display;
back = display.colormix(Draw->Palebluegreen, Draw->White);
hrhand = display.newimage(Rect((0,0),(1,1)), Draw->CMAP8, 1, Draw->Darkblue);
minhand = display.newimage(Rect((0,0),(1,1)), Draw->CMAP8, 1, Draw->Paleblue);
dots = display.newimage(Rect((0,0),(1,1)), Draw->CMAP8, 1, Draw->Blue);
w.reshape(Rect((0, 0), (100, 100)));
w.startinput("ptr" :: nil);
now := daytime->now();
w.onscreen(nil);
drawclock(w.image, now);
ticks := chan of int;
spawn timer(ticks, 30*1000);
for(;;) alt{
ctl := <-w.ctl or
ctl = <-w.ctxt.ctl =>
w.wmctl(ctl);
if(ctl != nil && ctl[0] == '!')
drawclock(w.image, now);
p := <-w.ctxt.ptr =>
w.pointer(*p);
<-ticks =>
t := daytime->now();
if(t != now){
now = t;
drawclock(w.image, now);
}
}
}
ZP := Point(0, 0);
drawclock(screen: ref Image, t: int)
{
if(screen == nil)
return;
tms := daytime->local(t);
anghr := 90-(tms.hour*5 + tms.min/10)*6;
angmin := 90-tms.min*6;
r := screen.r;
c := r.min.add(r.max).div(2);
if(r.dx() < r.dy())
rad := r.dx();
else
rad = r.dy();
rad /= 2;
rad -= 8;
screen.draw(screen.r, back, nil, ZP);
for(i:=0; i<12; i++)
screen.fillellipse(circlept(c, rad, i*(360/12)), 2, 2, dots, ZP);
screen.line(c, circlept(c, (rad*3)/4, angmin), 0, 0, 1, minhand, ZP);
screen.line(c, circlept(c, rad/2, anghr), 0, 0, 1, hrhand, ZP);
screen.flush(Draw->Flushnow);
}
circlept(c: Point, r: int, degrees: int): Point
{
rad := real degrees * Math->Pi/180.0;
c.x += int (math->cos(rad)*real r);
c.y -= int (math->sin(rad)*real r);
return c;
}
timer(c: chan of int, ms: int)
{
for(;;){
sys->sleep(ms);
c <-= 1;
}
}
|