def cb_draw(self, widget, cr): (w, h) = self.window.get_size() if self.compositing: cr.set_source_rgba(0.0, 0.0, 0.0, 0.45) else: cr.set_source_rgb(0.5, 0.5, 0.5) cr.set_operator(cairo.OPERATOR_SOURCE) cr.paint() # Draw the selection area cr.set_line_width(1) cr.set_source_rgb(1.0, 1.0, 1.0) cr.rectangle(self.startx, self.starty, self.width, self.height) cr.stroke() if self.compositing: cr.set_source_rgba(0.0, 0.0, 0.0, 0.0) else: cr.set_source_rgb(0.0, 0.0, 0.0) cr.rectangle(self.startx + 1, self.starty + 1, self.width - 2, self.height - 2) cr.fill() cr.set_operator(cairo.OPERATOR_OVER) # Draw resize handles for i in range(0, 9): # Skip center handle if i == HANDLE_MOVE: continue # X and Y offsets, added to start position x = i % 3 / 2 y = math.floor(i / 3) / 2 centerx = self.startx + self.width * x centery = self.starty + self.height * y # Handle shadow grad = cairo.RadialGradient(centerx, centery, 0, centerx, centery + 2, 10) grad.add_color_stop_rgba(0.6, 0.0, 0.0, 0.0, 0.6) grad.add_color_stop_rgba(0.75, 0.0, 0.0, 0.0, 0.25) grad.add_color_stop_rgba(1.0, 0.0, 0.0, 0.0, 0.0) cr.arc(centerx, centery, 10, 0, 2 * math.pi) cr.set_source(grad) cr.fill() # Handle background grad = cairo.LinearGradient(centerx, centery - 8, centerx, centery + 8) grad.add_color_stop_rgb(0.0, 0.75, 0.75, 0.75) grad.add_color_stop_rgb(0.75, 0.95, 0.95, 0.95) cr.arc(centerx, centery, 8, 0, 2 * math.pi) cr.set_source(grad) cr.fill() # White outline cr.set_source_rgb(1.0, 1.0, 1.0) cr.arc(centerx, centery, 8, 0, 2 * math.pi) cr.stroke() self._outline_text(cr, w, h, 30, _("Select an area by clicking and dragging.")) self._outline_text(cr, w, h + 50, 26, _("Press ENTER to confirm or ESC to cancel")) self._outline_text( cr, w, h + 100, 20, "({0} × {1})".format(abs(self.width + 1), abs(self.height + 1))) cr.set_operator(cairo.OPERATOR_SOURCE)
def expose(self, widget, event): if self.is_sensitive(): alpha = 1 else: alpha = 0.3 w = self.get_allocated_width() h = self.get_allocated_height() cr = widget.get_property('window').cairo_create() def set_color(c): return cr.set_source_rgba(c.red_float, c.green_float, c.blue_float, alpha) if (self.use_bitmaps == False): linewidth = 4 x = y = linewidth/2 w2 = w - linewidth h2 = h - linewidth x_center = x + w2/2 y_center = y + h2/2 degrees = math.pi / 180.0 cr.new_sub_path() cr.arc(x + w2 - self.corner_radius, y + self.corner_radius, self.corner_radius, -90 * degrees, 0 * degrees) cr.arc(x + w2 - self.corner_radius, y + h2 - self.corner_radius, self.corner_radius, 0 * degrees, 90 * degrees) cr.arc(x + self.corner_radius, y + h2 - self.corner_radius, self.corner_radius, 90 * degrees, 180 * degrees) cr.arc(x + self.corner_radius, y + self.corner_radius, self.corner_radius, 180 * degrees, 270 * degrees) cr.close_path() def modify_hsv_color(color, h_mult, s_mult, v_mult): hsv = Gtk.HSV() (h,s,v) = Gtk.rgb_to_hsv(color.red_float, color.green_float, color.blue_float) h = h*h_mult s = s*s_mult v = v*v_mult # suppress Gtk assertion error when value is > 1.0 due to rounding errors if h > 1.0: h = 1.0 if s > 1.0: s = 1.0 if v > 1.0: v = 1.0 (r,g,b) = hsv.to_rgb(h, s, v) return Gdk.Color.from_floats(r,g,b) if (self.light_is_on): color = self.light_on_color if self.mouseover: color = modify_hsv_color(color, 1.0, .5, 1.5) color2 = modify_hsv_color(color, 1.0, .25, 1.0) linecolor = modify_hsv_color(color, 1.0, 1.0, .95) else: color = self.light_off_color if self.mouseover: color = modify_hsv_color(color, 1.0, .5, 1.5) if (self.dual_color): color2 = modify_hsv_color(color, 1.0, .25, 1.0) linecolor = modify_hsv_color(color, 1.0, 1.0, .95) else: color1 = modify_hsv_color(color, 1.0, .50, 2) color2 = modify_hsv_color(color, 1.0, 1.0, .50) linecolor = modify_hsv_color(color, 1.0, .50, .75) cr.set_line_width(linewidth) set_color(linecolor) cr.stroke_preserve() if (self.light_is_on == True) or (self.dual_color == True): gradient_radius = (w2 + h2) g1 = cairo.RadialGradient(x_center, y_center, 0, x_center, y_center, gradient_radius) g1.add_color_stop_rgb(0.0, color2.red_float, color2.green_float, color2.blue_float) g1.add_color_stop_rgb(1.0, color.red_float, color.green_float, color.blue_float) else: g1 = cairo.LinearGradient(x, y, x, y + h2) g1.add_color_stop_rgb(0.0, color1.red_float, color1.green_float, color1.blue_float) g1.add_color_stop_rgb(0.0, color.red_float, color.green_float, color.blue_float) g1.add_color_stop_rgb(1.0, color2.red_float, color2.green_float, color2.blue_float) cr.set_source(g1) cr.fill() #Using bitmaps is not implemented. Bitmaps should not be scaled unless you figure out a way to make them scale nicely #The main reason to use bitmaps would be if someone wants a different look from the default one #The code below is the basic way to do it. update_widget_size() should use the button size instead of text size #and there should be properties to set image filenames for each state (light on, light off, mouseover, etc) else: cr.save() image = cairo.ImageSurface.create_from_png('resources/k_green.png') img_w = image.get_width() img_h = image.get_height() print(float(w)/img_w, float(h)/img_h) cr.set_source_surface(image, 0, 0) cr.paint() cr.restore() # write text _layout = self.default_pangolayout if (self.light_is_on): set_color(self.font_on_color) if (not self.button_on_text == ""): _layout = self.on_pangolayout else: set_color(self.font_off_color) fontw, fonth = _layout.get_pixel_size() cr.move_to((w - fontw)/2, (h - fonth)/2) PangoCairo.update_layout(cr, _layout) PangoCairo.show_layout(cr, _layout) return False
def _draw_buttons(self, cr, w, h): # Width of buttons group buttons_width = self.button_width * len(self.icons) # Draw bg cr.set_source_rgb(*gui.bg_color_tuple) cr.rectangle(0, 0, w, h) cr.fill() # Line width for all strokes cr.set_line_width(1.0) # bg self._set_button_draw_consts(self.button_x + 0.5, self.button_y + 0.5, buttons_width, self.button_height + 1.0) self._round_rect_path(cr) r, g, b = gui.bg_color_tuple if self.draw_button_gradients: if self.glass_style == True: cr.set_source_rgb(0.75, 0.75, 0.75)#*gui.bg_color_tuple)#0.75, 0.75, 0.75) cr.fill_preserve() else: grad = cairo.LinearGradient (self.button_x, self.button_y, self.button_x, self.button_y + self.button_height) if self.dark_theme == False: grad.add_color_stop_rgba(1, r - 0.1, g - 0.1, b - 0.1, 1) grad.add_color_stop_rgba(0, r + 0.1, g + 0.1, b + 0.1, 1) else: grad.add_color_stop_rgba(1, r + 0.04, g + 0.04, b + 0.04, 1) grad.add_color_stop_rgba(0, r + 0.07, g + 0.07, b + 0.07, 1) cr.set_source(grad) cr.fill_preserve() # Pressed button gradient if self.pressed_button > -1: if self.draw_button_gradients: grad = cairo.LinearGradient (self.button_x, self.button_y, self.button_x, self.button_y + self.button_height) if self.glass_style == True: for stop in BUTTONS_PRESSED_GRAD_STOPS: grad.add_color_stop_rgba(*stop) else: grad = cairo.LinearGradient (self.button_x, self.button_y, self.button_x, self.button_y + self.button_height) grad.add_color_stop_rgba(1, r - 0.3, g - 0.3, b - 0.3, 1) grad.add_color_stop_rgba(0, r - 0.1, g - 0.1, b - 0.1, 1) else: grad = cairo.LinearGradient (self.button_x, self.button_y, self.button_x, self.button_y + self.button_height) grad.add_color_stop_rgba(1, r - 0.3, g - 0.3, b - 0.3, 1) grad.add_color_stop_rgba(0, r - 0.3, g - 0.3, b - 0.3, 1) cr.save() cr.set_source(grad) cr.clip() cr.rectangle(self.button_x + self.pressed_button * self.button_width, self.button_y, self.button_width, self.button_height) cr.fill() cr.restore() # Icons and sensitive gradient grad = cairo.LinearGradient (self.button_x, self.button_y, self.button_x, self.button_y + self.button_height) for stop in BUTTON_NOT_SENSITIVE_GRAD_STOPS: grad.add_color_stop_rgba(*stop) x = self.button_x for i in range(0, len(self.icons)): icon = self.icons[i] cr.set_source_pixbuf(icon, x + self.image_x[i], self.image_y[i]) cr.paint() if self.sensitive[i] == False: cr.save() self._round_rect_path(cr) cr.set_source(grad) cr.clip() cr.rectangle(x, self.button_y, self.button_width, self.button_height) cr.fill() cr.restore() x += self.button_width if self.glass_style == True and self.draw_button_gradients: # Glass gradient self._round_rect_path(cr) grad = cairo.LinearGradient (self.button_x, self.button_y, self.button_x, self.button_y + self.button_height) for stop in BUTTONS_GRAD_STOPS: grad.add_color_stop_rgba(*stop) cr.set_source(grad) cr.fill() else: pass if self.dark_theme != True: # Round line grad = cairo.LinearGradient (self.button_x, self.button_y, self.button_x, self.button_y + self.button_height) for stop in LINE_GRAD_STOPS: grad.add_color_stop_rgba(*stop) cr.set_source(grad) self._set_button_draw_consts(self.button_x + 0.5, self.button_y + 0.5, buttons_width, self.button_height) self._round_rect_path(cr) cr.stroke() if self.dark_theme == True: cr.set_source_rgb(*gui.bg_color_tuple) # Vert lines x = self.button_x for i in range(0, len(self.icons)): if (i > 0) and (i < len(self.icons)): cr.move_to(x + 0.5, self.button_y) cr.line_to(x + 0.5, self.button_y + self.button_height) cr.stroke() x += self.button_width
def redraw(self): self.configure() cr = self._context w = self.get_allocated_width() h = self.get_allocated_height() if self.trk: w = self.trkview.width self._context.set_font_size(self.seqview.font_size) cr.set_source_rgb(*(col * cfg.intensity_background for col in cfg.colour)) cr.rectangle(0, 0, w, h) cr.fill() active = False if mod.active_track == self.trkview: active = True if not self.get_window().get_toplevel().get_state( ) & Gdk.WindowState.FOCUSED: active = False if self.trk == None: (x, y, width, height, dx, dy) = cr.text_extents("00_|") self.txt_height = height self.txt_width = int(dx) self.set_size_request(self.txt_width, self.txt_height * 2 * cfg.seq_spacing) cr.set_source_rgb(*(col * cfg.intensity_background for col in cfg.colour)) cr.rectangle(0, 0, w, h) cr.fill() if self.time_to_wiggle: (x, y, width, height, dx, dy) = cr.text_extents("***|") cr.set_source_rgb(*(col * cfg.intensity_txt_highlight for col in cfg.record_colour)) for f in range(random.randint(1, 10)): y = random.randint(0, h) cr.move_to(0, y) cr.line_to(width, y) cr.stroke() cr.set_source_rgb(*(col * cfg.intensity_txt_highlight for col in cfg.star_colour)) for f in range(random.randint(1, 3)): y = random.randint(0, h) cr.move_to(0, y) cr.line_to(width, y) cr.stroke() if self.popped or self.button_highlight: cr.set_source_rgb(*(col * cfg.intensity_txt_highlight for col in cfg.star_colour)) else: cr.set_source_rgb(*(col * cfg.intensity_txt / 2 for col in cfg.star_colour)) cr.move_to(x, self.txt_height * cfg.seq_spacing) cr.show_text("vht") cr.move_to(x, self.txt_height * 2 * cfg.seq_spacing) cr.show_text("***") self.button_rect.width = width self.button_rect.height = height * cfg.seq_spacing self.button_rect.x = x self.button_rect.y = height * cfg.seq_spacing self.popover.set_pointing_to(self.button_rect) self.button_rect.y = 0 self.button_rect.height = height * cfg.seq_spacing * 2 cr.set_line_width( (self.seq.extras["font_size"] / 6.0) * cfg.seq_line_width) (x, y, width, height, dx, dy) = cr.text_extents("|") cr.set_source_rgb(*(col * cfg.intensity_lines for col in cfg.colour)) cr.set_antialias(cairo.ANTIALIAS_NONE) cr.move_to(self.txt_width - (dx / 2), self.txt_height * 0.3 * cfg.seq_spacing) cr.line_to( self.txt_width - (dx / 2), (self.seq.length + 1) * self.txt_height * cfg.seq_spacing, ) cr.stroke() self.queue_draw() return # normal track (x, y, width, height, dx, dy) = cr.text_extents("000 00_|") if self.trkview.show_timeshift: (x, y, width, height, dx, dy) = cr.text_extents("000 000 00_|") self.txt_height = height self.txt_width = int(dx) self.width = self.trkview.width gradient = cairo.LinearGradient(0, 0, 0, h) gradient.add_color_stop_rgb( 0.0, *(col * cfg.intensity_background for col in cfg.colour)) colour = cfg.colour if self.trk.playing: gradient.add_color_stop_rgb( 0.1, *(col * cfg.intensity_txt_highlight for col in colour)) gradient.add_color_stop_rgb( 0.4, *(col * cfg.intensity_txt_highlight for col in colour)) else: gradient.add_color_stop_rgb( 0.1, *(col * cfg.intensity_txt for col in colour)) gradient.add_color_stop_rgb( 1.0, *(col * cfg.intensity_background for col in colour)) cr.set_source(gradient) (x, y, width, height, dx, dy) = cr.text_extents("0") cr.rectangle(0, 0, self.width - width, h) cr.fill() if active: txth = self.txt_height * cfg.seq_spacing alpha = 2 gradient = cairo.LinearGradient(0, 0, 0, txth * 2) gradient.add_color_stop_rgba( 0, *(col * cfg.intensity_txt_highlight for col in cfg.record_colour), alpha) gradient.add_color_stop_rgba( 0.1, *(col * cfg.intensity_txt_highlight for col in cfg.record_colour), alpha) gradient.add_color_stop_rgba( 0.8, *(col * cfg.intensity_txt_highlight for col in cfg.record_colour), alpha) gradient.add_color_stop_rgba( 1.0, *(col * cfg.intensity_background for col in cfg.record_colour), alpha) cr.set_source(gradient) yy = 1.3 c = len(self.trk) xfrom = -width * 2 xto = self.trkview.txt_width * c if self.trkview.velocity_editor: xto += self.trkview.velocity_editor.width if self.trkview.timeshift_editor: xto += self.trkview.timeshift_editor.width if self.trkview.prob_editor: xto += self.trkview.prob_editor.width kf = self.trkview.keyboard_focus if kf: xfrom = kf.x_from xto = kf.x_to + width xfrom -= width cr.move_to(xfrom, txth * yy * 2.5) cr.curve_to( xfrom + width, txth * 1.8, xfrom + width, txth * yy, xfrom + (width * 1.8), txth * yy, ) cr.line_to(xto - (width * 1.8), txth * yy) cr.curve_to( xto - width, txth * yy, xto - width, txth * 1.8, xto, txth * 2.5, ) cr.line_to(self.width - width, txth * yy * 10) cr.line_to(-1, txth * yy * 10) cr.stroke_preserve() cr.fill() if active and self.trkview.keyboard_focus: redfrom = 0 redto = 0 (x, y, width, height, dx, dy) = cr.text_extents("000 000|") if self.trkview.show_timeshift: (x, y, width, height, dx, dy) = cr.text_extents("000 000 000|") cr.set_source_rgb(*(col * cfg.intensity_txt for col in cfg.colour)) cr.set_source_rgb(*(col * cfg.intensity_background for col in cfg.colour)) if mod.active_track: if mod.active_track.trk.index == self.trk.index: cr.set_source_rgb(0, 0, 0) if mod.record == 1: cr.set_source_rgb(*(cfg.record_colour)) (x, y, width, height, dx, dy) = cr.text_extents("***!") self.button_rect.height = self.txt_height * cfg.seq_spacing self.button_rect.x = self.trkview.width - (dx + x) self.button_rect.y = self.txt_height * cfg.seq_spacing (x, y, width, height, dx, dy) = cr.text_extents("***") self.button_rect.width = dx + x self.popover.set_pointing_to(self.button_rect) if self.popped or self.button_highlight: cr.set_source_rgb(*(col * cfg.intensity_txt_highlight for col in cfg.star_colour)) else: cr.set_source_rgb(*(col * cfg.intensity_background for col in cfg.colour)) (x, y, width, height, dx, dy) = cr.text_extents("*** ") stars_x = self.trkview.width - (dx + x) cr.move_to(stars_x, self.txt_height * 2 * cfg.seq_spacing) for i in range(3): if self.popped or self.button_highlight: if self.ind[i]: cr.set_source_rgb(*(col * cfg.intensity_txt_highlight for col in cfg.record_colour)) else: cr.set_source_rgb(*(col * cfg.intensity_txt_highlight for col in cfg.star_colour)) else: if self.ind[i]: cr.set_source_rgb(*(col * cfg.intensity_indicator for col in cfg.star_colour)) else: cr.set_source_rgb(*(col * cfg.intensity_background for col in cfg.colour)) cr.show_text("*") cr.set_line_width((self.seqview.font_size / 6.0) * cfg.seq_line_width) (x, y, width, height, dx, dy) = cr.text_extents("0") cr.set_source_rgb(*(col * cfg.intensity_lines for col in cfg.colour)) cr.move_to(self.width - (width / 2), self.txt_height * cfg.seq_spacing * 0.3) cr.line_to(self.width - (width / 2), 2 * self.txt_height * cfg.seq_spacing) cr.stroke() # display labels cr.rectangle(0, 0, self.width - width, h) cr.clip() cr.set_source_rgb(*(col * cfg.intensity_txt for col in cfg.colour)) cr.set_source_rgb(*(col * cfg.intensity_background for col in cfg.colour)) if mod.active_track: if mod.active_track.trk.index == self.trk.index: cr.set_source_rgb(0, 0, 0) if mod.record == 1: cr.set_source_rgb(*(cfg.record_colour)) cr.move_to(x, self.txt_height * 0.99 * cfg.seq_spacing) trkname = self.trk.extras["track_name"] # print(trkname, self.seq.index, self.trk.index) if trkname: # cr.move_to(x, self.txt_height * 0.8 * cfg.seq_spacing) # self._context.set_font_size(self.seqview.font_size * 1.0) pref = "" if not self.trkview.show_notes and self.trk.nctrl > 2: pref = "p%02dc%02d " % (self.trk.port, self.trk.channel) cr.show_text("%s%s" % (pref, trkname)) else: cr.show_text("p%02d c%02d" % (self.trk.port, self.trk.channel)) self._context.set_font_size(self.seqview.font_size * 0.6) cr.set_source_rgb(*(col * cfg.intensity_txt_highlight for col in cfg.star_colour)) yadj = 1.7 if trkname and self.trkview.show_notes: cr.move_to(0, self.txt_height * yadj * cfg.seq_spacing) cr.show_text("p%02dc%02d" % (self.trk.port, self.trk.channel)) if self.trkview.show_pitchwheel and self.trkview.pitchwheel_editor: cr.move_to( self.trkview.pitchwheel_editor.x_from, self.txt_height * yadj * cfg.seq_spacing, ) cr.show_text(" pitch") cr.rectangle(0, 0, stars_x, h) cr.clip() if self.trkview.show_controllers: for i, c in enumerate(self.trkview.controller_editors): cr.move_to(c.x_from, self.txt_height * yadj * cfg.seq_spacing) ctrllabel = " ctrl %d" % self.trkview.trk.ctrls[c.ctrlnum] if str(i + 1) in self.trk.extras["ctrl_names"]: lbl = self.trk.extras["ctrl_names"][str(i + 1)] if len(lbl[1].strip()): ctrllabel = "%s" % lbl[1][:12] cr.show_text(ctrllabel) self.popover.refresh() self.queue_draw()
import math import cairo import pykicad m = pykicad.module.Module.from_file("test.kicad_mod") WIDTH, HEIGHT = 2048, 2048 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT) ctx = cairo.Context(surface) maxsize = 8 ctx.scale(WIDTH/maxsize, HEIGHT/maxsize) ctx.translate(maxsize / 2, maxsize / 2) pat = cairo.LinearGradient(0.0, -1.0, 0.0, 1.0) pat.add_color_stop_rgba(1, 0.7, 0, 0, 0.5) # First stop, 50% opacity pat.add_color_stop_rgba(0, 0.9, 0.7, 0.2, 1) # Last stop, 100% opacity ctx.rectangle(-(maxsize/2), -(maxsize/2), maxsize, maxsize) # Rectangle(x0, y0, x1, y1) ctx.set_source(pat) ctx.fill() class Line: def __init__(self, x1, y1, x2, y2, width): self.x1 = x1 self.y1 = y1 self.x2 = x2 self.y2 = y2 self.width = width def from_kicad(line):
def on_draw(self, area, cr): w = area.get_allocated_width() h = area.get_allocated_height() border = 4 radius = 8 #Draw the frame and the background cr.set_line_width(2) cr.set_source_rgb(0.8, 0.8, 0.8) cr.arc(border + radius, border + radius, radius, math.pi, 3.0 * math.pi / 2.0) cr.line_to(w - border - radius, border) cr.arc(w - border - radius, border + radius, radius, 3.0 * math.pi / 2.0, 0.0) cr.line_to(w - border, h - border - radius) cr.arc(w - border - radius, h - border - radius, radius, 0.0, math.pi / 2.0) cr.line_to(border + radius, h - border) cr.arc(border + radius, h - border - radius, radius, math.pi / 2.0, math.pi) cr.close_path() cr.stroke_preserve() GradientBackground = cairo.LinearGradient(0.0, 0.0, 0.0, h) GradientBackground.add_color_stop_rgba(0.0, 0.1, 0.18, 0.21, 0.8) GradientBackground.add_color_stop_rgba(1.0, 0.0, 0.0, 0.0, 0.5) cr.set_source(GradientBackground) cr.fill() cr.set_source_rgb(0.6, 0.6, 0.6) cr.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(16) txt_x, txt_y, txt_w, txt_h, txt_dx, txt_dy = cr.text_extents("L") cr.move_to(10, h - txt_h - 2) cr.show_text("L") cr.set_source_rgb(0.6, 0.6, 0.6) cr.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(16) txt_x, txt_y, txt_w, txt_h, txt_dx, txt_dy = cr.text_extents("R") cr.move_to(w - txt_w - 10, h - txt_h - 2) cr.show_text("R") MARGIN_X = 30 MARGIN_Y = 10 BALL_RADIUS = 18 #Line connecting both balls plotWidth = self.width if self.width == 1.0 and self.position != 0.5: plotWidth = 0.0 lpos = (self.position + (0.5 * plotWidth)) * (2 * MARGIN_X - w) + w - MARGIN_X rpos = (self.position - (0.5 * plotWidth)) * (2 * MARGIN_X - w) + w - MARGIN_X cr.set_line_width(8) cr.set_source_rgba(0.8, 0.8, 0.8, 0.5) cr.move_to(lpos, (h / 2.0) - MARGIN_Y) cr.line_to(rpos, (h / 2.0) - MARGIN_Y) cr.stroke() #Draw the Left ball cr.set_line_width(1.5) cr.set_source_rgb(0.8, 0.8, 0.8) cr.move_to(lpos + BALL_RADIUS, (h / 2.0) - MARGIN_Y) cr.arc(lpos, (h / 2.0) - MARGIN_Y, BALL_RADIUS, 0.0, 2.0 * math.pi) cr.close_path() cr.stroke_preserve() if plotWidth > 0: cr.set_source_rgba(0.23, 0.43, 0.58, 1) elif plotWidth < 0: cr.set_source_rgba(0.41, 0.15, 0.16, 1) else: cr.set_source_rgba(0.32, 0.51, 0.31, 1) #Mono/Balance mode cr.fill() cr.set_source_rgb(0.6, 0.6, 0.6) cr.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(18) txt_x, txt_y, txt_w, txt_h, txt_dx, txt_dy = cr.text_extents("L") cr.move_to(lpos - txt_w / 2.0, (h / 2.0) - MARGIN_Y + txt_h / 2.0) if plotWidth == 0.0: cr.show_text("P") else: cr.show_text("L") #Draw the Right ball if plotWidth != 0.0: cr.set_line_width(1.5) cr.set_source_rgb(0.8, 0.8, 0.8) cr.move_to(rpos + BALL_RADIUS, (h / 2.0) - MARGIN_Y) cr.arc(rpos, (h / 2.0) - MARGIN_Y, BALL_RADIUS, 0.0, 2.0 * math.pi) cr.close_path() cr.stroke_preserve() if plotWidth > 0: cr.set_source_rgba(0.23, 0.43, 0.58, 1) else: cr.set_source_rgba(0.41, 0.15, 0.16, 1) cr.fill() cr.set_source_rgb(0.6, 0.6, 0.6) cr.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(18) txt_x, txt_y, txt_w, txt_h, txt_dx, txt_dy = cr.text_extents("R") cr.move_to(rpos - txt_w / 2.0, (h / 2.0) - MARGIN_Y + txt_h / 2.0) cr.show_text("R")
def sourceRectangle(self, x, y, w, h, r, g, b): linear = cairo.LinearGradient((x + w) / 2, y, (x + w) / 2, y + h) linear.add_color_stop_rgb(0, 3.5 * r / 5.0, 3.5 * g / 5.0, 3.5 * b / 5.0) linear.add_color_stop_rgb(1, r, g, b) return linear
def get_pattern_v(self, ymin, ymax): pattern = cairo.LinearGradient(0.0, ymin, 0.0, ymax) return pattern
def expose(self, widget, event): cr = widget.window.cairo_create() sensitive = self.flags() & gtk.PARENT_SENSITIVE if not sensitive: alpha = .3 else: alpha = 1 cr.set_line_width(3) cr.set_source_rgba(0, 0, 0, alpha) if self.is_on: if self._blink_active == False: color = self._on_color elif self._blink_invert == True: color = self._on_color elif self._blink_state == False: color = self._blink_color else: color = self._on_color elif self._blink_active == False: color = self._off_color elif self._blink_invert == False: color = self._off_color elif self._blink_state == True: color = self._blink_color else: color = self._off_color # square led if self.led_shape == 2: self.set_size_request(self._dia * 2 + 5, self._dia * 2 + 5) w = self.allocation.width h = self.allocation.height cr.translate(w / 2, h / 2) cr.rectangle(-self._dia, -self._dia, self._dia * 2, self._dia * 2) cr.stroke_preserve() cr.set_source_rgba(color.red / 65535., color.green / 65535., color.blue / 65535., alpha) #cr.fill() cr.fill_preserve() # now make it shiny if self.led_shiny: #cr.rectangle(0, 0, w, h) lg = cairo.LinearGradient(0, -self._dia, 0, self._dia) lg.add_color_stop_rgba(0, color.red / 65535., color.green / 65535., color.blue / 65535., alpha) lg.add_color_stop_rgba(.4, 1, 1, 1, .75) lg.add_color_stop_rgba(1, color.red / 65535., color.green / 65535., color.blue / 65535., alpha) #lg.add_color_stop_rgba(1, .6, .6, .6, .5) cr.set_source(lg) cr.fill() # oval led elif self.led_shape == 1: if self.led_shiny: self.set_size_request(self._dia * 2 + 5, self._dia * 2) w = self.allocation.width h = self.allocation.height cr.translate(w / 2, h / 2) cr.scale(1, 0.7) radius = self._dia linewidth = math.sqrt(radius) * 1.25 cr.set_line_width(linewidth) #cr.arc(0, 0, radius-(linewidth/4), 0, 2*math.pi) cr.arc(0, 0, radius, 0, 2 * math.pi) r0 = cairo.RadialGradient(0, 0, radius - (linewidth / 2), 0, 0, radius + (linewidth / 2)) r0.add_color_stop_rgb(0, .75, .75, .75) r0.add_color_stop_rgb(1.0, .15, .15, .15) cr.set_source(r0) cr.stroke_preserve() r1 = cairo.RadialGradient(0, 0, radius / 8, 0, 0, radius) r1.add_color_stop_rgb(0.4, color.red / 65535., color.green / 65535., color.blue / 65535.) r1.add_color_stop_rgb(0.95, color.red / 65535. * 0.85, color.green / 65535. * 0.85, color.blue / 65535. * 0.85) r1.add_color_stop_rgb(1.0, color.red / 65535., color.green / 65535., color.blue / 65535.) cr.set_source(r1) cr.fill() cr.arc(0, 0, radius, 0, 2 * math.pi) if self.is_on or self.led_bicolor: r2 = cairo.RadialGradient(0, 0, 0, 0, 0, radius) #r2 = cairo.RadialGradient(-radius/6, -radius/6, 0, -radius/6, -radius/6, radius) else: r2 = cairo.RadialGradient(-radius / 6, -radius / 6, 0, -radius / 6, -radius / 6, radius / 2 - radius / 8) r2.add_color_stop_rgba(0, 1, 1, 1, 1) r2.add_color_stop_rgba(1, 1, 1, 1, 0) cr.set_source(r2) cr.fill() else: self.set_size_request(self._dia * 2 + 5, self._dia * 2) w = self.allocation.width h = self.allocation.height cr.translate(w / 2, h / 2) cr.scale(1, 0.7) cr.arc(0, 0, self._dia, 0, 2 * math.pi) cr.stroke_preserve() cr.set_source_rgba(color.red / 65535., color.green / 65535., color.blue / 65535., alpha) cr.fill() # round led else: if self.led_shiny: self.set_size_request(self._dia * 2 + 5, self._dia * 2 + 5) w = self.allocation.width h = self.allocation.height cr.translate(w / 2, h / 2) radius = self._dia linewidth = math.sqrt(radius) * 1.25 cr.set_line_width(linewidth) #cr.arc(0, 0, radius-(linewidth/4), 0, 2*math.pi) cr.arc(0, 0, radius, 0, 2 * math.pi) r0 = cairo.RadialGradient(0, 0, radius - (linewidth / 2), 0, 0, radius + (linewidth / 2)) r0.add_color_stop_rgb(0, .75, .75, .75) r0.add_color_stop_rgb(1.0, .15, .15, .15) cr.set_source(r0) cr.stroke_preserve() r1 = cairo.RadialGradient(0, 0, radius / 8, 0, 0, radius) r1.add_color_stop_rgb(0.4, color.red / 65535., color.green / 65535., color.blue / 65535.) r1.add_color_stop_rgb(0.95, color.red / 65535. * 0.85, color.green / 65535. * 0.85, color.blue / 65535. * 0.85) r1.add_color_stop_rgb(1.0, color.red / 65535., color.green / 65535., color.blue / 65535.) cr.set_source(r1) cr.fill() cr.arc(0, 0, radius, 0, 2 * math.pi) if self.is_on or self.led_bicolor: r2 = cairo.RadialGradient(0, 0, 0, 0, 0, radius) #r2 = cairo.RadialGradient(-radius/6, -radius/6, 0, -radius/6, -radius/6, radius) else: r2 = cairo.RadialGradient(-radius / 6, -radius / 6, 0, -radius / 6, -radius / 6, radius / 2 - radius / 8) r2.add_color_stop_rgba(0, 1, 1, 1, 1) r2.add_color_stop_rgba(1, 1, 1, 1, 0) cr.set_source(r2) cr.fill() else: self.set_size_request(self._dia * 2 + 5, self._dia * 2 + 5) w = self.allocation.width h = self.allocation.height cr.translate(w / 2, h / 2) lg2 = cairo.RadialGradient(0, 0, self._dia - 2, 0, 0, self._dia + 1) lg2.add_color_stop_rgba(0.0, 0., 0., 0., 0.) lg2.add_color_stop_rgba(.99, 0., 0., 0., 1.) lg2.add_color_stop_rgba(1.0, 0., 0., 0., 0.) cr.arc(0, 0, self._dia, 0, 2 * math.pi) cr.mask(lg2) cr.stroke_preserve() cr.set_source_rgba(color.red / 65535., color.green / 65535., color.blue / 65535., alpha) cr.fill() return False
def scrollbar(lines, topI, botI, w, h, bg, cr, scrollbarW=10): "top and bot a passed as line indices" # figure out location topY = None botY = None for line in lines: if not topY: if line.i >= topI: topY = line.y if not botY: if line.i >= botI: botY = line.y if topY is None: topY = 0 if botY is None: botY = lines[-1].y if 0: # bg rectangle cr.set_source_rgba(.1, .1, .1, .35) cr.rectangle(w - scrollbarW, 0, scrollbarW, topY) cr.fill() cr.rectangle(w - scrollbarW, botY, scrollbarW, h - botY) cr.fill() if 0: # scheme 1 cr.set_line_width(1) #cr.set_source_rgb(0,0,0) #cr.set_source_rgb(1,1,1) cr.set_source_rgb(0xd3 / 256., 0xd7 / 256., 0xcf / 256.) if 0: # big down line cr.set_source_rgb(0xd3 / 256., 0xd7 / 256., 0xcf / 256.) cr.move_to(w - scrollbarW / 2., 0) cr.line_to(w - scrollbarW / 2., topY) cr.stroke() cr.move_to(w - scrollbarW / 2., botY) cr.line_to(w - scrollbarW / 2., h) cr.stroke() if 0: cr.rectangle(w - scrollbarW, topY, scrollbarW - 1, botY - topY) cr.stroke() if 1: # bottom lines #cr.set_line_width(2) #cr.move_to(w-scrollbarW,topY) cr.move_to(0, topY) cr.line_to(w, topY) cr.stroke() cr.move_to(0, botY) cr.line_to(w, botY) cr.stroke() if 0: # rect cr.set_source_rgba(.5, .5, .5, .1) #cr.set_source_rgba(.1,.1,.1,.35) #cr.rectangle(w-scrollbarW,topY,scrollbarW,botY-topY) cr.rectangle(0, topY, w, botY - topY) cr.fill() if 0: # scheme 2 cr.set_line_width(3) cr.set_source_rgb(0xd3 / 256., 0xd7 / 256., 0xcf / 256.) if 1: # bottom lines cr.move_to(0, topY) cr.line_to(w, topY) cr.stroke() cr.move_to(0, botY) cr.line_to(w, botY) cr.stroke() if 1: # side lines cr.set_line_width(2) len = (botY - topY) / 8 margin = 1 if 0: # left cr.move_to(margin, topY) cr.line_to(margin, topY + len) cr.stroke() cr.move_to(margin, botY - len) cr.line_to(margin, botY) cr.stroke() if 1: # right cr.move_to(w - margin, topY) cr.line_to(w - margin, topY + len) cr.stroke() cr.move_to(w - margin, botY - len) cr.line_to(w - margin, botY) cr.stroke() if 0: # center len = (botY - topY) / 5 cx = w / 2 cy = topY + (botY - topY) / 2 if 1: # vert for x in (cx, ): #(cx-len/2,cx,cx+len/2): cr.move_to(x, cy - len / 2) cr.line_to(x, cy + len / 2) cr.stroke() if 0: # horiz cr.move_to(cx - len / 2, cy) cr.line_to(cx + len / 2, cy) cr.stroke() if 0: # view indicator cr.set_source_rgba(.5, .5, .5, .5) #cr.set_source_rgba(.1,.1,.1,.35) cr.rectangle(w - scrollbarW, topY, scrollbarW, botY - topY) cr.fill() cr.rectangle(w - scrollbarW, topY, scrollbarW - 1, botY - topY) cr.set_line_width(.5) cr.set_source_rgb(1, 1, 1) #cr.set_source_rgb(0,0,0) cr.stroke() if 0: # lines cr.set_source_rgb(1, 1, 1) cr.move_to(w, 0) cr.line_to(w - scrollbarW, topY) cr.line_to(w - scrollbarW, botY) cr.line_to(w, h) cr.stroke() if 0: # scheme 3 if 1: # black lines cr.set_line_width(2) cr.set_source_rgb(0, 0, 0) cr.move_to(0, topY) cr.line_to(w, topY) cr.stroke() cr.move_to(0, botY) cr.line_to(w, botY) cr.stroke() if 1: # white lines cr.set_line_width(2) cr.set_dash([1, 2]) cr.set_source_rgb(1, 1, 1) cr.move_to(0, topY) cr.line_to(w, topY) cr.stroke() cr.move_to(0, botY) cr.line_to(w, botY) cr.stroke() if 0: # scheme 4 pat = cairo.LinearGradient(0, topY - 10, 0, topY) pat.add_color_stop_rgba(0, 1, 1, 1, 1) pat.add_color_stop_rgba(1, .2, .2, .2, 1) pat.add_color_stop_rgba(2, 0, 0, 0, 1) cr.rectangle(0, topY - 10, w, 10) cr.set_source(pat) cr.fill() if 0: # triangle right # triangle size = 12 midY = topY + (botY - topY) / 2 cr.set_line_width(2) cr.set_source_rgb(1, 1, 1) cr.move_to(w - size - 1, midY) cr.line_to(w - 1, midY - size / 2) #cr.stroke_preserve() cr.line_to(w - 1, midY + size / 2) #cr.stroke_preserve() cr.line_to(w - size - 1, midY) cr.fill() # line cr.move_to(w - 2, topY + 2) cr.line_to(w - 2, botY - 2) cr.stroke() if dark(*bg): color = (1, 1, 1) else: color = (0, 0, 0) if 0: # triangle left # triangle size = 12 midY = topY + (botY - topY) / 2 cr.set_line_width(2) cr.set_source_rgb(*color) cr.move_to(size + 1, midY) cr.line_to(1, midY - size / 2) #cr.stroke_preserve() cr.line_to(1, midY + size / 2) #cr.stroke_preserve() cr.line_to(size + 1, midY) cr.fill() # line #cr.move_to(2,topY+2) #cr.line_to(2,botY-2) #cr.stroke() if 1: # dashed lines cr.set_line_width(2) cr.set_source_rgb(*color) cr.set_dash([8, 8]) #cr.rectangle(2,topY,w-4,botY-topY) cr.move_to(4, topY) cr.line_to(w, topY) cr.stroke() cr.move_to(4, botY) cr.line_to(w, botY) cr.stroke()
def get_pattern_h(self, xmin, xmax): pattern = cairo.LinearGradient(xmin, 0.0, xmax, 0.0) return pattern
def render_background_cb(self, cr, wd, ht, icon_border=None): """Renders the offscreen bg, for `ColorAdjusterWidget` impls. """ cr.save() border = icon_border if border is None: border = self.BORDER_WIDTH radius = self.get_radius(wd, ht, border) steps = self.HUE_SLICES # Move to the centre cx, cy = self.get_center(wd, ht) cr.translate(cx, cy) # Clip, for a slight speedup cr.arc(0, 0, radius + border, 0, 2 * math.pi) cr.clip() # Tangoesque outer border cr.set_line_width(self.OUTLINE_WIDTH) cr.arc(0, 0, radius, 0, 2 * math.pi) cr.set_source_rgba(*self.OUTLINE_RGBA) cr.stroke() # Each slice in turn cr.save() cr.set_line_width(1.0) cr.set_line_join(cairo.LINE_JOIN_ROUND) step_angle = 2.0 * math.pi / steps mgr = self.get_color_manager() for ih in xrange(steps + 1): # overshoot by 1, no solid bit for final h = ih / steps if mgr: h = mgr.undistort_hue(h) edge_col = self.color_at_normalized_polar_pos(1.0, h) edge_col.s = 1.0 edge_col.v = 1.0 rgb = edge_col.get_rgb() if ih > 0: # Backwards gradient cr.arc_negative(0, 0, radius, 0, -step_angle) x, y = cr.get_current_point() cr.line_to(0, 0) cr.close_path() lg = cairo.LinearGradient(radius, 0, (x + radius) / 2, y) lg.add_color_stop_rgba(0, rgb[0], rgb[1], rgb[2], 1.0) lg.add_color_stop_rgba(1, rgb[0], rgb[1], rgb[2], 0.0) cr.set_source(lg) cr.fill() if ih < steps: # Forward solid cr.arc(0, 0, radius, 0, step_angle) x, y = cr.get_current_point() cr.line_to(0, 0) cr.close_path() cr.set_source_rgb(*rgb) cr.stroke_preserve() cr.fill() cr.rotate(step_angle) cr.restore() # Tangoesque inner border cr.set_source_rgba(*self.EDGE_HIGHLIGHT_RGBA) cr.set_line_width(self.EDGE_HIGHLIGHT_WIDTH) cr.arc(0, 0, radius, 0, 2 * math.pi) cr.stroke() cr.set_line_width(self.OUTLINE_WIDTH) cr.arc(0, 0, radius * 0.8, 0, 2 * math.pi) cr.set_source_rgba(0, 0, 0, 1) cr.set_operator(cairo.OPERATOR_DEST_OUT) cr.fill() cr.set_operator(cairo.OPERATOR_OVER) cr.set_source_rgba(*self.OUTLINE_RGBA) cr.stroke() cr.set_source_rgba(*self.EDGE_HIGHLIGHT_RGBA) cr.set_line_width(self.EDGE_HIGHLIGHT_WIDTH) cr.arc(0, 0, radius * 0.8, 0, 2 * math.pi) cr.stroke()
def process_fill(self, ctx, obj): fill = obj.style[0] fill_rule = fill[0] if fill_rule & sk2const.FILL_CLOSED_ONLY and not obj.is_closed(): ctx.set_source_rgba(0.0, 0.0, 0.0, 0.0) return if fill_rule & sk2const.FILL_EVENODD: ctx.set_fill_rule(cairo.FILL_RULE_EVEN_ODD) else: ctx.set_fill_rule(cairo.FILL_RULE_WINDING) if fill[1] == sk2const.FILL_SOLID: if obj.fill_trafo: obj.fill_trafo = [] color = fill[2] ctx.set_source_rgba(*self.get_color(color)) elif fill[1] == sk2const.FILL_GRADIENT: if not obj.fill_trafo: obj.fill_trafo = [] + sk2const.NORMAL_TRAFO gradient = fill[2] points = gradient[1] if not points: obj.fill_trafo = [] + sk2const.NORMAL_TRAFO points = libgeom.bbox_middle_points(obj.cache_bbox) if gradient[0] == sk2const.GRADIENT_LINEAR: points = [points[0], points[2]] else: points = [[points[1][0], points[2][1]], points[2]] gradient[1] = points coords = points[0] + points[1] if gradient[0] == sk2const.GRADIENT_LINEAR: grd = cairo.LinearGradient(*coords) else: x0, y0 = coords[:2] radius = libgeom.distance(*points) grd = cairo.RadialGradient(x0, y0, 0, x0, y0, radius) for stop in gradient[2]: grd.add_color_stop_rgba(stop[0], *self.get_color(stop[1])) matrix = cairo.Matrix(*obj.fill_trafo) matrix.invert() extend = cairo.EXTEND_PAD if len(gradient) > 3: extend = EXTEND[gradient[3]] grd.set_extend(extend) grd.set_matrix(matrix) ctx.set_source(grd) elif fill[1] == sk2const.FILL_PATTERN: if not obj.fill_trafo: obj.fill_trafo = [] + sk2const.NORMAL_TRAFO obj.fill_trafo = obj.fill_trafo[:4] + [ obj.cache_bbox[0], obj.cache_bbox[3] ] pattern_fill = fill[2] sp = cairo.SurfacePattern(self.get_pattern_surface(obj)) sp.set_extend(cairo.EXTEND_REPEAT) flip_matrix = cairo.Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) if len(pattern_fill) > 3: pattern_matrix = cairo.Matrix(*pattern_fill[3]) pattern_matrix.invert() flip_matrix = flip_matrix * pattern_matrix trafo_matrix = cairo.Matrix(*obj.fill_trafo) trafo_matrix.invert() flip_matrix = flip_matrix * trafo_matrix sp.set_matrix(flip_matrix) ctx.set_source(sp) canvas_matrix = ctx.get_matrix() canvas_trafo = libcairo.get_trafo_from_matrix(canvas_matrix) zoom = canvas_trafo[0] if zoom * abs(obj.fill_trafo[0]) > .98: ctx.get_source().set_filter(cairo.FILTER_NEAREST)
def DrawWaveform(self, exposeArea): """ Uses Cairo to draw the waveform level information onto a canvas in memory. Parameters: exposeArea -- Cairo exposed area in which to draw the waveform. """ allocArea = self.get_allocation() rect = gtk.gdk.Rectangle(exposeArea.x - exposeArea.width, exposeArea.y, exposeArea.width*3, exposeArea.height) #Check if our area to cache is outside the allocated area if rect.x < 0: rect.x = 0 if rect.x + rect.width > allocArea.width: rect.width = allocArea.width - rect.x #set area to record where the cached surface goes if self.small: self.cachedDrawAreaSmall = rect self.sourceSmall = cairo.ImageSurface(cairo.FORMAT_ARGB32, rect.width, rect.height) context = cairo.Context(self.sourceSmall) else: self.cachedDrawAreaLarge = rect self.sourceLarge = cairo.ImageSurface(cairo.FORMAT_ARGB32, rect.width, rect.height) context = cairo.Context(self.sourceLarge) context.set_line_width(2) context.set_antialias(cairo.ANTIALIAS_SUBPIXEL) # Draw white background context.rectangle(0, 0, rect.width, rect.height) context.set_source_rgb(*self._BACKGROUND_RGB) context.fill() if self.event.levels_list and (self.event.duration or self.event.loadingLength): if self.event.loadingLength: duration = self.event.loadingLength else: duration = self.event.duration context.move_to(0,rect.height) levels = self.event.GetFadeLevels() length = len(levels) # time offset of the start of the drawing area in milliseconds starting_time = int(rect.x / self.project.viewScale * 1000) starting_index = levels.find_endtime_index(starting_time) x = 0 last_x = -2 skip_list = [] iterator = itertools.islice(levels, starting_index, length) for endtime, peak in iterator: x = int((endtime - starting_time) * self.project.viewScale / 1000) peakOnScreen = int(peak * rect.height / sys.maxint) skip_list.append(peakOnScreen) if (x - last_x) < self._MIN_POINT_SEPARATION: continue peakOnScreen = sum(skip_list) / len(skip_list) context.line_to(x, rect.height - peakOnScreen) skip_list = [] last_x = x if x > rect.width: break context.line_to(x, rect.height) #levels gradient fill gradient = cairo.LinearGradient(0.0, 0.0, 0, rect.height) gradient.add_color_stop_rgba(*self._OPAQUE_GRADIENT_STOP_ORGBA) gradient.add_color_stop_rgba(*self._TRANSPARENT_GRADIENT_STOP_ORGBA) context.set_source(gradient) context.fill_preserve() #levels path (on top of the fill) context.set_source_rgb(*self._BORDER_RGB) context.set_line_join(cairo.LINE_JOIN_ROUND) context.set_line_width(self._LINE_WIDTH) context.stroke() if self.event.audioFadePoints: pixelPoints = [] # draw the fade line context.set_source_rgb(*self._FADELINE_RGB) firstPoint = self.event.audioFadePoints[0] pixx = self.PixXFromSec(firstPoint[0]) - rect.x pixy = self.PixYFromVol(firstPoint[1]) context.move_to(pixx, pixy) for sec, vol in self.event.audioFadePoints[1:]: pixx = self.PixXFromSec(sec) - rect.x pixy = self.PixYFromVol(vol) pixelPoints.append((pixx, pixy)) context.line_to(pixx,pixy) context.stroke() #draw the fade points for pixx, pixy in pixelPoints: context.arc(pixx, pixy, 3.5, 0, 7) context.fill() # Reset the drawing scale context.identity_matrix() context.scale(1.0, 1.0) #check if we are at the beginning if rect.x == 0: context.set_source_rgb(*self._TEXT_RGB) context.move_to(5, 15) if self.event.isLoading: # Write "Loading..." or "Downloading..." if self.event.duration <= 0: # for some file types gstreamer doesn't give us a duration # so don't display the percentage if self.event.isDownloading: message = _("Downloading...") else: message = _("Loading...") else: displayLength = int(100 * self.event.loadingLength / self.event.duration) if self.event.isDownloading: message = _("Downloading (%d%%)...") % displayLength else: message = _("Loading (%d%%)...") % displayLength # show the appropriate message context.show_text(message) # display a cancel button self.cancelButtonArea.x = context.get_current_point()[0]+3 # take the current context.x and pad it a bit context.set_source_surface(self.cancelImg, self.cancelButtonArea.x, self.cancelButtonArea.y) context.paint() elif self.event.isRecording: context.show_text(_("Recording...")) else: #Draw event name context.show_text(self.event.name) self.redrawWaveform = False
def render_background_cb(self, cr, wd, ht, icon_border=None): """Renders the offscreen bg, for `ColorAdjusterWidget` impls. """ cr.save() ref_grey = self.color_at_normalized_polar_pos(0, 0) border = icon_border if border is None: border = self.BORDER_WIDTH radius = self.get_radius(wd, ht, border) steps = self.HUE_SLICES sat_slices = self.SAT_SLICES sat_gamma = self.SAT_GAMMA # Move to the centre cx, cy = self.get_center(wd, ht) cr.translate(cx, cy) # Clip, for a slight speedup cr.arc(0, 0, radius+border, 0, 2*math.pi) cr.clip() # Tangoesque outer border cr.set_line_width(self.OUTLINE_WIDTH) cr.arc(0, 0, radius, 0, 2*math.pi) cr.set_source_rgba(*self.OUTLINE_RGBA) cr.stroke() # Each slice in turn cr.save() cr.set_line_width(1.0) cr.set_line_join(cairo.LINE_JOIN_ROUND) step_angle = 2.0*math.pi/steps mgr = self.get_color_manager() for ih in xrange(steps+1): # overshoot by 1, no solid bit for final h = float(ih)/steps if mgr: h = mgr.undistort_hue(h) edge_col = self.color_at_normalized_polar_pos(1.0, h) rgb = edge_col.get_rgb() if ih > 0: # Backwards gradient cr.arc_negative(0, 0, radius, 0, -step_angle) x, y = cr.get_current_point() cr.line_to(0, 0) cr.close_path() lg = cairo.LinearGradient(radius, 0, float(x+radius)/2, y) lg.add_color_stop_rgba(0, rgb[0], rgb[1], rgb[2], 1.0) lg.add_color_stop_rgba(1, rgb[0], rgb[1], rgb[2], 0.0) cr.set_source(lg) cr.fill() if ih < steps: # Forward solid cr.arc(0, 0, radius, 0, step_angle) x, y = cr.get_current_point() cr.line_to(0, 0) cr.close_path() cr.set_source_rgb(*rgb) cr.stroke_preserve() cr.fill() cr.rotate(step_angle) cr.restore() # Cheeky approximation of the right desaturation gradients rg = cairo.RadialGradient(0, 0, 0, 0, 0, radius) add_distance_fade_stops(rg, ref_grey.get_rgb(), nstops=sat_slices, gamma=1.0/sat_gamma) cr.set_source(rg) cr.arc(0, 0, radius, 0, 2*math.pi) cr.fill() # Tangoesque inner border cr.set_source_rgba(*self.EDGE_HIGHLIGHT_RGBA) cr.set_line_width(self.EDGE_HIGHLIGHT_WIDTH) cr.arc(0, 0, radius, 0, 2*math.pi) cr.stroke() # Some small notches on the disc edge for pure colors if wd > 75 or ht > 75: cr.save() cr.arc(0, 0, radius+self.EDGE_HIGHLIGHT_WIDTH, 0, 2*math.pi) cr.clip() pure_cols = [ RGBColor(1, 0, 0), RGBColor(1, 1, 0), RGBColor(0, 1, 0), RGBColor(0, 1, 1), RGBColor(0, 0, 1), RGBColor(1, 0, 1), ] for col in pure_cols: x, y = self.get_pos_for_color(col) x = int(x)-cx y = int(y)-cy cr.set_source_rgba(*self.EDGE_HIGHLIGHT_RGBA) cr.arc(x+0.5, y+0.5, 1.0+self.EDGE_HIGHLIGHT_WIDTH, 0, 2*math.pi) cr.fill() cr.set_source_rgba(*self.OUTLINE_RGBA) cr.arc(x+0.5, y+0.5, self.EDGE_HIGHLIGHT_WIDTH, 0, 2*math.pi) cr.fill() cr.restore() cr.restore()
def _draw(self, context, drawing_table=None): self._process_color({ 'Pressed': gtk.STATE_ACTIVE, 'Released': gtk.STATE_NORMAL }[self._state]) if drawing_table is None: drawing_table = self._drawing_table for element in drawing_table: x_list = [] y_list = [] context.new_path() for command in element: if command[0] == 'm': context.move_to(command[1], command[2]) x_list.append(command[1]) y_list.append(command[2]) elif command[0] == 'l': context.line_to(command[1], command[2]) x_list.append(command[1]) y_list.append(command[2]) elif command[0] == 'b': context.curve_to(command[1], command[2], command[3], command[4], command[5], command[6]) x_list.append(command[5]) y_list.append(command[6]) elif command[0] == 'a': context.arc(command[1], command[2], command[3], command[4], command[5]) x_list.append(command[1] - command[3]) x_list.append(command[1] + command[3]) y_list.append(command[2] - command[3]) y_list.append(command[2] + command[3]) elif command[0] == 'n': context.arc_negative(command[1], command[2], command[3], command[4], command[5]) x_list.append(command[1] - command[3]) x_list.append(command[1] + command[3]) y_list.append(command[2] - command[3]) y_list.append(command[2] + command[3]) elif command[0] == 's': if isinstance(command[1], tuple): pattern = cairo.SolidPattern(command[1][0], command[1][1], command[1][2], command[1][3]) elif callable(command[1]): data = command[1]() pattern = cairo.SolidPattern(data[0], data[1], data[2], data[3]) else: pattern = cairo.SolidPattern(command[1], command[2], command[3], command[4]) context.set_source(pattern) elif command[0] == 'g': pattern = cairo.LinearGradient(min(x_list), min(y_list), max(x_list), max(y_list)) if callable(command[2]) and callable(command[4]): data = command[2]() pattern.add_color_stop_rgba(command[1], data[0], data[1], data[2], data[3]) data = command[4]() pattern.add_color_stop_rgba(command[3], data[0], data[1], data[2], data[3]) else: pattern.add_color_stop_rgb(command[1], command[2], command[3], command[4]) pattern.add_color_stop_rgb(command[5], command[6], command[7], command[8]) context.set_source(pattern) elif command[0] == 'p': context.set_source_rgba(command[1], command[2], command[3], command[4]) context.set_line_width(command[5]) context.stroke_preserve() context.set_source_rgba(command[1], command[2], command[3], 0.0) else: raise NotImplementedError( _('Command "%s" not implemented in drawing.') % command[0]) context.close_path() #pattern = cairo.LinearGradient(min(x_list), min(y_list), max(x_list), max(y_list)) #pattern.add_color_stop_rgb(0.25, 100, 100, 100) #pattern.add_color_stop_rgb(1, 0, 0, 0) context.fill_preserve() return
def expose(self, widget, event): cr, (w, h), set_color, alpha = self._expose_prepare(widget) # make bar cr.save() set_color(Gdk.Color.parse('black')[1]) zv = h * self.get_value_diff(self.zero) wv = h * self.get_value_diff(self.value) if not self.invert: cr.rectangle(0, h - wv, w, wv - zv) else: cr.rectangle(0, zv, w, wv - zv) cr.clip_preserve() cr.stroke_preserve() bi_flag = bool((self.min == (- self.max)) and self.value < 0) if self.invert or bi_flag: lg = cairo.LinearGradient(0, 0, 0, h) else: lg = cairo.LinearGradient(0, h, 0, 0) self._load_gradient(lg, alpha) cr.set_source(lg) cr.fill() cr.restore() # now make it shiny if self.shiny: cr.rectangle(0, 0, w, h) lg = cairo.LinearGradient(0, 0, w, 0) lg.add_color_stop_rgba(0, 0, 0, 0, .5) lg.add_color_stop_rgba(.16, 1, 1, 1, .25) lg.add_color_stop_rgba(.33, 1, 1, 1, .75) lg.add_color_stop_rgba(.66, 1, 1, 1, .25) lg.add_color_stop_rgba(1, 0, 0, 0, .5) cr.set_source(lg) cr.fill() # make target line if self.target_value > 0: set_color(self.target_color) if self.target_value > self.max: tvalue = self.max else: tvalue = self.target_value wv = h * self.get_value_diff(tvalue) cr.set_line_width(self.target_width) if not self.invert: cr.move_to(0,h - wv) cr.rel_line_to(w,0) else: #cr.rectangle(w - wv, 0, wv - zv, h) cr.move_to(0,zv + wv) cr.rel_line_to(w,0) cr.stroke() # make text set_color(Gdk.Color.parse('black')[1]) tmpl = lambda s: self.text_template % s if self.show_limits: if not self.invert: self.text_at(cr, tmpl(self.max), w/2, 5, yalign='top') self.text_at(cr, tmpl(self.min), w/2, h-5, yalign='bottom') else: self.text_at(cr, tmpl(self.min), w/2, 5, yalign='top') self.text_at(cr, tmpl(self.max), w/2, h-5, yalign='bottom') self.text_at(cr, tmpl(self.value), w/2, h/2) return False
def _draw(self, context): context.set_antialias(cairo.ANTIALIAS_DEFAULT) #pattern = cairo.LinearGradient(10, 10, 90, 90) #pattern.add_color_stop_rgb(0.25, 200, 200, 200) #pattern.add_color_stop_rgb(0.75, 100, 100, 100) for element in ControlButtons.__drawing_table: x_list = [] y_list = [] for command in element: if command[0] == 'm': context.move_to(command[1], command[2]) x_list.append(command[1]) y_list.append(command[2]) elif command[0] == 'l': context.line_to(command[1], command[2]) x_list.append(command[1]) y_list.append(command[2]) elif command[0] == 'b': context.curve_to(command[1], command[2], command[3], command[4], command[5], command[6]) x_list.append(command[5]) y_list.append(command[6]) elif command[0] == 'a': context.arc(command[1], command[2], command[3], command[4], command[5]) x_list.append(command[1] - command[3]) x_list.append(command[1] + command[3]) y_list.append(command[2] - command[3]) y_list.append(command[2] + command[3]) elif command[0] == 'n': context.arc_negative(command[1], command[2], command[3], command[4], command[5]) x_list.append(command[1] - command[3]) x_list.append(command[1] + command[3]) y_list.append(command[2] - command[3]) y_list.append(command[2] + command[3]) elif command[0] == 's': pattern = cairo.SolidPattern(command[1], command[2], command[3], command[4]) context.set_source(pattern) elif command[0] == 'g': pattern = cairo.LinearGradient(min(x_list), min(y_list), max(x_list), max(y_list)) pattern.add_color_stop_rgb(command[1], command[2], command[3], command[4]) pattern.add_color_stop_rgb(command[5], command[6], command[7], command[8]) context.set_source(pattern) elif command[0] == 'p': context.set_source_rgba(command[1], command[2], command[3], command[4]) context.set_line_width(command[5]) context.stroke_preserve() context.set_source_rgba(command[1], command[2], command[3], 0.0) else: raise NotImplementedError( _('Command "%s" not implemented in drawing.') % command[0]) context.close_path() #pattern = cairo.LinearGradient(min(x_list), min(y_list), max(x_list), max(y_list)) #pattern.add_color_stop_rgb(0.25, 100, 100, 100) #pattern.add_color_stop_rgb(1, 0, 0, 0) context.fill_preserve() context.new_path()
def draw_dish_key(self, context, rect, fill, line_width, lod): # compensate for smaller size due to missing stroke rect = rect.inflate(1.0) # parameters for the base rectangle w, h = rect.get_size() w2, h2 = w * 0.5, h * 0.5 xc, yc = rect.get_center() radius_pct = config.theme_settings.roundrect_radius radius_pct = max(radius_pct, 2) # too much +-1 fudging for square corners r, k = self.get_curved_rect_params(rect, radius_pct) base_rgba = brighten(-0.200, *fill) stroke_gradient = config.theme_settings.key_stroke_gradient / 100.0 light_dir = self.get_light_direction() # parameters for the top rectangle, key face scale = config.theme_settings.key_stroke_width / 100.0 border = config.DISH_KEY_BORDER border = (border[0] * scale, border[1] * scale) border = self.context.scale_log_to_canvas(border) offset_top = self.context.scale_log_to_canvas_y( config.DISH_KEY_Y_OFFSET) rect_top = rect.deflate(*border).offset(0, -offset_top) rect_top.w = max(rect_top.w, 0.0) rect_top.h = max(rect_top.h, 0.0) top_radius_scale = rect_top.h / float(rect.h) r_top, k_top = self.get_curved_rect_params( rect_top, radius_pct * top_radius_scale) # draw key border if self.show_border: if not lod: self.build_rect_path(context, rect) context.set_source_rgba(*base_rgba) context.fill() else: # lambert lighting edge_colors = [] for edge in range(4): normal_dir = edge * pi / 2.0 # 0 = light from top I = cos(normal_dir - light_dir) * stroke_gradient * 0.8 edge_colors.append(brighten(I, *base_rgba)) context.save() context.translate(xc, yc) # edge sections, edge 0 = top for edge in range(4): if edge & 1: p = (h2, w2) p_top = [rect_top.h / 2.0, rect_top.w / 2.0] else: p = (w2, h2) p_top = [rect_top.w / 2.0, rect_top.h / 2.0] m = cairo.Matrix() m.rotate(edge * pi / 2.0) p0 = m.transform_point(-p[0] + r - 1, -p[1]) # -1 to fill gaps p1 = m.transform_point(p[0] - r + 1, -p[1]) p0_top = m.transform_point(p_top[0] - r_top + 1, -p_top[1] + 1) p1_top = m.transform_point(-p_top[0] + r_top - 1, -p_top[1] + 1) p0_top = (p0_top[0], p0_top[1] - offset_top) p1_top = (p1_top[0], p1_top[1] - offset_top) context.set_source_rgba(*edge_colors[edge]) context.move_to(p0[0], p0[1]) context.line_to(p1[0], p1[1]) context.line_to(*p0_top) context.line_to(*p1_top) context.close_path() context.fill() # corner sections for edge in range(4): if edge & 1: p = (h2, w2) p_top = [rect_top.h / 2.0, rect_top.w / 2.0] else: p = (w2, h2) p_top = [rect_top.w / 2.0, rect_top.h / 2.0] m = cairo.Matrix() m.rotate(edge * pi / 2.0) p1 = m.transform_point(p[0] - r, -p[1]) p2 = m.transform_point(p[0], -p[1] + r) pk0 = m.transform_point(p[0] - k, -p[1]) pk1 = m.transform_point(p[0], -p[1] + k) p0_top = m.transform_point(p_top[0] - r_top, -p_top[1]) p2_top = m.transform_point(p_top[0], -p_top[1] + r_top) p0_top = (p0_top[0], p0_top[1] - offset_top) p2_top = (p2_top[0], p2_top[1] - offset_top) # Fake Gouraud shading: draw a gradient between mid points # of the lines connecting the base with the top rectangle. gline = ((p1[0] + p0_top[0]) / 2.0, (p1[1] + p0_top[1]) / 2.0, (p2[0] + p2_top[0]) / 2.0, (p2[1] + p2_top[1]) / 2.0) pat = cairo.LinearGradient(*gline) pat.add_color_stop_rgba(0.0, *edge_colors[edge]) pat.add_color_stop_rgba(1.0, *edge_colors[(edge + 1) % 4]) context.set_source(pat) context.move_to(*p1) context.curve_to(pk0[0], pk0[1], pk1[0], pk1[1], p2[0], p2[1]) context.line_to(*p2_top) context.line_to(*p0_top) context.close_path() context.fill() context.restore() # Draw the key face, the smaller top rectangle. if self.show_face: if not lod: context.set_source_rgba(*fill) else: # Simulate the concave key dish with a gradient that has # a sligthly brighter middle section. if self.id == "SPCE": angle = pi / 2.0 # space has a convex top else: angle = 0.0 # all others are concave fill_gradient = config.theme_settings.key_fill_gradient / 100.0 dark_rgba = brighten(-fill_gradient * .5, *fill) bright_rgba = brighten(+fill_gradient * .5, *fill) gline = gradient_line(rect, angle) pat = cairo.LinearGradient(*gline) pat.add_color_stop_rgba(0.0, *dark_rgba) pat.add_color_stop_rgba(0.5, *bright_rgba) pat.add_color_stop_rgba(1.0, *dark_rgba) context.set_source(pat) self.build_rect_path(context, rect_top, top_radius_scale) context.fill()
def draw_text_pill(left_text, right_text, x=0, y=0, border=2, radius=14, font_desc=None): # Use GTK+ style of a normal Button widget = Gtk.Label() style_context = widget.get_style_context() # Padding (in px) at the right edge of the image (for Ubuntu; bug 1533) padding_right = 7 x_border = border * 2 if font_desc is None: font_desc = style_context.get_font(Gtk.StateFlags.NORMAL) font_desc.set_weight(Pango.Weight.BOLD) pango_context = widget.create_pango_context() layout_left = Pango.Layout(pango_context) layout_left.set_font_description(font_desc) layout_left.set_text(left_text, -1) layout_right = Pango.Layout(pango_context) layout_right.set_font_description(font_desc) layout_right.set_text(right_text, -1) width_left, height_left = layout_left.get_pixel_size() width_right, height_right = layout_right.get_pixel_size() text_height = max(height_left, height_right) image_height = int(y + text_height + border * 2) image_width = int(x + width_left + width_right + x_border * 4 + padding_right) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, image_width, image_height) ctx = cairo.Context(surface) # Clip so as to not draw on the right padding (for Ubuntu; bug 1533) ctx.rectangle(0, 0, image_width - padding_right, image_height) ctx.clip() if left_text == '0': left_text = None if right_text == '0': right_text = None left_side_width = width_left + x_border * 2 right_side_width = width_right + x_border * 2 rect_width = left_side_width + right_side_width rect_height = text_height + border * 2 if left_text is not None: draw_rounded_rectangle(ctx, x, y, rect_width, rect_height, radius, left_side_width, RRECT_LEFT_SIDE, right_text is None) linear = cairo.LinearGradient(x, y, x + left_side_width / 2, y + rect_height / 2) linear.add_color_stop_rgba(0, .8, .8, .8, .5) linear.add_color_stop_rgba(.4, .8, .8, .8, .7) linear.add_color_stop_rgba(.6, .8, .8, .8, .6) linear.add_color_stop_rgba(.9, .8, .8, .8, .8) linear.add_color_stop_rgba(1, .8, .8, .8, .9) ctx.set_source(linear) ctx.fill() xpos, ypos, width_left, height = x + 1, y + 1, left_side_width, rect_height - 2 if right_text is None: width_left -= 2 draw_rounded_rectangle(ctx, xpos, ypos, rect_width, height, radius, width_left, RRECT_LEFT_SIDE, right_text is None) ctx.set_source_rgba(1., 1., 1., .3) ctx.set_line_width(1) ctx.stroke() draw_rounded_rectangle(ctx, x, y, rect_width, rect_height, radius, left_side_width, RRECT_LEFT_SIDE, right_text is None) ctx.set_source_rgba(.2, .2, .2, .6) ctx.set_line_width(1) ctx.stroke() ctx.move_to(x + x_border, y + 1 + border) ctx.set_source_rgba(0, 0, 0, 1) PangoCairo.show_layout(ctx, layout_left) ctx.move_to(x - 1 + x_border, y + border) ctx.set_source_rgba(1, 1, 1, 1) PangoCairo.show_layout(ctx, layout_left) if right_text is not None: draw_rounded_rectangle(ctx, x, y, rect_width, rect_height, radius, left_side_width, RRECT_RIGHT_SIDE, left_text is None) linear = cairo.LinearGradient( x + left_side_width, y, x + left_side_width + right_side_width / 2, y + rect_height) linear.add_color_stop_rgba(0, .2, .2, .2, .9) linear.add_color_stop_rgba(.4, .2, .2, .2, .8) linear.add_color_stop_rgba(.6, .2, .2, .2, .6) linear.add_color_stop_rgba(.9, .2, .2, .2, .7) linear.add_color_stop_rgba(1, .2, .2, .2, .5) ctx.set_source(linear) ctx.fill() xpos, ypos, width, height = x, y + 1, rect_width - 1, rect_height - 2 if left_text is None: xpos, width = x + 1, rect_width - 2 draw_rounded_rectangle(ctx, xpos, ypos, width, height, radius, left_side_width, RRECT_RIGHT_SIDE, left_text is None) ctx.set_source_rgba(1., 1., 1., .3) ctx.set_line_width(1) ctx.stroke() draw_rounded_rectangle(ctx, x, y, rect_width, rect_height, radius, left_side_width, RRECT_RIGHT_SIDE, left_text is None) ctx.set_source_rgba(.1, .1, .1, .6) ctx.set_line_width(1) ctx.stroke() ctx.move_to(x + left_side_width + x_border, y + 1 + border) ctx.set_source_rgba(0, 0, 0, 1) PangoCairo.show_layout(ctx, layout_right) ctx.move_to(x - 1 + left_side_width + x_border, y + border) ctx.set_source_rgba(1, 1, 1, 1) PangoCairo.show_layout(ctx, layout_right) return surface
def drawGraph(self, cr, width, height): key2fill = {} key2interpolation = {} for yfield in self.yfields: key = yfield.get('key', yfield['name']) key2fill[key] = bool(int(yfield.get('fill', 0))) key2interpolation[key] = yfield.get('interpolation', 'linear') def preparePath(key): interpolation = key2interpolation[key] points = (p for p in self.points if p.yname == key) zero = 1.0 + self.minyval * self.yscale cr.new_path() cr.move_to(self.area.x, zero * self.area.h + self.area.y) if interpolation == 'linear': for point in points: cr.line_to(point.x * self.area.w + self.area.x, point.y * self.area.h + self.area.y) else: previous = Point(0, zero, None, None, None, None) def breakage(previous, point): if interpolation == 'constant-center': return previous.x + ((point.x - previous.x) / 2.0) elif interpolation == 'constant-left': return point.x elif interpolation == 'constant-right': return previous.x for point in points: cr.line_to( breakage(previous, point) * self.area.w + self.area.x, previous.y * self.area.h + self.area.y) cr.line_to( breakage(previous, point) * self.area.w + self.area.x, point.y * self.area.h + self.area.y) cr.line_to(point.x * self.area.w + self.area.x, point.y * self.area.h + self.area.y) previous = point cr.line_to( breakage(previous, Point(1, zero, None, None, None, None)) * self.area.w + self.area.x, previous.y * self.area.h + self.area.y) cr.line_to(self.area.w + self.area.x, zero * self.area.h + self.area.y) cr.move_to(self.area.x, zero * self.area.h + self.area.y) if key2fill[key]: cr.close_path() else: cr.set_source_rgb(*self.colorScheme[key]) cr.stroke() cr.save() cr.set_line_width(2) if self._getDatasKeys(): transparency = 0.8 / len(self._getDatasKeys()) for key in self._getDatasKeys(): if key2fill[key]: cr.save() r, g, b = self.colorScheme[key] preparePath(key) cr.set_source_rgb(r, g, b) cr.stroke_preserve() cr.restore() # Add soft transparency the area when line is filled cr.set_source_rgba(r, g, b, transparency) cr.fill() # Add gradient top to bottom linear = cairo.LinearGradient(width / 2, 0, width / 2, height) linear.add_color_stop_rgba(0, r * 0.65, g * 0.65, b * 0.65, transparency) linear.add_color_stop_rgba(1, r, g, b, 0.1) cr.set_source(linear) preparePath(key) cr.fill() else: preparePath(key) for point in self.points: cr.set_source_rgb(*self.colorScheme[point.yname]) cr.move_to(point.x * self.area.w + self.area.x, point.y * self.area.h + self.area.y) cr.arc(point.x * self.area.w + self.area.x, point.y * self.area.h + self.area.y, 3, 0, 2 * math.pi) cr.fill() cr.restore()
def render_frame(self, cr, a, border_radius, assets): # we cache as much of the drawing as possible # store a copy of the rendered frame surface, so we only have to # do a full redraw if the widget dimensions change if self._frame_surface_cache is None: surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, a.width, a.height) _cr = cairo.Context(surf) at = self.ASSET_TAG width = a.width height = a.height cnr_slice = assets["corner-slice"] # paint north-west corner _cr.set_source_surface(assets["%s-nw" % at], 0, 0) _cr.paint() # paint north length _cr.save() _cr.set_source(assets["%s-n" % at]) _cr.rectangle(cnr_slice, 0, width - 2 * cnr_slice, cnr_slice) _cr.clip() _cr.paint() _cr.restore() # paint north-east corner _cr.set_source_surface(assets["%s-ne" % at], width - cnr_slice, 0) _cr.paint() # paint east length _cr.save() _cr.translate(width - cnr_slice, cnr_slice) _cr.set_source(assets["%s-e" % at]) _cr.rectangle(0, 0, cnr_slice, height - 2 * cnr_slice) _cr.clip() _cr.paint() _cr.restore() # paint south-east corner _cr.set_source_surface(assets["%s-se" % at], width - cnr_slice, height - cnr_slice) _cr.paint() # paint south length _cr.save() _cr.translate(cnr_slice, height - cnr_slice) _cr.set_source(assets["%s-s" % at]) _cr.rectangle(0, 0, width - 2 * cnr_slice, cnr_slice) _cr.clip() _cr.paint() _cr.restore() # paint south-west corner _cr.set_source_surface(assets["%s-sw" % at], 0, height - cnr_slice) _cr.paint() # paint west length _cr.save() _cr.translate(0, cnr_slice) _cr.set_source(assets["%s-w" % at]) _cr.rectangle(0, 0, cnr_slice, height - 2 * cnr_slice) _cr.clip() _cr.paint() _cr.restore() # fill interior rounded_rect(_cr, 3, 2, a.width - 6, a.height - 6, border_radius) context = self.get_style_context() bg = context.get_background_color(self.get_state_flags()) Gdk.cairo_set_source_rgba(_cr, bg) _cr.fill_preserve() lin = cairo.LinearGradient(0, 0, 0, max(300, a.height)) lin.add_color_stop_rgba(0, 1, 1, 1, 0.02) lin.add_color_stop_rgba(1, 0, 0, 0, 0.06) _cr.set_source(lin) _cr.fill() self._frame_surface_cache = surf del _cr # paint the cached surface and apply a rounded rect clip to # child draw ops A = self.get_allocation() xo, yo = a.x - A.x, a.y - A.y cr.set_source_surface(self._frame_surface_cache, xo, yo) cr.paint()
def draw(self, cairo_ctx): if self.has_focus(): state = Gtk.StateType.PRELIGHT else: state = Gtk.StateType.NORMAL #cairo_ctx.rectangle(0, 0, self.width, self.height) #cairo_ctx.set_source_color(self.style.bg[state]) #cairo_ctx.fill_preserve() #Gdk.cairo_set_source_color(cairo_ctx, # self.get_style_context().get_color(state).to_color()) #cairo_ctx.stroke() slider_knob_width = 37.5 if self.width * 3 / 4 > 37.5 else self.width * 3 / 4 slider_knob_height = slider_knob_width * 2 slider_knob_height -= slider_knob_height % 2 slider_knob_height += 1 slider_x = self.width / 2 cairo_ctx.set_line_width(1) # slider rail Gdk.cairo_set_source_color( cairo_ctx, self.get_style_context().get_color(state).to_color()) self.slider_rail_up = slider_knob_height / 2 + (self.width - slider_knob_width) / 2 self.slider_rail_height = self.height - 2 * self.slider_rail_up cairo_ctx.move_to(slider_x, self.slider_rail_up) cairo_ctx.line_to(slider_x, self.slider_rail_height + self.slider_rail_up) cairo_ctx.stroke() # slider knob slider_y = round(self.slider_rail_up + self.slider_rail_height * (1 - self.adjustment.get_value())) lg = cairo.LinearGradient(slider_x - float(slider_knob_width) / 2, slider_y - slider_knob_height / 2, slider_x - float(slider_knob_width) / 2, slider_y + slider_knob_height / 2) slider_alpha = 1.0 lg.add_color_stop_rgba(0, 0.55, 0.55, 0.55, slider_alpha) lg.add_color_stop_rgba(0.1, 0.65, 0.65, 0.65, slider_alpha) lg.add_color_stop_rgba(0.1, 0.75, 0.75, 0.75, slider_alpha) lg.add_color_stop_rgba(0.125, 0.75, 0.75, 0.75, slider_alpha) lg.add_color_stop_rgba(0.125, 0.15, 0.15, 0.15, slider_alpha) lg.add_color_stop_rgba(0.475, 0.35, 0.35, 0.35, slider_alpha) lg.add_color_stop_rgba(0.475, 0, 0, 0, slider_alpha) lg.add_color_stop_rgba(0.525, 0, 0, 0, slider_alpha) lg.add_color_stop_rgba(0.525, 0.35, 0.35, 0.35, slider_alpha) lg.add_color_stop_rgba(0.875, 0.65, 0.65, 0.65, slider_alpha) lg.add_color_stop_rgba(0.875, 0.75, 0.75, 0.75, slider_alpha) lg.add_color_stop_rgba(0.900, 0.75, 0.75, 0.75, slider_alpha) lg.add_color_stop_rgba(0.900, 0.15, 0.15, 0.15, slider_alpha) lg.add_color_stop_rgba(1.000, 0.10, 0.10, 0.10, slider_alpha) cairo_ctx.rectangle(slider_x - float(slider_knob_width) / 2, slider_y - slider_knob_height / 2, float(slider_knob_width), slider_knob_height) Gdk.cairo_set_source_color( cairo_ctx, self.get_style_context().get_background_color(state).to_color()) cairo_ctx.fill_preserve() cairo_ctx.set_source(lg) cairo_ctx.fill()
def _create_bars_chart(self, context, image_width, image_height): _set_screen_dpi() scale = image_width / 1600. context.rectangle(0, 0, image_width, image_height) logging.debug('canvas size %s x %s - scale %s', image_width, image_height, scale) context.set_source_rgb(1, 1, 1) context.fill() margin_top = (style.GRID_CELL_SIZE / 2) * scale padding = 20 * scale margin = padding * 2 title_font_size = self._calculate_title_font_size(scale) title_width, title_height = self._measure_text(self._title, title_font_size, max_width=image_width - margin * 2) logging.error('measure text bars %s %s', title_width, title_height) margin_top += title_height + margin graph_width = image_width - margin * 2 graph_height = image_height - margin_top - margin * 3 bar_width = graph_width / len(self._data) - margin max_bar_height = graph_height if self._show_labels: # measure the descriptions max_height = 0 for data in self._data: description = data['label'] # If there is no category, display as Unknown if description is '': description = _('Unknown') width, height = self._measure_text(description, (12 * scale), max_width=bar_width) max_height = max(max_height, height) max_bar_height = graph_height - max_height # draw the labels y = max_bar_height + margin * 2 + margin_top x = margin * 2 for data in self._data: description = data['label'] if description is '': description = _('Unknown') self._print_text(context, x, y, description, (12 * scale), max_width=bar_width, alignment=Pango.Alignment.CENTER) x += bar_width + margin self._print_text(context, 0, margin, self._title, title_font_size, max_width=image_width - margin * 2, alignment=Pango.Alignment.CENTER, color=self._title_color) max_value = 0 for data in self._data: max_value = max(max_value, data['value']) x_value = margin for data in self._data: value = data['value'] bar_height = value * max_bar_height / max_value bar_top = max_bar_height - bar_height + margin + margin_top top_rounded_rect(context, x_value + margin, bar_top, bar_width, bar_height, 10) color = style.Color(data['color']) context.set_source_rgba(*color.get_rgba()) context.fill() # draw the value width, height = self._measure_text(str(value), (22 * scale)) x_label = x_value + margin + bar_width / 2 - width / 2 if height * 2 < bar_height: y_label = bar_top + height else: y_label = bar_top - height * 2 self._print_text(context, x_label, y_label, str(value), (22 * scale), alignment=Pango.Alignment.CENTER) x_value += bar_width + margin # add a shadow at the bottom context.rectangle(2 * margin, max_bar_height + margin + margin_top, (bar_width + margin) * len(self._data) - margin, margin) gradient = cairo.LinearGradient( 2 * margin, max_bar_height + margin + margin_top, 2 * margin, max_bar_height + margin * 1.5 + margin_top) gradient.add_color_stop_rgba(0, 0, 0, 0, 0.10) gradient.add_color_stop_rgba(1, 1, 1, 1, 0.10) context.set_source(gradient) context.fill()
def main(): args = sys.argv[1:] if not args: print('usage: [-h, --help]') sys.exit(1) parser = ap.ArgumentParser() parser.add_argument( '--test_mode', action='store_true', help='Generate test graphs instead of using the Granatum SDK.') parser.add_argument( '--ppi_table', type=str, metavar='TAB_DELIMITED_TABLE', help='BIOGRID table with "Official Symbol Interactor A" and ' + 'Official Symbol Interactor B" named columns containing ' + 'the gene symbol pairs.') parser.add_argument( '--top_scoring_genes', type=int, default=100, metavar='INTEGER', help='Number of top absolute value scoring genes to include.') # parsed_args, unparsed = parser.parse_known_args() parsed_args = parser.parse_args() gene_pairs = pd.read_table(parsed_args.ppi_table, low_memory=False # compression='bz2', # header=1 ) number_of_top_genes = parsed_args.top_scoring_genes print(gene_pairs.head()) # TEST - can be removed later # Populate species and gene-scores depending on gbox_mode species = None gene_score_dict = None if (parsed_args.test_mode == False): print("Gbox mode") gn = gsdk.Granatum() species = gn.get_arg('species') gene_score_dict = gn.get_import('genesAndScores') else: print("Test mode") # Select vertices according to species = 'Hs' # Keeping Hs or Mm convention from Granatum (v1) gene_score_dict = dict() if species == 'Hs': gene_score_dict['BRCA1'] = 2 gene_score_dict['PRRC2A'] = 3 gene_score_dict['HNRNPM'] = 1 gene_score_dict['QARS'] = -1 gene_score_dict['MSH2'] = -0.5 gene_score_dict['HAND2'] = 0.25 gene_score_dict['EIF3K'] = 1 gene_score_dict['TCF3'] = -0.15 # if 'TCF3' in gene_score_dict: # print("OK "+'TCF3 '+str(gene_score_dict['TCF3'])) # TEST # Subset to top absolute values (otherwise graph will get too busy) gene_score_top_genes = sorted( gene_score_dict, reverse=True, key=lambda key: abs(gene_score_dict[key]))[0:number_of_top_genes] print("TEST:") # TEST print(gene_score_top_genes) # TEST # Set species code species_code = None if species == 'Hs': species_code = 9606 elif species == 'Mm': species_code = 10090 else: # Error raise ValueError('Could not understand species arguement.') # Get min/max of gene scores for scaling to adjust colors in graph score_min = min(gene_score_dict.values()) score_max = max(gene_score_dict.values()) score_scale = mpl.colors.Normalize(vmin=score_min, vmax=score_max) # Colors: https://matplotlib.org/users/colormaps.html #color_mapper = mpl.cm.ScalarMappable(norm=score_scale, cmap=mpl.cm.Greys) # Grey scale # If check for +/-, etc. may go with colors and scaled +/- the highest absolute value color_mapper = mpl.cm.ScalarMappable(norm=score_scale, cmap=mpl.cm.RdBu) # Red to blue print("min: " + str(score_min)) # TEST print("max: " + str(score_max)) # TEST # Load graph, filtering on input g = ig.Graph() # Without further filtering, multiple edges may be drawn for each # record, e.g., the gene-gene pair may be referenced in multiple # publications. Another idea could be to deduplicate entirely or # incrase the edge size for each additional pair. The same gene # may also reference its self, and currently will show an edge that # gets drawn back on its self, which may be reasonable to show. # To speed up processing, the human and mouse datasets could be separated, # however, to make it easy to update the PPI database, one file is used. #for index, row in gene_pairs.head(200).iterrows(): # TEST for index, row in gene_pairs.iterrows(): gene_A = row['Official Symbol Interactor A'] gene_B = row['Official Symbol Interactor B'] organism_A = row['Organism ID Interactor A'] organism_B = row['Organism ID Interactor B'] if ((organism_A == species_code) and (organism_A == organism_B)): # if ((gene_A in gene_score_dict) and # (gene_B in gene_score_dict)): if ((gene_A in gene_score_top_genes) and (gene_B in gene_score_top_genes)): # Keep the "label" attribute, since it is recognized by the plot function # Add colors according to score and min/max scaling score_A = gene_score_dict[gene_A] score_B = gene_score_dict[gene_B] color_A = color_mapper.to_rgba(score_A) color_B = color_mapper.to_rgba(score_B) g.add_vertex(gene_A, label=gene_A, color=color_A, label_size=14, label_angle=1.5708, label_dist=1) g.add_vertex(gene_B, label=gene_B, color=color_B, label_size=14, label_angle=1.5708, label_dist=1) g.add_edge(gene_A, gene_B) print(g) # TEST # Subset if want to load entire graph then subset # g_subgraph = g.induced_subgraph(vertices=gene_score_dict.keys()) # Not subsetting g_subgraph = g print(g_subgraph) # TEST print(g_subgraph.degree()) # TEST # Use vertices with at least one edge (degree > 0) g_seq = g_subgraph.vs(_degree_gt=0) g_subgraph_degree_gt_0 = g_subgraph.induced_subgraph(g_seq) if g_subgraph_degree_gt_0.ecount() == 0: # If the graph is empty there are no protein interactions fig = plt.figure() ax = fig.add_subplot(111) ax.axis('off') ax.text(0.1, 0.5, 'No protein interactions found') gn.add_current_figure_to_results(description='PPI-plot') gn.commit() else: kk_layout = g_subgraph_degree_gt_0.layout("kamada_kawai") plot = ig.plot(g_subgraph_degree_gt_0, "ppi_kk_plot_deg_gt_0.png", layout=kk_layout, bbox=(1000, 1000)) context = cairo.Context( plot.surface) # Get plot surface for manipulation # Add title and legend # This part could use improvement: consider switching to put the igraph # into matplotlib, scale to absolute min/max, and include tick marks pattern = cairo.LinearGradient( 0.0, 100.0, 0.0, 200.0) # cairo.LinearGradient(x0, y0, x1, y1) pattern.add_color_stop_rgba(0.0, 0, 0, 0, 0.9) pattern.add_color_stop_rgba(1.0, 1, 1, 1, 0.9) context.rectangle(900, 100, 20, 100) # Rectangle(x0, y0, x1, y1) context.set_source(pattern) context.fill() context = cairo.Context( plot.surface) # Get plot surface for manipulation context.set_font_size(20) drawer = ig.drawing.text.TextDrawer( context, score_max, valign=ig.drawing.text.TextDrawer.BOTTOM, halign=ig.drawing.text.TextDrawer.CENTER) drawer.draw_at(900, 95, width=20) drawer = ig.drawing.text.TextDrawer( context, score_min, valign=ig.drawing.text.TextDrawer.TOP, halign=ig.drawing.text.TextDrawer.CENTER) drawer.draw_at(900, 205, width=20) mpl.use("cairo") # Create the figure fig = plt.figure() # Create a basic plot axes = fig.add_subplot(111) graph_artist = GraphArtist(g_subgraph_degree_gt_0, (1000, 1000, 150, 150), layout=kk_layout) graph_artist.set_zorder(float('inf')) axes.artists.append(graph_artist) axes.axis('off') gn.add_current_figure_to_results(description="PPI-plot") gn.commit()
def __init__(self, x1, y1, x2, y2): self.pattern = cairo.LinearGradient(x1, y1, x2, y2)
def do_draw(self, ctx): alloc = self.get_allocation() # in case there are no parents use the same alloc which should # result in no custom drawing. p1 = self.get_parent() or self p2 = p1.get_parent() or p1 p3 = p2.get_parent() or p2 p2_alloc = p2.get_allocation() p3_alloc = p3.get_allocation() # remove the space needed by the arrow and add the space # added by the padding so we only start drawing when we clip # the text directly available_width = p2_alloc.width - \ abs(p2_alloc.x - alloc.x) + (p2_alloc.x - p3_alloc.x) if alloc.width <= available_width: return Gtk.Label.do_draw(self, ctx) req_height = self.get_requisition().height w, h = alloc.width, alloc.height aw = available_width # possible when adding new columns.... create_similar will fail # in this case below, so just skip. if min(w, h) < 0: return Gtk.Label.do_draw(self, ctx) surface = ctx.get_target() # draw label to image surface label_surface = surface.create_similar(cairo.CONTENT_COLOR_ALPHA, w, h) label_ctx = cairo.Context(label_surface) res = Gtk.Label.do_draw(self, label_ctx) # create a gradient. # make the gradient width depend roughly on the font size gradient_width = min(req_height * 0.8, aw) if self.get_direction() == Gtk.TextDirection.RTL: start = (w - aw) end = start + gradient_width else: end = (aw - gradient_width) start = end + gradient_width pat = cairo.LinearGradient(start, 0, end, 0) pat.add_color_stop_rgba(0, 0, 0, 0, 0) pat.add_color_stop_rgba(gradient_width, 1, 1, 1, 1) # gradient surface grad_surface = surface.create_similar(cairo.CONTENT_COLOR_ALPHA, w, h) imgctx = cairo.Context(grad_surface) imgctx.set_source(pat) imgctx.paint() # draw label using the gradient as the alpha channel mask ctx.save() ctx.set_source_surface(label_surface) ctx.mask_surface(grad_surface) ctx.restore() return res
def Render(self, dc): ctx = g.GraphicsContext.Create(dc) ctx.Clear("wheat") path = ctx.CreatePath() path.AddRectangle(0, 0, 100, 100) ctx.SetPen(g.GraphicsPen('black')) ctx.Translate(10,10) ctx.StrokePath(path) path.AddCircle(50, 50, 50) ctx.Translate(110, 0) ctx.SetPen(ctx.CreatePen(wx.Pen('blue', 3))) ctx.StrokePath(path) sqpath = path ctx.Translate(110, 0) pen = g.GraphicsPen('red', 3, wx.USER_DASH) pen.Dashes = [4, 6, 8, 6, 4] ctx.SetPen(pen) ctx.StrokeLine(0,0, 75,0) pen = g.GraphicsPen('purple', 3) ctx.SetPen(pen) ctx.StrokeLines( [ (0,10), (75,10), (75,30), (0,30) ] ) pen = g.GraphicsPen('green', 3) ctx.SetPen(pen) ctx.StrokeLineSegments( [ ( 0, 50), ( 0, 60), (0, 70), (0, 80) ], [ (75, 50), (75, 60), (75, 70), (75, 80) ] ) ctx.Translate(90, 0) path = ctx.CreatePath() path.AddEllipse(0,0, 100,48) path.AddRoundedRectangle(0,52,100,48, 5) ctx.SetPen(g.GraphicsPen('magenta', 3)) ctx.StrokePath(path) ctx.Translate(110, 0) path = ctx.CreatePath() path.AddLineToPoint(100,100) path.AddLineToPoint(100, 0) path.AddLineToPoint( 0,100) path.AddLineToPoint( 0, 0) path.AddLineToPoint(100,100) ctx.SetPen(g.GraphicsPen('orchid', 3)) ctx.StrokePath(path) ctx.SetTransform(ctx.CreateMatrix()) ctx.Translate(10, 120) pattern = cairo.LinearGradient(0,0, 0,100) pattern.add_color_stop_rgb(0, 0,0,1) pattern.add_color_stop_rgba(1, 1,0,0, 0.1) pen = g.GraphicsPen.CreateFromPattern(pattern, 30) pen.Cap = wx.CAP_BUTT ctx.SetPen(pen) ctx.StrokeLine(0,0, 100, 100) ctx.Translate(110, 0) fname = os.path.join(os.path.dirname(sys.argv[0]), 'toucan.png') bmp = wx.Bitmap(fname) pen = g.GraphicsPen(width=40, style=wx.STIPPLE) pen.Stipple = bmp pen.Cap = wx.CAP_BUTT ctx.SetPen(pen) ctx.StrokeLine(0,0, 100, 100) ctx.Translate(120, 0) ctx.SetPen(g.GraphicsPen('black', 4)) ctx.SetBrush(g.GraphicsBrush('orange')) ctx.FillPath(sqpath) ctx.Translate(120, 0) ctx.DrawPath(sqpath) ctx.SetTransform(ctx.CreateMatrix()) ctx.Translate(10, 250) ctx.SetFont(wx.FFont(28, wx.SWISS, wx.FONTFLAG_BOLD), 'blue') ctx.DrawText("Hello", 0,0) ctx.DrawText("World", 0,35, g.GraphicsBrush('orchid')) ctx.Translate(125, 0) ctx.DrawRotatedText("wxPython", 0, 0, math.radians(-30)) ctx.SetFont(wx.FFont(28, wx.ROMAN, wx.FONTFLAG_BOLD)) ctx.DrawRotatedText("& Cairo", 0, 45, math.radians(-30), g.GraphicsBrush('orchid')) ctx.SetBrush(g.GraphicsBrush((0,128,0,128))) ctx.FillPath(g.GraphicsPath().AddCircle(0,0,4)) ctx.FillPath(g.GraphicsPath().AddCircle(0,45,4)) ctx.Translate(125, 0) font = ctx.CreateFont(wx.FFont(40, wx.SWISS, wx.FONTFLAG_BOLD)) gbrush = ctx.CreateLinearGradientBrush(0,0, 100,0, "orchid", "navy") font.Brush = gbrush ctx.SetFont(font) ctx.DrawText("brush", 0,0)
def Calc(self, ctx): startDI = self.__noderel.getStart().get_drawinfo() endDI = self.__noderel.getEnd().get_drawinfo() (self.__sx, self.__sy) = startDI.get_center() (self.__ex, self.__ey) = endDI.get_center() (self.__sr, self.__er) = (startDI.get_radius(), endDI.get_radius()) (self.__dx, self.__dy) = (self.__ex - self.__sx, self.__ey - self.__sy) self.__l = math.sqrt(math.pow(self.__dx, 2) + math.pow(self.__dy, 2)) # var factor = self.getParent().GetFactor() nodeEdgeSpace = factor / 20 aW = factor / 2 # 箭头宽度 aH = factor / 4 # 箭头高度 angle = math.pi / 8 # 角度 if (self.__l < (self.__sr + self.__er + 2 * nodeEdgeSpace + aW)): print("warning: " + self.get_label() + " dist is too close") return # path asx = self.__sr + nodeEdgeSpace aex = self.__l - self.__er - nodeEdgeSpace # 箭头顶点纵坐标 axillax = aex - aW * 2 / 3 # 箭腋坐标 axillay = aH / 3 ctrl1x = (asx + axillax) / 2 ctrl1y = axillay ctrl2x = (asx + axillax) * 2 / 3 ctrl2y = axillay ctx.new_path() ctx.move_to(asx, 0) ctx.arc(0, 0, asx, 0, angle) ctx.curve_to(ctrl1x, ctrl1y, ctrl2x, ctrl2y, axillax, axillay) ctx.line_to(aex - aW, aH) ctx.line_to(aex, 0) ctx.line_to(asx, 0) ctx.arc_negative(0, 0, asx, 0, -angle) ctx.curve_to(ctrl1x, -ctrl1y, ctrl2x, -ctrl2y, axillax, -axillay) ctx.line_to(aex - aW, -aH) ctx.line_to(aex, 0) ctx.close_path() self.__path = ctx.copy_path() # pat self.__pat = cairo.LinearGradient(asx, 0, aex, 0) self.__pat.add_color_stop_rgba(0, 0.7, 0, 0, 0.3) self.__pat.add_color_stop_rgba(1, 0.3, 0.2, 0.5, 0.3) # mpat self.__mpat = cairo.LinearGradient(asx, 0, aex, 0) self.__mpat.add_color_stop_rgba(0, 0.7, 0, 0, 1) self.__mpat.add_color_stop_rgba(1, 0.3, 0.2, 0.5, 1) # dpat self.__dpat = cairo.LinearGradient(asx, 0, aex, 0) self.__dpat.add_color_stop_rgba(0, 0, 0, 0.5, 1) self.__dpat.add_color_stop_rgba(1, 0.2, 0.1, 0.4, 1)
# ctx.set_source_rgb(0,1,0) # ctx.quick_rect() # pass with ctx.in_box(0,.800,1.000,1.000): radial = cairo.RadialGradient(0.25, 0.25, 0.1, 0.5, 0.5, 0.5) radial.add_color_stop_rgb(0, 1.0, 0.8, 0.8) radial.add_color_stop_rgb(1, 0.9, 0.0, 0.0) for i in range(1, 10): for j in range(1, 10): ctx.rectangle(i/10.0 - 0.04, j/10.0 - 0.04, 0.08, 0.08) ctx.set_source(radial) ctx.fill() linear = cairo.LinearGradient(0.25, 0.35, 0.75, 0.65) linear.add_color_stop_rgba(0.00, 1, 1, 1, 0) linear.add_color_stop_rgba(0.25, 0, 1, 0, 0.5) linear.add_color_stop_rgba(0.50, 1, 1, 1, 0) linear.add_color_stop_rgba(0.75, 0, 0, 1, 0.5) linear.add_color_stop_rgba(1.00, 1, 1, 1, 0) ctx.rectangle(0.0, 0.0, 1, 1) ctx.set_source(linear) ctx.fill() with ctx.in_box(0, 500, 500,1000,(4,10), (4,10)): with ctx.source_rgb(0,0,1): ctx.rectangle(4, 4, 3, 3) ctx.fill() radial = cairo.RadialGradient(0.25, 0.25, 0.1, 0.5, 0.5, 0.5)