#-------------------------------------------------------------------------- # # PyGUI - Grid View - Generic # #-------------------------------------------------------------------------- from GUI import export from GUI.Properties import overridable_property from GUI import ScrollableView, rgb class GridView(ScrollableView): """A ScrollableView consisting of a grid of equal-sized cells.""" num_columns = overridable_property('num_columns', "Width of the view in columns") num_rows = overridable_property('num_rows', "Height of the view in rows") cell_size = overridable_property('cell_size', "Size of each cell") backcolor = overridable_property('backcolor', "Background fill colour") _cell_size = (32, 32) _num_rows = 0 _num_columns = 0 _backcolor = rgb(1, 1, 1, 1) def __init__(self, num_rows, num_columns, cell_size, **kwds): ScrollableView.__init__(self) self._num_rows = num_rows self._num_columns = num_columns self._cell_size = cell_size self._update_extent() self.set(**kwds) def get_cell_size(self): return self._cell_size def set_cell_size(self, x): self._cell_size = x self._update_extent() def get_num_rows(self): return self._num_rows def set_num_rows(self, x): self._num_rows = x self._update_extent() def get_num_columns(self): return self._num_columns def set_num_columns(self, x): self._num_columns = x self._update_extent() def _update_extent(self): cw, ch = self._cell_size nr = self._num_rows nc = self._num_columns self.extent = (cw * nc, ch * nr) def cell_rect(self, row, col): w, h = self._cell_size l = col * w t = row * h return (l, t, l + w, t + h) def get_backcolor(self): return self._backcolor def set_backcolor(self, x): self._backcolor = x def cell_containing_point(self, p): x, y = p cw, ch = self.cell_size return (int(y // ch), int(x // cw)) def draw(self, canvas, update_rect): canvas.backcolor = self.backcolor canvas.erase_rect(update_rect) ul, ut, ur, ub = update_rect nr = self._num_rows nc = self._num_columns cw, ch = self.cell_size row0 = max(0, int(ut // ch)) row1 = min(nr, int(ub // ch) + 1) col0 = max(0, int(ul // cw)) col1 = min(nc, int(ur // cw) + 1) row_range = xrange(row0, row1) col_range = xrange(col0, col1) for row in row_range: for col in col_range: rect = self.cell_rect(row, col) self.draw_cell(canvas, row, col, rect) def draw_cell(self, canvas, row, col, rect): """Should draw the cell at the given row and colum inside the given rect.""" pass def mouse_down(self, event): row, col = self.cell_containing_point(event.position) nr = self._num_rows nc = self._num_columns if 0 <= row < nr and 0 <= col < nc: self.click_cell(row, col, event) def click_cell(self, row, col, event): """Called when a mouse_down event has occured in the indicated cell.""" pass export(GridView)