| #! /usr/bin/env python |
| |
| # "M Clock" |
| # |
| # An implementation in software of an original design by Rob Juda. |
| # Clock implementation: Guido van Rossum. |
| # Alarm and Gong features: Sape Mullender. |
| # |
| # XXX TO DO: |
| # add arguments to specify initial window position and size |
| # find out local time zone difference automatically |
| # add a date indicator |
| # allow multiple alarms |
| # allow the menu to change more parameters |
| |
| import sys |
| |
| from gl import * |
| from GL import * |
| from DEVICE import * |
| import time |
| import getopt |
| import string |
| import os |
| from math import pi |
| import math |
| |
| FULLC = 3600 # Full circle in 1/10-ths of a degree |
| MIDN = 900 # Angle of the 12 o'clock position |
| R, G, B = 0, 1, 2 # Indices of colors in RGB list |
| |
| HOUR = 3600 # Number of seconds per hour |
| MINUTE = 60 # Number of seconds per minute |
| |
| class struct: pass # Class to define featureless structures |
| Gl = struct() # Object to hold writable global variables |
| |
| # Default constants (used in multiple places) |
| |
| SCREENBG = 127, 156, 191 |
| NPARTS = 9 |
| TITLE = 'M Clock' |
| |
| # Set timezone, check for daylight saving time |
| TZDIFF = time.timezone |
| if time.localtime(time.time())[-1]: |
| TZDIFF = time.altzone |
| |
| # Default parameters |
| |
| Gl.foreground = 0 # If set, run in the foreground |
| Gl.fullscreen = 0 # If set, run on full screen |
| Gl.tzdiff = TZDIFF # Seconds west of Greenwich (winter time) |
| Gl.nparts = NPARTS # Number of parts each circle is divided in (>= 2) |
| Gl.debug = 0 # If set, print debug output |
| Gl.doublebuffer = 1 # If set, use double buffering |
| Gl.update = 0 # Update interval; seconds hand is suppressed if > 1 |
| Gl.colorsubset = 0 # If set, display only a subset of the colors |
| Gl.cyan = 0 # If set, display cyan overlay (big hand) |
| Gl.magenta = 0 # If set, display magenta overlay (little hand) |
| Gl.yellow = 0 # If set, display yellow overlay (fixed background) |
| Gl.black = 0 # If set, display black overlay (hands) |
| Gl.colormap = 0 # If set, use colormap mode instead of RGB mode |
| Gl.warnings = 0 # If set, print warnings |
| Gl.title = '' # Window title (default set later) |
| Gl.name = 'mclock' # Window title for resources |
| Gl.border = 1 # If set, use a window border (and title) |
| Gl.bg = 0, 0, 0 # Background color R, G, B value |
| Gl.iconic = 0 # Set in iconic state |
| Gl.fg = 255, 0, 0 # Alarm background RGB (either normal or alarm) |
| Gl.ox,Gl.oy = 0,0 # Window origin |
| Gl.cx,Gl.cy = 0,0 # Window size |
| Gl.alarm_set = 0 # Alarm on or off |
| Gl.alarm_on = 0 # Alarm is ringing |
| Gl.alarm_time = 0 # Alarm time in seconds after midnight |
| Gl.alarm_hours = 0 # Alarm hour setting, 24 hour clock |
| Gl.alarm_minutes = 0 # Alarm minutes setting |
| Gl.alarm_rgb = 0,0,0 # Alarm display RGB colors |
| Gl.alarm_cmd = '' # Command to execute when alarm goes off |
| Gl.mouse2down = 0 # Mouse button state |
| Gl.mouse3down = 0 # Mouse button state |
| Gl.gong_cmd = '' # Command to execute when chimes go off |
| Gl.gong_int = 3600 # Gong interval |
| Gl.indices = R, G, B # Colors (permuted when alarm is on) |
| |
| def main(): |
| # |
| sys.stdout = sys.stderr # All output is errors/warnings etc. |
| # |
| try: |
| args = getoptions() |
| except string.atoi_error, value: |
| usage(string.atoi_error, value) |
| except getopt.error, msg: |
| usage(getopt.error, msg) |
| # |
| if args: |
| realtime = 0 |
| hours = string.atoi(args[0]) |
| minutes = seconds = 0 |
| if args[1:]: minutes = string.atoi(args[1]) |
| if args[2:]: seconds = string.atoi(args[2]) |
| localtime = ((hours*60)+minutes)*60+seconds |
| else: |
| realtime = 1 |
| # |
| if Gl.title == '': |
| if realtime: |
| Gl.title = TITLE |
| else: |
| title = '' |
| for arg in args: title = title + ' ' + arg |
| Gl.title = title[1:] |
| del title |
| # |
| wid = makewindow() |
| Gl.ox,Gl.oy = getorigin() |
| Gl.cx,Gl.cy = getsize() |
| initmenu() |
| clearall() |
| # |
| if not Gl.update: |
| Gl.update = 60 |
| # |
| if Gl.update <= 1: |
| Gl.timernoise = 6 |
| else: |
| Gl.timernoise = 60 |
| noise(TIMER0, Gl.timernoise) |
| # |
| qdevice(WINSHUT) |
| qdevice(WINQUIT) |
| qdevice(ESCKEY) |
| if realtime: |
| qdevice(TIMER0) |
| qdevice(REDRAW) |
| qdevice(WINFREEZE) |
| qdevice(WINTHAW) |
| qdevice(MENUBUTTON) # MOUSE1 |
| qdevice(MOUSE3) # Left button |
| qdevice(MOUSE2) # Middle button |
| unqdevice(INPUTCHANGE) |
| # |
| lasttime = 0 |
| Gl.change = 1 |
| while 1: |
| if realtime: |
| localtime = int(time.time() - Gl.tzdiff) |
| if Gl.alarm_set: |
| if localtime%(24*HOUR) == Gl.alarm_time: |
| # Ring the alarm! |
| if Gl.debug: |
| print 'Rrrringg!' |
| Gl.alarm_on = 1 |
| if Gl.alarm_cmd <> '': |
| d = os.system(Gl.alarm_cmd+' '+`Gl.alarm_time/3600`+' '+`(Gl.alarm_time/60)%60` + ' &') |
| Gl.change = 1 |
| clearall() |
| if Gl.alarm_on: |
| if (localtime - Gl.alarm_time) % (24*HOUR) > 300: |
| # More than 5 minutes away from alarm |
| Gl.alarm_on = 0 |
| if Gl.debug: |
| print 'Alarm turned off' |
| Gl.change = 1 |
| clearall() |
| Gl.indices = R, G, B |
| else: |
| if localtime % 2 == 0: |
| # Permute color indices |
| Gl.indices = Gl.indices[2:] + Gl.indices[:2] |
| Gl.change = 1 |
| if Gl.gong_cmd <> '' and localtime%Gl.gong_int == 0: |
| d = os.system(Gl.gong_cmd+' '+`(localtime/3600)%24`+' '+`(localtime/60)%60` + ' &') |
| if localtime/Gl.update <> lasttime/Gl.update: |
| if Gl.debug: print 'new time' |
| Gl.change = 1 |
| if Gl.change: |
| if Gl.debug: print 'drawing' |
| doit(localtime) |
| lasttime = localtime |
| Gl.change = 0 |
| dev, data = qread() |
| if Gl.debug and dev <> TIMER0: |
| print dev, data |
| if dev == TIMER0: |
| if Gl.debug > 1: |
| print dev, data |
| elif dev == MOUSE3: |
| mousex = getvaluator(MOUSEX) |
| mousey = getvaluator(MOUSEY) |
| if mouseclick(3, data, mousex, mousey): |
| Gl.change = 1 |
| elif dev == MOUSE2: |
| mousex = getvaluator(MOUSEX) |
| mousey = getvaluator(MOUSEY) |
| if mouseclick(2, data, mousex, mousey): |
| Gl.change = 1 |
| elif dev == MOUSEX: |
| mousex = data |
| if Gl.mouse2down: |
| mouse2track(mousex, mousey) |
| if Gl.mouse3down: |
| mouse3track(mousex, mousey) |
| elif dev == MOUSEY: |
| mousey = data |
| if Gl.mouse2down: |
| mouse2track(mousex, mousey) |
| if Gl.mouse3down: |
| mouse3track(mousex, mousey) |
| elif dev == REDRAW or dev == REDRAWICONIC: |
| if Gl.debug: |
| if dev == REDRAW: print 'REDRAW' |
| else: print 'REDRAWICONIC' |
| reshapeviewport() |
| Gl.ox,Gl.oy = getorigin() |
| Gl.cx,Gl.cy = getsize() |
| Gl.change = 1 |
| clearall() |
| elif dev == MENUBUTTON: |
| if Gl.debug: print 'MENUBUTTON' |
| handlemenu() |
| elif dev == WINFREEZE: |
| if Gl.debug: print 'WINFREEZE' |
| Gl.iconic = 1 |
| noise(TIMER0, 60*60) # Redraw every 60 seconds only |
| elif dev == WINTHAW: |
| if Gl.debug: print 'WINTHAW' |
| Gl.iconic = 0 |
| noise(TIMER0, Gl.timernoise) |
| Gl.change = 1 |
| elif dev == ESCKEY or dev == WINSHUT or dev == WINQUIT: |
| if Gl.debug: print 'Exit' |
| sys.exit(0) |
| |
| def getoptions(): |
| optlist, args = getopt.getopt(sys.argv[1:], 'A:a:B:bc:dFfG:g:n:sT:t:u:wCMYK') |
| for optname, optarg in optlist: |
| if optname == '-A': |
| Gl.fg = eval(optarg) # Should be (r,g,b) |
| elif optname == '-a': |
| Gl.alarm_cmd = optarg |
| elif optname == '-B': |
| Gl.bg = eval(optarg) # Should be (r,g,b) |
| elif optname == '-b': |
| Gl.border = 0 |
| elif optname == '-c': |
| Gl.colormap = string.atoi(optarg) |
| elif optname == '-d': |
| Gl.debug = Gl.debug + 1 |
| Gl.warnings = 1 |
| elif optname == '-F': |
| Gl.foreground = 1 |
| elif optname == '-f': |
| Gl.fullscreen = 1 |
| elif optname == '-G': |
| Gl.gong_int = 60*string.atoi(optarg) |
| elif optname == '-g': |
| Gl.gong_cmd = optarg |
| elif optname == '-n': |
| Gl.nparts = string.atoi(optarg) |
| elif optname == '-s': |
| Gl.doublebuffer = 0 |
| elif optname == '-T': |
| Gl.title = Gl.name = optarg |
| elif optname == '-t': |
| Gl.tzdiff = string.atoi(optarg) |
| elif optname == '-u': |
| Gl.update = string.atoi(optarg) |
| elif optname == '-w': |
| Gl.warnings = 1 |
| elif optname == '-C': |
| Gl.cyan = Gl.colorsubset = 1 |
| elif optname == '-M': |
| Gl.magenta = Gl.colorsubset = 1 |
| elif optname == '-Y': |
| Gl.yellow = Gl.colorsubset = 1 |
| elif optname == '-K': |
| Gl.black = Gl.colorsubset = 1 |
| else: |
| print 'Unsupported option', optname |
| return args |
| |
| def usage(exc, msg): |
| if sys.argv: |
| progname = os.path.basename(sys.argv[0]) |
| else: |
| progname = 'mclock' |
| # |
| print progname + ':', |
| if exc == string.atoi_error: |
| print 'non-numeric argument:', |
| print msg |
| # |
| print 'usage:', progname, '[options] [hh [mm [ss]]]' |
| # |
| print '-A r,g,b : alarm background red,green,blue [255,0,0]' |
| print '-a cmd : shell command executed when alarm goes off' |
| print '-B r,g,b : background red,green,blue [0,0,0]' |
| print ' (-B SCREENBG uses the default screen background)' |
| print '-b : suppress window border and title' |
| print '-c cmapid : select explicit colormap' |
| print '-d : more debug output (implies -F, -w)' |
| print '-F : run in foreground' |
| print '-f : use full screen' |
| print '-G intrvl : interval between chimes in minutes [60]' |
| print '-g cmd : shell command executed when chimes go off' |
| print '-s : single buffer mode' |
| print '-w : print various warnings' |
| print '-n nparts : number of parts [' + `NPARTS` + ']' |
| print '-T title : alternate window title [\'' + TITLE + '\']' |
| print '-t tzdiff : time zone difference [' + `TZDIFF` + ']' |
| print '-u update : update interval [60]' |
| print '-CMYK : Cyan, Magenta, Yellow or blacK overlay only' |
| print 'if hh [mm [ss]] is specified, display that time statically' |
| print 'on machines with < 12 bitplanes, -s is forced on' |
| # |
| sys.exit(2) |
| |
| def doit(localtime): |
| hands = makehands(localtime) |
| list = makelist(hands) |
| render(list, hands) |
| |
| def makehands(localtime): |
| localtime = localtime % (12*HOUR) |
| seconds_hand = MIDN + FULLC - (localtime*60) % FULLC |
| big_hand = (MIDN + FULLC - (localtime%HOUR)) % FULLC |
| little_hand = (MIDN + FULLC - ((localtime/12) % HOUR)) % FULLC |
| return little_hand, big_hand, seconds_hand |
| |
| def makelist(hands): |
| little_hand, big_hand, seconds_hand = hands |
| total = [] |
| if Gl.cyan or not Gl.colorsubset: |
| total = total + makesublist(big_hand, Gl.indices[0]) |
| if Gl.magenta or not Gl.colorsubset: |
| total = total + makesublist(little_hand, Gl.indices[1]) |
| if Gl.yellow or not Gl.colorsubset: |
| total = total + makesublist(MIDN, Gl.indices[2]) |
| total.sort() |
| return total |
| |
| def makesublist(first, icolor): |
| list = [] |
| alpha = FULLC/Gl.nparts |
| a = first - alpha/2 |
| for i in range(Gl.nparts): |
| angle = (a + i*alpha + FULLC) % FULLC |
| value = 255*(Gl.nparts-1-i)/(Gl.nparts-1) |
| list.append((angle, icolor, value)) |
| list.sort() |
| a, icolor, value = list[0] |
| if a <> 0: |
| a, icolor, value = list[len(list)-1] |
| t = 0, icolor, value |
| list.insert(0, t) |
| return list |
| |
| def rgb_fg(): |
| return Gl.fg |
| # Obsolete code: |
| if Gl.alarm_on: |
| return Gl.bg |
| else: |
| return Gl.fg |
| |
| def rgb_bg(): |
| return Gl.bg |
| # Obsolete code: |
| if Gl.alarm_on: |
| return Gl.fg |
| else: |
| return Gl.bg |
| |
| def clearall(): |
| Gl.c3i(rgb_bg()) |
| clear() |
| if Gl.doublebuffer: |
| swapbuffers() |
| clear() |
| |
| def draw_alarm(color): |
| frontbuffer(TRUE) |
| Gl.c3i(color) |
| pushmatrix() |
| rotate(-((Gl.alarm_time/12)%3600), 'z') |
| bgnpolygon() |
| v2f( 0.00,1.00) |
| v2f( 0.04,1.05) |
| v2f(-0.04,1.05) |
| endpolygon() |
| popmatrix() |
| # |
| pushmatrix() |
| rotate(-((Gl.alarm_time)%3600), 'z') |
| bgnpolygon() |
| v2f( 0.00,1.05) |
| v2f( 0.07,1.10) |
| v2f(-0.07,1.10) |
| endpolygon() |
| popmatrix() |
| # |
| cmov2(-1.06, -1.06) |
| charstr(string.rjust(`Gl.alarm_time/3600`,2)) |
| charstr(':') |
| charstr(string.zfill((Gl.alarm_time/60)%60,2)) |
| frontbuffer(FALSE) |
| |
| def render(list, (little_hand, big_hand, seconds_hand)): |
| # |
| if Gl.colormap: |
| resetindex() |
| # |
| if not list: |
| Gl.c3i((255, 255, 255)) # White |
| circf(0.0, 0.0, 1.0) |
| else: |
| list.append((3600, 0, 255)) # Sentinel |
| # |
| rgb = [255, 255, 255] |
| a_prev = 0 |
| for a, icolor, value in list: |
| if a <> a_prev: |
| [r, g, b] = rgb |
| if Gl.debug > 1: |
| print rgb, a_prev, a |
| Gl.c3i((r, g, b)) |
| arcf(0.0, 0.0, 1.0, a_prev, a) |
| rgb[icolor] = value |
| a_prev = a |
| # |
| if Gl.black or not Gl.colorsubset: |
| # |
| # Draw the hands -- in black |
| # |
| Gl.c3i((0, 0, 0)) |
| # |
| if Gl.update == 1 and not Gl.iconic: |
| # Seconds hand is only drawn if we update every second |
| pushmatrix() |
| rotate(seconds_hand, 'z') |
| bgnline() |
| v2f(0.0, 0.0) |
| v2f(1.0, 0.0) |
| endline() |
| popmatrix() |
| # |
| pushmatrix() |
| rotate(big_hand, 'z') |
| rectf(0.0, -0.01, 0.97, 0.01) |
| circf(0.0, 0.0, 0.01) |
| circf(0.97, 0.0, 0.01) |
| popmatrix() |
| # |
| pushmatrix() |
| rotate(little_hand, 'z') |
| rectf(0.04, -0.02, 0.63, 0.02) |
| circf(0.04, 0.0, 0.02) |
| circf(0.63, 0.0, 0.02) |
| popmatrix() |
| # |
| # Draw the alarm time, if set or being set |
| # |
| if Gl.alarm_set: |
| draw_alarm(rgb_fg()) |
| # |
| if Gl.doublebuffer: swapbuffers() |
| |
| def makewindow(): |
| # |
| if Gl.debug or Gl.foreground: |
| foreground() |
| # |
| if Gl.fullscreen: |
| scrwidth, scrheight = getgdesc(GD_XPMAX), getgdesc(GD_YPMAX) |
| prefposition(0, scrwidth-1, 0, scrheight-1) |
| else: |
| keepaspect(1, 1) |
| prefsize(80, 80) |
| # |
| if not Gl.border: |
| noborder() |
| wid = winopen(Gl.name) |
| wintitle(Gl.title) |
| # |
| if not Gl.fullscreen: |
| keepaspect(1, 1) |
| minsize(10, 10) |
| maxsize(2000, 2000) |
| iconsize(66, 66) |
| winconstraints() |
| # |
| nplanes = getplanes() |
| nmaps = getgdesc(GD_NMMAPS) |
| if Gl.warnings: |
| print nplanes, 'color planes,', nmaps, 'color maps' |
| # |
| if Gl.doublebuffer and not Gl.colormap and nplanes < 12: |
| if Gl.warnings: print 'forcing single buffer mode' |
| Gl.doublebuffer = 0 |
| # |
| if Gl.colormap: |
| if not Gl.colormap: |
| Gl.colormap = nmaps - 1 |
| if Gl.warnings: |
| print 'not enough color planes available', |
| print 'for RGB mode; forcing colormap mode' |
| print 'using color map number', Gl.colormap |
| if not Gl.colorsubset: |
| needed = 3 |
| else: |
| needed = Gl.cyan + Gl.magenta + Gl.yellow |
| needed = needed*Gl.nparts |
| if Gl.bg <> (0, 0, 0): |
| needed = needed+1 |
| if Gl.fg <> (0, 0, 0): |
| needed = needed+1 |
| if Gl.doublebuffer: |
| if needed > available(nplanes/2): |
| Gl.doublebuffer = 0 |
| if Gl.warnings: |
| print 'not enough colors available', |
| print 'for double buffer mode;', |
| print 'forcing single buffer mode' |
| else: |
| nplanes = nplanes/2 |
| if needed > available(nplanes): |
| # Do this warning always |
| print 'still not enough colors available;', |
| print 'parts will be left white' |
| print '(needed', needed, 'but have only', |
| print available(nplanes), 'colors available)' |
| # |
| if Gl.doublebuffer: |
| doublebuffer() |
| gconfig() |
| # |
| if Gl.colormap: |
| Gl.c3i = pseudo_c3i |
| fixcolormap() |
| else: |
| Gl.c3i = c3i |
| RGBmode() |
| gconfig() |
| # |
| if Gl.fullscreen: |
| # XXX Should find out true screen size using getgdesc() |
| ortho2(-1.1*1.280, 1.1*1.280, -1.1*1.024, 1.1*1.024) |
| else: |
| ortho2(-1.1, 1.1, -1.1, 1.1) |
| # |
| return wid |
| |
| def available(nplanes): |
| return pow(2, nplanes) - 1 # Reserve one pixel for black |
| |
| def fixcolormap(): |
| multimap() |
| gconfig() |
| nplanes = getplanes() |
| if Gl.warnings: |
| print 'multimap mode has', nplanes, 'color planes' |
| imap = Gl.colormap |
| Gl.startindex = pow(2, nplanes) - 1 |
| Gl.stopindex = 1 |
| setmap(imap) |
| mapcolor(0, 0, 0, 0) # Fixed entry for black |
| if Gl.bg <> (0, 0, 0): |
| r, g, b = Gl.bg |
| mapcolor(1, r, g, b) # Fixed entry for Gl.bg |
| Gl.stopindex = 2 |
| if Gl.fg <> (0, 0, 0): |
| r, g, b = Gl.fg |
| mapcolor(2, r, g, b) # Fixed entry for Gl.fg |
| Gl.stopindex = 3 |
| Gl.overflow_seen = 0 |
| resetindex() |
| |
| def resetindex(): |
| Gl.index = Gl.startindex |
| |
| r0g0b0 = (0, 0, 0) |
| |
| def pseudo_c3i(rgb): |
| if rgb == r0g0b0: |
| index = 0 |
| elif rgb == Gl.bg: |
| index = 1 |
| elif rgb == Gl.fg: |
| index = 2 |
| else: |
| index = definecolor(rgb) |
| color(index) |
| |
| def definecolor(rgb): |
| index = Gl.index |
| if index < Gl.stopindex: |
| if Gl.debug: print 'definecolor hard case', rgb |
| # First see if we already have this one... |
| for index in range(Gl.stopindex, Gl.startindex+1): |
| if rgb == getmcolor(index): |
| if Gl.debug: print 'return', index |
| return index |
| # Don't clobber reserverd colormap entries |
| if not Gl.overflow_seen: |
| # Shouldn't happen any more, hence no Gl.warnings test |
| print 'mclock: out of colormap entries' |
| Gl.overflow_seen = 1 |
| return Gl.stopindex |
| r, g, b = rgb |
| if Gl.debug > 1: print 'mapcolor', (index, r, g, b) |
| mapcolor(index, r, g, b) |
| Gl.index = index - 1 |
| return index |
| |
| # Compute n**i |
| def pow(n, i): |
| x = 1 |
| for j in range(i): x = x*n |
| return x |
| |
| def mouseclick(mouse, updown, x, y): |
| if updown == 1: |
| # mouse button came down, start tracking |
| if Gl.debug: |
| print 'mouse', mouse, 'down at', x, y |
| if mouse == 2: |
| Gl.mouse2down = 1 |
| mouse2track(x, y) |
| elif mouse == 3: |
| Gl.mouse3down = 1 |
| mouse3track(x, y) |
| else: |
| print 'fatal error' |
| qdevice(MOUSEX) |
| qdevice(MOUSEY) |
| return 0 |
| else: |
| # mouse button came up, stop tracking |
| if Gl.debug: |
| print 'mouse', mouse, 'up at', x, y |
| unqdevice(MOUSEX) |
| unqdevice(MOUSEY) |
| if mouse == 2: |
| mouse2track(x, y) |
| Gl.mouse2down = 0 |
| elif mouse == 3: |
| mouse3track(x, y) |
| Gl.mouse3down = 0 |
| else: |
| print 'fatal error' |
| Gl.alarm_set = 1 |
| return 1 |
| |
| def mouse3track(x, y): |
| # first compute polar coordinates from x and y |
| cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2 |
| x, y = x - cx, y - cy |
| if (x, y) == (0, 0): return # would cause an exception |
| minutes = int(30.5 + 30.0*math.atan2(float(-x), float(-y))/pi) |
| if minutes == 60: minutes = 0 |
| a,b = Gl.alarm_minutes/15, minutes/15 |
| if (a,b) == (0,3): |
| # Moved backward through 12 o'clock: |
| Gl.alarm_hours = Gl.alarm_hours - 1 |
| if Gl.alarm_hours < 0: Gl.alarm_hours = Gl.alarm_hours + 24 |
| if (a,b) == (3,0): |
| # Moved forward through 12 o'clock: |
| Gl.alarm_hours = Gl.alarm_hours + 1 |
| if Gl.alarm_hours >= 24: Gl.alarm_hours = Gl.alarm_hours - 24 |
| Gl.alarm_minutes = minutes |
| seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE |
| if seconds <> Gl.alarm_time: |
| draw_alarm(rgb_bg()) |
| Gl.alarm_time = seconds |
| draw_alarm(rgb_fg()) |
| |
| def mouse2track(x, y): |
| # first compute polar coordinates from x and y |
| cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2 |
| x, y = x - cx, y - cy |
| if (x, y) == (0, 0): return # would cause an exception |
| hours = int(6.5 - float(Gl.alarm_minutes)/60.0 + 6.0*math.atan2(float(-x), float(-y))/pi) |
| if hours == 12: hours = 0 |
| if (Gl.alarm_hours,hours) == (0,11): |
| # Moved backward through midnight: |
| Gl.alarm_hours = 23 |
| elif (Gl.alarm_hours,hours) == (12,11): |
| # Moved backward through noon: |
| Gl.alarm_hours = 11 |
| elif (Gl.alarm_hours,hours) == (11,0): |
| # Moved forward through noon: |
| Gl.alarm_hours = 12 |
| elif (Gl.alarm_hours,hours) == (23,0): |
| # Moved forward through midnight: |
| Gl.alarm_hours = 0 |
| elif Gl.alarm_hours < 12: |
| Gl.alarm_hours = hours |
| else: |
| Gl.alarm_hours = hours + 12 |
| seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE |
| if seconds <> Gl.alarm_time: |
| draw_alarm(rgb_bg()) |
| Gl.alarm_time = seconds |
| draw_alarm(rgb_fg()) |
| |
| def initmenu(): |
| Gl.pup = pup = newpup() |
| addtopup(pup, 'M Clock%t|Alarm On/Off|Seconds Hand On/Off|Quit', 0) |
| |
| def handlemenu(): |
| item = dopup(Gl.pup) |
| if item == 1: |
| # Toggle alarm |
| if Gl.alarm_set: |
| Gl.alarm_set = 0 |
| Gl.alarm_on = 0 |
| else: |
| Gl.alarm_set = 1 |
| Gl.change = 1 |
| clearall() |
| elif item == 2: |
| # Toggle Seconds Hand |
| if Gl.update == 1: |
| Gl.update = 60 |
| Gl.timernoise = 60 |
| else: |
| Gl.update = 1 |
| Gl.timernoise = 6 |
| Gl.change = 1 |
| elif item == 3: |
| if Gl.debug: print 'Exit' |
| sys.exit(0) |
| |
| main() |