The clock.py
original by Ralph Glass
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gobject
import pango
import gtk
import math
import time
from gtk import gdk
try:
import cairo
except ImportError:
pass
if gtk.pygtk_version < (2,3,93):
print "PyGtk 2.3.93 or later required"
raise SystemExit
TEXT = 'cairo'
BORDER_WIDTH = 10
def progress_timeout(object):
x, y, w, h = object.allocation
object.window.invalidate_rect((0,0,w,h),False)
return True
class PyGtkWidget(gtk.Widget):
__gsignals__ = { 'realize': 'override',
'expose-event' : 'override',
'size-allocate': 'override',
'size-request': 'override',}
def __init__(self):
gtk.Widget.__init__(self)
self.draw_gc = None
self.layout = self.create_pango_layout(TEXT)
self.layout.set_font_description(pango.FontDescription("sans serif 8"))
self.timer = gobject.timeout_add (1000, progress_timeout, self)
def do_realize(self):
self.set_flags(self.flags() | gtk.REALIZED)
self.window = gdk.Window(self.get_parent_window(),
width=self.allocation.width,
height=self.allocation.height,
window_type=gdk.WINDOW_CHILD,
wclass=gdk.INPUT_OUTPUT,
event_mask=self.get_events() | gdk.EXPOSURE_MASK)
if not hasattr(self.window, "cairo_create"):
self.draw_gc = gdk.GC(self.window,
line_width=5,
line_style=gdk.SOLID,
join_style=gdk.JOIN_ROUND)
self.window.set_user_data(self)
self.style.attach(self.window)
self.style.set_background(self.window, gtk.STATE_NORMAL)
self.window.move_resize(*self.allocation)
def do_size_request(self, requisition):
width, height = self.layout.get_size()
requisition.width = (width // pango.SCALE + BORDER_WIDTH*4)* 1.45
requisition.height = (3 * height // pango.SCALE + BORDER_WIDTH*4) * 1.2
def do_size_allocate(self, allocation):
self.allocation = allocation
if self.flags() & gtk.REALIZED:
self.window.move_resize(*allocation)
def _expose_gdk(self, event):
x, y, w, h = self.allocation
self.layout = self.create_pango_layout('no cairo')
fontw, fonth = self.layout.get_pixel_size()
self.style.paint_layout(self.window, self.state, False,
event.area, self, "label",
(w - fontw) / 2, (h - fonth) / 2,
self.layout)
def _expose_cairo(self, event, cr):
# time
hours = time.localtime().tm_hour
minutes = time.localtime().tm_min
secs = time.localtime().tm_sec
minute_arc = (2*math.pi / 60) * minutes
if hours > 12:
hours = hours - 12
hour_arc = (2*math.pi / 12) * hours + minute_arc / 12
# clock background
x, y, w, h = self.allocation
cr.set_source_rgba(1, 0.2, 0.2, 0.6)
cr.arc(w/2, h/2, min(w,h)/2 - 8 , 0, 2 * 3.14)
cr.fill()
cr.stroke()
# center arc
cr.set_source_color(self.style.fg[self.state])
cr.arc ( w/2, h/2, (min(w,h)/2 -20) / 5, 0, 2 * math.pi)
cr.fill()
cr.line_to(w/2,h/2)
cr.stroke()
# pointer hour
cr.set_source_color(self.style.fg[self.state])
cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
cr.set_line_width ((min(w,h)/2 -20)/6 )
cr.move_to(w/2,h/2)
cr.line_to(w/2 + (min(w,h)/2 -20) * 0.6 * math.cos(hour_arc - math.pi/2),
h/2 + (min(w,h)/2 -20) * 0.6 * math.sin(hour_arc - math.pi/2))
cr.stroke()
# pointer minute
cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
cr.set_line_width ((min(w,h)/2 -20)/6 * 0.8)
cr.move_to(w/2,h/2)
cr.line_to(w/2 + (min(w,h)/2 -20) * 0.8 * math.cos(minute_arc - math.pi/2),
h/2 + (min(w,h)/2 -20) * 0.8 * math.sin(minute_arc - math.pi/2))
cr.stroke()
# pango layout
fontw, fonth = self.layout.get_pixel_size()
cr.move_to((w - fontw - 4), (h - fonth ))
cr.update_layout(self.layout)
cr.show_layout(self.layout)
def do_expose_event(self, event):
self.chain(event)
try:
cr = self.window.cairo_create()
except AttributeError:
return self._expose_gdk(event)
return self._expose_cairo(event, cr)
win = gtk.Window()
win.set_title('clock')
win.connect('delete-event', gtk.main_quit)
event_box = gtk.EventBox()
event_box.connect("button_press_event", lambda w,e: win.set_decorated(not win.get_decorated()))
win.add(event_box)
w = PyGtkWidget()
event_box.add(w)
win.move(gtk.gdk.screen_width() - 120, 40)
win.show_all()
gtk.main()
ClockGramplet.gpr.py by Doug Blank
register(GRAMPLET,
id= "Clock Gramplet",
name=_("Clock"),
description = _("Gramplet for demonstrating Cairo graphics"),
height=100,
expand=False,
gramplet = 'ClockGramplet',
gramplet_title=_("Clock"),
status = STABLE,
version = '0.0.32',
gramps_target_version = "5.1",
fname="ClockGramplet.py",
help_url="Gramplets#GUI_Interface",
)
ClockGramplet.py as adapted by Doug Blank
# Clock Example by Ralph Glass
# http://ralph-glass.homepage.t-online.de/clock/readme.html
from gi.repository import PangoCairo
from gi.repository import GObject
from gi.repository import Gtk
import math
import time
from gramps.gen.constfunc import is_quartz
TEXT = 'cairo'
BORDER_WIDTH = 10
class ClockWidget(Gtk.DrawingArea):
def __init__(self):
Gtk.DrawingArea.__init__(self)
self.connect("draw", self.on_draw)
self.timer = GObject.timeout_add(1000, self.tick)
def on_draw(self, widget, cr):
layout = PangoCairo.create_layout(cr)
if is_quartz():
PangoCairo.context_set_resolution(layout.get_context(), 72)
layout.set_font_description(self.get_style().font_desc)
layout.set_markup(TEXT, -1)
fontw, fonth = layout.get_pixel_size()
xmin = fontw + BORDER_WIDTH
ymin = fonth + BORDER_WIDTH
self.set_size_request(xmin, ymin)
# time
hours = time.localtime().tm_hour
minutes = time.localtime().tm_min
secs = time.localtime().tm_sec
second_arc = (2*math.pi / 60) * secs
minute_arc = (2*math.pi / 60) * minutes
if hours > 12:
hours = hours - 12
hour_arc = (2*math.pi / 12) * hours + minute_arc / 12
# clock background
alloc = self.get_allocation()
x = alloc.x
y = alloc.y
w = alloc.width
h = alloc.height
cr.set_source_rgba(1, 0.2, 0.2, 0.6)
cr.arc(w/2, h/2, min(w,h)/2 - 8 , 0, 2 * 3.14)
cr.fill()
cr.stroke()
# center arc
cr.set_source_rgb(0, 0, 0)
cr.arc ( w/2, h/2, (min(w,h)/2 -20) / 5, 0, 2 * math.pi)
cr.fill()
cr.line_to(w/2,h/2)
cr.stroke()
# pointer hour
cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
cr.set_line_width ((min(w,h)/2 -20)/6 )
cr.move_to(w/2,h/2)
cr.line_to(w/2 + (min(w,h)/2 -20) * 0.6 * math.cos(hour_arc - math.pi/2),
h/2 + (min(w,h)/2 -20) * 0.6 * math.sin(hour_arc - math.pi/2))
cr.stroke()
# pointer minute
cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
cr.set_line_width ((min(w,h)/2 -20)/6 * 0.8)
cr.move_to(w/2,h/2)
cr.line_to(w/2 + (min(w,h)/2 -20) * 0.8 * math.cos(minute_arc - math.pi/2),
h/2 + (min(w,h)/2 -20) * 0.8 * math.sin(minute_arc - math.pi/2))
cr.stroke()
# pointer second
cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
cr.set_line_width ((min(w,h)/2 -20)/6 * 0.4)
cr.move_to(w/2,h/2)
cr.line_to(w/2 + (min(w,h)/2 -20) * math.cos(second_arc - math.pi/2),
h/2 + (min(w,h)/2 -20) * math.sin(second_arc - math.pi/2))
cr.stroke()
# pango layout
cr.move_to((w - fontw - 4), (h - fonth ))
PangoCairo.show_layout(cr, layout)
def tick(self):
self.queue_draw()
return True
# Clock Integrated with Gramplets
# (c) 2009, Doug Blank
from gramps.gen.plug import Gramplet
class ClockGramplet(Gramplet):
def init(self):
self.gui.clock = ClockWidget()
self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add_with_viewport(self.gui.clock)
self.gui.clock.show()