164 lines
4.8 KiB
Python
164 lines
4.8 KiB
Python
#
|
|
# Albow - Layout widgets
|
|
#
|
|
|
|
from pygame import Rect
|
|
from widget import Widget
|
|
|
|
|
|
class RowOrColumn(Widget):
|
|
|
|
_is_gl_container = True
|
|
|
|
def __init__(self, size, items, kwds):
|
|
align = kwds.pop('align', 'c')
|
|
spacing = kwds.pop('spacing', 10)
|
|
expand = kwds.pop('expand', None)
|
|
if isinstance(expand, int):
|
|
expand = items[expand]
|
|
#if kwds:
|
|
# raise TypeError("Unexpected keyword arguments to Row or Column: %s"
|
|
# % kwds.keys())
|
|
Widget.__init__(self, **kwds)
|
|
#print "albow.controls: RowOrColumn: size =", size, "expand =", expand ###
|
|
d = self.d
|
|
longways = self.longways
|
|
crossways = self.crossways
|
|
axis = self.axis
|
|
k, attr2, attr3 = self.align_map[align]
|
|
w = 0
|
|
length = 0
|
|
if isinstance(expand, int):
|
|
expand = items[expand]
|
|
elif not expand:
|
|
expand = items[-1]
|
|
move = ''
|
|
for item in items:
|
|
r = item.rect
|
|
w = max(w, getattr(r, crossways))
|
|
if item is expand:
|
|
item.set_resizing(axis, 's')
|
|
move = 'm'
|
|
else:
|
|
item.set_resizing(axis, move)
|
|
length += getattr(r, longways)
|
|
if size is not None:
|
|
n = len(items)
|
|
if n > 1:
|
|
length += spacing * (n - 1)
|
|
#print "albow.controls: expanding size from", length, "to", size ###
|
|
setattr(expand.rect, longways, max(1, size - length))
|
|
h = w * k // 2
|
|
m = self.margin
|
|
px = h * d[1] + m
|
|
py = h * d[0] + m
|
|
sx = spacing * d[0]
|
|
sy = spacing * d[1]
|
|
for item in items:
|
|
setattr(item.rect, attr2, (px, py))
|
|
self.add(item)
|
|
p = getattr(item.rect, attr3)
|
|
px = p[0] + sx
|
|
py = p[1] + sy
|
|
self.shrink_wrap()
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
class Row(RowOrColumn):
|
|
|
|
d = (1, 0)
|
|
axis = 'h'
|
|
longways = 'width'
|
|
crossways = 'height'
|
|
align_map = {
|
|
't': (0, 'topleft', 'topright'),
|
|
'c': (1, 'midleft', 'midright'),
|
|
'b': (2, 'bottomleft', 'bottomright'),
|
|
}
|
|
|
|
def __init__(self, items, width=None, **kwds):
|
|
"""
|
|
Row(items, align=alignment, spacing=10, width=None, expand=None)
|
|
align = 't', 'c' or 'b'
|
|
"""
|
|
RowOrColumn.__init__(self, width, items, kwds)
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
class Column(RowOrColumn):
|
|
|
|
d = (0, 1)
|
|
axis = 'v'
|
|
longways = 'height'
|
|
crossways = 'width'
|
|
align_map = {
|
|
'l': (0, 'topleft', 'bottomleft'),
|
|
'c': (1, 'midtop', 'midbottom'),
|
|
'r': (2, 'topright', 'bottomright'),
|
|
}
|
|
|
|
def __init__(self, items, height=None, **kwds):
|
|
"""
|
|
Column(items, align=alignment, spacing=10, height=None, expand=None)
|
|
align = 'l', 'c' or 'r'
|
|
"""
|
|
RowOrColumn.__init__(self, height, items, kwds)
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
class Grid(Widget):
|
|
|
|
_is_gl_container = True
|
|
|
|
def __init__(self, rows, row_spacing=10, column_spacing=10, **kwds):
|
|
col_widths = [0] * len(rows[0])
|
|
row_heights = [0] * len(rows)
|
|
for j, row in enumerate(rows):
|
|
for i, widget in enumerate(row):
|
|
if widget:
|
|
col_widths[i] = max(col_widths[i], widget.width)
|
|
row_heights[j] = max(row_heights[j], widget.height)
|
|
row_top = 0
|
|
for j, row in enumerate(rows):
|
|
h = row_heights[j]
|
|
y = row_top + h // 2
|
|
col_left = 0
|
|
for i, widget in enumerate(row):
|
|
if widget:
|
|
w = col_widths[i]
|
|
x = col_left
|
|
widget.midleft = (x, y)
|
|
col_left += w + column_spacing
|
|
row_top += h + row_spacing
|
|
width = max(1, col_left - column_spacing)
|
|
height = max(1, row_top - row_spacing)
|
|
r = Rect(0, 0, width, height)
|
|
#print "albow.controls.Grid: r =", r ###
|
|
#print "...col_widths =", col_widths ###
|
|
#print "...row_heights =", row_heights ###
|
|
Widget.__init__(self, r, **kwds)
|
|
self.add(rows)
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
class Frame(Widget):
|
|
# margin int spacing between border and widget
|
|
|
|
border_width = 1
|
|
margin = 2
|
|
|
|
def __init__(self, client, border_spacing=None, **kwds):
|
|
Widget.__init__(self, **kwds)
|
|
self.client = client
|
|
if border_spacing is not None:
|
|
self.margin = self.border_width + border_spacing
|
|
d = self.margin
|
|
w, h = client.size
|
|
self.size = (w + 2 * d, h + 2 * d)
|
|
client.topleft = (d, d)
|
|
self.add(client)
|