Cleanup timeouts.
--- a/tuikit/application.py Tue Jan 08 23:36:01 2013 +0100
+++ b/tuikit/application.py Tue Jan 08 23:59:55 2013 +0100
@@ -2,11 +2,55 @@
import logging
import time
-import math
from tuikit.container import Container
+class Timer:
+ def __init__(self):
+ self.timeouts = []
+ self.timelast = None
+
+ def add_timeout(self, delay, callback):
+ """Register callback to be called after delay seconds.
+
+ delay -- in seconds, float
+ callback -- function to be called with no parameters
+
+ """
+ if not len(self.timeouts):
+ self.timelast = time.time()
+ self.timeouts += [[delay, callback]]
+
+ def remove_timeout(self, callback):
+ """Unregister callback previously registered with add_timeout."""
+ for timeout in self.timeouts[:]:
+ if timeout[1] == callback:
+ self.timeouts.remove(timeout)
+
+ def has_timeout(self):
+ return len(self.timeouts) > 0
+
+ def nearest_timeout(self):
+ if not self.has_timeout():
+ return None
+ return min(self.timeouts)[0]
+
+ def process_timeouts(self):
+ if not self.has_timeout():
+ return
+ now = time.time()
+ lasted = now - self.timelast
+ self.timelast = now
+ for timeout in self.timeouts[:]:
+ adjusted_delay = timeout[0] - lasted
+ if adjusted_delay <= 0.0:
+ timeout[1]()
+ self.timeouts.remove(timeout)
+ else:
+ timeout[0] = adjusted_delay
+
+
class TopWindow(Container):
'''Top window of an application. Covers entire screen.'''
@@ -14,11 +58,8 @@
def __init__(self):
'''Create top window.'''
Container.__init__(self)
-
self.top = self
-
- self.timeout = []
- self.timelast = None
+ self.timer = Timer()
def draw(self, driver, x=0, y=0):
"""Draw the top window and its children.
@@ -29,42 +70,6 @@
driver.erase()
Container.draw(self, driver, x, y)
- def add_timeout(self, s, func):
- if not len(self.timeout):
- self.timelast = time.time()
- self.timeout += [[s, func]]
-
-
- def remove_timeout(self, func):
- for to in self.timeout[:]:
- if to[1] == func:
- self.timeout.remove(to)
-
-
- def has_timeout(self):
- return len(self.timeout) > 0
-
-
- def nearest_timeout(self):
- if not self.has_timeout():
- return None
- return min(self.timeout)[0]
-
-
- def process_timeout(self):
- if not self.has_timeout():
- return
- now = time.time()
- lasted = now - self.timelast
- self.timelast = now
- for to in self.timeout[:]:
- newt = to[0] - lasted
- if newt <= 0.0:
- to[1]()
- self.timeout.remove(to)
- else:
- to[0] = newt
-
class Application:
@@ -102,14 +107,15 @@
self.applytheme()
self.top.size = self.driver.size # link top widget size to screen size
self.top.emit('resize')
+ timer = self.top.timer
while True:
self.top.draw(self.driver)
self.driver.commit()
- timeout = self.top.nearest_timeout()
+ timeout = timer.nearest_timeout()
events = self.driver.getevents(timeout)
- self.top.process_timeout()
+ timer.process_timeouts()
for event in events:
if event[0] == 'quit':
--- a/tuikit/scrollbar.py Tue Jan 08 23:36:01 2013 +0100
+++ b/tuikit/scrollbar.py Tue Jan 08 23:59:55 2013 +0100
@@ -12,7 +12,9 @@
self._pos = 0
self._thumbpos = 0
- self.interval = 0.1
+ # interval for continuous scroll when user holds mouse on scrollbar arrow
+ self.scroll_delay = 0.150
+ self.scroll_interval = 0.030
self.dragging = False
self.move = None
@@ -67,7 +69,7 @@
self.move_up()
else:
self.move_down()
- self.top.add_timeout(self.interval * 2, self._timeout)
+ self.add_timeout(self.scroll_delay, self._continuous_scroll)
return
# thumb bar
if ev.wy == 1 + self._thumbpos:
@@ -80,7 +82,7 @@
self.dragging = False
return
if self.move:
- self.top.remove_timeout(self._timeout)
+ self.remove_timeout(self._continuous_scroll)
self.move = None
return
@@ -88,13 +90,6 @@
if self.dragging:
self.drag(ev.wy)
- def _timeout(self):
- if self.move == 'up':
- self.move_up()
- if self.move == 'down':
- self.move_down()
- self.top.add_timeout(self.interval, self._timeout)
-
def move_up(self):
if self._pos > 0:
self.pos = self._pos - 1
@@ -114,3 +109,10 @@
if self._pos != newpos:
self.pos = newpos
+ def _continuous_scroll(self):
+ if self.move == 'up':
+ self.move_up()
+ if self.move == 'down':
+ self.move_down()
+ self.add_timeout(self.scroll_interval, self._continuous_scroll)
+
--- a/tuikit/widget.py Tue Jan 08 23:36:01 2013 +0100
+++ b/tuikit/widget.py Tue Jan 08 23:59:55 2013 +0100
@@ -260,3 +260,19 @@
self.hidden = False
self.redraw()
+
+ ## timeout ##
+
+ def add_timeout(self, delay, callback):
+ """Register callback to be called after delay seconds.
+
+ delay -- in seconds, float
+ callback -- function to be called with no parameters
+
+ """
+ self.top.timer.add_timeout(delay, callback)
+
+ def remove_timeout(self, callback):
+ """Unregister callback previously registered with add_timeout."""
+ self.top.timer.remove_timeout(callback)
+