tuikit/layouts/fixed.py
author Radek Brich <radek.brich@devl.cz>
Mon, 16 Feb 2015 21:17:43 +0100
changeset 117 8680c2333546
parent 116 165b5d65e1cb
permissions -rw-r--r--
Update FixedLayout. Add demo launcher.

from .layout import Layout


class FixedLayout(Layout):

    """Widgets are placed on fixed position as specified in hints.

    Position can be relative to any side or center of parent widget.

    """

    def __init__(self):
        Layout.__init__(self)
        self._widget_hints = {}  # Widget : (left, top, right, bottom, xrel, yrel)

    def add(self, widget, left=None, top=None, right=None, bottom=None,
            center=None, fill=None):
        """Add widget to layout.

        Place hints:
        * left, right, top, bottom = None | <num> ; <num> >= 0
            - Fix Widget position to parent sides.
            - If both left and right (or top and bottom) are set, the widget
              will be stretched to fill full area minus specified space.
        * center, fill = None | 'x' | 'y' | 'xy'
            - Center widget in x, y or both axes.
            - Fill is shortcut for setting both positions in same axis.

        """
        Layout.add(self, widget)
        # Internally, coordinate relation is marked as:
        # '+': from left or top
        # '-': from right or bottom
        # 'C': from center
        # 'F': from both sides (fill)
        xrel, yrel = '+', '+'
        fill, center = fill or '', center or ''
        if left is None and right is not None:
            xrel = '-'
        if top is None and bottom is not None:
            yrel = '-'
        if 'x' in center:
            xrel = 'C'
        if 'y' in center:
            yrel = 'C'
        if 'x' in fill:
            xrel = 'F'
        if 'y' in fill:
            yrel = 'F'
        self._widget_hints[widget] = (left or 0, top or 0,
                                      right or 0, bottom or 0,
                                      xrel, yrel)

    def update(self, w, h):
        for widget in self._managed_widgets:
            left, top, right, bottom, xrel, yrel = self._widget_hints[widget]
            sw, sh = widget.sizereq
            ox, oy = 0, 0  # origin
            if xrel == '-':
                ox = w - sw
            if yrel == '-':
                oy = h - sh
            if xrel == 'C':
                ox = (w - sw) // 2
            if yrel == 'C':
                oy = (h - sh) // 2
            px = ox + left - right
            py = oy + top - bottom
            if xrel == 'F':
                px = left
                sw = w - left - right
            if yrel == 'F':
                py = top
                sh = h - top - bottom
            widget.resize(sw, sh)
            widget.pos.update(px, py)