Add Widget.posreq. Add OffsetLayout.
from .layout import Layout
class AnchorLayout(Layout):
"""Anchor widgets to borders of container."""
def __init__(self):
Layout.__init__(self)
self.register_hints(
'halign', make_select('left', 'right', 'fill', 'center'),
'valign', make_select('top', 'bottom', 'fill', 'center'),
'margin', Borders,
)
def on_resize(self, ev):
for child in self._get_children():
reqw = max(child.sizereq.w, child.sizemin.w)
reqh = max(child.sizereq.h, child.sizemin.h)
ha = child.hint_value('halign')
va = child.hint_value('valign')
margin = child.hint_value('margin')
if ha == 'left':
x = margin.l
w = reqw
if ha == 'right':
x = self.width - margin.r - reqw
w = reqw
if ha == 'fill':
x = margin.l
w = self.width - margin.l - margin.r
if ha == 'center':
x = (self.width - reqw) // 2
w = reqw
if va == 'top':
y = margin.t
h = reqh
if va == 'bottom':
y = self.height - margin.b - reqh
h = reqh
if va == 'fill':
y = margin.t
h = self.height - margin.t - margin.b
if va == 'center':
y = (self.height - reqh) // 2
h = reqh
child._pos.update(x=x, y=y)
child._size.update(w=w, h=h)
child._view_size.update(w=w, h=h)
def move_child(self, child, x=None, y=None):
"""Move child inside container by adjusting its margin.
Operation is supported only for one-side anchors:
left, right, top, bottom
No move on axis where align is set to
center, fill
"""
if not child in self.children:
raise ValueError('AnchorLayout.move(): Cannot move foreign child.')
margin = child.hint_value('margin')
newx = None
if x is not None:
ha = child.hint_value('halign')
ofsx = x - child.x
if ha == 'left':
margin.l += ofsx
newx = margin.l
elif ha == 'right':
margin.r -= ofsx
newx = self.width - margin.r - child.sizereq.w
newy = None
if y is not None:
va = child.hint_value('valign')
ofsy = y - child.y
if va == 'top':
margin.t += ofsy
newy = margin.t
elif va == 'bottom':
margin.b -= ofsy
newy = self.height - margin.b - child.sizereq.h
child._pos.update(x=newx, y=newy)