import wx
import thread
import time

_EVT_SPRING_DRAGGED = wx.NewEventType()
EVT_SPRING_DRAGGED = wx.PyEventBinder(_EVT_SPRING_DRAGGED, 1)

class SimplePanel(wx.Panel):
    def __init__(self, parent, dir=wx.VERTICAL):
        wx.Panel.__init__(self, parent, -1)
        self.sizer = wx.BoxSizer(dir)
        self.SetSizer(self.sizer)
        
    def Add(self, *args, **kargs):
        self.sizer.Add(*args, **kargs)
        
    def ShowComp(self, *args, **kargs):
        self.sizer.Show(*args, **kargs)

class SpringDragEvent(wx.PyCommandEvent):
    def __init__(self, id, value=0):
        wx.PyCommandEvent.__init__(self, _EVT_SPRING_DRAGGED, id)
        self.val = value

    def SetValue(self, val):
        self.val = val

    def GetValue(self):
        return self.val

class SpringSlider(wx.Slider):
    def __init__(self, parent, style, value=10, delay=.02):
        self.value = value
        self.delay = delay
        self.adjustedValue = 0 
        self.zerosent = False
        wx.Slider.__init__(self, parent, wx.NewId(), 0, -100, 100, style=style)
        self.Bind(wx.EVT_SCROLL, self.Reset) 
        self.Bind(wx.EVT_SCROLL_THUMBTRACK, self._OnDrag)
        thread.start_new_thread(self._evtGen, ())
        
    def _evtGen(self):
        try:
            while 1:
                if self.adjustedValue != 0:
                    self.GetEventHandler().ProcessEvent(SpringDragEvent(self.GetId(), self.adjustedValue))
                    time.sleep(self.delay)
                elif not self.zerosent:
                    self.zerosent = True
                    self.GetEventHandler().ProcessEvent(SpringDragEvent(self.GetId()))
                    time.sleep(self.delay)
                    
        except:
            thread.exit()

    def Reset(self, evt):
        self.SetValue(0)
        self.adjustedValue = 0
        evt.Skip()
        
    def _OnDrag(self, evt):
        self.adjustedValue = (self.GetValue()*self.value)/100
        self.zerosent = self.adjustedValue == 0

if __name__ == '__main__':
    def e(evt):
        print "EVT_SPRING_DRAGGED Event Handler, value=", evt.GetValue()
    
    app = wx.App(0)
    frame = wx.Frame(None, title="testSlider")
    frame.Bind(EVT_SPRING_DRAGGED, e)
    sizer = wx.BoxSizer(wx.VERTICAL)
    p = SimplePanel(frame)
    p.Add(SimplePanel(p), 1, wx.EXPAND)
    p.Add(SpringSlider(p, style=wx.HORIZONTAL), 0, wx.EXPAND)
    sizer.Add(p, 1, wx.EXPAND)
    frame.SetSizer(sizer)
    frame.Show()
    app.MainLoop()