shithub: clock

Download patch

ref: 6670406eb7bc3a815fe16a71b41a3cf265689fa7
author: Igor Böhm <igor@9lab.org>
date: Sun Oct 10 16:26:54 EDT 2021

Initial import.

--- /dev/null
+++ b/README.md
@@ -1,0 +1,1 @@
+Another kind of clock for Plan9.
--- /dev/null
+++ b/clock.c
@@ -1,0 +1,137 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+
+Point
+circlept(Point c, int r, int degrees)
+{
+ double rad = (double)degrees * PI / 180.0;
+
+ c.x += cos(rad) * r;
+ c.y -= sin(rad) * r;
+ return c;
+}
+
+void
+lineb(Image* dst, Point p0, Point p1, Image* src)
+{
+ int dx = abs(p1.x - p0.x), sx = p0.x < p1.x ? 1 : -1;
+ int dy = -abs(p1.y - p0.y), sy = p0.y < p1.y ? 1 : -1;
+ int err = dx + dy, e2;
+
+ for(;;) {
+  draw(dst, Rect(p0.x, p0.y, p0.x + 1, p0.y + 1), src, nil, ZP);
+  if(p0.x == p1.x && p0.y == p1.y)
+   break;
+  e2 = 2 * err;
+  if(e2 >= dy) {
+   err += dy;
+   p0.x += sx;
+  }
+  if(e2 <= dx) {
+   err += dx;
+   p0.y += sy;
+  }
+ }
+}
+
+void
+redraw(Image* dst)
+{
+ Point size = subpt(screen->r.max, screen->r.min);
+ Point center = divpt(size, 2);
+ Rectangle frame = (Rectangle){Pt(0, 0), size};
+ int pad = 10;
+ int rad = ((size.x < size.y ? size.x : size.y) / 2) - 2;
+ int range = rad - pad;
+ Image* view = allocimage(display, frame, screen->chan, 1, 0x000000FF);
+ Image* secclr = allocimagemix(display, DRed, DRed);
+
+ for(int i = 0; i < 60; i++) {
+  int len = i % 15 == 0 ? range : i % 5 == 0 ? rad - pad / 2 : rad - pad / 3;
+  lineb(view, circlept(center, len, i * 6), circlept(center, rad, i * 6), display->white);
+ }
+
+ Tm tms = *localtime(time(0));
+ int anghr = 90 - (tms.hour * 5 + tms.min / 12) * 6;
+ int angmin = 90 - tms.min * 6;
+ int angsec = 90 - tms.sec * 6;
+ int angsecrev = 270 - tms.sec * 6;
+
+ fillellipse(view, center, rad - pad, rad - pad, display->black, ZP);
+ lineb(view, center, circlept(center, range * 0.7, anghr), display->white);
+ lineb(view, center, circlept(center, range - 2, angmin), display->white);
+ lineb(view, center, circlept(center, range - 2, angsec), secclr);
+ lineb(view, center, circlept(center, range * 0.1, angsecrev), secclr);
+ fillellipse(view, center, 2, 2, secclr, ZP);
+
+ /* collapse when horizontal window */
+ if(size.y > size.x + 2 * pad) {
+  /* time */
+  char timestr[9];
+  snprint(timestr, sizeof(timestr), "%02d:%02d:%02d", tms.hour, tms.min, tms.sec);
+  Point timesize = stringsize(display->defaultfont, timestr);
+  Point timept = Pt(pad, pad);
+  /* date */
+  char datestr[30];
+  snprint(datestr, sizeof(datestr), "%s", ctime(time(0)));
+  datestr[10] = '\0';
+  Point datesize = stringsize(display->defaultfont, datestr);
+  Point datept = Pt(size.x - datesize.x - pad, pad);
+  /* draw */
+  draw(view,
+       (Rectangle){timept, addpt(timept, Pt(size.x - pad * 2, 0))},
+       display->black, nil, ZP);
+  string(view, timept, display->white, ZP, display->defaultfont, timestr);
+  if(timesize.x + datesize.x < size.x - pad - pad)
+   string(view, datept, display->white, ZP, display->defaultfont, datestr);
+ }
+
+ draw(dst, screen->r, view, nil, ZP);
+ flushimage(display, 1);
+ freeimage(secclr);
+ freeimage(view);
+}
+
+void
+eresized(int new)
+{
+ if(new&& getwindow(display, Refnone) < 0)
+  fprint(2, "can't reattach to window");
+ redraw(screen);
+}
+
+void
+main(int argc, char* argv[])
+{
+ USED(argc, argv);
+ 
+ Event e;
+ Mouse m;
+ Menu menu;
+ char* mstr[] = {"exit", 0};
+ int key, timer, t = 1000;
+
+ if(initdraw(0, 0, "clock") < 0)
+  sysfatal("initdraw failed");
+
+ eresized(0);
+ einit(Emouse);
+ timer = etimer(0, t);
+ menu.item = mstr;
+ menu.lasthit = 0;
+
+ for(;;) {
+  key = event(&e);
+  if(key == Emouse) {
+   m = e.mouse;
+   if(m.buttons & 4) {
+    if(emenuhit(3, &m, &menu) == 0)
+     exits(0);
+   }
+  } else if(key == timer) {
+   redraw(screen);
+  }
+ }
+}
binary files /dev/null b/clock.png differ
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,8 @@
+</$objtype/mkfile
+
+BIN=$home/bin/$objtype
+CFLAGS=-FTVw
+TARG=clock
+OFILES=clock.$O
+
+</sys/src/cmd/mkone