changeset 9:342f7d1c7561

The FlyingFader will accept keyboard values and fade to them over 1.5 The FlyingFader will accept keyboard values and fade to them over 1.5 seconds. Combinations of control and alt change that speed. RMB also creates a fade and LMB will cancel them. Colors are pretty and informative. Fades can be created manually with the newfade() function.
author dmcc
date Sun, 07 Jul 2002 05:13:12 +0000
parents 6faae180d1c5
children 533ac835083f
files Widgets/FlyingFader.py
diffstat 1 files changed, 46 insertions(+), 127 deletions(-) [+]
line wrap: on
line diff
--- a/Widgets/FlyingFader.py	Sun Jul 07 05:05:36 2002 +0000
+++ b/Widgets/FlyingFader.py	Sun Jul 07 05:13:12 2002 +0000
@@ -1,176 +1,95 @@
-from Tix import *
-from time import time,sleep
-from __future__ import division
-
-class Mass:
-    def __init__(self):
-        self.x=0 # position
-        self.xgoal=0 # position goal
-        
-        self.v=0 # velocity
-        self.maxspeed = .8 # maximum speed, in position/second
-        self.maxaccel = 3 # maximum acceleration, in position/second^2
-        self.eps = .03 # epsilon - numbers within this much are considered the same
-
-        self._lastupdate=time()
-        self._stopped=1
-
-    def equal(self,a,b):
-        return abs(a-b)<self.eps
-
-    def stop(self):
-        self.v=0
-        self.xgoal=self.x
-        self._stopped=1
-        
-    def update(self):
-        t0 = self._lastupdate
-        tnow = time()
-        self._lastupdate = tnow
-
-        dt = tnow-t0
-
-        self.x += self.v*dt
-        # hitting the ends stops the slider
-        if self.x>1: self.v=max(self.v,0); self.x=1
-        if self.x<0: self.v=min(self.v,0); self.x=0
-            
-        if self.equal(self.x,self.xgoal):
-            self.x=self.xgoal # clean up value
-            self.stop()
-            return
-        
-        self._stopped=0
-        dir = (-1.0,1,0)[self.xgoal>self.x]
-
-        if abs(self.xgoal-self.x) < abs(self.v*5*dt):
-            # apply the brakes on the last 5 steps
-            dir *= -.5
-
-        self.v += dir*self.maxaccel*dt # velocity changes with acceleration in the right direction
-        self.v = min(max(self.v,-self.maxspeed),self.maxspeed) # clamp velocity
-
-        #print "x=%+.03f v=%+.03f a=%+.03f %f" % (self.x,self.v,self.maxaccel,self.xgoal)
-
-    def goto(self,newx):
-        self.xgoal=newx
-
-    def ismoving(self):
-        return not self._stopped
+from Tkinter import *
+from time import time
 
 class FlyingFader(Frame):
-    def __init__(self, master, variable, label, fadedur=1.5, font=('Arial', 8), labelwidth=12,
+    def __init__(self, master, variable, label, time=1.5, font=('Arial', 8), 
                  **kw):
         Frame.__init__(self, master)
         self.name = label
         self.variable = variable
+        self.fadelength = time
+        self.curfade = None
+        self.fadetimes = 0, 0
 
-        self.mass = Mass()
-        
         self.config({'bd':1, 'relief':'raised'})
-        scaleopts = {'variable' : variable, 'showvalue' : 0, 'from' : 1.0,
-                     'to' : 0, 'res' : 0.001, 'width' : 20, 'length' : 200, 'orient':'vert'}
-        scaleopts.update(kw)
-        if scaleopts['orient']=='vert':
-            side1=TOP
-            side2=BOTTOM
-        else:
-            side1=RIGHT
-            side2=LEFT
-        
-        self.scale = Scale(self, **scaleopts)
-        self.vlabel = Label(self, text="0.0", width=6, font=font)
-        self.label = Label(self, text=label, font=font, anchor='w',width=labelwidth) #wraplength=40, )
+        self.scale = Scale(self, variable=variable, showvalue=0, from_=100, 
+            to_=0, res=0.1, width=20, length=200)
+        self.vlabel = Label(self, text="0.0", font=font)
+        self.label = Label(self, text=label, wraplength=40, font=font)
 
         self.oldtrough = self.scale['troughcolor']
 
-        self.scale.pack(side=side2, expand=1, fill=BOTH, anchor='c')
-        self.vlabel.pack(side=side2, expand=0, fill=X)
-        self.label.pack(side=side2, expand=0, fill=X)
+        self.scale.pack(side=TOP, expand=1, fill=BOTH, anchor='c')
+        self.vlabel.pack(side=BOTTOM, expand=0, fill=X)
+        self.label.pack(side=BOTTOM, expand=0, fill=X)
 
         for k in range(1, 10):
             self.scale.bind("<Key-%d>" % k, 
-                lambda evt, k=k: self.newfade(k / 10.0, evt))
+                lambda evt, k=k: self.newfade(k * 10, evt))
 
