ScrolledWindow woes

What I want to do is have a ScrolledWindow that only draws its active area. I imagined that it would work like this:

* On a SCROLLWIN_LINEUP/_LINEDOWN event, the bar would be updated, and OnPaint() would be called.
* On a SCROLLWIN_THUMBRELEASE event, OnPaint would be called.
* OnPaint would determine where within the logical window we actually are, and paint the results.

Here was the ill-fated code:

import wx

WIDGET_SIZE = 50
app = wx.PySimpleApp()

class Widget(wx.StaticText):

    def __init__(self, parent, label="empty widget",
                 size=(WIDGET_SIZE,WIDGET_SIZE),
                 pos=wx.DefaultPosition,
                 style=wx.ALIGN_CENTRE |wx.ST_NO_AUTORESIZE

wx.SIMPLE_BORDER):

        wx.StaticText.__init__(self,parent,label=label,size=size,pos=pos,
                               style=style)

def Scroll(event):
    #print "Scrolling!", app.w.GetScrollPos(wx.HORIZONTAL)
    #print dir(event)
    OnPaint()
   def ScrollLeft(event):
    x = app.w.GetScrollPos(wx.HORIZONTAL)
    x = max(x-5,0)
    app.w.SetScrollPos(wx.HORIZONTAL,x)
    OnPaint()

def ScrollRight(event):
    x = app.w.GetScrollPos(wx.HORIZONTAL)
    x = min(x+5,app.w.GetScrollRange(wx.HORIZONTAL))
    app.w.SetScrollPos(wx.HORIZONTAL,x)
    OnPaint()

def OnPaint():
    #print "paint!"
    x = app.w.GetScrollPos(wx.HORIZONTAL)
    width,_ = app.w.GetSize()
    for w in range(x,x+width,WIDGET_SIZE):
        x,y = app.w.CalcUnscrolledPosition(w,0)
        widget = Widget(app.w,label="%d" % (w/WIDGET_SIZE), pos=(x,y))
        print w,0,x,y # (1)
    print "----"

app.f = wx.Frame(None, id=wx.ID_ANY, title="ScrollBar Test")
app.w = wx.ScrolledWindow(app.f,id=wx.ID_ANY,style=wx.HSCROLL,size=(200,50))
app.w.SetScrollbars(20,0,300,0)

app.w.Bind(wx.EVT_SCROLLWIN_THUMBRELEASE,Scroll)
app.w.Bind(wx.EVT_SCROLLWIN_LINEUP, ScrollLeft) # left scroll arrow
app.w.Bind(wx.EVT_SCROLLWIN_LINEDOWN, ScrollRight) # right scroll arrow
app.f.Fit()
app.f.Show()
#app.w.SetScrollPos(wx.HORIZONTAL,250) # must occur after Show()
OnPaint()
app.MainLoop()

The output of (1) in OnPrint() was as follows for a typical run:
x y x y
0 0 0 0
50 0 50 0
100 0 100 0
150 0 150 0

···

----
20 0 420 0 # << after scrolling with thumb
70 0 470 0
120 0 520 0
170 0 570 0
----
0 0 0 0 # thumb-ed back to home
50 0 50 0
100 0 100 0
150 0 150 0
----
16 0 336 0 # more thumb scrolling
66 0 386 0
116 0 436 0
166 0 486 0
----
4 0 84 0
54 0 134 0
104 0 184 0
154 0 234 0
----
9 0 89 0
59 0 139 0
109 0 189 0
159 0 239 0
----
4 0 84 0 << left scroll arrow used
54 0 134 0
104 0 184 0
154 0 234 0
----
0 0 80 0 << left scroll arrow-ed back to home.
50 0 130 0
100 0 180 0
150 0 230 0

Apparently, there is no simple rule to correlate the results of GetScrollPos() and CalcUnscrolledPosition()??!!!

Help?

Thanks,
Jeff Cagle