Package screenlets :: Module drawing
[hide private]
[frames] | no frames]

Source Code for Module screenlets.drawing

  1  # This application is released under the GNU General Public License  
  2  # v3 (or, at your option, any later version). You can find the full  
  3  # text of the license under http://www.gnu.org/licenses/gpl.txt.  
  4  # By using, editing and/or distributing this software you agree to  
  5  # the terms and conditions of this license.  
  6  # Thank you for using free software! 
  7   
  8  # Screenlets Drawing Helder Fraga aka Whise <helder.fraga@hotmail.com> 
  9   
 10   
 11  import gtk, cairo, pango, math 
 12   
13 -class Drawing(object):
14 """Contains static drawing functions.""" 15 16 # ---------------------------------------------------------------------- 17 # Screenlet's Drawing functions 18 # ---------------------------------------------------------------------- 19 p_context = None # PangoContext 20 p_layout = None # PangoLayout 21
22 - def get_text_width(self, ctx, text, font):
23 """Returns the pixel width of a given text""" 24 ctx.save() 25 if self.p_layout == None : 26 27 self.p_layout = ctx.create_layout() 28 else: 29 30 ctx.update_layout(self.p_layout) 31 if self.p_fdesc == None:self.p_fdesc = pango.FontDescription() 32 else: pass 33 self.p_fdesc.set_family_static(font) 34 self.p_layout.set_font_description(self.p_fdesc) 35 self.p_layout.set_text(text) 36 extents, lextents = self.p_layout.get_pixel_extents() 37 ctx.restore() 38 return extents[2]
39
40 - def get_text_height(self, ctx, text, font):
41 """Returns the pixel height of a given text""" 42 ctx.save() 43 if self.p_layout == None : 44 45 self.p_layout = ctx.create_layout() 46 else: 47 48 ctx.update_layout(self.p_layout) 49 if self.p_fdesc == None:self.p_fdesc = pango.FontDescription() 50 else: pass 51 self.p_fdesc.set_family_static(font) 52 self.p_layout.set_font_description(self.p_fdesc) 53 self.p_layout.set_text(text) 54 extents, lextents = self.p_layout.get_pixel_extents() 55 ctx.restore() 56 return extents[3]
57
58 - def get_text_line_count(self, ctx, text, font, size = None):
59 """Returns the line count of a given text""" 60 ctx.save() 61 if self.p_layout == None : 62 63 self.p_layout = ctx.create_layout() 64 else: 65 66 ctx.update_layout(self.p_layout) 67 if self.p_fdesc == None:self.p_fdesc = pango.FontDescription() 68 else: pass 69 self.p_fdesc.set_family_static(font) 70 if size is not None: 71 self.p_fdesc.set_size(size * pango.SCALE) 72 else: pass 73 self.p_layout.set_font_description(self.p_fdesc) 74 self.p_layout.set_text(text) 75 ctx.restore() 76 return self.p_layout.get_line_count()
77
78 - def get_text_line(self, ctx, text, font, line):
79 """Returns a line of a given text""" 80 ctx.save() 81 if self.p_layout == None : 82 83 self.p_layout = ctx.create_layout() 84 else: 85 86 ctx.update_layout(self.p_layout) 87 if self.p_fdesc == None:self.p_fdesc = pango.FontDescription() 88 else: pass 89 self.p_fdesc.set_family_static(font) 90 self.p_layout.set_font_description(self.p_fdesc) 91 self.p_layout.set_text(text) 92 ctx.restore() 93 return self.p_layout.get_line(line)
94
95 - def check_for_icon(self,icon):
96 try: 97 icontheme = gtk.icon_theme_get_default() 98 image = icontheme.load_icon (icon,32,32) 99 image = None 100 icontheme = None 101 return True 102 except: 103 return False
104
105 - def draw_text(self, ctx, text, x, y, font, size, width, allignment=pango.ALIGN_LEFT,alignment=None,justify = False,weight = 0, ellipsize = pango.ELLIPSIZE_NONE):
106 """Draws text""" 107 size = int(size) 108 109 ctx.save() 110 ctx.translate(x, y) 111 if self.p_layout == None : 112 113 self.p_layout = ctx.create_layout() 114 else: 115 116 ctx.update_layout(self.p_layout) 117 if self.p_fdesc == None:self.p_fdesc = pango.FontDescription() 118 else: pass 119 self.p_fdesc.set_family_static(font) 120 self.p_fdesc.set_size(size * pango.SCALE) 121 self.p_fdesc.set_weight(weight) 122 self.p_layout.set_font_description(self.p_fdesc) 123 self.p_layout.set_width(width * pango.SCALE) 124 self.p_layout.set_alignment(allignment) 125 if alignment != None:self.p_layout.set_alignment(alignment) 126 self.p_layout.set_justify(justify) 127 self.p_layout.set_ellipsize(ellipsize) 128 self.p_layout.set_markup(text) 129 ctx.show_layout(self.p_layout) 130 ctx.restore()
131 132
133 - def draw_circle(self,ctx,x,y,width,height,fill=True):
134 """Draws a circule""" 135 ctx.save() 136 ctx.translate(x, y) 137 ctx.arc(width/2,height/2,min(height,width)/2,0,2*math.pi) 138 if fill:ctx.fill() 139 else: ctx.stroke() 140 ctx.restore()
141 142
143 - def draw_triangle(self,ctx,x,y,width,height,fill=True):
144 """Draws a circule""" 145 ctx.save() 146 ctx.translate(x, y) 147 ctx.move_to(width-(width/3), height/3) 148 ctx.line_to(width,height) 149 ctx.rel_line_to(-(width-(width/3)), 0) 150 ctx.close_path() 151 if fill:ctx.fill() 152 else: ctx.stroke() 153 ctx.restore()
154
155 - def draw_line(self,ctx,start_x,start_y,end_x,end_y,line_width = 1,close=False,preserve=False):
156 """Draws a line""" 157 ctx.save() 158 ctx.move_to(start_x, start_y) 159 ctx.set_line_width(line_width) 160 ctx.rel_line_to(end_x, end_y) 161 if close : ctx.close_path() 162 if preserve: ctx.stroke_preserve() 163 else: ctx.stroke() 164 ctx.restore()
165
166 - def draw_rectangle(self,ctx,x,y,width,height,fill=True):
167 """Draws a rectangle""" 168 ctx.save() 169 ctx.translate(x, y) 170 ctx.rectangle (0,0,width,height) 171 if fill:ctx.fill() 172 else: ctx.stroke() 173 ctx.restore()
174 175
176 - def draw_rectangle_advanced (self, ctx, x, y, width, height, rounded_angles=(0,0,0,0), fill=True, border_size=0, border_color=(0,0,0,1), shadow_size=0, shadow_color=(0,0,0,0.5)):
177 '''with this funktion you can create a rectangle in advanced mode''' 178 ctx.save() 179 ctx.translate(x, y) 180 s = shadow_size 181 w = width 182 h = height 183 rounded = rounded_angles 184 if shadow_size > 0: 185 ctx.save() 186 #top shadow 187 gradient = cairo.LinearGradient(0,s,0,0) 188 gradient.add_color_stop_rgba(0,*shadow_color) 189 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 190 ctx.set_source(gradient) 191 ctx.rectangle(s+rounded[0],0, w-rounded[0]-rounded[1], s) 192 ctx.fill() 193 194 #bottom 195 gradient = cairo.LinearGradient(0, s+h, 0, h+(s*2)) 196 gradient.add_color_stop_rgba(0,*shadow_color) 197 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 198 ctx.set_source(gradient) 199 ctx.rectangle(s+rounded[2], s+h, w-rounded[2]-rounded[3], s) 200 ctx.fill() 201 202 #left 203 gradient = cairo.LinearGradient(s, 0, 0, 0) 204 gradient.add_color_stop_rgba(0,*shadow_color) 205 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 206 ctx.set_source(gradient) 207 ctx.rectangle(0, s+rounded[0], s, h-rounded[0]-rounded[2]) 208 ctx.fill() 209 210 #right 211 gradient = cairo.LinearGradient(s+w, 0, (s*2)+w, 0) 212 gradient.add_color_stop_rgba(0,*shadow_color) 213 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 214 ctx.set_source(gradient) 215 ctx.rectangle(s+w, s+rounded[1], s, h-rounded[1]-rounded[3]) 216 ctx.fill() 217 ctx.restore 218 219 #top-left 220 gradient = cairo.RadialGradient(s+rounded[0], s+rounded[0], rounded[0], s+rounded[0], s+rounded[0], s+rounded[0]) 221 gradient.add_color_stop_rgba(0,*shadow_color) 222 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 223 ctx.set_source(gradient) 224 ctx.new_sub_path() 225 ctx.arc(s,s,s, -math.pi, -math.pi/2) 226 ctx.line_to(s+rounded[0],0) 227 ctx.line_to(s+rounded[0],s) 228 ctx.arc_negative(s+rounded[0],s+rounded[0],rounded[0], -math.pi/2, math.pi) 229 ctx.line_to(0, s+rounded[0]) 230 ctx.close_path() 231 ctx.fill() 232 233 #top-right 234 gradient = cairo.RadialGradient(w+s-rounded[1], s+rounded[1], rounded[1], w+s-rounded[1], s+rounded[1], s+rounded[1]) 235 gradient.add_color_stop_rgba(0,*shadow_color) 236 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 237 ctx.set_source(gradient) 238 ctx.new_sub_path() 239 ctx.arc(w+s,s,s, -math.pi/2, 0) 240 ctx.line_to(w+(s*2), s+rounded[1]) 241 ctx.line_to(w+s, s+rounded[1]) 242 ctx.arc_negative(w+s-rounded[1], s+rounded[1], rounded[1], 0, -math.pi/2) 243 ctx.line_to(w+s-rounded[1], 0) 244 ctx.close_path() 245 ctx.fill() 246 247 #bottom-left 248 gradient = cairo.RadialGradient(s+rounded[2], h+s-rounded[2], rounded[2], s+rounded[2], h+s-rounded[2], s+rounded[2]) 249 gradient.add_color_stop_rgba(0,*shadow_color) 250 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 251 ctx.set_source(gradient) 252 ctx.new_sub_path() 253 ctx.arc(s,h+s,s, math.pi/2, math.pi) 254 ctx.line_to(0, h+s-rounded[2]) 255 ctx.line_to(s, h+s-rounded[2]) 256 ctx.arc_negative(s+rounded[2], h+s-rounded[2], rounded[2], -math.pi, math.pi/2) 257 ctx.line_to(s+rounded[2], h+(s*2)) 258 ctx.close_path() 259 ctx.fill() 260 261 #bottom-right 262 gradient = cairo.RadialGradient(w+s-rounded[3], h+s-rounded[3], rounded[3], w+s-rounded[3], h+s-rounded[3], s+rounded[3]) 263 gradient.add_color_stop_rgba(0,*shadow_color) 264 gradient.add_color_stop_rgba(1,shadow_color[0], shadow_color[1], shadow_color[2], 0) 265 ctx.set_source(gradient) 266 ctx.new_sub_path() 267 ctx.arc(w+s,h+s,s, 0, math.pi/2) 268 ctx.line_to(w+s-rounded[3], h+(s*2)) 269 ctx.line_to(w+s-rounded[3], h+s) 270 ctx.arc_negative(s+w-rounded[3], s+h-rounded[3], rounded[3], math.pi/2, 0) 271 ctx.line_to((s*2)+w, s+h-rounded[3]) 272 ctx.close_path() 273 ctx.fill() 274 ctx.restore() 275 276 #the content starts here! 277 ctx.translate(s, s) 278 else: 279 ctx.translate(border_size, border_size) 280 281 #and now the rectangle 282 if fill: 283 ctx.line_to(0, rounded[0]) 284 ctx.arc(rounded[0], rounded[0], rounded[0], math.pi, -math.pi/2) 285 ctx.line_to(w-rounded[1], 0) 286 ctx.arc(w-rounded[1], rounded[1], rounded[1], -math.pi/2, 0) 287 ctx.line_to(w, h-rounded[3]) 288 ctx.arc(w-rounded[3], h-rounded[3], rounded[3], 0, math.pi/2) 289 ctx.line_to(rounded[2], h) 290 ctx.arc(rounded[2], h-rounded[2], rounded[2], math.pi/2, -math.pi) 291 ctx.close_path() 292 ctx.fill() 293 294 if border_size > 0: 295 ctx.save() 296 ctx.line_to(0, rounded[0]) 297 ctx.arc(rounded[0], rounded[0], rounded[0], math.pi, -math.pi/2) 298 ctx.line_to(w-rounded[1], 0) 299 ctx.arc(w-rounded[1], rounded[1], rounded[1], -math.pi/2, 0) 300 ctx.line_to(w, h-rounded[3]) 301 ctx.arc(w-rounded[3], h-rounded[3], rounded[3], 0, math.pi/2) 302 ctx.line_to(rounded[2], h) 303 ctx.arc(rounded[2], h-rounded[2], rounded[2], math.pi/2, -math.pi) 304 ctx.close_path() 305 ctx.set_source_rgba(*border_color) 306 ctx.set_line_width(border_size) 307 ctx.stroke() 308 ctx.restore() 309 ctx.restore()
310
311 - def draw_rounded_rectangle(self,ctx,x,y,rounded_angle,width,height,round_top_left = True ,round_top_right = True,round_bottom_left = True,round_bottom_right = True, fill=True):
312 """Draws a rounded rectangle""" 313 ctx.save() 314 ctx.translate(x, y) 315 padding=0 # Padding from the edges of the window 316 rounded=rounded_angle # How round to make the edges 20 is ok 317 w = width 318 h = height 319 320 # Move to top corner 321 ctx.move_to(0+padding+rounded, 0+padding) 322 323 # Top right corner and round the edge 324 if round_top_right: 325 ctx.line_to(w-padding-rounded, 0+padding) 326 ctx.arc(w-padding-rounded, 0+padding+rounded, rounded, (math.pi/2 )+(math.pi) , 0) 327 else: 328 ctx.line_to(w-padding, 0+padding) 329 330 # Bottom right corner and round the edge 331 if round_bottom_right: 332 ctx.line_to(w-padding, h-padding-rounded) 333 ctx.arc(w-padding-rounded, h-padding-rounded, rounded, 0, math.pi/2) 334 else: 335 ctx.line_to(w-padding, h-padding) 336 # Bottom left corner and round the edge. 337 if round_bottom_left: 338 ctx.line_to(0+padding+rounded, h-padding) 339 ctx.arc(0+padding+rounded, h-padding-rounded, rounded,math.pi/2, math.pi) 340 else: 341 ctx.line_to(0+padding, h-padding) 342 # Top left corner and round the edge 343 if round_top_left: 344 ctx.line_to(0+padding, 0+padding+rounded) 345 ctx.arc(0+padding+rounded, 0+padding+rounded, rounded, math.pi, (math.pi/2 )+(math.pi)) 346 else: 347 ctx.line_to(0+padding, 0+padding) 348 # Fill in the shape. 349 if fill:ctx.fill() 350 else: ctx.stroke() 351 ctx.restore()
352
353 - def draw_quadrant_shadow(self, ctx, x, y, from_r, to_r, quad, col):
354 gradient = cairo.RadialGradient(x,y,from_r,x,y,to_r) 355 gradient.add_color_stop_rgba(0,col[0],col[1],col[2],col[3]) 356 gradient.add_color_stop_rgba(1,col[0],col[1],col[2],0) 357 ctx.set_source(gradient) 358 ctx.new_sub_path() 359 if quad==0: ctx.arc(x,y,to_r, -math.pi, -math.pi/2) 360 elif quad==1: ctx.arc(x,y,to_r, -math.pi/2, 0) 361 elif quad==2: ctx.arc(x,y,to_r, math.pi/2, math.pi) 362 elif quad==3: ctx.arc(x,y,to_r, 0, math.pi/2) 363 ctx.line_to(x,y) 364 ctx.close_path() 365 ctx.fill()
366 367 # side: 0 - left, 1 - right, 2 - top, 3 - bottom
368 - def draw_side_shadow(self, ctx, x, y, w, h, side, col):
369 gradient = None 370 if side==0: 371 gradient = cairo.LinearGradient(x+w,y,x,y) 372 elif side==1: 373 gradient = cairo.LinearGradient(x,y,x+w,y) 374 elif side==2: 375 gradient = cairo.LinearGradient(x,y+h,x,y) 376 elif side==3: 377 gradient = cairo.LinearGradient(x,y,x,y+h) 378 if gradient: 379 gradient.add_color_stop_rgba(0,col[0],col[1],col[2],col[3]) 380 gradient.add_color_stop_rgba(1,col[0],col[1],col[2],0) 381 ctx.set_source(gradient) 382 ctx.rectangle(x,y,w,h) 383 ctx.fill()
384
385 - def draw_shadow(self, ctx, x, y, w, h, shadow_size, col):
386 s = shadow_size 387 #r = self.layout.window.radius 388 r = s 389 rr = r+s 390 h = h-r 391 if h < 2*r: h = 2*r 392 393 # TODO: Offsets [Will need to change all places doing 394 # x+=shadow_size/2 or such to use the offsets then 395 ctx.save() 396 ctx.translate(x,y) 397 398 # Top Left 399 self.draw_quadrant_shadow(ctx, rr, rr, 0, rr, 0, col) 400 # Left 401 self.draw_side_shadow(ctx, 0, rr, r+s, h-2*r, 0, col) 402 # Bottom Left 403 self.draw_quadrant_shadow(ctx, rr, h-r+s, 0, rr, 2, col) 404 # Bottom 405 self.draw_side_shadow(ctx, rr, h-r+s, w-2*r, s+r, 3, col) 406 # Bottom Right 407 self.draw_quadrant_shadow(ctx, w-r+s, h-r+s, 0, rr, 3, col) 408 # Right 409 self.draw_side_shadow(ctx, w-r+s, rr, s+r, h-2*r, 1, col) 410 # Top Right 411 self.draw_quadrant_shadow(ctx, w-r+s, rr, 0, rr, 1, col) 412 # Top 413 self.draw_side_shadow(ctx, rr, 0, w-2*r, s+r, 2, col) 414 415 ctx.restore()
416 417 418
419 - def get_image_size(self,pix):
420 """Gets a picture width and height""" 421 422 pixbuf = gtk.gdk.pixbuf_new_from_file(pix) 423 iw = pixbuf.get_width() 424 ih = pixbuf.get_height() 425 puxbuf = None 426 return iw,ih
427
428 - def draw_image(self,ctx,x,y, pix):
429 """Draws a picture from specified path""" 430 431 ctx.save() 432 ctx.translate(x, y) 433 pixbuf = gtk.gdk.pixbuf_new_from_file(pix) 434 format = cairo.FORMAT_RGB24 435 if pixbuf.get_has_alpha(): 436 format = cairo.FORMAT_ARGB32 437 438 iw = pixbuf.get_width() 439 ih = pixbuf.get_height() 440 image = cairo.ImageSurface(format, iw, ih) 441 image = ctx.set_source_pixbuf(pixbuf, 0, 0) 442 443 ctx.paint() 444 puxbuf = None 445 image = None 446 ctx.restore()
447
448 - def draw_icon(self,ctx,x,y, pix,width=32,height=32):
449 """Draws a gtk icon """ 450 451 ctx.save() 452 ctx.translate(x, y) 453 icontheme = gtk.icon_theme_get_default() 454 image = icontheme.load_icon (pix,width,height) 455 ctx.set_source_pixbuf(image, 0, 0) 456 ctx.paint() 457 icontheme = None 458 image = None 459 ctx.restore()
460
461 - def draw_scaled_image(self,ctx,x,y, pix, w, h):
462 """Draws a picture from specified path with a certain width and height""" 463 w = int(w) 464 h = int(h) 465 466 ctx.save() 467 ctx.translate(x, y) 468 pixbuf = gtk.gdk.pixbuf_new_from_file(pix).scale_simple(w,h,gtk.gdk.INTERP_HYPER) 469 format = cairo.FORMAT_RGB24 470 if pixbuf.get_has_alpha(): 471 format = cairo.FORMAT_ARGB32 472 473 iw = pixbuf.get_width() 474 ih = pixbuf.get_height() 475 image = cairo.ImageSurface(format, iw, ih) 476 477 matrix = cairo.Matrix(xx=iw/w, yy=ih/h) 478 image = ctx.set_source_pixbuf(pixbuf, 0, 0) 479 if image != None :image.set_matrix(matrix) 480 ctx.paint() 481 puxbuf = None 482 image = None 483 ctx.restore()
484