From: Robin Dunn Date: Fri, 18 Jul 2003 01:53:08 +0000 (+0000) Subject: Applied patch that converts the throbber to using timers instead of threads X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/52fcf3b1bd3b312d4bcabbeec39d749d73f7be40 Applied patch that converts the throbber to using timers instead of threads git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22070 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/wxPython/wxPython/lib/throbber.py b/wxPython/wxPython/lib/throbber.py index 3211ce699e..d1a8695235 100644 --- a/wxPython/wxPython/lib/throbber.py +++ b/wxPython/wxPython/lib/throbber.py @@ -4,12 +4,12 @@ started, stopped, reversed, etc. Useful for showing an ongoing process (like most web browsers use) or simply for adding eye-candy to an application. -Throbbers run in a separate thread so normal application -processing can continue unencumbered. +Throbbers utilize a wxTimer so that normal processing +can continue unencumbered. """ # -# throbber.py - Cliff Wells +# throbber.py - Cliff Wells # # Thanks to Harald Massa for # suggestions and sample code. @@ -17,23 +17,22 @@ processing can continue unencumbered. # $Id$ # -import threading, os -from wxPython.wx import * +import os +import wx # ------------------------------------------------------------------------------ - -wxEVT_UPDATE_THROBBER = wxNewEventType() +THROBBER_EVENT = wx.NewEventType() def EVT_UPDATE_THROBBER(win, func): - win.Connect(-1, -1, wxEVT_UPDATE_THROBBER, func) + win.Connect(-1, -1, THROBBER_EVENT, func) -class UpdateThrobberEvent(wxPyEvent): +class UpdateThrobberEvent(wx.PyEvent): def __init__(self): - wxPyEvent.__init__(self) - self.SetEventType(wxEVT_UPDATE_THROBBER) + wx.PyEvent.__init__(self) + self.SetEventType(THROBBER_EVENT) # ------------------------------------------------------------------------------ -class Throbber(wxPanel): +class Throbber(wx.Panel): """ The first argument is either the name of a file that will be split into frames (a composite image) or a list of strings of image names that will be treated @@ -46,8 +45,8 @@ class Throbber(wxPanel): """ def __init__(self, parent, id, bitmap, # single (composite) bitmap or list of bitmaps - pos = wxDefaultPosition, - size = wxDefaultSize, + pos = wx.DefaultPosition, + size = wx.DefaultSize, frameDelay = 0.1,# time between frames frames = 0, # number of frames (only necessary for composite image) frameWidth = 0, # width of each frame (only necessary for composite image) @@ -56,9 +55,10 @@ class Throbber(wxPanel): reverse = 0, # reverse direction at end of animation style = 0, # window style name = "throbber"): - wxPanel.__init__(self, parent, id, pos, size, style, name) + wx.Panel.__init__(self, parent, id, pos, size, style, name) self.name = name self.label = label + self.running = (1 != 1) _seqTypes = (type([]), type(())) # set size, guessing if necessary @@ -115,18 +115,20 @@ class Throbber(wxPanel): self.SetClientSize((width, height)) - EVT_PAINT(self, self.OnPaint) + timerID = wx.NewId() + self.timer = wx.Timer(self, timerID) + EVT_UPDATE_THROBBER(self, self.Rotate) - EVT_WINDOW_DESTROY(self, self.OnDestroyWindow) + wx.EVT_PAINT(self, self.OnPaint) + wx.EVT_TIMER(self, timerID, self.OnTimer) + wx.EVT_WINDOW_DESTROY(self, self.OnDestroyWindow) + - self.event = threading.Event() - self.event.set() # we start out in the "resting" state + def OnTimer(self, event): + wx.PostEvent(self, UpdateThrobberEvent()) def OnDestroyWindow(self, event): - # this is currently broken due to a bug in wxWindows... hopefully - # it'll be fixed soon. Meanwhile be sure to explicitly call Stop() - # before the throbber is destroyed. self.Stop() event.Skip() @@ -137,27 +139,16 @@ class Throbber(wxPanel): dc.DrawBitmap(self.overlay, self.overlayX, self.overlayY, True) if self.label and self.showLabel: dc.DrawText(self.label, self.labelX, self.labelY) - dc.SetTextForeground(wxWHITE) + dc.SetTextForeground(wx.WHITE) dc.DrawText(self.label, self.labelX-1, self.labelY-1) def OnPaint(self, event): - self.Draw(wxPaintDC(self)) + self.Draw(wx.PaintDC(self)) event.Skip() - def UpdateThread(self): - try: - while hasattr(self, 'event') and not self.event.isSet(): - wxPostEvent(self, UpdateThrobberEvent()) - self.event.wait(self.frameDelay) - except wxPyDeadObjectError: # BUG: we were destroyed - return - - def Rotate(self, event): - if self.event.isSet(): - return self.current += self.direction if self.current >= len(self.sequence): if self.autoReverse: @@ -171,22 +162,22 @@ class Throbber(wxPanel): self.current = 1 else: self.current = len(self.sequence) - 1 - self.Draw(wxClientDC(self)) + self.Draw(wx.ClientDC(self)) # --------- public methods --------- def SetFont(self, font): """Set the font for the label""" - wxPanel.SetFont(self, font) + wx.Panel.SetFont(self, font) self.SetLabel(self.label) - self.Draw(wxClientDC(self)) + self.Draw(wx.ClientDC(self)) def Rest(self): """Stop the animation and return to frame 0""" self.Stop() self.current = 0 - self.Draw(wxClientDC(self)) + self.Draw(wx.ClientDC(self)) def Reverse(self): @@ -196,28 +187,29 @@ class Throbber(wxPanel): def Running(self): """Returns True if the animation is running""" - return not self.event.isSet() + return self.running def Start(self): """Start the animation""" - if not self.Running(): - self.event.clear() - thread = threading.Thread(target = self.UpdateThread, - name = "%s-thread" % self.name) - thread.start() + if not self.running: + self.running = not self.running + self.timer.Start(self.frameDelay * 1000) def Stop(self): """Stop the animation""" - if self.event.isSet(): - return - self.event.set() + if self.running: + self.timer.Stop() + self.running = not self.running def SetFrameDelay(self, frameDelay = 0.05): """Delay between each frame""" self.frameDelay = frameDelay + if self.running: + self.Stop() + self.Start() def ToggleOverlay(self, state = None): @@ -226,7 +218,7 @@ class Throbber(wxPanel): self.showOverlay = not self.showOverlay else: self.showOverlay = state - self.Draw(wxClientDC(self)) + self.Draw(wx.ClientDC(self)) def ToggleLabel(self, state = None): @@ -235,7 +227,7 @@ class Throbber(wxPanel): self.showLabel = not self.showLabel else: self.showLabel = state - self.Draw(wxClientDC(self)) + self.Draw(wx.ClientDC(self)) def SetLabel(self, label): @@ -245,7 +237,7 @@ class Throbber(wxPanel): extentX, extentY = self.GetTextExtent(label) self.labelX = (self.width - extentX)/2 self.labelY = (self.height - extentY)/2 - self.Draw(wxClientDC(self)) + self.Draw(wx.ClientDC(self))