1"""Chip viewer and widget. 2 3In the lower left corner of the main Pynche window, you will see two 4ChipWidgets, one for the selected color and one for the nearest color. The 5selected color is the actual RGB value expressed as an X11 #COLOR name. The 6nearest color is the named color from the X11 database that is closest to the 7selected color in 3D space. There may be other colors equally close, but the 8nearest one is the first one found. 9 10Clicking on the nearest color chip selects that named color. 11 12The ChipViewer class includes the entire lower left quandrant; i.e. both the 13selected and nearest ChipWidgets. 14""" 15 16from Tkinter import * 17import ColorDB 18 19 20class ChipWidget: 21 _WIDTH = 150 22 _HEIGHT = 80 23 24 def __init__(self, 25 master = None, 26 width = _WIDTH, 27 height = _HEIGHT, 28 text = 'Color', 29 initialcolor = 'blue', 30 presscmd = None, 31 releasecmd = None): 32 # create the text label 33 self.__label = Label(master, text=text) 34 self.__label.grid(row=0, column=0) 35 # create the color chip, implemented as a frame 36 self.__chip = Frame(master, relief=RAISED, borderwidth=2, 37 width=width, 38 height=height, 39 background=initialcolor) 40 self.__chip.grid(row=1, column=0) 41 # create the color name 42 self.__namevar = StringVar() 43 self.__namevar.set(initialcolor) 44 self.__name = Entry(master, textvariable=self.__namevar, 45 relief=FLAT, justify=CENTER, state=DISABLED, 46 font=self.__label['font']) 47 self.__name.grid(row=2, column=0) 48 # create the message area 49 self.__msgvar = StringVar() 50 self.__name = Entry(master, textvariable=self.__msgvar, 51 relief=FLAT, justify=CENTER, state=DISABLED, 52 font=self.__label['font']) 53 self.__name.grid(row=3, column=0) 54 # set bindings 55 if presscmd: 56 self.__chip.bind('<ButtonPress-1>', presscmd) 57 if releasecmd: 58 self.__chip.bind('<ButtonRelease-1>', releasecmd) 59 60 def set_color(self, color): 61 self.__chip.config(background=color) 62 63 def get_color(self): 64 return self.__chip['background'] 65 66 def set_name(self, colorname): 67 self.__namevar.set(colorname) 68 69 def set_message(self, message): 70 self.__msgvar.set(message) 71 72 def press(self): 73 self.__chip.configure(relief=SUNKEN) 74 75 def release(self): 76 self.__chip.configure(relief=RAISED) 77 78 79 80class ChipViewer: 81 def __init__(self, switchboard, master=None): 82 self.__sb = switchboard 83 self.__frame = Frame(master, relief=RAISED, borderwidth=1) 84 self.__frame.grid(row=3, column=0, ipadx=5, sticky='NSEW') 85 # create the chip that will display the currently selected color 86 # exactly 87 self.__sframe = Frame(self.__frame) 88 self.__sframe.grid(row=0, column=0) 89 self.__selected = ChipWidget(self.__sframe, text='Selected') 90 # create the chip that will display the nearest real X11 color 91 # database color name 92 self.__nframe = Frame(self.__frame) 93 self.__nframe.grid(row=0, column=1) 94 self.__nearest = ChipWidget(self.__nframe, text='Nearest', 95 presscmd = self.__buttonpress, 96 releasecmd = self.__buttonrelease) 97 98 def update_yourself(self, red, green, blue): 99 # Selected always shows the #rrggbb name of the color, nearest always 100 # shows the name of the nearest color in the database. BAW: should 101 # an exact match be indicated in some way? 102 # 103 # Always use the #rrggbb style to actually set the color, since we may 104 # not be using X color names (e.g. "web-safe" names) 105 colordb = self.__sb.colordb() 106 rgbtuple = (red, green, blue) 107 rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple) 108 # find the nearest 109 nearest = colordb.nearest(red, green, blue) 110 nearest_tuple = colordb.find_byname(nearest) 111 nearest_rrggbb = ColorDB.triplet_to_rrggbb(nearest_tuple) 112 self.__selected.set_color(rrggbb) 113 self.__nearest.set_color(nearest_rrggbb) 114 # set the name and messages areas 115 self.__selected.set_name(rrggbb) 116 if rrggbb == nearest_rrggbb: 117 self.__selected.set_message(nearest) 118 else: 119 self.__selected.set_message('') 120 self.__nearest.set_name(nearest_rrggbb) 121 self.__nearest.set_message(nearest) 122 123 def __buttonpress(self, event=None): 124 self.__nearest.press() 125 126 def __buttonrelease(self, event=None): 127 self.__nearest.release() 128 rrggbb = self.__nearest.get_color() 129 red, green, blue = ColorDB.rrggbb_to_triplet(rrggbb) 130 self.__sb.update_views(red, green, blue) 131