| 1 | Pynche - The PYthonically Natural Color and Hue Editor | 
|---|
| 2 |  | 
|---|
| 3 | Contact: Barry A. Warsaw | 
|---|
| 4 | Email:   bwarsaw@python.org | 
|---|
| 5 | Version: 1.3 | 
|---|
| 6 |  | 
|---|
| 7 | Introduction | 
|---|
| 8 |  | 
|---|
| 9 | Pynche is a color editor based largely on a similar program that I | 
|---|
| 10 | originally wrote back in 1987 for the Sunview window system.  That | 
|---|
| 11 | editor was called ICE, the Interactive Color Editor.  I'd always | 
|---|
| 12 | wanted to port this program to X but didn't feel like hacking X | 
|---|
| 13 | and C code to do it.  Fast forward many years, to where Python + | 
|---|
| 14 | Tkinter provides such a nice programming environment, with enough | 
|---|
| 15 | power, that I finally buckled down and re-implemented it.  I | 
|---|
| 16 | changed the name because these days, too many other systems have | 
|---|
| 17 | the acronym `ICE'. | 
|---|
| 18 |  | 
|---|
| 19 | Pynche should work with any variant of Python after 1.5.2 | 
|---|
| 20 | (e.g. 2.0.1 and 2.1.1), using Tk 8.0.x.  It's been tested on | 
|---|
| 21 | Solaris 2.6, Windows NT 4, and various Linux distros.  You'll want | 
|---|
| 22 | to be sure to have at least Tk 8.0.3 for Windows.  Also, Pynche is | 
|---|
| 23 | very colormap intensive, so it doesn't work very well on 8-bit | 
|---|
| 24 | graphics cards; 24bit+ graphics cards are so cheap these days, | 
|---|
| 25 | I'll probably never "fix" that. | 
|---|
| 26 |  | 
|---|
| 27 | Pynche must find a text database of colors names in order to | 
|---|
| 28 | provide `nearest' color matching.  Pynche is distributed with an | 
|---|
| 29 | rgb.txt file from the X11R6.4 distribution for this reason, along | 
|---|
| 30 | with other "Web related" database (see below).  You can use a | 
|---|
| 31 | different file with the -d option.  The file xlicense.txt contains | 
|---|
| 32 | the license only for rgb.txt and both files are in the X/ | 
|---|
| 33 | subdirectory. | 
|---|
| 34 |  | 
|---|
| 35 | Pynche is pronounced: Pin'-chee | 
|---|
| 36 |  | 
|---|
| 37 |  | 
|---|
| 38 | Running Standalone | 
|---|
| 39 |  | 
|---|
| 40 | On Unix, start it by running the `pynche' script.  On Windows, run | 
|---|
| 41 | pynche.pyw to inhibit the console window.  When run from the | 
|---|
| 42 | command line, the following options are recognized: | 
|---|
| 43 |  | 
|---|
| 44 | --database file | 
|---|
| 45 | -d file | 
|---|
| 46 | Alternate location of the color database file.  Without this | 
|---|
| 47 | option, the first valid file found will be used (see below). | 
|---|
| 48 |  | 
|---|
| 49 | --initfile file | 
|---|
| 50 | -i file | 
|---|
| 51 | Alternate location of the persistent initialization file.  See | 
|---|
| 52 | the section on Persistency below. | 
|---|
| 53 |  | 
|---|
| 54 | --ignore | 
|---|
| 55 | -X | 
|---|
| 56 | Ignore the persistent initialization file when starting up. | 
|---|
| 57 | Pynche will still write the current option settings to the | 
|---|
| 58 | persistent init file when it quits. | 
|---|
| 59 |  | 
|---|
| 60 | --help | 
|---|
| 61 | -h | 
|---|
| 62 | Print the help message. | 
|---|
| 63 |  | 
|---|
| 64 | initialcolor | 
|---|
| 65 | a Tk color name or #rrggbb color spec to be used as the | 
|---|
| 66 | initially selected color.  This overrides any color saved in | 
|---|
| 67 | the persistent init file.  Since `#' needs to be escaped in | 
|---|
| 68 | many shells, it is optional in the spec (e.g. #45dd1f is the | 
|---|
| 69 | same as 45dd1f). | 
|---|
| 70 |  | 
|---|
| 71 |  | 
|---|
| 72 | Running as a Modal Dialog | 
|---|
| 73 |  | 
|---|
| 74 | Pynche can be run as a modal dialog, inside another application, | 
|---|
| 75 | say as a general color chooser.  In fact, Grail 0.6 uses Pynche | 
|---|
| 76 | and a future version of IDLE may as well.  Pynche supports the API | 
|---|
| 77 | implemented by the Tkinter standard tkColorChooser module, with a | 
|---|
| 78 | few changes as described below.  By importing pyColorChooser from | 
|---|
| 79 | the Pynche package, you can run | 
|---|
| 80 |  | 
|---|
| 81 | pyColorChooser.askcolor() | 
|---|
| 82 |  | 
|---|
| 83 | which will popup Pynche as a modal dialog, and return the selected | 
|---|
| 84 | color. | 
|---|
| 85 |  | 
|---|
| 86 | There are some UI differences when running as a modal | 
|---|
| 87 | vs. standalone.  When running as a modal, there is no "Quit" menu | 
|---|
| 88 | item under the "File" menu.  Instead there are "Okay" and "Cancel" | 
|---|
| 89 | buttons. | 
|---|
| 90 |  | 
|---|
| 91 | When "Okay" is hit, askcolor() returns the tuple | 
|---|
| 92 |  | 
|---|
| 93 | ((r, g, b), "name") | 
|---|
| 94 |  | 
|---|
| 95 | where r, g, and b are red, green, and blue color values | 
|---|
| 96 | respectively (in the range 0 to 255).  "name" will be a color name | 
|---|
| 97 | from the color database if there is an exact match, otherwise it | 
|---|
| 98 | will be an X11 color spec of the form "#rrggbb".  Note that this | 
|---|
| 99 | is different than tkColorChooser, which doesn't know anything | 
|---|
| 100 | about color names. | 
|---|
| 101 |  | 
|---|
| 102 | askcolor() supports the following optional keyword arguments: | 
|---|
| 103 |  | 
|---|
| 104 | color | 
|---|
| 105 | the color to set as the initial selected color | 
|---|
| 106 |  | 
|---|
| 107 | master[*] | 
|---|
| 108 | the master window to use as the parent of the modal | 
|---|
| 109 | dialog.  Without this argument, pyColorChooser will create | 
|---|
| 110 | its own Tkinter.Tk instance as the master.  This may not | 
|---|
| 111 | be what you want. | 
|---|
| 112 |  | 
|---|
| 113 | databasefile | 
|---|
| 114 | similar to the --database option, the value must be a | 
|---|
| 115 | file name | 
|---|
| 116 |  | 
|---|
| 117 | initfile[*] | 
|---|
| 118 | similar to the --initfile option, the value must be a | 
|---|
| 119 | file name | 
|---|
| 120 |  | 
|---|
| 121 | ignore[*] | 
|---|
| 122 | similar to the --ignore flag, the value is a boolean | 
|---|
| 123 |  | 
|---|
| 124 | wantspec | 
|---|
| 125 | When this is true, the "name" field in the return tuple | 
|---|
| 126 | will always be a color spec of the form "#rrggbb".  It | 
|---|
| 127 | will not return a color name even if there is a match; | 
|---|
| 128 | this is so pyColorChooser can exactly match the API of | 
|---|
| 129 | tkColorChooser. | 
|---|
| 130 |  | 
|---|
| 131 | [*] these arguments must be specified the first time | 
|---|
| 132 | askcolor() is used and cannot be changed on subsequent calls. | 
|---|
| 133 |  | 
|---|
| 134 |  | 
|---|
| 135 | The Colorstrip Window | 
|---|
| 136 |  | 
|---|
| 137 | The top part of the main Pynche window contains the "variation | 
|---|
| 138 | strips".  Each strip contains a number of "color chips".  The | 
|---|
| 139 | strips always indicate the currently selected color by a highlight | 
|---|
| 140 | rectangle around the selected color chip, with an arrow pointing | 
|---|
| 141 | to the chip.  Each arrow has an associated number giving you the | 
|---|
| 142 | color value along the variation's axis.  Each variation strip | 
|---|
| 143 | shows you the colors that are reachable from the selected color by | 
|---|
| 144 | varying just one axis of the color solid. | 
|---|
| 145 |  | 
|---|
| 146 | For example, when the selected color is (in Red/Green/Blue | 
|---|
| 147 | notation) 127/127/127, the Red Variations strip shows you every | 
|---|
| 148 | color in the range 0/127/127 to 255/127/127.  Similarly for the | 
|---|
| 149 | green and blue axes.  You can select any color by clicking on its | 
|---|
| 150 | chip.  This will update the highlight rectangle and the arrow, as | 
|---|
| 151 | well as other displays in Pynche. | 
|---|
| 152 |  | 
|---|
| 153 | Click on "Update while dragging" if you want Pynche to update the | 
|---|
| 154 | selected color while you drag along any variation strip (this will | 
|---|
| 155 | be a bit slower).  Click on "Hexadecimal" to display the arrow | 
|---|
| 156 | numbers in hex. | 
|---|
| 157 |  | 
|---|
| 158 | There are also two shortcut buttons in this window, which | 
|---|
| 159 | auto-select Black (0/0/0) and White (255/255/255). | 
|---|
| 160 |  | 
|---|
| 161 |  | 
|---|
| 162 | The Proof Window | 
|---|
| 163 |  | 
|---|
| 164 | In the lower left corner of the main window you see two larger | 
|---|
| 165 | color chips.  The Selected chip shows you a larger version of the | 
|---|
| 166 | color selected in the variation strips, along with its X11 color | 
|---|
| 167 | specification.  The Nearest chip shows you the closest color in | 
|---|
| 168 | the X11 database to the selected color, giving its X11 color | 
|---|
| 169 | specification, and below that, its X11 color name.  When the | 
|---|
| 170 | Selected chip color exactly matches the Nearest chip color, you | 
|---|
| 171 | will see the color name appear below the color specification for | 
|---|
| 172 | the Selected chip. | 
|---|
| 173 |  | 
|---|
| 174 | Clicking on the Nearest color chip selects that color.  Color | 
|---|
| 175 | distance is calculated in the 3D space of the RGB color solid and | 
|---|
| 176 | if more than one color name is the same distance from the selected | 
|---|
| 177 | color, the first one found will be chosen. | 
|---|
| 178 |  | 
|---|
| 179 | Note that there may be more than one X11 color name for the same | 
|---|
| 180 | RGB value.  In that case, the first one found in the text database | 
|---|
| 181 | is designated the "primary" name, and this is shown under the | 
|---|
| 182 | Nearest chip.  The other names are "aliases" and they are visible | 
|---|
| 183 | in the Color List Window (see below). | 
|---|
| 184 |  | 
|---|
| 185 | Both the color specifications and color names are selectable for | 
|---|
| 186 | copying and pasting into another window. | 
|---|
| 187 |  | 
|---|
| 188 |  | 
|---|
| 189 | The Type-in Window | 
|---|
| 190 |  | 
|---|
| 191 | At the lower right of the main window are three entry fields. | 
|---|
| 192 | Here you can type numeric values for any of the three color axes. | 
|---|
| 193 | Legal values are between 0 and 255, and these fields do not allow | 
|---|
| 194 | you to enter illegal values.  You must hit Enter or Tab to select | 
|---|
| 195 | the new color. | 
|---|
| 196 |  | 
|---|
| 197 | Click on "Update while typing" if you want Pynche to select the | 
|---|
| 198 | color on every keystroke (well, every one that produces a legal | 
|---|
| 199 | value!)  Click on "Hexadecimal" to display and enter color values | 
|---|
| 200 | in hex. | 
|---|
| 201 |  | 
|---|
| 202 |  | 
|---|
| 203 | Other Views | 
|---|
| 204 |  | 
|---|
| 205 | There are three secondary windows which are not displayed by | 
|---|
| 206 | default.  You can bring these up via the "View" menu on the main | 
|---|
| 207 | Pynche window. | 
|---|
| 208 |  | 
|---|
| 209 |  | 
|---|
| 210 | The Text Window | 
|---|
| 211 |  | 
|---|
| 212 | The "Text Window" allows you to see what effects various colors | 
|---|
| 213 | have on the standard Tk text widget elements.  In the upper part | 
|---|
| 214 | of the window is a plain Tk text widget and here you can edit the | 
|---|
| 215 | text, select a region of text, etc.  Below this is a button "Track | 
|---|
| 216 | color changes".  When this is turned on, any colors selected in | 
|---|
| 217 | the other windows will change the text widget element specified in | 
|---|
| 218 | the radio buttons below.  When this is turned off, text widget | 
|---|
| 219 | elements are not affected by color selection. | 
|---|
| 220 |  | 
|---|
| 221 | You can choose which element gets changed by color selection by | 
|---|
| 222 | clicking on one of the radio buttons in the bottom part of this | 
|---|
| 223 | window.  Text foreground and background affect the text in the | 
|---|
| 224 | upper part of the window.  Selection foreground and background | 
|---|
| 225 | affect the colors of the primary selection which is what you see | 
|---|
| 226 | when you click the middle button (depending on window system) and | 
|---|
| 227 | drag it through some text. | 
|---|
| 228 |  | 
|---|
| 229 | The Insertion is the insertion cursor in the text window, where | 
|---|
| 230 | new text will be inserted as you type.  The insertion cursor only | 
|---|
| 231 | has a background. | 
|---|
| 232 |  | 
|---|
| 233 |  | 
|---|
| 234 | The Color List Window | 
|---|
| 235 |  | 
|---|
| 236 | The "Color List" window shows every named color in the color name | 
|---|
| 237 | database (this window may take a while to come up).  In the upper | 
|---|
| 238 | part of the window you see a scrolling list of all the color names | 
|---|
| 239 | in the database, in alphabetical order.  Click on any color to | 
|---|
| 240 | select it.  In the bottom part of the window is displayed any | 
|---|
| 241 | aliases for the selected color (those color names that have the | 
|---|
| 242 | same RGB value, but were found later in the text database).  For | 
|---|
| 243 | example, find the color "Black" and you'll see that its aliases | 
|---|
| 244 | are "gray0" and "grey0". | 
|---|
| 245 |  | 
|---|
| 246 | If the color has no aliases you'll see "<no aliases>" here.  If you | 
|---|
| 247 | just want to see if a color has an alias, and do not want to select a | 
|---|
| 248 | color when you click on it, turn off "Update on Click". | 
|---|
| 249 |  | 
|---|
| 250 | Note that the color list is always updated when a color is selected | 
|---|
| 251 | from the main window.  There's no way to turn this feature off.  If | 
|---|
| 252 | the selected color has no matching color name you'll see | 
|---|
| 253 | "<no matching color>" in the Aliases window. | 
|---|
| 254 |  | 
|---|
| 255 |  | 
|---|
| 256 | The Details Window | 
|---|
| 257 |  | 
|---|
| 258 | The "Details" window gives you more control over color selection | 
|---|
| 259 | than just clicking on a color chip in the main window.  The row of | 
|---|
| 260 | buttons along the top apply the specified increment and decrement | 
|---|
| 261 | amounts to the selected color.  These delta amounts are applied to | 
|---|
| 262 | the variation strips specified by the check boxes labeled "Move | 
|---|
| 263 | Sliders".  Thus if just Red and Green are selected, hitting -10 | 
|---|
| 264 | will subtract 10 from the color value along the red and green | 
|---|
| 265 | variation only.  Note the message under the checkboxes; this | 
|---|
| 266 | indicates the primary color level being changed when more than one | 
|---|
| 267 | slider is tied together.  For example, if Red and Green are | 
|---|
| 268 | selected, you will be changing the Yellow level of the selected | 
|---|
| 269 | color. | 
|---|
| 270 |  | 
|---|
| 271 | The "At Boundary" behavior determines what happens when any color | 
|---|
| 272 | variation hits either the lower or upper boundaries (0 or 255) as | 
|---|
| 273 | a result of clicking on the top row buttons: | 
|---|
| 274 |  | 
|---|
| 275 | Stop | 
|---|
| 276 | When the increment or decrement would send any of the tied | 
|---|
| 277 | variations out of bounds, the entire delta is discarded. | 
|---|
| 278 |  | 
|---|
| 279 | Wrap Around | 
|---|
| 280 | When the increment or decrement would send any of the tied | 
|---|
| 281 | variations out of bounds, the out of bounds value is wrapped | 
|---|
| 282 | around to the other side.  Thus if red were at 238 and +25 | 
|---|
| 283 | were clicked, red would have the value 7. | 
|---|
| 284 |  | 
|---|
| 285 | Preserve Distance | 
|---|
| 286 | When the increment or decrement would send any of the tied | 
|---|
| 287 | variations out of bounds, all tied variations are wrapped as | 
|---|
| 288 | one, so as to preserve the distance between them.  Thus if | 
|---|
| 289 | green and blue were tied, and green was at 238 while blue was | 
|---|
| 290 | at 223, and +25 were clicked, green would be at 15 and blue | 
|---|
| 291 | would be at 0. | 
|---|
| 292 |  | 
|---|
| 293 | Squash | 
|---|
| 294 | When the increment or decrement would send any of the tied | 
|---|
| 295 | variations out of bounds, the out of bounds variation is set | 
|---|
| 296 | to the ceiling of 255 or floor of 0, as appropriate.  In this | 
|---|
| 297 | way, all tied variations are squashed to one edge or the | 
|---|
| 298 | other. | 
|---|
| 299 |  | 
|---|
| 300 | The top row buttons have the following keyboard accelerators: | 
|---|
| 301 |  | 
|---|
| 302 | -25 == Shift Left Arrow | 
|---|
| 303 | -10 == Control Left Arrow | 
|---|
| 304 | -1 == Left Arrow | 
|---|
| 305 | +1 == Right Arrow | 
|---|
| 306 | +10 == Control Right Arrow | 
|---|
| 307 | +25 == Shift Right Arrow | 
|---|
| 308 |  | 
|---|
| 309 |  | 
|---|
| 310 | Keyboard Accelerators | 
|---|
| 311 |  | 
|---|
| 312 | Alt-w in any secondary window dismisses the window.  In the main | 
|---|
| 313 | window it exits Pynche (except when running as a modal). | 
|---|
| 314 |  | 
|---|
| 315 | Alt-q in any window exits Pynche (except when running as a modal). | 
|---|
| 316 |  | 
|---|
| 317 |  | 
|---|
| 318 | Persistency | 
|---|
| 319 |  | 
|---|
| 320 | Pynche remembers various settings of options and colors between | 
|---|
| 321 | invocations, storing these values in a `persistent initialization | 
|---|
| 322 | file'.  The actual location of this file is specified by the | 
|---|
| 323 | --initfile option (see above), and defaults to ~/.pynche. | 
|---|
| 324 |  | 
|---|
| 325 | When Pynche exits, it saves these values in the init file, and | 
|---|
| 326 | re-reads them when it starts up.  There is no locking on this | 
|---|
| 327 | file, so if you run multiple instances of Pynche at a time, you | 
|---|
| 328 | may clobber the init file. | 
|---|
| 329 |  | 
|---|
| 330 | The actual options stored include | 
|---|
| 331 |  | 
|---|
| 332 | - the currently selected color | 
|---|
| 333 |  | 
|---|
| 334 | - all settings of checkbox and radio button options in all windows | 
|---|
| 335 |  | 
|---|
| 336 | - the contents of the text window, the current text selection and | 
|---|
| 337 | insertion point, and all current text widget element color | 
|---|
| 338 | settings. | 
|---|
| 339 |  | 
|---|
| 340 | - the name of the color database file (but not its contents) | 
|---|
| 341 |  | 
|---|
| 342 | You can inhibit Pynche from reading the init file by supplying the | 
|---|
| 343 | --ignore option on the command line.  However, you cannot suppress | 
|---|
| 344 | the storing of the settings in the init file on Pynche exit.  If | 
|---|
| 345 | you really want to do this, use /dev/null as the init file, using | 
|---|
| 346 | --initfile. | 
|---|
| 347 |  | 
|---|
| 348 |  | 
|---|
| 349 | Color Name Database Files | 
|---|
| 350 |  | 
|---|
| 351 | Pynche uses a color name database file to calculate the nearest | 
|---|
| 352 | color to the selected color, and to display in the Color List | 
|---|
| 353 | view.  Several files are distributed with Pynche, described | 
|---|
| 354 | below.  By default, the X11 color name database file is selected. | 
|---|
| 355 | Other files: | 
|---|
| 356 |  | 
|---|
| 357 | html40colors.txt -- the HTML 4.0 guaranteed color names | 
|---|
| 358 |  | 
|---|
| 359 | websafe.txt -- the 216 "Web-safe" colors that Netscape and MSIE | 
|---|
| 360 | guarantee will not be dithered.  These are specified in #rrggbb | 
|---|
| 361 | format for both values and names | 
|---|
| 362 |  | 
|---|
| 363 | webcolors.txt -- The 140 color names that Tim Peters and his | 
|---|
| 364 | sister say NS and MSIE both understand (with some controversy over | 
|---|
| 365 | AliceBlue). | 
|---|
| 366 |  | 
|---|
| 367 | namedcolors.txt -- an alternative set of Netscape colors. | 
|---|
| 368 |  | 
|---|
| 369 | You can switch between files by choosing "Load palette..." from | 
|---|
| 370 | the "File" menu.  This brings up a standard Tk file dialog. | 
|---|
| 371 | Choose the file you want and then click "Ok".  If Pynche | 
|---|
| 372 | understands the format in this file, it will load the database and | 
|---|
| 373 | update the appropriate windows.  If not, it will bring up an error | 
|---|
| 374 | dialog. | 
|---|
| 375 |  | 
|---|
| 376 |  | 
|---|
| 377 | To Do | 
|---|
| 378 |  | 
|---|
| 379 | Here's a brief list of things I want to do (some mythical day): | 
|---|
| 380 |  | 
|---|
| 381 | - Better support for resizing the top level windows | 
|---|
| 382 |  | 
|---|
| 383 | - More output views, e.g. color solids | 
|---|
| 384 |  | 
|---|
| 385 | - Have the notion of a `last color selected'; this may require a | 
|---|
| 386 | new output view | 
|---|
| 387 |  | 
|---|
| 388 | - Support setting the font in the text view | 
|---|
| 389 |  | 
|---|
| 390 | - Support distutils setup.py for installation | 
|---|
| 391 |  | 
|---|
| 392 | I'm open to suggestions! | 
|---|
| 393 |  | 
|---|
| 394 |  | 
|---|
| 395 |  | 
|---|
| 396 |  | 
|---|
| 397 | Local Variables: | 
|---|
| 398 | indent-tabs-mode: nil | 
|---|
| 399 | End: | 
|---|