1 """Main Pynche (Pythonically Natural Color and Hue Editor) widget.
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)
27 seq
.append(int(start
))
29 numchips
= numchips
- 1
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
)
68 self
.__menubar
= Pmw
.MenuBar(parent
,
71 self
.__menubar
.pack(side
=TOP
, expand
=YES
, fill
=BOTH
)
72 self
.__menubar
.addmenu('File', None)
73 self
.__menubar
.addmenuitem('File',
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',
85 command
=self
.__popup
_about
,
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',
94 command
=self
.__popup
_options
,
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')
106 self
.__blues
= StripWidget(group
.interior(),
107 generator
=constant_magenta_generator
,
108 axis
=1, label
='Green Variations')
110 self
.__greens
= StripWidget(group
.interior(),
111 generator
=constant_yellow_generator
,
112 axis
=2, label
='Blue Variations')
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
)
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
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']
168 delegate
.set_color(self
, rgbtuple
)
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):
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'
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()
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
)