|
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 |