# HG changeset patch # User dmcc # Date 2002-07-07 05:13:12 # Node ID 342f7d1c7561e32a07f69fefa992c0d6061b73d0 # Parent 6faae180d1c59ac7febd11e93776246df7dab7e0 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. diff --git a/Widgets/FlyingFader.py b/Widgets/FlyingFader.py --- a/Widgets/FlyingFader.py +++ b/Widgets/FlyingFader.py @@ -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)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("" % k, - lambda evt, k=k: self.newfade(k / 10.0, evt)) + lambda evt, k=k: self.newfade(k * 10, evt)) - self.scale.bind("", lambda evt: self.newfade(1.0, evt)) + self.scale.bind("", lambda evt: self.newfade(100, evt)) self.scale.bind("", 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("",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)