--- /dev/null
+
+import wx
+from wx.lib.ticker import Ticker
+import wx.lib.colourselect as csel #for easy color selection
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ self.ticker = Ticker(self)
+
+ # Controls for ...controlling... the ticker.
+ self.txt = wx.TextCtrl(self, value="I am a scrolling ticker!!!!", size=(200,-1))
+ wx.CallAfter(self.txt.SetInsertionPoint, 0)
+ txtl = wx.StaticText(self, label="Ticker text:")
+ fgb = csel.ColourSelect(self, -1, colour=self.ticker.GetForegroundColour())
+ fgl = wx.StaticText(self, label="Foreground Color:")
+ bgb = csel.ColourSelect(self, -1, colour=self.ticker.GetBackgroundColour())
+ bgl = wx.StaticText(self, label="Background Color:")
+ fontb = wx.Button(self, label="Change")
+ self.fontl = wx.StaticText(self)
+ dirb = wx.Button(self, label="Switch")
+ self.dirl = wx.StaticText(self)
+ fpsl = wx.StaticText(self, label="Frames per Second:")
+ fps = wx.Slider(self, value=self.ticker.GetFPS(), minValue=1, maxValue=100,
+ size=(150,-1),
+ style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS)
+ fps.SetTickFreq(5)
+ ppfl = wx.StaticText(self, label="Pixels per frame:")
+ ppf = wx.Slider(self, value=self.ticker.GetPPF(), minValue=1, maxValue=10,
+ size=(150,-1),
+ style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS)
+
+ # Do layout
+ sz = wx.FlexGridSizer(cols=2, hgap=4, vgap=4)
+
+ sz.Add(txtl, flag=wx.ALIGN_CENTER_VERTICAL)
+ sz.Add(self.txt, flag=wx.ALIGN_CENTER_VERTICAL)
+
+ sz.Add(fgl, flag=wx.ALIGN_CENTER_VERTICAL)
+ sz.Add(fgb, flag=wx.ALIGN_CENTER_VERTICAL)
+
+ sz.Add(bgl, flag=wx.ALIGN_CENTER_VERTICAL)
+ sz.Add(bgb, flag=wx.ALIGN_CENTER_VERTICAL)
+
+ sz.Add(self.fontl, flag=wx.ALIGN_CENTER_VERTICAL)
+ sz.Add(fontb, flag=wx.ALIGN_CENTER_VERTICAL)
+
+ sz.Add(self.dirl, flag=wx.ALIGN_CENTER_VERTICAL)
+ sz.Add(dirb, flag=wx.ALIGN_CENTER_VERTICAL)
+
+ sz.Add(fpsl, flag=wx.ALIGN_CENTER_VERTICAL)
+ sz.Add(fps, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
+
+ sz.Add(ppfl, flag=wx.ALIGN_CENTER_VERTICAL)
+ sz.Add(ppf, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
+
+ sz2 = wx.BoxSizer(wx.VERTICAL)
+ sz2.Add(self.ticker, flag=wx.EXPAND|wx.ALL, border=5)
+ sz2.Add(sz, flag=wx.EXPAND|wx.ALL, proportion=1, border=25)
+ self.SetSizer(sz2)
+ sz2.SetSizeHints(self)
+
+ # Bind events
+ self.Bind(wx.EVT_BUTTON, self.OnChangeTickDirection, dirb)
+ self.Bind(wx.EVT_BUTTON, self.OnChangeTickFont, fontb)
+ self.Bind(wx.EVT_TEXT, self.OnText, self.txt)
+ self.Bind(csel.EVT_COLOURSELECT, self.ChangeTickFGColor, fgb)
+ self.Bind(csel.EVT_COLOURSELECT, self.ChangeTickBGColor, bgb)
+ self.Bind(wx.EVT_SCROLL, self.ChangeFPS, fps)
+ self.Bind(wx.EVT_SCROLL, self.ChangePPF, ppf)
+
+ # Set defaults
+ self.SetTickDirection("rtl")
+ self.SetTickFont(self.ticker.GetFont())
+ self.ticker.SetText(self.txt.GetValue())
+ def SetTickFont(self, font):
+ """Sets ticker font, updates label"""
+ self.ticker.SetFont(font)
+ self.fontl.SetLabel("Font: %s"%(self.ticker.GetFont().GetFaceName()))
+ self.Layout()
+
+
+ def OnChangeTickFont(self, evt):
+ fd = wx.FontData()
+ fd.EnableEffects(False)
+ fd.SetInitialFont(self.ticker.GetFont())
+ dlg = wx.FontDialog(wx.GetTopLevelParent(self), fd)
+ if dlg.ShowModal() == wx.ID_OK:
+ data = dlg.GetFontData()
+ self.SetTickFont(data.GetChosenFont())
+
+
+ def SetTickDirection(self, dir):
+ """Sets tick direction, updates label"""
+ self.ticker.SetDirection(dir)
+ self.dirl.SetLabel("Direction: %s"%(self.ticker.GetDirection()))
+
+
+ def OnChangeTickDirection(self, dir):
+ if self.ticker.GetDirection() == "rtl":
+ self.SetTickDirection("ltr")
+ else:
+ self.SetTickDirection("rtl")
+
+
+ def OnText(self, evt):
+ """Live update of the ticker text"""
+ self.ticker.SetText(self.txt.GetValue())
+
+ def ChangeTickFGColor(self, evt):
+ self.ticker.SetForegroundColour(evt.GetValue())
+
+ def ChangeTickBGColor(self, evt):
+ self.ticker.SetBackgroundColour(evt.GetValue())
+
+ def ChangeFPS(self, evt):
+ self.ticker.SetFPS(evt.GetPosition())
+
+ def ChangePPF(self, evt):
+ self.ticker.SetPPF(evt.GetPosition())
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = wx.lib.ticker.__doc__
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
+
--- /dev/null
+#----------------------------------------------------------------------
+# Name: wx.lib.ticker
+# Purpose: A news-ticker style scrolling text control
+#
+# Author: Chris Mellon
+#
+# Created: 29-Aug-2004
+# RCS-ID: $Id$
+# Copyright: (c) 2004 by Chris Mellon
+# Licence: wxWindows license
+#----------------------------------------------------------------------
+
+"""News-ticker style scrolling text control
+
+ Can scroll from right to left or left to right.
+ Speed of the ticking is controlled by two parameters:
+ Frames per Second(FPS): How many times per second the ticker updates
+ Pixels per Frame(PPF): How many pixels the text moves each update
+ Low FPS with high PPF will result in "jumpy" text, lower PPF with higher FPS
+ is smoother (but blurrier and more CPU intensive) text.
+"""
+
+import wx
+
+#----------------------------------------------------------------------
+
+class Ticker(wx.PyControl):
+ def __init__(self,
+ parent,
+ id=-1,
+ text=wx.EmptyString, #text in the ticker
+ fgcolor = wx.BLACK, #text/foreground color
+ bgcolor = wx.WHITE, #background color
+ start=True, #if True, the ticker starts immediately
+ ppf=2, #pixels per frame
+ fps=20, #frames per second
+ direction="rtl", #direction of ticking, rtl or ltr
+ pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.NO_BORDER,
+ name="Ticker"
+ ):
+ wx.PyControl.__init__(self, parent, id=id, pos=pos, size=size, style=style, name=name)
+ self.timer = wx.Timer(owner=self)
+ self._extent = (-1, -1) #cache value for the GetTextExtent call
+ self._offset = 0
+ self._fps = fps #frames per second
+ self._ppf = ppf #pixels per frame
+ self.SetDirection(direction)
+ self.SetText(text)
+ self.SetBestFittingSize(size)
+ self.SetForegroundColour(fgcolor)
+ self.SetBackgroundColour(bgcolor)
+ wx.EVT_TIMER(self, -1, self.OnTick)
+ wx.EVT_PAINT(self, self.OnPaint)
+ wx.EVT_ERASE_BACKGROUND(self, self.OnErase)
+ if start:
+ self.Start()
+
+
+ def Stop(self):
+ """Stop moving the text"""
+ self.timer.Stop()
+
+
+ def Start(self):
+ """Starts the text moving"""
+ if not self.timer.IsRunning():
+ self.timer.Start(1000 / self._fps)
+
+
+ def IsTicking(self):
+ """Is the ticker ticking? ie, is the text moving?"""
+ return self.timer.IsRunning()
+
+
+ def SetFPS(self, fps):
+ """Adjust the update speed of the ticker"""
+ self._fps = fps
+ self.Stop()
+ self.Start()
+
+
+ def GetFPS(self):
+ """Update speed of the ticker"""
+ return self._fps
+
+
+ def SetPPF(self, ppf):
+ """Set the number of pixels per frame the ticker moves - ie, how "jumpy" it is"""
+ self._ppf = ppf
+
+
+ def GetPPF(self):
+ """Pixels per frame"""
+ return self._ppf
+
+
+ def SetFont(self, font):
+ self._extent = (-1, -1)
+ wx.Control.SetFont(self, font)
+
+
+ def SetDirection(self, dir):
+ """Sets the direction of the ticker: right to left(rtl) or left to right (ltr)"""
+ if dir == "ltr" or dir == "rtl":
+ if self._offset <> 0:
+ #Change the offset so it's correct for the new direction
+ self._offset = self._extent[0] + self.GetSize()[0] - self._offset
+ self._dir = dir
+ else:
+ raise TypeError
+
+
+ def GetDirection(self):
+ return self._dir
+
+
+ def SetText(self, text):
+ """Set the ticker text."""
+ self._text = text
+ self._extent = (-1, -1)
+ if not self._text:
+ self.Refresh() #Refresh here to clear away the old text.
+
+
+ def GetText(self):
+ return self._text
+
+
+ def UpdateExtent(self, dc):
+ """Updates the cached text extent if needed"""
+ if not self._text:
+ self._extent = (-1, -1)
+ return
+ if self._extent == (-1, -1):
+ self._extent = dc.GetTextExtent(self.GetText())
+
+
+ def DrawText(self, dc):
+ """Draws the ticker text at the current offset using the provided DC"""
+ dc.SetTextForeground(self.GetForegroundColour())
+ dc.SetFont(self.GetFont())
+ self.UpdateExtent(dc)
+ if self._dir == "ltr":
+ offx = self._offset - self._extent[0]
+ else:
+ offx = self.GetSize()[0] - self._offset
+ offy = (self.GetSize()[1] - self._extent[1]) / 2 #centered vertically
+ dc.DrawText(self._text, offx, offy)
+
+
+ def OnTick(self, evt):
+ self._offset += self._ppf
+ w1 = self.GetSize()[0]
+ w2 = self._extent[0]
+ if self._offset >= w1+w2:
+ self._offset = 0
+ self.Refresh()
+
+
+ def OnPaint(self, evt):
+ dc = wx.BufferedPaintDC(self)
+ brush = wx.Brush(self.GetBackgroundColour())
+ dc.SetBackground(brush)
+ dc.Clear()
+ self.DrawText(dc)
+
+
+ def OnErase(self, evt):
+ """Noop because of double buffering"""
+ pass
+
+
+ def AcceptsFocus(self):
+ """Non-interactive, so don't accept focus"""
+ return False
+
+
+ def DoGetBestSize(self):
+ """Width we don't care about, height is either -1, or the character
+ height of our text with a little extra padding
+ """
+ if self._extent == (-1, -1):
+ if not self._text:
+ h = self.GetCharHeight()
+ else:
+ h = self.GetTextExtent(self.GetText())[1]
+ else:
+ h = self._extent[1]
+ return (100, h+5)
+
+
+ def ShouldInheritColours(self):
+ """Don't get colours from our parent..."""
+ return False
+
+
+
+#testcase/demo
+if __name__ == '__main__':
+ app = wx.PySimpleApp()
+ f = wx.Frame(None)
+ p = wx.Panel(f)
+ t = Ticker(p, text="Some sample ticker text")
+ #set ticker properties here if you want
+ s = wx.BoxSizer(wx.VERTICAL)
+ s.Add(t, flag=wx.GROW, proportion=0)
+ p.SetSizer(s)
+ f.Show()
+ app.MainLoop()
+
+