tuikit/layouts/anchor.py
changeset 114 26c02bd94bd9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tuikit/layouts/anchor.py	Sun Feb 15 12:48:23 2015 +0100
@@ -0,0 +1,83 @@
+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)