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