tuikit/layouts/fixed.py
changeset 117 8680c2333546
parent 116 165b5d65e1cb
equal deleted inserted replaced
116:165b5d65e1cb 117:8680c2333546
     1 from .layout import Layout
     1 from .layout import Layout
     2 
     2 
     3 
     3 
     4 class FixedLayout(Layout):
     4 class FixedLayout(Layout):
     5 
     5 
     6     """Widgets are placed on fixed position as specified in `sizereq`.
     6     """Widgets are placed on fixed position as specified in hints.
     7 
     7 
     8     Align hints (kwargs to :meth:`add`):
     8     Position can be relative to any side or center of parent widget.
     9         * halign = 'left' (default) | 'right' | 'fill' | 'center'
       
    10         * valign = 'top' (default) | 'bottom' | 'fill' | 'center'
       
    11 
     9 
    12     """
    10     """
    13 
    11 
    14     def __init__(self):
    12     def __init__(self):
    15         Layout.__init__(self)
    13         Layout.__init__(self)
    16         self._widget_hints = {}  # Widget : (halign, valign)
    14         self._widget_hints = {}  # Widget : (left, top, right, bottom, xrel, yrel)
    17 
    15 
    18     def add(self, widget, *args, **kwargs):
    16     def add(self, widget, left=None, top=None, right=None, bottom=None,
       
    17             center=None, fill=None):
       
    18         """Add widget to layout.
       
    19 
       
    20         Place hints:
       
    21         * left, right, top, bottom = None | <num> ; <num> >= 0
       
    22             - Fix Widget position to parent sides.
       
    23             - If both left and right (or top and bottom) are set, the widget
       
    24               will be stretched to fill full area minus specified space.
       
    25         * center, fill = None | 'x' | 'y' | 'xy'
       
    26             - Center widget in x, y or both axes.
       
    27             - Fill is shortcut for setting both positions in same axis.
       
    28 
       
    29         """
    19         Layout.add(self, widget)
    30         Layout.add(self, widget)
    20         assert len(args) == 0, \
    31         # Internally, coordinate relation is marked as:
    21             "FixedLayout does not support positional hint args: %s" % args
    32         # '+': from left or top
    22         assert all(key in ('halign', 'valign') for key in kwargs.keys()), \
    33         # '-': from right or bottom
    23             "Unsupported hints: %s" % tuple(kwargs.keys())
    34         # 'C': from center
    24         halign = kwargs.get('halign', 'left')
    35         # 'F': from both sides (fill)
    25         valign = kwargs.get('valign', 'top')
    36         xrel, yrel = '+', '+'
    26         self._widget_hints[widget] = (halign, valign)
    37         fill, center = fill or '', center or ''
       
    38         if left is None and right is not None:
       
    39             xrel = '-'
       
    40         if top is None and bottom is not None:
       
    41             yrel = '-'
       
    42         if 'x' in center:
       
    43             xrel = 'C'
       
    44         if 'y' in center:
       
    45             yrel = 'C'
       
    46         if 'x' in fill:
       
    47             xrel = 'F'
       
    48         if 'y' in fill:
       
    49             yrel = 'F'
       
    50         self._widget_hints[widget] = (left or 0, top or 0,
       
    51                                       right or 0, bottom or 0,
       
    52                                       xrel, yrel)
    27 
    53 
    28     def update(self, w, h):
    54     def update(self, w, h):
    29         for widget in self._managed_widgets:
    55         for widget in self._managed_widgets:
    30             halign, valign = self._widget_hints[widget]
    56             left, top, right, bottom, xrel, yrel = self._widget_hints[widget]
    31             px, py = widget.posreq
       
    32             sw, sh = widget.sizereq
    57             sw, sh = widget.sizereq
    33             if halign == 'right':   px = w - px
    58             ox, oy = 0, 0  # origin
    34             if valign == 'bottom':  py = h - py
    59             if xrel == '-':
    35             if halign == 'fill':    px = 0; sw = w
    60                 ox = w - sw
    36             if valign == 'fill':    py = 0; sh = h
    61             if yrel == '-':
    37             if halign == 'center':  px = (w - sw) // 2
    62                 oy = h - sh
    38             if valign == 'center':  py = (h - sh) // 2
    63             if xrel == 'C':
       
    64                 ox = (w - sw) // 2
       
    65             if yrel == 'C':
       
    66                 oy = (h - sh) // 2
       
    67             px = ox + left - right
       
    68             py = oy + top - bottom
       
    69             if xrel == 'F':
       
    70                 px = left
       
    71                 sw = w - left - right
       
    72             if yrel == 'F':
       
    73                 py = top
       
    74                 sh = h - top - bottom
    39             widget.resize(sw, sh)
    75             widget.resize(sw, sh)
    40             widget.pos.update(px, py)
    76             widget.pos.update(px, py)