From 67a33cad36a2dc18666c7e4006b47494d1904e68 Mon Sep 17 00:00:00 2001 From: q Date: Thu, 20 Jun 2024 09:27:27 +0300 Subject: [PATCH] new and improved --- bin/clockcurses | 86 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/bin/clockcurses b/bin/clockcurses index cde3ae8..77deed2 100755 --- a/bin/clockcurses +++ b/bin/clockcurses @@ -94,20 +94,21 @@ def centerpoint(ry, rx): def saddstr(win, y, x, s, a=None): if not a: - a=curses.color_pair(0) + a = curses.color_pair(0) try: win.addstr(y, x, s, a) except: pass -def drawcircle(win, cy, cx, r): +def drawcircle(win, cy, cx, r, s="·", attr=None): + # TODO: get seconds?, color by angle, darkening to past. current seconds bright precision = 360 for a in range(precision): alpha = 2.0 * math.pi * a / precision dy = int(round(cy - float(r) * math.cos(alpha))) dx = int(round(cx + 2.0 * float(r) * math.sin(alpha))) - saddstr(win, dy, dx, "·") + saddstr(win, dy, dx, s, attr) return @@ -118,8 +119,8 @@ def drawline(win, cy, cx, a, s, r, char, attr=None): if l > s: ly = cy - float(l) * math.cos(a) / prec lx = cx + 2.0 * float(l) * math.sin(a) / prec - iy,ix = int(round(ly)), int(round(lx)) - saddstr(win, iy,ix, char, attr) + iy, ix = int(round(ly)), int(round(lx)) + saddstr(win, iy, ix, char, attr) return @@ -157,6 +158,52 @@ def drawdigital(win, y, x, t, ascii=False): drawdigit(win, y, x + 4 * c, hrs[c], ascii=ascii) +def drawalarms(stdscr, y, x, t, alarms): + ya = y + now = 100 * t.tm_hour + t.tm_min + is_alarm = False + for alarm in alarms: + if alarm["hstart"] <= now and alarm["hend"] >= now: + if t.tm_sec % 2 == 0: + color = curses.color_pair(4) + curses.A_BOLD + curses.A_REVERSE + else: + color = curses.color_pair(2) + curses.A_BOLD + is_alarm = True + else: + color = curses.color_pair(7) + st = "{:02d}:{:02d}".format(*alarm["start"]) + ed = "{:02d}:{:02d}".format(*alarm["end"]) + s = f"{st}-{ed} {alarm['name']}" + stdscr.addstr(ya, x, s, color) + ya += 1 + return is_alarm + + +def parse_alarms(alarms): + + parsed = [] + for alarm in alarms: + t, n = alarm.split("/", 1) + t = t.split("-") + tstart = [int(x) for x in t[0].split(":")] + if len(t) > 1: + tend = [int(x) for x in t[1].split(":")] + else: + tend = tstart + parsed.append( + { + "start": tstart, + "end": tend, + "name": n, + "hstart": 100 * tstart[0] + tstart[1], + "hend": 100 * tend[0] + tend[1], + } + ) + parsed.sort(key=lambda x: x["start"][1]) + parsed.sort(key=lambda x: x["start"][0]) + return parsed + + def readinput(win, timeout): started = time.time() try: @@ -181,6 +228,7 @@ class timer_struct: def main(): stdscr = curses.initscr() + alarms = parse_alarms(options.alarm) curses.curs_set(0) curses.start_color() curses.use_default_colors() @@ -188,13 +236,13 @@ def main(): for i in range(0, curses.COLORS): curses.init_pair(i + 1, i, -1) start_t = time.time() + is_alarm = False try: # rows,columns = termsize() curses.cbreak() while 1: rows, columns = stdscr.getmaxyx() cy, cx, r = centerpoint(rows, columns) - stdscr.clear() now = time.time() t = time.localtime(now) if options.timer: @@ -207,23 +255,33 @@ def main(): t_s = float(t.tm_sec) t_m = float(t.tm_min) t_h = float(t.tm_hour) - alphas = math.pi * (f+t_s) / 30.0 + alphas = math.pi * (f + t_s) / 30.0 alpham = math.pi * t_m / 30.0 + alphas / 60.0 alphah = math.pi * t_h / 6.0 + alpham / 12.0 - drawcircle(stdscr, cy, cx, r / 2) + if t_s == 0: + # clear once a minute + stdscr.clear() + drawcircle( + stdscr, + cy, + cx, + r / 2, + attr=curses.color_pair(2) + curses.A_BOLD if is_alarm and t_s % 2 == 0 else curses.color_pair(1), + ) if options.seconds: drawline(stdscr, cy, cx, alphas, 1, r / 2, "■", curses.color_pair(2)) drawline(stdscr, cy, cx, alpham, 1, int(round(r * 0.9) / 2), "█", curses.color_pair(3)) - drawline(stdscr, cy, cx, alphah, 1, int(round(r * 0.7) / 2), "█", curses.color_pair(7)) - stdscr.addstr(cy, cx, "█") + drawline(stdscr, cy, cx, alphah, 1, int(round(r * 0.6) / 2), "██", curses.color_pair(7)) + stdscr.addstr(cy, cx, "⊙") for h in range(12): - drawline(stdscr, cy, cx, math.pi * h / 6.0, r, 1 + r / 2, "@") + drawline(stdscr, cy, cx, math.pi * h / 6.0, r, 1 + r / 2, "◆", curses.color_pair(4)) if options.timer: drawdigital(stdscr, 1, 1, timer_struct(t_h, t_m, t_s), options.ascii) drawdigital(stdscr, 7, 1, t, options.ascii) else: drawdigital(stdscr, 1, 1, t, options.ascii) + is_alarm = drawalarms(stdscr, 1, 35, t, alarms) stdscr.refresh() userinput = readinput(stdscr, options.refresh) if userinput == "x": @@ -231,6 +289,11 @@ def main(): stdscr.keypad(0) curses.endwin() sys.exit(0) + # wipe + if options.seconds: + drawline(stdscr, cy, cx, alphas, 1, r / 2, " ", curses.color_pair(2)) + drawline(stdscr, cy, cx, alpham, 1, int(round(r * 0.9) / 2), " ", curses.color_pair(3)) + drawline(stdscr, cy, cx, alphah, 1, int(round(r * 0.6) / 2), " ", curses.color_pair(7)) except KeyboardInterrupt: curses.nocbreak() @@ -251,6 +314,7 @@ parser.add_option( "-t", action="store_true", dest="timer", default=False, help="Timer instead of current time [%default]" ) parser.add_option("-a", action="store_true", dest="ascii", default=False, help="Plain ascii characters only [%default]") +parser.add_option("--alarm", action="append", dest="alarm", default=[], help="alarms") global options (options, args) = parser.parse_args()