9 |
38 |
10 """ |
39 """ |
11 |
40 |
12 def __init__(self): |
41 def __init__(self): |
13 Layout.__init__(self) |
42 Layout.__init__(self) |
|
43 #: map grid coordinates (x,y) to Widget |
|
44 self._grid = {} |
|
45 #: size of grid, expanded to accommodate given grid coordinates |
|
46 self._grid_size = Size() |
|
47 #: GridRow object for each row contains row parameters |
|
48 self._rows = [] |
|
49 #: GridColumn object for each column contains column parameters |
|
50 self._columns = [] |
|
51 |
|
52 @property |
|
53 def row_count(self): |
|
54 return self._grid_size.h |
|
55 |
|
56 @property |
|
57 def column_count(self): |
|
58 return self._grid_size.w |
14 |
59 |
15 def add(self, widget, row, column): |
60 def add(self, widget, row, column): |
16 Layout.add(self, widget) |
61 Layout.add(self, widget) |
|
62 self._grid_size.update(w=max(row + 1, self._grid_size.h), |
|
63 h=max(column + 1, self._grid_size.w)) |
|
64 if (row, column) in self._grid: |
|
65 raise Exception( |
|
66 'GridLayout.add: Cell (%s,%s) is occupied, cannot add widget.' |
|
67 % (row, column)) |
|
68 self._grid[(row, column)] = GridCell(widget) |
17 |
69 |
|
70 def get_widget_at(self, row, column): |
|
71 cell = self._grid.get((row, column)) |
|
72 return cell.widget if cell else None |
18 |
73 |
|
74 def update(self, w, h): |
|
75 row_height = [] |
|
76 column_width = [] |
19 |
77 |
|
78 # compute min. height of each row |
|
79 for row in range(self.row_count): |
|
80 minh = 0 |
|
81 for col in range(self.column_count): |
|
82 widget = self.get_widget_at(row, col) |
|
83 if widget: |
|
84 minh = max(minh, widget.sizemin.h) |
|
85 row_height.append(minh) |
20 |
86 |
21 def update(self): |
87 # compute min. width of each column |
22 for widget in self._managed_widgets: |
88 for col in range(self.column_count): |
23 widget.resize(*widget.sizereq) |
89 minw = 0 |
24 widget.pos.update(*(widget.posreq + self.offset)) |
90 for row in range(self.row_count): |
|
91 widget = self.get_widget_at(row, col) |
|
92 if widget: |
|
93 minw = max(minw, widget.sizemin.w) |
|
94 column_width.append(minw) |
|
95 |
|
96 # distribute rest of space to rows |
|
97 resth = h - sum(row_height) |
|
98 if resth > 0: |
|
99 addh = resth // self.row_count |
|
100 resth = resth % self.row_count |
|
101 for row in range(self.row_count): |
|
102 row_height[row] += addh |
|
103 if resth: |
|
104 row_height[row] += 1 |
|
105 resth -= 1 |
|
106 |
|
107 # distribute rest of space to columns |
|
108 restw = w - sum(column_width) |
|
109 if restw > 0: |
|
110 addw = restw // self.column_count |
|
111 restw = restw % self.column_count |
|
112 for col in range(self.column_count): |
|
113 column_width[col] += addw |
|
114 if restw: |
|
115 column_width[col] += 1 |
|
116 restw -= 1 |
|
117 |
|
118 # place widgets |
|
119 for row in range(self.row_count): |
|
120 for col in range(self.column_count): |
|
121 widget = self.get_widget_at(row, col) |
|
122 if widget: |
|
123 widget.resize(column_width[col], row_height[row]) |
|
124 widget.move(sum(column_width[:col]), sum(row_height[:row])) |
|
125 |