author | Radek Brich <radek.brich@devl.cz> |
Sun, 15 Feb 2015 12:52:46 +0100 | |
changeset 115 | b4ff7392003a |
parent 114 | 26c02bd94bd9 |
permissions | -rw-r--r-- |
114
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
1 |
from .layout import Layout |
115
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
2 |
from ..core.coords import Size |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
3 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
4 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
5 |
class GridCell: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
6 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
7 |
"""Grid cell, |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
8 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
9 |
This class contains attributes of the row/column |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
10 |
and references to all widgets placed here. |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
11 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
12 |
""" |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
13 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
14 |
def __init__(self, widget=None): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
15 |
self.widget = widget |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
16 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
17 |
@property |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
18 |
def sizemin(self): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
19 |
return self.widget.sizemin if self.widget else Size(0, 0) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
20 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
21 |
def __repr__(self): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
22 |
return '%s(%r)' % (self.__class__.__name__, self.widget) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
23 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
24 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
25 |
class GridRow: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
26 |
pass |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
27 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
28 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
29 |
class GridColumn: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
30 |
pass |
114
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
31 |
|
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
32 |
|
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
33 |
class GridLayout(Layout): |
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
34 |
|
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
35 |
"""Lay out widgets in a grid. |
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
36 |
|
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
37 |
Grid size is determined by each widget's specified column and row. |
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
38 |
|
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
39 |
""" |
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
40 |
|
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
41 |
def __init__(self): |
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
42 |
Layout.__init__(self) |
115
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
43 |
#: map grid coordinates (x,y) to Widget |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
44 |
self._grid = {} |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
45 |
#: size of grid, expanded to accommodate given grid coordinates |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
46 |
self._grid_size = Size() |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
47 |
#: GridRow object for each row contains row parameters |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
48 |
self._rows = [] |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
49 |
#: GridColumn object for each column contains column parameters |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
50 |
self._columns = [] |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
51 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
52 |
@property |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
53 |
def row_count(self): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
54 |
return self._grid_size.h |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
55 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
56 |
@property |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
57 |
def column_count(self): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
58 |
return self._grid_size.w |
114
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
59 |
|
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
60 |
def add(self, widget, row, column): |
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
61 |
Layout.add(self, widget) |
115
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
62 |
self._grid_size.update(w=max(row + 1, self._grid_size.h), |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
63 |
h=max(column + 1, self._grid_size.w)) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
64 |
if (row, column) in self._grid: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
65 |
raise Exception( |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
66 |
'GridLayout.add: Cell (%s,%s) is occupied, cannot add widget.' |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
67 |
% (row, column)) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
68 |
self._grid[(row, column)] = GridCell(widget) |
114
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
69 |
|
115
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
70 |
def get_widget_at(self, row, column): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
71 |
cell = self._grid.get((row, column)) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
72 |
return cell.widget if cell else None |
114
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
73 |
|
115
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
74 |
def update(self, w, h): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
75 |
row_height = [] |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
76 |
column_width = [] |
114
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
77 |
|
115
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
78 |
# compute min. height of each row |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
79 |
for row in range(self.row_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
80 |
minh = 0 |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
81 |
for col in range(self.column_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
82 |
widget = self.get_widget_at(row, col) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
83 |
if widget: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
84 |
minh = max(minh, widget.sizemin.h) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
85 |
row_height.append(minh) |
114
26c02bd94bd9
Add Widget.posreq. Add OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
86 |
|
115
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
87 |
# compute min. width of each column |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
88 |
for col in range(self.column_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
89 |
minw = 0 |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
90 |
for row in range(self.row_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
91 |
widget = self.get_widget_at(row, col) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
92 |
if widget: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
93 |
minw = max(minw, widget.sizemin.w) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
94 |
column_width.append(minw) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
95 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
96 |
# distribute rest of space to rows |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
97 |
resth = h - sum(row_height) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
98 |
if resth > 0: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
99 |
addh = resth // self.row_count |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
100 |
resth = resth % self.row_count |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
101 |
for row in range(self.row_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
102 |
row_height[row] += addh |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
103 |
if resth: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
104 |
row_height[row] += 1 |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
105 |
resth -= 1 |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
106 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
107 |
# distribute rest of space to columns |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
108 |
restw = w - sum(column_width) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
109 |
if restw > 0: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
110 |
addw = restw // self.column_count |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
111 |
restw = restw % self.column_count |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
112 |
for col in range(self.column_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
113 |
column_width[col] += addw |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
114 |
if restw: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
115 |
column_width[col] += 1 |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
116 |
restw -= 1 |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
117 |
|
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
118 |
# place widgets |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
119 |
for row in range(self.row_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
120 |
for col in range(self.column_count): |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
121 |
widget = self.get_widget_at(row, col) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
122 |
if widget: |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
123 |
widget.resize(column_width[col], row_height[row]) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
124 |
widget.move(sum(column_width[:col]), sum(row_height[:row])) |
b4ff7392003a
GridLayout: basic implementation.
Radek Brich <radek.brich@devl.cz>
parents:
114
diff
changeset
|
125 |