def create_editor_item(self): main = gtk.VBox(False, 0) main.set_spacing(6) label = gtk.Label() label.set_alignment(0, 0) label.set_markup(u"<b>Colors</b>") main.pack_start(label, False, False, 6) colors_combo = gtk.combo_box_new_text() colors_combo.connect("changed", self.on_colors_combo_changed) colors_combo.append_text("") for key, value in COLORS: colors_combo.append_text(value.title) colors_combo.set_active(0) color_table = gtk.Table(5, 2) color_table.set_col_spacings(6) main.pack_start(color_table, False, False, 0) for i, (code, label, button) in enumerate(_COLOR_BUTTONS): color = gtk.gdk.Color(*read_pref_color(code, False)) setattr(self, button, gtk.ColorButton()) getattr(self, button).set_color(color) getattr(self, button).connect("color-set" , lambda button: self.refresh_color_preferences()) align = gtk.Alignment(0, 0.5) align.set_padding(0, 0, 12, 0) align.add(gtk.Label(label)) color_table.attach(align, 0, 1, i, i + 1, gtk.FILL, gtk.FILL) color_table.attach(getattr(self, button), 1, 2, i, i + 1, 0, 0) align = gtk.Alignment(0, 0.5) align.set_padding(0, 0, 12, 0) align.add(gtk.Label(u"Load color scheme:")) scheme_hbox = gtk.HBox(False, 0) scheme_hbox.pack_start(align, False, False, 0) align = gtk.Alignment(0, 0.5) align.set_padding(0, 0, 12, 0) align.add(colors_combo) scheme_hbox.pack_start(align, True, True, 0) main.pack_start(scheme_hbox, False, False, 0) label = gtk.Label() label.set_alignment(0, 0) label.set_markup(u"<b>Arrow keys</b>") main.pack_start(label, False, False, 6) def callback(widget): prefs[constants.PREF_ARROWS_CHANGE_DIR] = widget.get_active() arrows_button = gtk.CheckButton(u"Right / down arrow keys change typing direction") arrows_button.set_active(prefs[constants.PREF_ARROWS_CHANGE_DIR]) arrows_button.connect("toggled", callback) align = gtk.Alignment(0, 0.5) align.set_padding(0, 0, 12, 0) align.add(arrows_button) main.pack_start(align, False, False, 0) return main
def _render_cells(puzzle, cells, e_settings, drawing_area, editor=True): if not cells or not e_settings.surface: return view = puzzle.view view.select_mode(constants.VIEW_MODE_EDITOR) context = cairo.Context(e_settings.surface) width, height = puzzle.grid.size cs = [(x, y) for x, y in cells if 0 <= x < width and 0 <= y < height] view.render_bottom(context, cs) if editor: e_cells = compute_editor_of_cell(cs, puzzle, e_settings) render = [] for x, y, code in e_cells: r, g, b = read_pref_color(code) render.append((x, y, r, g, b)) view.render_locations(context, render) view.render_top(context, cs) context = drawing_area.window.cairo_create() context.set_source(e_settings.pattern) context.paint()
def render_top(self, context, cells): grid = self.grid data = grid.data props = self.properties settings = self.settings if settings["has_padding"]: context.translate(*props.margin) cur_color = None default = props._data default_char_font = default["char", "font"] default_char_size = default["char", "size"] default_char_color = default["char", "color"] default_block_color = default["block", "color"] default_block_margin = default["block", "margin"] default_number_color = default["number", "color"] default_number_font = default["number", "font"] default_number_size = default["number", "size"] default_circle = default["circle"] styles = props.styles screen_xs, screen_ys = self.comp_screen() pcr = pangocairo.CairoContext(context) pcr_layout = pcr.create_layout() pcr_set_markup = pcr_layout.set_markup pcr_show_layout = pcr.show_layout ctx_move_to = context.move_to ctx_text_extents = context.text_extents ctx_set_source_rgb = context.set_source_rgb ctx_set_line_width = context.set_line_width ctx_rel_line_to = context.rel_line_to ctx_stroke = context.stroke ctx_rectangle = context.rectangle def _render_pango(r, s, font, content, rx=None, ry=None): if rx is None and ry is None: rx = screen_xs[r] + 1 # ? ry = screen_ys[s] pcr_set_markup('''<span font_desc="%s">%s</span>''' % (font, content)) ctx_move_to(rx, ry) pcr_show_layout(pcr_layout) def _render_char(r, s, c, extents): xbearing, ybearing, width, height = extents[c][:4] border_width = props["border", "width"] size = props["cell", "size"] line_width = props["line", "width"] char_font = default_char_font char_size = default_char_size if (r, s) in styles: style = styles[r, s] char_font = style["char", "font"] char_size = style["char", "size"] context.select_font_face(char_font, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) context.set_font_size(char_size[1]) fascent, fdescent, fheight = context.font_extents()[:3] cx = border_width + r * (size + line_width) + 0.5 * size cy = border_width + s * (size + line_width) + 0.5 * size rx = cx - xbearing - width / 2 ry = cy - fdescent + fheight / 2 context.move_to(rx, ry) context.show_text(c) # chars and overlay chars n_chars, o_chars = [], [] if settings["show_chars"]: n_chars = [(p, q, data[q][p]["char"]) for p, q in cells if data[q][p]["char"] != ''] if settings["render_overlays"]: o_chars = [(p, q, c) for p, q in cells for r, s, c in self.overlay if (p, q) == (r, s)] extents = {} for p, q, c in (n_chars + o_chars): if c not in extents: extents[c] = ctx_text_extents(c) for p, q, c in n_chars: color = styles[p, q]["char", "color"] if (p, q) in styles else default_char_color if color != cur_color: cur_color = color ctx_set_source_rgb(*[cc / 65535.0 for cc in color]) _render_char(p, q, c, extents) for p, q, c in o_chars: # TODO custom color color = (65535.0 / 2, 65535.0 / 2, 65535.0 / 2) if color != cur_color: cur_color = color ctx_set_source_rgb(*[cc / 65535.0 for cc in color]) _render_char(p, q, c, extents) cell_size = props["cell", "size"] line_width = props["line", "width"] # highlights highlights = self.highlights if highlights: hwidth = int(cell_size / 8) ctx_set_line_width(hwidth) color = read_pref_color(constants.COLOR_HIGHLIGHT, False) if color != cur_color: cur_color = color ctx_set_source_rgb(*[c / 65535.0 for c in color]) for p, q in cells: for r, s, direction, length in highlights: top, bottom, left, right = None, None, None, None if direction == "across" and r <= p < r + length and s == q: top = bottom = True right = p == (r + length - 1) left = p == r elif direction == "down" and s <= q < s + length and r == p: left = right = True top = q == s bottom = q == (s + length - 1) sx = screen_xs[p] sy = screen_ys[q] lines = [] if top: lines.append((sx, sy + 0.5 * hwidth, cell_size, 0)) if bottom: lines.append((sx, sy + cell_size - 0.5 * hwidth, cell_size, 0)) if left: lines.append((sx + 0.5 * hwidth, sy, 0, cell_size)) if right: lines.append((sx + cell_size - 0.5 * hwidth, sy, 0, cell_size)) for rx, ry, rdx, rdy in lines: ctx_move_to(rx, ry) ctx_rel_line_to(rdx, rdy) ctx_stroke() ctx_set_line_width(line_width) # block for p, q in cells: color = styles[p, q]["block", "color"] if (p, q) in styles else default_block_color if color != cur_color: cur_color = color ctx_set_source_rgb(*[c / 65535.0 for c in color]) if data[q][p]["block"]: rx = screen_xs[p] ry = screen_ys[q] rsize = cell_size margin = styles[p, q]["block", "margin"] if (p, q) in styles else default_block_margin if margin == 0: # -0.5 for coordinates and +1 for size # are needed to render seamlessly in PDF ctx_rectangle(rx - 0.5, ry - 0.5, rsize + 1, rsize + 1) else: offset = int((margin / 100.0) * rsize) rsize -= (2 * offset) ctx_rectangle(rx + offset, ry + offset, rsize, rsize) context.fill() # number if settings["show_numbers"]: numbers = [(p, q) for p, q in cells if data[q][p]["number"] > 0] for p, q in numbers: if (p, q) in styles: style = styles[p, q] color = style["number", "color"] font = style["number", "font"] + " " + str(style["number", "size"][1]) + "px" else: color = default_number_color font = default_number_font + " " + str(default_number_size[1]) + "px" if color != cur_color: cur_color = color ctx_set_source_rgb(*[c / 65535.0 for c in color]) _render_pango(p, q, font, str(data[q][p]["number"])) # circle for p, q in cells: if (p, q) in styles: has_circle = styles[p, q]["circle"] else: has_circle = default_circle if has_circle: if (p, q) in styles: color = styles[p, q]["block", "color"] else: color = default_block_color if color != cur_color: cur_color = color ctx_set_source_rgb(*[c / 65535.0 for c in color]) ctx_set_line_width(line_width) rsize = cell_size rx = screen_xs[p] + rsize / 2 ry = screen_ys[q] + rsize / 2 context.new_sub_path() context.arc(rx, ry, rsize / 2, 0, 2 * math.pi) context.stroke() # lines if len(cells) < grid.width * grid.height: cls = [c for c in cells] for x, y in cells: cls += grid.neighbors(x, y, diagonals=True) self.render_lines_of_cells(context, set(cls), screen_xs, screen_ys) else: self.render_lines_of_cells(context, cells, screen_xs, screen_ys) if settings["has_padding"]: mx, my = props.margin context.translate(-1 * mx, -1 * my)