--- 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]))
+