Mercurial > code > home > repos > light9
annotate Widgets/FlyingFader.py @ 59:001646cd5349
all mousewheel events everywhere will now pass up the tree to be caught by
all mousewheel events everywhere will now pass up the tree to be caught by
higher widgets. if things get slow, this might be the problem
author | drewp |
---|---|
date | Tue, 09 Jul 2002 07:36:29 +0000 |
parents | 065896b0913c |
children | 15ead14b4dd1 |
rev | line source |
---|---|
52 | 1 from Tix import * |
24 | 2 from time import time,sleep |
3 from __future__ import division | |
4 | |
5 class Mass: | |
6 def __init__(self): | |
7 self.x=0 # position | |
8 self.xgoal=0 # position goal | |
9 | |
10 self.v=0 # velocity | |
11 self.maxspeed = .8 # maximum speed, in position/second | |
12 self.maxaccel = 3 # maximum acceleration, in position/second^2 | |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
13 self.eps = .03 # epsilon - numbers within this much are considered the same |
24 | 14 |
15 self._lastupdate=time() | |
16 self._stopped=1 | |
17 | |
18 def equal(self,a,b): | |
19 return abs(a-b)<self.eps | |
20 | |
21 def stop(self): | |
22 self.v=0 | |
23 self.xgoal=self.x | |
24 self._stopped=1 | |
25 | |
26 def update(self): | |
27 t0 = self._lastupdate | |
28 tnow = time() | |
29 self._lastupdate = tnow | |
30 | |
31 dt = tnow-t0 | |
32 | |
33 self.x += self.v*dt | |
34 # hitting the ends stops the slider | |
35 if self.x>1: self.v=max(self.v,0); self.x=1 | |
36 if self.x<0: self.v=min(self.v,0); self.x=0 | |
37 | |
38 if self.equal(self.x,self.xgoal): | |
39 self.x=self.xgoal # clean up value | |
40 self.stop() | |
41 return | |
42 | |
43 self._stopped=0 | |
44 dir = (-1.0,1,0)[self.xgoal>self.x] | |
45 | |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
46 if abs(self.xgoal-self.x) < abs(self.v*5*dt): |
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
47 # apply the brakes on the last 5 steps |
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
48 dir *= -.5 |
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
49 |
24 | 50 self.v += dir*self.maxaccel*dt # velocity changes with acceleration in the right direction |
51 self.v = min(max(self.v,-self.maxspeed),self.maxspeed) # clamp velocity | |
52 | |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
53 #print "x=%+.03f v=%+.03f a=%+.03f %f" % (self.x,self.v,self.maxaccel,self.xgoal) |
24 | 54 |
55 def goto(self,newx): | |
56 self.xgoal=newx | |
57 | |
58 def ismoving(self): | |
59 return not self._stopped | |
0 | 60 |
61 class FlyingFader(Frame): | |
31 | 62 def __init__(self, master, variable, label, fadedur=1.5, font=('Arial', 8), labelwidth=12, |
15
c76b62eccdec
put **kw back in, they now go to the scale and can override the defaults.
dmcc
parents:
11
diff
changeset
|
63 **kw): |
0 | 64 Frame.__init__(self, master) |
65 self.name = label | |
66 self.variable = variable | |
67 | |
24 | 68 self.mass = Mass() |
69 | |
0 | 70 self.config({'bd':1, 'relief':'raised'}) |
22 | 71 scaleopts = {'variable' : variable, 'showvalue' : 0, 'from' : 1.0, |
31 | 72 'to' : 0, 'res' : 0.001, 'width' : 20, 'length' : 200, 'orient':'vert'} |
15
c76b62eccdec
put **kw back in, they now go to the scale and can override the defaults.
dmcc
parents:
11
diff
changeset
|
73 scaleopts.update(kw) |
31 | 74 if scaleopts['orient']=='vert': |
75 side1=TOP | |
76 side2=BOTTOM | |
77 else: | |
78 side1=RIGHT | |
79 side2=LEFT | |
15
c76b62eccdec
put **kw back in, they now go to the scale and can override the defaults.
dmcc
parents:
11
diff
changeset
|
80 |
c76b62eccdec
put **kw back in, they now go to the scale and can override the defaults.
dmcc
parents:
11
diff
changeset
|
81 self.scale = Scale(self, scaleopts) |
22 | 82 self.vlabel = Label(self, text="0.0", width=6, font=font) |
31 | 83 self.label = Label(self, text=label, font=font, anchor='w',width=labelwidth) #wraplength=40, ) |
0 | 84 |
85 self.oldtrough = self.scale['troughcolor'] | |
86 | |
31 | 87 self.scale.pack(side=side2, expand=1, fill=BOTH, anchor='c') |
88 self.vlabel.pack(side=side2, expand=0, fill=X) | |
89 self.label.pack(side=side2, expand=0, fill=X) | |
0 | 90 |
91 for k in range(1, 10): | |
92 self.scale.bind("<Key-%d>" % k, | |
20 | 93 lambda evt, k=k: self.newfade(k / 10.0, evt)) |
0 | 94 |
24 | 95 self.scale.bind("<Key-0>", lambda evt: self.newfade(1.0, evt)) |
0 | 96 self.scale.bind("<grave>", lambda evt: self.newfade(0, evt)) |
97 | |
98 self.scale.bind("<1>", self.cancelfade) | |
11
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
99 self.scale.bind("<2>", self.cancelfade) |
0 | 100 self.scale.bind("<3>", self.mousefade) |
101 | |
50 | 102 self.trace_ret = self.variable.trace('w', self.updatelabel) |
103 self.bind("<Destroy>",self.ondestroy) | |
104 | |
105 def ondestroy(self,*ev): | |
106 self.variable.trace_vdelete('w',self.trace_ret) | |
0 | 107 |
108 def cancelfade(self, evt): | |
24 | 109 self.fadegoal = self.variable.get() |
110 self.fadevel = self.fadeacc = 0 | |
111 | |
0 | 112 self.scale['troughcolor'] = self.oldtrough |
113 | |
114 def mousefade(self, evt): | |
115 target = float(self.tk.call(self.scale, 'get', evt.x, evt.y)) | |
116 self.newfade(target, evt) | |
117 | |
24 | 118 def ismoving(self): |
119 return self.fadevel!=0 or self.fadeacc!=0 | |
22 | 120 |
9
342f7d1c7561
The FlyingFader will accept keyboard values and fade to them over 1.5
dmcc
parents:
0
diff
changeset
|
121 def newfade(self, newlevel, evt=None, length=None): |
24 | 122 |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
123 # these are currently unused-- Mass needs to accept a speed input |
9
342f7d1c7561
The FlyingFader will accept keyboard values and fade to them over 1.5
dmcc
parents:
0
diff
changeset
|
124 mult = 1 |
0 | 125 if evt.state & 8 and evt.state & 4: mult = 0.25 # both |
126 elif evt.state & 8: mult = 0.5 # alt | |
127 elif evt.state & 4: mult = 2 # control | |
128 | |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
129 |
24 | 130 self.mass.x = self.variable.get() |
131 self.mass.goto(newlevel) | |
0 | 132 |
133 self.gofade() | |
134 | |
135 def gofade(self): | |
24 | 136 self.mass.update() |
137 self.variable.set(self.mass.x) | |
138 | |
139 if not self.mass.ismoving(): | |
0 | 140 self.scale['troughcolor'] = self.oldtrough |
141 return | |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
142 |
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
143 # blink the trough while the thing's moving |
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
144 if time()%.4>.2: |
27 | 145 # self.scale.config(troughcolor=self.oldtrough) |
146 self.scale.config(troughcolor='orange') | |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
147 else: |
27 | 148 # self.scale.config(troughcolor='white') |
149 self.scale.config(troughcolor='yellow') | |
24 | 150 |
151 # colorfade(self.scale, percent) | |
22 | 152 self.after(30, self.gofade) |
0 | 153 |
154 def updatelabel(self, *args): | |
52 | 155 if self.variable: |
156 self.vlabel['text'] = "%.3f" % self.variable.get() | |
24 | 157 # if self.fadetimes[1] == 0: # no fade |
158 # self.vlabel['fg'] = 'black' | |
159 # elif self.curfade[1] > self.curfade[0]: | |
160 # self.vlabel['fg'] = 'red' | |
161 # else: | |
162 # self.vlabel['fg'] = 'blue' | |
0 | 163 |
11
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
164 def get(self): |
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
165 return self.scale.get() |
0 | 166 |
11
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
167 def set(self, val): |
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
168 self.scale.set(val) |
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
169 |
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
170 def colorfade(scale, lev): |
0 | 171 low = (255, 255, 255) |
172 high = (0, 0, 0) | |
11
c65119b66b00
- no more kw args -- they didn't do anything. use configure to change
dmcc
parents:
9
diff
changeset
|
173 out = [int(l+lev*(h-l)) for h, l in zip(high,low)] |
0 | 174 col="#%02X%02X%02X" % tuple(out) |
175 scale.config(troughcolor=col) | |
176 | |
25
f0e1dde35aec
better brakes and numerics (oscillations are still possible if the updates get
drewp
parents:
24
diff
changeset
|
177 |
0 | 178 if __name__ == '__main__': |
179 root = Tk() | |
180 root.tk_focusFollowsMouse() | |
181 | |
182 FlyingFader(root, variable=DoubleVar(), label="suck").pack(side=LEFT, | |
183 expand=1, fill=BOTH) | |
184 FlyingFader(root, variable=DoubleVar(), label="moof").pack(side=LEFT, | |
185 expand=1, fill=BOTH) | |
186 FlyingFader(root, variable=DoubleVar(), label="zarf").pack(side=LEFT, | |
187 expand=1, fill=BOTH) | |
188 FlyingFader(root, variable=DoubleVar(), | |
189 label="long name goes here. got it?").pack(side=LEFT, expand=1, | |
190 fill=BOTH) | |
191 | |
192 root.mainloop() |