mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	 f67a50c2e1
			
		
	
	
		f67a50c2e1
		
	
	
	
	
		
			
			self.__chips now contains the list of rgbtuple values for the
    chips named i - 1 (Tkinter counts from 1, we count from zero).
    The chip number was just the index + 1.  This means color lookup
    need not do an itemcget(), it can just index into __chips.
    instead of calling __canvas.itemconfigure(), we glom up a huge Tcl
    script and call tk.eval() directly.  Actually we do many appends
    to a Python list, then string.join() them together into one huge
    string.  This reduces the overhead of Tkinter but making one fast
    call to Tcl.
		
	
			
		
			
				
	
	
		
			234 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import string
 | ||
| from Tkinter import *
 | ||
| import Pmw
 | ||
| import ColorDB
 | ||
| 
 | ||
| 
 | ||
| class LeftArrow:
 | ||
|     _ARROWWIDTH = 30
 | ||
|     _ARROWHEIGHT = 15
 | ||
|     _YOFFSET = 13
 | ||
|     _TEXTYOFFSET = 1
 | ||
|     _TAG = ('leftarrow',)
 | ||
| 
 | ||
|     def __init__(self, canvas, x):
 | ||
| 	self._canvas = canvas
 | ||
| 	self.__arrow, self.__text = self._create(x)
 | ||
| 	self.move_to(x)
 | ||
| 
 | ||
|     def _create(self, x):
 | ||
| 	arrow = self._canvas.create_line(
 | ||
| 	    x, self._ARROWHEIGHT + self._YOFFSET,
 | ||
| 	    x, self._YOFFSET,
 | ||
| 	    x + self._ARROWWIDTH, self._YOFFSET,
 | ||
| 	    arrow='first',
 | ||
| 	    width=3.0,
 | ||
| 	    tags=self._TAG)
 | ||
| 	text = self._canvas.create_text(
 | ||
| 	    x + self._ARROWWIDTH + 13,
 | ||
| 	    self._ARROWHEIGHT - self._TEXTYOFFSET,
 | ||
| 	    tags=self._TAG,
 | ||
| 	    text='128')
 | ||
| 	return arrow, text
 | ||
| 
 | ||
|     def _x(self):
 | ||
| 	coords = self._canvas.coords(self._TAG)
 | ||
| 	assert coords
 | ||
| 	return coords[0]
 | ||
| 
 | ||
|     def move_to(self, x):
 | ||
| 	deltax = x - self._x()
 | ||
| 	self._canvas.move(self._TAG, deltax, 0)
 | ||
| 
 | ||
|     def set_text(self, text):
 | ||
| 	self._canvas.itemconfigure(self.__text, text=text)
 | ||
| 
 | ||
| 
 | ||
| class RightArrow(LeftArrow):
 | ||
|     _TAG = ('rightarrow',)
 | ||
| 
 | ||
|     def _create(self, x):
 | ||
| 	arrow = self._canvas.create_line(
 | ||
| 	    x, self._YOFFSET,
 | ||
| 	    x + self._ARROWWIDTH, self._YOFFSET,
 | ||
| 	    x + self._ARROWWIDTH, self._ARROWHEIGHT + self._YOFFSET,
 | ||
| 	    arrow='last',
 | ||
| 	    width=3.0,
 | ||
| 	    tags=self._TAG)
 | ||
| 	text = self._canvas.create_text(
 | ||
| 	    x - self._ARROWWIDTH + 15,		  # TBD: kludge
 | ||
| 	    self._ARROWHEIGHT - self._TEXTYOFFSET,
 | ||
| 	    text='128',
 | ||
| 	    tags=self._TAG)
 | ||
| 	return arrow, text
 | ||
| 
 | ||
|     def _x(self):
 | ||
| 	coords = self._canvas.bbox(self._TAG)
 | ||
| 	assert coords
 | ||
| 	return coords[2] - 6			  # TBD: kludge
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| class StripWidget(Pmw.MegaWidget):
 | ||
|     _CHIPHEIGHT = 50
 | ||
|     _CHIPWIDTH = 10
 | ||
|     _NUMCHIPS = 40
 | ||
| 
 | ||
|     def __init__(self, parent=None, **kw):
 | ||
