]>
Commit | Line | Data |
---|---|---|
d14a1e28 RD |
1 | #---------------------------------------------------------------------------- |
2 | # Name: wxScrolledPanel.py | |
3 | # Author: Will Sadkin | |
4 | # Created: 03/21/2003 | |
5 | # Copyright: (c) 2003 by Will Sadkin | |
6 | # RCS-ID: $Id$ | |
7 | # License: wxWindows license | |
8 | #---------------------------------------------------------------------------- | |
b881fc78 RD |
9 | # 12/11/2003 - Jeff Grimmett (grimmtooth@softhome.net) |
10 | # | |
11 | # o 2.5 compatability update. | |
d14a1e28 | 12 | # |
1fded56b | 13 | |
b881fc78 | 14 | import wx |
1fded56b | 15 | |
d14a1e28 | 16 | |
b881fc78 RD |
17 | class wxScrolledPanel( wx.ScrolledWindow ): |
18 | """\ | |
d14a1e28 RD |
19 | wxScrolledPanel fills a "hole" in the implementation of wxScrolledWindow, |
20 | providing automatic scrollbar and scrolling behavior and the tab traversal | |
21 | management that wxScrolledWindow lacks. This code was based on the original | |
22 | demo code showing how to do this, but is now available for general use | |
23 | as a proper class (and the demo is now converted to just use it.) | |
24 | """ | |
25 | def __init__(self, parent, id=-1, | |
b881fc78 RD |
26 | pos = wx.DefaultPosition, size = wx.DefaultSize, |
27 | style = wx.TAB_TRAVERSAL, name = "scrolledpanel"): | |
d14a1e28 | 28 | |
b881fc78 | 29 | wx.ScrolledWindow.__init__(self, parent, -1, |
d14a1e28 RD |
30 | pos=pos, size=size, |
31 | style=style, name=name) | |
32 | ||
b881fc78 | 33 | self.Bind(wx.EVT_CHILD_FOCUS, self.OnChildFocus) |
d14a1e28 RD |
34 | |
35 | ||
36 | def SetupScrolling(self, scroll_x=True, scroll_y=True, rate_x=20, rate_y=20): | |
37 | """ | |
38 | This function sets up the event handling necessary to handle | |
39 | scrolling properly. It should be called within the __init__ | |
40 | function of any class that is derived from wxScrolledPanel, | |
41 | once the controls on the panel have been constructed and | |
42 | thus the size of the scrolling area can be determined. | |
43 | ||
44 | """ | |
45 | # The following is all that is needed to integrate the sizer and the | |
46 | # scrolled window. | |
47 | if not scroll_x: rate_x = 0 | |
48 | if not scroll_y: rate_y = 0 | |
49 | ||
50 | # Round up the virtual size to be a multiple of the scroll rate | |
51 | sizer = self.GetSizer() | |
52 | if sizer: | |
53 | w, h = sizer.GetMinSize() | |
54 | if rate_x: | |
55 | w += rate_x - (w % rate_x) | |
56 | if rate_y: | |
57 | h += rate_y - (h % rate_y) | |
58 | self.SetVirtualSize( (w, h) ) | |
59 | self.SetVirtualSizeHints( w, h ) | |
60 | ||
61 | self.SetScrollRate(rate_x, rate_y) | |
b881fc78 | 62 | wx.CallAfter(self.Scroll, 0, 0) # scroll back to top after initial events |
d14a1e28 RD |
63 | |
64 | ||
65 | def OnChildFocus(self, evt): | |
66 | # If the child window that gets the focus is not visible, | |
67 | # this handler will try to scroll enough to see it. | |
68 | evt.Skip() | |
69 | child = evt.GetWindow() | |
70 | ||
71 | sppu_x, sppu_y = self.GetScrollPixelsPerUnit() | |
72 | vs_x, vs_y = self.GetViewStart() | |
73 | cpos = child.GetPosition() | |
74 | csz = child.GetSize() | |
75 | new_vs_x, new_vs_y = -1, -1 | |
76 | ||
77 | # is it before the left edge? | |
78 | if cpos.x < 0 and sppu_x > 0: | |
79 | new_vs_x = vs_x + (cpos.x / sppu_x) | |
80 | ||
81 | # is it above the top? | |
82 | if cpos.y < 0 and sppu_y > 0: | |
83 | new_vs_y = vs_y + (cpos.y / sppu_y) | |
84 | ||
b881fc78 | 85 | clntsz = self.GetClientSize() |
d14a1e28 RD |
86 | |
87 | # is it past the right edge ? | |
b881fc78 RD |
88 | if cpos.x + csz.width > clntsz.width and sppu_x > 0: |
89 | diff = (cpos.x + csz.width - clntsz.width) / sppu_x | |
d14a1e28 RD |
90 | new_vs_x = vs_x + diff + 1 |
91 | ||
92 | # is it below the bottom ? | |
b881fc78 RD |
93 | if cpos.y + csz.height > clntsz.height and sppu_y > 0: |
94 | diff = (cpos.y + csz.height - clntsz.height) / sppu_y | |
d14a1e28 RD |
95 | new_vs_y = vs_y + diff + 1 |
96 | ||
97 | # if we need to adjust | |
98 | if new_vs_x != -1 or new_vs_y != -1: | |
99 | self.Scroll(new_vs_x, new_vs_y) |