|
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 types import StringType |
|
17 from Tkinter import * |
|
18 import ColorDB |
|
19 |
|
20 |
|
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 |
|
81 class ChipViewer: |
|
82 def __init__(self, switchboard, master=None): |
|
83 self.__sb = switchboard |
|
84 self.__frame = Frame(master, relief=RAISED, borderwidth=1) |
|
85 self.__frame.grid(row=3, column=0, ipadx=5, sticky='NSEW') |
|
86 # create the chip that will display the currently selected color |
|
87 # exactly |
|
88 self.__sframe = Frame(self.__frame) |
|
89 self.__sframe.grid(row=0, column=0) |
|
90 self.__selected = ChipWidget(self.__sframe, text='Selected') |
|
91 # create the chip that will display the nearest real X11 color |
|
92 # database color name |
|
93 self.__nframe = Frame(self.__frame) |
|
94 self.__nframe.grid(row=0, column=1) |
|
95 self.__nearest = ChipWidget(self.__nframe, text='Nearest', |
|
96 presscmd = self.__buttonpress, |
|
97 releasecmd = self.__buttonrelease) |
|
98 |
|
99 def update_yourself(self, red, green, blue): |
|
100 # Selected always shows the #rrggbb name of the color, nearest always |
|
101 # shows the name of the nearest color in the database. BAW: should |
|
102 # an exact match be indicated in some way? |
|
103 # |
|
104 # Always use the #rrggbb style to actually set the color, since we may |
|
105 # not be using X color names (e.g. "web-safe" names) |
|
106 colordb = self.__sb.colordb() |
|
107 rgbtuple = (red, green, blue) |
|
108 rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple) |
|
109 # find the nearest |
|
110 nearest = colordb.nearest(red, green, blue) |
|
111 nearest_tuple = colordb.find_byname(nearest) |
|
112 nearest_rrggbb = ColorDB.triplet_to_rrggbb(nearest_tuple) |
|
113 self.__selected.set_color(rrggbb) |
|
114 self.__nearest.set_color(nearest_rrggbb) |
|
115 # set the name and messages areas |
|
116 self.__selected.set_name(rrggbb) |
|
117 if rrggbb == nearest_rrggbb: |
|
118 self.__selected.set_message(nearest) |
|
119 else: |
|
120 self.__selected.set_message('') |
|
121 self.__nearest.set_name(nearest_rrggbb) |
|
122 self.__nearest.set_message(nearest) |
|
123 |
|
124 def __buttonpress(self, event=None): |
|
125 self.__nearest.press() |
|
126 |
|
127 def __buttonrelease(self, event=None): |
|
128 self.__nearest.release() |
|
129 rrggbb = self.__nearest.get_color() |
|
130 red, green, blue = ColorDB.rrggbb_to_triplet(rrggbb) |
|
131 self.__sb.update_views(red, green, blue) |