tuikit/scrollwindow.py
changeset 74 23767a33a781
child 75 2430c643838a
equal deleted inserted replaced
73:85a282b5e4fc 74:23767a33a781
       
     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