#!/usr/bin/env python # (c) 2007 Simon Budig # Minutenstrich: 2 x 5 # Stundenstrich: 4 x 15 # Viertelstundenstrich: 4 x 17.5 # # Minutenzeiger: 4 x (15 + 55 + rechter Winkel) # Stundenzeiger: 7 x (15 + 37.5 + rechter Winkel) # # Aussenradius Markierungen: 60 # Radius insgesamt: 70 import gobject, gtk, cairo import math, time show_seconds = True class Values(object): pass def key_press_event (win, event, val): if event.string in ['q', 'Q']: gtk.main_quit () elif event.string in ['f', 'F']: val.full = not val.full if val.full: win.fullscreen () else: win.unfullscreen () else: return False return True def update_time (val): val.win.queue_draw () return True def expose_event (win, event, val): w, h = win.get_size () cr = win.window.cairo_create () cr.rectangle (*event.area) cr.clip () cr.translate (w/2.0, h/2.0) cr.scale (min (w/2., h/2.), -min (w/2., h/2.)) cr.scale (1./75, 1./75) cr.set_source_rgb (0.3, 0.3, 0.3) cr.arc (0, 0, 70, 0, 2 * math.pi) cr.fill () cr.set_source_rgb (1.0, 1.0, 1.0) cr.arc (0, 0, 60 + 20./3, 0, 2 * math.pi) cr.fill () cr.set_source_rgb (0.8, 0.8, 0.8) cr.arc (0, 0, 60 + 10./3, 0, 2 * math.pi) cr.fill () cr.set_source_rgb (0.15, 0.15, 0.15) for i in range (60): cr.save () cr.rotate (i * 6. / 180 * math.pi) if i % 15 == 0: cr.rectangle (60-17.5, -2, 17.5, 4) elif i % 5 == 0: cr.rectangle (60-15, -2, 15, 4) else: cr.rectangle (60-5, -1, 5, 2) cr.fill () cr.restore () t = time.localtime() s = t[5] + time.time() % 1 if show_seconds: m = t[4] else: m = t[4] + s / 60. h = t[3] % 12 + m / 60. cr.set_source_rgb (0.1, 0.1, 0.1) cr.save () cr.rotate ((90 - h * 30) / 180 * math.pi) cr.move_to (-15, 3.5) cr.line_to (37.5, 3.5) cr.line_to (41, 0) cr.line_to (37.5, -3.5) cr.line_to (-15, -3.5) cr.close_path () cr.fill () cr.restore () cr.set_source_rgb (0.05, 0.05, 0.05) cr.save () cr.rotate ((90 - m * 6.) / 180 * math.pi) cr.move_to (-15, 2) cr.line_to (55, 2) cr.line_to (57, 0) cr.line_to (55, -2) cr.line_to (-15, -2) cr.close_path () cr.fill () cr.restore () if show_seconds: s, ds = divmod (min (60., s / 58.5*60), 1) if ds < 0.5: ds = (ds*2)**2 / 2 else: ds = 1 - ((1-ds)*2)**2 / 2 cr.set_source_rgb (0.9, 0.1, 0.1) cr.save () cr.rotate ((90 - (s+ds) * 6) / 180 * math.pi) cr.arc (35, 0, 7, 0, 2 * math.pi) cr.arc_negative (35, 0, 4, 2 * math.pi, 0) cr.move_to (-16, -1.5) cr.line_to (30, -1.03) cr.line_to (30, 1.03) cr.line_to (-16, 1.5) cr.new_sub_path () cr.move_to (40, -0.93) cr.line_to (57.25, -0.75) cr.line_to (58, 0) cr.line_to (57.25, 0.75) cr.line_to (40, 0.93) cr.close_path () cr.fill () cr.restore () return True def setup_ui (val): win = gtk.Window () win.set_default_size (150, 150) win.set_decorated (False) win.set_events (gtk.gdk.EXPOSURE_MASK | gtk.gdk.KEY_PRESS_MASK) win.connect ("expose-event", expose_event, val) win.connect ("key-press-event", key_press_event, val) win.connect ("delete-event", gtk.main_quit) win.show_all () val.full = False val.win = win if __name__=='__main__': val = Values () setup_ui (val) if show_seconds: gobject.timeout_add (40, update_time, val) else: gobject.timeout_add (250, update_time, val) gtk.main ()