tuikit/layouts/anchor.py
author Radek Brich <radek.brich@devl.cz>
Sun, 15 Feb 2015 12:48:23 +0100
changeset 114 26c02bd94bd9
permissions -rw-r--r--
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)