diff -r 26c02bd94bd9 -r b4ff7392003a tuikit/layouts/grid.py --- a/tuikit/layouts/grid.py Sun Feb 15 12:48:23 2015 +0100 +++ b/tuikit/layouts/grid.py Sun Feb 15 12:52:46 2015 +0100 @@ -1,4 +1,33 @@ from .layout import Layout +from ..core.coords import Size + + +class GridCell: + + """Grid cell, + + This class contains attributes of the row/column + and references to all widgets placed here. + + """ + + def __init__(self, widget=None): + self.widget = widget + + @property + def sizemin(self): + return self.widget.sizemin if self.widget else Size(0, 0) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, self.widget) + + +class GridRow: + pass + + +class GridColumn: + pass class GridLayout(Layout): @@ -11,14 +40,86 @@ def __init__(self): Layout.__init__(self) + #: map grid coordinates (x,y) to Widget + self._grid = {} + #: size of grid, expanded to accommodate given grid coordinates + self._grid_size = Size() + #: GridRow object for each row contains row parameters + self._rows = [] + #: GridColumn object for each column contains column parameters + self._columns = [] + + @property + def row_count(self): + return self._grid_size.h + + @property + def column_count(self): + return self._grid_size.w def add(self, widget, row, column): Layout.add(self, widget) + self._grid_size.update(w=max(row + 1, self._grid_size.h), + h=max(column + 1, self._grid_size.w)) + if (row, column) in self._grid: + raise Exception( + 'GridLayout.add: Cell (%s,%s) is occupied, cannot add widget.' + % (row, column)) + self._grid[(row, column)] = GridCell(widget) + def get_widget_at(self, row, column): + cell = self._grid.get((row, column)) + return cell.widget if cell else None + def update(self, w, h): + row_height = [] + column_width = [] + # compute min. height of each row + for row in range(self.row_count): + minh = 0 + for col in range(self.column_count): + widget = self.get_widget_at(row, col) + if widget: + minh = max(minh, widget.sizemin.h) + row_height.append(minh) - def update(self): - for widget in self._managed_widgets: - widget.resize(*widget.sizereq) - widget.pos.update(*(widget.posreq + self.offset)) + # compute min. width of each column + for col in range(self.column_count): + minw = 0 + for row in range(self.row_count): + widget = self.get_widget_at(row, col) + if widget: + minw = max(minw, widget.sizemin.w) + column_width.append(minw) + + # distribute rest of space to rows + resth = h - sum(row_height) + if resth > 0: + addh = resth // self.row_count + resth = resth % self.row_count + for row in range(self.row_count): + row_height[row] += addh + if resth: + row_height[row] += 1 + resth -= 1 + + # distribute rest of space to columns + restw = w - sum(column_width) + if restw > 0: + addw = restw // self.column_count + restw = restw % self.column_count + for col in range(self.column_count): + column_width[col] += addw + if restw: + column_width[col] += 1 + restw -= 1 + + # place widgets + for row in range(self.row_count): + for col in range(self.column_count): + widget = self.get_widget_at(row, col) + if widget: + widget.resize(column_width[col], row_height[row]) + widget.move(sum(column_width[:col]), sum(row_height[:row])) +