Mercurial > code > home > repos > light9
annotate light8/uihelpers.py @ 161:0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
we now have TkCueList, which is really cool. it doesn't provide editing
yet, but you could almost nearly probably maybe run a show with it.
heck, i hope so.
some of the shifting/drawing problems were probably fixed.
cuelist1 got more bogus data to help populate the TkCueList.
author | dmcc |
---|---|
date | Mon, 07 Jul 2003 17:18:26 +0000 |
parents | 4136e92829e3 |
children |
rev | line source |
---|---|
0 | 1 """all the tiny tk helper functions""" |
51
71489bb71528
- Meet Fader. He is going to grow up and be a crossfader some day
dmcc
parents:
47
diff
changeset
|
2 |
47 | 3 from __future__ import nested_scopes |
0 | 4 from Tkinter import * |
51
71489bb71528
- Meet Fader. He is going to grow up and be a crossfader some day
dmcc
parents:
47
diff
changeset
|
5 from Tix import * |
34
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
6 from types import StringType |
0 | 7 |
68 | 8 windowlocations = { |
9 'sub' : '425x738+00+00', | |
10 'console' : '168x24+848+000', | |
11 'leveldisplay' : '144x340+870+400', | |
12 'cuefader' : '314x212+546+741', | |
13 'effect' : '24x24+0963+338', | |
69 | 14 'stage' : '823x683+37+030', |
15 'scenes' : '504x198+462+12', | |
68 | 16 } |
17 | |
0 | 18 def make_frame(parent): |
102 | 19 f = Frame(parent, bd=0, bg='black') |
0 | 20 f.pack(side='left') |
21 return f | |
22 | |
23 def bindkeys(root,key, func): | |
24 root.bind(key, func) | |
25 for w in root.winfo_children(): | |
26 w.bind(key, func) | |
27 | |
84 | 28 |
29 def toplevel_savegeometry(tl,name): | |
30 try: | |
90
d34a4956417a
rsn has a separate thread that receives rlslider connections from a potserver.py process,
drewp
parents:
84
diff
changeset
|
31 geo = tl.geometry() |
d34a4956417a
rsn has a separate thread that receives rlslider connections from a potserver.py process,
drewp
parents:
84
diff
changeset
|
32 if not geo.startswith("1x1"): |
d34a4956417a
rsn has a separate thread that receives rlslider connections from a potserver.py process,
drewp
parents:
84
diff
changeset
|
33 f=open(".light9-window-geometry-%s" % name.replace(' ','_'),'w') |
d34a4956417a
rsn has a separate thread that receives rlslider connections from a potserver.py process,
drewp
parents:
84
diff
changeset
|
34 f.write(tl.geometry()) |
d34a4956417a
rsn has a separate thread that receives rlslider connections from a potserver.py process,
drewp
parents:
84
diff
changeset
|
35 # else the window never got mapped |
84 | 36 except: |
37 # it's ok if there's no saved geometry | |
38 pass | |
39 | |
40 # this would get called repeatedly for each child of the window (i | |
41 # dont know why) so we unbind after the first Destroy event | |
42 tl.unbind("<Destroy>",tl._toplevelat_funcid) | |
43 | |
132 | 44 def toplevelat(name, existingtoplevel=None): |
45 tl = existingtoplevel or Toplevel() | |
46 tl.title(name) | |
67 | 47 |
84 | 48 try: |
49 f=open(".light9-window-geometry-%s" % name.replace(' ','_')) | |
50 windowlocations[name]=f.read() # file has no newline | |
51 except: | |
52 # it's ok if there's no saved geometry | |
53 pass | |
54 | |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
69
diff
changeset
|
55 if name in windowlocations: |
84 | 56 tl.geometry(windowlocations[name]) |
57 | |
58 tl._toplevelat_funcid=tl.bind("<Destroy>",lambda ev,tl=tl,name=name: toplevel_savegeometry(tl,name)) | |
68 | 59 |
12
7adc65771676
big restructuring - moved lots of things (including most panels) to other files
drewp
parents:
0
diff
changeset
|
60 return tl |
0 | 61 |
62 def toggle_slider(s): | |
63 if s.get() == 0: | |
64 s.set(100) | |
65 else: | |
66 s.set(0) | |
67 | |
68 # for lambda callbacks | |
69 def printout(t): | |
70 print t | |
58 | 71 |
72 def printevent(ev): | |
73 for k in dir(ev): | |
74 if not k.startswith('__'): | |
75 print k,getattr(ev,k) | |
76 print "" | |
0 | 77 |
58 | 78 def eventtoparent(ev,sequence): |
102 | 79 "passes an event to the parent, screws up TixComboBoxes" |
80 | |
81 wid_class = str(ev.widget.__class__) | |
82 if wid_class == 'Tix.ComboBox' or wid_class == 'Tix.TixSubWidget': | |
83 return | |
84 | |
58 | 85 evdict={} |
86 for x in ['state', 'time', 'y', 'x', 'serial']: | |
87 evdict[x]=getattr(ev,x) | |
88 # evdict['button']=ev.num | |
89 par=ev.widget.winfo_parent() | |
90 if par!=".": | |
91 ev.widget.nametowidget(par).event_generate(sequence,**evdict) | |
92 #else the event made it all the way to the top, unhandled | |
93 | |
0 | 94 def colorlabel(label): |
95 """color a label based on its own text""" | |
96 txt=label['text'] or "0" | |
97 lev=float(txt)/100 | |
98 low=(80,80,180) | |
99 high=(255,55,050) | |
100 out = [int(l+lev*(h-l)) for h,l in zip(high,low)] | |
101 col="#%02X%02X%02X" % tuple(out) | |
102 label.config(bg=col) | |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
103 |
34
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
104 # TODO: get everyone to use this |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
105 def colorfade(low, high, percent): |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
106 '''not foolproof. make sure 0 < percent < 1''' |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
107 out = [int(l+percent*(h-l)) for h,l in zip(high,low)] |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
108 col="#%02X%02X%02X" % tuple(out) |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
109 return col |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
110 |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
111 def colortotuple(anytkobj, colorname): |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
112 'pass any tk object and a color name, like "yellow"' |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
113 rgb = anytkobj.winfo_rgb(colorname) |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
114 return [v / 256 for v in rgb] |
411de8b46aef
the famous you-are-in-the-process-of-changing-this-light indicator.
dmcc
parents:
30
diff
changeset
|
115 |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
116 class Togglebutton(Button): |
47 | 117 """works like a single radiobutton, but it's a button so the |
118 label's on the button face, not to the side. the optional command | |
119 callback is called on button set, not on unset. takes a variable | |
120 just like a checkbutton""" | |
52 | 121 def __init__(self,parent,variable=None,command=None,downcolor='red',**kw): |
47 | 122 |
123 self.oldcommand = command | |
124 Button.__init__(self,parent,command=self.invoke,**kw) | |
125 | |
126 self._origbkg = self.cget('bg') | |
52 | 127 self.downcolor = downcolor |
47 | 128 |
129 self._variable = variable | |
130 if self._variable: | |
131 self._variable.trace('w',self._varchanged) | |
132 self._setstate(self._variable.get()) | |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
133 else: |
47 | 134 self._setstate(0) |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
135 |
47 | 136 self.bind("<Return>",self.invoke) |
137 self.bind("<1>",self.invoke) | |
138 self.bind("<space>",self.invoke) | |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
139 |
47 | 140 def _varchanged(self,*args): |
141 self._setstate(self._variable.get()) | |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
142 |
47 | 143 def invoke(self,*ev): |
144 if self._variable: | |
145 self._variable.set(not self.state) | |
146 else: | |
147 self._setstate(not self.state) | |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
148 |
47 | 149 if self.oldcommand and self.state: # call command only when state goes to 1 |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
150 self.oldcommand() |
47 | 151 return "break" |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
152 |
47 | 153 def _setstate(self,newstate): |
154 self.state = newstate | |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
155 if newstate: # set |
52 | 156 self.config(bg=self.downcolor,relief='sunken') |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
157 else: # unset |
47 | 158 self.config(bg=self._origbkg,relief='raised') |
30
e9d2e7754fd9
sideways subs, new x/y buttons (which don't draw right, but they work)
drewp
parents:
26
diff
changeset
|
159 return "break" |
47 | 160 |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
161 |
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
162 class FancyDoubleVar(DoubleVar): |
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
163 def __init__(self,master=None): |
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
164 DoubleVar.__init__(self,master) |
101 | 165 self.callbacklist = {} # cbname : mode |
166 self.namedtraces = {} # name : cbname | |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
167 def trace_variable(self,mode,callback): |
97 | 168 """Define a trace callback for the variable. |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
169 |
97 | 170 MODE is one of "r", "w", "u" for read, write, undefine. |
171 CALLBACK must be a function which is called when | |
172 the variable is read, written or undefined. | |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
173 |
97 | 174 Return the name of the callback. |
175 """ | |
176 cbname = self._master._register(callback) | |
177 self._tk.call("trace", "variable", self._name, mode, cbname) | |
178 | |
179 # we build a list of the trace callbacks (the py functrions and the tcl functionnames) | |
101 | 180 self.callbacklist[cbname] = mode |
98 | 181 # print "added trace:",callback,cbname |
97 | 182 |
183 return cbname | |
184 trace=trace_variable | |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
185 def disable_traces(self): |
97 | 186 for cb,mode in self.callbacklist.items(): |
187 # DoubleVar.trace_vdelete(self,v[0],k) | |
188 self._tk.call("trace", "vdelete", self._name, mode,cb) | |
189 # but no master delete! | |
190 | |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
191 def recreate_traces(self): |
97 | 192 for cb,mode in self.callbacklist.items(): |
193 # self.trace_variable(v[0],v[1]) | |
194 self._tk.call("trace", "variable", self._name, mode,cb) | |
195 | |
101 | 196 def trace_named(self, name, callback): |
197 if name in self.namedtraces: | |
198 print "FancyDoubleVar: already had a trace named %s - replacing it" % name | |
199 self.delete_named(name) | |
200 | |
201 cbname = self.trace_variable('w',callback) # this will register in self.callbacklist too | |
202 | |
203 self.namedtraces[name] = cbname | |
204 return cbname | |
205 | |
206 def delete_named(self, name): | |
207 if name in self.namedtraces: | |
208 | |
209 cbname = self.namedtraces[name] | |
210 | |
211 self.trace_vdelete('w',cbname) | |
212 #self._tk.call("trace","vdelete",self._name,'w',cbname) | |
213 print "FancyDoubleVar: successfully deleted trace named %s" % name | |
214 else: | |
215 print "FancyDoubleVar: attempted to delete named %s which wasn't set to any function" % name | |
216 | |
102 | 217 def get_selection(listbox): |
218 'Given a listbox, returns first selection as integer' | |
219 selection = int(listbox.curselection()[0]) # blech | |
220 return selection | |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
90
diff
changeset
|
221 |
47 | 222 if __name__=='__main__': |
223 root=Tk() | |
224 root.tk_focusFollowsMouse() | |
225 iv=IntVar() | |
226 def cb(): | |
227 print "cb!" | |
228 t = Togglebutton(root,text="testbutton",command=cb,variable=iv) | |
229 t.pack() | |
230 Entry(root,textvariable=iv).pack() | |
231 root.mainloop() |