pmacs3/color.py

143 lines
3.9 KiB
Python
Raw Normal View History

2007-03-06 10:05:38 -05:00
import curses
colors = {}
_colors = []
_pairs = {}
index = 1
attributes = {
'bold': curses.A_BOLD,
'reverse': curses.A_REVERSE,
'normal': curses.A_NORMAL,
'underline': curses.A_UNDERLINE,
'dim': curses.A_DIM,
'standout': curses.A_STANDOUT,
}
2007-03-06 10:05:38 -05:00
inited = False
default_color = True
ascii_map = {
'*': 'bold',
}
rev_ascii_map = {
'bold': '*',
}
2007-03-06 10:05:38 -05:00
def add_color(name, value, abbrev):
colors[name] = value
ascii_map[abbrev] = name
rev_ascii_map[name] = abbrev
2007-03-06 10:05:38 -05:00
def iter256():
for r in range(0, 6):
for g in range(0, 6):
for b in range(0, 6):
if r >= g and g > b: name = 'yellow'
elif r >= b and b - g > 1: name = 'magenta'
elif b >= g and g - r > 2: name = 'cyan'
elif b >= r and r > g: name = 'magenta'
elif g >= r and r - b > 2: name = 'yellow'
elif g >= b and b - r > 1: name = 'cyan'
elif r > b and r > g: name = 'red'
elif g > b and g > r: name = 'green'
elif b > r and b > g: name = 'blue'
else: continue
yield (name, r, g, b)
raise StopIteration
def color256(name, fallback, abbrev, r, g, b):
name2 = '%s%d%d%d' % (name, r, g, b)
abbrev2 = '%s%d%d%d' % (abbrev, r, g, b)
if curses.COLORS == 256:
value = 16 + r * 36 + g * 6 + b
if curses.can_change_color():
try:
curses.init_color(value, r * 200, g * 200, b* 200)
except:
raise Exception("arghh: %d, %d, %d, %d", value, r * 200, g * 200, b * 200)
2007-03-06 10:05:38 -05:00
else:
value = fallback
add_color(name2, value, abbrev2)
2007-03-06 10:05:38 -05:00
# PUBLIC METHODS
def init():
global _pairs, inited
if inited:
return
2007-03-06 10:05:38 -05:00
add_color('cyan', curses.COLOR_CYAN, 'c')
add_color('blue', curses.COLOR_BLUE, 'b')
add_color('green', curses.COLOR_GREEN, 'g')
add_color('red', curses.COLOR_RED, 'r')
add_color('yellow', curses.COLOR_YELLOW, 'y')
add_color('magenta', curses.COLOR_MAGENTA, 'm')
add_color('black', curses.COLOR_BLACK, 'B')
add_color('white', curses.COLOR_WHITE, 'w')
if default_color:
colors['default'] = -1
ascii_map['d'] = 'default'
rev_ascii_map['default'] = 'd'
inited = True
for i in range(0, 256):
name = 'f%02x' % i
abbrev = 'f%02x' % i
add_color(name, i, abbrev)
# GREY
for i in range(0, 24):
name2 = 'grey%d' % i
abbrev2 = 'G%d' % i
if curses.COLORS == 256:
value = 232 + i
if curses.can_change_color():
try:
curses.init_color(value, i * 41, i * 41, i * 41)
except:
raise Exception("arghh: %d, %d, %d, %d", value, i * 41, i * 41, i * 41)
else:
value = curses.COLOR_WHITE
add_color(name2, value, abbrev2)
2007-03-06 10:05:38 -05:00
for name, r, g, b in iter256():
color256(name, colors[name], rev_ascii_map[name], r, g, b)
def build(fg, bg, *attr):
v = curses.A_NORMAL | pairs(fg, bg)
2007-03-06 10:05:38 -05:00
for x in attr:
if type(x) == type(''):
x = attributes[x]
v = v | x
return v
return build_attr(cattr, *attr)
# PRIVATE METHODS
def pairs(fg, bg):
if not curses.has_colors():
return curses.color_pair(0)
global index
fgi = colors.get(fg, colors['white'])
bgi = colors.get(bg, colors['black'])
key = (fgi, bgi)
if key not in _pairs:
assert index < curses.COLOR_PAIRS, "too many colors"
assert type(fgi) == type(0), "illegal fgi: %r" % fgi
assert type(bgi) == type(0), "illegal bgi: %r" % bgi
try:
curses.init_pair(index, fgi, bgi)
except:
raise Exception('failed to init %d,%d,%d' % (index, fgi, bgi))
_pairs[key] = curses.color_pair(index)
_colors.append(key)
index = len(_colors) + 1
return _pairs[key]