summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2022-04-17 22:38:44 (GMT)
committerGitHub <noreply@github.com>2022-04-17 22:38:44 (GMT)
commit7173fd5de0cb259b488828634745c03dbea94e6b (patch)
tree99896e93a25d1efb5394e740a188fd45dfe37583
parentceea0715df33ae6dc3931670b4b749432d4e9707 (diff)
downloadcpython-7173fd5de0cb259b488828634745c03dbea94e6b.zip
cpython-7173fd5de0cb259b488828634745c03dbea94e6b.tar.gz
cpython-7173fd5de0cb259b488828634745c03dbea94e6b.tar.bz2
Remove the ancient Pynche color editor (#91554)
Closes #91551
-rw-r--r--Misc/NEWS.d/next/Tools-Demos/2022-04-14-18-11-46.gh-issue-91551.l_nNT-.rst1
-rw-r--r--PC/layout/main.py2
-rw-r--r--Tools/README2
-rw-r--r--Tools/msi/tools/tools.wixproj8
-rw-r--r--Tools/pynche/ChipViewer.py130
-rw-r--r--Tools/pynche/ColorDB.py271
-rw-r--r--Tools/pynche/DetailsViewer.py273
-rw-r--r--Tools/pynche/ListViewer.py175
-rw-r--r--Tools/pynche/Main.py229
-rw-r--r--Tools/pynche/PyncheWidget.py313
-rw-r--r--Tools/pynche/README398
-rw-r--r--Tools/pynche/StripViewer.py397
-rw-r--r--Tools/pynche/Switchboard.py138
-rw-r--r--Tools/pynche/TextViewer.py188
-rw-r--r--Tools/pynche/TypeinViewer.py161
-rw-r--r--Tools/pynche/X/rgb.txt753
-rw-r--r--Tools/pynche/X/xlicense.txt29
-rw-r--r--Tools/pynche/__init__.py1
-rw-r--r--Tools/pynche/html40colors.txt17
-rw-r--r--Tools/pynche/namedcolors.txt100
-rw-r--r--Tools/pynche/pyColorChooser.py125
-rwxr-xr-xTools/pynche/pynche7
-rwxr-xr-xTools/pynche/pynche.pyw7
-rw-r--r--Tools/pynche/webcolors.txt141
-rw-r--r--Tools/pynche/websafe.txt217
25 files changed, 3 insertions, 4080 deletions
diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-04-14-18-11-46.gh-issue-91551.l_nNT-.rst b/Misc/NEWS.d/next/Tools-Demos/2022-04-14-18-11-46.gh-issue-91551.l_nNT-.rst
new file mode 100644
index 0000000..f0c1866
--- /dev/null
+++ b/Misc/NEWS.d/next/Tools-Demos/2022-04-14-18-11-46.gh-issue-91551.l_nNT-.rst
@@ -0,0 +1 @@
+Remove the ancient Pynche color editor.
diff --git a/PC/layout/main.py b/PC/layout/main.py
index fb6f526..8e69ecc 100644
--- a/PC/layout/main.py
+++ b/PC/layout/main.py
@@ -61,7 +61,7 @@ CDF_FILES = FileSuffixSet(".cdf")
DATA_DIRS = FileNameSet("data")
-TOOLS_DIRS = FileNameSet("scripts", "i18n", "pynche", "demo", "parser")
+TOOLS_DIRS = FileNameSet("scripts", "i18n", "demo", "parser")
TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt")
diff --git a/Tools/README b/Tools/README
index 1f9d927..862bba7 100644
--- a/Tools/README
+++ b/Tools/README
@@ -25,8 +25,6 @@ parser Un-parsing tool to generate code from an AST.
peg_generator PEG-based parser generator (pegen) used for new parser.
-pynche A Tkinter-based color editor.
-
scripts A number of useful single-file programs, e.g. tabnanny.py
by Tim Peters, which checks for inconsistent mixing of
tabs and spaces, and 2to3, which converts Python 2 code
diff --git a/Tools/msi/tools/tools.wixproj b/Tools/msi/tools/tools.wixproj
index b7fc41e..2963048 100644
--- a/Tools/msi/tools/tools.wixproj
+++ b/Tools/msi/tools/tools.wixproj
@@ -15,18 +15,12 @@
<EmbeddedResource Include="*.wxl" />
</ItemGroup>
<ItemGroup>
- <ToolDirectories Include="scripts;i18n;pynche;pynche\X;demo" />
- </ItemGroup>
- <ItemGroup>
<InstallFiles Include="$(PySourcePath)Tools\scripts\**\*.py;
$(PySourcePath)Tools\scripts\**\*.pyw;
$(PySourcePath)Tools\scripts\**\*.txt;
$(PySourcePath)Tools\i18n\**\*.py;
$(PySourcePath)Tools\i18n\**\*.pyw;
$(PySourcePath)Tools\i18n\**\*.txt;
- $(PySourcePath)Tools\pynche\**\*.py;
- $(PySourcePath)Tools\pynche\**\*.pyw;
- $(PySourcePath)Tools\pynche\**\*.txt;
$(PySourcePath)Tools\demo\**\*.py;
$(PySourcePath)Tools\demo\**\*.pyw;
$(PySourcePath)Tools\demo\**\*.txt;
@@ -41,4 +35,4 @@
</ItemGroup>
<Import Project="..\msi.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/Tools/pynche/ChipViewer.py b/Tools/pynche/ChipViewer.py
deleted file mode 100644
index 78139f8..0000000
--- a/Tools/pynche/ChipViewer.py
+++ /dev/null
@@ -1,130 +0,0 @@
-"""Chip viewer and widget.
-
-In the lower left corner of the main Pynche window, you will see two
-ChipWidgets, one for the selected color and one for the nearest color. The
-selected color is the actual RGB value expressed as an X11 #COLOR name. The
-nearest color is the named color from the X11 database that is closest to the
-selected color in 3D space. There may be other colors equally close, but the
-nearest one is the first one found.
-
-Clicking on the nearest color chip selects that named color.
-
-The ChipViewer class includes the entire lower left quandrant; i.e. both the
-selected and nearest ChipWidgets.
-"""
-
-from tkinter import *
-import ColorDB
-
-
-class ChipWidget:
- _WIDTH = 150
- _HEIGHT = 80
-
- def __init__(self,
- master = None,
- width = _WIDTH,
- height = _HEIGHT,
- text = 'Color',
- initialcolor = 'blue',
- presscmd = None,
- releasecmd = None):
- # create the text label
- self.__label = Label(master, text=text)
- self.__label.grid(row=0, column=0)
- # create the color chip, implemented as a frame
- self.__chip = Frame(master, relief=RAISED, borderwidth=2,
- width=width,
- height=height,
- background=initialcolor)
- self.__chip.grid(row=1, column=0)
- # create the color name
- self.__namevar = StringVar()
- self.__namevar.set(initialcolor)
- self.__name = Entry(master, textvariable=self.__namevar,
- relief=FLAT, justify=CENTER, state=DISABLED,
- font=self.__label['font'])
- self.__name.grid(row=2, column=0)
- # create the message area
- self.__msgvar = StringVar()
- self.__name = Entry(master, textvariable=self.__msgvar,
- relief=FLAT, justify=CENTER, state=DISABLED,
- font=self.__label['font'])
- self.__name.grid(row=3, column=0)
- # set bindings
- if presscmd:
- self.__chip.bind('<ButtonPress-1>', presscmd)
- if releasecmd:
- self.__chip.bind('<ButtonRelease-1>', releasecmd)
-
- def set_color(self, color):
- self.__chip.config(background=color)
-
- def get_color(self):
- return self.__chip['background']
-
- def set_name(self, colorname):
- self.__namevar.set(colorname)
-
- def set_message(self, message):
- self.__msgvar.set(message)
-
- def press(self):
- self.__chip.configure(relief=SUNKEN)
-
- def release(self):
- self.__chip.configure(relief=RAISED)
-
-
-
-class ChipViewer:
- def __init__(self, switchboard, master=None):
- self.__sb = switchboard
- self.__frame = Frame(master, relief=RAISED, borderwidth=1)
- self.__frame.grid(row=3, column=0, ipadx=5, sticky='NSEW')
- # create the chip that will display the currently selected color
- # exactly
- self.__sframe = Frame(self.__frame)
- self.__sframe.grid(row=0, column=0)
- self.__selected = ChipWidget(self.__sframe, text='Selected')
- # create the chip that will display the nearest real X11 color
- # database color name
- self.__nframe = Frame(self.__frame)
- self.__nframe.grid(row=0, column=1)
- self.__nearest = ChipWidget(self.__nframe, text='Nearest',
- presscmd = self.__buttonpress,
- releasecmd = self.__buttonrelease)
-
- def update_yourself(self, red, green, blue):
- # Selected always shows the #rrggbb name of the color, nearest always
- # shows the name of the nearest color in the database. BAW: should
- # an exact match be indicated in some way?
- #
- # Always use the #rrggbb style to actually set the color, since we may
- # not be using X color names (e.g. "web-safe" names)
- colordb = self.__sb.colordb()
- rgbtuple = (red, green, blue)
- rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple)
- # find the nearest
- nearest = colordb.nearest(red, green, blue)
- nearest_tuple = colordb.find_byname(nearest)
- nearest_rrggbb = ColorDB.triplet_to_rrggbb(nearest_tuple)
- self.__selected.set_color(rrggbb)
- self.__nearest.set_color(nearest_rrggbb)
- # set the name and messages areas
- self.__selected.set_name(rrggbb)
- if rrggbb == nearest_rrggbb:
- self.__selected.set_message(nearest)
- else:
- self.__selected.set_message('')
- self.__nearest.set_name(nearest_rrggbb)
- self.__nearest.set_message(nearest)
-
- def __buttonpress(self, event=None):
- self.__nearest.press()
-
- def __buttonrelease(self, event=None):
- self.__nearest.release()
- rrggbb = self.__nearest.get_color()
- red, green, blue = ColorDB.rrggbb_to_triplet(rrggbb)
- self.__sb.update_views(red, green, blue)
diff --git a/Tools/pynche/ColorDB.py b/Tools/pynche/ColorDB.py
deleted file mode 100644
index c013a60..0000000
--- a/Tools/pynche/ColorDB.py
+++ /dev/null
@@ -1,271 +0,0 @@
-"""Color Database.
-
-This file contains one class, called ColorDB, and several utility functions.
-The class must be instantiated by the get_colordb() function in this file,
-passing it a filename to read a database out of.
-
-The get_colordb() function will try to examine the file to figure out what the
-format of the file is. If it can't figure out the file format, or it has
-trouble reading the file, None is returned. You can pass get_colordb() an
-optional filetype argument.
-
-Supported file types are:
-
- X_RGB_TXT -- X Consortium rgb.txt format files. Three columns of numbers
- from 0 .. 255 separated by whitespace. Arbitrary trailing
- columns used as the color name.
-
-The utility functions are useful for converting between the various expected
-color formats, and for calculating other color values.
-
-"""
-
-import sys
-import re
-from types import *
-
-class BadColor(Exception):
- pass
-
-DEFAULT_DB = None
-SPACE = ' '
-COMMASPACE = ', '
-
-
-
-# generic class
-class ColorDB:
- def __init__(self, fp):
- lineno = 2
- self.__name = fp.name
- # Maintain several dictionaries for indexing into the color database.
- # Note that while Tk supports RGB intensities of 4, 8, 12, or 16 bits,
- # for now we only support 8 bit intensities. At least on OpenWindows,
- # all intensities in the /usr/openwin/lib/rgb.txt file are 8-bit
- #
- # key is (red, green, blue) tuple, value is (name, [aliases])
- self.__byrgb = {}
- # key is name, value is (red, green, blue)
- self.__byname = {}
- # all unique names (non-aliases). built-on demand
- self.__allnames = None
- for line in fp:
- # get this compiled regular expression from derived class
- mo = self._re.match(line)
- if not mo:
- print('Error in', fp.name, ' line', lineno, file=sys.stderr)
- lineno += 1
- continue
- # extract the red, green, blue, and name
- red, green, blue = self._extractrgb(mo)
- name = self._extractname(mo)
- keyname = name.lower()
- # BAW: for now the `name' is just the first named color with the
- # rgb values we find. Later, we might want to make the two word
- # version the `name', or the CapitalizedVersion, etc.
- key = (red, green, blue)
- foundname, aliases = self.__byrgb.get(key, (name, []))
- if foundname != name and foundname not in aliases:
- aliases.append(name)
- self.__byrgb[key] = (foundname, aliases)
- # add to byname lookup
- self.__byname[keyname] = key
- lineno = lineno + 1
-
- # override in derived classes
- def _extractrgb(self, mo):
- return [int(x) for x in mo.group('red', 'green', 'blue')]
-
- def _extractname(self, mo):
- return mo.group('name')
-
- def filename(self):
- return self.__name
-
- def find_byrgb(self, rgbtuple):
- """Return name for rgbtuple"""
- try:
- return self.__byrgb[rgbtuple]
- except KeyError:
- raise BadColor(rgbtuple) from None
-
- def find_byname(self, name):
- """Return (red, green, blue) for name"""
- name = name.lower()
- try:
- return self.__byname[name]
- except KeyError:
- raise BadColor(name) from None
-
- def nearest(self, red, green, blue):
- """Return the name of color nearest (red, green, blue)"""
- # BAW: should we use Voronoi diagrams, Delaunay triangulation, or
- # octree for speeding up the locating of nearest point? Exhaustive
- # search is inefficient, but seems fast enough.
- nearest = -1
- nearest_name = ''
- for name, aliases in self.__byrgb.values():
- r, g, b = self.__byname[name.lower()]
- rdelta = red - r
- gdelta = green - g
- bdelta = blue - b
- distance = rdelta * rdelta + gdelta * gdelta + bdelta * bdelta
- if nearest == -1 or distance < nearest:
- nearest = distance
- nearest_name = name
- return nearest_name
-
- def unique_names(self):
- # sorted
- if not self.__allnames:
- self.__allnames = []
- for name, aliases in self.__byrgb.values():
- self.__allnames.append(name)
- self.__allnames.sort(key=str.lower)
- return self.__allnames
-
- def aliases_of(self, red, green, blue):
- try:
- name, aliases = self.__byrgb[(red, green, blue)]
- except KeyError:
- raise BadColor((red, green, blue)) from None
- return [name] + aliases
-
-
-class RGBColorDB(ColorDB):
- _re = re.compile(
- r'\s*(?P<red>\d+)\s+(?P<green>\d+)\s+(?P<blue>\d+)\s+(?P<name>.*)')
-
-
-class HTML40DB(ColorDB):
- _re = re.compile(r'(?P<name>\S+)\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
-
- def _extractrgb(self, mo):
- return rrggbb_to_triplet(mo.group('hexrgb'))
-
-class LightlinkDB(HTML40DB):
- _re = re.compile(r'(?P<name>(.+))\s+(?P<hexrgb>#[0-9a-fA-F]{6})')
-
- def _extractname(self, mo):
- return mo.group('name').strip()
-
-class WebsafeDB(ColorDB):
- _re = re.compile('(?P<hexrgb>#[0-9a-fA-F]{6})')
-
- def _extractrgb(self, mo):
- return rrggbb_to_triplet(mo.group('hexrgb'))
-
- def _extractname(self, mo):
- return mo.group('hexrgb').upper()
-
-
-
-# format is a tuple (RE, SCANLINES, CLASS) where RE is a compiled regular
-# expression, SCANLINES is the number of header lines to scan, and CLASS is
-# the class to instantiate if a match is found
-
-FILETYPES = [
- (re.compile('Xorg'), RGBColorDB),
- (re.compile('XConsortium'), RGBColorDB),
- (re.compile('HTML'), HTML40DB),
- (re.compile('lightlink'), LightlinkDB),
- (re.compile('Websafe'), WebsafeDB),
- ]
-
-def get_colordb(file, filetype=None):
- colordb = None
- fp = open(file)
- try:
- line = fp.readline()
- if not line:
- return None
- # try to determine the type of RGB file it is
- if filetype is None:
- filetypes = FILETYPES
- else:
- filetypes = [filetype]
- for typere, class_ in filetypes:
- mo = typere.search(line)
- if mo:
- break
- else:
- # no matching type
- return None
- # we know the type and the class to grok the type, so suck it in
- colordb = class_(fp)
- finally:
- fp.close()
- # save a global copy
- global DEFAULT_DB
- DEFAULT_DB = colordb
- return colordb
-
-
-
-_namedict = {}
-
-def rrggbb_to_triplet(color):
- """Converts a #rrggbb color to the tuple (red, green, blue)."""
- rgbtuple = _namedict.get(color)
- if rgbtuple is None:
- if color[0] != '#':
- raise BadColor(color)
- red = color[1:3]
- green = color[3:5]
- blue = color[5:7]
- rgbtuple = int(red, 16), int(green, 16), int(blue, 16)
- _namedict[color] = rgbtuple
- return rgbtuple
-
-
-_tripdict = {}
-def triplet_to_rrggbb(rgbtuple):
- """Converts a (red, green, blue) tuple to #rrggbb."""
- global _tripdict
- hexname = _tripdict.get(rgbtuple)
- if hexname is None:
- hexname = '#%02x%02x%02x' % rgbtuple
- _tripdict[rgbtuple] = hexname
- return hexname
-
-
-def triplet_to_fractional_rgb(rgbtuple):
- return [x / 256 for x in rgbtuple]
-
-
-def triplet_to_brightness(rgbtuple):
- # return the brightness (grey level) along the scale 0.0==black to
- # 1.0==white
- r = 0.299
- g = 0.587
- b = 0.114
- return r*rgbtuple[0] + g*rgbtuple[1] + b*rgbtuple[2]
-
-
-
-if __name__ == '__main__':
- colordb = get_colordb('/usr/openwin/lib/rgb.txt')
- if not colordb:
- print('No parseable color database found')
- sys.exit(1)
- # on my system, this color matches exactly
- target = 'navy'
- red, green, blue = rgbtuple = colordb.find_byname(target)
- print(target, ':', red, green, blue, triplet_to_rrggbb(rgbtuple))
- name, aliases = colordb.find_byrgb(rgbtuple)
- print('name:', name, 'aliases:', COMMASPACE.join(aliases))
- r, g, b = (1, 1, 128) # nearest to navy
- r, g, b = (145, 238, 144) # nearest to lightgreen
- r, g, b = (255, 251, 250) # snow
- print('finding nearest to', target, '...')
- import time
- t0 = time.time()
- nearest = colordb.nearest(r, g, b)
- t1 = time.time()
- print('found nearest color', nearest, 'in', t1-t0, 'seconds')
- # dump the database
- for n in colordb.unique_names():
- r, g, b = colordb.find_byname(n)
- aliases = colordb.aliases_of(r, g, b)
- print('%20s: (%3d/%3d/%3d) == %s' % (n, r, g, b,
- SPACE.join(aliases[1:])))
diff --git a/Tools/pynche/DetailsViewer.py b/Tools/pynche/DetailsViewer.py
deleted file mode 100644
index bed11f4..0000000
--- a/Tools/pynche/DetailsViewer.py
+++ /dev/null
@@ -1,273 +0,0 @@
-"""DetailsViewer class.
-
-This class implements a pure input window which allows you to meticulously
-edit the current color. You have both mouse control of the color (via the
-buttons along the bottom row), and there are keyboard bindings for each of the
-increment/decrement buttons.
-
-The top three check buttons allow you to specify which of the three color
-variations are tied together when incrementing and decrementing. Red, green,
-and blue are self evident. By tying together red and green, you can modify
-the yellow level of the color. By tying together red and blue, you can modify
-the magenta level of the color. By tying together green and blue, you can
-modify the cyan level, and by tying all three together, you can modify the
-grey level.
-
-The behavior at the boundaries (0 and 255) are defined by the `At boundary'
-option menu:
-
- Stop
- When the increment or decrement would send any of the tied variations
- out of bounds, the entire delta is discarded.
-
- Wrap Around
- When the increment or decrement would send any of the tied variations
- out of bounds, the out of bounds variation is wrapped around to the
- other side. Thus if red were at 238 and 25 were added to it, red
- would have the value 7.
-
- Preserve Distance
- When the increment or decrement would send any of the tied variations
- out of bounds, all tied variations are wrapped as one, so as to
- preserve the distance between them. Thus if green and blue were tied,
- and green was at 238 while blue was at 223, and an increment of 25
- were applied, green would be at 15 and blue would be at 0.
-
- Squash
- When the increment or decrement would send any of the tied variations
- out of bounds, the out of bounds variation is set to the ceiling of
- 255 or floor of 0, as appropriate. In this way, all tied variations
- are squashed to one edge or the other.
-
-The following key bindings can be used as accelerators. Note that Pynche can
-fall behind if you hold the key down as a key repeat:
-
-Left arrow == -1
-Right arrow == +1
-
-Control + Left == -10
-Control + Right == 10
-
-Shift + Left == -25
-Shift + Right == +25
-"""
-
-from tkinter import *
-
-STOP = 'Stop'
-WRAP = 'Wrap Around'
-RATIO = 'Preserve Distance'
-GRAV = 'Squash'
-
-ADDTOVIEW = 'Details Window...'
-
-
-class DetailsViewer:
- def __init__(self, switchboard, master=None):
- self.__sb = switchboard
- optiondb = switchboard.optiondb()
- self.__red, self.__green, self.__blue = switchboard.current_rgb()
- # GUI
- root = self.__root = Toplevel(master, class_='Pynche')
- root.protocol('WM_DELETE_WINDOW', self.withdraw)
- root.title('Pynche Details Window')
- root.iconname('Pynche Details Window')
- root.bind('<Alt-q>', self.__quit)
- root.bind('<Alt-Q>', self.__quit)
- root.bind('<Alt-w>', self.withdraw)
- root.bind('<Alt-W>', self.withdraw)
- # accelerators
- root.bind('<KeyPress-Left>', self.__minus1)
- root.bind('<KeyPress-Right>', self.__plus1)
- root.bind('<Control-KeyPress-Left>', self.__minus10)
- root.bind('<Control-KeyPress-Right>', self.__plus10)
- root.bind('<Shift-KeyPress-Left>', self.__minus25)
- root.bind('<Shift-KeyPress-Right>', self.__plus25)
- #
- # color ties
- frame = self.__frame = Frame(root)
- frame.pack(expand=YES, fill=X)
- self.__l1 = Label(frame, text='Move Sliders:')
- self.__l1.grid(row=1, column=0, sticky=E)
- self.__rvar = IntVar()
- self.__rvar.set(optiondb.get('RSLIDER', 4))
- self.__radio1 = Checkbutton(frame, text='Red',
- variable=self.__rvar,
- command=self.__effect,
- onvalue=4, offvalue=0)
- self.__radio1.grid(row=1, column=1, sticky=W)
- self.__gvar = IntVar()
- self.__gvar.set(optiondb.get('GSLIDER', 2))
- self.__radio2 = Checkbutton(frame, text='Green',
- variable=self.__gvar,
- command=self.__effect,
- onvalue=2, offvalue=0)
- self.__radio2.grid(row=2, column=1, sticky=W)
- self.__bvar = IntVar()
- self.__bvar.set(optiondb.get('BSLIDER', 1))
- self.__radio3 = Checkbutton(frame, text='Blue',
- variable=self.__bvar,
- command=self.__effect,
- onvalue=1, offvalue=0)
- self.__radio3.grid(row=3, column=1, sticky=W)
- self.__l2 = Label(frame)
- self.__l2.grid(row=4, column=1, sticky=W)
- self.__effect()
- #
- # Boundary behavior
- self.__l3 = Label(frame, text='At boundary:')
- self.__l3.grid(row=5, column=0, sticky=E)
- self.__boundvar = StringVar()
- self.__boundvar.set(optiondb.get('ATBOUND', STOP))
- self.__omenu = OptionMenu(frame, self.__boundvar,
- STOP, WRAP, RATIO, GRAV)
- self.__omenu.grid(row=5, column=1, sticky=W)
- self.__omenu.configure(width=17)
- #
- # Buttons
- frame = self.__btnframe = Frame(frame)
- frame.grid(row=0, column=0, columnspan=2, sticky='EW')
- self.__down25 = Button(frame, text='-25',
- command=self.__minus25)
- self.__down10 = Button(frame, text='-10',
- command=self.__minus10)
- self.__down1 = Button(frame, text='-1',
- command=self.__minus1)
- self.__up1 = Button(frame, text='+1',
- command=self.__plus1)
- self.__up10 = Button(frame, text='+10',
- command=self.__plus10)
- self.__up25 = Button(frame, text='+25',
- command=self.__plus25)
- self.__down25.pack(expand=YES, fill=X, side=LEFT)
- self.__down10.pack(expand=YES, fill=X, side=LEFT)
- self.__down1.pack(expand=YES, fill=X, side=LEFT)
- self.__up1.pack(expand=YES, fill=X, side=LEFT)
- self.__up10.pack(expand=YES, fill=X, side=LEFT)
- self.__up25.pack(expand=YES, fill=X, side=LEFT)
-
- def __effect(self, event=None):
- tie = self.__rvar.get() + self.__gvar.get() + self.__bvar.get()
- if tie in (0, 1, 2, 4):
- text = ''
- else:
- text = '(= %s Level)' % {3: 'Cyan',
- 5: 'Magenta',
- 6: 'Yellow',
- 7: 'Grey'}[tie]
- self.__l2.configure(text=text)
-
- def __quit(self, event=None):
- self.__root.quit()
-
- def withdraw(self, event=None):
- self.__root.withdraw()
-
- def deiconify(self, event=None):
- self.__root.deiconify()
-
- def __minus25(self, event=None):
- self.__delta(-25)
-
- def __minus10(self, event=None):
- self.__delta(-10)
-
- def __minus1(self, event=None):
- self.__delta(-1)
-
- def __plus1(self, event=None):
- self.__delta(1)
-
- def __plus10(self, event=None):
- self.__delta(10)
-
- def __plus25(self, event=None):
- self.__delta(25)
-
- def __delta(self, delta):
- tie = []
- if self.__rvar.get():
- red = self.__red + delta
- tie.append(red)
- else:
- red = self.__red
- if self.__gvar.get():
- green = self.__green + delta
- tie.append(green)
- else:
- green = self.__green
- if self.__bvar.get():
- blue = self.__blue + delta
- tie.append(blue)
- else:
- blue = self.__blue
- # now apply at boundary behavior
- atbound = self.__boundvar.get()
- if atbound == STOP:
- if red < 0 or green < 0 or blue < 0 or \
- red > 255 or green > 255 or blue > 255:
- # then
- red, green, blue = self.__red, self.__green, self.__blue
- elif atbound == WRAP or (atbound == RATIO and len(tie) < 2):
- if red < 0:
- red += 256
- if green < 0:
- green += 256
- if blue < 0:
- blue += 256
- if red > 255:
- red -= 256
- if green > 255:
- green -= 256
- if blue > 255:
- blue -= 256
- elif atbound == RATIO:
- # for when 2 or 3 colors are tied together
- dir = 0
- for c in tie:
- if c < 0:
- dir = -1
- elif c > 255:
- dir = 1
- if dir == -1:
- delta = max(tie)
- if self.__rvar.get():
- red = red + 255 - delta
- if self.__gvar.get():
- green = green + 255 - delta
- if self.__bvar.get():
- blue = blue + 255 - delta
- elif dir == 1:
- delta = min(tie)
- if self.__rvar.get():
- red = red - delta
- if self.__gvar.get():
- green = green - delta
- if self.__bvar.get():
- blue = blue - delta
- elif atbound == GRAV:
- if red < 0:
- red = 0
- if green < 0:
- green = 0
- if blue < 0:
- blue = 0
- if red > 255:
- red = 255
- if green > 255:
- green = 255
- if blue > 255:
- blue = 255
- self.__sb.update_views(red, green, blue)
- self.__root.update_idletasks()
-
- def update_yourself(self, red, green, blue):
- self.__red = red
- self.__green = green
- self.__blue = blue
-
- def save_options(self, optiondb):
- optiondb['RSLIDER'] = self.__rvar.get()
- optiondb['GSLIDER'] = self.__gvar.get()
- optiondb['BSLIDER'] = self.__bvar.get()
- optiondb['ATBOUND'] = self.__boundvar.get()
diff --git a/Tools/pynche/ListViewer.py b/Tools/pynche/ListViewer.py
deleted file mode 100644
index b187844..0000000
--- a/Tools/pynche/ListViewer.py
+++ /dev/null
@@ -1,175 +0,0 @@
-"""ListViewer class.
-
-This class implements an input/output view on the color model. It lists every
-unique color (e.g. unique r/g/b value) found in the color database. Each
-color is shown by small swatch and primary color name. Some colors have
-aliases -- more than one name for the same r/g/b value. These aliases are
-displayed in the small listbox at the bottom of the screen.
-
-Clicking on a color name or swatch selects that color and updates all other
-windows. When a color is selected in a different viewer, the color list is
-scrolled to the selected color and it is highlighted. If the selected color
-is an r/g/b value without a name, no scrolling occurs.
-
-You can turn off Update On Click if all you want to see is the alias for a
-given name, without selecting the color.
-"""
-
-from tkinter import *
-import ColorDB
-
-ADDTOVIEW = 'Color %List Window...'
-
-class ListViewer:
- def __init__(self, switchboard, master=None):
- self.__sb = switchboard
- optiondb = switchboard.optiondb()
- self.__lastbox = None
- self.__dontcenter = 0
- # GUI
- root = self.__root = Toplevel(master, class_='Pynche')
- root.protocol('WM_DELETE_WINDOW', self.withdraw)
- root.title('Pynche Color List')
- root.iconname('Pynche Color List')
- root.bind('<Alt-q>', self.__quit)
- root.bind('<Alt-Q>', self.__quit)
- root.bind('<Alt-w>', self.withdraw)
- root.bind('<Alt-W>', self.withdraw)
- #
- # create the canvas which holds everything, and its scrollbar
- #
- frame = self.__frame = Frame(root)
- frame.pack()
- canvas = self.__canvas = Canvas(frame, width=160, height=300,
- borderwidth=2, relief=SUNKEN)
- self.__scrollbar = Scrollbar(frame)
- self.__scrollbar.pack(fill=Y, side=RIGHT)
- canvas.pack(fill=BOTH, expand=1)
- canvas.configure(yscrollcommand=(self.__scrollbar, 'set'))
- self.__scrollbar.configure(command=(canvas, 'yview'))
- self.__populate()
- #
- # Update on click
- self.__uoc = BooleanVar()
- self.__uoc.set(optiondb.get('UPONCLICK', 1))
- self.__uocbtn = Checkbutton(root,
- text='Update on Click',
- variable=self.__uoc,
- command=self.__toggleupdate)
- self.__uocbtn.pack(expand=1, fill=BOTH)
- #
- # alias list
- self.__alabel = Label(root, text='Aliases:')
- self.__alabel.pack()
- self.__aliases = Listbox(root, height=5,
- selectmode=BROWSE)
- self.__aliases.pack(expand=1, fill=BOTH)
-
- def __populate(self):
- #
- # create all the buttons
- colordb = self.__sb.colordb()
- canvas = self.__canvas
- row = 0
- widest = 0
- bboxes = self.__bboxes = []
- for name in colordb.unique_names():
- exactcolor = ColorDB.triplet_to_rrggbb(colordb.find_byname(name))
- canvas.create_rectangle(5, row*20 + 5,
- 20, row*20 + 20,
- fill=exactcolor)
- textid = canvas.create_text(25, row*20 + 13,
- text=name,
- anchor=W)
- x1, y1, textend, y2 = canvas.bbox(textid)
- boxid = canvas.create_rectangle(3, row*20+3,
- textend+3, row*20 + 23,
- outline='',
- tags=(exactcolor, 'all'))
- canvas.bind('<ButtonRelease>', self.__onrelease)
- bboxes.append(boxid)
- if textend+3 > widest:
- widest = textend+3
- row += 1
- canvheight = (row-1)*20 + 25
- canvas.config(scrollregion=(0, 0, 150, canvheight))
- for box in bboxes:
- x1, y1, x2, y2 = canvas.coords(box)
- canvas.coords(box, x1, y1, widest, y2)
-
- def __onrelease(self, event=None):
- canvas = self.__canvas
- # find the current box
- x = canvas.canvasx(event.x)
- y = canvas.canvasy(event.y)
- ids = canvas.find_overlapping(x, y, x, y)
- for boxid in ids:
- if boxid in self.__bboxes:
- break
- else:
-## print 'No box found!'
- return
- tags = self.__canvas.gettags(boxid)
- for t in tags:
- if t[0] == '#':
- break
- else:
-## print 'No color tag found!'
- return
- red, green, blue = ColorDB.rrggbb_to_triplet(t)
- self.__dontcenter = 1
- if self.__uoc.get():
- self.__sb.update_views(red, green, blue)
- else:
- self.update_yourself(red, green, blue)
- self.__red, self.__green, self.__blue = red, green, blue
-
- def __toggleupdate(self, event=None):
- if self.__uoc.get():
- self.__sb.update_views(self.__red, self.__green, self.__blue)
-
- def __quit(self, event=None):
- self.__root.quit()
-
- def withdraw(self, event=None):
- self.__root.withdraw()
-
- def deiconify(self, event=None):
- self.__root.deiconify()
-
- def update_yourself(self, red, green, blue):
- canvas = self.__canvas
- # turn off the last box
- if self.__lastbox:
- canvas.itemconfigure(self.__lastbox, outline='')
- # turn on the current box
- colortag = ColorDB.triplet_to_rrggbb((red, green, blue))
- canvas.itemconfigure(colortag, outline='black')
- self.__lastbox = colortag
- # fill the aliases
- self.__aliases.delete(0, END)
- try:
- aliases = self.__sb.colordb().aliases_of(red, green, blue)[1:]
- except ColorDB.BadColor:
- self.__aliases.insert(END, '<no matching color>')
- return
- if not aliases:
- self.__aliases.insert(END, '<no aliases>')
- else:
- for name in aliases:
- self.__aliases.insert(END, name)
- # maybe scroll the canvas so that the item is visible
- if self.__dontcenter:
- self.__dontcenter = 0
- else:
- ig, ig, ig, y1 = canvas.coords(colortag)
- ig, ig, ig, y2 = canvas.coords(self.__bboxes[-1])
- h = int(canvas['height']) * 0.5
- canvas.yview('moveto', (y1-h) / y2)
-
- def save_options(self, optiondb):
- optiondb['UPONCLICK'] = self.__uoc.get()
-
- def colordb_changed(self, colordb):
- self.__canvas.delete('all')
- self.__populate()
diff --git a/Tools/pynche/Main.py b/Tools/pynche/Main.py
deleted file mode 100644
index 4db560b..0000000
--- a/Tools/pynche/Main.py
+++ /dev/null
@@ -1,229 +0,0 @@
-"""Pynche -- The PYthon Natural Color and Hue Editor.
-
-Contact: %(AUTHNAME)s
-Email: %(AUTHEMAIL)s
-Version: %(__version__)s
-
-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 +
-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'.
-
-This program currently requires Python 2.2 with Tkinter.
-
-Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-v] [-h] [initialcolor]
-
-Where:
- --database file
- -d file
- Alternate location of a color database file
-
- --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.
-
- --version
- -v
- print the version number and exit
-
- --help
- -h
- print this message
-
- initialcolor
- initial color, as a color name or #RRGGBB format
-"""
-
-__version__ = '1.4.1'
-
-import sys
-import os
-import getopt
-import ColorDB
-
-from PyncheWidget import PyncheWidget
-from Switchboard import Switchboard
-from StripViewer import StripViewer
-from ChipViewer import ChipViewer
-from TypeinViewer import TypeinViewer
-
-
-
-PROGRAM = sys.argv[0]
-AUTHNAME = 'Barry Warsaw'
-AUTHEMAIL = 'barry@python.org'
-
-# Default locations of rgb.txt or other textual color database
-RGB_TXT = [
- # Solaris OpenWindows
- '/usr/openwin/lib/rgb.txt',
- # Linux
- '/usr/lib/X11/rgb.txt',
- # The X11R6.4 rgb.txt file
- os.path.join(sys.path[0], 'X/rgb.txt'),
- # add more here
- ]
-
-
-
-# Do this because PyncheWidget.py wants to get at the interpolated docstring
-# too, for its Help menu.
-def docstring():
- return __doc__ % globals()
-
-
-def usage(code, msg=''):
- print(docstring())
- if msg:
- print(msg)
- sys.exit(code)
-
-
-
-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
-
-
-
-def build(master=None, initialcolor=None, initfile=None, ignore=None,
- dbfile=None):
- # create all output widgets
- s = Switchboard(not ignore and initfile)
- # defer to the command line chosen color database, falling back to the one
- # in the .pynche file.
- if dbfile is None:
- dbfile = s.optiondb().get('DBFILE')
- # find a parseable color database
- colordb = None
- files = RGB_TXT[:]
- if dbfile is None:
- dbfile = files.pop()
- while colordb is None:
- try:
- colordb = ColorDB.get_colordb(dbfile)
- except (KeyError, IOError):
- pass
- if colordb is None:
- if not files:
- break
- dbfile = files.pop(0)
- if not colordb:
- usage(1, 'No color database file found, see the -d option.')
- s.set_colordb(colordb)
-
- # create the application window decorations
- app = PyncheWidget(__version__, s, master=master)
- w = app.window()
-
- # these built-in viewers live inside the main Pynche window
- s.add_view(StripViewer(s, w))
- s.add_view(ChipViewer(s, w))
- s.add_view(TypeinViewer(s, w))
-
- # 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)
- s.update_views(red, green, blue)
- return app, s
-
-
-def run(app, s):
- try:
- app.start()
- except KeyboardInterrupt:
- pass
-
-
-
-def main():
- try:
- opts, args = getopt.getopt(
- sys.argv[1:],
- 'hd:i:Xv',
- ['database=', 'initfile=', 'ignore', 'help', 'version'])
- except getopt.error as msg:
- usage(1, msg)
-
- if len(args) == 0:
- initialcolor = None
- elif len(args) == 1:
- initialcolor = args[0]
- else:
- usage(1)
-
- ignore = False
- dbfile = None
- initfile = os.path.expanduser('~/.pynche')
- for opt, arg in opts:
- if opt in ('-h', '--help'):
- usage(0)
- elif opt in ('-v', '--version'):
- print("""\
-Pynche -- The PYthon Natural Color and Hue Editor.
-Contact: %(AUTHNAME)s
-Email: %(AUTHEMAIL)s
-Version: %(__version__)s""" % globals())
- sys.exit(0)
- elif opt in ('-d', '--database'):
- dbfile = arg
- elif opt in ('-X', '--ignore'):
- ignore = True
- elif opt in ('-i', '--initfile'):
- initfile = arg
-
- app, sb = build(initialcolor=initialcolor,
- initfile=initfile,
- ignore=ignore,
- dbfile=dbfile)
- run(app, sb)
- sb.save_views()
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/Tools/pynche/PyncheWidget.py b/Tools/pynche/PyncheWidget.py
deleted file mode 100644
index ea456e5..0000000
--- a/Tools/pynche/PyncheWidget.py
+++ /dev/null
@@ -1,313 +0,0 @@
-"""Main Pynche (Pythonically Natural Color and Hue Editor) widget.
-
-This window provides the basic decorations, primarily including the menubar.
-It is used to bring up other windows.
-"""
-
-import sys
-import os
-from tkinter import *
-from tkinter import messagebox, filedialog
-import ColorDB
-
-# Milliseconds between interrupt checks
-KEEPALIVE_TIMER = 500
-
-
-
-class PyncheWidget:
- def __init__(self, version, switchboard, master=None, extrapath=[]):
- self.__sb = switchboard
- self.__version = version
- self.__textwin = None
- self.__listwin = None
- self.__detailswin = None
- self.__helpwin = None
- self.__dialogstate = {}
- modal = self.__modal = not not master
- # If a master was given, we are running as a modal dialog servant to
- # some other application. We rearrange our UI in this case (there's
- # no File menu and we get `Okay' and `Cancel' buttons), and we do a
- # grab_set() to make ourselves modal
- if modal:
- self.__tkroot = tkroot = Toplevel(master, class_='Pynche')
- tkroot.grab_set()
- tkroot.withdraw()
- else:
- # Is there already a default root for Tk, say because we're
- # running under Guido's IDE? :-) Two conditions say no, either the
- # _default_root is None or it is unset.
- tkroot = getattr(tkinter, '_default_root', None)
- if not tkroot:
- tkroot = Tk(className='Pynche')
- self.__tkroot = tkroot
- # but this isn't our top level widget, so make it invisible
- tkroot.withdraw()
- # create the menubar
- menubar = self.__menubar = Menu(tkroot)
- #
- # File menu
- #
- filemenu = self.__filemenu = Menu(menubar, tearoff=0)
- filemenu.add_command(label='Load palette...',
- command=self.__load,
- underline=0)
- if not modal:
- filemenu.add_command(label='Quit',
- command=self.__quit,
- accelerator='Alt-Q',
- underline=0)
- #
- # View menu
- #
- views = make_view_popups(self.__sb, self.__tkroot, extrapath)
- viewmenu = Menu(menubar, tearoff=0)
- for v in views:
- viewmenu.add_command(label=v.menutext(),
- command=v.popup,
- underline=v.underline())
- #
- # Help menu
- #
- helpmenu = Menu(menubar, name='help', tearoff=0)
- helpmenu.add_command(label='About Pynche...',
- command=self.__popup_about,
- underline=0)
- helpmenu.add_command(label='Help...',
- command=self.__popup_usage,
- underline=0)
- #
- # Tie them all together
- #
- menubar.add_cascade(label='File',
- menu=filemenu,
- underline=0)
- menubar.add_cascade(label='View',
- menu=viewmenu,
- underline=0)
- menubar.add_cascade(label='Help',
- menu=helpmenu,
- underline=0)
-
- # now create the top level window
- root = self.__root = Toplevel(tkroot, class_='Pynche', menu=menubar)
- root.protocol('WM_DELETE_WINDOW',
- modal and self.__bell or self.__quit)
- root.title('Pynche %s' % version)
- root.iconname('Pynche')
- # Only bind accelerators for the File->Quit menu item if running as a
- # standalone app
- if not modal:
- root.bind('<Alt-q>', self.__quit)
- root.bind('<Alt-Q>', self.__quit)
- else:
- # We're a modal dialog so we have a new row of buttons
- bframe = Frame(root, borderwidth=1, relief=RAISED)
- bframe.grid(row=4, column=0, columnspan=2,
- sticky='EW',
- ipady=5)
- okay = Button(bframe,
- text='Okay',
- command=self.__okay)
- okay.pack(side=LEFT, expand=1)
- cancel = Button(bframe,
- text='Cancel',
- command=self.__cancel)
- cancel.pack(side=LEFT, expand=1)
-
- def __quit(self, event=None):
- self.__tkroot.quit()
-
- def __bell(self, event=None):
- self.__tkroot.bell()
-
- def __okay(self, event=None):
- self.__sb.withdraw_views()
- self.__tkroot.grab_release()
- self.__quit()
-
- def __cancel(self, event=None):
- self.__sb.canceled()
- self.__okay()
-
- def __keepalive(self):
- # Exercise the Python interpreter regularly so keyboard interrupts get
- # through.
- self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive)
-
- def start(self):
- if not self.__modal:
- self.__keepalive()
- self.__tkroot.mainloop()
-
- def window(self):
- return self.__root
-
- def __popup_about(self, event=None):
- from Main import __version__
- messagebox.showinfo('About Pynche ' + __version__,
- '''\
-Pynche %s
-The PYthonically Natural
-Color and Hue Editor
-
-For information
-contact: Barry A. Warsaw
-email: bwarsaw@python.org''' % __version__)
-
- def __popup_usage(self, event=None):
- if not self.__helpwin:
- self.__helpwin = Helpwin(self.__root, self.__quit)
- self.__helpwin.deiconify()
-
- def __load(self, event=None):
- while 1:
- idir, ifile = os.path.split(self.__sb.colordb().filename())
- file = filedialog.askopenfilename(
- filetypes=[('Text files', '*.txt'),
- ('All files', '*'),
- ],
- initialdir=idir,
- initialfile=ifile)
- if not file:
- # cancel button
- return
- try:
- colordb = ColorDB.get_colordb(file)
- except IOError:
- messagebox.showerror('Read error', '''\
-Could not open file for reading:
-%s''' % file)
- continue
- if colordb is None:
- messagebox.showerror('Unrecognized color file type', '''\
-Unrecognized color file type in file:
-%s''' % file)
- continue
- break
- self.__sb.set_colordb(colordb)
-
- def withdraw(self):
- self.__root.withdraw()
-
- def deiconify(self):
- self.__root.deiconify()
-
-
-
-class Helpwin:
- def __init__(self, master, quitfunc):
- from Main import docstring
- self.__root = root = Toplevel(master, class_='Pynche')
- root.protocol('WM_DELETE_WINDOW', self.__withdraw)
- root.title('Pynche Help Window')
- root.iconname('Pynche Help Window')
- root.bind('<Alt-q>', quitfunc)
- root.bind('<Alt-Q>', quitfunc)
- root.bind('<Alt-w>', self.__withdraw)
- root.bind('<Alt-W>', self.__withdraw)
-
- # more elaborate help is available in the README file
- readmefile = os.path.join(sys.path[0], 'README')
- try:
- fp = None
- try:
- fp = open(readmefile)
- contents = fp.read()
- # wax the last page, it contains Emacs cruft
- i = contents.rfind('\f')
- if i > 0:
- contents = contents[:i].rstrip()
- finally:
- if fp:
- fp.close()
- except IOError:
- sys.stderr.write("Couldn't open Pynche's README, "
- 'using docstring instead.\n')
- contents = docstring()
-
- self.__text = text = Text(root, relief=SUNKEN,
- width=80, height=24)
- self.__text.focus_set()
- text.insert(0.0, contents)
- scrollbar = Scrollbar(root)
- scrollbar.pack(fill=Y, side=RIGHT)
- text.pack(fill=BOTH, expand=YES)
- text.configure(yscrollcommand=(scrollbar, 'set'))
- scrollbar.configure(command=(text, 'yview'))
-
- def __withdraw(self, event=None):
- self.__root.withdraw()
-
- def deiconify(self):
- self.__root.deiconify()
-
-
-
-import functools
-@functools.total_ordering
-class PopupViewer:
- def __init__(self, module, name, switchboard, root):
- self.__m = module
- self.__name = name
- self.__sb = switchboard
- self.__root = root
- self.__menutext = module.ADDTOVIEW
- # find the underline character
- underline = module.ADDTOVIEW.find('%')
- if underline == -1:
- underline = 0
- else:
- self.__menutext = module.ADDTOVIEW.replace('%', '', 1)
- self.__underline = underline
- self.__window = None
-
- def menutext(self):
- return self.__menutext
-
- def underline(self):
- return self.__underline
-
- def popup(self, event=None):
- if not self.__window:
- # class and module must have the same name
- class_ = getattr(self.__m, self.__name)
- self.__window = class_(self.__sb, self.__root)
- self.__sb.add_view(self.__window)
- self.__window.deiconify()
-
- def __eq__(self, other):
- if isinstance(self, PopupViewer):
- return self.__menutext == other.__menutext
- return NotImplemented
-
- def __lt__(self, other):
- if isinstance(self, PopupViewer):
- return self.__menutext < other.__menutext
- return NotImplemented
-
-
-def make_view_popups(switchboard, root, extrapath):
- viewers = []
- # where we are in the file system
- dirs = [os.path.dirname(__file__)] + extrapath
- for dir in dirs:
- if dir == '':
- dir = '.'
- for file in os.listdir(dir):
- if file[-9:] == 'Viewer.py':
- name = file[:-3]
- try:
- module = __import__(name)
- except ImportError:
- # Pynche is running from inside a package, so get the
- # module using the explicit path.
- pkg = __import__('pynche.'+name)
- module = getattr(pkg, name)
- if hasattr(module, 'ADDTOVIEW') and module.ADDTOVIEW:
- # this is an external viewer
- v = PopupViewer(module, name, switchboard, root)
- viewers.append(v)
- # sort alphabetically
- viewers.sort()
- return viewers
diff --git a/Tools/pynche/README b/Tools/pynche/README
deleted file mode 100644
index ae8183f..0000000
--- a/Tools/pynche/README
+++ /dev/null
@@ -1,398 +0,0 @@
-Pynche - The PYthonically Natural Color and Hue Editor
-
-Contact: Barry A. Warsaw
-Email: bwarsaw@python.org
-Version: 1.3
-
-Introduction
-
- Pynche is a color editor based largely on a similar program that I
- originally wrote back in 1987 for the Sunview window system. That
- editor was called ICE, the Interactive Color Editor. I'd always
- wanted to port this program to X but didn't feel like hacking X
- and C code to do it. Fast forward many years, to where Python +
- Tkinter provides such a nice programming environment, with enough
- power, that I finally buckled down and re-implemented it. I
- changed the name because these days, too many other systems have
- the acronym `ICE'.
-
- Pynche should work with any variant of Python after 1.5.2
- (e.g. 2.0.1 and 2.1.1), using Tk 8.0.x. It's been tested on
- Solaris 2.6, Windows NT 4, and various Linux distros. You'll want
- to be sure to have at least Tk 8.0.3 for Windows. Also, Pynche is
- very colormap intensive, so it doesn't work very well on 8-bit
- graphics cards; 24bit+ graphics cards are so cheap these days,
- I'll probably never "fix" that.
-
- Pynche must find a text database of colors names in order to
- provide `nearest' color matching. Pynche is distributed with an
- rgb.txt file from the X11R6.4 distribution for this reason, along
- with other "web related" database (see below). You can use a
- different file with the -d option. The file xlicense.txt contains
- the license only for rgb.txt and both files are in the X/
- subdirectory.
-
- Pynche is pronounced: Pin'-chee
-
-
-Running Standalone
-
- On Unix, start it by running the `pynche' script. On Windows, run
- pynche.pyw to inhibit the console window. When run from the
- command line, the following options are recognized:
-
- --database file
- -d file
- Alternate location of the color database file. Without this
- option, the first valid file found will be used (see below).
-
- --initfile file
- -i file
- Alternate location of the persistent initialization file. See
- the section on Persistency below.
-
- --ignore
- -X
- Ignore the persistent initialization file when starting up.
- Pynche will still write the current option settings to the
- persistent init file when it quits.
-
- --help
- -h
- Print the help message.
-
- initialcolor
- a Tk color name or #rrggbb color spec to be used as the
- initially selected color. This overrides any color saved in
- the persistent init file. Since `#' needs to be escaped in
- many shells, it is optional in the spec (e.g. #45dd1f is the
- same as 45dd1f).
-
-
-Running as a Modal Dialog
-
- Pynche can be run as a modal dialog, inside another application,
- say as a general color chooser. In fact, Grail 0.6 uses Pynche
- and a future version of IDLE may as well. Pynche supports the API
- implemented by the Tkinter standard tkColorChooser module, with a
- few changes as described below. By importing pyColorChooser from
- the Pynche package, you can run
-
- pyColorChooser.askcolor()
-
- which will popup Pynche as a modal dialog, and return the selected
- color.
-
- There are some UI differences when running as a modal
- vs. standalone. When running as a modal, there is no "Quit" menu
- item under the "File" menu. Instead there are "Okay" and "Cancel"
- buttons.
-
- When "Okay" is hit, askcolor() returns the tuple
-
- ((r, g, b), "name")
-
- where r, g, and b are red, green, and blue color values
- respectively (in the range 0 to 255). "name" will be a color name
- from the color database if there is an exact match, otherwise it
- will be an X11 color spec of the form "#rrggbb". Note that this
- is different than tkColorChooser, which doesn't know anything
- about color names.
-
- askcolor() supports the following optional keyword arguments:
-
- color
- the color to set as the initial selected color
-
- master[*]
- the master window to use as the parent of the modal
- dialog. Without this argument, pyColorChooser will create
- its own Tkinter.Tk instance as the master. This may not
- be what you want.
-
- databasefile
- similar to the --database option, the value must be a
- file name
-
- initfile[*]
- similar to the --initfile option, the value must be a
- file name
-
- ignore[*]
- similar to the --ignore flag, the value is a boolean
-
- wantspec
- When this is true, the "name" field in the return tuple
- will always be a color spec of the form "#rrggbb". It
- will not return a color name even if there is a match;
- this is so pyColorChooser can exactly match the API of
- tkColorChooser.
-
- [*] these arguments must be specified the first time
- askcolor() is used and cannot be changed on subsequent calls.
-
-
-The Colorstrip Window
-
- The top part of the main Pynche window contains the "variation
- strips". Each strip contains a number of "color chips". The
- strips always indicate the currently selected color by a highlight
- rectangle around the selected color chip, with an arrow pointing
- to the chip. Each arrow has an associated number giving you the
- color value along the variation's axis. Each variation strip
- shows you the colors that are reachable from the selected color by
- varying just one axis of the color solid.
-
- For example, when the selected color is (in Red/Green/Blue
- notation) 127/127/127, the Red Variations strip shows you every
- color in the range 0/127/127 to 255/127/127. Similarly for the
- green and blue axes. You can select any color by clicking on its
- chip. This will update the highlight rectangle and the arrow, as
- well as other displays in Pynche.
-
- Click on "Update while dragging" if you want Pynche to update the
- selected color while you drag along any variation strip (this will
- be a bit slower). Click on "Hexadecimal" to display the arrow
- numbers in hex.
-
- There are also two shortcut buttons in this window, which
- auto-select Black (0/0/0) and White (255/255/255).
-
-
-The Proof Window
-
- In the lower left corner of the main window you see two larger
- color chips. The Selected chip shows you a larger version of the
- color selected in the variation strips, along with its X11 color
- specification. The Nearest chip shows you the closest color in
- the X11 database to the selected color, giving its X11 color
- specification, and below that, its X11 color name. When the
- Selected chip color exactly matches the Nearest chip color, you
- will see the color name appear below the color specification for
- the Selected chip.
-
- Clicking on the Nearest color chip selects that color. Color
- distance is calculated in the 3D space of the RGB color solid and
- if more than one color name is the same distance from the selected
- color, the first one found will be chosen.
-
- Note that there may be more than one X11 color name for the same
- RGB value. In that case, the first one found in the text database
- is designated the "primary" name, and this is shown under the
- Nearest chip. The other names are "aliases" and they are visible
- in the Color List Window (see below).
-
- Both the color specifications and color names are selectable for
- copying and pasting into another window.
-
-
-The Type-in Window
-
- At the lower right of the main window are three entry fields.
- Here you can type numeric values for any of the three color axes.
- Legal values are between 0 and 255, and these fields do not allow
- you to enter illegal values. You must hit Enter or Tab to select
- the new color.
-
- Click on "Update while typing" if you want Pynche to select the
- color on every keystroke (well, every one that produces a legal
- value!) Click on "Hexadecimal" to display and enter color values
- in hex.
-
-
-Other Views
-
- There are three secondary windows which are not displayed by
- default. You can bring these up via the "View" menu on the main
- Pynche window.
-
-
-The Text Window
-
- The "Text Window" allows you to see what effects various colors
- have on the standard Tk text widget elements. In the upper part
- of the window is a plain Tk text widget and here you can edit the
- text, select a region of text, etc. Below this is a button "Track
- color changes". When this is turned on, any colors selected in
- the other windows will change the text widget element specified in
- the radio buttons below. When this is turned off, text widget
- elements are not affected by color selection.
-
- You can choose which element gets changed by color selection by
- clicking on one of the radio buttons in the bottom part of this
- window. Text foreground and background affect the text in the
- upper part of the window. Selection foreground and background
- affect the colors of the primary selection which is what you see
- when you click the middle button (depending on window system) and
- drag it through some text.
-
- The Insertion is the insertion cursor in the text window, where
- new text will be inserted as you type. The insertion cursor only
- has a background.
-
-
-The Color List Window
-
- The "Color List" window shows every named color in the color name
- database (this window may take a while to come up). In the upper
- part of the window you see a scrolling list of all the color names
- in the database, in alphabetical order. Click on any color to
- select it. In the bottom part of the window is displayed any
- aliases for the selected color (those color names that have the
- same RGB value, but were found later in the text database). For
- example, find the color "Black" and you'll see that its aliases
- are "gray0" and "grey0".
-
- If the color has no aliases you'll see "<no aliases>" here. If you
- just want to see if a color has an alias, and do not want to select a
- color when you click on it, turn off "Update on Click".
-
- Note that the color list is always updated when a color is selected
- from the main window. There's no way to turn this feature off. If
- the selected color has no matching color name you'll see
- "<no matching color>" in the Aliases window.
-
-
-The Details Window
-
- The "Details" window gives you more control over color selection
- than just clicking on a color chip in the main window. The row of
- buttons along the top apply the specified increment and decrement
- amounts to the selected color. These delta amounts are applied to
- the variation strips specified by the check boxes labeled "Move
- Sliders". Thus if just Red and Green are selected, hitting -10
- will subtract 10 from the color value along the red and green
- variation only. Note the message under the checkboxes; this
- indicates the primary color level being changed when more than one
- slider is tied together. For example, if Red and Green are
- selected, you will be changing the Yellow level of the selected
- color.
-
- The "At Boundary" behavior determines what happens when any color
- variation hits either the lower or upper boundaries (0 or 255) as
- a result of clicking on the top row buttons:
-
- Stop
- When the increment or decrement would send any of the tied
- variations out of bounds, the entire delta is discarded.
-
- Wrap Around
- When the increment or decrement would send any of the tied
- variations out of bounds, the out of bounds value is wrapped
- around to the other side. Thus if red were at 238 and +25
- were clicked, red would have the value 7.
-
- Preserve Distance
- When the increment or decrement would send any of the tied
- variations out of bounds, all tied variations are wrapped as
- one, so as to preserve the distance between them. Thus if
- green and blue were tied, and green was at 238 while blue was
- at 223, and +25 were clicked, green would be at 15 and blue
- would be at 0.
-
- Squash
- When the increment or decrement would send any of the tied
- variations out of bounds, the out of bounds variation is set
- to the ceiling of 255 or floor of 0, as appropriate. In this
- way, all tied variations are squashed to one edge or the
- other.
-
- The top row buttons have the following keyboard accelerators:
-
- -25 == Shift Left Arrow
- -10 == Control Left Arrow
- -1 == Left Arrow
- +1 == Right Arrow
- +10 == Control Right Arrow
- +25 == Shift Right Arrow
-
-
-Keyboard Accelerators
-
- Alt-w in any secondary window dismisses the window. In the main
- window it exits Pynche (except when running as a modal).
-
- Alt-q in any window exits Pynche (except when running as a modal).
-
-
-Persistency
-
- Pynche remembers various settings of options and colors between
- invocations, storing these values in a `persistent initialization
- file'. The actual location of this file is specified by the
- --initfile option (see above), and defaults to ~/.pynche.
-
- When Pynche exits, it saves these values in the init file, and
- re-reads them when it starts up. There is no locking on this
- file, so if you run multiple instances of Pynche at a time, you
- may clobber the init file.
-
- The actual options stored include
-
- - the currently selected color
-
- - all settings of checkbox and radio button options in all windows
-
- - the contents of the text window, the current text selection and
- insertion point, and all current text widget element color
- settings.
-
- - the name of the color database file (but not its contents)
-
- You can inhibit Pynche from reading the init file by supplying the
- --ignore option on the command line. However, you cannot suppress
- the storing of the settings in the init file on Pynche exit. If
- you really want to do this, use /dev/null as the init file, using
- --initfile.
-
-
-Color Name Database Files
-
- Pynche uses a color name database file to calculate the nearest
- color to the selected color, and to display in the Color List
- view. Several files are distributed with Pynche, described
- below. By default, the X11 color name database file is selected.
- Other files:
-
- html40colors.txt -- the HTML 4.0 guaranteed color names
-
- websafe.txt -- the 216 "web-safe" colors that Netscape and MSIE
- guarantee will not be dithered. These are specified in #rrggbb
- format for both values and names
-
- webcolors.txt -- The 140 color names that Tim Peters and his
- sister say NS and MSIE both understand (with some controversy over
- AliceBlue).
-
- namedcolors.txt -- an alternative set of Netscape colors.
-
- You can switch between files by choosing "Load palette..." from
- the "File" menu. This brings up a standard Tk file dialog.
- Choose the file you want and then click "Ok". If Pynche
- understands the format in this file, it will load the database and
- update the appropriate windows. If not, it will bring up an error
- dialog.
-
-
-To Do
-
- Here's a brief list of things I want to do (some mythical day):
-
- - Better support for resizing the top level windows
-
- - More output views, e.g. color solids
-
- - Have the notion of a `last color selected'; this may require a
- new output view
-
- - Support setting the font in the text view
-
- - Support distutils setup.py for installation
-
- I'm open to suggestions!
-
-
-
-Local Variables:
-indent-tabs-mode: nil
-End:
diff --git a/Tools/pynche/StripViewer.py b/Tools/pynche/StripViewer.py
deleted file mode 100644
index 6914ca9..0000000
--- a/Tools/pynche/StripViewer.py
+++ /dev/null
@@ -1,397 +0,0 @@
-"""Strip viewer and related widgets.
-
-The classes in this file implement the StripViewer shown in the top two thirds
-of the main Pynche window. It consists of three StripWidgets which display
-the variations in red, green, and blue respectively of the currently selected
-r/g/b color value.
-
-Each StripWidget shows the color variations that are reachable by varying an
-axis of the currently selected color. So for example, if the color is
-
- (R,G,B)=(127,163,196)
-
-then the Red variations show colors from (0,163,196) to (255,163,196), the
-Green variations show colors from (127,0,196) to (127,255,196), and the Blue
-variations show colors from (127,163,0) to (127,163,255).
-
-The selected color is always visible in all three StripWidgets, and in fact
-each StripWidget highlights the selected color, and has an arrow pointing to
-the selected chip, which includes the value along that particular axis.
-
-Clicking on any chip in any StripWidget selects that color, and updates all
-arrows and other windows. By toggling on Update while dragging, Pynche will
-select the color under the cursor while you drag it, but be forewarned that
-this can be slow.
-"""
-
-from tkinter import *
-import ColorDB
-
-# Load this script into the Tcl interpreter and call it in
-# StripWidget.set_color(). This is about as fast as it can be with the
-# current _tkinter.c interface, which doesn't support Tcl Objects.
-TCLPROC = '''\
-proc setcolor {canv colors} {
- set i 1
- foreach c $colors {
- $canv itemconfigure $i -fill $c -outline $c
- incr i
- }
-}
-'''
-
-# Tcl event types
-BTNDOWN = 4
-BTNUP = 5
-BTNDRAG = 6
-
-SPACE = ' '
-
-
-
-def constant(numchips):
- step = 255.0 / (numchips - 1)
- start = 0.0
- seq = []
- while numchips > 0:
- seq.append(int(start))
- start = start + step
- numchips = numchips - 1
- return seq
-
-# red variations, green+blue = cyan constant
-def constant_red_generator(numchips, red, green, blue):
- seq = constant(numchips)
- return list(zip([red] * numchips, seq, seq))
-
-# green variations, red+blue = magenta constant
-def constant_green_generator(numchips, red, green, blue):
- seq = constant(numchips)
- return list(zip(seq, [green] * numchips, seq))
-
-# blue variations, red+green = yellow constant
-def constant_blue_generator(numchips, red, green, blue):
- seq = constant(numchips)
- return list(zip(seq, seq, [blue] * numchips))
-
-# red variations, green+blue = cyan constant
-def constant_cyan_generator(numchips, red, green, blue):
- seq = constant(numchips)
- return list(zip(seq, [green] * numchips, [blue] * numchips))
-
-# green variations, red+blue = magenta constant
-def constant_magenta_generator(numchips, red, green, blue):
- seq = constant(numchips)
- return list(zip([red] * numchips, seq, [blue] * numchips))
-
-# blue variations, red+green = yellow constant
-def constant_yellow_generator(numchips, red, green, blue):
- seq = constant(numchips)
- return list(zip([red] * numchips, [green] * numchips, seq))
-
-
-
-class LeftArrow:
- _ARROWWIDTH = 30
- _ARROWHEIGHT = 15
- _YOFFSET = 13
- _TEXTYOFFSET = 1
- _TAG = ('leftarrow',)
-
- def __init__(self, canvas, x):
- self._canvas = canvas
- self.__arrow, self.__text = self._create(x)
- self.move_to(x)
-
- def _create(self, x):
- arrow = self._canvas.create_line(
- x, self._ARROWHEIGHT + self._YOFFSET,
- x, self._YOFFSET,
- x + self._ARROWWIDTH, self._YOFFSET,
- arrow='first',
- width=3.0,
- tags=self._TAG)
- text = self._canvas.create_text(
- x + self._ARROWWIDTH + 13,
- self._ARROWHEIGHT - self._TEXTYOFFSET,
- tags=self._TAG,
- text='128')
- return arrow, text
-
- def _x(self):
- coords = list(self._canvas.coords(self._TAG))
- assert coords
- return coords[0]
-
- def move_to(self, x):
- deltax = x - self._x()
- self._canvas.move(self._TAG, deltax, 0)
-
- def set_text(self, text):
- self._canvas.itemconfigure(self.__text, text=text)
-
-
-class RightArrow(LeftArrow):
- _TAG = ('rightarrow',)
-
- def _create(self, x):
- arrow = self._canvas.create_line(
- x, self._YOFFSET,
- x + self._ARROWWIDTH, self._YOFFSET,
- x + self._ARROWWIDTH, self._ARROWHEIGHT + self._YOFFSET,
- arrow='last',
- width=3.0,
- tags=self._TAG)
- text = self._canvas.create_text(
- x - self._ARROWWIDTH + 15, # BAW: kludge
- self._ARROWHEIGHT - self._TEXTYOFFSET,
- justify=RIGHT,
- text='128',
- tags=self._TAG)
- return arrow, text
-
- def _x(self):
- coords = list(self._canvas.coords(self._TAG))
- assert coords
- return coords[0] + self._ARROWWIDTH
-
-
-
-class StripWidget:
- _CHIPHEIGHT = 50
- _CHIPWIDTH = 10
- _NUMCHIPS = 40
-
- def __init__(self, switchboard,
- master = None,
- chipwidth = _CHIPWIDTH,
- chipheight = _CHIPHEIGHT,
- numchips = _NUMCHIPS,
- generator = None,
- axis = None,
- label = '',
- uwdvar = None,
- hexvar = None):
- # instance variables
- self.__generator = generator
- self.__axis = axis
- self.__numchips = numchips
- assert self.__axis in (0, 1, 2)
- self.__uwd = uwdvar
- self.__hexp = hexvar
- # the last chip selected
- self.__lastchip = None
- self.__sb = switchboard
-
- canvaswidth = numchips * (chipwidth + 1)
- canvasheight = chipheight + 43 # BAW: Kludge
-
- # create the canvas and pack it
- canvas = self.__canvas = Canvas(master,
- width=canvaswidth,
- height=canvasheight,
-## borderwidth=2,
-## relief=GROOVE
- )
-
- canvas.pack()
- canvas.bind('<ButtonPress-1>', self.__select_chip)
- canvas.bind('<ButtonRelease-1>', self.__select_chip)
- canvas.bind('<B1-Motion>', self.__select_chip)
-
- # Load a proc into the Tcl interpreter. This is used in the
- # set_color() method to speed up setting the chip colors.
- canvas.tk.eval(TCLPROC)
-
- # create the color strip
- chips = self.__chips = []
- x = 1
- y = 30
- tags = ('chip',)
- for c in range(self.__numchips):
- color = 'grey'
- canvas.create_rectangle(
- x, y, x+chipwidth, y+chipheight,
- fill=color, outline=color,
- tags=tags)
- x = x + chipwidth + 1 # for outline
- chips.append(color)
-
- # create the strip label
- self.__label = canvas.create_text(
- 3, y + chipheight + 8,
- text=label,
- anchor=W)
-
- # create the arrow and text item
- chipx = self.__arrow_x(0)
- self.__leftarrow = LeftArrow(canvas, chipx)
-
- chipx = self.__arrow_x(len(chips) - 1)
- self.__rightarrow = RightArrow(canvas, chipx)
-
- def __arrow_x(self, chipnum):
- coords = self.__canvas.coords(chipnum+1)
- assert coords
- x0, y0, x1, y1 = coords
- return (x1 + x0) / 2.0
-
- # Invoked when one of the chips is clicked. This should just tell the
- # switchboard to set the color on all the output components
- def __select_chip(self, event=None):
- x = event.x
- y = event.y
- canvas = self.__canvas
- chip = canvas.find_overlapping(x, y, x, y)
- if chip and (1 <= chip[0] <= self.__numchips):
- color = self.__chips[chip[0]-1]
- red, green, blue = ColorDB.rrggbb_to_triplet(color)
- etype = int(event.type)
- if (etype == BTNUP or self.__uwd.get()):
- # update everyone
- self.__sb.update_views(red, green, blue)
- else:
- # just track the arrows
- self.__trackarrow(chip[0], (red, green, blue))
-
- def __trackarrow(self, chip, rgbtuple):
- # invert the last chip
- if self.__lastchip is not None:
- color = self.__canvas.itemcget(self.__lastchip, 'fill')
- self.__canvas.itemconfigure(self.__lastchip, outline=color)
- self.__lastchip = chip
- # get the arrow's text
- coloraxis = rgbtuple[self.__axis]
- if self.__hexp.get():
- # hex
- text = hex(coloraxis)
- else:
- # decimal
- text = repr(coloraxis)
- # move the arrow, and set its text
- if coloraxis <= 128:
- # use the left arrow
- self.__leftarrow.set_text(text)
- self.__leftarrow.move_to(self.__arrow_x(chip-1))
- self.__rightarrow.move_to(-100)
- else:
- # use the right arrow
- self.__rightarrow.set_text(text)
- self.__rightarrow.move_to(self.__arrow_x(chip-1))
- self.__leftarrow.move_to(-100)
- # and set the chip's outline
- brightness = ColorDB.triplet_to_brightness(rgbtuple)
- if brightness <= 128:
- outline = 'white'
- else:
- outline = 'black'
- self.__canvas.itemconfigure(chip, outline=outline)
-
-
- def update_yourself(self, red, green, blue):
- assert self.__generator
- i = 1
- chip = 0
- chips = self.__chips = []
- tk = self.__canvas.tk
- # get the red, green, and blue components for all chips
- for t in self.__generator(self.__numchips, red, green, blue):
- rrggbb = ColorDB.triplet_to_rrggbb(t)
- chips.append(rrggbb)
- tred, tgreen, tblue = t
- if tred <= red and tgreen <= green and tblue <= blue:
- chip = i
- i = i + 1
- # call the raw tcl script
- colors = SPACE.join(chips)
- tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors))
- # move the arrows around
- self.__trackarrow(chip, (red, green, blue))
-
- def set(self, label, generator):
- self.__canvas.itemconfigure(self.__label, text=label)
- self.__generator = generator
-
-
-class StripViewer:
- def __init__(self, switchboard, master=None):
- self.__sb = switchboard
- optiondb = switchboard.optiondb()
- # create a frame inside the master.
- frame = Frame(master, relief=RAISED, borderwidth=1)
- frame.grid(row=1, column=0, columnspan=2, sticky='NSEW')
- # create the options to be used later
- uwd = self.__uwdvar = BooleanVar()
- uwd.set(optiondb.get('UPWHILEDRAG', 0))
- hexp = self.__hexpvar = BooleanVar()
- hexp.set(optiondb.get('HEXSTRIP', 0))
- # create the red, green, blue strips inside their own frame
- frame1 = Frame(frame)
- frame1.pack(expand=YES, fill=BOTH)
- self.__reds = StripWidget(switchboard, frame1,
- generator=constant_cyan_generator,
- axis=0,
- label='Red Variations',
- uwdvar=uwd, hexvar=hexp)
-
- self.__greens = StripWidget(switchboard, frame1,
- generator=constant_magenta_generator,
- axis=1,
- label='Green Variations',
- uwdvar=uwd, hexvar=hexp)
-
- self.__blues = StripWidget(switchboard, frame1,
- generator=constant_yellow_generator,
- axis=2,
- label='Blue Variations',
- uwdvar=uwd, hexvar=hexp)
-
- # create a frame to contain the controls
- frame2 = Frame(frame)
- frame2.pack(expand=YES, fill=BOTH)
- frame2.columnconfigure(0, weight=20)
- frame2.columnconfigure(2, weight=20)
-
- padx = 8
-
- # create the black button
- blackbtn = Button(frame2,
- text='Black',
- command=self.__toblack)
- blackbtn.grid(row=0, column=0, rowspan=2, sticky=W, padx=padx)
-
- # create the controls
- uwdbtn = Checkbutton(frame2,
- text='Update while dragging',
- variable=uwd)
- uwdbtn.grid(row=0, column=1, sticky=W)
- hexbtn = Checkbutton(frame2,
- text='Hexadecimal',
- variable=hexp,
- command=self.__togglehex)
- hexbtn.grid(row=1, column=1, sticky=W)
-
- # create the white button
- whitebtn = Button(frame2,
- text='White',
- command=self.__towhite)
- whitebtn.grid(row=0, column=2, rowspan=2, sticky=E, padx=padx)
-
- def update_yourself(self, red, green, blue):
- self.__reds.update_yourself(red, green, blue)
- self.__greens.update_yourself(red, green, blue)
- self.__blues.update_yourself(red, green, blue)
-
- def __togglehex(self, event=None):
- red, green, blue = self.__sb.current_rgb()
- self.update_yourself(red, green, blue)
-
- def __toblack(self, event=None):
- self.__sb.update_views(0, 0, 0)
-
- def __towhite(self, event=None):
- self.__sb.update_views(255, 255, 255)
-
- def save_options(self, optiondb):
- optiondb['UPWHILEDRAG'] = self.__uwdvar.get()
- optiondb['HEXSTRIP'] = self.__hexpvar.get()
diff --git a/Tools/pynche/Switchboard.py b/Tools/pynche/Switchboard.py
deleted file mode 100644
index 013bb01..0000000
--- a/Tools/pynche/Switchboard.py
+++ /dev/null
@@ -1,138 +0,0 @@
-"""Switchboard class.
-
-This class is used to coordinate updates among all Viewers. Every Viewer must
-conform to the following interface:
-
- - it must include a method called update_yourself() which takes three
- arguments; the red, green, and blue values of the selected color.
-
- - When a Viewer selects a color and wishes to update all other Views, it
- should call update_views() on the Switchboard object. Note that the
- Viewer typically does *not* update itself before calling update_views(),
- since this would cause it to get updated twice.
-
-Optionally, Viewers can also implement:
-
- - save_options() which takes an optiondb (a dictionary). Store into this
- dictionary any values the Viewer wants to save in the persistent
- ~/.pynche file. This dictionary is saved using marshal. The namespace
- for the keys is ad-hoc; make sure you don't clobber some other Viewer's
- keys!
-
- - withdraw() which takes no arguments. This is called when Pynche is
- unmapped. All Viewers should implement this.
-
- - colordb_changed() which takes a single argument, an instance of
- ColorDB. This is called whenever the color name database is changed and
- gives a chance for the Viewers to do something on those events. See
- ListViewer for details.
-
-External Viewers are found dynamically. Viewer modules should have names such
-as FooViewer.py. If such a named module has a module global variable called
-ADDTOVIEW and this variable is true, the Viewer will be added dynamically to
-the `View' menu. ADDTOVIEW contains a string which is used as the menu item
-to display the Viewer (one kludge: if the string contains a `%', this is used
-to indicate that the next character will get an underline in the menu,
-otherwise the first character is underlined).
-
-FooViewer.py should contain a class called FooViewer, and its constructor
-should take two arguments, an instance of Switchboard, and optionally a Tk
-master window.
-
-"""
-
-import sys
-import marshal
-
-
-
-class Switchboard:
- def __init__(self, initfile):
- self.__initfile = initfile
- self.__colordb = None
- self.__optiondb = {}
- self.__views = []
- self.__red = 0
- self.__green = 0
- self.__blue = 0
- self.__canceled = 0
- # read the initialization file
- fp = None
- if initfile:
- try:
- try:
- fp = open(initfile, 'rb')
- self.__optiondb = marshal.load(fp)
- if not isinstance(self.__optiondb, dict):
- print('Problem reading options from file:', initfile,
- file=sys.stderr)
- self.__optiondb = {}
- except (IOError, EOFError, ValueError):
- pass
- finally:
- if fp:
- fp.close()
-
- def add_view(self, view):
- self.__views.append(view)
-
- def update_views(self, red, green, blue):
- self.__red = red
- self.__green = green
- self.__blue = blue
- for v in self.__views:
- v.update_yourself(red, green, blue)
-
- def update_views_current(self):
- self.update_views(self.__red, self.__green, self.__blue)
-
- def current_rgb(self):
- return self.__red, self.__green, self.__blue
-
- def colordb(self):
- return self.__colordb
-
- def set_colordb(self, colordb):
- self.__colordb = colordb
- for v in self.__views:
- if hasattr(v, 'colordb_changed'):
- v.colordb_changed(colordb)
- self.update_views_current()
-
- def optiondb(self):
- return self.__optiondb
-
- def save_views(self):
- # save the current color
- self.__optiondb['RED'] = self.__red
- self.__optiondb['GREEN'] = self.__green
- self.__optiondb['BLUE'] = self.__blue
- for v in self.__views:
- if hasattr(v, 'save_options'):
- v.save_options(self.__optiondb)
- # save the name of the file used for the color database. we'll try to
- # load this first.
- self.__optiondb['DBFILE'] = self.__colordb.filename()
- fp = None
- try:
- try:
- fp = open(self.__initfile, 'wb')
- except IOError:
- print('Cannot write options to file:', \
- self.__initfile, file=sys.stderr)
- else:
- marshal.dump(self.__optiondb, fp)
- finally:
- if fp:
- fp.close()
-
- def withdraw_views(self):
- for v in self.__views:
- if hasattr(v, 'withdraw'):
- v.withdraw()
-
- def canceled(self, flag=1):
- self.__canceled = flag
-
- def canceled_p(self):
- return self.__canceled
diff --git a/Tools/pynche/TextViewer.py b/Tools/pynche/TextViewer.py
deleted file mode 100644
index baa1e62..0000000
--- a/Tools/pynche/TextViewer.py
+++ /dev/null
@@ -1,188 +0,0 @@
-"""TextViewer class.
-
-The TextViewer allows you to see how the selected color would affect various
-characteristics of a Tk text widget. This is an output viewer only.
-
-In the top part of the window is a standard text widget with some sample text
-in it. You are free to edit this text in any way you want (BAW: allow you to
-change font characteristics). If you want changes in other viewers to update
-text characteristics, turn on Track color changes.
-
-To select which characteristic tracks the change, select one of the radio
-buttons in the window below. Text foreground and background affect the text
-in the window above. The Selection is what you see when you click the middle
-button and drag it through some text. The Insertion is the insertion cursor
-in the text window (which only has a background).
-"""
-
-from tkinter import *
-import ColorDB
-
-ADDTOVIEW = 'Text Window...'
-
-
-
-class TextViewer:
- def __init__(self, switchboard, master=None):
- self.__sb = switchboard
- optiondb = switchboard.optiondb()
- root = self.__root = Toplevel(master, class_='Pynche')
- root.protocol('WM_DELETE_WINDOW', self.withdraw)
- root.title('Pynche Text Window')
- root.iconname('Pynche Text Window')
- root.bind('<Alt-q>', self.__quit)
- root.bind('<Alt-Q>', self.__quit)
- root.bind('<Alt-w>', self.withdraw)
- root.bind('<Alt-W>', self.withdraw)
- #
- # create the text widget
- #
- self.__text = Text(root, relief=SUNKEN,
- background=optiondb.get('TEXTBG', 'black'),
- foreground=optiondb.get('TEXTFG', 'white'),
- width=35, height=15)
- sfg = optiondb.get('TEXT_SFG')
- if sfg:
- self.__text.configure(selectforeground=sfg)
- sbg = optiondb.get('TEXT_SBG')
- if sbg:
- self.__text.configure(selectbackground=sbg)
- ibg = optiondb.get('TEXT_IBG')
- if ibg:
- self.__text.configure(insertbackground=ibg)
- self.__text.pack()
- self.__text.insert(0.0, optiondb.get('TEXT', '''\
-Insert some stuff here and play
-with the buttons below to see
-how the colors interact in
-textual displays.
-
-See how the selection can also
-be affected by tickling the buttons
-and choosing a color.'''))
- insert = optiondb.get('TEXTINS')
- if insert:
- self.__text.mark_set(INSERT, insert)
- try:
- start, end = optiondb.get('TEXTSEL', (6.0, END))
- self.__text.tag_add(SEL, start, end)
- except ValueError:
- # selection wasn't set
- pass
- self.__text.focus_set()
- #
- # variables
- self.__trackp = BooleanVar()
- self.__trackp.set(optiondb.get('TRACKP', 0))
- self.__which = IntVar()
- self.__which.set(optiondb.get('WHICH', 0))
- #
- # track toggle
- self.__t = Checkbutton(root, text='Track color changes',
- variable=self.__trackp,
- relief=GROOVE,
- command=self.__toggletrack)
- self.__t.pack(fill=X, expand=YES)
- frame = self.__frame = Frame(root)
- frame.pack()
- #
- # labels
- self.__labels = []
- row = 2
- for text in ('Text:', 'Selection:', 'Insertion:'):
- l = Label(frame, text=text)
- l.grid(row=row, column=0, sticky=E)
- self.__labels.append(l)
- row += 1
- col = 1
- for text in ('Foreground', 'Background'):
- l = Label(frame, text=text)
- l.grid(row=1, column=col)
- self.__labels.append(l)
- col += 1
- #
- # radios
- self.__radios = []
- for col in (1, 2):
- for row in (2, 3, 4):
- # there is no insertforeground option
- if row==4 and col==1:
- continue
- r = Radiobutton(frame, variable=self.__which,
- value=(row-2)*2 + col-1,
- command=self.__set_color)
- r.grid(row=row, column=col)
- self.__radios.append(r)
- self.__toggletrack()
-
- def __quit(self, event=None):
- self.__root.quit()
-
- def withdraw(self, event=None):
- self.__root.withdraw()
-
- def deiconify(self, event=None):
- self.__root.deiconify()
-
- def __forceupdate(self, event=None):
- self.__sb.update_views_current()
-
- def __toggletrack(self, event=None):
- if self.__trackp.get():
- state = NORMAL
- fg = self.__radios[0]['foreground']
- else:
- state = DISABLED
- fg = self.__radios[0]['disabledforeground']
- for r in self.__radios:
- r.configure(state=state)
- for l in self.__labels:
- l.configure(foreground=fg)
-
- def __set_color(self, event=None):
- which = self.__which.get()
- text = self.__text
- if which == 0:
- color = text['foreground']
- elif which == 1:
- color = text['background']
- elif which == 2:
- color = text['selectforeground']
- elif which == 3:
- color = text['selectbackground']
- elif which == 5:
- color = text['insertbackground']
- try:
- red, green, blue = ColorDB.rrggbb_to_triplet(color)
- except ColorDB.BadColor:
- # must have been a color name
- red, green, blue = self.__sb.colordb().find_byname(color)
- self.__sb.update_views(red, green, blue)
-
- def update_yourself(self, red, green, blue):
- if self.__trackp.get():
- colorname = ColorDB.triplet_to_rrggbb((red, green, blue))
- which = self.__which.get()
- text = self.__text
- if which == 0:
- text.configure(foreground=colorname)
- elif which == 1:
- text.configure(background=colorname)
- elif which == 2:
- text.configure(selectforeground=colorname)
- elif which == 3:
- text.configure(selectbackground=colorname)
- elif which == 5:
- text.configure(insertbackground=colorname)
-
- def save_options(self, optiondb):
- optiondb['TRACKP'] = self.__trackp.get()
- optiondb['WHICH'] = self.__which.get()
- optiondb['TEXT'] = self.__text.get(0.0, 'end - 1c')
- optiondb['TEXTSEL'] = self.__text.tag_ranges(SEL)[0:2]
- optiondb['TEXTINS'] = self.__text.index(INSERT)
- optiondb['TEXTFG'] = self.__text['foreground']
- optiondb['TEXTBG'] = self.__text['background']
- optiondb['TEXT_SFG'] = self.__text['selectforeground']
- optiondb['TEXT_SBG'] = self.__text['selectbackground']
- optiondb['TEXT_IBG'] = self.__text['insertbackground']
diff --git a/Tools/pynche/TypeinViewer.py b/Tools/pynche/TypeinViewer.py
deleted file mode 100644
index 2f93e6b..0000000
--- a/Tools/pynche/TypeinViewer.py
+++ /dev/null
@@ -1,161 +0,0 @@
-"""TypeinViewer class.
-
-The TypeinViewer is what you see at the lower right of the main Pynche
-widget. It contains three text entry fields, one each for red, green, blue.
-Input into these windows is highly constrained; it only allows you to enter
-values that are legal for a color axis. This usually means 0-255 for decimal
-input and 0x0 - 0xff for hex input.
-
-You can toggle whether you want to view and input the values in either decimal
-or hex by clicking on Hexadecimal. By clicking on Update while typing, the
-color selection will be made on every change to the text field. Otherwise,
-you must hit Return or Tab to select the color.
-"""
-
-from tkinter import *
-
-
-
-class TypeinViewer:
- def __init__(self, switchboard, master=None):
- # non-gui ivars
- self.__sb = switchboard
- optiondb = switchboard.optiondb()
- self.__hexp = BooleanVar()
- self.__hexp.set(optiondb.get('HEXTYPE', 0))
- self.__uwtyping = BooleanVar()
- self.__uwtyping.set(optiondb.get('UPWHILETYPE', 0))
- # create the gui
- self.__frame = Frame(master, relief=RAISED, borderwidth=1)
- self.__frame.grid(row=3, column=1, sticky='NSEW')
- # Red
- self.__xl = Label(self.__frame, text='Red:')
- self.__xl.grid(row=0, column=0, sticky=E)
- subframe = Frame(self.__frame)
- subframe.grid(row=0, column=1)
- self.__xox = Label(subframe, text='0x')
- self.__xox.grid(row=0, column=0, sticky=E)
- self.__xox['font'] = 'courier'
- self.__x = Entry(subframe, width=3)
- self.__x.grid(row=0, column=1)
- self.__x.bindtags(self.__x.bindtags() + ('Normalize', 'Update'))
- self.__x.bind_class('Normalize', '<Key>', self.__normalize)
- self.__x.bind_class('Update' , '<Key>', self.__maybeupdate)
- # Green
- self.__yl = Label(self.__frame, text='Green:')
- self.__yl.grid(row=1, column=0, sticky=E)
- subframe = Frame(self.__frame)
- subframe.grid(row=1, column=1)
- self.__yox = Label(subframe, text='0x')
- self.__yox.grid(row=0, column=0, sticky=E)
- self.__yox['font'] = 'courier'
- self.__y = Entry(subframe, width=3)
- self.__y.grid(row=0, column=1)
- self.__y.bindtags(self.__y.bindtags() + ('Normalize', 'Update'))
- # Blue
- self.__zl = Label(self.__frame, text='Blue:')
- self.__zl.grid(row=2, column=0, sticky=E)
- subframe = Frame(self.__frame)
- subframe.grid(row=2, column=1)
- self.__zox = Label(subframe, text='0x')
- self.__zox.grid(row=0, column=0, sticky=E)
- self.__zox['font'] = 'courier'
- self.__z = Entry(subframe, width=3)
- self.__z.grid(row=0, column=1)
- self.__z.bindtags(self.__z.bindtags() + ('Normalize', 'Update'))
- # Update while typing?
- self.__uwt = Checkbutton(self.__frame,
- text='Update while typing',
- variable=self.__uwtyping)
- self.__uwt.grid(row=3, column=0, columnspan=2, sticky=W)
- # Hex/Dec
- self.__hex = Checkbutton(self.__frame,
- text='Hexadecimal',
- variable=self.__hexp,
- command=self.__togglehex)
- self.__hex.grid(row=4, column=0, columnspan=2, sticky=W)
-
- def __togglehex(self, event=None):
- red, green, blue = self.__sb.current_rgb()
- if self.__hexp.get():
- label = '0x'
- else:
- label = ' '
- self.__xox['text'] = label
- self.__yox['text'] = label
- self.__zox['text'] = label
- self.update_yourself(red, green, blue)
-
- def __normalize(self, event=None):
- ew = event.widget
- contents = ew.get()
- icursor = ew.index(INSERT)
- if contents and contents[0] in 'xX' and self.__hexp.get():
- contents = '0' + contents
- # Figure out the contents in the current base.
- try:
- if self.__hexp.get():
- v = int(contents, 16)
- else:
- v = int(contents)
- except ValueError:
- v = None
- # If value is not legal, or empty, delete the last character inserted
- # and ring the bell. Don't ring the bell if the field is empty (it'll
- # just equal zero.
- if v is None:
- pass
- elif v < 0 or v > 255:
- i = ew.index(INSERT)
- if event.char:
- contents = contents[:i-1] + contents[i:]
- icursor -= 1
- ew.bell()
- elif self.__hexp.get():
- contents = hex(v)[2:]
- else:
- contents = int(v)
- ew.delete(0, END)
- ew.insert(0, contents)
- ew.icursor(icursor)
-
- def __maybeupdate(self, event=None):
- if self.__uwtyping.get() or event.keysym in ('Return', 'Tab'):
- self.__update(event)
-
- def __update(self, event=None):
- redstr = self.__x.get() or '0'
- greenstr = self.__y.get() or '0'
- bluestr = self.__z.get() or '0'
- if self.__hexp.get():
- base = 16
- else:
- base = 10
- red, green, blue = [int(x, base) for x in (redstr, greenstr, bluestr)]
- self.__sb.update_views(red, green, blue)
-
- def update_yourself(self, red, green, blue):
- if self.__hexp.get():
- sred, sgreen, sblue = [hex(x)[2:] for x in (red, green, blue)]
- else:
- sred, sgreen, sblue = red, green, blue
- x, y, z = self.__x, self.__y, self.__z
- xicursor = x.index(INSERT)
- yicursor = y.index(INSERT)
- zicursor = z.index(INSERT)
- x.delete(0, END)
- y.delete(0, END)
- z.delete(0, END)
- x.insert(0, sred)
- y.insert(0, sgreen)
- z.insert(0, sblue)
- x.icursor(xicursor)
- y.icursor(yicursor)
- z.icursor(zicursor)
-
- def hexp_var(self):
- return self.__hexp
-
- def save_options(self, optiondb):
- optiondb['HEXTYPE'] = self.__hexp.get()
- optiondb['UPWHILETYPE'] = self.__uwtyping.get()
diff --git a/Tools/pynche/X/rgb.txt b/Tools/pynche/X/rgb.txt
deleted file mode 100644
index b11ffd0..0000000
--- a/Tools/pynche/X/rgb.txt
+++ /dev/null
@@ -1,753 +0,0 @@
-! $XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp $
-255 250 250 snow
-248 248 255 ghost white
-248 248 255 GhostWhite
-245 245 245 white smoke
-245 245 245 WhiteSmoke
-220 220 220 gainsboro
-255 250 240 floral white
-255 250 240 FloralWhite
-253 245 230 old lace
-253 245 230 OldLace
-250 240 230 linen
-250 235 215 antique white
-250 235 215 AntiqueWhite
-255 239 213 papaya whip
-255 239 213 PapayaWhip
-255 235 205 blanched almond
-255 235 205 BlanchedAlmond
-255 228 196 bisque
-255 218 185 peach puff
-255 218 185 PeachPuff
-255 222 173 navajo white
-255 222 173 NavajoWhite
-255 228 181 moccasin
-255 248 220 cornsilk
-255 255 240 ivory
-255 250 205 lemon chiffon
-255 250 205 LemonChiffon
-255 245 238 seashell
-240 255 240 honeydew
-245 255 250 mint cream
-245 255 250 MintCream
-240 255 255 azure
-240 248 255 alice blue
-240 248 255 AliceBlue
-230 230 250 lavender
-255 240 245 lavender blush
-255 240 245 LavenderBlush
-255 228 225 misty rose
-255 228 225 MistyRose
-255 255 255 white
- 0 0 0 black
- 47 79 79 dark slate gray
- 47 79 79 DarkSlateGray
- 47 79 79 dark slate grey
- 47 79 79 DarkSlateGrey
-105 105 105 dim gray
-105 105 105 DimGray
-105 105 105 dim grey
-105 105 105 DimGrey
-112 128 144 slate gray
-112 128 144 SlateGray
-112 128 144 slate grey
-112 128 144 SlateGrey
-119 136 153 light slate gray
-119 136 153 LightSlateGray
-119 136 153 light slate grey
-119 136 153 LightSlateGrey
-190 190 190 gray
-190 190 190 grey
-211 211 211 light grey
-211 211 211 LightGrey
-211 211 211 light gray
-211 211 211 LightGray
- 25 25 112 midnight blue
- 25 25 112 MidnightBlue
- 0 0 128 navy
- 0 0 128 navy blue
- 0 0 128 NavyBlue
-100 149 237 cornflower blue
-100 149 237 CornflowerBlue
- 72 61 139 dark slate blue
- 72 61 139 DarkSlateBlue
-106 90 205 slate blue
-106 90 205 SlateBlue
-123 104 238 medium slate blue
-123 104 238 MediumSlateBlue
-132 112 255 light slate blue
-132 112 255 LightSlateBlue
- 0 0 205 medium blue
- 0 0 205 MediumBlue
- 65 105 225 royal blue
- 65 105 225 RoyalBlue
- 0 0 255 blue
- 30 144 255 dodger blue
- 30 144 255 DodgerBlue
- 0 191 255 deep sky blue
- 0 191 255 DeepSkyBlue
-135 206 235 sky blue
-135 206 235 SkyBlue
-135 206 250 light sky blue
-135 206 250 LightSkyBlue
- 70 130 180 steel blue
- 70 130 180 SteelBlue
-176 196 222 light steel blue
-176 196 222 LightSteelBlue
-173 216 230 light blue
-173 216 230 LightBlue
-176 224 230 powder blue
-176 224 230 PowderBlue
-175 238 238 pale turquoise
-175 238 238 PaleTurquoise
- 0 206 209 dark turquoise
- 0 206 209 DarkTurquoise
- 72 209 204 medium turquoise
- 72 209 204 MediumTurquoise
- 64 224 208 turquoise
- 0 255 255 cyan
-224 255 255 light cyan
-224 255 255 LightCyan
- 95 158 160 cadet blue
- 95 158 160 CadetBlue
-102 205 170 medium aquamarine
-102 205 170 MediumAquamarine
-127 255 212 aquamarine
- 0 100 0 dark green
- 0 100 0 DarkGreen
- 85 107 47 dark olive green
- 85 107 47 DarkOliveGreen
-143 188 143 dark sea green
-143 188 143 DarkSeaGreen
- 46 139 87 sea green
- 46 139 87 SeaGreen
- 60 179 113 medium sea green
- 60 179 113 MediumSeaGreen
- 32 178 170 light sea green
- 32 178 170 LightSeaGreen
-152 251 152 pale green
-152 251 152 PaleGreen
- 0 255 127 spring green
- 0 255 127 SpringGreen
-124 252 0 lawn green
-124 252 0 LawnGreen
- 0 255 0 green
-127 255 0 chartreuse
- 0 250 154 medium spring green
- 0 250 154 MediumSpringGreen
-173 255 47 green yellow
-173 255 47 GreenYellow
- 50 205 50 lime green
- 50 205 50 LimeGreen
-154 205 50 yellow green
-154 205 50 YellowGreen
- 34 139 34 forest green
- 34 139 34 ForestGreen
-107 142 35 olive drab
-107 142 35 OliveDrab
-189 183 107 dark khaki
-189 183 107 DarkKhaki
-240 230 140 khaki
-238 232 170 pale goldenrod
-238 232 170 PaleGoldenrod
-250 250 210 light goldenrod yellow
-250 250 210 LightGoldenrodYellow
-255 255 224 light yellow
-255 255 224 LightYellow
-255 255 0 yellow
-255 215 0 gold
-238 221 130 light goldenrod
-238 221 130 LightGoldenrod
-218 165 32 goldenrod
-184 134 11 dark goldenrod
-184 134 11 DarkGoldenrod
-188 143 143 rosy brown
-188 143 143 RosyBrown
-205 92 92 indian red
-205 92 92 IndianRed
-139 69 19 saddle brown
-139 69 19 SaddleBrown
-160 82 45 sienna
-205 133 63 peru
-222 184 135 burlywood
-245 245 220 beige
-245 222 179 wheat
-244 164 96 sandy brown
-244 164 96 SandyBrown
-210 180 140 tan
-210 105 30 chocolate
-178 34 34 firebrick
-165 42 42 brown
-233 150 122 dark salmon
-233 150 122 DarkSalmon
-250 128 114 salmon
-255 160 122 light salmon
-255 160 122 LightSalmon
-255 165 0 orange
-255 140 0 dark orange
-255 140 0 DarkOrange
-255 127 80 coral
-240 128 128 light coral
-240 128 128 LightCoral
-255 99 71 tomato
-255 69 0 orange red
-255 69 0 OrangeRed
-255 0 0 red
-255 105 180 hot pink
-255 105 180 HotPink
-255 20 147 deep pink
-255 20 147 DeepPink
-255 192 203 pink
-255 182 193 light pink
-255 182 193 LightPink
-219 112 147 pale violet red
-219 112 147 PaleVioletRed
-176 48 96 maroon
-199 21 133 medium violet red
-199 21 133 MediumVioletRed
-208 32 144 violet red
-208 32 144 VioletRed
-255 0 255 magenta
-238 130 238 violet
-221 160 221 plum
-218 112 214 orchid
-186 85 211 medium orchid
-186 85 211 MediumOrchid
-153 50 204 dark orchid
-153 50 204 DarkOrchid
-148 0 211 dark violet
-148 0 211 DarkViolet
-138 43 226 blue violet
-138 43 226 BlueViolet
-160 32 240 purple
-147 112 219 medium purple
-147 112 219 MediumPurple
-216 191 216 thistle
-255 250 250 snow1
-238 233 233 snow2
-205 201 201 snow3
-139 137 137 snow4
-255 245 238 seashell1
-238 229 222 seashell2
-205 197 191 seashell3
-139 134 130 seashell4
-255 239 219 AntiqueWhite1
-238 223 204 AntiqueWhite2
-205 192 176 AntiqueWhite3
-139 131 120 AntiqueWhite4
-255 228 196 bisque1
-238 213 183 bisque2
-205 183 158 bisque3
-139 125 107 bisque4
-255 218 185 PeachPuff1
-238 203 173 PeachPuff2
-205 175 149 PeachPuff3
-139 119 101 PeachPuff4
-255 222 173 NavajoWhite1
-238 207 161 NavajoWhite2
-205 179 139 NavajoWhite3
-139 121 94 NavajoWhite4
-255 250 205 LemonChiffon1
-238 233 191 LemonChiffon2
-205 201 165 LemonChiffon3
-139 137 112 LemonChiffon4
-255 248 220 cornsilk1
-238 232 205 cornsilk2
-205 200 177 cornsilk3
-139 136 120 cornsilk4
-255 255 240 ivory1
-238 238 224 ivory2
-205 205 193 ivory3
-139 139 131 ivory4
-240 255 240 honeydew1
-224 238 224 honeydew2
-193 205 193 honeydew3
-131 139 131 honeydew4
-255 240 245 LavenderBlush1
-238 224 229 LavenderBlush2
-205 193 197 LavenderBlush3
-139 131 134 LavenderBlush4
-255 228 225 MistyRose1
-238 213 210 MistyRose2
-205 183 181 MistyRose3
-139 125 123 MistyRose4
-240 255 255 azure1
-224 238 238 azure2
-193 205 205 azure3
-131 139 139 azure4
-131 111 255 SlateBlue1
-122 103 238 SlateBlue2
-105 89 205 SlateBlue3
- 71 60 139 SlateBlue4
- 72 118 255 RoyalBlue1
- 67 110 238 RoyalBlue2
- 58 95 205 RoyalBlue3
- 39 64 139 RoyalBlue4
- 0 0 255 blue1
- 0 0 238 blue2
- 0 0 205 blue3
- 0 0 139 blue4
- 30 144 255 DodgerBlue1
- 28 134 238 DodgerBlue2
- 24 116 205 DodgerBlue3
- 16 78 139 DodgerBlue4
- 99 184 255 SteelBlue1
- 92 172 238 SteelBlue2
- 79 148 205 SteelBlue3
- 54 100 139 SteelBlue4
- 0 191 255 DeepSkyBlue1
- 0 178 238 DeepSkyBlue2
- 0 154 205 DeepSkyBlue3
- 0 104 139 DeepSkyBlue4
-135 206 255 SkyBlue1
-126 192 238 SkyBlue2
-108 166 205 SkyBlue3
- 74 112 139 SkyBlue4
-176 226 255 LightSkyBlue1
-164 211 238 LightSkyBlue2
-141 182 205 LightSkyBlue3
- 96 123 139 LightSkyBlue4
-198 226 255 SlateGray1
-185 211 238 SlateGray2
-159 182 205 SlateGray3
-108 123 139 SlateGray4
-202 225 255 LightSteelBlue1
-188 210 238 LightSteelBlue2
-162 181 205 LightSteelBlue3
-110 123 139 LightSteelBlue4
-191 239 255 LightBlue1
-178 223 238 LightBlue2
-154 192 205 LightBlue3
-104 131 139 LightBlue4
-224 255 255 LightCyan1
-209 238 238 LightCyan2
-180 205 205 LightCyan3
-122 139 139 LightCyan4
-187 255 255 PaleTurquoise1
-174 238 238 PaleTurquoise2
-150 205 205 PaleTurquoise3
-102 139 139 PaleTurquoise4
-152 245 255 CadetBlue1
-142 229 238 CadetBlue2
-122 197 205 CadetBlue3
- 83 134 139 CadetBlue4
- 0 245 255 turquoise1
- 0 229 238 turquoise2
- 0 197 205 turquoise3
- 0 134 139 turquoise4
- 0 255 255 cyan1
- 0 238 238 cyan2
- 0 205 205 cyan3
- 0 139 139 cyan4
-151 255 255 DarkSlateGray1
-141 238 238 DarkSlateGray2
-121 205 205 DarkSlateGray3
- 82 139 139 DarkSlateGray4
-127 255 212 aquamarine1
-118 238 198 aquamarine2
-102 205 170 aquamarine3
- 69 139 116 aquamarine4
-193 255 193 DarkSeaGreen1
-180 238 180 DarkSeaGreen2
-155 205 155 DarkSeaGreen3
-105 139 105 DarkSeaGreen4
- 84 255 159 SeaGreen1
- 78 238 148 SeaGreen2
- 67 205 128 SeaGreen3
- 46 139 87 SeaGreen4
-154 255 154 PaleGreen1
-144 238 144 PaleGreen2
-124 205 124 PaleGreen3
- 84 139 84 PaleGreen4
- 0 255 127 SpringGreen1
- 0 238 118 SpringGreen2
- 0 205 102 SpringGreen3
- 0 139 69 SpringGreen4
- 0 255 0 green1
- 0 238 0 green2
- 0 205 0 green3
- 0 139 0 green4
-127 255 0 chartreuse1
-118 238 0 chartreuse2
-102 205 0 chartreuse3
- 69 139 0 chartreuse4
-192 255 62 OliveDrab1
-179 238 58 OliveDrab2
-154 205 50 OliveDrab3
-105 139 34 OliveDrab4
-202 255 112 DarkOliveGreen1
-188 238 104 DarkOliveGreen2
-162 205 90 DarkOliveGreen3
-110 139 61 DarkOliveGreen4
-255 246 143 khaki1
-238 230 133 khaki2
-205 198 115 khaki3
-139 134 78 khaki4
-255 236 139 LightGoldenrod1
-238 220 130 LightGoldenrod2
-205 190 112 LightGoldenrod3
-139 129 76 LightGoldenrod4
-255 255 224 LightYellow1
-238 238 209 LightYellow2
-205 205 180 LightYellow3
-139 139 122 LightYellow4
-255 255 0 yellow1
-238 238 0 yellow2
-205 205 0 yellow3
-139 139 0 yellow4
-255 215 0 gold1
-238 201 0 gold2
-205 173 0 gold3
-139 117 0 gold4
-255 193 37 goldenrod1
-238 180 34 goldenrod2
-205 155 29 goldenrod3
-139 105 20 goldenrod4
-255 185 15 DarkGoldenrod1
-238 173 14 DarkGoldenrod2
-205 149 12 DarkGoldenrod3
-139 101 8 DarkGoldenrod4
-255 193 193 RosyBrown1
-238 180 180 RosyBrown2
-205 155 155 RosyBrown3
-139 105 105 RosyBrown4
-255 106 106 IndianRed1
-238 99 99 IndianRed2
-205 85 85 IndianRed3
-139 58 58 IndianRed4
-255 130 71 sienna1
-238 121 66 sienna2
-205 104 57 sienna3
-139 71 38 sienna4
-255 211 155 burlywood1
-238 197 145 burlywood2
-205 170 125 burlywood3
-139 115 85 burlywood4
-255 231 186 wheat1
-238 216 174 wheat2
-205 186 150 wheat3
-139 126 102 wheat4
-255 165 79 tan1
-238 154 73 tan2
-205 133 63 tan3
-139 90 43 tan4
-255 127 36 chocolate1
-238 118 33 chocolate2
-205 102 29 chocolate3
-139 69 19 chocolate4
-255 48 48 firebrick1
-238 44 44 firebrick2
-205 38 38 firebrick3
-139 26 26 firebrick4
-255 64 64 brown1
-238 59 59 brown2
-205 51 51 brown3
-139 35 35 brown4
-255 140 105 salmon1
-238 130 98 salmon2
-205 112 84 salmon3
-139 76 57 salmon4
-255 160 122 LightSalmon1
-238 149 114 LightSalmon2
-205 129 98 LightSalmon3
-139 87 66 LightSalmon4
-255 165 0 orange1
-238 154 0 orange2
-205 133 0 orange3
-139 90 0 orange4
-255 127 0 DarkOrange1
-238 118 0 DarkOrange2
-205 102 0 DarkOrange3
-139 69 0 DarkOrange4
-255 114 86 coral1
-238 106 80 coral2
-205 91 69 coral3
-139 62 47 coral4
-255 99 71 tomato1
-238 92 66 tomato2
-205 79 57 tomato3
-139 54 38 tomato4
-255 69 0 OrangeRed1
-238 64 0 OrangeRed2
-205 55 0 OrangeRed3
-139 37 0 OrangeRed4
-255 0 0 red1
-238 0 0 red2
-205 0 0 red3
-139 0 0 red4
-255 20 147 DeepPink1
-238 18 137 DeepPink2
-205 16 118 DeepPink3
-139 10 80 DeepPink4
-255 110 180 HotPink1
-238 106 167 HotPink2
-205 96 144 HotPink3
-139 58 98 HotPink4
-255 181 197 pink1
-238 169 184 pink2
-205 145 158 pink3
-139 99 108 pink4
-255 174 185 LightPink1
-238 162 173 LightPink2
-205 140 149 LightPink3
-139 95 101 LightPink4
-255 130 171 PaleVioletRed1
-238 121 159 PaleVioletRed2
-205 104 137 PaleVioletRed3
-139 71 93 PaleVioletRed4
-255 52 179 maroon1
-238 48 167 maroon2
-205 41 144 maroon3
-139 28 98 maroon4
-255 62 150 VioletRed1
-238 58 140 VioletRed2
-205 50 120 VioletRed3
-139 34 82 VioletRed4
-255 0 255 magenta1
-238 0 238 magenta2
-205 0 205 magenta3
-139 0 139 magenta4
-255 131 250 orchid1
-238 122 233 orchid2
-205 105 201 orchid3
-139 71 137 orchid4
-255 187 255 plum1
-238 174 238 plum2
-205 150 205 plum3
-139 102 139 plum4
-224 102 255 MediumOrchid1
-209 95 238 MediumOrchid2
-180 82 205 MediumOrchid3
-122 55 139 MediumOrchid4
-191 62 255 DarkOrchid1
-178 58 238 DarkOrchid2
-154 50 205 DarkOrchid3
-104 34 139 DarkOrchid4
-155 48 255 purple1
-145 44 238 purple2
-125 38 205 purple3
- 85 26 139 purple4
-171 130 255 MediumPurple1
-159 121 238 MediumPurple2
-137 104 205 MediumPurple3
- 93 71 139 MediumPurple4
-255 225 255 thistle1
-238 210 238 thistle2
-205 181 205 thistle3
-139 123 139 thistle4
- 0 0 0 gray0
- 0 0 0 grey0
- 3 3 3 gray1
- 3 3 3 grey1
- 5 5 5 gray2
- 5 5 5 grey2
- 8 8 8 gray3
- 8 8 8 grey3
- 10 10 10 gray4
- 10 10 10 grey4
- 13 13 13 gray5
- 13 13 13 grey5
- 15 15 15 gray6
- 15 15 15 grey6
- 18 18 18 gray7
- 18 18 18 grey7
- 20 20 20 gray8
- 20 20 20 grey8
- 23 23 23 gray9
- 23 23 23 grey9
- 26 26 26 gray10
- 26 26 26 grey10
- 28 28 28 gray11
- 28 28 28 grey11
- 31 31 31 gray12
- 31 31 31 grey12
- 33 33 33 gray13
- 33 33 33 grey13
- 36 36 36 gray14
- 36 36 36 grey14
- 38 38 38 gray15
- 38 38 38 grey15
- 41 41 41 gray16
- 41 41 41 grey16
- 43 43 43 gray17
- 43 43 43 grey17
- 46 46 46 gray18
- 46 46 46 grey18
- 48 48 48 gray19
- 48 48 48 grey19
- 51 51 51 gray20
- 51 51 51 grey20
- 54 54 54 gray21
- 54 54 54 grey21
- 56 56 56 gray22
- 56 56 56 grey22
- 59 59 59 gray23
- 59 59 59 grey23
- 61 61 61 gray24
- 61 61 61 grey24
- 64 64 64 gray25
- 64 64 64 grey25
- 66 66 66 gray26
- 66 66 66 grey26
- 69 69 69 gray27
- 69 69 69 grey27
- 71 71 71 gray28
- 71 71 71 grey28
- 74 74 74 gray29
- 74 74 74 grey29
- 77 77 77 gray30
- 77 77 77 grey30
- 79 79 79 gray31
- 79 79 79 grey31
- 82 82 82 gray32
- 82 82 82 grey32
- 84 84 84 gray33
- 84 84 84 grey33
- 87 87 87 gray34
- 87 87 87 grey34
- 89 89 89 gray35
- 89 89 89 grey35
- 92 92 92 gray36
- 92 92 92 grey36
- 94 94 94 gray37
- 94 94 94 grey37
- 97 97 97 gray38
- 97 97 97 grey38
- 99 99 99 gray39
- 99 99 99 grey39
-102 102 102 gray40
-102 102 102 grey40
-105 105 105 gray41
-105 105 105 grey41
-107 107 107 gray42
-107 107 107 grey42
-110 110 110 gray43
-110 110 110 grey43
-112 112 112 gray44
-112 112 112 grey44
-115 115 115 gray45
-115 115 115 grey45
-117 117 117 gray46
-117 117 117 grey46
-120 120 120 gray47
-120 120 120 grey47
-122 122 122 gray48
-122 122 122 grey48
-125 125 125 gray49
-125 125 125 grey49
-127 127 127 gray50
-127 127 127 grey50
-130 130 130 gray51
-130 130 130 grey51
-133 133 133 gray52
-133 133 133 grey52
-135 135 135 gray53
-135 135 135 grey53
-138 138 138 gray54
-138 138 138 grey54
-140 140 140 gray55
-140 140 140 grey55
-143 143 143 gray56
-143 143 143 grey56
-145 145 145 gray57
-145 145 145 grey57
-148 148 148 gray58
-148 148 148 grey58
-150 150 150 gray59
-150 150 150 grey59
-153 153 153 gray60
-153 153 153 grey60
-156 156 156 gray61
-156 156 156 grey61
-158 158 158 gray62
-158 158 158 grey62
-161 161 161 gray63
-161 161 161 grey63
-163 163 163 gray64
-163 163 163 grey64
-166 166 166 gray65
-166 166 166 grey65
-168 168 168 gray66
-168 168 168 grey66
-171 171 171 gray67
-171 171 171 grey67
-173 173 173 gray68
-173 173 173 grey68
-176 176 176 gray69
-176 176 176 grey69
-179 179 179 gray70
-179 179 179 grey70
-181 181 181 gray71
-181 181 181 grey71
-184 184 184 gray72
-184 184 184 grey72
-186 186 186 gray73
-186 186 186 grey73
-189 189 189 gray74
-189 189 189 grey74
-191 191 191 gray75
-191 191 191 grey75
-194 194 194 gray76
-194 194 194 grey76
-196 196 196 gray77
-196 196 196 grey77
-199 199 199 gray78
-199 199 199 grey78
-201 201 201 gray79
-201 201 201 grey79
-204 204 204 gray80
-204 204 204 grey80
-207 207 207 gray81
-207 207 207 grey81
-209 209 209 gray82
-209 209 209 grey82
-212 212 212 gray83
-212 212 212 grey83
-214 214 214 gray84
-214 214 214 grey84
-217 217 217 gray85
-217 217 217 grey85
-219 219 219 gray86
-219 219 219 grey86
-222 222 222 gray87
-222 222 222 grey87
-224 224 224 gray88
-224 224 224 grey88
-227 227 227 gray89
-227 227 227 grey89
-229 229 229 gray90
-229 229 229 grey90
-232 232 232 gray91
-232 232 232 grey91
-235 235 235 gray92
-235 235 235 grey92
-237 237 237 gray93
-237 237 237 grey93
-240 240 240 gray94
-240 240 240 grey94
-242 242 242 gray95
-242 242 242 grey95
-245 245 245 gray96
-245 245 245 grey96
-247 247 247 gray97
-247 247 247 grey97
-250 250 250 gray98
-250 250 250 grey98
-252 252 252 gray99
-252 252 252 grey99
-255 255 255 gray100
-255 255 255 grey100
-169 169 169 dark grey
-169 169 169 DarkGrey
-169 169 169 dark gray
-169 169 169 DarkGray
-0 0 139 dark blue
-0 0 139 DarkBlue
-0 139 139 dark cyan
-0 139 139 DarkCyan
-139 0 139 dark magenta
-139 0 139 DarkMagenta
-139 0 0 dark red
-139 0 0 DarkRed
-144 238 144 light green
-144 238 144 LightGreen
diff --git a/Tools/pynche/X/xlicense.txt b/Tools/pynche/X/xlicense.txt
deleted file mode 100644
index b4471db..0000000
--- a/Tools/pynche/X/xlicense.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-X Window System License - X11R6.4
-
-Copyright (c) 1998 The Open Group
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-X Window System is a trademark of The Open Group
diff --git a/Tools/pynche/__init__.py b/Tools/pynche/__init__.py
deleted file mode 100644
index b93054b..0000000
--- a/Tools/pynche/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# Dummy file to make this directory a package.
diff --git a/Tools/pynche/html40colors.txt b/Tools/pynche/html40colors.txt
deleted file mode 100644
index 3eeb0a1..0000000
--- a/Tools/pynche/html40colors.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-# HTML 4.0 color names
-Black #000000
-Silver #c0c0c0
-Gray #808080
-White #ffffff
-Maroon #800000
-Red #ff0000
-Purple #800080
-Fuchsia #ff00ff
-Green #008000
-Lime #00ff00
-Olive #808000
-Yellow #ffff00
-Navy #000080
-Blue #0000ff
-Teal #008080
-Aqua #00ffff
diff --git a/Tools/pynche/namedcolors.txt b/Tools/pynche/namedcolors.txt
deleted file mode 100644
index 3658e85..0000000
--- a/Tools/pynche/namedcolors.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-# named colors from http://www.lightlink.com/xine/bells/namedcolors.html
-White #FFFFFF
-Red #FF0000
-Green #00FF00
-Blue #0000FF
-Magenta #FF00FF
-Cyan #00FFFF
-Yellow #FFFF00
-Black #000000
-Aquamarine #70DB93
-Baker's Chocolate #5C3317
-Blue Violet #9F5F9F
-Brass #B5A642
-Bright Gold #D9D919
-Brown #A62A2A
-Bronze #8C7853
-Bronze II #A67D3D
-Cadet Blue #5F9F9F
-Cool Copper #D98719
-Copper #B87333
-Coral #FF7F00
-Corn Flower Blue #42426F
-Dark Brown #5C4033
-Dark Green #2F4F2F
-Dark Green Copper #4A766E
-Dark Olive Green #4F4F2F
-Dark Orchid #9932CD
-Dark Purple #871F78
-Dark Slate Blue #6B238E
-Dark Slate Grey #2F4F4F
-Dark Tan #97694F
-Dark Turquoise #7093DB
-Dark Wood #855E42
-Dim Grey #545454
-Dusty Rose #856363
-Feldspar #D19275
-Firebrick #8E2323
-Forest Green #238E23
-Gold #CD7F32
-Goldenrod #DBDB70
-Grey #C0C0C0
-Green Copper #527F76
-Green Yellow #93DB70
-Hunter Green #215E21
-Indian Red #4E2F2F
-Khaki #9F9F5F
-Light Blue #C0D9D9
-Light Grey #A8A8A8
-Light Steel Blue #8F8FBD
-Light Wood #E9C2A6
-Lime Green #32CD32
-Mandarian Orange #E47833
-Maroon #8E236B
-Medium Aquamarine #32CD99
-Medium Blue #3232CD
-Medium Forest Green #6B8E23
-Medium Goldenrod #EAEAAE
-Medium Orchid #9370DB
-Medium Sea Green #426F42
-Medium Slate Blue #7F00FF
-Medium Spring Green #7FFF00
-Medium Turquoise #70DBDB
-Medium Violet Red #DB7093
-Medium Wood #A68064
-Midnight Blue #2F2F4F
-Navy Blue #23238E
-Neon Blue #4D4DFF
-Neon Pink #FF6EC7
-New Midnight Blue #00009C
-New Tan #EBC79E
-Old Gold #CFB53B
-Orange #FF7F00
-Orange Red #FF2400
-Orchid #DB70DB
-Pale Green #8FBC8F
-Pink #BC8F8F
-Plum #EAADEA
-Quartz #D9D9F3
-Rich Blue #5959AB
-Salmon #6F4242
-Scarlet #8C1717
-Sea Green #238E68
-Semi-Sweet Chocolate #6B4226
-Sienna #8E6B23
-Silver #E6E8FA
-Sky Blue #3299CC
-Slate Blue #007FFF
-Spicy Pink #FF1CAE
-Spring Green #00FF7F
-Steel Blue #236B8E
-Summer Sky #38B0DE
-Tan #DB9370
-Thistle #D8BFD8
-Turquoise #ADEAEA
-Very Dark Brown #5C4033
-Very Light Grey #CDCDCD
-Violet #4F2F4F
-Violet Red #CC3299
-Wheat #D8D8BF
-Yellow Green #99CC32
diff --git a/Tools/pynche/pyColorChooser.py b/Tools/pynche/pyColorChooser.py
deleted file mode 100644
index 3286047..0000000
--- a/Tools/pynche/pyColorChooser.py
+++ /dev/null
@@ -1,125 +0,0 @@
-"""Color chooser implementing (almost) the tkColorColor interface
-"""
-
-import os
-import Main
-import ColorDB
-
-
-
-class Chooser:
- """Ask for a color"""
- def __init__(self,
- master = None,
- databasefile = None,
- initfile = None,
- ignore = None,
- wantspec = None):
- self.__master = master
- self.__databasefile = databasefile
- self.__initfile = initfile or os.path.expanduser('~/.pynche')
- self.__ignore = ignore
- self.__pw = None
- self.__wantspec = wantspec
-
- def show(self, color, options):
- # scan for options that can override the ctor options
- self.__wantspec = options.get('wantspec', self.__wantspec)
- dbfile = options.get('databasefile', self.__databasefile)
- # load the database file
- colordb = None
- if dbfile != self.__databasefile:
- colordb = ColorDB.get_colordb(dbfile)
- if not self.__master:
- from tkinter import Tk
- self.__master = Tk()
- if not self.__pw:
- self.__pw, self.__sb = \
- Main.build(master = self.__master,
- initfile = self.__initfile,
- ignore = self.__ignore)
- else:
- self.__pw.deiconify()
- # convert color
- if colordb:
- self.__sb.set_colordb(colordb)
- else:
- colordb = self.__sb.colordb()
- if color:
- r, g, b = Main.initial_color(color, colordb)
- self.__sb.update_views(r, g, b)
- # reset the canceled flag and run it
- self.__sb.canceled(0)
- Main.run(self.__pw, self.__sb)
- rgbtuple = self.__sb.current_rgb()
- self.__pw.withdraw()
- # check to see if the cancel button was pushed
- if self.__sb.canceled_p():
- return None, None
- # Try to return the color name from the database if there is an exact
- # match, otherwise use the "#rrggbb" spec. BAW: Forget about color
- # aliases for now, maybe later we should return these too.
- name = None
- if not self.__wantspec:
- try:
- name = colordb.find_byrgb(rgbtuple)[0]
- except ColorDB.BadColor:
- pass
- if name is None:
- name = ColorDB.triplet_to_rrggbb(rgbtuple)
- return rgbtuple, name
-
- def save(self):
- if self.__sb:
- self.__sb.save_views()
-
-
-# convenience stuff
-_chooser = None
-
-def askcolor(color = None, **options):
- """Ask for a color"""
- global _chooser
- if not _chooser:
- _chooser = Chooser(**options)
- return _chooser.show(color, options)
-
-def save():
- global _chooser
- if _chooser:
- _chooser.save()
-
-
-# test stuff
-if __name__ == '__main__':
- from tkinter import *
-
- class Tester:
- def __init__(self):
- self.__root = tk = Tk()
- b = Button(tk, text='Choose Color...', command=self.__choose)
- b.pack()
- self.__l = Label(tk)
- self.__l.pack()
- q = Button(tk, text='Quit', command=self.__quit)
- q.pack()
-
- def __choose(self, event=None):
- rgb, name = askcolor(master=self.__root)
- if rgb is None:
- text = 'You hit CANCEL!'
- else:
- r, g, b = rgb
- text = 'You picked %s (%3d/%3d/%3d)' % (name, r, g, b)
- self.__l.configure(text=text)
-
- def __quit(self, event=None):
- self.__root.quit()
-
- def run(self):
- self.__root.mainloop()
- t = Tester()
- t.run()
- # simpler
-## print 'color:', askcolor()
-## print 'color:', askcolor()
diff --git a/Tools/pynche/pynche b/Tools/pynche/pynche
deleted file mode 100755
index 64bf703..0000000
--- a/Tools/pynche/pynche
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /usr/bin/env python
-
-"""Run this file under Unix, or when debugging under Windows.
-Run the file pynche.pyw under Windows to inhibit the console window.
-"""
-import Main
-Main.main()
diff --git a/Tools/pynche/pynche.pyw b/Tools/pynche/pynche.pyw
deleted file mode 100755
index 6dfc8fe..0000000
--- a/Tools/pynche/pynche.pyw
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /usr/bin/env python
-
-"""Run this file under Windows to inhibit the console window.
-Run the file pynche.py under Unix or when debugging under Windows.
-"""
-import Main
-Main.main()
diff --git a/Tools/pynche/webcolors.txt b/Tools/pynche/webcolors.txt
deleted file mode 100644
index f645c1e..0000000
--- a/Tools/pynche/webcolors.txt
+++ /dev/null
@@ -1,141 +0,0 @@
-# De-facto NS & MSIE recognized HTML color names
-AliceBlue #f0f8ff
-AntiqueWhite #faebd7
-Aqua #00ffff
-Aquamarine #7fffd4
-Azure #f0ffff
-Beige #f5f5dc
-Bisque #ffe4c4
-Black #000000
-BlanchedAlmond #ffebcd
-Blue #0000ff
-BlueViolet #8a2be2
-Brown #a52a2a
-BurlyWood #deb887
-CadetBlue #5f9ea0
-Chartreuse #7fff00
-Chocolate #d2691e
-Coral #ff7f50
-CornflowerBlue #6495ed
-Cornsilk #fff8dc
-Crimson #dc143c
-Cyan #00ffff
-DarkBlue #00008b
-DarkCyan #008b8b
-DarkGoldenrod #b8860b
-DarkGray #a9a9a9
-DarkGreen #006400
-DarkKhaki #bdb76b
-DarkMagenta #8b008b
-DarkOliveGreen #556b2f
-DarkOrange #ff8c00
-DarkOrchid #9932cc
-DarkRed #8b0000
-DarkSalmon #e9967a
-DarkSeaGreen #8fbc8f
-DarkSlateBlue #483d8b
-DarkSlateGray #2f4f4f
-DarkTurquoise #00ced1
-DarkViolet #9400d3
-DeepPink #ff1493
-DeepSkyBlue #00bfff
-DimGray #696969
-DodgerBlue #1e90ff
-FireBrick #b22222
-FloralWhite #fffaf0
-ForestGreen #228b22
-Fuchsia #ff00ff
-Gainsboro #dcdcdc
-GhostWhite #f8f8ff
-Gold #ffd700
-Goldenrod #daa520
-Gray #808080
-Green #008000
-GreenYellow #adff2f
-Honeydew #f0fff0
-HotPink #ff69b4
-IndianRed #cd5c5c
-Indigo #4b0082
-Ivory #fffff0
-Khaki #f0e68c
-Lavender #e6e6fa
-LavenderBlush #fff0f5
-LawnGreen #7cfc00
-LemonChiffon #fffacd
-LightBlue #add8e6
-LightCoral #f08080
-LightCyan #e0ffff
-LightGoldenrodYellow #fafad2
-LightGreen #90ee90
-LightGrey #d3d3d3
-LightPink #ffb6c1
-LightSalmon #ffa07a
-LightSeaGreen #20b2aa
-LightSkyBlue #87cefa
-LightSlateGray #778899
-LightSteelBlue #b0c4de
-LightYellow #ffffe0
-Lime #00ff00
-LimeGreen #32cd32
-Linen #faf0e6
-Magenta #ff00ff
-Maroon #800000
-MediumAquamarine #66cdaa
-MediumBlue #0000cd
-MediumOrchid #ba55d3
-MediumPurple #9370db
-MediumSeaGreen #3cb371
-MediumSlateBlue #7b68ee
-MediumSpringGreen #00fa9a
-MediumTurquoise #48d1cc
-MediumVioletRed #c71585
-MidnightBlue #191970
-MintCream #f5fffa
-MistyRose #ffe4e1
-Moccasin #ffe4b5
-NavajoWhite #ffdead
-Navy #000080
-OldLace #fdf5e6
-Olive #808000
-OliveDrab #6b8e23
-Orange #ffa500
-OrangeRed #ff4500
-Orchid #da70d6
-PaleGoldenrod #eee8aa
-PaleGreen #98fb98
-PaleTurquoise #afeeee
-PaleVioletRed #db7093
-PapayaWhip #ffefd5
-PeachPuff #ffdab9
-Peru #cd853f
-Pink #ffc0cb
-Plum #dda0dd
-PowderBlue #b0e0e6
-Purple #800080
-Red #ff0000
-RosyBrown #bc8f8f
-RoyalBlue #4169e1
-SaddleBrown #8b4513
-Salmon #fa8072
-SandyBrown #f4a460
-SeaGreen #2e8b57
-Seashell #fff5ee
-Sienna #a0522d
-Silver #c0c0c0
-SkyBlue #87ceeb
-SlateBlue #6a5acd
-SlateGray #708090
-Snow #fffafa
-SpringGreen #00ff7f
-SteelBlue #4682b4
-Tan #d2b48c
-Teal #008080
-Thistle #d8bfd8
-Tomato #ff6347
-Turquoise #40e0d0
-Violet #ee82ee
-Wheat #f5deb3
-White #ffffff
-WhiteSmoke #f5f5f5
-Yellow #ffff00
-YellowGreen #9acd32
diff --git a/Tools/pynche/websafe.txt b/Tools/pynche/websafe.txt
deleted file mode 100644
index 70ed51e..0000000
--- a/Tools/pynche/websafe.txt
+++ /dev/null
@@ -1,217 +0,0 @@
-# Websafe RGB values
-#000000
-#000033
-#000066
-#000099
-#0000cc
-#0000ff
-#003300
-#003333
-#003366
-#003399
-#0033cc
-#0033ff
-#006600
-#006633
-#006666
-#006699
-#0066cc
-#0066ff
-#009900
-#009933
-#009966
-#009999
-#0099cc
-#0099ff
-#00cc00
-#00cc33
-#00cc66
-#00cc99
-#00cccc
-#00ccff
-#00ff00
-#00ff33
-#00ff66
-#00ff99
-#00ffcc
-#00ffff
-#330000
-#330033
-#330066
-#330099
-#3300cc
-#3300ff
-#333300
-#333333
-#333366
-#333399
-#3333cc
-#3333ff
-#336600
-#336633
-#336666
-#336699
-#3366cc
-#3366ff
-#339900
-#339933
-#339966
-#339999
-#3399cc
-#3399ff
-#33cc00
-#33cc33
-#33cc66
-#33cc99
-#33cccc
-#33ccff
-#33ff00
-#33ff33
-#33ff66
-#33ff99
-#33ffcc
-#33ffff
-#660000
-#660033
-#660066
-#660099
-#6600cc
-#6600ff
-#663300
-#663333
-#663366
-#663399
-#6633cc
-#6633ff
-#666600
-#666633
-#666666
-#666699
-#6666cc
-#6666ff
-#669900
-#669933
-#669966
-#669999
-#6699cc
-#6699ff
-#66cc00
-#66cc33
-#66cc66
-#66cc99
-#66cccc
-#66ccff
-#66ff00
-#66ff33
-#66ff66
-#66ff99
-#66ffcc
-#66ffff
-#990000
-#990033
-#990066
-#990099
-#9900cc
-#9900ff
-#993300
-#993333
-#993366
-#993399
-#9933cc
-#9933ff
-#996600
-#996633
-#996666
-#996699
-#9966cc
-#9966ff
-#999900
-#999933
-#999966
-#999999
-#9999cc
-#9999ff
-#99cc00
-#99cc33
-#99cc66
-#99cc99
-#99cccc
-#99ccff
-#99ff00
-#99ff33
-#99ff66
-#99ff99
-#99ffcc
-#99ffff
-#cc0000
-#cc0033
-#cc0066
-#cc0099
-#cc00cc
-#cc00ff
-#cc3300
-#cc3333
-#cc3366
-#cc3399
-#cc33cc
-#cc33ff
-#cc6600
-#cc6633
-#cc6666
-#cc6699
-#cc66cc
-#cc66ff
-#cc9900
-#cc9933
-#cc9966
-#cc9999
-#cc99cc
-#cc99ff
-#cccc00
-#cccc33
-#cccc66
-#cccc99
-#cccccc
-#ccccff
-#ccff00
-#ccff33
-#ccff66
-#ccff99
-#ccffcc
-#ccffff
-#ff0000
-#ff0033
-#ff0066
-#ff0099
-#ff00cc
-#ff00ff
-#ff3300
-#ff3333
-#ff3366
-#ff3399
-#ff33cc
-#ff33ff
-#ff6600
-#ff6633
-#ff6666
-#ff6699
-#ff66cc
-#ff66ff
-#ff9900
-#ff9933
-#ff9966
-#ff9999
-#ff99cc
-#ff99ff
-#ffcc00
-#ffcc33
-#ffcc66
-#ffcc99
-#ffcccc
-#ffccff
-#ffff00
-#ffff33
-#ffff66
-#ffff99
-#ffffcc
-#ffffff