mirror of
https://github.com/gryf/wmdocklib.git
synced 2025-12-19 04:20:17 +01:00
Make pixmap merge inside a base class.
Also suport fonts being taken from a string rather, than from file only.
This commit is contained in:
@@ -58,18 +58,132 @@ class DockApp:
|
||||
pywmgeneral.open_xwindow(len(sys.argv), sys.argv, self.width,
|
||||
self.height)
|
||||
|
||||
def prepare_pixmaps(self, background=None, patterns=None, style='3d',
|
||||
margin=3):
|
||||
def prepare_pixmaps(self):
|
||||
"""builds and sets the pixmap of the program.
|
||||
|
||||
dockapp_size = (self.width, self.height)
|
||||
the (width)x(height) upper left area is the work area in which we put
|
||||
what we want to be displayed.
|
||||
|
||||
(self.char_width, self.char_height, self.charset_start,
|
||||
self.charset_width) = helpers.init_pixmap(background, patterns,
|
||||
style, dockapp_size[0],
|
||||
dockapp_size[1], margin,
|
||||
self.font,
|
||||
self.background_color,
|
||||
self.palette)
|
||||
the remaining upper right area contains patterns that can be used for
|
||||
blanking/resetting portions of the displayed area.
|
||||
|
||||
the remaining lower area defines the character set. this is initialized
|
||||
using the corresponding named character set. a file with this name must
|
||||
be found somewhere in the path.
|
||||
|
||||
palette is a dictionary
|
||||
1: of integers <- [0..15] to colors.
|
||||
2: of single chars to colors.
|
||||
|
||||
a default palette is provided, and can be silently overwritten with the
|
||||
one passed as parameter.
|
||||
|
||||
The XBM mask is created out of the XPM.
|
||||
"""
|
||||
palette = {}
|
||||
patterns = self.patterns
|
||||
font_width = 0
|
||||
font_height = 0
|
||||
|
||||
if self.font:
|
||||
# Read provided xpm file with font definition
|
||||
palette, fontdef = helpers.read_xpm(self.font)
|
||||
font_width = self.charset_width = len(fontdef[0])
|
||||
font_height = len(fontdef)
|
||||
|
||||
if self.font_dimentions is None:
|
||||
(self.char_width,
|
||||
self.char_height) = helpers.get_font_char_size(self.font)
|
||||
else:
|
||||
self.char_width, self.char_height = self.font_dimentions
|
||||
|
||||
if self.char_width is None:
|
||||
# font filename doesn't provide hints regarding font size
|
||||
raise ValueError('Cannot infer font size either from font '
|
||||
'name (does not contain wxh), or from '
|
||||
'font_dimentions attribute')
|
||||
else:
|
||||
palette[' '] = 'None'
|
||||
|
||||
palette_values = {v: k for k, v in palette.items()}
|
||||
|
||||
# merge defined palette colors to existing one
|
||||
if self.palette:
|
||||
for key, color in self.palette.items():
|
||||
color = helpers.normalize_color(color)
|
||||
if color in palette_values:
|
||||
continue
|
||||
if key not in palette:
|
||||
palette[key] = color
|
||||
else:
|
||||
new_key = helpers.get_unique_key(palette)
|
||||
palette[new_key] = color
|
||||
|
||||
palette_values = {v: k for k, v in palette.items()}
|
||||
|
||||
bevel = helpers.get_unique_key(palette)
|
||||
palette[bevel] = self.bevel_color
|
||||
|
||||
# handle bg color
|
||||
bg = helpers.normalize_color(self.background_color)
|
||||
key = helpers.get_unique_key(palette)
|
||||
palette[key] = bg
|
||||
bg = key
|
||||
|
||||
if patterns is None:
|
||||
patterns = [bg * self.width] * self.height
|
||||
|
||||
if self.style == '3d':
|
||||
ex = bevel
|
||||
else:
|
||||
ex = bg
|
||||
|
||||
if self.background is None:
|
||||
self.background = (
|
||||
[' ' * self.width for item in range(self.margin)] +
|
||||
[' ' * self.margin + bg * (self.width - 2 * self.margin - 1) +
|
||||
ex + ' ' * (self.margin)
|
||||
for item in range(self.margin,
|
||||
self.height - self.margin - 1)] +
|
||||
[' ' * self.margin + ex * (self.width - 2 * self.margin) +
|
||||
' ' * (self.margin)] +
|
||||
[' ' * self.width for item in range(self.margin)])
|
||||
|
||||
elif isinstance(self.background,
|
||||
list) and not isinstance(self.background[0], str):
|
||||
nbackground = [[' '] * self.width for i in range(self.height)]
|
||||
for ((left, top), (right, bottom)) in self.background:
|
||||
for x in range(left, right+1):
|
||||
for y in range(top, bottom):
|
||||
if x < right:
|
||||
nbackground[y][x] = bg
|
||||
else:
|
||||
nbackground[y][x] = ex
|
||||
nbackground[bottom][x] = ex
|
||||
self.background = [''.join(item) for item in nbackground]
|
||||
|
||||
self.charset_start = self.height + len(patterns)
|
||||
|
||||
xpmwidth = max(len(self.background[0]), len(patterns[0]), font_width)
|
||||
xpmheight = len(self.background) + len(patterns) + font_height
|
||||
|
||||
xpm = ([f'{xpmwidth} {xpmheight} {len(palette)} 1'] +
|
||||
[f'{k}\tc {v}'
|
||||
for k, v in list(palette.items()) if v == 'None'] +
|
||||
[f'{k}\tc {v}'
|
||||
for k, v in list(palette.items()) if v != 'None'] +
|
||||
[item + ' ' * (xpmwidth - len(item))
|
||||
for item in self.background + patterns])
|
||||
if self.font:
|
||||
xpm += [line + ' ' * (xpmwidth - len(line)) for line in fontdef]
|
||||
|
||||
with open('/tmp/foo.xpm', 'w') as fobj:
|
||||
fobj.write('/* XPM */\nstatic char *_x_[] = {\n')
|
||||
for item in xpm:
|
||||
fobj.write(f'"{item}"\n')
|
||||
fobj.write('};\n')
|
||||
|
||||
pywmgeneral.include_pixmap(xpm)
|
||||
|
||||
def redraw(self):
|
||||
pywmgeneral.redraw_window()
|
||||
|
||||
@@ -118,8 +118,8 @@ def get_vertical_spacing(num_lines, margin, height, y_offset):
|
||||
return h / (num_lines - 1)
|
||||
|
||||
|
||||
def read_xpm(filename):
|
||||
"""Read the xpm in filename.
|
||||
def read_xpm(obj):
|
||||
"""Read the xpm in filename or treat object as a string with XPM data.
|
||||
|
||||
Return the pair (palette, pixels).
|
||||
|
||||
@@ -129,8 +129,11 @@ def read_xpm(filename):
|
||||
Raise IOError if we run into trouble when trying to read the file. This
|
||||
function has not been tested extensively. do not try to use more than
|
||||
"""
|
||||
with open(filename, 'r') as fobj:
|
||||
lines = fobj.read().split('\n')
|
||||
if obj.startswith('/* XPM */'):
|
||||
lines = [line for line in obj.split('\n')]
|
||||
else:
|
||||
with open(obj, 'r') as fobj:
|
||||
lines = fobj.read().split('\n')
|
||||
|
||||
string = ''.join(lines)
|
||||
data = []
|
||||
@@ -157,132 +160,6 @@ def read_xpm(filename):
|
||||
return palette, data
|
||||
|
||||
|
||||
def init_pixmap(background=None, patterns=None, style='3d', width=64,
|
||||
height=64, margin=3, font_name=None, bg="black", palette=None):
|
||||
"""builds and sets the pixmap of the program.
|
||||
|
||||
the (width)x(height) upper left area is the work area in which we put
|
||||
what we want to be displayed.
|
||||
|
||||
the remaining upper right area contains patterns that can be used for
|
||||
blanking/resetting portions of the displayed area.
|
||||
|
||||
the remaining lower area defines the character set. this is initialized
|
||||
using the corresponding named character set. a file with this name must
|
||||
be found somewhere in the path.
|
||||
|
||||
palette is a dictionary
|
||||
1: of integers <- [0..15] to colors.
|
||||
2: of single chars to colors.
|
||||
|
||||
a default palette is provided, and can be silently overwritten with the
|
||||
one passed as parameter.
|
||||
|
||||
The XBM mask is created out of the XPM.
|
||||
"""
|
||||
|
||||
def get_unique_key(dict_to_check):
|
||||
for char in range(40, 126):
|
||||
char = chr(char)
|
||||
if char not in dict_to_check:
|
||||
return char
|
||||
|
||||
def normalize_color(color):
|
||||
if color.startswith('#'):
|
||||
return color
|
||||
else:
|
||||
return get_color_code(color)
|
||||
|
||||
# Read provided xpm file with font definition
|
||||
global char_width, char_height
|
||||
|
||||
char_width, char_height, fontdef, font_palette = read_font(font_name)
|
||||
palette_values = {v: k for k, v in font_palette.items()}
|
||||
|
||||
if not palette:
|
||||
palette = font_palette
|
||||
else:
|
||||
# make sure we don't overwrite font colors
|
||||
for key, color in palette.items():
|
||||
color = normalize_color(color)
|
||||
if color in palette_values:
|
||||
continue
|
||||
if key not in font_palette:
|
||||
font_palette[key] = color
|
||||
else:
|
||||
new_key = get_unique_key(font_palette)
|
||||
font_palette[new_key] = color
|
||||
|
||||
palette_values = {v: k for k, v in font_palette.items()}
|
||||
palette = font_palette
|
||||
|
||||
bevel = get_unique_key('#bebebe')
|
||||
palette[bevel] = '#bebebe'
|
||||
|
||||
# handle bg color
|
||||
bg = normalize_color(bg)
|
||||
key = get_unique_key(palette)
|
||||
palette[key] = bg
|
||||
bg = key
|
||||
|
||||
if patterns is None:
|
||||
patterns = [bg * width] * height
|
||||
|
||||
if style == '3d':
|
||||
ex = bevel
|
||||
else:
|
||||
ex = bg
|
||||
|
||||
if background is None:
|
||||
background = [' ' * width for item in range(margin)] + \
|
||||
[' ' * margin +
|
||||
bg * (width - 2 * margin - 1) +
|
||||
ex + ' ' * (margin)
|
||||
for item in range(margin, height-margin-1)] + \
|
||||
[' ' * margin + ex * (width - 2 * margin) + ' ' * (margin)] + \
|
||||
[' ' * width for item in range(margin)]
|
||||
|
||||
elif isinstance(background, list) and not isinstance(background[0], str):
|
||||
nbackground = [[' ']*width for i in range(height)]
|
||||
for ((left, top), (right, bottom)) in background:
|
||||
for x in range(left, right+1):
|
||||
for y in range(top, bottom):
|
||||
if x < right:
|
||||
nbackground[y][x] = bg
|
||||
else:
|
||||
nbackground[y][x] = ex
|
||||
nbackground[bottom][x] = ex
|
||||
background = [''.join(item) for item in nbackground]
|
||||
|
||||
global charset_start, charset_width
|
||||
charset_start = height + len(patterns)
|
||||
charset_width = len(fontdef[0])
|
||||
|
||||
xpmwidth = max(len(background[0]), len(patterns[0]), len(fontdef[0]))
|
||||
xpmheight = len(background) + len(patterns) + len(fontdef)
|
||||
|
||||
xpm = [
|
||||
'%s %s %d 1' % (xpmwidth, xpmheight, len(palette)),
|
||||
] + [
|
||||
'%s\tc %s' % (k, v)
|
||||
for k,v in list(palette.items())
|
||||
if v == 'None'
|
||||
] + [
|
||||
'%s\tc %s' % (k,v)
|
||||
for k,v in list(palette.items())
|
||||
if v != 'None'
|
||||
] + [
|
||||
item+' '*(xpmwidth-len(item))
|
||||
for item in background + patterns
|
||||
] + [
|
||||
line + ' '*(xpmwidth-len(line))
|
||||
for line in fontdef
|
||||
]
|
||||
|
||||
pywmgeneral.include_pixmap(xpm)
|
||||
return char_width, char_height, charset_start, charset_width
|
||||
|
||||
|
||||
def redraw_xy(x, y):
|
||||
"""Redraw a given region of the window."""
|
||||
pywmgeneral.redraw_window_xy(x, y)
|
||||
@@ -365,3 +242,17 @@ def get_color_code(color_name, rgb_fname=None):
|
||||
|
||||
return f'#{r:02x}{g:02x}{b:02x}'
|
||||
return None
|
||||
|
||||
|
||||
def get_unique_key(dict_to_check):
|
||||
for char in range(40, 126):
|
||||
char = chr(char)
|
||||
if char not in dict_to_check:
|
||||
return char
|
||||
|
||||
|
||||
def normalize_color(color):
|
||||
if color.startswith('#'):
|
||||
return color
|
||||
else:
|
||||
return get_color_code(color)
|
||||
|
||||
Reference in New Issue
Block a user