diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2013-08-16 20:59:14 (GMT) |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2013-08-16 20:59:14 (GMT) |
commit | 76ab880620fb36e3860360f60cd11ad45d04474d (patch) | |
tree | 2de4c33c10a64b32f5bcf3595bb64c9c57a74ea4 /PascalTriangle.activity/pascaltriangle.py | |
parent | ccf35761bca15c7f3524f3c38de820c9a05b9ec7 (diff) |
Improve rendering of cells
Render them as hexagons rather than rectangles.
Diffstat (limited to 'PascalTriangle.activity/pascaltriangle.py')
-rwxr-xr-x | PascalTriangle.activity/pascaltriangle.py | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/PascalTriangle.activity/pascaltriangle.py b/PascalTriangle.activity/pascaltriangle.py index 2acd364..6fd6f45 100755 --- a/PascalTriangle.activity/pascaltriangle.py +++ b/PascalTriangle.activity/pascaltriangle.py @@ -2,6 +2,7 @@ from sugar3.activity import activity from sugar3.graphics.toolbarbox import ToolbarBox import math from gi.repository import Gtk +import cairo class PascalTriangleActivity(activity.Activity): def __init__(self, handle): @@ -51,43 +52,71 @@ class PascalTriangleActivity(activity.Activity): # Default sizes (Cairo units). padding = 10.0 - # Widget allocation. + # Widget allocation and sizes. The cell_height is calculated weirdly + # because the cells interlock as they tesselate; so for 2 rows, the + # bottom third of the top row overlaps with the top third of the bottom + # row. widget_height = widget.get_allocated_height() base_width = widget.get_allocated_width() - 2.0 * padding triangle_height = widget_height - 2.0 * padding cell_width = base_width / self.triangle_size - cell_height = triangle_height / self.triangle_size + cell_height = 3.0 * (triangle_height / (2 * self.triangle_size + 1)) # Draw the triangle rows from the top down. The row_order is the number # of cells in the row (increasing from 1 to triangle_size, inclusive). row_order = 1 # X position of the first cell on the row - cell_start_x = padding + base_width / 2.0 - cell_width / 2.0 + cell_start_x = padding + base_width / 2.0 for row_index in range(self.triangle_size): for column_index in range(row_order): # Calculate the cell position. Add an offset every odd row so - # the triangle is balanced. + # the triangle is balanced. Each row is only 2/3 of cell_height + # because the hexagons interlock as they tesselate. cell_x = cell_start_x + cell_width * column_index - cell_y = padding + cell_height * row_index - - # Draw the cell and fill it. - ctx.rectangle(cell_x, cell_y, cell_width, cell_height) - ctx.set_source_rgb(0.0, 0.0, 0.0) - ctx.stroke_preserve() - ctx.set_source_rgb(1.0, 1.0, 1.0) - ctx.fill() - - # Write its number. - cell_number = self._calculate_pascal_number(row_index, - column_index) - extents = ctx.text_extents(str(cell_number)) - ctx.move_to(cell_x + (cell_width - extents[2]) / 2.0, - cell_y + (cell_height - extents[3]) / 2.0) - ctx.set_source_rgb(0.0, 0.0, 0.0) - ctx.show_text(str(cell_number)) + cell_y = padding + cell_height / 2.0 + \ + (cell_height * row_index * (2.0 / 3.0)) + + # Move to the cell position and draw the cell. + ctx.move_to(cell_x, cell_y) + self._draw_cell(ctx, + row_index, column_index, + cell_width, cell_height) cell_start_x -= cell_width / 2.0 row_order += 1 return True + + + def _get_cell_background(self, row_index, column_index): + return cairo.SolidPattern(1.0, 1.0, 1.0) + + + def _draw_cell(self, ctx, row_index, column_index, cell_width, cell_height): + centre = ctx.get_current_point() + + # Draw the cell outline as a hexagon and fill it. + ctx.rel_move_to(0.0, -cell_height / 2.0) + ctx.rel_line_to(cell_width / 2.0, cell_height / 3.0) + ctx.rel_line_to(0.0, cell_height / 3.0) + ctx.rel_line_to(-cell_width / 2.0, cell_height / 3.0) + ctx.rel_line_to(-cell_width / 2.0, -cell_height / 3.0) + ctx.rel_line_to(0.0, -cell_height / 3.0) + ctx.close_path() + + ctx.set_source_rgb(0.0, 0.0, 0.0) + ctx.stroke_preserve() + + ctx.set_source(self._get_cell_background(row_index, column_index)) + ctx.fill() + + # Write its number. + cell_number = self._calculate_pascal_number(row_index, + column_index) + extents = ctx.text_extents(str(cell_number)) + ctx.move_to(centre[0] - extents[2] / 2.0, centre[1] + extents[3] / 2.0) + + ctx.set_font_size(50) + ctx.set_source_rgb(0.0, 0.0, 0.0) + ctx.show_text(str(cell_number)) |