5
Custom widgets that have rounded edges
11
from gi.repository import Gdk, GdkPixbuf, GObject, Gtk
13
from Theme import Color
15
logger = logging.getLogger("RoundedWidgets")
17
# Angles in pi/2 increments
21
A3 = 3.0 * math.pi / 2.0
24
def draw_rounded_box(cr, x, y, width, height, radius):
25
"""Draws a rounded box to a cairo context, but doesn't fill or stroke it
26
so it can be used as a clipping region as well."""
35
cr.move_to(x1 + r, y1)
36
cr.line_to(x2 - r, y1)
37
cr.arc(x2 - r, y1 + r, r, A3, A4)
38
cr.line_to(x2, y2 - r)
39
cr.arc(x2 - r, y2 - r, r, A0, A1)
40
cr.line_to(x1 + r, y2)
41
cr.arc(x1 + r, y2 - r, r, A1, A2)
42
cr.line_to(x1, y1 + r)
43
cr.arc(x1 + r, y1 + r, r, A2, A3)
45
class RoundedBox(Gtk.Box):
46
"""A simple container that draws a solid background with rounded edges"""
47
BACKGROUND_COLOR = Color("#fff")
48
def __init__(self, radius = 10):
49
GObject.GObject.__init__(self)
53
self.set_double_buffered(False)
54
self.set_redraw_on_allocate(True)
56
def set_radius(self, radius):
57
"""Sets the radius of the curved edges of this box"""
62
"""Gets the radius of the curved edges of this box"""
65
def do_expose_event(self, event):
66
"""Draws the background and propagates the event to the children"""
67
window = self.get_window()
68
alloc = self.get_allocation()
69
cr = window.cairo_create()
71
# Set the clipping region
72
cr.rectangle(event.area.x, event.area.y, event.area.width,
77
color = RoundedBox.BACKGROUND_COLOR
78
cr.set_source_rgb(color.red, color.green, color.blue)
80
# Draw the rounded box
81
draw_rounded_box(cr, alloc.x, alloc.y, alloc.width, alloc.height,
85
# Propagate the event to the children
86
for child in self.get_children():
87
self.propagate_expose(child, event)
89
class RoundedIcon(Gtk.Widget):
90
"""Draws a pixbuf with rounded edges"""
91
def __init__(self, pixbuf = None, radius = 10):
92
GObject.GObject.__init__(self)
97
self.set_has_window(False)
98
self.set_double_buffered(False)
99
self.set_redraw_on_allocate(True)
101
def set_from_pixbuf(self, pixbuf):
102
"""Sets the icon from a pixbuf"""
103
self._pixbuf = pixbuf
105
def do_expose_event(self, event):
106
"""Draws the pixbuf"""
107
pixbuf = self._pixbuf
111
window = self.get_window()
112
alloc = self.get_allocation()
113
cr = window.cairo_create()
115
w = pixbuf.get_width()
116
h = pixbuf.get_height()
118
if alloc.width < w or alloc.height < h:
119
self.set_size_request(w, h)
122
cr.translate(alloc.x, alloc.y)
124
draw_rounded_box(cr, 0, 0,
129
Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0)