From 9e6fc6c89965973f60a3d7565aec53649d31eefc Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 24 Mar 2003 19:48:42 +0000 Subject: [PATCH] Added wxScrolledPanel from Wil Sadkin git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@19768 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/CHANGES.txt | 7 ++ wxPython/demo/Main.py | 3 +- wxPython/demo/ScrolledPanel.py | 97 --------------------- wxPython/demo/wxScrolledPanel.py | 112 +++++++++++++++++++++++++ wxPython/wxPython/lib/scrolledpanel.py | 85 +++++++++++++++++++ 5 files changed, 206 insertions(+), 98 deletions(-) delete mode 100644 wxPython/demo/ScrolledPanel.py create mode 100644 wxPython/demo/wxScrolledPanel.py create mode 100644 wxPython/wxPython/lib/scrolledpanel.py diff --git a/wxPython/CHANGES.txt b/wxPython/CHANGES.txt index 8886bb0bfe..1f94276ec2 100644 --- a/wxPython/CHANGES.txt +++ b/wxPython/CHANGES.txt @@ -2,6 +2,13 @@ CHANGES.txt for wxPython ---------------------------------------------------------------------- +????? +------- + +Added wxScrolledPanel from Wil Sadkin + + + 2.4.0.7 ------- Gave up on generating a warning upon the use of the old true/false or diff --git a/wxPython/demo/Main.py b/wxPython/demo/Main.py index 092e776b87..40f9425b84 100644 --- a/wxPython/demo/Main.py +++ b/wxPython/demo/Main.py @@ -28,6 +28,7 @@ _treeList = [ ('Recent Additions', [ 'wxIntCtrl', 'wxPyColourChooser', + 'wxScrolledPanel', ]), # managed windows == things with a (optional) caption you can close @@ -134,9 +135,9 @@ _treeList = [ 'LayoutAnchors', 'Layoutf', 'RowColSizer', - 'ScrolledPanel', 'Sizers', 'wxLayoutConstraints', + 'wxScrolledPanel', 'wxXmlResource', 'wxXmlResourceHandler', ]), diff --git a/wxPython/demo/ScrolledPanel.py b/wxPython/demo/ScrolledPanel.py deleted file mode 100644 index 13b5e693a5..0000000000 --- a/wxPython/demo/ScrolledPanel.py +++ /dev/null @@ -1,97 +0,0 @@ - -from wxPython.wx import * - -#---------------------------------------------------------------------- - -text = "one two buckle my shoe three four shut the door five six pick up sticks seven eight lay them straight nine ten big fat hen" - - -class ScrolledPanel(wxScrolledWindow): - def __init__(self, parent, log): - self.log = log - wxScrolledWindow.__init__(self, parent, -1, - style = wxTAB_TRAVERSAL) - - box = wxBoxSizer(wxVERTICAL) - box.Add(wxStaticText(self, -1, - "This sample shows how to make a scrollable data entry \n" - "form by using a wxSizer in a wxScrolledWindow."), - 0, wxCENTER|wxALL, 5) - box.Add(wxStaticLine(self, -1), 0, wxEXPAND|wxALL, 5) - - fgs = wxFlexGridSizer(cols=2, vgap=4, hgap=4) - fgs.AddGrowableCol(1) - - # Add some spacers - fgs.Add(75, 10) - fgs.Add(150, 10) - - for word in text.split(): - label = wxStaticText(self, -1, word+":") - tc = wxTextCtrl(self, -1, word) - fgs.Add(label, flag=wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL) - fgs.Add(tc, flag=wxEXPAND) - - box.Add(fgs, 1) - box.Add(10, 40) # some more empty space at the bottom - self.SetSizer(box) - - - # The following is all that is needed to integrate the sizer and the - # scrolled window. In this case we will only support vertical scrolling. - self.EnableScrolling(False, True) - self.SetScrollRate(0, 20) - box.SetVirtualSizeHints(self) - EVT_CHILD_FOCUS(self, self.OnChildFocus) - - wxCallAfter(self.Scroll, 0, 0) # scroll back to top after initial events - - - def OnChildFocus(self, evt): - # If the child window that gets the focus is not visible, - # this handler will try to scroll enough to see it. If you - # need to handle horizontal auto-scrolling too then this will - # need adapted. - evt.Skip() - child = evt.GetWindow() - - sppu_y = self.GetScrollPixelsPerUnit()[1] - vs_y = self.GetViewStart()[1] - cpos = child.GetPosition() - csz = child.GetSize() - - # is it above the top? - if cpos.y < 0: - new_vs = cpos.y / sppu_y - self.Scroll(-1, new_vs) - - # is it below the bottom ? - if cpos.y + csz.height > self.GetClientSize().height: - diff = (cpos.y + csz.height - self.GetClientSize().height) / sppu_y - self.Scroll(-1, vs_y + diff + 1) - - -#---------------------------------------------------------------------- - - -def runTest(frame, nb, log): - win = ScrolledPanel(nb, log) - return win - -#---------------------------------------------------------------------- - - - -overview = """ -This sample shows how to make a scrollable data entry form by -using a wxSizer in a wxScrolledWindow. - -""" - - - -if __name__ == '__main__': - import sys,os - import run - run.main(['', os.path.basename(sys.argv[0])]) - diff --git a/wxPython/demo/wxScrolledPanel.py b/wxPython/demo/wxScrolledPanel.py new file mode 100644 index 0000000000..079f878dc6 --- /dev/null +++ b/wxPython/demo/wxScrolledPanel.py @@ -0,0 +1,112 @@ +from wxPython.wx import * +from wxPython.lib.scrolledpanel import wxScrolledPanel + +#---------------------------------------------------------------------- + +text = "one two buckle my shoe three four shut the door five six pick up sticks seven eight lay them straight nine ten big fat hen" + + +class TestPanel(wxScrolledPanel): + def __init__(self, parent, log): + self.log = log + wxScrolledPanel.__init__(self, parent, -1) + + vbox = wxBoxSizer(wxVERTICAL) + desc = wxStaticText(self, -1, + "wxScrolledPanel extends wxScrolledWindow, adding all " + "the necessary bits to set up scroll handling for you.\n\n" + "Here are three fixed size examples of its use, and the " + "mail demo panel is also using it." + ) + desc.SetForegroundColour("Blue") + vbox.Add(desc, 0, wxALIGN_LEFT|wxALL, 5) + vbox.Add(wxStaticLine(self, -1), 0, wxEXPAND|wxALL, 5) + vbox.AddSpacer(20,20) + + words = text.split() + + panel1 = wxScrolledPanel(self, -1, size=(120,300), + style = wxTAB_TRAVERSAL|wxSUNKEN_BORDER ) + fgs1 = wxFlexGridSizer(cols=2, vgap=4, hgap=4) + + for word in words: + label = wxStaticText(panel1, -1, word+":") + tc = wxTextCtrl(panel1, -1, word, size=(50,-1)) + fgs1.Add(label, flag=wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL) + fgs1.Add(tc, flag=wxEXPAND|wxRIGHT, border=25) + + panel1.SetSizer( fgs1 ) + panel1.SetAutoLayout(1) + panel1.SetupScrolling( scroll_x=False ) + + panel2 = wxScrolledPanel(self, -1, size=(350, 40), + style = wxTAB_TRAVERSAL|wxSUNKEN_BORDER) + panel3 = wxScrolledPanel(self, -1, size=(200,100), + style = wxTAB_TRAVERSAL|wxSUNKEN_BORDER) + + fgs2 = wxFlexGridSizer(cols=25, vgap=4, hgap=4) + fgs3 = wxFlexGridSizer(cols=5, vgap=4, hgap=4) + + for i in range(len(words)): + word = words[i] + if i % 5 != 4: + label2 = wxStaticText(panel2, -1, word) + fgs2.Add(label2, flag=wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL) + label3 = wxStaticText(panel3, -1, word) + fgs3.Add(label3, flag=wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL) + else: + tc2 = wxTextCtrl(panel2, -1, word, size=(50,-1)) + fgs2.Add(tc2, flag=wxLEFT, border=5) + tc3 = wxTextCtrl(panel3, -1, word ) + fgs3.Add(tc3, flag=wxLEFT, border=5) + + panel2.SetSizer( fgs2 ) + panel2.SetAutoLayout(1) + panel2.SetupScrolling(scroll_y = False) + + panel3.SetSizer( fgs3 ) + panel3.SetAutoLayout(1) + panel3.SetupScrolling() + + hbox = wxBoxSizer(wxHORIZONTAL) + hbox.AddSpacer(20,20) + hbox.Add(panel1, 0) + hbox.AddSpacer(40, 10) + + vbox2 = wxBoxSizer(wxVERTICAL) + vbox2.Add(panel2, 0) + vbox2.AddSpacer(20, 50) + + vbox2.Add(panel3, 0) + vbox2.AddSpacer(20, 10) + hbox.Add(vbox2) + + vbox.AddSizer(hbox, 0) + self.SetSizer(vbox) + self.SetAutoLayout(1) + self.SetupScrolling() + + +#---------------------------------------------------------------------- + + +def runTest(frame, nb, log): + win = TestPanel(nb, log) + return win + +#---------------------------------------------------------------------- + + + +overview = """ +wxScrolledPanel fills a "hole" in the implementation of wxScrolledWindow, +providing automatic scrollbar and scrolling behavior and the tab traversal +mangement that wxScrolledWindow lacks. + +""" + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) diff --git a/wxPython/wxPython/lib/scrolledpanel.py b/wxPython/wxPython/lib/scrolledpanel.py new file mode 100644 index 0000000000..2ec3c47e6b --- /dev/null +++ b/wxPython/wxPython/lib/scrolledpanel.py @@ -0,0 +1,85 @@ +#---------------------------------------------------------------------------- +# Name: wxScrolledPanel.py +# Author: Will Sadkin +# Created: 03/21/2003 +# Copyright: (c) 2003 by Will Sadkin +# RCS-ID: $Id$ +# License: wxWindows license +#---------------------------------------------------------------------------- +# + +from wxPython.wx import * + + +class wxScrolledPanel( wxScrolledWindow ): + """ +wxScrolledPanel fills a "hole" in the implementation of wxScrolledWindow, +providing automatic scrollbar and scrolling behavior and the tab traversal +mangement that wxScrolledWindow lacks. This code was based on the original +demo code showing how to do this, but is now available for general use +as a proper class (and the demo is now converted to just use it.) +""" + def __init__(self, parent, id=-1, + pos = wxDefaultPosition, size = wxDefaultSize, + style = wxTAB_TRAVERSAL, name = "scrolledpanel"): + + wxScrolledWindow.__init__(self, parent, -1, + pos=pos, size=size, + style=style, name=name) + + + def SetupScrolling(self, scroll_x=True, scroll_y=True, rate_x=1, rate_y=1): + """ + This function sets up the event handling necessary to handle + scrolling properly. It should be called within the __init__ + function of any class that is derived from wxScrolledPanel, + once the controls on the panel have been constructed and + thus the size of the scrolling area can be determined. + + """ + # The following is all that is needed to integrate the sizer and the + # scrolled window. + if not scroll_x: rate_x = 0 + if not scroll_y: rate_y = 0 + + self.SetScrollRate(rate_x, rate_y) + + self.GetSizer().SetVirtualSizeHints(self) + EVT_CHILD_FOCUS(self, self.OnChildFocus) + wxCallAfter(self.Scroll, 0, 0) # scroll back to top after initial events + + + def OnChildFocus(self, evt): + # If the child window that gets the focus is not visible, + # this handler will try to scroll enough to see it. + evt.Skip() + child = evt.GetWindow() + + sppu_x, sppu_y = self.GetScrollPixelsPerUnit() + vs_x, vs_y = self.GetViewStart() + cpos = child.GetPosition() + csz = child.GetSize() + new_vs_x, new_vs_y = -1, -1 + + # is it before the left edge? + if cpos.x < 0 and sppu_x > 0: + new_vs_x = cpos.x / sppu_x + + # is it above the top? + if cpos.y < 0 and sppu_y > 0: + new_vs_y = cpos.y / sppu_y + + + # is it past the right edge ? + if cpos.x + csz.width > self.GetClientSize().width and sppu_x > 0: + diff = (cpos.x + csz.width - self.GetClientSize().width) / sppu_x + new_vs_x = vs_x + diff + 1 + + # is it below the bottom ? + if cpos.y + csz.height > self.GetClientSize().height and sppu_y > 0: + diff = (cpos.y + csz.height - self.GetClientSize().height) / sppu_y + new_vs_y = vs_y + diff + 1 + + # if we need to adjust + if new_vs_x != -1 or new_vs_y != -1: + self.Scroll(new_vs_x, new_vs_y)