summaryrefslogtreecommitdiff
path: root/appl/wm/clock.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/wm/clock.b')
-rw-r--r--appl/wm/clock.b123
1 files changed, 123 insertions, 0 deletions
diff --git a/appl/wm/clock.b b/appl/wm/clock.b
new file mode 100644
index 00000000..a8022f09
--- /dev/null
+++ b/appl/wm/clock.b
@@ -0,0 +1,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;
+ }
+}