Keyframe selector widget testery.py (5680B)
1 import wx 2 3 4 class Timeline(wx.Panel): 5 def __init__(self, parent, id, max_ = 300): 6 wx.Panel.__init__(self, parent, id, style = wx.NO_BORDER) 7 self.SetSize((0, 80)) 8 self.max = max_ 9 self.curframe = 0 10 self.sidepadding = 5 11 self.drawpos = (0, 0) 12 self.size = (0, 0) 13 self.mousetolerance = 5 14 self.dragging = False 15 self.pointerimg = wx.Image("framepointer.png", wx.BITMAP_TYPE_PNG) 16 self.pointerbmp = wx.BitmapFromImage(self.pointerimg) 17 self.keypointerimg = wx.Image("keyframepointer.png", wx.BITMAP_TYPE_PNG) 18 self.keypointerbmp = wx.BitmapFromImage(self.keypointerimg) 19 self.keyedframes = [0, 10, 25, 27, 49, 68, 98, 106, 132] 20 21 self.font = wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, 22 wx.FONTWEIGHT_NORMAL, False) 23 24 self.Bind(wx.EVT_PAINT, self.OnPaint) 25 self.Bind(wx.EVT_LEFT_DOWN, self.OnClick) 26 self.Bind(wx.EVT_LEFT_UP, self.OnRelease) 27 self.Bind(wx.EVT_MOTION, self.OnMouseMotion) 28 29 def Update(self, event): 30 self.curframe += 1 31 32 def SetMax(self, val): 33 self.max = val 34 35 def SetCurframe(self, val): 36 self.curframe = val 37 38 def OnClick(self, event): 39 p = event.GetPosition() 40 41 foundFrameTarget = False 42 for frame in self.keyedframes: 43 drawpos = (self.drawpos[0] + int((float(frame) / float(self.max)) * float(self.size[0])), self.drawpos[1] - (self.keypointerbmp.GetHeight())) 44 if p[1] > (drawpos[1]) and \ 45 p[1] < (drawpos[1]+ self.keypointerimg.GetHeight()) and \ 46 p[0] > (drawpos[0]) and \ 47 p[0] < (drawpos[0] + self.keypointerbmp.GetWidth()): 48 self.curframe = frame 49 foundFrameTarget = True 50 51 if foundFrameTarget: 52 self.SendSliderEvent() 53 54 if p[1] > (self.drawpos[1] - self.mousetolerance) and \ 55 p[1] < (self.drawpos[1] + self.size[1] + self.pointerbmp.GetHeight()) and \ 56 p[0] > (self.drawpos[0] - self.mousetolerance) and \ 57 p[0] < (self.drawpos[0] + self.size[0] + self.mousetolerance): 58 self.dragging = True 59 self.CaptureMouse() 60 self.OnMouseMotion(event) 61 62 def OnRelease(self, event): 63 if self.HasCapture(): 64 self.ReleaseMouse() 65 self.dragging = False 66 67 def OnMouseMotion(self, event): 68 if self.dragging: 69 posx = event.GetPosition()[0] - self.drawpos[0] 70 if posx >= self.size[0]: 71 self.curframe = self.max 72 elif posx <= 0: 73 self.curframe = 0 74 else: 75 self.curframe = int(float(posx) / float(self.size[0]) * self.max) 76 self.SendSliderEvent() 77 78 def SendSliderEvent(self): 79 event = wx.CommandEvent(wx.EVT_SLIDER.typeId, self.GetId()) 80 event.SetInt(self.curframe) 81 self.GetEventHandler().ProcessEvent(event) 82 83 def OnPaint(self, event): 84 self.DoPaint() 85 86 def DoPaint(self): 87 windc = wx.ClientDC(self) 88 dc = wx.BufferedDC(windc) 89 w, h = self.GetSize() 90 91 # Background fill 92 #dc.Clear() 93 dc.SetBrush(windc.GetBackground()) 94 dc.DrawRectangle(0, 0, w, h) 95 96 # Slider bar pos/size calculations 97 self.drawpos = (self.sidepadding, self.keypointerbmp.GetHeight() + self.sidepadding) 98 self.size = (w - (self.sidepadding * 2), 4) 99 100 # Slider bar 101 dc.SetPen(wx.Pen('#000000')) 102 dc.SetBrush(wx.Brush('#FFFFFF')) 103 dc.DrawRectangle(self.drawpos[0], self.drawpos[1], self.size[0], self.size[1]) 104 105 # Curframe pointer 106 pointerpos = ((self.drawpos[0] + int((float(self.size[0]) * (float(self.curframe) / float(self.max))))) - (self.pointerbmp.GetWidth() / 2), self.drawpos[1]) 107 #dc.DrawRectangle(pointerpos[0], pointerpos[1], self.pointerbmp.GetWidth(), self.pointerbmp.GetHeight()) 108 dc.DrawBitmap(self.pointerbmp, pointerpos[0], pointerpos[1]) 109 110 # Keyed frame pointers 111 for frame in self.keyedframes: 112 drawpos = (self.drawpos[0] + int((float(frame) / float(self.max)) * float(self.size[0])), self.drawpos[1] - (self.keypointerbmp.GetHeight())) 113 dc.DrawBitmap(self.keypointerbmp, drawpos[0], drawpos[1]) 114 115 # Current frame text 116 #dc.SetFont(self.font) 117 string = "Current frame: %i" % self.curframe 118 stringwidth, stringheight = dc.GetTextExtent(string) 119 dc.DrawText(string, w - (self.sidepadding + stringwidth), h - (self.sidepadding + stringheight)) 120 121 122 class Frame(wx.Frame): 123 def __init__(self, parent): 124 wx.Frame.__init__(self, parent, -1) 125 126 self.panel = wx.Panel(self, -1) 127 self.timeline = Timeline(self.panel, -1) 128 129 self.sizer = wx.BoxSizer(wx.VERTICAL) 130 self.sizer.Add(self.timeline, 0, flag = wx.EXPAND) 131 132 self.panel.SetSizer(self.sizer) 133 self.Layout() 134 self.timeline.SetMax(150) 135 136 self.Bind(wx.EVT_CLOSE, self.Exit) 137 self.Bind(wx.EVT_SLIDER, self.Slider) 138 139 def Exit(self, event): 140 self.timeline.Destroy() 141 self.Destroy() 142 143 def Slider(self, event): 144 pass#print "Frame = %i" % event.GetInt()) 145 146 147 if __name__ == "__main__": 148 app = wx.PySimpleApp() 149 frame = Frame(None) 150 frame.SetTitle("ExeSoft Obsidian - timeline widget test") 151 frame.Show() 152 app.SetTopWindow(frame) 153 app.MainLoop()