Improved some error messages for command line processing.
[python/dscho.git] / Tools / pynche / PyncheWidget.py
bloba16cbcdb0505ad1ff7f936d33f83887e7ba33e9a
1 """Main Pynche (Pythonically Natural Color and Hue Editor) widget.
2 """
4 from Tkinter import *
5 import Pmw
6 import ColorDB
7 from ChipWidget import ChipWidget
8 from TypeinWidget import TypeinWidget
9 from StripWidget import StripWidget
10 from OptionsWidget import PyncheOptions
14 ABOUTTEXT = '''Pynche 1.0 -- The Pythonically Natural Color and Hue Editor
15 Copyright (C) 1998 Barry A. Warsaw
17 Pynche is based on ICE 1.2 (Interactive Color Editor), written by
18 Barry A. Warsaw for the SunView window system in 1987.'''
22 def constant(numchips):
23 step = 255.0 / (numchips - 1)
24 start = 0.0
25 seq = []
26 while numchips > 0:
27 seq.append(int(start))
28 start = start + step
29 numchips = numchips - 1
30 return seq
32 # red variations, green+blue = cyan constant
33 def constant_cyan_generator(numchips, rgbtuple):
34 red, green, blue = rgbtuple
35 seq = constant(numchips)
36 return map(None, seq, [green] * numchips, [blue] * numchips)
38 # green variations, red+blue = magenta constant
39 def constant_magenta_generator(numchips, rgbtuple):
40 red, green, blue = rgbtuple
41 seq = constant(numchips)
42 return map(None, [red] * numchips, seq, [blue] * numchips)
44 # blue variations, red+green = yellow constant
45 def constant_yellow_generator(numchips, rgbtuple):
46 red, green, blue = rgbtuple
47 seq = constant(numchips)
48 return map(None, [red] * numchips, [green] * numchips, seq)
52 class PyncheWidget(Pmw.MegaWidget):
53 def __init__(self, colordb, parent=None, **kw):
54 self.__colordb = colordb
55 self.__parent = parent
56 self.__about_dialog = None
57 self.__options_dialog = None
59 options = (('color', (128, 128, 128), self.__set_color),
60 ('delegate', None, None),
62 self.defineoptions(kw, options)
64 # initialize base class -- after defining options
65 Pmw.MegaWidget.__init__(self, parent)
67 # create menubar
68 self.__menubar = Pmw.MenuBar(parent,
69 hull_relief=RAISED,
70 hull_borderwidth=1)
71 self.__menubar.pack(side=TOP, expand=YES, fill=BOTH)
72 self.__menubar.addmenu('File', None)
73 self.__menubar.addmenuitem('File',
74 type=COMMAND,
75 label='Quit',
76 command=self.__quit,
77 accelerator='Alt-Q')
78 parent.bind('<Alt-q>', self.__quit)
79 parent.bind('<Alt-Q>', self.__quit)
81 self.__menubar.addmenu('Help', None, side=RIGHT)
82 self.__menubar.addmenuitem('Help',
83 type=COMMAND,
84 label='About...',
85 command=self.__popup_about,
86 accelerator='Alt-A')
87 parent.bind('<Alt-a>', self.__popup_about)
88 parent.bind('<Alt-A>', self.__popup_about)
90 self.__menubar.addmenu('Edit', None)
91 self.__menubar.addmenuitem('Edit',
92 type=COMMAND,
93 label='Options...',
94 command=self.__popup_options,
95 accelerator='Alt-O')
96 parent.bind('<Alt-o>', self.__popup_options)
97 parent.bind('<Alt-O>', self.__popup_options)
99 # create color selectors
100 group = Pmw.Group(parent, tag_text='Variations')
101 group.pack(side=TOP, expand=YES, fill=BOTH)
102 self.__reds = StripWidget(group.interior(),
103 generator=constant_cyan_generator,
104 axis=0, label='Red Variations')
105 self.__reds.pack()
106 self.__blues = StripWidget(group.interior(),
107 generator=constant_magenta_generator,
108 axis=1, label='Green Variations')
109 self.__blues.pack()
110 self.__greens = StripWidget(group.interior(),
111 generator=constant_yellow_generator,
112 axis=2, label='Blue Variations')
113 self.__greens.pack()
115 # create chip window
116 group = Pmw.Group(parent, tag_text='Current Color')
117 interior = group.interior()
118 group.pack(side=LEFT, expand=YES, fill=BOTH)
119 self.__selected = ChipWidget(interior,
120 label_text='Selected')
121 self.__selected.grid()
122 self.__nearest = ChipWidget(interior,
123 label_text='Nearest')
124 self.__nearest.grid(row=0, column=1)
126 # TBD: this is somewhat bogus, as the code should be in a derived
127 # class of ChipWidget.
128 self.__chip = self.__nearest.component('chip')
129 self.__chip.bind('<ButtonPress-1>', self.__buttonpress)
130 self.__chip.bind('<ButtonRelease-1>', self.__buttonrelease)
132 # create the type-in window
133 self.__typein = TypeinWidget(interior)
134 self.__typein.grid(row=0, column=2)
136 # Check keywords and initialize options
137 self.initialiseoptions(PyncheWidget)
139 self.__typein.configure(delegate=self)
140 self.__reds.configure(delegate=self)
141 self.__greens.configure(delegate=self)
142 self.__blues.configure(delegate=self)
145 # PUBLIC INTERFACE
149 def set_color(self, obj, rgbtuple):
150 nearest = self.__colordb.nearest(rgbtuple)
151 red, green, blue = self.__colordb.find_byname(nearest)
152 # for an exact match, use the color name
153 if (red, green, blue) == rgbtuple:
154 self.__selected.configure(color=nearest)
155 # otherwise, use the #rrggbb name
156 else:
157 rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple)
158 self.__selected.configure(color=rrggbb)
160 # configure all subwidgets
161 self.__nearest.configure(color=nearest)
162 self.__typein.configure(color=rgbtuple)
163 self.__reds.configure(color=rgbtuple)
164 self.__greens.configure(color=rgbtuple)
165 self.__blues.configure(color=rgbtuple)
166 delegate = self['delegate']
167 if delegate:
168 delegate.set_color(self, rgbtuple)
171 # PRIVATE INTERFACE
174 def __set_color(self):
175 self.set_color(self, self['color'])
177 def __buttonpress(self, event=None):
178 self.__chip.configure(relief=SUNKEN)
180 def __buttonrelease(self, event=None):
181 self.__chip.configure(relief=RAISED)
182 color = self.__nearest['color']
183 rgbtuple = self.__colordb.find_byname(color)
184 self.set_color(self, rgbtuple)
186 def __quit(self, event=None):
187 self.__parent.quit()
189 def __popup_about(self, event=None):
190 if not self.__about_dialog:
191 Pmw.aboutversion('1.0')
192 Pmw.aboutcopyright('Copyright (C) 1998 Barry A. Warsaw\n'
193 'All rights reserved')
194 Pmw.aboutcontact('For information about Pynche contact:\n'
195 'Barry A. Warsaw\n'
196 'email: bwarsaw@python.org')
197 self.__about_dialog = Pmw.AboutDialog(
198 applicationname='Pynche -- the PYthonically Natural\n'
199 'Color and Hue Editor')
200 self.__about_dialog.show()
202 def __popup_options(self, event=None):
203 if not self.__options_dialog:
204 self.__options_dialog = PyncheOptions(
205 title='Pynche Options',
206 applycommand=self.__apply)
207 # pop up the window, non-modal
208 self.__options_dialog.deiconify()
210 def __apply(self):
211 self.__typein.set_update_on_typing(
212 self.__options_dialog.get_value('typing'))
213 flag = self.__options_dialog.get_value('dragging')
214 for strip in (self.__reds, self.__greens, self.__blues):
215 strip.set_update_while_dragging(flag)