3

I wish to emulate or most media players' sliders - where clicking anywhere on the slider widget skips the video to that position. How can I get the slider's value under the mouse click and set the value to that?

By default, when clicked on the slider, it only scrolls by a Pagesize at a time, not scrolls to the position user clicked.

halfer
  • 19,824
  • 17
  • 99
  • 186
zJay
  • 2,889
  • 3
  • 22
  • 19

2 Answers2

4

The following code works in Windows XP, however I have no idea how to get the GAP constant in another way than by experimenting. The GAP value indicates what is the empty space between edge of the widget and actual start of the drawn slider.

import wx

GAP = 12

class VideoSlider(wx.Slider):
    def __init__(self, gap, *args, **kwargs):
        wx.Slider.__init__(self, *args, **kwargs)
        self.gap = gap
        self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)

    def linapp(self, x1, x2, y1, y2, x):
        return (float(x - x1) / (x2 - x1)) * (y2 - y1) + y1

    def OnClick(self, e):
        click_min = self.gap
        click_max = self.GetSize()[0] - self.gap
        click_position = e.GetX()
        result_min = self.GetMin()
        result_max = self.GetMax()
        if click_position > click_min and click_position < click_max:
            result = self.linapp(click_min, click_max, 
                                 result_min, result_max, 
                                 click_position)
        elif click_position <= click_min:
            result = result_min
        else:
            result = result_max
        self.SetValue(result)
        e.Skip()

class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = wx.Panel(self)
        self.slider = VideoSlider(parent=self.panel, size=(300, -1), gap=GAP)
        self.slider.Bind(wx.EVT_SLIDER, self.OnSlider)

        self.sizer = wx.BoxSizer()
        self.sizer.Add(self.slider)

        self.panel.SetSizerAndFit(self.sizer)  
        self.Show()     

    def OnSlider(self, e):
        print(self.slider.GetValue())    

app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
Fenikso
  • 9,251
  • 5
  • 44
  • 72
  • Thanks, I used this code and it worked (Windows 7), with a modification - the gaps from left and right were not identical, so I had to specify `LEFT_GAP` and `RIGHT_GAP` separately. – shiftyscales Feb 02 '16 at 15:16
0

Create a new control by inheritance from the slider. The only change from the base slider control is that you override the method that handles mouse click events, Your method needs to do two things: call the routine that you use to 'skip the video to the mouse click' and call the base slider control mouse click handler so it can look after the visual feedback details.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103