ยปCore Development>Code coverage>Tools/pynche/DetailsViewer.py

Python code coverage for Tools/pynche/DetailsViewer.py

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