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