~jconti/recent-notifications/trunk

« back to all changes in this revision

Viewing changes to unity/RoundedWidgets.py

  • Committer: Jason Conti
  • Date: 2011-04-23 18:59:12 UTC
  • Revision ID: jason.conti@gmail.com-20110423185912-ggrbhv0hoa1lmcru
Using a bit of cairo to display icons with rounded edges and message items with rounded backgrounds. Still need to get the proper colors from the gtk theme and possibly add options for custom colors.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
RoundedWidgets.py
 
3
April 22, 2011
 
4
 
 
5
Custom widgets that have rounded edges
 
6
"""
 
7
 
 
8
import logging
 
9
import math
 
10
 
 
11
from gi.repository import Gdk, GdkPixbuf, GObject, Gtk
 
12
 
 
13
logger = logging.getLogger("RoundedWidgets")
 
14
 
 
15
# Angles in pi/2 increments 
 
16
A0 = 0
 
17
A1 = math.pi / 2.0
 
18
A2 = math.pi
 
19
A3 = 3.0 * math.pi / 2.0
 
20
A4 = 2.0 * math.pi
 
21
 
 
22
def draw_rounded_box(cr, x, y, width, height, radius):
 
23
  """Draws a rounded box to a cairo context, but doesn't fill or stroke it
 
24
  so it can be used as a clipping region as well."""
 
25
  x1 = x
 
26
  y1 = y
 
27
  w = width
 
28
  h = height
 
29
  x2 = x1 + w
 
30
  y2 = y1 + h
 
31
  r = radius
 
32
 
 
33
  cr.move_to(x1 + r, y1)
 
34
  cr.line_to(x2 - r, y1)
 
35
  cr.arc(x2 - r, y1 + r, r, A3, A4)
 
36
  cr.line_to(x2, y2 - r)
 
37
  cr.arc(x2 - r, y2 - r, r, A0, A1)
 
38
  cr.line_to(x1 + r, y2)
 
39
  cr.arc(x1 + r, y2 - r, r, A1, A2)
 
40
  cr.line_to(x1, y1 + r)
 
41
  cr.arc(x1 + r, y1 + r, r, A2, A3)
 
42
 
 
43
class RoundedBox(Gtk.Box):
 
44
  """A simple container that draws a solid background with rounded edges"""
 
45
  def __init__(self, r = 0.75, g = 0.75, b = 0.75, radius = 10):
 
46
    GObject.GObject.__init__(self)
 
47
 
 
48
    self._r = r
 
49
    self._g = g
 
50
    self._b = b
 
51
    self._radius = radius
 
52
 
 
53
    self.set_double_buffered(False)
 
54
    self.set_redraw_on_allocate(True)
 
55
 
 
56
  def set_color(self, r, g, b):
 
57
    """Sets the background color of this box"""
 
58
    self._r = r
 
59
    self._g = g
 
60
    self._b = b
 
61
    self.queue_draw()
 
62
 
 
63
  def get_color(self):
 
64
    """Gets the background color of this box as a tuple (r, g, b)"""
 
65
    return (self._r, self._g, self._b)
 
66
 
 
67
  def set_radius(self, radius):
 
68
    """Sets the radius of the curved edges of this box"""
 
69
    self._radius = radius
 
70
    self.queue_draw()
 
71
 
 
72
  def get_radius(self):
 
73
    """Gets the radius of the curved edges of this box"""
 
74
    return self._radius
 
75
 
 
76
  def do_expose_event(self, event):
 
77
    """Draws the background and propagates the event to the children"""
 
78
    window = self.get_window()
 
79
    alloc = self.get_allocation()
 
80
    cr = window.cairo_create()
 
81
 
 
82
    # Set the clipping region
 
83
    cr.rectangle(event.area.x, event.area.y, event.area.width,
 
84
        event.area.height)
 
85
    cr.clip()
 
86
 
 
87
    cr.set_source_rgb(self._r, self._g, self._b)
 
88
 
 
89
    # Draw the rounded box
 
90
    draw_rounded_box(cr, alloc.x, alloc.y, alloc.width, alloc.height,
 
91
        self._radius)
 
92
    cr.fill()
 
93
 
 
94
    # Propagate the event to the children
 
95
    for child in self.get_children():
 
96
      self.propagate_expose(child, event)
 
97
 
 
98
class RoundedIcon(Gtk.Widget):
 
99
  """Draws a pixbuf with rounded edges"""
 
100
  def __init__(self, pixbuf = None, radius = 10):
 
101
    GObject.GObject.__init__(self)
 
102
 
 
103
    self._pixbuf = pixbuf
 
104
    self._radius = radius
 
105
 
 
106
    self.set_has_window(False)
 
107
    self.set_double_buffered(False)
 
108
    self.set_redraw_on_allocate(True)
 
109
 
 
110
  def set_from_pixbuf(self, pixbuf):
 
111
    """Sets the icon from a pixbuf"""
 
112
    self._pixbuf = pixbuf
 
113
 
 
114
  def do_expose_event(self, event):
 
115
    """Draws the pixbuf"""
 
116
    pixbuf = self._pixbuf
 
117
    if pixbuf == None:
 
118
      return
 
119
 
 
120
    window = self.get_window()
 
121
    alloc = self.get_allocation()
 
122
    cr = window.cairo_create()
 
123
 
 
124
    w = pixbuf.get_width()
 
125
    h = pixbuf.get_height()
 
126
 
 
127
    if alloc.width < w or alloc.height < h:
 
128
      self.set_size_request(w, h)
 
129
      return
 
130
 
 
131
    cr.translate(alloc.x, alloc.y)
 
132
 
 
133
    draw_rounded_box(cr, 0, 0,
 
134
        w, h,
 
135
        self._radius)
 
136
    cr.clip()
 
137
 
 
138
    Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0)
 
139
    cr.paint()
 
140