blob: b2294de7575ba9cd311b3e3df10785d85ad95ce1 [file] [log] [blame]
Barry Warsaw3fe1b141998-11-18 03:45:09 +00001"""Pynche -- The PYthon Natural Color and Hue Editor.
2
Barry Warsaw64039911998-12-15 01:02:51 +00003Contact: Barry Warsaw
Barry Warsaw3fe1b141998-11-18 03:45:09 +00004Email: bwarsaw@python.org
5Version: %(__version__)s
Barry Warsaw516f1891998-01-27 03:19:00 +00006
7Pynche is based largely on a similar color editor I wrote years ago for the
8Sunview window system. That editor was called ICE: the Interactive Color
9Editor. I'd always wanted to port the editor to X but didn't feel like
10hacking X and C code to do it. Fast forward many years, to where Python +
Barry Warsaw04c78861998-09-28 16:28:04 +000011Tkinter provides such a nice programming environment, with enough power, that
12I finally buckled down and implemented it. I changed the name because these
13days, too many other systems have the acronym `ICE'.
Barry Warsaw516f1891998-01-27 03:19:00 +000014
Barry Warsaw04c78861998-09-28 16:28:04 +000015This program currently requires Python 1.5 with Tkinter. It has only been
16tested on Solaris 2.6. Feedback is greatly appreciated. Send email to
17bwarsaw@python.org
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000018
Barry Warsaw3fe1b141998-11-18 03:45:09 +000019Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-v] [-h] [initialcolor]
Barry Warsaw516f1891998-01-27 03:19:00 +000020
21Where:
Barry Warsaw04c78861998-09-28 16:28:04 +000022 --database file
23 -d file
24 Alternate location of a color database file
Barry Warsaweab81a91998-02-11 18:56:13 +000025
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000026 --initfile file
27 -i file
28 Alternate location of the initialization file. This file contains a
29 persistent database of the current Pynche options and color. This
30 means that Pynche restores its option settings and current color when
31 it restarts, using this file (unless the -X option is used). The
32 default is ~/.pynche
33
34 --ignore
35 -X
36 Ignore the initialization file when starting up. Pynche will still
37 write the current option settings to this file when it quits.
38
Barry Warsaw3fe1b141998-11-18 03:45:09 +000039 --version
40 -v
41 print the version number
42
Barry Warsaw516f1891998-01-27 03:19:00 +000043 --help
44 -h
45 print this message
46
Barry Warsaw04c78861998-09-28 16:28:04 +000047 initialcolor
48 initial color, as a color name or #RRGGBB format
49
Barry Warsaw516f1891998-01-27 03:19:00 +000050"""
51
Barry Warsawd515a7e1999-04-26 23:18:07 +000052__version__ = '1.0'
Barry Warsaw516f1891998-01-27 03:19:00 +000053
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000054import sys
Barry Warsaw6bfd6551998-10-06 20:44:14 +000055import os
Barry Warsawd0e1e511998-12-03 19:49:13 +000056import string
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000057import getopt
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000058import ColorDB
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000059from PyncheWidget import PyncheWidget
Barry Warsaw04c78861998-09-28 16:28:04 +000060from Switchboard import Switchboard
Barry Warsaw63c9e981998-09-28 23:41:53 +000061from StripViewer import StripViewer
Barry Warsaw4ab5d851998-10-01 16:47:06 +000062from ChipViewer import ChipViewer
63from TypeinViewer import TypeinViewer
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000064
65
66
67PROGRAM = sys.argv[0]
68
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000069# Default locations of rgb.txt or other textual color database
70RGB_TXT = [
71 # Solaris OpenWindows
72 '/usr/openwin/lib/rgb.txt',
Barry Warsawc2aadcd1999-04-23 16:24:00 +000073 # Linux
74 '/usr/lib/X11/rgb.txt',
Barry Warsaw6bfd6551998-10-06 20:44:14 +000075 # The X11R6.4 rgb.txt file
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000076 os.path.join(sys.path[0], 'X/rgb.txt'),
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000077 # add more here
78 ]
79
80
81
Barry Warsawd0e1e511998-12-03 19:49:13 +000082def docstring():
83 return string.rstrip(__doc__ % globals())
84
85
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000086def usage(status, msg=''):
Barry Warsawd0e1e511998-12-03 19:49:13 +000087 print docstring()
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000088 if msg:
Barry Warsaw3fe1b141998-11-18 03:45:09 +000089 print msg
Barry Warsawf7c1e5a1998-01-31 23:39:28 +000090 sys.exit(status)
91
92
93
Barry Warsawe7f4a471998-10-06 19:50:33 +000094def initial_color(s, colordb):
95 # function called on every color
96 def scan_color(s, colordb=colordb):
97 try:
98 r, g, b = colordb.find_byname(s)
99 except ColorDB.BadColor:
100 try:
101 r, g, b = ColorDB.rrggbb_to_triplet(s)
102 except ColorDB.BadColor:
103 return None, None, None
104 return r, g, b
105 #
106 # First try the passed in color
107 r, g, b = scan_color(s)
108 if r is None:
109 # try the same color with '#' prepended, since some shells require
110 # this to be escaped, which is a pain
111 r, g, b = scan_color('#' + s)
112 if r is None:
113 print 'Bad initial color, using gray50:', s
114 r, g, b = scan_color('gray50')
115 if r is None:
116 usage(1, 'Cannot find an initial color to use')
117 # does not return
118 return r, g, b
119
120
121
Barry Warsawca07ba01998-10-22 03:25:59 +0000122def build(master=None, initialcolor=None, initfile=None, ignore=None):
Barry Warsawca07ba01998-10-22 03:25:59 +0000123 # create all output widgets
Barry Warsaw0604d721999-04-26 23:17:16 +0000124 s = Switchboard(not ignore and initfile)
125
126 # load the color database
127 colordb = None
128 try:
129 dbfile = s.optiondb()['DBFILE']
130 colordb = ColorDB.get_colordb(dbfile)
131 except (KeyError, IOError):
132 # scoot through the files listed above to try to find a usable color
133 # database file
134 for f in RGB_TXT:
135 try:
136 colordb = ColorDB.get_colordb(f)
137 if colordb:
138 break
139 except IOError:
140 pass
141 if not colordb:
142 usage(1, 'No color database file found, see the -d option.')
143 s.set_colordb(colordb)
Barry Warsawca07ba01998-10-22 03:25:59 +0000144
145 # create the application window decorations
146 app = PyncheWidget(__version__, s, master=master)
147 w = app.window()
148
Barry Warsawb61a28e1999-04-27 18:43:47 +0000149 # these built-in viewers live inside the main Pynche window
Barry Warsawca07ba01998-10-22 03:25:59 +0000150 s.add_view(StripViewer(s, w))
151 s.add_view(ChipViewer(s, w))
152 s.add_view(TypeinViewer(s, w))
153
154 # get the initial color as components and set the color on all views. if
155 # there was no initial color given on the command line, use the one that's
156 # stored in the option database
157 if initialcolor is None:
158 optiondb = s.optiondb()
159 red = optiondb.get('RED')
160 green = optiondb.get('GREEN')
161 blue = optiondb.get('BLUE')
162 # but if there wasn't any stored in the database, use grey50
163 if red is None or blue is None or green is None:
164 red, green, blue = initial_color('grey50', colordb)
165 else:
166 red, green, blue = initial_color(initialcolor, colordb)
167 s.update_views(red, green, blue)
168 return app, s
169
170
171def run(app, s):
172 try:
173 app.start()
174 except KeyboardInterrupt:
175 pass
Barry Warsawca07ba01998-10-22 03:25:59 +0000176
177
178
Barry Warsawf7c1e5a1998-01-31 23:39:28 +0000179def main():
Barry Warsawf7c1e5a1998-01-31 23:39:28 +0000180 try:
Barry Warsaw04c78861998-09-28 16:28:04 +0000181 opts, args = getopt.getopt(
182 sys.argv[1:],
Barry Warsaw3fe1b141998-11-18 03:45:09 +0000183 'hd:i:Xv',
184 ['database=', 'initfile=', 'ignore', 'help', 'version'])
Barry Warsawf7c1e5a1998-01-31 23:39:28 +0000185 except getopt.error, msg:
186 usage(1, msg)
187
Barry Warsaw04c78861998-09-28 16:28:04 +0000188 if len(args) == 0:
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000189 initialcolor = None
Barry Warsaw04c78861998-09-28 16:28:04 +0000190 elif len(args) == 1:
191 initialcolor = args[0]
192 else:
Barry Warsawf7c1e5a1998-01-31 23:39:28 +0000193 usage(1)
194
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000195 ignore = 0
196 initfile = os.path.expanduser('~/.pynche')
Barry Warsawf7c1e5a1998-01-31 23:39:28 +0000197 for opt, arg in opts:
198 if opt in ('-h', '--help'):
199 usage(0)
Barry Warsaw3fe1b141998-11-18 03:45:09 +0000200 elif opt in ('-v', '--version'):
201 print '''\
202Pynche -- The PYthon Natural Color and Hue Editor.
Barry Warsaw64039911998-12-15 01:02:51 +0000203Contact: Barry Warsaw
Barry Warsaw3fe1b141998-11-18 03:45:09 +0000204Email: bwarsaw@python.org
205Version: %s''' % __version__
206 sys.exit(0)
Barry Warsaw04c78861998-09-28 16:28:04 +0000207 elif opt in ('-d', '--database'):
208 RGB_TXT.insert(0, arg)
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000209 elif opt in ('-X', '--ignore'):
210 ignore = 1
211 elif opt in ('-i', '--initfile'):
212 initfile = arg
Barry Warsawf7c1e5a1998-01-31 23:39:28 +0000213
Barry Warsaw877d2991998-10-22 18:45:52 +0000214 app, sb = build(initialcolor=initialcolor,
215 initfile=initfile,
216 ignore=ignore)
217 run(app, sb)
218 sb.save_views()
Barry Warsawf7c1e5a1998-01-31 23:39:28 +0000219
220
221if __name__ == '__main__':
222 main()