tuikit/core/container.py
changeset 119 dd91747504dd
parent 118 8c7970520632
equal deleted inserted replaced
118:8c7970520632 119:dd91747504dd
    14     def __init__(self, layout_class=FixedLayout):
    14     def __init__(self, layout_class=FixedLayout):
    15         Widget.__init__(self)
    15         Widget.__init__(self)
    16         #: List of child widgets.
    16         #: List of child widgets.
    17         self._widgets = []
    17         self._widgets = []
    18         #: Widget with keyboard focus
    18         #: Widget with keyboard focus
    19         self.focus_widget = None
    19         self._focus_widget = None
    20         #: Widget on last mouse position
    20         #: Widget on last mouse position
    21         self.mouse_widget = None
    21         self.mouse_widget = None
    22         #: If True, tab cycles inside container
    22         #: If True, tab cycles inside container
    23         self.trap_focus = False
    23         self.trap_focus = False
    24         self.layout = layout_class()
    24         self.layout = layout_class()
    27         """Add widget into container."""
    27         """Add widget into container."""
    28         self._widgets.append(widget)
    28         self._widgets.append(widget)
    29         widget.parent = self
    29         widget.parent = self
    30         widget.window = self.window
    30         widget.window = self.window
    31         widget.set_theme(self.theme)
    31         widget.set_theme(self.theme)
       
    32         widget.timer = self.timer
    32         self.layout.add(widget, *args, **kwargs)
    33         self.layout.add(widget, *args, **kwargs)
    33         if self.focus_widget is None and widget.can_focus():
    34         if self._focus_widget is None and widget.can_focus():
    34             self.focus_widget = widget
    35             self._focus_widget = widget
       
    36         widget.redraw()
    35 
    37 
    36     def resize(self, w, h):
    38     def resize(self, w, h):
    37         Widget.resize(self, w, h)
    39         Widget.resize(self, w, h)
    38         self.layout.update(w, h)
    40         self.layout.update(w, h)
    39 
    41 
    40     def draw(self, buffer):
    42     # -------------------------------------------------------------------------
    41         """Draw child widgets."""
    43     #   Presentation
    42         Widget.draw(self, buffer)
    44 
       
    45     def draw_if_needed(self, buffer):
       
    46         """Draw this and child widgets, whichever was requested by redraw."""
       
    47         Widget.draw_if_needed(self, buffer)
    43         for child in self._widgets:
    48         for child in self._widgets:
    44             with buffer.moved_origin(child.x, child.y):
    49             with buffer.moved_origin(child.x, child.y):
    45                 with buffer.clip(buffer.origin.x, buffer.origin.y,
    50                 with buffer.clip(buffer.origin.x, buffer.origin.y,
    46                                  child.width, child.height):
    51                                  child.width, child.height):
    47                     child.draw(buffer)
    52                     child.draw_if_needed(buffer)
       
    53 
       
    54     def redraw(self):
       
    55         """Request redraw of all widgets in container."""
       
    56         Widget.redraw(self)
       
    57         for child in self._widgets:
       
    58             child.redraw()
    48 
    59 
    49     def set_theme(self, theme):
    60     def set_theme(self, theme):
    50         Widget.set_theme(self, theme)
    61         Widget.set_theme(self, theme)
    51         for child in self._widgets:
    62         for child in self._widgets:
    52             child.set_theme(theme)
    63             child.set_theme(theme)
    54     @property
    65     @property
    55     def cursor(self):
    66     def cursor(self):
    56         """Return cursor coordinates or None if cursor is not set
    67         """Return cursor coordinates or None if cursor is not set
    57         or is set outside of widget boundaries.
    68         or is set outside of widget boundaries.
    58 
    69 
    59         If this container has child with focus, return its cursor position instead.
    70         If this container has child with focus,
       
    71         return its cursor position instead.
    60 
    72 
    61         """
    73         """
    62         if self.focus_widget:
    74         if self.focus_widget:
    63             cursor = self.focus_widget.cursor
    75             cursor = self.focus_widget.cursor
    64             if not cursor:
    76             if not cursor:
    65                 return None
    77                 return None
    66             cursor = cursor.moved(*self.focus_widget.pos)
    78             cursor = cursor.moved(*self.focus_widget.pos)
    67         else:
    79         else:
    68             cursor = self._cursor.immutable()
    80             cursor = self._cursor.immutable()
    69         if cursor in Rect._make((0, 0), self._size):
    81         if cursor in Rect(0, 0, *self._size):
    70             return cursor
    82             return cursor
    71 
    83 
    72     @property
    84     @property
    73     def cursor_visible(self):
    85     def cursor_visible(self):
    74         if self.focus_widget:
    86         if self.focus_widget:
    75             return self.focus_widget.cursor_visible
    87             return self.focus_widget.cursor_visible
    76         else:
    88         else:
    77             return self._cursor_visible
    89             return self._cursor_visible
    78 
    90 
    79     ## input events ##
    91     # -------------------------------------------------------------------------
       
    92     #   Events
    80 
    93 
    81     def keypress_event(self, ev):
    94     def keypress_event(self, ev):
    82         # First, handle the keypress event to focused child widget
    95         # First, handle the keypress event to focused child widget
    83         if self.focus_widget is not None:
    96         if self.focus_widget is not None:
    84             if self.focus_widget.keypress_event(ev):
    97             if self.focus_widget.keypress_event(ev):
   104 
   117 
   105     def mousemove_event(self, ev):
   118     def mousemove_event(self, ev):
   106         if self.mouse_widget:
   119         if self.mouse_widget:
   107             self.mouse_widget.mousemove_event(ev.rebase(self.mouse_widget.pos))
   120             self.mouse_widget.mousemove_event(ev.rebase(self.mouse_widget.pos))
   108 
   121 
   109     ## focus ##
   122     # -------------------------------------------------------------------------
       
   123     #   Focus
   110 
   124 
   111     def focus_next(self, step=1):
   125     def focus_next(self, step=1):
   112         """Focus next child.
   126         """Focus next child.
   113 
   127 
   114         Sets focus to next child, if there is one
   128         Sets focus to next child, if there is one
   148                 return self.trap_focus or not cycled
   162                 return self.trap_focus or not cycled
   149 
   163 
   150     def focus_previous(self):
   164     def focus_previous(self):
   151         """Focus previous child."""
   165         """Focus previous child."""
   152         self.focus_next(-1)
   166         self.focus_next(-1)
       
   167 
       
   168     @property
       
   169     def focus_widget(self):
       
   170         return self._focus_widget
       
   171 
       
   172     @focus_widget.setter
       
   173     def focus_widget(self, widget):
       
   174         orig_focus_widget = self._focus_widget
       
   175         self._focus_widget = widget
       
   176         widget.redraw()
       
   177         if orig_focus_widget:
       
   178             orig_focus_widget.redraw()