-        self.scale.bind("<Key-0>", lambda evt: self.newfade(1.0, evt))
+        self.scale.bind("<Key-0>", lambda evt: self.newfade(100, evt))
         self.scale.bind("<grave>", lambda evt: self.newfade(0, evt))
 
         self.scale.bind("<1>", self.cancelfade)
-        self.scale.bind("<2>", self.cancelfade)
         self.scale.bind("<3>", self.mousefade)
 
-        self.trace_ret = self.variable.trace('w', self.updatelabel)
-        self.bind("<Destroy>",self.ondestroy)
-
-    def ondestroy(self,*ev):
-        self.variable.trace_vdelete('w',self.trace_ret)
+        self.variable.trace('w', self.updatelabel)
 
     def cancelfade(self, evt):
-        self.fadegoal = self.variable.get()
-        self.fadevel = self.fadeacc = 0
-
+        self.fadetimes = 0, 0
+        self.curfade = 0, self.variable.get()
         self.scale['troughcolor'] = self.oldtrough
 
     def mousefade(self, evt):
         target = float(self.tk.call(self.scale, 'get', evt.x, evt.y))
         self.newfade(target, evt)
 
-    def ismoving(self):
-        return self.fadevel!=0 or self.fadeacc!=0
+    def newfade(self, newlevel, evt=None, length=None):
+        if length is None:
+            length = self.fadelength
+        mult = 1
 
-    def newfade(self, newlevel, evt=None, length=None):
-
-        # these are currently unused-- Mass needs to accept a speed input
-        mult = 1
         if evt.state & 8 and evt.state & 4: mult = 0.25 # both
         elif evt.state & 8: mult = 0.5 # alt
         elif evt.state & 4: mult = 2   # control
 
+        now = time()
+        self.fadetimes = (now, now + (mult * length))
+        self.curfade = (self.variable.get(), newlevel)
 
-        self.mass.x = self.variable.get()
-        self.mass.goto(newlevel)
+        self.scale['troughcolor'] = 'red'
 
         self.gofade()
 
     def gofade(self):
-        self.mass.update()
-        self.variable.set(self.mass.x)
-
-        if not self.mass.ismoving():
+        now = time()
+        start, end = self.fadetimes
+        lstart, lend = self.curfade
+        if now > end: 
+            self.fadetimes = 0, 0
+            self.variable.set(lend)
             self.scale['troughcolor'] = self.oldtrough
             return
-        
-        # blink the trough while the thing's moving
-        if time()%.4>.2:
-            # self.scale.config(troughcolor=self.oldtrough)
-            self.scale.config(troughcolor='orange')
-        else:
-            # self.scale.config(troughcolor='white')
-            self.scale.config(troughcolor='yellow')
-
-#        colorfade(self.scale, percent)
-        self.after(30, self.gofade)
+        percent = (now - start) / (end - start)
+        newvalue = (percent * (lend - lstart)) + lstart
+        self.variable.set(newvalue)
+        colortrough(self.scale, percent)
+        self.after(10, self.gofade)
 
     def updatelabel(self, *args):
-        if self.variable:
-            self.vlabel['text'] = "%.3f" % self.variable.get()
-#        if self.fadetimes[1] == 0: # no fade
-#            self.vlabel['fg'] = 'black'
-#        elif self.curfade[1] > self.curfade[0]:
-#            self.vlabel['fg'] = 'red'
-#        else:
-#            self.vlabel['fg'] = 'blue'
+        self.vlabel['text'] = "%.1f" % self.variable.get()
+        if self.fadetimes[1] == 0: # no fade
+            self.vlabel['fg'] = 'black'
+        elif self.curfade[1] > self.curfade[0]:
+            self.vlabel['fg'] = 'red'
+        else:
+            self.vlabel['fg'] = 'blue'
 
-    def get(self):
-        return self.scale.get()
 
-    def set(self, val):
-        self.scale.set(val)
-
-def colorfade(scale, lev):
+def colortrough(scale, lev):
     low = (255, 255, 255)
     high = (0, 0, 0)
-    out = [int(l+lev*(h-l)) for h, l in zip(high,low)]
+    out = [int(l+lev*(h-l)) for h,l in zip(high,low)]
     col="#%02X%02X%02X" % tuple(out)
     scale.config(troughcolor=col)