Redraw widgets on request. Add scrollbar demo.
from tuikit.core.buffer import Buffer
from tuikit.core.signal import Signal
from tuikit.core.container import Container
class Window(Container):
"""Window is rectangular part of screen containing widgets.
Widgets are drawn into window, events are routed to widgets through window.
Parent of Window is always WindowManager.
"""
def __init__(self, buffer=None):
"""New buffer for the window will be created unless given existing
`buffer` as parameter."""
Container.__init__(self)
self.allow_focus = True
self.trap_focus = True
self._buffer = None
self.buffer = buffer or Buffer()
@property
def buffer(self):
return self._buffer
@buffer.setter
def buffer(self, buffer):
# replace the buffer
self._buffer = buffer
@property
def size(self):
return self.buffer.size
def resize(self, w, h):
"""Resize buffer when window gets resized."""
Container.resize(self, w, h)
self.buffer.resize(w, h)
self.redraw()
def draw_content_if_needed(self):
"""Draw window contents into its own buffer."""
buffer = self.buffer
buffer.reset_origin()
for child in self._widgets:
with buffer.moved_origin(child.x, child.y):
with buffer.clip(buffer.origin.x, buffer.origin.y,
child.width, child.height):
child.draw_if_needed(buffer)
def draw_if_needed(self, buffer):
"""Refresh window content and draw it into `buffer` if required."""
self.draw_content_if_needed()
# Draw window unconditionally (for now)
self.draw(buffer)
def draw(self, buffer):
"""Draw window buffer into given`buffer`."""
buffer.draw(self.buffer)
class WindowManager(Container):
def __init__(self, timer):
Container.__init__(self)
self.timer = timer
def draw(self, buffer):
Container.draw(self, buffer)
self.log.debug('%s has focus.', self.get_focused_widget().name)
def resize(self, w, h):
Container.resize(self, w, h)
self._widgets[0].resize(w, h)
def keypress_event(self, ev):
self.log.debug('%s', ev)
return Container.keypress_event(self, ev)
def handle_event(self, event):
"""Handle input event to managed windows."""
self.log.debug('Handle event: %r', event)
handler = getattr(self, event.name + '_event', None)
if handler:
handler(event)
else:
raise Exception('Unknown event: %r' % event)
def get_focused_widget(self):
"""Traverse the widget hierarchy to bottom
and return actually focused Widget."""
node = self
while isinstance(node, Container) and node.focus_widget:
node = node.focus_widget
return node
def get_cursor_if_visible(self):
if self.cursor_visible:
return self.cursor