Mercurial > code > home > repos > light9
comparison light8/uihelpers.py @ 12:7adc65771676
big restructuring - moved lots of things (including most panels) to other files
author | drewp |
---|---|
date | Sun, 07 Jul 2002 06:16:11 +0000 |
parents | 45b12307c695 |
children | 219d6fcbc28d |
comparison
equal
deleted
inserted
replaced
11:c65119b66b00 | 12:7adc65771676 |
---|---|
1 """all the tiny tk helper functions""" | 1 """all the tiny tk helper functions""" |
2 | 2 |
3 from __future__ import nested_scopes | |
4 from Tkinter import * | 3 from Tkinter import * |
5 from Tix import * | |
6 from types import StringType | |
7 | |
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', | |
14 'stage' : '823x683+37+030', | |
15 'scenes' : '504x198+462+12', | |
16 } | |
17 | 4 |
18 def make_frame(parent): | 5 def make_frame(parent): |
19 f = Frame(parent, bd=0, bg='black') | 6 f = Frame(parent, bd=0) |
20 f.pack(side='left') | 7 f.pack(side='left') |
21 return f | 8 return f |
9 | |
22 | 10 |
23 def bindkeys(root,key, func): | 11 def bindkeys(root,key, func): |
24 root.bind(key, func) | 12 root.bind(key, func) |
25 for w in root.winfo_children(): | 13 for w in root.winfo_children(): |
26 w.bind(key, func) | 14 w.bind(key, func) |
27 | 15 |
28 | 16 |
29 def toplevel_savegeometry(tl,name): | 17 def toplevelat(x,y,w=None,h=None): |
30 try: | 18 tl=Toplevel() |
31 geo = tl.geometry() | 19 if w and h: |
32 if not geo.startswith("1x1"): | 20 tl.wm_geometry("%dx%d+%d+%d"%(w,h,x,y)) |
33 f=open(".light9-window-geometry-%s" % name.replace(' ','_'),'w') | 21 else: |
34 f.write(tl.geometry()) | 22 tl.wm_geometry("+%d+%d"%(x,y)) |
35 # else the window never got mapped | 23 return tl |
36 except: | |
37 # it's ok if there's no saved geometry | |
38 pass | |
39 | 24 |
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 | |
44 def toplevelat(name, existingtoplevel=None): | |
45 tl = existingtoplevel or Toplevel() | |
46 tl.title(name) | |
47 | |
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 | |
55 if name in windowlocations: | |
56 tl.geometry(windowlocations[name]) | |
57 | |
58 tl._toplevelat_funcid=tl.bind("<Destroy>",lambda ev,tl=tl,name=name: toplevel_savegeometry(tl,name)) | |
59 | |
60 return tl | |
61 | 25 |
62 def toggle_slider(s): | 26 def toggle_slider(s): |
63 if s.get() == 0: | 27 if s.get() == 0: |
64 s.set(100) | 28 s.set(100) |
65 else: | 29 else: |
66 s.set(0) | 30 s.set(0) |
67 | 31 |
68 # for lambda callbacks | 32 # for lambda callbacks |
69 def printout(t): | 33 def printout(t): |
70 print t | 34 print t |
71 | |
72 def printevent(ev): | |
73 for k in dir(ev): | |
74 if not k.startswith('__'): | |
75 print k,getattr(ev,k) | |
76 print "" | |
77 | 35 |
78 def eventtoparent(ev,sequence): | |
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 | |
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 | 36 |
94 def colorlabel(label): | 37 def colorlabel(label): |
95 """color a label based on its own text""" | 38 """color a label based on its own text""" |
96 txt=label['text'] or "0" | 39 txt=label['text'] or "0" |
97 lev=float(txt)/100 | 40 lev=float(txt)/100 |
98 low=(80,80,180) | 41 low=(80,80,180) |
99 high=(255,55,050) | 42 high=(255,55,050) |
100 out = [int(l+lev*(h-l)) for h,l in zip(high,low)] | 43 out = [int(l+lev*(h-l)) for h,l in zip(high,low)] |
101 col="#%02X%02X%02X" % tuple(out) | 44 col="#%02X%02X%02X" % tuple(out) |
102 label.config(bg=col) | 45 label.config(bg=col) |
103 | |
104 # TODO: get everyone to use this | |
105 def colorfade(low, high, percent): | |
106 '''not foolproof. make sure 0 < percent < 1''' | |
107 out = [int(l+percent*(h-l)) for h,l in zip(high,low)] | |
108 col="#%02X%02X%02X" % tuple(out) | |
109 return col | |
110 | |
111 def colortotuple(anytkobj, colorname): | |
112 'pass any tk object and a color name, like "yellow"' | |
113 rgb = anytkobj.winfo_rgb(colorname) | |
114 return [v / 256 for v in rgb] | |
115 | |
116 class Togglebutton(Button): | |
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""" | |
121 def __init__(self,parent,variable=None,command=None,downcolor='red',**kw): | |
122 | |
123 self.oldcommand = command | |
124 Button.__init__(self,parent,command=self.invoke,**kw) | |
125 | |
126 self._origbkg = self.cget('bg') | |
127 self.downcolor = downcolor | |
128 | |
129 self._variable = variable | |
130 if self._variable: | |
131 self._variable.trace('w',self._varchanged) | |
132 self._setstate(self._variable.get()) | |
133 else: | |
134 self._setstate(0) | |
135 | |
136 self.bind("<Return>",self.invoke) | |
137 self.bind("<1>",self.invoke) | |
138 self.bind("<space>",self.invoke) | |
139 | |
140 def _varchanged(self,*args): | |
141 self._setstate(self._variable.get()) | |
142 | |
143 def invoke(self,*ev): | |
144 if self._variable: | |
145 self._variable.set(not self.state) | |
146 else: | |
147 self._setstate(not self.state) | |
148 | |
149 if self.oldcommand and self.state: # call command only when state goes to 1 | |
150 self.oldcommand() | |
151 return "break" | |
152 | |
153 def _setstate(self,newstate): | |
154 self.state = newstate | |
155 if newstate: # set | |
156 self.config(bg=self.downcolor,relief='sunken') | |
157 else: # unset | |
158 self.config(bg=self._origbkg,relief='raised') | |
159 return "break" | |
160 | |
161 | |
162 class FancyDoubleVar(DoubleVar): | |
163 def __init__(self,master=None): | |
164 DoubleVar.__init__(self,master) | |
165 self.callbacklist = {} # cbname : mode | |
166 self.namedtraces = {} # name : cbname | |
167 def trace_variable(self,mode,callback): | |
168 """Define a trace callback for the variable. | |
169 | |
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. | |
173 | |
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) | |
180 self.callbacklist[cbname] = mode | |
181 # print "added trace:",callback,cbname | |
182 | |
183 return cbname | |
184 trace=trace_variable | |
185 def disable_traces(self): | |
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 | |
191 def recreate_traces(self): | |
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 | |
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 | |
217 def get_selection(listbox): | |
218 'Given a listbox, returns first selection as integer' | |
219 selection = int(listbox.curselection()[0]) # blech | |
220 return selection | |
221 | |
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() |