blob: 2b5691f2ef8d32c70883364bbc88d1a6a90fe85d [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 Warsawf67a50c1998-02-18 00:05:59 +00006
Barry Warsaw9d882bc1998-02-12 19:51:57 +00007class LeftArrow:
8 _ARROWWIDTH = 30
9 _ARROWHEIGHT = 15
10 _YOFFSET = 13
11 _TEXTYOFFSET = 1
12 _TAG = ('leftarrow',)
13
14 def __init__(self, canvas, x):
15 self._canvas = canvas
16 self.__arrow, self.__text = self._create(x)
17 self.move_to(x)
18
19 def _create(self, x):
20 arrow = self._canvas.create_line(
21 x, self._ARROWHEIGHT + self._YOFFSET,
22 x, self._YOFFSET,
23 x + self._ARROWWIDTH, self._YOFFSET,
24 arrow='first',
25 width=3.0,
26 tags=self._TAG)
27 text = self._canvas.create_text(
28 x + self._ARROWWIDTH + 13,
29 self._ARROWHEIGHT - self._TEXTYOFFSET,
Barry Warsaw35ae8641998-02-13 21:28:47 +000030 tags=self._TAG,
Barry Warsaw9d882bc1998-02-12 19:51:57 +000031 text='128')
32 return arrow, text
33
34 def _x(self):
35 coords = self._canvas.coords(self._TAG)
36 assert coords
37 return coords[0]
38
39 def move_to(self, x):
40 deltax = x - self._x()
41 self._canvas.move(self._TAG, deltax, 0)
42
Barry Warsaw35ae8641998-02-13 21:28:47 +000043 def set_text(self, text):
44 self._canvas.itemconfigure(self.__text, text=text)
45
Barry Warsaw9d882bc1998-02-12 19:51:57 +000046
47class RightArrow(LeftArrow):
48 _TAG = ('rightarrow',)
49
50 def _create(self, x):
51 arrow = self._canvas.create_line(
52 x, self._YOFFSET,
53 x + self._ARROWWIDTH, self._YOFFSET,
54 x + self._ARROWWIDTH, self._ARROWHEIGHT + self._YOFFSET,
55 arrow='last',
56 width=3.0,
57 tags=self._TAG)
58 text = self._canvas.create_text(
Barry Warsaw35ae8641998-02-13 21:28:47 +000059 x - self._ARROWWIDTH + 15, # TBD: kludge
Barry Warsaw9d882bc1998-02-12 19:51:57 +000060 self._ARROWHEIGHT - self._TEXTYOFFSET,
Barry Warsaw35ae8641998-02-13 21:28:47 +000061 text='128',
62 tags=self._TAG)
Barry Warsaw9d882bc1998-02-12 19:51:57 +000063 return arrow, text
64
65 def _x(self):
66 coords = self._canvas.bbox(self._TAG)
67 assert coords
68 return coords[2] - 6 # TBD: kludge
69
70
71
72class StripWidget(Pmw.MegaWidget):
73 _CHIPHEIGHT = 50
74 _CHIPWIDTH = 10
75 _NUMCHIPS = 40
76
77 def __init__(self, parent=None, **kw):
Barry Warsawf67a50c1998-02-18 00:05:59 +000078 options = (('color', (128, 128, 128), self.__set_color),
79 ('delegate', None, self.__set_delegate),
80 ('chipwidth', self._CHIPWIDTH, Pmw.INITOPT),
Barry Warsaw9d882bc1998-02-12 19:51:57 +000081 ('chipheight', self._CHIPHEIGHT, Pmw.INITOPT),
Barry Warsawf67a50c1998-02-18 00:05:59 +000082 ('numchips', self._NUMCHIPS, Pmw.INITOPT),
83 ('generator', None, Pmw.INITOPT),
84 ('axis', None, Pmw.INITOPT),
85 ('label', '', Pmw.INITOPT),
Barry Warsaw9d882bc1998-02-12 19:51:57 +000086 )
87 self.defineoptions(kw, options)
88
89 Pmw.MegaWidget.__init__(self, parent)
90 interiorarg = (self.interior(),)
91
92 # group component contains a convas containing a bunch of objects
93 # (moveable arrow + text label, relief'd rectangle color chips)
94 chipwidth = self.__chipwidth = self['chipwidth']
95 chipheight = self.__chipheight = self['chipheight']
96 numchips = self.__numchips = self['numchips']
97
98 canvaswidth = numchips * (chipwidth + 1)
Barry Warsawbc689301998-02-17 03:09:40 +000099 canvasheight = chipheight + 43 # TBD: Kludge
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000100
Barry Warsawbc689301998-02-17 03:09:40 +0000101 # create the canvas and pack it
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000102 self.__canvas = Canvas(
103 parent,
104 width=canvaswidth,
Barry Warsawbc689301998-02-17 03:09:40 +0000105 height=canvasheight,
106## borderwidth=2,
107## relief=GROOVE
108 )
109
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000110 self.__canvas.pack()
Barry Warsawbc689301998-02-17 03:09:40 +0000111 self.__canvas.bind('<ButtonRelease-1>',
112 self.__select_chip)
113 self.__canvas.bind('<B1-Motion>',
114 self.__select_chip)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000115
116 # create the color strip
117 chips = self.__chips = []
118 x = 1
119 y = 30
120 for c in range(self.__numchips):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000121 color = 'grey'
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000122 rect = self.__canvas.create_rectangle(
123 x, y, x+chipwidth, y+chipheight,
Barry Warsawf67a50c1998-02-18 00:05:59 +0000124 fill=color, outline=color)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000125
126 x = x + chipwidth + 1 # for outline
Barry Warsawf67a50c1998-02-18 00:05:59 +0000127 chips.append(color)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000128
Barry Warsawbc689301998-02-17 03:09:40 +0000129 # create the string tag
130 self.__label = self.__canvas.create_text(
131 3, y + chipheight + 8,
132 text=self['label'],
133 anchor=W)
134
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000135 # create the arrow and text item
136 chipx = self.__arrow_x(0)
137 self.__leftarrow = LeftArrow(self.__canvas, chipx)
138
139 chipx = self.__arrow_x(len(chips) - 1)
140 self.__rightarrow = RightArrow(self.__canvas, chipx)
141
142 self.__generator = self['generator']
Barry Warsaw35ae8641998-02-13 21:28:47 +0000143 self.__axis = self['axis']
144 assert self.__axis in (0, 1, 2)
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000145 self.initialiseoptions(StripWidget)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000146 self.__delegate = self['delegate']
Barry Warsaw9d882bc1998-02-12 19:51:57 +0000147
148 def __set_color(self):
149 rgbtuple = self['color']
Barry Warsawbc689301998-02-17 03:09:40 +0000150 self.set_color(self, rgbtuple)
151
152 def __arrow_x(self, chipnum):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000153 coords = self.__canvas.coords(chipnum+1)
Barry Warsawbc689301998-02-17 03:09:40 +0000154 assert coords
155 x0, y0, x1, y1 = coords
156 return (x1 + x0) / 2.0
157
158 def __select_chip(self, event=None):
Barry Warsawf67a50c1998-02-18 00:05:59 +0000159 chip = self.__canvas.find_closest(event.x, event.y)[0]
160 if chip and self.__delegate:
161 color = self.__chips[chip-1]
Barry Warsawbc689301998-02-17 03:09:40 +0000162 rgbtuple = ColorDB.rrggbb_to_triplet(color)
Barry Warsawf67a50c1998-02-18 00:05:59 +0000163 self.__delegate.set_color(self, rgbtuple)
164
165## import profile
166## import pstats
167## import tempfile
168## statfile = tempfile.mktemp()
169## p = profile.Profile()
170## p.runcall(self.__delegate.set_color, self, rgbtuple)
171## p.dump_stats(statfile)
172## s = pstats.Stats(statfile)
173## s.strip_dirs().sort_stats('time').print_stats(10)
174
175 def __set_delegate(self):
176 self.__delegate = self['delegate']
Barry Warsawbc689301998-02-17 03:09:40 +0000177
178
179 #
180 # public interface
181 #
182
183 def set_color(self, obj, rgbtuple):
Barry Warsaw35ae8641998-02-13 21:28:47 +0000184 red, green, blue = rgbtuple
Barry Warsawf67a50c1998-02-18 00:05:59 +0000185 assert self.__generator
186 i = 1
187 chip = 0
188 chips = self.__chips = []
189 tclcmd = []
190 for t in self.__generator(self.__numchips, rgbtuple):
191 rrggbb = ColorDB.triplet_to_rrggbb(t)
192 chips.append(rrggbb)
193## self.__canvas.itemconfigure(i,
194## fill=rrggbb,
195## outline=rrggbb)
196 tclcmd.append(self.__canvas._w)
197 tclcmd.append('itemconfigure')
198 tclcmd.append(`i`)
199 tclcmd.append('-fill')
200 tclcmd.append(rrggbb)
201 tclcmd.append('-outline')
202 tclcmd.append(rrggbb)
203 tclcmd.append('\n')
204 tred, tgreen, tblue = t
205 if tred <= red and tgreen <= green and tblue <= blue:
206 chip = i
207 i = i + 1
208 # call the raw tcl script
209 script = string.join(tclcmd, ' ')
210 self.__canvas.tk.eval(script)
Barry Warsaw35ae8641998-02-13 21:28:47 +0000211
Barry Warsawf67a50c1998-02-18 00:05:59 +0000212 # get the arrow's text
213 coloraxis = rgbtuple[self.__axis]
214 text = repr(coloraxis)
215
216 # move the arrow, and set it's text
217 if coloraxis <= 128:
218 # use the left chip
219 self.__leftarrow.set_text(text)
220 self.__leftarrow.move_to(self.__arrow_x(chip-1))
221 self.__rightarrow.move_to(-100)
222 else:
223 # use the right chip
224 self.__rightarrow.set_text(text)
225 self.__rightarrow.move_to(self.__arrow_x(chip-1))
226 self.__leftarrow.move_to(-100)
227 # and set the chip's outline
228 pmwrgb = ColorDB.triplet_to_pmwrgb(rgbtuple)
229 b = Pmw.Color.rgb2brightness(pmwrgb)
230 if b <= 0.5:
231 outline = 'white'
232 else:
233 outline = 'black'
234 self.__canvas.itemconfigure(chip, outline=outline)