tuikit/core/container.py
author Radek Brich <radek.brich@devl.cz>
Wed, 03 Sep 2014 19:14:43 +0200
changeset 111 b055add74b18
parent 109 105b1affc3c2
child 112 ce2e67e7bbb8
permissions -rw-r--r--
Refactor events.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
     1
from tuikit.core.widget import Widget
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
     2
from tuikit.core.coords import Point
93
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
     3
from tuikit.layouts.fixed import FixedLayout
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
     4
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
     5
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
     6
class Container(Widget):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
     7
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
     8
    """Container widget.
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     9
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    10
    Can contain other widgets to create hierarchical structure.
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    11
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    12
    """
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 23
diff changeset
    13
93
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
    14
    def __init__(self, layout_class=FixedLayout):
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    15
        Widget.__init__(self)
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    16
        #: List of child widgets.
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    17
        self._widgets = []
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    18
        #: Widget with keyboard focus
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    19
        self.focus_widget = None
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    20
        #: If True, tab cycles inside container
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    21
        self.trap_focus = False
93
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
    22
        self.layout = layout_class()
9
7175ed629a76 Added ComboBox, HorizontalLayout, TreeNode, TreeModel, TreeView. Widget is now descendant of EventSource. Improved color management (color prefixes).
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    23
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    24
    def add(self, widget):
87
ee5ea9671f28 Add core Widget, Container. Add widgets Label.
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
    25
        """Add widget into container."""
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    26
        self._widgets.append(widget)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    27
        widget.parent = self
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    28
        widget.window = self.window
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
    29
        widget.set_theme(self.theme)
93
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
    30
        self.layout.add(widget)
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    31
        if self.focus_widget is None and widget.can_focus():
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    32
            self.focus_widget = widget
93
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
    33
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
    34
    def resize(self, w, h):
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
    35
        Widget.resize(self, w, h)
c1e79acb9fcb Add Layout, FixedLayout.
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
    36
        self.layout.resize()
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
    37
94
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
    38
    def draw(self, buffer):
87
ee5ea9671f28 Add core Widget, Container. Add widgets Label.
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
    39
        """Draw child widgets."""
94
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
    40
        Widget.draw(self, buffer)
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    41
        for child in self._widgets:
94
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
    42
            with buffer.moved_origin(child.x, child.y):
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
    43
                with buffer.clip(buffer.origin.x, buffer.origin.y,
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
    44
                                 child.width, child.height):
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
    45
                    child.draw(buffer)
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    46
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    47
    def set_theme(self, theme):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    48
        Widget.set_theme(self, theme)
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    49
        for child in self._widgets:
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    50
            child.set_theme(theme)
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    51
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    52
    @property
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    53
    def cursor(self):
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    54
        if self.focus_widget:
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    55
            cursor = self.focus_widget.cursor
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    56
            if cursor is not None:
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    57
                return cursor.moved(*self.focus_widget.pos)
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    58
        else:
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    59
            if self._cursor is not None:
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    60
                return Point(self._cursor)
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    61
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    62
    ## input events ##
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    63
111
b055add74b18 Refactor events.
Radek Brich <radek.brich@devl.cz>
parents: 109
diff changeset
    64
    def keypress_event(self, ev):
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    65
        # First, handle the keypress event to focused child widget
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    66
        if self.focus_widget is not None:
111
b055add74b18 Refactor events.
Radek Brich <radek.brich@devl.cz>
parents: 109
diff changeset
    67
            if self.focus_widget.keypress_event(ev):
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    68
                return True
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    69
        # Next, handle default key behaviour by Container
111
b055add74b18 Refactor events.
Radek Brich <radek.brich@devl.cz>
parents: 109
diff changeset
    70
        if ev.keyname == 'tab':
b055add74b18 Refactor events.
Radek Brich <radek.brich@devl.cz>
parents: 109
diff changeset
    71
            return self.focus_next(-1 if 'shift' in ev.mods else 1)
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    72
        # Finally, handle default keys by Widget
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    73
        # and send keypress signal
111
b055add74b18 Refactor events.
Radek Brich <radek.brich@devl.cz>
parents: 109
diff changeset
    74
        if Widget.keypress_event(self, ev):
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    75
            return True
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    76
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    77
    ## focus ##
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    78
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    79
    def focus_next(self, step=1):
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    80
        """Focus next child.
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    81
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    82
        Sets focus to next child, if there is one
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    83
        which can be focused. Cycles from last child
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    84
        to first when needed. Return value depends on
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    85
        this cycling:
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    86
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    87
         * False means there wasn't any child to focus
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    88
           before end of list. Focus was either not changed
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    89
           or first child was focused.
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    90
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    91
         * True when focus is set to next child in normal
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    92
           way or when self.trap_focus is set.
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    93
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    94
        Return value is supposed to be returned from keypress
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    95
        event - in that case, True stops event propagation.
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    96
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    97
        """
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    98
        if self.focus_widget is None:
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    99
            idx_current = 0
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   100
        else:
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   101
            idx_current = self._widgets.index(self.focus_widget)
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   102
        idx_new = idx_current
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   103
        cycled = False
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   104
        while True:
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   105
            idx_new += step
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   106
            if idx_new >= len(self._widgets):
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   107
                idx_new = 0
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   108
                cycled = True
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   109
            if idx_new < 0:  # for focus_previous
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   110
                idx_new = len(self._widgets) - 1
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   111
                cycled = True
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   112
            if idx_current == idx_new:
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   113
                return False
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   114
            if self._widgets[idx_new].can_focus():
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   115
                self.focus_widget = self._widgets[idx_new]
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   116
                return self.trap_focus or not cycled
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   117
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   118
    def focus_previous(self):
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   119
        """Focus previous child."""
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
   120
        self.focus_next(-1)