|         |      1 from tuikit.window import Window | 
|         |      2 from tuikit.layout import OffsetLayout, AnchorLayout | 
|         |      3 from tuikit.scrollbar import VScrollbar, HScrollbar | 
|         |      4 from tuikit.common import Borders | 
|         |      5  | 
|         |      6  | 
|         |      7 class ScrollWindow(Window): | 
|         |      8     def __init__(self): | 
|         |      9         Window.__init__(self, inner_layout=OffsetLayout) | 
|         |     10  | 
|         |     11         self.vscroll = VScrollbar() | 
|         |     12         self.vscroll.add_handler('change', self._on_vscroll_change) | 
|         |     13         AnchorLayout.add(self, self.vscroll, halign='right', valign='fill', margin=Borders(t=1, b=1)) | 
|         |     14  | 
|         |     15         self.hscroll = HScrollbar() | 
|         |     16         self.hscroll.add_handler('change', self._on_hscroll_change) | 
|         |     17         AnchorLayout.add(self, self.hscroll, halign='fill', valign='bottom', margin=Borders(l=1, r=2)) | 
|         |     18  | 
|         |     19     def add(self, widget, **kwargs): | 
|         |     20         Window.add(self, widget, **kwargs) | 
|         |     21         widget.add_handler('sizereq', self._on_child_sizereq) | 
|         |     22         widget.add_handler('spotmove', self._on_child_spotmove) | 
|         |     23         widget.add_handler('scrollreq', self._on_child_scrollreq) | 
|         |     24  | 
|         |     25     def on_resize(self, ev): | 
|         |     26         self._update_scroll_max() | 
|         |     27  | 
|         |     28     def _on_child_sizereq(self, ev): | 
|         |     29         self._update_scroll_max() | 
|         |     30  | 
|         |     31     def _on_vscroll_change(self, ev): | 
|         |     32         self._inner.offset.y = - self.vscroll.scroll_pos | 
|         |     33  | 
|         |     34     def _on_hscroll_change(self, ev): | 
|         |     35         self._inner.offset.x = - self.hscroll.scroll_pos | 
|         |     36  | 
|         |     37     def _on_child_spotmove(self, ev): | 
|         |     38         child = ev.originator | 
|         |     39         # x | 
|         |     40         spot_x = child.x - self._inner.offset.x + child.spot.x | 
|         |     41         if spot_x < self.hscroll.scroll_pos: | 
|         |     42             self.hscroll.scroll_pos = spot_x | 
|         |     43         if spot_x > (self._inner.width - 1) + self.hscroll.scroll_pos: | 
|         |     44             self.hscroll.scroll_pos = spot_x - (self._inner.width - 1) | 
|         |     45         # y | 
|         |     46         spot_y = child.y - self._inner.offset.y + child.spot.y | 
|         |     47         if spot_y < self.vscroll.scroll_pos: | 
|         |     48             self.vscroll.scroll_pos = spot_y | 
|         |     49         if spot_y > (self._inner.height - 1) + self.vscroll.scroll_pos: | 
|         |     50             self.vscroll.scroll_pos = spot_y - (self._inner.height - 1) | 
|         |     51  | 
|         |     52     def _on_child_scrollreq(self, ev): | 
|         |     53         new_scroll_pos = self.vscroll.scroll_pos + ev.data | 
|         |     54         if new_scroll_pos > self.vscroll.scroll_max: | 
|         |     55             self.vscroll.scroll_pos = self.vscroll.scroll_max | 
|         |     56         elif new_scroll_pos < 0: | 
|         |     57             self.vscroll.scroll_pos = 0 | 
|         |     58         else: | 
|         |     59             self.vscroll.scroll_pos = new_scroll_pos | 
|         |     60  | 
|         |     61     def _update_scroll_max(self): | 
|         |     62         max_width = 0 | 
|         |     63         max_height = 0 | 
|         |     64         for child in self._inner.children: | 
|         |     65             child_width = child.x - self._inner.offset.x + child.sizereq.w | 
|         |     66             if child_width > max_width: | 
|         |     67                 max_width = child_width | 
|         |     68             child_height = child.y - self._inner.offset.y + child.sizereq.h | 
|         |     69             if child_height > max_height: | 
|         |     70                 max_height = child_height | 
|         |     71         max_width += 1 | 
|         |     72         if max_width < self._inner.width: | 
|         |     73             self.hscroll.hide() | 
|         |     74         else: | 
|         |     75             self.hscroll.scroll_max = max_width - self._inner.width | 
|         |     76             self.hscroll.show() | 
|         |     77         if max_height < self._inner.height: | 
|         |     78             self.vscroll.hide() | 
|         |     79         else: | 
|         |     80             self.vscroll.scroll_max = max_height - self._inner.height | 
|         |     81             self.vscroll.show() | 
|         |     82  |