blob: 5c38c0e9113a593ce476708a75e49319bb75aaa9 [file] [log] [blame]
Barry Warsawf67a50c1998-02-18 00:05:59 +00001import string
Barry Warsaw9d882bc1998-02-12 19:51:57 +00002from Tkinter import *
Barry Warsaw9d882bc1998-02-12 19:51:57 +00003import ColorDB
4
Barry Warsaw4c2fab51998-02-18 16:22:22 +00005# Load this script into the Tcl interpreter and call it in
6# StripWidget.set_color(). This is about as fast as it can be with the
7# current _tkinter.c interface, which doesn't support Tcl Objects.
8TCLPROC = '''\
9proc setcolor {canv colors} {
10 set i 1
11 foreach c $colors {
12 $canv itemconfigure $i -fill $c -outline $c
13 incr i
14 }
15}
16'''
17
Barry Warsawee6d8a51998-03-17 15:59:26 +000018# Tcl event types
19BTNDOWN = 4
20BTNUP = 5
21BTNDRAG = 6
22
Barry Warsaw4c2fab51998-02-18 16:22:22 +000023
Barry Warsaw0dc9c921998-09-28 22:42:44 +000024def constant(numchips):
25 step = 255.0 / (numchips - 1)
26 start = 0.0
27 seq = []
28 while numchips > 0:
29 seq.append(int(start))
30 start = start + step
31 numchips = numchips - 1
32 return seq
33
34# red variations, green+blue = cyan constant
35def constant_cyan_generator(numchips, red, green, blue):
36 seq = constant(numchips)
37 return map(None, seq, [green] * numchips, [blue] * numchips)
38
39# green variations, red+blue = magenta constant
40def constant_magenta_generator(numchips, red, green, blue):
41 seq = constant(numchips)
42 return map(None, [red] * numchips, seq, [blue] * numchips)
43
44# blue variations, red+green = yellow constant
45def constant_yellow_generator(numchips, red, green, blue):
46 seq = constant(numchips)
47 return map(None, [red] * numchips, [green] * numchips, seq)
48
49
50
Barry Warsawf67a50c1998-02-18 00:05:59 +000051
Barry Warsaw9d882bc1998-02-12 19:51:57 +000052class LeftArrow:
53 _ARROWWIDTH = 30
54 _ARROWHEIGHT = 15
55 _YOFFSET = 13
56 _TEXTYOFFSET = 1
57 _TAG = ('leftarrow',)
58
59 def __init__(self, canvas, x):
60 self._canvas = canvas
61 self.__arrow, self.__text = self._create(x)
62 self.move_to(x)
63
64 def _create(self, x):
65 arrow = self._canvas.create_line(
66 x, self._ARROWHEIGHT + self._YOFFSET,
67 x, self._YOFFSET,
68 x + self._ARROWWIDTH, self._YOFFSET,
69 arrow='first',
70 width=3.0,
71 tags=self._TAG)
72 text = self._canvas.create_text(
73 x + self._ARROWWIDTH + 13,
74 self._ARROWHEIGHT - self._TEXTYOFFSET,
Barry Warsaw35ae8641998-02-13 21:28:47 +000075 tags=self._TAG,
Barry Warsaw9d882bc1998-02-12 19:51:57 +000076 text='128')
77 return arrow, text
78
79 def _x(self):
80 coords = self._canvas.coords(self._TAG)
81 assert coords
82 return coords[0]
83
84 def move_to(self, x):
85 deltax = x - self._x()
86 self._canvas.move(self._TAG, deltax, 0)
87
Barry Warsaw35ae8641998-02-13 21:28:47 +000088 def set_text(self, text):
89 self._canvas.itemconfigure(self.__text, text=text)
90
Barry Warsaw9d882bc1998-02-12 19:51:57 +000091
92class RightArrow(LeftArrow):
93 _TAG = ('rightarrow',)
94
95 def _create(self, x):
96 arrow = self._canvas.create_line(
97 x, self._YOFFSET,
98 x + self._ARROWWIDTH, self._YOFFSET,
99 x + self._ARROWWIDTH, self._ARROWHEIGHT + self._YOFFSET,
100 arrow='last',
101 width=3.0,
102 tags=self._TAG)
103 text = self._canvas.create_text(
Barry Warsaw35ae8641998-02-13 21:28:47 +0000104 x - self._ARROWWIDTH + 15, # TBD: kludge
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000105 self._ARROWHEIGHT - self._TEXTYOFFSET,
Barry Warsaw35ae8641998-02-13 21:28:47 +0000106 text='128',
107 tags=self._TAG)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000108 return arrow, text
109
110 def _x(self):
111 coords = self._canvas.bbox(self._TAG)
112 assert coords
113 return coords[2] - 6 # TBD: kludge
114
115
116
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000117class StripWidget:
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000118 _CHIPHEIGHT = 50
119 _CHIPWIDTH = 10
120 _NUMCHIPS = 40
121
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000122 def __init__(self, switchboard,
123 parent = None,
Barry Warsaw0dc9c921998-09-28 22:42:44 +0000124 chipwidth = _CHIPWIDTH,
125 chipheight = _CHIPHEIGHT,
126 numchips = _NUMCHIPS,
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000127 generator = None,
128 axis = None,
129 label = ''):
Barry Warsaw5177c481998-09-28 21:01:55 +0000130 # instance variables
131 self.__generator = generator
132 self.__axis = axis
Barry Warsaw0dc9c921998-09-28 22:42:44 +0000133 self.__numchips = numchips
Barry Warsaw5177c481998-09-28 21:01:55 +0000134 assert self.__axis in (0, 1, 2)
135 self.__update_while_dragging = 0
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000136 # the last chip selected
Barry Warsawee6d8a51998-03-17 15:59:26 +0000137 self.__lastchip = None
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000138 self.__sb = switchboard
Barry Warsaw5177c481998-09-28 21:01:55 +0000139
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000140 canvaswidth = numchips * (chipwidth + 1)
Barry Warsawbc689301998-02-17 03:09:40 +0000141 canvasheight = chipheight + 43 # TBD: Kludge
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000142
Barry Warsawbc689301998-02-17 03:09:40 +0000143 # create the canvas and pack it
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000144 canvas = self.__canvas = Canvas(
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000145 parent,
146 width=canvaswidth,
Barry Warsawbc689301998-02-17 03:09:40 +0000147 height=canvasheight,
148## borderwidth=2,
149## relief=GROOVE
150 )
151
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000152 canvas.pack()
Barry Warsawee6d8a51998-03-17 15:59:26 +0000153 canvas.bind('<ButtonPress-1>', self.__select_chip)
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000154 canvas.bind('<ButtonRelease-1>', self.__select_chip)
Barry Warsawee6d8a51998-03-17 15:59:26 +0000155 canvas.bind('<B1-Motion>', self.__select_chip)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000156
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000157 # Load a proc into the Tcl interpreter. This is used in the
158 # set_color() method to speed up setting the chip colors.
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000159 canvas.tk.eval(TCLPROC)
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000160
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000161 # create the color strip
162 chips = self.__chips = []
163 x = 1
164 y = 30
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000165 tags = ('chip',)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000166 for c in range(self.__numchips):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000167 color = 'grey'
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000168 rect = canvas.create_rectangle(
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000169 x, y, x+chipwidth, y+chipheight,
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000170 fill=color, outline=color,
171 tags=tags)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000172 x = x + chipwidth + 1 # for outline
Barry Warsawf67a50c1998-02-18 00:05:59 +0000173 chips.append(color)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000174
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000175 # create the strip label
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000176 self.__label = canvas.create_text(
Barry Warsawbc689301998-02-17 03:09:40 +0000177 3, y + chipheight + 8,
Barry Warsaw0dc9c921998-09-28 22:42:44 +0000178 text=label,
Barry Warsawbc689301998-02-17 03:09:40 +0000179 anchor=W)
180
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000181 # create the arrow and text item
182 chipx = self.__arrow_x(0)
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000183 self.__leftarrow = LeftArrow(canvas, chipx)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000184
185 chipx = self.__arrow_x(len(chips) - 1)
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000186 self.__rightarrow = RightArrow(canvas, chipx)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000187
Barry Warsawbc689301998-02-17 03:09:40 +0000188 def __arrow_x(self, chipnum):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000189 coords = self.__canvas.coords(chipnum+1)
Barry Warsawbc689301998-02-17 03:09:40 +0000190 assert coords
191 x0, y0, x1, y1 = coords
192 return (x1 + x0) / 2.0
193
Barry Warsaw0dc9c921998-09-28 22:42:44 +0000194 # Invoked when one of the chips is clicked. This should just tell the
195 # switchboard to set the color on all the output components
Barry Warsawbc689301998-02-17 03:09:40 +0000196 def __select_chip(self, event=None):
Barry Warsaw0dc9c921998-09-28 22:42:44 +0000197 x = event.x
198 y = event.y
199 canvas = self.__canvas
200 chip = canvas.find_overlapping(x, y, x, y)
201 if chip and (1 <= chip[0] <= self.__numchips):
202 color = self.__chips[chip[0]-1]
203 red, green, blue = ColorDB.rrggbb_to_triplet(color)
204 etype = int(event.type)
205 if (etype == BTNUP or self.__update_while_dragging):
206 # update everyone
207 self.__sb.update_views(red, green, blue)
208 else:
209 # just track the arrows
210 self.__trackarrow(chip[0], (red, green, blue))
Barry Warsawbc689301998-02-17 03:09:40 +0000211
Barry Warsawee6d8a51998-03-17 15:59:26 +0000212 def __trackarrow(self, chip, rgbtuple):
213 # invert the last chip
214 if self.__lastchip is not None:
215 color = self.__canvas.itemcget(self.__lastchip, 'fill')
216 self.__canvas.itemconfigure(self.__lastchip, outline=color)
217 self.__lastchip = chip
Barry Warsawf67a50c1998-02-18 00:05:59 +0000218 # get the arrow's text
219 coloraxis = rgbtuple[self.__axis]
220 text = repr(coloraxis)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000221 # move the arrow, and set it's text
222 if coloraxis <= 128:
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000223 # use the left arrow
Barry Warsawf67a50c1998-02-18 00:05:59 +0000224 self.__leftarrow.set_text(text)
225 self.__leftarrow.move_to(self.__arrow_x(chip-1))
226 self.__rightarrow.move_to(-100)
227 else:
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000228 # use the right arrow
Barry Warsawf67a50c1998-02-18 00:05:59 +0000229 self.__rightarrow.set_text(text)
230 self.__rightarrow.move_to(self.__arrow_x(chip-1))
231 self.__leftarrow.move_to(-100)
232 # and set the chip's outline
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000233 brightness = ColorDB.triplet_to_brightness(rgbtuple)
Barry Warsaw26f4b5d1998-09-28 22:52:02 +0000234 if brightness <= 128:
Barry Warsawf67a50c1998-02-18 00:05:59 +0000235 outline = 'white'
236 else:
237 outline = 'black'
238 self.__canvas.itemconfigure(chip, outline=outline)
Barry Warsaw70787ed1998-03-16 23:08:53 +0000239
Barry Warsawee6d8a51998-03-17 15:59:26 +0000240
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000241 def update_yourself(self, red, green, blue):
Barry Warsawee6d8a51998-03-17 15:59:26 +0000242 assert self.__generator
243 i = 1
244 chip = 0
245 chips = self.__chips = []
246 tclcmd = []
247 tk = self.__canvas.tk
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000248 # get the red, green, and blue components for all chips
Barry Warsaw0dc9c921998-09-28 22:42:44 +0000249 for t in self.__generator(self.__numchips, red, green, blue):
Barry Warsawee6d8a51998-03-17 15:59:26 +0000250 rrggbb = ColorDB.triplet_to_rrggbb(t)
251 chips.append(rrggbb)
252 tred, tgreen, tblue = t
253 if tred <= red and tgreen <= green and tblue <= blue:
254 chip = i
255 i = i + 1
256 # call the raw tcl script
257 colors = string.join(chips)
258 tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors))
Barry Warsawee6d8a51998-03-17 15:59:26 +0000259 # move the arrows around
Barry Warsaw6a3ea741998-09-28 20:58:06 +0000260 self.__trackarrow(chip, (red, green, blue))
Barry Warsawee6d8a51998-03-17 15:59:26 +0000261
Barry Warsaw70787ed1998-03-16 23:08:53 +0000262 def set_update_while_dragging(self, flag):
263 self.__update_while_dragging = flag
Barry Warsaw0dc9c921998-09-28 22:42:44 +0000264
265
266
267class StripViewer:
268 def __init__(self, switchboard, parent=None):
269 self.__sb = switchboard
270 self.__reds = StripWidget(switchboard, parent,
271 generator=constant_cyan_generator,
272 axis=0,
273 label='Red Variations')
274
275 self.__greens = StripWidget(switchboard, parent,
276 generator=constant_magenta_generator,
277 axis=1,
278 label='Green Variations')
279
280 self.__blues = StripWidget(switchboard, parent,
281 generator=constant_yellow_generator,
282 axis=2,
283 label='Blue Variations')
284
285 def update_yourself(self, red, green, blue):
286 self.__reds.update_yourself(red, green, blue)
287 self.__greens.update_yourself(red, green, blue)
288 self.__blues.update_yourself(red, green, blue)