Lightningbeam/PyGUI-2.5.3/GUI/Generic/GridView.py

117 lines
3.3 KiB
Python

#--------------------------------------------------------------------------
#
# 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)