wxpython custom control and sizers

hello,

just for my interest i try to develop a custom wxpython control that support
sizers. but i have big problems. i don't know how to build the DoGetBestSize-
and/or OnSize-event-function.
what i have to do, that my floatspin-control behaves like the normal
wx.spinctrl-control? is there a detailed, central documentation, beside the
wxpywiki "CreatingCustomControls" or the general wxpython docs? are there any
ideas?
please ... please help me or i go mad :o)

thnx
daniel

<<< code >>>

import wx

···

#------------------------------------------------------------------------------
# FloatSpin
# This is the main class implementation.
#------------------------------------------------------------------------------

class FloatSpin(wx.PyControl):

  def __init__(self, parent, idf=wx.NewId(), pos=wx.DefaultPosition,
               size=wx.DefaultSize, style=0, pval=0.0, pmin=None, pmax=None,
               pinc=1.0, pdig=3, name="FloatSpin" ):
    self._parm_val = max(pval, pmin)
    self._parm_min = pmin
    self._parm_max = pmax
    self._parm_inc = pinc
    self._parm_dig = pdig
    self._parm_sze = size

    wx.PyControl.__init__ ( self, parent, idf, pos, size,
                   wx.NO_BORDER|wx.NO_FULL_REPAINT_ON_RESIZE|wx.CLIP_CHILDREN,
                   wx.DefaultValidator, name )
    self.SetLabel(name)
    self._text = wx.TextCtrl ( self, wx.NewId(), pos=pos,
                   size=wx.Size(size.GetWidth()-16, size.GetHeight()),
                   style=wx.TE_NOHIDESEL|wx.TE_PROCESS_ENTER,
                   value="%0.*f"%(self._parm_dig,self._parm_val),
                   validator=wx.DefaultValidator,
                   name=name+"_TextCtrl" )
    self._spin = wx.SpinButton ( self, wx.NewId(), pos=pos,
                   size=wx.Size(16, size.GetHeight()),
                   style=wx.SP_ARROW_KEYS|wx.SP_VERTICAL,
                   name=name+"_SpinButton" )
    self._szer = wx.BoxSizer(wx.HORIZONTAL)
    self._szer.Add(self._text)
    self._szer.Add(self._spin)
# self._szer.Add(self._text, 0, wx.ALL|wx.EXPAND, 1)
# self._szer.Add(self._spin, 1, wx.ALL|wx.EXPAND, 1)
    self.SetSizer(self._szer)
    self._szer.Layout()

    self.Bind (wx.EVT_SIZE, self.evt_size,
                    id=self.GetId() )
    self._text.Bind(wx.EVT_TEXT_ENTER, self.evt_text_enter,
                    id=self._text.GetId())
    self._text.Bind(wx.EVT_SET_FOCUS, self.evt_text_focusset,
                    id=self._text.GetId())
    self._text.Bind(wx.EVT_KILL_FOCUS, self.evt_text_focuskill,
                    id=self._text.GetId())
    self._spin.Bind(wx.EVT_SPIN_UP, self.evt_spin_up,
                    id=self._spin.GetId())
    self._spin.Bind(wx.EVT_SPIN_DOWN, self.evt_spin_down,
                    id=self._spin.GetId())

    return

  def evt_text_enter(self, event):
    self._parm_val = float(event.GetString())
    if self._parm_val > self._parm_max: self._parm_val = self._parm_max
    elif self._parm_val < self._parm_min: self._parm_val = self._parm_min
    self._text.ChangeValue("%0.*f"%(self._parm_dig,self._parm_val))
    return

  def evt_text_focusset(self, event):
    if self._text: self._text.SetFocus()
    event.Skip()
    return

  def evt_text_focuskill(self, event):
    event.Skip()
    return

  def evt_spin_up(self, event):
    self._parm_val += self._parm_inc
    if self._parm_val > self._parm_max: self._parm_val = self._parm_min
    self._text.ChangeValue("%0.*f"%(self._parm_dig,self._parm_val))
    return

  def evt_spin_down(self, event):
    self._parm_val -= self._parm_inc
    if self._parm_val < self._parm_min: self._parm_val = self._parm_max
    self._text.ChangeValue("%0.*f"%(self._parm_dig,self._parm_val))
    return

  def OnDestroy(self, event):
    self._text.Destroy(); self._text = None
    self._spin.Destroy(); self._spin = None
    self = None
    return

  def DoGetBestSize(self):
    print "DoGetBestSize"
    self._parm_sze = wx.Size(self.GetContainingSizer().GetSize().GetWidth(),
                             self._parm_sze.GetHeight())
    self._text.SetSize(wx.Size(self._parm_sze.GetWidth()-16,
                               self._parm_sze.GetHeight()))
    self._spin.SetSize(wx.Size( 16,
                               self._parm_sze.GetHeight()))
# self.SetSize (wx.Size(self._parm_sze.GetWidth(),
# self._parm_sze.GetHeight()))
# self._szer.Layout()
# self.Layout()
    return self._parm_sze

  def evt_size(self, event):
    print "OnSize"
    self._parm_sze = wx.Size(self.GetContainingSizer().GetSize().GetWidth(),
                             self._parm_sze.GetHeight())
    self._text.SetSize(wx.Size(self._parm_sze.GetWidth()-16,
                               self._parm_sze.GetHeight()))
    self._spin.SetSize(wx.Size( 16,
                               self._parm_sze.GetHeight()))
# self._szer.Layout()
# self.Layout()
# self.GetContainingSizer().SetVirtualSizeHints(self)

#------------------------------------------------------------------------------
# FloatSpinDemo
# This is a demo class for represent FloatSpin class.
#------------------------------------------------------------------------------

class FloatSpinDemo(wx.Frame):
  def __init__(self, *args, **kwds):
    kwds["style"] = wx.DEFAULT_FRAME_STYLE
    wx.Frame.__init__(self, *args, **kwds)
    self.mainpanel = wx.Panel(self, -1)
    self.spinctrl = wx.SpinCtrl( self.mainpanel, -1)
    self.floatspin1 = FloatSpin ( self.mainpanel, -1, pval=0, pmax=1.0,
                                   pinc=0.01, pmin=0.5,
                                   size=wx.Size(100,22) )
# size=wx.DefaultSize )
    self.sizer = wx.BoxSizer(wx.VERTICAL)
    self.sizer.Add(self.spinctrl, 0, wx.ALL|wx.EXPAND|wx.FIXED_MINSIZE, 1)
    self.sizer.Add(self.floatspin1, 0, wx.ALL|wx.EXPAND|wx.FIXED_MINSIZE, 1)
    self.mainpanel.SetSizer(self.sizer)
    self.Layout()

if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    frame = FloatSpinDemo(None, -1, "FloatSpin Demo")
    frame.CenterOnScreen()
    app.SetTopWindow(frame)
    frame.Show()
    app.MainLoop()