def render(self, widget, cr): if not self.order: return a = self.get_allocation() for layout in self.order: lx, ly = layout.get_position() self._selection_highlight(layout, self.selection, self._bg, self._fg) if layout.is_bullet: if self.get_direction() != Gtk.TextDirection.RTL: indent = layout.indent - self.indent else: indent = a.width - layout.indent self._paint_bullet_point(cr, indent, ly) if self.DEBUG_PAINT_BBOXES: la = layout.allocation cr.rectangle(la.x, la.y, la.width, la.height) cr.set_source_rgb(1, 0, 0) cr.stroke() # draw the layout Gtk.render_layout( self.get_style_context(), cr, lx, # x coord ly, # y coord layout._layout) # a Pango.Layout() # draw the cursor if self.PAINT_PRIMARY_CURSOR and self.has_focus(): self.cursor.draw(cr, self._get_layout(self.cursor), a)
def render(self, widget, cr): if not self.order: return a = self.get_allocation() for layout in self.order: lx, ly = layout.get_position() self._selection_highlight(layout, self.selection, self._bg, self._fg) if layout.is_bullet: if self.get_direction() != Gtk.TextDirection.RTL: indent = layout.indent - self.indent else: indent = a.width - layout.indent self._paint_bullet_point(cr, indent, ly) if self.DEBUG_PAINT_BBOXES: la = layout.allocation cr.rectangle(la.x, la.y, la.width, la.height) cr.set_source_rgb(1, 0, 0) cr.stroke() # draw the layout Gtk.render_layout( self.get_style_context(), cr, lx, ly, layout._layout # x coord # y coord ) # a Pango.Layout() # draw the cursor if self.PAINT_PRIMARY_CURSOR and self.has_focus(): self.cursor.draw(cr, self._get_layout(self.cursor), a)
def _paint_bullet_point(self, cr, x, y): # draw the layout Gtk.render_layout(self.get_style_context(), cr, # state x, # x coord y, # y coord self._bullet._layout) # a Pango.Layout()
def on_draw(self, widget, cr, layout): a = widget.get_allocation() # paint the current animation frame x = (a.width - self.h_stride) * 0.5 y = (a.height - self.v_stride) * 0.5 Gdk.cairo_set_source_pixbuf(cr, self.frame, x, y) cr.paint() if self.transaction_count <= 0: return # paint a bubble with the transaction count layout.set_markup('<small>%i</small>' % self.transaction_count, -1) # determine bubble size extents = layout.get_pixel_extents()[1] width = extents.width + (2 * self.BUBBLE_XPADDING) height = extents.height + (2 * self.BUBBLE_YPADDING) # now render the bubble and layout context = self.get_style_context() x += self.h_stride + self.BUBBLE_XPADDING y += (self.v_stride - height) / 2 rounded_rect(cr, x, y, width, height, self.BUBBLE_BORDER_RADIUS) cr.set_source_rgba(0,0,0,0.2) cr.fill() Gtk.render_layout(context, cr, x + self.BUBBLE_XPADDING, y + self.BUBBLE_YPADDING, layout) return
def _render_summary(self, context, cr, repo, cell_area, layout, xpad, ypad, is_rtl): markup = repo.get_markup() layout.set_markup(markup, -1) # work out max allowable layout width layout.set_width(-1) lw = self._layout_get_pixel_width(layout) max_layout_width = (cell_area.width - self.pixbuf_width - 3 * xpad) max_layout_width = cell_area.width - self.pixbuf_width - 3 * xpad if lw >= max_layout_width: layout.set_width((max_layout_width) * Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.MIDDLE) lw = max_layout_width self.title_width = cell_area.width - self.pixbuf_width - \ 10 * xpad self.title_height = Ems.EM if not is_rtl: x = cell_area.x + 2 * xpad + self.pixbuf_width else: x = cell_area.x + cell_area.width - lw - self.pixbuf_width - 2 * xpad y = cell_area.y + ypad Gtk.render_layout(context, cr, x, y, layout)
def redraw_rect(self, widget, cairo_ctx): style_ctx = widget.get_style_context() (w, h) = (widget.get_allocated_width(), widget.get_allocated_height()) xc = w // 2 yc = h // 2 radius = min(w, h) // 2 - 1 # text pango_ctx = widget.get_pango_context() layout = Pango.Layout(pango_ctx) layout.set_text(self.text, len(self.text)) (text_width, text_height) = layout.get_pixel_size() Gtk.render_layout(style_ctx, cairo_ctx, xc - text_width // 2, yc - text_height // 2, layout) cairo_ctx.new_path() # outer circle cairo_ctx.arc(xc, yc, radius - 1, 0, self.two_pi) cairo_ctx.set_line_width(1) cairo_ctx.stroke() # inner circle indicating current angle angle = self.get_current_angle() (ptr_xc, ptr_yc) = self.pointer_coords(radius - 2, angle) cairo_ctx.arc(int(xc + ptr_xc), int(yc + ptr_yc), T.ptr_radius, 0, self.two_pi) cairo_ctx.fill() cairo_ctx.stroke()
def render(self, context, cr, layout): if not self.visible: return x, y, width, height = self.allocation context.save() context.add_class("cellrenderer-button") if self.has_focus: context.set_state(self.state | Gtk.StateFlags.FOCUSED) else: context.set_state(self.state) # render background and focal frame if has-focus context.save() context.add_class(Gtk.STYLE_CLASS_BUTTON) Gtk.render_background(context, cr, x, y, width, height) context.restore() if self.has_focus: Gtk.render_focus(context, cr, x + 3, y + 3, width - 6, height - 6) # position and render layout markup context.save() context.add_class(Gtk.STYLE_CLASS_BUTTON) layout.set_markup(self.markup_variants[self.current_variant], -1) layout_width = layout.get_pixel_extents()[1].width x = x + (width - layout_width) / 2 y += self.ypad Gtk.render_layout(context, cr, x, y, layout) context.restore() context.restore()
def render(self, context, cr, layout): if not self.visible: return x, y, width, height = self.allocation context.save() context.add_class("cellrenderer-button") if self.has_focus: context.set_state(self.state | Gtk.StateFlags.FOCUSED) else: context.set_state(self.state) # render background and focal frame if has-focus context.save() context.add_class(Gtk.STYLE_CLASS_BUTTON) Gtk.render_background(context, cr, x, y, width, height) context.restore() if self.has_focus: Gtk.render_focus(context, cr, x+3, y+3, width-6, height-6) # position and render layout markup context.save() context.add_class(Gtk.STYLE_CLASS_BUTTON) layout.set_markup(self.markup_variants[self.current_variant], -1) layout_width = layout.get_pixel_extents()[1].width x = x + (width - layout_width)/2 y += self.ypad Gtk.render_layout(context, cr, x, y, layout) context.restore() context.restore() return
def _render_summary(self, context, cr, repo, cell_area, layout, xpad, ypad, is_rtl): markup = repo.get_markup() layout.set_markup(markup, -1) # work out max allowable layout width layout.set_width(-1) lw = self._layout_get_pixel_width(layout) max_layout_width = (cell_area.width - self.pixbuf_width - 3 * xpad) max_layout_width = cell_area.width - self.pixbuf_width - 3 * xpad if lw >= max_layout_width: layout.set_width((max_layout_width)*Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.MIDDLE) lw = max_layout_width self.title_width = cell_area.width - self.pixbuf_width - \ 10 * xpad self.title_height = Ems.EM if not is_rtl: x = cell_area.x+2*xpad+self.pixbuf_width else: x = cell_area.x+cell_area.width-lw-self.pixbuf_width-2*xpad y = cell_area.y + ypad Gtk.render_layout(context, cr, x, y, layout)
def _paint_bullet_point(self, cr, x, y): # draw the layout Gtk.render_layout( self.get_style_context(), cr, # state x, # x coord y, # y coord self._bullet._layout) # a Pango.Layout()
def on_draw(self, widget, cr, *args, **kwargs): cr.save() if self.is_animating(): # translate to the center, then set the rotation a = widget.get_allocation() cr.translate(a.width * 0.5, a.height * 0.5) cr.rotate(self.rotation) # pass on the translation details kwargs['xo'] = -(a.width * 0.5) kwargs['yo'] = -(a.height * 0.5) # do icon drawing SymbolicIcon.on_draw(self, widget, cr, *args, **kwargs) cr.restore() if not self.is_animating() or not self.transaction_count: return # paint transactions bubble # get the layout extents and calc the bubble size ex = self.layout.get_pixel_extents()[1] x = ((a.width - self.icon.get_width()) / 2 + self.icon.get_width() - ex.width + 2) y = ((a.height - self.icon.get_height()) / 2 + self.icon.get_height() - ex.height + 2) w = ex.width + 2 * self.BUBBLE_XPADDING h = ex.height + 2 * self.BUBBLE_YPADDING border_radius = w / 3 if border_radius > self.BUBBLE_MAX_BORDER_RADIUS: border_radius = self.BUBBLE_MAX_BORDER_RADIUS # paint background context = widget.get_style_context() context.save() color = context.get_background_color(Gtk.StateFlags.SELECTED) rounded_rect(cr, x + 1, y + 1, w - 2, h - 2, border_radius) Gdk.cairo_set_source_rgba(cr, color) cr.fill() context.restore() # paint outline rounded_rect(cr, x + 1.5, y + 1.5, w - 3, h - 3, border_radius - 1) cr.set_source_rgb(1, 1, 1) cr.set_line_width(1) cr.stroke() # paint layout cr.save() cr.translate(x + (w - ex.width) * 0.5, y + (h - ex.height) * 0.5) cr.move_to(0, 1) PangoCairo.layout_path(cr, self.layout) cr.set_source_rgba(0, 0, 0, 0.6) cr.fill() Gtk.render_layout(context, cr, 0, 0, self.layout) cr.restore()
def paint(self, cr, a, context, xo, yo): if self.is_nopaint: return cr.save() x, y = 0, 0 w, h = a.width, a.height arrow_width = 12#theme['arrow-width'] if isinstance(self, PathPart): _a = self.get_allocation() self.shape.layout(cr, _a.x-xo+1, _a.y-yo, w, h, 3, arrow_width) cr.clip() else: Gtk.render_background(context, cr, a.x-xo-10, a.y-yo, a.width+10, a.height) cr.translate(a.x-xo, a.y-yo) if self.shape.name.find('Arrow') != -1: # draw arrow head cr.move_to(w-arrow_width/2, 2) cr.line_to(w+5, h/2) cr.line_to(w-arrow_width/2, h-2) # fetch the line color and stroke rgba = context.get_border_color(Gtk.StateFlags.NORMAL) cr.set_source_rgb(rgba.red, rgba.green, rgba.blue) cr.set_line_width(1) cr.stroke() # render the layout e = self.layout.get_pixel_extents()[1] lw, lh = e.width, e.height pw, ph = a.width, a.height x = min(self.xpadding, (pw-lw)/2) y = (ph-lh)/2 # layout area Gtk.render_layout(context, cr, int(x), int(y), self.layout) # paint the focus frame if need be if isinstance(self, PathPart) and self.has_focus(): # layout area x, w, h = x-2, lw+4, lh+1 Gtk.render_focus(context, cr, x, y, w, h) cr.restore() return
def paint(self, cr, a, context, xo, yo): if self.is_nopaint: return cr.save() x, y = 0, 0 w, h = a.width, a.height arrow_width = 12 # theme['arrow-width'] if isinstance(self, PathPart): _a = self.get_allocation() self.shape.layout(cr, _a.x - xo + 1, _a.y - yo, w, h, 3, arrow_width) cr.clip() else: Gtk.render_background(context, cr, a.x - xo - 10, a.y - yo, a.width + 10, a.height) cr.translate(a.x - xo, a.y - yo) if self.shape.name.find('Arrow') != -1: # draw arrow head cr.move_to(w - arrow_width / 2, 2) cr.line_to(w + 5, h / 2) cr.line_to(w - arrow_width / 2, h - 2) # fetch the line color and stroke rgba = context.get_border_color(Gtk.StateFlags.NORMAL) cr.set_source_rgb(rgba.red, rgba.green, rgba.blue) cr.set_line_width(1) cr.stroke() # render the layout e = self.layout.get_pixel_extents()[1] lw, lh = e.width, e.height pw, ph = a.width, a.height x = min(self.xpadding, (pw - lw) / 2) y = (ph - lh) / 2 # layout area Gtk.render_layout(context, cr, int(x), int(y), self.layout) # paint the focus frame if need be if isinstance(self, PathPart) and self.has_focus(): # layout area x, w, h = x - 2, lw + 4, lh + 1 Gtk.render_focus(context, cr, x, y, w, h) cr.restore()
def redraw_rect(self, widget, cairo_ctx): style_ctx = widget.get_style_context() (w, h) = (widget.get_allocated_width(), widget.get_allocated_height()) Gtk.render_background(style_ctx, cairo_ctx, 0, 0, w - 1, h - 1) xc = w // 2 yc = h // 2 # Consider using gtk_render_arrow def triangle(points): cairo_ctx.move_to(*points[0]) cairo_ctx.line_to(*points[1]) cairo_ctx.line_to(*points[2]) cairo_ctx.line_to(*points[0]) cairo_ctx.fill() cairo_ctx.stroke() th = 8 tw = 6 # Triangle pointing left points = [(1, yc), (1 + th, yc - tw), (1 + th, yc + tw)] triangle(points) # pointing right points = [(w - 2, yc), (w - 2 - th, yc - tw), (w - 2 - th, yc + tw)] triangle(points) # pointing up points = [(xc, 1), (xc - tw, th), (xc + tw, th)] triangle(points) # pointing down points = [(xc, h - 2), (xc - tw, h - 2 - th), (xc + tw, h - 2 - th)] triangle(points) pango_ctx = widget.get_pango_context() layout = Pango.Layout(pango_ctx) try: drawtext = self.text except AttributeError: print("fourway has no text") return while True: layout.set_text(drawtext, len(drawtext)) (text_width, text_height) = layout.get_pixel_size() # truncate text if it's too long if text_width < (w - th * 2) or len(drawtext) < 3: break drawtext = drawtext[:-1] Gtk.render_layout(style_ctx, cairo_ctx, xc - text_width // 2, yc - text_height // 2, layout)
def do_render(self, cr, widget, bg_area, cell_area, flags): context = widget.get_style_context() context.save() context.add_class(Gtk.STYLE_CLASS_BUTTON) self.layout.set_markup("Install") (x, y, w, h) = self.do_get_size(widget, cell_area) h -= 4 # Gtk.render_background(context, cr, x, y, w, h) Gtk.render_frame(context, cr, x, y, w - 2, h + 4) Gtk.render_layout(context, cr, x + 10, y, self.layout) context.restore()
def _render_price(self, context, cr, app, layout, cell_area, xpad, ypad, is_rtl): layout.set_markup("%s" % self.model.get_display_price(app)) if is_rtl: x = cell_area.x + xpad else: x = (cell_area.x + cell_area.width - xpad - self._layout_get_pixel_width(layout)) Gtk.render_layout(context, cr, x, ypad + cell_area.y, layout)
def on_view_draw_after(self, view, cr): window = view.get_window(Gtk.TextWindowType.TOP) if window is None or not Gtk.cairo_should_draw_window(cr, window): return False if not self._in_mode: return False layout = view.create_pango_layout(_('Multi Edit Mode')) extents = layout.get_pixel_extents() w = window.get_width() h = window.get_height() Gtk.cairo_transform_to_window(cr, view, window) cr.save() cr.translate(0.5, 0.5) cr.set_line_width(1) col = self.get_border_color() Gdk.cairo_set_source_rgba(cr, col) cr.move_to(0, h - 1) cr.rel_line_to(w, 0) cr.stroke() cr.restore() ctx = self.view.get_style_context() ctx.save() ctx.add_class('top') cr.save() Gtk.render_layout(ctx, cr, w - extents[1].width - 3, (h - extents[1].height) / 2, layout) cr.restore() if not self._status: status = '' else: status = str(self._status) if status: layout.set_markup(status, -1) cr.save() Gtk.render_layout(ctx, cr, 3, (h - extents[1].height) / 2, layout) cr.restore() ctx.restore() return False
def do_render(self, cr, widget, bg_area, cell_area, flags): context = widget.get_style_context() context.save() context.add_class(Gtk.STYLE_CLASS_BUTTON) self.layout.set_markup("Install") (x, y, w, h) = self.do_get_size(widget, cell_area) h -= 4 # Gtk.render_background(context, cr, x, y, w, h) Gtk.render_frame(context, cr, x, y, w-2, h+4) Gtk.render_layout(context, cr, x + 10, y, self.layout) context.restore()
def _render_price(self, context, cr, app, layout, cell_area, xpad, ypad, is_rtl): layout.set_markup("US$ %s" % self.model.get_price(app), -1) if is_rtl: x = cell_area.x + xpad else: x = (cell_area.x + cell_area.width - xpad - self._layout_get_pixel_width(layout)) Gtk.render_layout(context, cr, x, ypad + cell_area.y, layout)
def calculate_positions(self, ctx, widget, x_base=0, y_base=0, width=0): '''calculate x,y coord of each element''' current_line = 1 #base coord x_coord = x_base y_coord = y_base context = widget.get_style_context() for w in self.update_markup(): #calculate remaining space in current line avariable_width = width - x_coord if isinstance(w, basestring): lines = w.split("\n") lines_count = len(lines) for i in range(0, lines_count): lbl = Gtk.Label() lbl.set_markup(lines[i]) layout = lbl.get_layout() lblwidth = lbl.get_preferred_width()[1] # only render if we have enought space # otherwise only do the calculation for coords if avariable_width > 0: # if can can't render the label entirely, elipside it. if avariable_width < lblwidth: layout.set_width(avariable_width * Pango.SCALE) layout.set_ellipsize(Pango.ELLIPSIZE_END) Gtk.render_layout(context, ctx, x_coord, y_coord, layout) #if we aren't in last line then update coords if lines_count > 1 and i != lines_count - 1: x_coord = x_base y_coord += self._lines_height[current_line] #avoid moving on last line, since we can have pixbuf in it current_line += i else: #update only x coord because we can have smileys in this line x_coord += lblwidth elif isinstance(w, GdkPixbuf.Pixbuf): #scale image to the text height size = min(self._lines_height[current_line], w.get_width()) pix = w.scale_simple(size, size, GdkPixbuf.InterpType.BILINEAR) # only render the image if it's totally into the visible area if avariable_width > size: Gtk.render_icon(context, ctx, pix, x_coord, y_coord) x_coord += pix.get_width() else: log.error("unhandled type %s" % type(i))
def _render_rating(self, context, cr, app, cell_area, layout, xpad, ypad, star_width, star_height, is_rtl): def _still_visible(): return self.model.visible(app.get_details().pkg) stats = app.get_review_stats( _still_visible_cb=_still_visible, cached=self._is_scrolling()) if not stats: return sr = self._stars if not is_rtl: x = (cell_area.x + 7 * xpad + self.pixbuf_width + self.apptitle_width) else: x = (cell_area.x + cell_area.width - 7*xpad - self.pixbuf_width - self.apptitle_width - star_width) star_size = self.STAR_SIZE y = cell_area.y + ypad + (self.apptitle_height - star_size)/2 sr.rating = stats.ratings_average sr.render_star(context, cr, x, y) # and nr-reviews in parenthesis to the right of the title nreviews_int = stats.downloads_total nreviews = stats.downloads_total_markup size = app.get_details().humansize if nreviews_int < 0: s = "..." else: s = nreviews layout.set_markup("<small>%s\n%s</small>" % (s, size), -1) y += ypad + self.STAR_SIZE context.save() context.add_class("cellrenderer-avgrating-label") Gtk.render_layout(context, cr, x, y, layout) context.restore() return
def _render_summary(self, context, cr, app, cell_area, layout, xpad, ypad, star_width, is_rtl): layout.set_markup(app.get_markup(), -1) # work out max allowable layout width layout.set_width(-1) lw = self._layout_get_pixel_width(layout) max_layout_width = (cell_area.width - self.pixbuf_width - 3*xpad - star_width) max_layout_width = cell_area.width - self.pixbuf_width - 3*xpad if self.show_ratings: max_layout_width -= star_width+6*xpad if self.props.isactive: if app.get_transaction_progress() > 0: action_btn = self.get_button_by_name(CellButtonIDs.ACTION) max_layout_width -= (xpad + action_btn.width) if lw >= max_layout_width: layout.set_width((max_layout_width)*Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.MIDDLE) lw = max_layout_width # HACK{lxnay}: apparently, using Layout directly screws its internal # structure and overwrites random areas of the heap causing # random f**k ups. # But fortunately, this code just positions the stars in the canvas self.apptitle_width = cell_area.width - self.pixbuf_width - \ 10 * xpad - star_width self.apptitle_height = self.STAR_SIZE # WHACKY CODE: #apptitle_extents = layout.get_line_readonly(0).get_pixel_extents()[1] #self.apptitle_width = apptitle_extents.width #self.apptitle_height = apptitle_extents.height if not is_rtl: x = cell_area.x+2*xpad+self.pixbuf_width else: x = cell_area.x+cell_area.width-lw-self.pixbuf_width-2*xpad y = cell_area.y + ypad Gtk.render_layout(context, cr, x, y, layout) return
def _render_category(self, context, cr, app, cell_area, layout, xpad, ypad, is_rtl): layout.set_markup('<b>%s</b>' % app.display_name, -1) # work out max allowable layout width lw = self._layout_get_pixel_width(layout) lh = self._layout_get_pixel_height(layout) if not is_rtl: x = cell_area.x else: x = cell_area.x + cell_area.width - lw y = cell_area.y + (cell_area.height - lh) / 2 Gtk.render_layout(context, cr, x, y, layout)
def __render_username(self, context, cr, cell_area, layout): username = self.get_property('username').decode('utf-8') y = cell_area.y x = cell_area.x + self.accum_header_width user = '******' % ( self.base.get_color_scheme('links'), username) layout.set_markup(user, -1) inkRect, logicalRect = layout.get_pixel_extents() self.accum_header_width += logicalRect.width + self.HEADER_PADDING self.total_height = 20 context.save() Gtk.render_layout(context, cr, x, y, layout) context.restore() return
def _on_text_view_draw(text_view, cairoc): """Calculate and show line lengths in text view margin.""" text_buffer = text_view.get_buffer() start, end = text_buffer.get_bounds() text = text_buffer.get_text(start, end, False) if not text: return lengths = get_lengths(text) layout = Pango.Layout(text_view.get_pango_context()) layout.set_markup("\n".join(str(x) for x in lengths), -1) layout.set_alignment(Pango.Alignment.RIGHT) width = layout.get_pixel_size()[0] text_view.set_border_window_size(Gtk.TextWindowType.RIGHT, width+6) x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.RIGHT, 2, 4) x += text_view.get_border_width() style = text_view.get_style_context() Gtk.render_layout(style, cairoc, x, y, layout)
def do_render(self, cr, widget, background_area, cell_area, flags): x_offset, y_offset, width, height = self.do_get_size(widget, cell_area) # Center the label y_offset = cell_area.height / 2 - height / 2 # Draws label context = widget.get_style_context() Gtk.render_layout(context, cr, cell_area.x + x_offset, cell_area.y + y_offset, self._label_layout) if not self._details_callback: return Gtk.render_line(context, cr, cell_area.x, cell_area.y, cell_area.x + cell_area.width, cell_area.y + cell_area.height - 1)
def _on_text_view_draw(text_view, cairoc): """Calculate and show line lengths in text view margin.""" text_buffer = text_view.get_buffer() start, end = text_buffer.get_bounds() text = text_buffer.get_text(start, end, False) if not text: return lengths = get_lengths(text) layout = Pango.Layout(text_view.get_pango_context()) layout.set_markup("\n".join(str(x) for x in lengths), -1) layout.set_alignment(Pango.Alignment.RIGHT) width = layout.get_pixel_size()[0] text_view.set_border_window_size(Gtk.TextWindowType.RIGHT, width + 6) x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.RIGHT, 2, 4) x += text_view.get_border_width() style = text_view.get_style_context() Gtk.render_layout(style, cairoc, x, y, layout)
def __render_message(self, context, cr, cell_area, layout): y = cell_area.y + self.total_height x = cell_area.x + self.MESSAGE_PADDING text = self.get_property('text').decode('utf-8') #escaped_text = GObject.markup_escape_text(text) pango_text = u'<span size="9000">%s</span>' % text pango_text = self.__highlight_elements(pango_text) layout.set_markup(pango_text, -1) inkRect, logicalRect = layout.get_pixel_extents() self.total_height += logicalRect.height + self.MESSAGE_PADDING context.save() Gtk.render_layout(context, cr, x, y, layout) context.restore() return
def __draw_part_rtl(self, cr, part, style, r, aw, shapes, sxO=0): x, y, w, h = part.get_allocation_tuple() shape = part.shape state = part.state icon_pb = part.icon.pixbuf cr.save() cr.translate(x+sxO, y) # draw bg self.__draw_part_bg(cr, part, w, h, state, shape, style,r, aw, shapes) # determine left margin. left margin depends on part shape # and whether there exists an icon or not if shape == self.SHAPE_MID_ARROW or shape == self.SHAPE_END_CAP: margin = self.theme.arrow_width + self.theme.xpadding else: margin = self.theme.xpadding # draw icon if icon_pb: margin += icon_pb.get_width() cr.set_source_pixbuf( icon_pb, w - margin + sxO, (h - icon_pb.get_height())/2) cr.paint() margin += self.spacing # if space is limited and an icon is set, dont draw label # otherwise, draw label if w == self.theme.min_part_width and icon_pb: pass else: layout = part.get_layout() lw, lh = layout.get_pixel_size() dst_x = x + part.get_width() - margin - lw + int(sxO) dst_y = (self.get_allocation().height - lh)/2+1 Gtk.render_layout(style, cr, dst_x, dst_y, layout) cr.restore() return
def redraw_rect(self, widget, cairo_ctx): style_ctx = widget.get_style_context() (w,h) = (widget.get_allocated_width(), widget.get_allocated_height()) xc = w//2 yc = h//2 radius = min(w,h)//2 - 1 # text pango_ctx = widget.get_pango_context() layout = Pango.Layout(pango_ctx) layout.set_text(self.text,len(self.text)) (text_width, text_height) = layout.get_pixel_size() Gtk.render_layout(style_ctx, cairo_ctx, xc - text_width//2, yc - text_height//2, layout) cairo_ctx.new_path() # outer circle cairo_ctx.arc( xc, yc, radius - 1, 0, self.two_pi) cairo_ctx.set_line_width(1) cairo_ctx.stroke() # inner circle indicating current angle angle = self.get_current_angle() (ptr_xc, ptr_yc) = self.pointer_coords(radius - 2, angle) cairo_ctx.arc( int(xc + ptr_xc), int(yc + ptr_yc), T.ptr_radius, 0, self.two_pi) cairo_ctx.fill() cairo_ctx.stroke()
def do_render(self, cr, widget, background_area, cell_area, flags): if not self.visible: return if not self.sensitive: state = Gtk.StateFlags.INSENSITIVE else: state = Gtk.StateFlags.NORMAL context = widget.get_style_context() context.save() context.add_class('text-button') context.set_state(state) xpad, ypad = self.get_padding() x = cell_area.x + xpad y = cell_area.y + ypad w = cell_area.width - 2 * xpad h = cell_area.height - 2 * ypad Gtk.render_background(context, cr, x, y, w, h) Gtk.render_frame(context, cr, x, y, w, h) padding = context.get_padding(state) layout = widget.create_pango_layout(self.text) layout.set_width((w - padding.left - padding.right) * Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.END) layout.set_wrap(Pango.WrapMode.CHAR) lw, lh = layout.get_size() # Can not use get_pixel_extents lw /= Pango.SCALE lh /= Pango.SCALE if w < lw: x = x + padding.left else: x = x + padding.left + 0.5 * (w - padding.left - padding.right - lw) y = y + padding.top + 0.5 * (h - padding.top - padding.bottom - lh) Gtk.render_layout(context, cr, x, y, layout) context.restore()
def _render_summary(self, context, cr, app, cell_area, layout, xpad, ypad, star_width, is_rtl): layout.set_markup(self.model.get_markup(app), -1) # work out max allowable layout width layout.set_width(-1) lw = self._layout_get_pixel_width(layout) max_layout_width = (cell_area.width - self.pixbuf_width - 3 * xpad - star_width) max_layout_width = cell_area.width - self.pixbuf_width - 3 * xpad stats = self.model.get_review_stats(app) if self.show_ratings and stats: max_layout_width -= star_width + 6 * xpad if (self.props.isactive and self.model.get_transaction_progress(app) > 0): action_btn = self.get_button_by_name(CellButtonIDs.ACTION) max_layout_width -= (xpad + action_btn.width) if lw >= max_layout_width: layout.set_width((max_layout_width) * Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.MIDDLE) lw = max_layout_width apptitle_extents = layout.get_line_readonly(0).get_pixel_extents()[1] self.apptitle_width = apptitle_extents.width self.apptitle_height = apptitle_extents.height if not is_rtl: x = cell_area.x + 2 * xpad + self.pixbuf_width else: x = (cell_area.x + cell_area.width - lw - self.pixbuf_width - 2 * xpad) y = cell_area.y + ypad Gtk.render_layout(context, cr, x, y, layout)
def __render_reposted_by(self, context, cr, cell_area, layout): reposted_by = self.get_property('reposted_by') if not reposted_by: return y = cell_area.y + self.total_height x = cell_area.x + self.MESSAGE_PADDING reposted_by = reposted_by.decode('utf-8') pango_text = u'<span size="7000" foreground="#999">%s %s</span>' % ( i18n.get('retweeted_by'), reposted_by) layout.set_markup(pango_text, -1) inkRect, logicalRect = layout.get_pixel_extents() self.total_height += logicalRect.height + self.FOOTER_PADDING context.save() Gtk.render_layout(context, cr, x, y, layout) context.restore() return
def _on_text_view_draw(text_view, cairoc): """Calculate and show line lengths in text view margin.""" text_buffer = text_view.get_buffer() start, end = text_buffer.get_bounds() text = text_buffer.get_text(start, end, False) if not text: return lengths = get_lengths(text) layout = Pango.Layout(text_view.get_pango_context()) # XXX: Lines overlap if we don't set a spacing!? layout.set_spacing(2 * Pango.SCALE) layout.set_markup("\n".join(str(x) for x in lengths), -1) layout.set_alignment(Pango.Alignment.RIGHT) width = layout.get_pixel_size()[0] text_view.set_border_window_size(Gtk.TextWindowType.RIGHT, width + 6) x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.RIGHT, 2, 4) x += text_view.get_border_width() with aeidon.util.silent(AttributeError): # Top margin available since GTK 3.18. y += text_view.props.top_margin style = text_view.get_style_context() Gtk.render_layout(style, cairoc, x, y, layout)
def _on_text_view_draw(text_view, cairoc): """Calculate and show line lengths in text view margin.""" text_buffer = text_view.get_buffer() start, end = text_buffer.get_bounds() text = text_buffer.get_text(start, end, False) if not text: return lengths = get_lengths(text) layout = Pango.Layout(text_view.get_pango_context()) # XXX: Lines overlap if we don't set a spacing!? layout.set_spacing(2*Pango.SCALE) layout.set_markup("\n".join(str(x) for x in lengths), -1) layout.set_alignment(Pango.Alignment.RIGHT) width = layout.get_pixel_size()[0] text_view.set_border_window_size(Gtk.TextWindowType.RIGHT, width+6) x, y = text_view.window_to_buffer_coords(Gtk.TextWindowType.RIGHT, 2, 4) x += text_view.get_border_width() with aeidon.util.silent(AttributeError): # Top margin available since GTK+ 3.18. y += text_view.props.top_margin style = text_view.get_style_context() Gtk.render_layout(style, cairoc, x, y, layout)
def _render_rating(self, context, cr, app, cell_area, layout, xpad, ypad, star_width, star_height, is_rtl): stats = self.model.get_review_stats(app) if not stats: return sr = self._stars if not is_rtl: x = cell_area.x+3*xpad+self.pixbuf_width+self.apptitle_width else: x = (cell_area.x + cell_area.width - 3*xpad - self.pixbuf_width - self.apptitle_width - star_width) y = cell_area.y + ypad + (self.apptitle_height-self.STAR_SIZE)/2 sr.rating = stats.ratings_average sr.render_star(context, cr, x, y) # and nr-reviews in parenthesis to the right of the title nreviews = stats.ratings_total s = "(%i)" % nreviews layout.set_markup("<small>%s</small>" % s, -1) lw = self._layout_get_pixel_width(layout) w = star_width if not is_rtl: x += xpad+w else: x -= xpad+lw context.save() context.add_class("cellrenderer-avgrating-label") Gtk.render_layout(context, cr, x, y, layout) context.restore() return
def _render_summary(self, context, cr, app, cell_area, layout, xpad, ypad, star_width, is_rtl): layout.set_markup(self.model.get_markup(app), -1) # work out max allowable layout width layout.set_width(-1) lw = self._layout_get_pixel_width(layout) max_layout_width = (cell_area.width - self.pixbuf_width - 3 * xpad - star_width) max_layout_width = cell_area.width - self.pixbuf_width - 3 * xpad stats = self.model.get_review_stats(app) if self.show_ratings and stats: max_layout_width -= star_width + 6 * xpad if (self.props.isactive and self.model.get_transaction_progress(app) > 0): action_btn = self.get_button_by_name(CellButtonIDs.ACTION) max_layout_width -= (xpad + action_btn.width) if lw >= max_layout_width: layout.set_width((max_layout_width) * Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.END) lw = max_layout_width apptitle_extents = layout.get_line_readonly(0).get_pixel_extents()[1] self.apptitle_width = apptitle_extents.width self.apptitle_height = apptitle_extents.height if not is_rtl: x = cell_area.x + 2 * xpad + self.pixbuf_width else: x = (cell_area.x + cell_area.width - lw - self.pixbuf_width - 2 * xpad) y = cell_area.y + ypad Gtk.render_layout(context, cr, x, y, layout)
def do_draw(self, cr): style = self.get_style_context() r, g, b, a = style.get_color(style.get_state()) cr.set_source_rgba(r, g, b, a) pango = self.get_pango_context() metrics = pango.get_metrics() ratio = metrics.get_ascent() / (metrics.get_ascent() + metrics.get_descent()) fontsize = (metrics.get_ascent() + metrics.get_descent()) / 1024 self.set_size_request(40, fontsize) w, h = self.get_allocated_width(), self.get_allocated_height() Gtk.render_background(style, cr, 0, 0, w, h - 1) cr.translate(0, -metrics.get_descent() / 1024 * ratio) font = pango.get_font_description().copy() font.set_size(h * 1024 * ratio) lay = self.create_pango_layout() lay.set_text(self.prefix + "012K") Gtk.render_layout(style, cr, 0, 0, lay)
def calculate_positions(self, ctx, widget, x_base=0, y_base=0): '''calculate x,y coord of each element''' current_line = 1 lines_height = self.calculate_lines_height() #base coord x_coord = x_base y_coord = y_base context = widget.get_style_context() for w in self.update_markup(): if isinstance(w, basestring): lines = w.split("\n") lines_count = len(lines) for i in range(0, lines_count): lbl = Gtk.Label() lbl.set_markup(lines[i]) layout = lbl.get_layout() Gtk.render_layout(context, ctx, x_coord, y_coord, layout) #if we aren't in last line then update coords if lines_count > 1 and i != lines_count - 1: x_coord = x_base y_coord += lines_height[current_line] #avoid moving on last line, since we can have pixbuf in it current_line += i else: #update only x coord because we can have smileys in this line x_coord += lbl.get_preferred_width()[1] elif isinstance(w, GdkPixbuf.Pixbuf): #scale image to the text height size = min(lines_height[current_line], w.get_width()) pix = w.scale_simple(size, size, GdkPixbuf.InterpType.BILINEAR) Gtk.render_icon(context, ctx, pix, x_coord, y_coord) x_coord += pix.get_width() else: log.error("unhandled type %s" % type(i))
def calculate_positions(self, ctx, widget, x_base=0, y_base=0): '''calculate x,y coord of each element''' current_line = 1 #base coord x_coord = x_base y_coord = y_base context = widget.get_style_context() for w in self.update_markup(): if isinstance(w, basestring): lines = w.split("\n") lines_count = len(lines) for i in range(0, lines_count): lbl = Gtk.Label() lbl.set_markup(lines[i]) layout = lbl.get_layout() Gtk.render_layout(context, ctx, x_coord, y_coord, layout) #if we aren't in last line then update coords if lines_count > 1 and i != lines_count - 1: x_coord = x_base y_coord += self._lines_height[current_line] #avoid moving on last line, since we can have pixbuf in it current_line += i else: #update only x coord because we can have smileys in this line x_coord += lbl.get_preferred_width()[1] elif isinstance(w, GdkPixbuf.Pixbuf): #scale image to the text height size = min(self._lines_height[current_line], w.get_width()) pix = w.scale_simple(size, size, GdkPixbuf.InterpType.BILINEAR) Gtk.render_icon(context, ctx, pix, x_coord, y_coord) x_coord += pix.get_width() else: log.error("unhandled type %s" % type(i))
def _render_rating(self, context, cr, app, cell_area, layout, xpad, ypad, star_width, star_height, is_rtl): stats = self.model.get_review_stats(app) if not stats: return sr = self._stars if not is_rtl: x = (cell_area.x + 3 * xpad + self.pixbuf_width + self.apptitle_width) else: x = (cell_area.x + cell_area.width - 3 * xpad - self.pixbuf_width - self.apptitle_width - star_width) y = cell_area.y + ypad + (self.apptitle_height - self.STAR_SIZE) / 2 sr.rating = stats.ratings_average sr.render_star(context, cr, x, y) # and nr-reviews in parenthesis to the right of the title nreviews = stats.ratings_total s = "(%i)" % nreviews layout.set_markup("<small>%s</small>" % s, -1) if not is_rtl: x += xpad + star_width else: x -= xpad + self._layout_get_pixel_width(layout) context.save() context.add_class("cellrenderer-avgrating-label") Gtk.render_layout(context, cr, x, y, layout) context.restore()
def on_draw(self, widget, cr, layout): a = widget.get_allocation() # paint the current animation frame x = (a.width - self.h_stride) * 0.5 y = (a.height - self.v_stride) * 0.5 Gdk.cairo_set_source_pixbuf(cr, self.frame, x, y) cr.paint() if self.transaction_count <= 0: return # paint a bubble with the transaction count layout.set_markup('<small>%i</small>' % self.transaction_count, -1) # determine bubble size extents = layout.get_pixel_extents()[1] width = extents.width + (2 * self.BUBBLE_XPADDING) height = extents.height + (2 * self.BUBBLE_YPADDING) # now render the bubble and layout context = self.get_style_context() x += self.h_stride + self.BUBBLE_XPADDING y += (self.v_stride - height) / 2 rounded_rect(cr, x, y, width, height, self.BUBBLE_BORDER_RADIUS) cr.set_source_rgba(0, 0, 0, 0.2) cr.fill() Gtk.render_layout(context, cr, x + self.BUBBLE_XPADDING, y + self.BUBBLE_YPADDING, layout) return
def __render_datetime(self, context, cr, cell_area, layout): #datetime = self.get_property('datetime').decode('utf-8') # Ported to base datetime = self.base.humanize_timestamp(self.get_property('timestamp')) in_reply_to_user = self.get_property('in_reply_to_user') y = cell_area.y + self.total_height x = cell_area.x + self.MESSAGE_PADDING if in_reply_to_user: pango_text = u'<span size="7000" foreground="#999">%s %s %s</span>' % ( datetime, i18n.get('in_reply_to'), in_reply_to_user) else: pango_text = u'<span size="7000" foreground="#999">%s</span>' % datetime layout.set_markup(pango_text, -1) inkRect, logicalRect = layout.get_pixel_extents() self.total_height += logicalRect.height + self.FOOTER_PADDING context.save() Gtk.render_layout(context, cr, x, y, layout) context.restore() return
def do_render(self, cr, widget, background_area, cell_area, flags): if not self.visible: return button_width = self.button_width() state = self.get_state(widget, flags) context = widget.get_style_context() context.save() context.add_class('button') xpad, ypad = self.get_padding() x = cell_area.x + xpad y = cell_area.y + ypad w = cell_area.width - 2 * xpad h = cell_area.height - 2 * ypad padding = context.get_padding(state) layout = widget.create_pango_layout(self.size) lwidth = w - button_width - padding.left - padding.right if lwidth < 0: lwidth = 0 layout.set_width(lwidth * Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.END) layout.set_wrap(Pango.WrapMode.CHAR) layout.set_alignment(Pango.Alignment.RIGHT) if lwidth > 0: lw, lh = layout.get_size() # Can not use get_pixel_extents lw /= Pango.SCALE lh /= Pango.SCALE lx = x + padding.left if self.buttons and self.buttons[0] == 'open': pxbf_width = self.images['open'][2] lx += pxbf_width + 2 * BUTTON_BORDER + BUTTON_SPACING ly = y + padding.top + 0.5 * ( h - padding.top - padding.bottom - lh) Gtk.render_layout(context, cr, lx, ly, layout) for index, button_name in enumerate(self.buttons): pxbf_sens, pxbf_insens, pxbf_width, pxbf_height = \ self.images[button_name] if (not self.editable and button_name in {'select', 'clear'} or not self.size and button_name in {'open', 'save'}): pixbuf = pxbf_insens else: pixbuf = pxbf_sens if index == 0 and button_name == 'open': x_offset = 0 else: x_offset = (w - button_width + (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING) * index) if x_offset < 0: continue bx = cell_area.x + x_offset by = cell_area.y bw = pxbf_width + (2 * BUTTON_BORDER) Gtk.render_background(context, cr, bx, by, bw, h) Gtk.render_frame(context, cr, bx, by, bw, h) Gdk.cairo_set_source_pixbuf( cr, pixbuf, bx + BUTTON_BORDER, by + (h - pxbf_height) / 2) cr.paint() context.restore()
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 do_render(self, cr, widget, background_area, cell_area, flags): context = widget.get_style_context() context.save() context.add_class("clocks-digital-renderer") context.add_class(self.css_class) cr.save() Gdk.cairo_rectangle(cr, cell_area) cr.clip() # draw background if self.props.pixbuf: Gtk.CellRendererPixbuf.do_render(self, cr, widget, background_area, cell_area, flags) else: Gtk.render_frame(context, cr, cell_area.x, cell_area.y, cell_area.width, cell_area.height) Gtk.render_background(context, cr, cell_area.x, cell_area.y, cell_area.width, cell_area.height) cr.translate(cell_area.x, cell_area.y) # for now the space around the digital clock is hardcoded and # relative to the image width (not the width of the cell which # may be larger in case of long city names). # We need to know the width to create the pango layouts if self.props.pixbuf: pixbuf_margin = (cell_area.width - self.props.pixbuf.get_width()) // 2 else: pixbuf_margin = 0 margin = 12 + pixbuf_margin padding = 12 w = cell_area.width - 2 * margin # create the layouts so that we can measure them layout = widget.create_pango_layout("") layout.set_markup( "<span size='xx-large'><b>%s</b></span>" % self.text, -1) layout.set_width(w * Pango.SCALE) layout.set_alignment(Pango.Alignment.CENTER) text_w, text_h = layout.get_pixel_size() if self.subtext: layout_subtext = widget.create_pango_layout("") layout_subtext.set_markup( "<span size='medium'>%s</span>" % self.subtext, -1) layout_subtext.set_width(w * Pango.SCALE) layout_subtext.set_alignment(Pango.Alignment.CENTER) subtext_w, subtext_h = layout_subtext.get_pixel_size() subtext_pad = 6 # We just assume the first line is the longest line = layout_subtext.get_line(0) ink_rect, log_rect = line.get_pixel_extents() subtext_w = log_rect.width else: subtext_w, subtext_h, subtext_pad = 0, 0, 0 # measure the actual height and coordinates (xpad is ignored for now) h = 2 * padding + text_h + subtext_h + subtext_pad x = margin y = (cell_area.height - h) / 2 context.add_class("inner") # draw inner rectangle background Gtk.render_frame(context, cr, x, y, w, h) Gtk.render_background(context, cr, x, y, w, h) # draw text Gtk.render_layout(context, cr, x, y + padding, layout) if self.subtext: Gtk.render_layout(context, cr, x, y + padding + text_h + subtext_pad, layout_subtext) context.restore() # draw the overlayed checkbox if self.toggle_visible: context.save() context.add_class(Gtk.STYLE_CLASS_CHECK) xpad, ypad = self.get_padding() direction = widget.get_direction() if direction == Gtk.TextDirection.RTL: x_offset = xpad else: x_offset = cell_area.width - self.icon_size - xpad check_x = x_offset check_y = cell_area.height - self.icon_size - ypad if self.active: context.set_state(Gtk.StateFlags.ACTIVE) Gtk.render_check(context, cr, check_x, check_y, self.icon_size, self.icon_size) context.restore() cr.restore()
def create_multi_row_drag_icon(self, paths, max_rows): if not paths: return if len(paths) == 1: return self.oTreeviev.create_row_drag_icon(paths[0]) # create_row_drag_icon can return None icons = [self.oTreeviev.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 # Gives (x, y, width, height) for a pixbuf or a surface, scale independent sizes = [] for oIcon in icons: if isinstance(oIcon, GdkPixbuf.Pixbuf): sizes.append((0, 0, oIcon.get_width(), oIcon.get_height())) else: ctx = cairo.Context(oIcon) x1, y1, x2, y2 = ctx.clip_extents() x1 = int(math.floor(x1)) y1 = int(math.floor(y1)) x2 = int(math.ceil(x2)) y2 = int(math.ceil(y2)) x2 -= x1 y2 -= y1 sizes.append((x1, y1, x2, y2)) #~Gives (x, y, width, height) for a pixbuf or a surface, scale independent 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 = _('and {rowcount} more').format(rowcount = len(paths) - max_rows) more = "<b><i>%s</i></b>" % more layout = self.oTreeviev.create_pango_layout("") layout.set_markup(more) layout.set_alignment(Pango.Alignment.LEFT) 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.oTreeviev.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 redraw_rect(self, widget, cairo_ctx): style_ctx = widget.get_style_context() (w,h) = (widget.get_allocated_width(), widget.get_allocated_height()) Gtk.render_background(style_ctx, cairo_ctx, 0, 0, w-1, h-1) xc = w//2 yc = h//2 # Consider using gtk_render_arrow def triangle(points): cairo_ctx.move_to(*points[0]) cairo_ctx.line_to(*points[1]) cairo_ctx.line_to(*points[2]) cairo_ctx.line_to(*points[0]) cairo_ctx.fill() cairo_ctx.stroke() th = 8 tw = 6 # Triangle pointing left points = [ (1, yc), (1+th, yc-tw), (1+th, yc+tw)] triangle(points) # pointing right points = [ (w-2, yc), (w-2-th, yc-tw), (w-2-th, yc+tw)] triangle(points) # pointing up points = [ (xc, 1), (xc-tw, th), (xc+tw, th)] triangle(points) # pointing down points = [ (xc, h-2), (xc-tw, h-2-th), (xc+tw, h-2-th)] triangle(points) pango_ctx = widget.get_pango_context() layout = Pango.Layout(pango_ctx) try: drawtext = self.text except AttributeError: print("fourway has no text") return while True: layout.set_text(drawtext, len(drawtext)) (text_width, text_height) = layout.get_pixel_size() # truncate text if it's too long if text_width < (w-th*2) or len(drawtext) < 3: break drawtext = drawtext[:-1] Gtk.render_layout( style_ctx, cairo_ctx, xc - text_width//2, yc - text_height//2, layout)