| 	options = (('color',      (128, 128, 128),  self.__set_color),
 | ||
| 		   ('delegate',   None,             self.__set_delegate),
 | ||
| 		   ('chipwidth',  self._CHIPWIDTH,  Pmw.INITOPT),
 | ||
| 		   ('chipheight', self._CHIPHEIGHT, Pmw.INITOPT),
 | ||
| 		   ('numchips',   self._NUMCHIPS,   Pmw.INITOPT),
 | ||
| 		   ('generator',  None,             Pmw.INITOPT),
 | ||
| 		   ('axis',       None,             Pmw.INITOPT),
 | ||
| 		   ('label',      '',               Pmw.INITOPT),
 | ||
| 		   )
 | ||
| 	self.defineoptions(kw, options)
 | ||
| 
 | ||
| 	Pmw.MegaWidget.__init__(self, parent)
 | ||
| 	interiorarg = (self.interior(),)
 | ||
| 
 | ||
| 	# group component contains a convas containing a bunch of objects
 | ||
| 	# (moveable arrow + text label, relief'd rectangle color chips)
 | ||
| 	chipwidth = self.__chipwidth = self['chipwidth']
 | ||
| 	chipheight = self.__chipheight = self['chipheight']
 | ||
| 	numchips = self.__numchips = self['numchips']
 | ||
| 
 | ||
| 	canvaswidth = numchips * (chipwidth + 1)
 | ||
| 	canvasheight = chipheight + 43		  # TBD: Kludge
 | ||
| 
 | ||
| 	# create the canvas and pack it
 | ||
| 	self.__canvas = Canvas(
 | ||
| 	    parent,
 | ||
| 	    width=canvaswidth,
 | ||
| 	    height=canvasheight,
 | ||
| ## 	    borderwidth=2,
 | ||
| ## 	    relief=GROOVE
 | ||
| 	    )
 | ||
| 
 | ||
| 	self.__canvas.pack()
 | ||
| 	self.__canvas.bind('<ButtonRelease-1>',
 | ||
| 			   self.__select_chip)
 | ||
| 	self.__canvas.bind('<B1-Motion>',
 | ||
| 			   self.__select_chip)
 | ||
| 
 | ||
| 	# create the color strip
 | ||
| 	chips = self.__chips = []
 | ||
| 	x = 1
 | ||
| 	y = 30
 | ||
| 	for c in range(self.__numchips):
 | ||
| 	    color = 'grey'
 | ||
| 	    rect = self.__canvas.create_rectangle(
 | ||
| 		x, y, x+chipwidth, y+chipheight,
 | ||
| 		fill=color, outline=color)
 | ||
| 
 | ||
| 	    x = x + chipwidth + 1		  # for outline
 | ||
| 	    chips.append(color)
 | ||
| 
 | ||
| 	# create the string tag
 | ||
| 	self.__label = self.__canvas.create_text(
 | ||
| 	    3, y + chipheight + 8,
 | ||
| 	    text=self['label'],
 | ||
| 	    anchor=W)
 | ||
| 
 | ||
| 	# create the arrow and text item
 | ||
| 	chipx = self.__arrow_x(0)
 | ||
| 	self.__leftarrow = LeftArrow(self.__canvas, chipx)
 | ||
| 
 | ||
| 	chipx = self.__arrow_x(len(chips) - 1)
 | ||
| 	self.__rightarrow = RightArrow(self.__canvas, chipx)
 | ||
| 
 | ||
| 	self.__generator = self['generator']
 | ||
| 	self.__axis = self['axis']
 | ||
| 	assert self.__axis in (0, 1, 2)
 | ||
| 	self.initialiseoptions(StripWidget)
 | ||
| 	self.__delegate = self['delegate']
 | ||
| 
 | ||
|     def __set_color(self):
 | ||
| 	rgbtuple = self['color']
 | ||
| 	self.set_color(self, rgbtuple)
 | ||
| 
 | ||
|     def __arrow_x(self, chipnum):
 | ||
| 	coords = self.__canvas.coords(chipnum+1)
 | ||
| 	assert coords
 | ||
| 	x0, y0, x1, y1 = coords
 | ||
