source: vendor/python/2.5/Tools/pynche/DetailsViewer.py

Last change on this file was 3225, checked in by bird, 18 years ago

Python 2.5

File size: 9.9 KB
Line 
1"""DetailsViewer class.
2
3This class implements a pure input window which allows you to meticulously
4edit the current color. You have both mouse control of the color (via the
5buttons along the bottom row), and there are keyboard bindings for each of the
6increment/decrement buttons.
7
8The top three check buttons allow you to specify which of the three color
9variations are tied together when incrementing and decrementing. Red, green,
10and blue are self evident. By tying together red and green, you can modify
11the yellow level of the color. By tying together red and blue, you can modify
12the magenta level of the color. By tying together green and blue, you can
13modify the cyan level, and by tying all three together, you can modify the
14grey level.
15
16The behavior at the boundaries (0 and 255) are defined by the `At boundary'
17option menu:
18
19 Stop
20 When the increment or decrement would send any of the tied variations
21 out of bounds, the entire delta is discarded.
22
23 Wrap Around
24 When the increment or decrement would send any of the tied variations
25 out of bounds, the out of bounds variation is wrapped around to the
26 other side. Thus if red were at 238 and 25 were added to it, red
27 would have the value 7.
28
29 Preseve Distance
30 When the increment or decrement would send any of the tied variations
31 out of bounds, all tied variations are wrapped as one, so as to
32 preserve the distance between them. Thus if green and blue were tied,
33 and green was at 238 while blue was at 223, and an increment of 25
34 were applied, green would be at 15 and blue would be at 0.
35
36 Squash
37 When the increment or decrement would send any of the tied variations
38 out of bounds, the out of bounds variation is set to the ceiling of
39 255 or floor of 0, as appropriate. In this way, all tied variations
40 are squashed to one edge or the other.
41
42The following key bindings can be used as accelerators. Note that Pynche can
43fall behind if you hold the key down as a key repeat:
44
45Left arrow == -1
46Right arrow == +1
47
48Control + Left == -10
49Control + Right == 10
50
51Shift + Left == -25
52Shift + Right == +25
53"""
54
55from Tkinter import *
56
57STOP = 'Stop'
58WRAP = 'Wrap Around'
59RATIO = 'Preserve Distance'
60GRAV = 'Squash'
61
62ADDTOVIEW = 'Details Window...'
63
64
65
66class DetailsViewer:
67 def __init__(self, switchboard, master=None):
68 self.__sb = switchboard
69 optiondb = switchboard.optiondb()
70 self.__red, self.__green, self.__blue = switchboard.current_rgb()
71 # GUI
72 root = self.__root = Toplevel(master, class_='Pynche')
73 root.protocol('WM_DELETE_WINDOW', self.withdraw)
74 root.title('Pynche Details Window')
75 root.iconname('Pynche Details Window')
76 root.bind('<Alt-q>', self.__quit)
77 root.bind('<Alt-Q>', self.__quit)
78 root.bind('<Alt-w>', self.withdraw)
79 root.bind('<Alt-W>', self.withdraw)
80 # accelerators
81 root.bind('<KeyPress-Left>', self.__minus1)
82 root.bind('<KeyPress-Right>', self.__plus1)
83 root.bind('<Control-KeyPress-Left>', self.__minus10)
84 root.bind('<Control-KeyPress-Right>', self.__plus10)
85 root.bind('<Shift-KeyPress-Left>', self.__minus25)
86 root.bind('<Shift-KeyPress-Right>', self.__plus25)
87 #
88 # color ties
89 frame = self.__frame = Frame(root)
90 frame.pack(expand=YES, fill=X)
91 self.__l1 = Label(frame, text='Move Sliders:')
92 self.__l1.grid(row=1, column=0, sticky=E)
93 self.__rvar = IntVar()
94 self.__rvar.set(optiondb.get('RSLIDER', 4))
95 self.__radio1 = Checkbutton(frame, text='Red',
96 variable=self.__rvar,
97 command=self.__effect,
98 onvalue=4, offvalue=0)
99 self.__radio1.grid(row=1, column=1, sticky=W)
100 self.__gvar = IntVar()
101 self.__gvar.set(optiondb.get('GSLIDER', 2))
102 self.__radio2 = Checkbutton(frame, text='Green',
103 variable=self.__gvar,
104 command=self.__effect,
105 onvalue=2, offvalue=0)
106 self.__radio2.grid(row=2, column=1, sticky=W)
107 self.__bvar = IntVar()
108 self.__bvar.set(optiondb.get('BSLIDER', 1))
109 self.__radio3 = Checkbutton(frame, text='Blue',
110 variable=self.__bvar,
111 command=self.__effect,
112 onvalue=1, offvalue=0)
113 self.__radio3.grid(row=3, column=1, sticky=W)
114 self.__l2 = Label(frame)
115 self.__l2.grid(row=4, column=1, sticky=W)
116 self.__effect()
117 #
118 # Boundary behavior
119 self.__l3 = Label(frame, text='At boundary:')
120 self.__l3.grid(row=5, column=0, sticky=E)
121 self.__boundvar = StringVar()
122 self.__boundvar.set(optiondb.get('ATBOUND', STOP))
123 self.__omenu = OptionMenu(frame, self.__boundvar,
124 STOP, WRAP, RATIO, GRAV)
125 self.__omenu.grid(row=5, column=1, sticky=W)
126 self.__omenu.configure(width=17)
127 #
128 # Buttons
129 frame = self.__btnframe = Frame(frame)
130 frame.grid(row=0, column=0, columnspan=2, sticky='EW')
131 self.__down25 = Button(frame, text='-25',
132 command=self.__minus25)
133 self.__down10 = Button(frame, text='-10',
134 command=self.__minus10)
135 self.__down1 = Button(frame, text='-1',
136 command=self.__minus1)
137 self.__up1 = Button(frame, text='+1',
138 command=self.__plus1)
139 self.__up10 = Button(frame, text='+10',
140 command=self.__plus10)
141 self.__up25 = Button(frame, text='+25',
142 command=self.__plus25)
143 self.__down25.pack(expand=YES, fill=X, side=LEFT)
144 self.__down10.pack(expand=YES, fill=X, side=LEFT)
145 self.__down1.pack(expand=YES, fill=X, side=LEFT)
146 self.__up1.pack(expand=YES, fill=X, side=LEFT)
147 self.__up10.pack(expand=YES, fill=X, side=LEFT)
148 self.__up25.pack(expand=YES, fill=X, side=LEFT)
149
150 def __effect(self, event=None):
151 tie = self.__rvar.get() + self.__gvar.get() + self.__bvar.get()
152 if tie in (0, 1, 2, 4):
153 text = ''
154 else:
155 text = '(= %s Level)' % {3: 'Cyan',
156 5: 'Magenta',
157 6: 'Yellow',
158 7: 'Grey'}[tie]
159 self.__l2.configure(text=text)
160
161 def __quit(self, event=None):
162 self.__root.quit()
163
164 def withdraw(self, event=None):
165 self.__root.withdraw()
166
167 def deiconify(self, event=None):
168 self.__root.deiconify()
169
170 def __minus25(self, event=None):
171 self.__delta(-25)
172
173 def __minus10(self, event=None):
174 self.__delta(-10)
175
176 def __minus1(self, event=None):
177 self.__delta(-1)
178
179 def __plus1(self, event=None):
180 self.__delta(1)
181
182 def __plus10(self, event=None):
183 self.__delta(10)
184
185 def __plus25(self, event=None):
186 self.__delta(25)
187
188 def __delta(self, delta):
189 tie = []
190 if self.__rvar.get():
191 red = self.__red + delta
192 tie.append(red)
193 else:
194 red = self.__red
195 if self.__gvar.get():
196 green = self.__green + delta
197 tie.append(green)
198 else:
199 green = self.__green
200 if self.__bvar.get():
201 blue = self.__blue + delta
202 tie.append(blue)
203 else:
204 blue = self.__blue
205 # now apply at boundary behavior
206 atbound = self.__boundvar.get()
207 if atbound == STOP:
208 if red < 0 or green < 0 or blue < 0 or \
209 red > 255 or green > 255 or blue > 255:
210 # then
211 red, green, blue = self.__red, self.__green, self.__blue
212 elif atbound == WRAP or (atbound == RATIO and len(tie) < 2):
213 if red < 0:
214 red += 256
215 if green < 0:
216 green += 256
217 if blue < 0:
218 blue += 256
219 if red > 255:
220 red -= 256
221 if green > 255:
222 green -= 256
223 if blue > 255:
224 blue -= 256
225 elif atbound == RATIO:
226 # for when 2 or 3 colors are tied together
227 dir = 0
228 for c in tie:
229 if c < 0:
230 dir = -1
231 elif c > 255:
232 dir = 1
233 if dir == -1:
234 delta = max(tie)
235 if self.__rvar.get():
236 red = red + 255 - delta
237 if self.__gvar.get():
238 green = green + 255 - delta
239 if self.__bvar.get():
240 blue = blue + 255 - delta
241 elif dir == 1:
242 delta = min(tie)
243 if self.__rvar.get():
244 red = red - delta
245 if self.__gvar.get():
246 green = green - delta
247 if self.__bvar.get():
248 blue = blue - delta
249 elif atbound == GRAV:
250 if red < 0:
251 red = 0
252 if green < 0:
253 green = 0
254 if blue < 0:
255 blue = 0
256 if red > 255:
257 red = 255
258 if green > 255:
259 green = 255
260 if blue > 255:
261 blue = 255
262 self.__sb.update_views(red, green, blue)
263 self.__root.update_idletasks()
264
265 def update_yourself(self, red, green, blue):
266 self.__red = red
267 self.__green = green
268 self.__blue = blue
269
270 def save_options(self, optiondb):
271 optiondb['RSLIDER'] = self.__rvar.get()
272 optiondb['GSLIDER'] = self.__gvar.get()
273 optiondb['BSLIDER'] = self.__bvar.get()
274 optiondb['ATBOUND'] = self.__boundvar.get()
Note: See TracBrowser for help on using the repository browser.