diff urwid_satext/sat_widgets.py @ 75:8ff563825080

FocusFrame is now based on Pile instead of Frame, header, body and footer attributes can be used to change part at any time
author Goffi <goffi@goffi.org>
date Fri, 21 Mar 2014 15:20:59 +0100
parents 0afff3c54b6e
children 6c2a1b349416
line wrap: on
line diff
--- a/urwid_satext/sat_widgets.py	Fri Mar 21 15:14:53 2014 +0100
+++ b/urwid_satext/sat_widgets.py	Fri Mar 21 15:20:59 2014 +0100
@@ -1045,23 +1045,98 @@
         return urwid.CanvasJoin(render)
 
 
-class FocusFrame(urwid.Frame):
-    """Frame which manage 'tab' key"""
+class FocusFrame(urwid.Pile):
+    """Frame-like which manage 'tab' key"""
+    _sizing = frozenset(['box'])
+
+    def __init__(self, body, header=None, footer=None, focus_part='body'):
+        self._header = self._footer = None
+        super(FocusFrame, self).__init__([body])
+        self.header = header
+        self._body = body
+        self.footer = footer
+        self.focus_position = focus_part
+
+    def _focus_part_recalc(self):
+        self._FOCUS_PARTS=[]
+        if self._header is not None:
+            self._FOCUS_PARTS.append('header')
+        self._FOCUS_PARTS.append('body')
+        if self._footer is not None:
+            self._FOCUS_PARTS.append('footer')
+        assert(len(self._FOCUS_PARTS) == len(self.contents))
+
+    @property
+    def header(self):
+        return self._header
+
+    @header.setter
+    def header(self, widget):
+        content = (widget, ('pack', None))
+        if widget is None:
+            if self._header is not None:
+                del self.contents[0]
+        elif self._header is None:
+            self.contents.insert(0, content)
+        else:
+            self.contents[0] = content
+        self._header = widget
+        self._focus_part_recalc()
+
+    @property
+    def body(self):
+        return self._body
+
+    @body.setter
+    def body(self, widget):
+        assert widget is not None
+        idx = self._FOCUS_PARTS.index('body')
+        self.contents[idx] = (widget, ("weight", 1))
+
+    @property
+    def footer(self):
+        return self._footer
+
+    @footer.setter
+    def footer(self, widget):
+        content = (widget, ('pack', None))
+        if widget is None:
+            if self._footer is not None:
+                del self.contents[-1]
+        elif self._footer is None:
+            self.contents.append(content)
+        else:
+            self.contents[-1] = content
+        self._footer = widget
+        self._focus_part_recalc()
+
+    @property
+    def focus_position_named(self):
+        return self._FOCUS_PARTS[self.int_focus_position]
+
+    @property
+    def focus_position(self):
+        return super(FocusFrame, self).focus_position
+
+    @focus_position.setter
+    def focus_position(self, position):
+        if isinstance(position, basestring):
+            try:
+                position = self._FOCUS_PARTS.index(position)
+            except IndexError:
+               raise IndexError("This FocusFrame has no %s" % position)
+        urwid.Pile.focus_position.__set__(self, position)
 
     def keypress(self, size, key):
-        ret = urwid.Frame.keypress(self, size, key)
+        ret = super(FocusFrame, self).keypress(size, key)
         if not ret:
             return
 
         if key == 'tab':
-            focus_list = ('header','body','footer')
-            focus_idx = focus_list.index(self.focus_part)
-            for i in range(2):
-                focus_idx = (focus_idx + 1) % len(focus_list)
-                focus_name = focus_list[focus_idx]
-                widget = getattr(self,'_'+focus_name)
-                if widget!=None and widget.selectable():
-                    self.set_focus(focus_name)
+            try:
+                self.focus_position -= 1
+            except IndexError:
+                self.focus_position = 2
 
         return ret