|
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 |
|
20 class 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 |
|
80 class 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) |