blob: 39b9778d09bb6c705fd8edb390aebd756faa1d16 [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 Warsaw9d882bc1998-02-12 19:51:57 +0000116 self.__canvas = Canvas(
117 parent,
118 width=canvaswidth,
Barry Warsawbc689301998-02-17 03:09:40 +0000119 height=canvasheight,
120## borderwidth=2,
121## relief=GROOVE
122 )
123
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000124 self.__canvas.pack()
Barry Warsawbc689301998-02-17 03:09:40 +0000125 self.__canvas.bind('<ButtonRelease-1>',
126 self.__select_chip)
127 self.__canvas.bind('<B1-Motion>',
128 self.__select_chip)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000129
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000130 # Load a proc into the Tcl interpreter. This is used in the
131 # set_color() method to speed up setting the chip colors.
132 self.__canvas.tk.eval(TCLPROC)
133
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000134 # create the color strip
135 chips = self.__chips = []
136 x = 1
137 y = 30
138 for c in range(self.__numchips):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000139 color = 'grey'
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000140 rect = self.__canvas.create_rectangle(
141 x, y, x+chipwidth, y+chipheight,
Barry Warsawf67a50c1998-02-18 00:05:59 +0000142 fill=color, outline=color)
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
148 self.__label = self.__canvas.create_text(
149 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)
155 self.__leftarrow = LeftArrow(self.__canvas, chipx)
156
157 chipx = self.__arrow_x(len(chips) - 1)
158 self.__rightarrow = RightArrow(self.__canvas, chipx)
159
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 Warsawf67a50c1998-02-18 00:05:59 +0000177 chip = self.__canvas.find_closest(event.x, event.y)[0]
178 if chip and self.__delegate:
179 color = self.__chips[chip-1]
Barry Warsawbc689301998-02-17 03:09:40 +0000180 rgbtuple = ColorDB.rrggbb_to_triplet(color)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000181 self.__delegate.set_color(self, rgbtuple)
182
183## import profile
184## import pstats
185## import tempfile
186## statfile = tempfile.mktemp()
187## p = profile.Profile()
188## p.runcall(self.__delegate.set_color, self, rgbtuple)
189## p.dump_stats(statfile)
190## s = pstats.Stats(statfile)
191## s.strip_dirs().sort_stats('time').print_stats(10)
192
193 def __set_delegate(self):
194 self.__delegate = self['delegate']
Barry Warsawbc689301998-02-17 03:09:40 +0000195
196
197 #
198 # public interface
199 #
200
201 def set_color(self, obj, rgbtuple):
Barry Warsaw35ae8641998-02-13 21:28:47 +0000202 red, green, blue = rgbtuple
Barry Warsawf67a50c1998-02-18 00:05:59 +0000203 assert self.__generator
204 i = 1
205 chip = 0
206 chips = self.__chips = []
207 tclcmd = []
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000208 tk = self.__canvas.tk
Barry Warsawf67a50c1998-02-18 00:05:59 +0000209 for t in self.__generator(self.__numchips, rgbtuple):
210 rrggbb = ColorDB.triplet_to_rrggbb(t)
211 chips.append(rrggbb)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000212 tred, tgreen, tblue = t
213 if tred <= red and tgreen <= green and tblue <= blue:
214 chip = i
215 i = i + 1
216 # call the raw tcl script
Barry Warsaw4c2fab51998-02-18 16:22:22 +0000217 colors = string.join(chips)
218 tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors))
Barry Warsaw35ae8641998-02-13 21:28:47 +0000219
Barry Warsawf67a50c1998-02-18 00:05:59 +0000220 # get the arrow's text
221 coloraxis = rgbtuple[self.__axis]
222 text = repr(coloraxis)
223
224 # move the arrow, and set it's text
225 if coloraxis <= 128:
226 # use the left chip
227 self.__leftarrow.set_text(text)
228 self.__leftarrow.move_to(self.__arrow_x(chip-1))
229 self.__rightarrow.move_to(-100)
230 else:
231 # use the right chip
232 self.__rightarrow.set_text(text)
233 self.__rightarrow.move_to(self.__arrow_x(chip-1))
234 self.__leftarrow.move_to(-100)
235 # and set the chip's outline
236 pmwrgb = ColorDB.triplet_to_pmwrgb(rgbtuple)
237 b = Pmw.Color.rgb2brightness(pmwrgb)
238 if b <= 0.5:
239 outline = 'white'
240 else:
241 outline = 'black'
242 self.__canvas.itemconfigure(chip, outline=outline)