blob: 608a58d835b644b7df798746695cb351c350d84e [file] [log] [blame]
Barry Warsawf67a50c1998-02-18 00:05:59 +00001import string
Barry Warsaw9d882bc1998-02-12 19:51:57 +00002from Tkinter import *
3import Pmw
4import ColorDB
5
Barry Warsaw4c2fab51998-02-18 16:22:22 +00006# Load this script into the Tcl interpreter and call it in
7# StripWidget.set_color(). This is about as fast as it can be with the
8# current _tkinter.c interface, which doesn't support Tcl Objects.
9TCLPROC = '''\
10proc setcolor {canv colors} {
11 set i 1
12 foreach c $colors {
13 $canv itemconfigure $i -fill $c -outline $c
14 incr i
15 }
16}
17'''
18
19
Barry Warsawf67a50c1998-02-18 00:05:59 +000020
Barry Warsaw9d882bc1998-02-12 19:51:57 +000021class LeftArrow:
22 _ARROWWIDTH = 30
23 _ARROWHEIGHT = 15
24 _YOFFSET = 13
25 _TEXTYOFFSET = 1
26 _TAG = ('leftarrow',)
27
28 def __init__(self, canvas, x):
29 self._canvas = canvas
30 self.__arrow, self.__text = self._create(x)
31 self.move_to(x)
32
33 def _create(self, x):
34 arrow = self._canvas.create_line(
35 x, self._ARROWHEIGHT + self._YOFFSET,
36 x, self._YOFFSET,
37 x + self._ARROWWIDTH, self._YOFFSET,
38 arrow='first',
39 width=3.0,
40 tags=self._TAG)
41 text = self._canvas.create_text(
42 x + self._ARROWWIDTH + 13,
43 self._ARROWHEIGHT - self._TEXTYOFFSET,
Barry Warsaw35ae8641998-02-13 21:28:47 +000044 tags=self._TAG,
Barry Warsaw9d882bc1998-02-12 19:51:57 +000045 text='128')
46 return arrow, text
47
48 def _x(self):
49 coords = self._canvas.coords(self._TAG)
50 assert coords
51 return coords[0]
52
53 def move_to(self, x):
54 deltax = x - self._x()
55 self._canvas.move(self._TAG, deltax, 0)
56
Barry Warsaw35ae8641998-02-13 21:28:47 +000057 def set_text(self, text):
58 self._canvas.itemconfigure(self.__text, text=text)
59
Barry Warsaw9d882bc1998-02-12 19:51:57 +000060
61class RightArrow(LeftArrow):
62 _TAG = ('rightarrow',)
63
64 def _create(self, x):
65 arrow = self._canvas.create_line(
66 x, self._YOFFSET,
67 x + self._ARROWWIDTH, self._YOFFSET,
68 x + self._ARROWWIDTH, self._ARROWHEIGHT + self._YOFFSET,
69 arrow='last',
70 width=3.0,
71 tags=self._TAG)
72 text = self._canvas.create_text(
Barry Warsaw35ae8641998-02-13 21:28:47 +000073 x - self._ARROWWIDTH + 15, # TBD: kludge
Barry Warsaw9d882bc1998-02-12 19:51:57 +000074 self._ARROWHEIGHT - self._TEXTYOFFSET,
Barry Warsaw35ae8641998-02-13 21:28:47 +000075 text='128',
76 tags=self._TAG)
Barry Warsaw9d882bc1998-02-12 19:51:57 +000077 return arrow, text
78
79 def _x(self):
80 coords = self._canvas.bbox(self._TAG)
81 assert coords
82 return coords[2] - 6 # TBD: kludge
83
84
85
86class StripWidget(Pmw.MegaWidget):
87 _CHIPHEIGHT = 50
88 _CHIPWIDTH = 10
89 _NUMCHIPS = 40
90
91 def __init__(self, parent=None, **kw):
Barry Warsawf67a50c1998-02-18 00:05:59 +000092 options = (('color', (128, 128, 128), self.__set_color),
93 ('delegate', None, self.__set_delegate),
94 ('chipwidth', self._CHIPWIDTH, Pmw.INITOPT),
Barry Warsaw9d882bc1998-02-12 19:51:57 +000095 ('chipheight', self._CHIPHEIGHT, Pmw.INITOPT),
Barry Warsawf67a50c1998-02-18 00:05:59 +000096 ('numchips', self._NUMCHIPS, Pmw.INITOPT),
97 ('generator', None, Pmw.INITOPT),
98 ('axis', None, Pmw.INITOPT),
99 ('label', '', Pmw.INITOPT),
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000100 )
101 self.defineoptions(kw, options)
102
103 Pmw.MegaWidget.__init__(self, parent)
104 interiorarg = (self.interior(),)
105
106 # group component contains a convas containing a bunch of objects
107 # (moveable arrow + text label, relief'd rectangle color chips)
108 chipwidth = self.__chipwidth = self['chipwidth']
109 chipheight = self.__chipheight = self['chipheight']
110 numchips = self.__numchips = self['numchips']
111
112 canvaswidth = numchips * (chipwidth + 1)
Barry Warsawbc689301998-02-17 03:09:40 +0000113 canvasheight = chipheight + 43 # TBD: Kludge
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000114
Barry Warsawbc689301998-02-17 03:09:40 +0000115 # create the canvas and pack it
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000116 canvas = self.__canvas = Canvas(
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000117 parent,
118 width=canvaswidth,
Barry Warsawbc689301998-02-17 03:09:40 +0000119 height=canvasheight,
120## borderwidth=2,
121## relief=GROOVE
122 )
123
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000124 canvas.pack()
125 canvas.bind('<ButtonRelease-1>', self.__select_chip)
126 canvas.bind('<B1-Motion>', self.__select_chip)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000127
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000128 # Load a proc into the Tcl interpreter. This is used in the
129 # set_color() method to speed up setting the chip colors.
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000130 canvas.tk.eval(TCLPROC)
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000131
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000132 # create the color strip
133 chips = self.__chips = []
134 x = 1
135 y = 30
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000136 tags = ('chip',)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000137 for c in range(self.__numchips):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000138 color = 'grey'
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000139 rect = canvas.create_rectangle(
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000140 x, y, x+chipwidth, y+chipheight,
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000141 fill=color, outline=color,
142 tags=tags)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000143
144 x = x + chipwidth + 1 # for outline
Barry Warsawf67a50c1998-02-18 00:05:59 +0000145 chips.append(color)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000146
Barry Warsawbc689301998-02-17 03:09:40 +0000147 # create the string tag
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000148 self.__label = canvas.create_text(
Barry Warsawbc689301998-02-17 03:09:40 +0000149 3, y + chipheight + 8,
150 text=self['label'],
151 anchor=W)
152
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000153 # create the arrow and text item
154 chipx = self.__arrow_x(0)
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000155 self.__leftarrow = LeftArrow(canvas, chipx)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000156
157 chipx = self.__arrow_x(len(chips) - 1)
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000158 self.__rightarrow = RightArrow(canvas, chipx)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000159
160 self.__generator = self['generator']
Barry Warsaw35ae8641998-02-13 21:28:47 +0000161 self.__axis = self['axis']
162 assert self.__axis in (0, 1, 2)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000163 self.initialiseoptions(StripWidget)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000164 self.__delegate = self['delegate']
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000165
166 def __set_color(self):
167 rgbtuple = self['color']
Barry Warsawbc689301998-02-17 03:09:40 +0000168 self.set_color(self, rgbtuple)
169
170 def __arrow_x(self, chipnum):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000171 coords = self.__canvas.coords(chipnum+1)
Barry Warsawbc689301998-02-17 03:09:40 +0000172 assert coords
173 x0, y0, x1, y1 = coords
174 return (x1 + x0) / 2.0
175
176 def __select_chip(self, event=None):
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000177 if self.__delegate:
178 x = event.x
179 y = event.y
180 canvas = self.__canvas
181 chip = canvas.find_overlapping(x, y, x, y)
182 if chip and (1 <= chip[0] <= self.__numchips):
183 color = self.__chips[chip[0]-1]
184 rgbtuple = ColorDB.rrggbb_to_triplet(color)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000185
Barry Warsaw4435d5a1998-02-18 17:00:24 +0000186 self.__delegate.set_color(self, rgbtuple)
187## import profile
188## import pstats
189## import tempfile
190## statfile = tempfile.mktemp()
191## p = profile.Profile()
192## p.runcall(self.__delegate.set_color, self, rgbtuple)
193## p.dump_stats(statfile)
194## s = pstats.Stats(statfile)
195## s.strip_dirs().sort_stats('time').print_stats(10)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000196
197 def __set_delegate(self):
198 self.__delegate = self['delegate']
Barry Warsawbc689301998-02-17 03:09:40 +0000199
200
201 #
202 # public interface
203 #
204
205 def set_color(self, obj, rgbtuple):
Barry Warsaw35ae8641998-02-13 21:28:47 +0000206 red, green, blue = rgbtuple
Barry Warsawf67a50c1998-02-18 00:05:59 +0000207 assert self.__generator
208 i = 1
209 chip = 0
210 chips = self.__chips = []
211 tclcmd = []
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000212 tk = self.__canvas.tk
Barry Warsawf67a50c1998-02-18 00:05:59 +0000213 for t in self.__generator(self.__numchips, rgbtuple):
214 rrggbb = ColorDB.triplet_to_rrggbb(t)
215 chips.append(rrggbb)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000216 tred, tgreen, tblue = t
217 if tred <= red and tgreen <= green and tblue <= blue:
218 chip = i
219 i = i + 1
220 # call the raw tcl script
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000221 colors = string.join(chips)
222 tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors))
Barry Warsaw35ae8641998-02-13 21:28:47 +0000223
Barry Warsawf67a50c1998-02-18 00:05:59 +0000224 # get the arrow's text
225 coloraxis = rgbtuple[self.__axis]
226 text = repr(coloraxis)
227
228 # move the arrow, and set it's text
229 if coloraxis <= 128:
230 # use the left chip
231 self.__leftarrow.set_text(text)
232 self.__leftarrow.move_to(self.__arrow_x(chip-1))
233 self.__rightarrow.move_to(-100)
234 else:
235 # use the right chip
236 self.__rightarrow.set_text(text)
237 self.__rightarrow.move_to(self.__arrow_x(chip-1))
238 self.__leftarrow.move_to(-100)
239 # and set the chip's outline
240 pmwrgb = ColorDB.triplet_to_pmwrgb(rgbtuple)
241 b = Pmw.Color.rgb2brightness(pmwrgb)
242 if b <= 0.5:
243 outline = 'white'
244 else:
245 outline = 'black'
246 self.__canvas.itemconfigure(chip, outline=outline)