[Desktop Entry] Name=Python Cairo Clock Type=python X-Path=pyclock
import sys import gobject import pango import pygtk pygtk.require('2.0') import gtk from gtk import gdk import hildondesktop import cairo from datetime import datetime import gobject import math # set this to False to disable display of seconds and update # only once per minute (saves CPU cycles on the tablet) enable_seconds = True supports_alpha = False class PyClock(hildondesktop.HomeItem): def __init__(self): hildondesktop.HomeItem.__init__(self) self.set_resize_type(hildondesktop.HOME_ITEM_RESIZE_BOTH) self.set_size_request(140, 140) self.connect("expose-event", self.expose) self.connect("screen-changed", self.screen_changed) self.connect ("background", self.set_timer, False) self.connect ("foreground", self.set_timer, True) self.connect ("unrealize", self.unrealize) # set a timeout to update the clock, depending # on whether we are in the foreground or background self.timer = None self.set_timer(self, True) self.show_all() def expose(self, widget, event): global supports_alpha width, height = self.allocation[2], self.allocation[3] #Get a cairo context cr = widget.window.cairo_create() if supports_alpha == True: cr.set_source_rgba(1.0, 1.0, 1.0, 0.0) # Transparent else: cr.set_source_rgb(1.0, 1.0, 1.0) # Opaque white # Draw the background cr.set_operator(cairo.OPERATOR_SOURCE) cr.paint() #And draw everything we want #Some cos/sin magic is done, never mind if supports_alpha == True: cr.set_source_rgba(1.0, 1.0, 1.0, 0.5) else: cr.set_source_rgb(1.0, 1.0, 1.0) if width < height: radius = float(width)/2 - 0.8 else: radius = float(height)/2 - 0.8 cr.arc(float(width)/2, float(height)/2, radius, 0, 2.0*3.14) cr.fill() cr.stroke() if supports_alpha == True: cr.set_source_rgba(0.0, 0.0, 0.0, 1.0) else: cr.set_source_rgb(0.0, 0.0, 0.0) cr.set_line_width(0.07 * radius) cr.move_to(-0.05 * radius + float(width/2 + radius), float(height)/2) cr.rel_line_to(-0.1 * radius, 0) cr.stroke() cr.move_to(float(width)/2, -0.05 * radius + float(height/2 + radius)) cr.rel_line_to(0, -0.1 * radius) cr.stroke() cr.move_to(0.05 * radius + float(width/2 - radius), float(height)/2) cr.rel_line_to(0.1 * radius, 0) cr.stroke() cr.move_to(float(width)/2, 0.05 * radius + float(height/2 - radius)) cr.rel_line_to(0, 0.1 * radius) cr.stroke() time = datetime.now() hour = time.hour minutes = time.minute seconds = time.second per_hour = (2 * 3.14) / 12 dh = (hour * per_hour) + ((per_hour / 60) * minutes) dh += 2 * 3.14 / 4 cr.set_line_width(0.07 * radius) cr.move_to(float(width)/2, float(height)/2) cr.rel_line_to(-0.6 * radius * math.cos(dh), -0.6 * radius * math.sin(dh)) cr.stroke() per_minute = (2 * 3.14) / 60 dm = minutes * per_minute dm += 2 * 3.14 / 4 cr.set_line_width(0.05 * radius) cr.move_to(float(width)/2, float(height)/2) cr.rel_line_to(-0.9 * radius * math.cos(dm), -0.9 * radius * math.sin(dm)) cr.stroke() # only draw seconds when in foreground if enable_seconds: # disable seconds, to much work for little tablets per_second = (2 * 3.14) / 60 ds = seconds * per_second ds += 2 * 3.14 / 4 cr.set_line_width(0.02 * radius) cr.move_to(float(width)/2, float(height)/2) cr.rel_line_to(-0.9 * radius * math.cos(ds), -0.9 * radius * math.sin(ds)) cr.stroke() cr.arc(float(width)/2, float(height)/2, 0.1 * radius, 0, 2.0*3.14) cr.fill() cr.stroke() #Once everything has been drawn, create our XShape mask #Our window content is contained inside the big circle, #so let's use that one as our mask """pm = gtk.gdk.Pixmap(None, width, height, 1) pmcr = pm.cairo_create() pmcr.arc(float(width)/2, float(height)/2, radius, 0, 2.0*3.14) pmcr.fill() pmcr.stroke() #Apply input mask self.input_shape_combine_mask(pm, 0, 0)""" return False def screen_changed(self, widget, old_screen=None): global supports_alpha # print "screen changed" # To check if the display supports alpha channels, get the colormap screen = self.get_screen() colormap = screen.get_rgba_colormap() if colormap == None: # print 'Your screen does not support alpha channels!' colormap = screen.get_rgb_colormap() supports_alpha = False else: # print 'Your screen supports alpha channels!' supports_alpha = True # Now we have a colormap appropriate for the screen, use it self.set_colormap(colormap) return False def unrealize(self, widget, date=None): # cancel timeout if self.timer: v = gobject.source_remove(self.timer) print "canceled pyclock timeout:", v self.timer = None def set_timer(self, widget, on): # when called first time from __init__ widget is None if self.timer != None: # print "removing old timer" gobject.source_remove(self.timer) if on: # print "creating new timer" delay = 1000 if enable_seconds else 60000 self.timer = gobject.timeout_add(delay, self.update) # repaint immediately when coming to the foreground self.update() def update(self): # print "updating pyclock" self.queue_draw() return True def hd_plugin_get_objects(): plugin = PyClock() return [plugin]