def create_multi_row_drag_icon(self, paths, max_rows): """Similar to create_row_drag_icon() but creates a drag icon for multiple paths or None. The resulting surface will draw max_rows rows and point out if there are more rows selected. """ if not paths: return if len(paths) == 1: return self.create_row_drag_icon(paths[0]) # create_row_drag_icon can return None icons = [self.create_row_drag_icon(p) for p in paths[:max_rows]] icons = [i for i in icons if i is not None] if not icons: return sizes = [get_surface_extents(s) for s in icons] if None in sizes: return width = max([s[2] for s in sizes]) height = sum([s[3] for s in sizes]) # this is the border width we see in the gtk provided surface, not # much we can do besides hardcoding it here bw = 1 layout = None if len(paths) > max_rows: more = _(u"and %d more…") % (len(paths) - max_rows) more = "<i>%s</i>" % more layout = self.create_pango_layout("") layout.set_markup(more) layout.set_alignment(Pango.Alignment.CENTER) layout.set_width(Pango.SCALE * (width - 2 * bw)) lw, lh = layout.get_pixel_size() height += lh height += 6 # padding surface = icons[0].create_similar( cairo.CONTENT_COLOR_ALPHA, width, height) ctx = cairo.Context(surface) # render background style_ctx = self.get_style_context() Gtk.render_background(style_ctx, ctx, 0, 0, width, height) # render rows count_y = 0 for icon, (x, y, icon_width, icon_height) in zip(icons, sizes): ctx.save() ctx.set_source_surface(icon, -x, count_y + -y) ctx.rectangle(bw, count_y + bw, icon_width - 2 * bw, icon_height - 2 * bw) ctx.clip() ctx.paint() ctx.restore() count_y += icon_height if layout: Gtk.render_layout(style_ctx, ctx, bw, count_y, layout) # render border Gtk.render_line(style_ctx, ctx, 0, 0, 0, height - 1) Gtk.render_line(style_ctx, ctx, 0, height - 1, width - 1, height - 1) Gtk.render_line(style_ctx, ctx, width - 1, height - 1, width - 1, 0) Gtk.render_line(style_ctx, ctx, width - 1, 0, 0, 0) return surface
def test_get_surface_extents(self): sf = cairo.ImageSurface(cairo.FORMAT_RGB24, 10, 11) self.assertEqual(get_surface_extents(sf), (0, 0, 10, 11))
def draw_title_info(self, cr): cr.save() do_shadow = (self.conf.shadow[0] != -1.0) do_outline = (self.conf.outline[0] != -1.0) self.set_name("osd_bubble") qltk.add_css(self, """ #osd_bubble { background-color:rgba(0,0,0,0); } """) cr.set_operator(cairo.OPERATOR_OVER) cr.set_source_rgba(*self.conf.fill) radius = min(25, self.corners_factor * min(*self.get_size())) self.draw_conf_rect(cr, 0, 0, self.get_size()[0], self.get_size()[1], radius) cr.fill() # draw border if do_outline: # Make border darker and more translucent than the fill f = self.conf.fill rgba = (f[0] / 1.25, f[1] / 1.25, f[2] / 1.25, f[3] / 2.0) cr.set_source_rgba(*rgba) self.draw_conf_rect(cr, 1, 1, self.get_size()[0] - 2, self.get_size()[1] - 2, radius) cr.set_line_width(2.0) cr.stroke() textx = self.BORDER if self.cover_surface is not None: rect = self.cover_rectangle textx += rect.width + self.BORDER surface = self.cover_surface transmat = cairo.Matrix() if do_shadow: cr.set_source_rgba(*self.conf.shadow) self.draw_conf_rect(cr, rect.x + 2, rect.y + 2, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.fill() if do_outline: cr.set_source_rgba(*self.conf.outline) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.stroke() cr.set_source_surface(surface, 0, 0) width, height = get_surface_extents(surface)[2:] transmat.scale(width / float(rect.width), height / float(rect.height)) transmat.translate(-rect.x, -rect.y) cr.get_source().set_matrix(transmat) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.fill() PangoCairo.update_layout(cr, self.title_layout) height = self.title_layout.get_pixel_size()[1] texty = (self.get_size()[1] - height) // 2 if do_shadow: cr.set_source_rgba(*self.conf.shadow) cr.move_to(textx + 2, texty + 2) PangoCairo.show_layout(cr, self.title_layout) if do_outline: cr.set_source_rgba(*self.conf.outline) cr.move_to(textx, texty) PangoCairo.layout_path(cr, self.title_layout) cr.stroke() cr.set_source_rgb(*self.conf.text[:3]) cr.move_to(textx, texty) PangoCairo.show_layout(cr, self.title_layout) cr.restore()