--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tuikit/widgets/scrollview.py Sun Feb 15 12:48:23 2015 +0100
@@ -0,0 +1,134 @@
+from tuikit.core.container import Container
+from tuikit.layouts.offset import OffsetLayout
+
+#from tuikit.layout import AnchorLayout, OffsetLayout
+#from tuikit.scrollbar import VScrollbar, HScrollbar
+#from tuikit.common import Borders
+
+
+class Viewport(Container):
+
+ """Viewport for partial view on widgets.
+
+ Viewport is special type of Container, which shows partial view
+ on its managed widgets. This view can be moved to show different part
+ and thus allow "scrolling" over the content. Complete view with scrollbars
+ is implemented in ScrollView.
+
+ """
+
+ def __init__(self):
+ Container.__init__(self, OffsetLayout)
+
+
+class Scrollview(Container):
+
+ def __init__(self):
+ Container.__init__(self)
+
+
+class Scrolling:
+ def __init__(self):
+ self.vscroll = VScrollbar()
+ self.vscroll.add_handler('change', self._on_vscroll_change)
+ AnchorLayout.add(self, self.vscroll, halign='right', valign='fill')
+
+ self.hscroll = HScrollbar()
+ self.hscroll.add_handler('change', self._on_hscroll_change)
+ AnchorLayout.add(self, self.hscroll, halign='fill', valign='bottom')
+
+ def on_resize(self, ev):
+ self._update_scroll_max()
+
+ def _connect_child(self, widget):
+ widget.add_handler('sizereq', self._on_child_sizereq)
+ widget.add_handler('spotmove', self._on_child_spotmove)
+ widget.add_handler('scrollreq', self._on_child_scrollreq)
+
+ def _on_child_sizereq(self, ev):
+ self._update_scroll_max()
+
+ def _on_child_spotmove(self, ev):
+ child = ev.originator
+ # x
+ spot_x = child.x - self._inner.offset.x + child.spot.x
+ if spot_x < self.hscroll.scroll_pos:
+ self.hscroll.scroll_pos = spot_x
+ if spot_x > (self._inner.width - 1) + self.hscroll.scroll_pos:
+ self.hscroll.scroll_pos = spot_x - (self._inner.width - 1)
+ # y
+ spot_y = child.y - self._inner.offset.y + child.spot.y
+ if spot_y < self.vscroll.scroll_pos:
+ self.vscroll.scroll_pos = spot_y
+ if spot_y > (self._inner.height - 1) + self.vscroll.scroll_pos:
+ self.vscroll.scroll_pos = spot_y - (self._inner.height - 1)
+
+ def _on_child_scrollreq(self, ev):
+ new_scroll_pos = self.vscroll.scroll_pos + ev.data
+ if new_scroll_pos > self.vscroll.scroll_max:
+ self.vscroll.scroll_pos = self.vscroll.scroll_max
+ elif new_scroll_pos < 0:
+ self.vscroll.scroll_pos = 0
+ else:
+ self.vscroll.scroll_pos = new_scroll_pos
+
+ def _on_vscroll_change(self, ev):
+ self._inner.offset.y = - self.vscroll.scroll_pos
+
+ def _on_hscroll_change(self, ev):
+ self._inner.offset.x = - self.hscroll.scroll_pos
+
+ def _update_scroll_max(self):
+ max_width = 0
+ max_height = 0
+ for child in self._inner.children:
+ posx, posy = child.hint_value('position')
+ child_width = posx + child.sizereq.w
+ if child_width > max_width:
+ max_width = child_width
+ child_height = posy + child.sizereq.h
+ if child_height > max_height:
+ max_height = child_height
+ max_width += 1
+ self.hscroll.scroll_max = max_width - self._inner.width
+ self.vscroll.scroll_max = max_height - self._inner.height
+ hscroll_hide = max_width < self._inner.width
+ vscroll_hide = max_height < self._inner.height
+ self._toggle_scrollers(hscroll_hide, vscroll_hide)
+
+ def _toggle_scrollers(self, hscroll_hide, vscroll_hide):
+ if hscroll_hide:
+ self.hscroll.hide()
+ else:
+ self.hscroll.show()
+ if vscroll_hide:
+ self.vscroll.hide()
+ else:
+ self.vscroll.show()
+ # self._inner.need_resize()
+
+
+class ScrollView(OffsetView, Scrolling):
+ """Scrolling view
+
+ Shows scrollbars when needed.
+ Scrolling area is determined according to child widget's size request.
+
+ """
+
+ def __init__(self):
+ OffsetView.__init__(self)
+ Scrolling.__init__(self)
+
+ def add(self, widget, **kwargs):
+ OffsetView.add(self, widget, **kwargs)
+ self._connect_child(widget)
+
+ def _toggle_scrollers(self, hscroll_hide, vscroll_hide):
+ bpad = int(not hscroll_hide)
+ self.vscroll.update_hint('margin', b=bpad)
+ rpad = int(not vscroll_hide)
+ self.hscroll.update_hint('margin', r=rpad)
+ self._inner.update_hint('margin', b=bpad, r=rpad)
+ Scrolling._toggle_scrollers(self, hscroll_hide, vscroll_hide)
+