1998-01-27 03:19:00 +00:00
|
|
|
|
"""Pynche: The PYthon Natural Color and Hue Editor.
|
|
|
|
|
|
|
|
|
|
Pynche is based largely on a similar color editor I wrote years ago for the
|
|
|
|
|
Sunview window system. That editor was called ICE: the Interactive Color
|
|
|
|
|
Editor. I'd always wanted to port the editor to X but didn't feel like
|
|
|
|
|
hacking X and C code to do it. Fast forward many years, to where Python +
|
1998-09-28 16:28:04 +00:00
|
|
|
|
Tkinter provides such a nice programming environment, with enough power, that
|
|
|
|
|
I finally buckled down and implemented it. I changed the name because these
|
|
|
|
|
days, too many other systems have the acronym `ICE'.
|
1998-01-27 03:19:00 +00:00
|
|
|
|
|
1998-09-28 16:28:04 +00:00
|
|
|
|
This program currently requires Python 1.5 with Tkinter. It has only been
|
|
|
|
|
tested on Solaris 2.6. Feedback is greatly appreciated. Send email to
|
|
|
|
|
bwarsaw@python.org
|
1998-01-31 23:39:28 +00:00
|
|
|
|
|
1998-10-20 20:45:46 +00:00
|
|
|
|
Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-h] [initialcolor]
|
1998-01-27 03:19:00 +00:00
|
|
|
|
|
|
|
|
|
Where:
|
1998-09-28 16:28:04 +00:00
|
|
|
|
--database file
|
|
|
|
|
-d file
|
|
|
|
|
Alternate location of a color database file
|
1998-02-11 18:56:13 +00:00
|
|
|
|
|
1998-10-20 20:45:46 +00:00
|
|
|
|
--initfile file
|
|
|
|
|
-i file
|
|
|
|
|
Alternate location of the initialization file. This file contains a
|
|
|
|
|
persistent database of the current Pynche options and color. This
|
|
|
|
|
means that Pynche restores its option settings and current color when
|
|
|
|
|
it restarts, using this file (unless the -X option is used). The
|
|
|
|
|
default is ~/.pynche
|
|
|
|
|
|
|
|
|
|
--ignore
|
|
|
|
|
-X
|
|
|
|
|
Ignore the initialization file when starting up. Pynche will still
|
|
|
|
|
write the current option settings to this file when it quits.
|
|
|
|
|
|
1998-01-27 03:19:00 +00:00
|
|
|
|
--help
|
|
|
|
|
-h
|
|
|
|
|
print this message
|
|
|
|
|
|
1998-09-28 16:28:04 +00:00
|
|
|
|
initialcolor
|
|
|
|
|
initial color, as a color name or #RRGGBB format
|
|
|
|
|
|
1998-01-27 03:19:00 +00:00
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
__version__ = '1.0'
|
|
|
|
|
|
1998-01-31 23:39:28 +00:00
|
|
|
|
import sys
|
1998-10-06 20:44:14 +00:00
|
|
|
|
import os
|
1998-01-31 23:39:28 +00:00
|
|
|
|
import getopt
|
|
|
|
|
import ColorDB
|
|
|
|
|
from PyncheWidget import PyncheWidget
|
1998-09-28 16:28:04 +00:00
|
|
|
|
from Switchboard import Switchboard
|
1998-09-28 23:41:53 +00:00
|
|
|
|
from StripViewer import StripViewer
|
1998-10-01 16:47:06 +00:00
|
|
|
|
from ChipViewer import ChipViewer
|
|
|
|
|
from TypeinViewer import TypeinViewer
|
1998-01-31 23:39:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PROGRAM = sys.argv[0]
|
|
|
|
|
|
|
|
|
|
# Default locations of rgb.txt or other textual color database
|
|
|
|
|
RGB_TXT = [
|
|
|
|
|
# Solaris OpenWindows
|
|
|
|
|
'/usr/openwin/lib/rgb.txt',
|
1998-10-06 20:44:14 +00:00
|
|
|
|
# The X11R6.4 rgb.txt file
|
1998-10-20 20:45:46 +00:00
|
|
|
|
os.path.join(sys.path[0], 'X/rgb.txt'),
|
1998-01-31 23:39:28 +00:00
|
|
|
|
# add more here
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def usage(status, msg=''):
|
1998-10-06 15:21:04 +00:00
|
|
|
|
print __doc__ % globals()
|
1998-01-31 23:39:28 +00:00
|
|
|
|
if msg:
|
|
|
|
|
print msg
|
|
|
|
|
sys.exit(status)
|
|
|
|
|
|
|
|
|
|
|
1998-10-06 19:50:33 +00:00
|
|
|
|
|
|
|
|
|
def initial_color(s, colordb):
|
|
|
|
|
# function called on every color
|
|
|
|
|
def scan_color(s, colordb=colordb):
|
|
|
|
|
try:
|
|
|
|
|
r, g, b = colordb.find_byname(s)
|
|
|
|
|
except ColorDB.BadColor:
|
|
|
|
|
try:
|
|
|
|
|
r, g, b = ColorDB.rrggbb_to_triplet(s)
|
|
|
|
|
except ColorDB.BadColor:
|
|
|
|
|
return None, None, None
|
|
|
|
|
return r, g, b
|
|
|
|
|
#
|
|
|
|
|
# First try the passed in color
|
|
|
|
|
r, g, b = scan_color(s)
|
|
|
|
|
if r is None:
|
|
|
|
|
# try the same color with '#' prepended, since some shells require
|
|
|
|
|
# this to be escaped, which is a pain
|
|
|
|
|
r, g, b = scan_color('#' + s)
|
|
|
|
|
if r is None:
|
|
|
|
|
print 'Bad initial color, using gray50:', s
|
|
|
|
|
r, g, b = scan_color('gray50')
|
|
|
|
|
if r is None:
|
|
|
|
|
usage(1, 'Cannot find an initial color to use')
|
|
|
|
|
# does not return
|
|
|
|
|
return r, g, b
|
|
|
|
|
|
|
|
|
|
|
1998-01-31 23:39:28 +00:00
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
try:
|
1998-09-28 16:28:04 +00:00
|
|
|
|
opts, args = getopt.getopt(
|
|
|
|
|
sys.argv[1:],
|
1998-10-20 20:45:46 +00:00
|
|
|
|
'hd:i:X',
|
|
|
|
|
['database=', 'initfile=', 'ignore', 'help'])
|
1998-01-31 23:39:28 +00:00
|
|
|
|
except getopt.error, msg:
|
|
|
|
|
usage(1, msg)
|
|
|
|
|
|
1998-09-28 16:28:04 +00:00
|
|
|
|
if len(args) == 0:
|
1998-10-20 20:45:46 +00:00
|
|
|
|
initialcolor = None
|
1998-09-28 16:28:04 +00:00
|
|
|
|
elif len(args) == 1:
|
|
|
|
|
initialcolor = args[0]
|
|
|
|
|
else:
|
1998-01-31 23:39:28 +00:00
|
|
|
|
usage(1)
|
|
|
|
|
|
1998-10-20 20:45:46 +00:00
|
|
|
|
ignore = 0
|
|
|
|
|
initfile = os.path.expanduser('~/.pynche')
|
1998-01-31 23:39:28 +00:00
|
|
|
|
for opt, arg in opts:
|
|
|
|
|
if opt in ('-h', '--help'):
|
|
|
|
|
usage(0)
|
1998-09-28 16:28:04 +00:00
|
|
|
|
elif opt in ('-d', '--database'):
|
|
|
|
|
RGB_TXT.insert(0, arg)
|
1998-10-20 20:45:46 +00:00
|
|
|
|
elif opt in ('-X', '--ignore'):
|
|
|
|
|
ignore = 1
|
|
|
|
|
elif opt in ('-i', '--initfile'):
|
|
|
|
|
initfile = arg
|
1998-01-31 23:39:28 +00:00
|
|
|
|
|
|
|
|
|
# create the windows and go
|
|
|
|
|
for f in RGB_TXT:
|
|
|
|
|
try:
|
|
|
|
|
colordb = ColorDB.get_colordb(f)
|
1998-10-06 15:21:04 +00:00
|
|
|
|
if colordb:
|
|
|
|
|
break
|
1998-01-31 23:39:28 +00:00
|
|
|
|
except IOError:
|
|
|
|
|
pass
|
|
|
|
|
else:
|
1998-10-06 15:21:04 +00:00
|
|
|
|
usage(1, 'No color database file found, see the -d option.')
|
1998-01-31 23:39:28 +00:00
|
|
|
|
|
1998-09-28 23:41:53 +00:00
|
|
|
|
# create all output widgets
|
1998-10-20 20:45:46 +00:00
|
|
|
|
s = Switchboard(colordb, not ignore and initfile)
|
1998-10-01 16:47:06 +00:00
|
|
|
|
|
|
|
|
|
# create the application window decorations
|
|
|
|
|
app = PyncheWidget(__version__, s)
|
|
|
|
|
parent = app.parent()
|
|
|
|
|
|
1998-09-28 23:41:53 +00:00
|
|
|
|
s.add_view(StripViewer(s, parent))
|
1998-10-01 16:47:06 +00:00
|
|
|
|
s.add_view(ChipViewer(s, parent))
|
|
|
|
|
s.add_view(TypeinViewer(s, parent))
|
1998-10-20 20:45:46 +00:00
|
|
|
|
|
|
|
|
|
# get the initial color as components and set the color on all views. if
|
|
|
|
|
# there was no initial color given on the command line, use the one that's
|
|
|
|
|
# stored in the option database
|
|
|
|
|
if initialcolor is None:
|
|
|
|
|
optiondb = s.optiondb()
|
|
|
|
|
red = optiondb.get('RED')
|
|
|
|
|
green = optiondb.get('GREEN')
|
|
|
|
|
blue = optiondb.get('BLUE')
|
|
|
|
|
# but if there wasn't any stored in the database, use grey50
|
|
|
|
|
if red is None or blue is None or green is None:
|
|
|
|
|
red, green, blue = initial_color('grey50', colordb)
|
|
|
|
|
else:
|
|
|
|
|
red, green, blue = initial_color(initialcolor, colordb)
|
1998-09-28 23:41:53 +00:00
|
|
|
|
s.update_views(red, green, blue)
|
|
|
|
|
|
1998-01-31 23:39:28 +00:00
|
|
|
|
try:
|
1998-09-28 23:41:53 +00:00
|
|
|
|
app.start()
|
1998-01-31 23:39:28 +00:00
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
pass
|
|
|
|
|
|
1998-10-20 20:45:46 +00:00
|
|
|
|
# save the option database
|
|
|
|
|
s.save_views(initfile)
|
|
|
|
|
|
1998-01-31 23:39:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|