| 	return (x1 + x0) / 2.0
 | ||
| 
 | ||
|     def __select_chip(self, event=None):
 | ||
| 	chip = self.__canvas.find_closest(event.x, event.y)[0]
 | ||
| 	if chip and self.__delegate:
 | ||
| 	    color = self.__chips[chip-1]
 | ||
| 	    rgbtuple = ColorDB.rrggbb_to_triplet(color)
 | ||
| 	    self.__delegate.set_color(self, rgbtuple)
 | ||
| 
 | ||
| ## 	    import profile
 | ||
| ## 	    import pstats
 | ||
| ## 	    import tempfile
 | ||
| ## 	    statfile = tempfile.mktemp()
 | ||
| ## 	    p = profile.Profile()
 | ||
| ## 	    p.runcall(self.__delegate.set_color, self, rgbtuple)
 | ||
| ## 	    p.dump_stats(statfile)
 | ||
| ## 	    s = pstats.Stats(statfile)
 | ||
| ## 	    s.strip_dirs().sort_stats('time').print_stats(10)
 | ||
| 
 | ||
|     def __set_delegate(self):
 | ||
| 	self.__delegate = self['delegate']
 | ||
| 	
 | ||
| 
 | ||
|     #
 | ||
|     # public interface
 | ||
|     #
 | ||
| 
 | ||
|     def set_color(self, obj, rgbtuple):
 | ||
| 	red, green, blue = rgbtuple
 | ||
| 	assert self.__generator
 | ||
| 	i = 1
 | ||
| 	chip = 0
 | ||
| 	chips = self.__chips = []
 | ||
| 	tclcmd = []
 | ||
| 	for t in self.__generator(self.__numchips, rgbtuple):
 | ||
| 	    rrggbb = ColorDB.triplet_to_rrggbb(t)
 | ||
| 	    chips.append(rrggbb)
 | ||
| ## 	    self.__canvas.itemconfigure(i,
 | ||
| ## 					fill=rrggbb,
 | ||
| ## 					outline=rrggbb)
 | ||
| 	    tclcmd.append(self.__canvas._w)
 | ||
| 	    tclcmd.append('itemconfigure')
 | ||
| 	    tclcmd.append(`i`)
 | ||
| 	    tclcmd.append('-fill')
 | ||
| 	    tclcmd.append(rrggbb)
 | ||
| 	    tclcmd.append('-outline')
 | ||
| 	    tclcmd.append(rrggbb)
 | ||
| 	    tclcmd.append('\n')
 | ||
| 	    tred, tgreen, tblue = t
 | ||
| 	    if tred <= red and tgreen <= green and tblue <= blue:
 | ||
| 		chip = i
 | ||
| 	    i = i + 1
 | ||
| 	# call the raw tcl script
 | ||
| 	script = string.join(tclcmd, ' ')
 | ||
| 	self.__canvas.tk.eval(script)
 | ||
| 
 | ||
| 	# get the arrow's text
 | ||
| 	coloraxis = rgbtuple[self.__axis]
 | ||
| 	text = repr(coloraxis)
 | ||
| 
 | ||
| 	# move the arrow, and set it's text
 | ||
| 	if coloraxis <= 128:
 | ||
| 	    # use the left chip
 | ||
| 	    self.__leftarrow.set_text(text)
 | ||
| 	    self.__leftarrow.move_to(self.__arrow_x(chip-1))
 | ||
| 	    self.__rightarrow.move_to(-100)
 | ||
| 	else:
 | ||
| 	    # use the right chip
 | ||
| 	    self.__rightarrow.set_text(text)
 | ||
| 	    self.__rightarrow.move_to(self.__arrow_x(chip-1))
 | ||
| 	    self.__leftarrow.move_to(-100)
 | ||
| 	# and set the chip's outline
 | ||
| 	pmwrgb = ColorDB.triplet_to_pmwrgb(rgbtuple)
 | ||
| 	b = Pmw.Color.rgb2brightness(pmwrgb)
 | ||
| 	if b <= 0.5:
 | ||
| 	    outline = 'white'
 | ||
| 	else:
 | ||
| 	    outline = 'black'
 | ||
| 	self.__canvas.itemconfigure(chip, outline=outline)
 |