#!/usr/bin/env python3 """ simple-gtk xpm generator Copyright (C) 2012 Felipe A. Hernandez <spayder26@gmail.com> Portions adapted by Cedric Leporcq. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ import shutil from dataclasses import dataclass from os import linesep from pathlib import Path from xpm2png import xpm2png @dataclass class IconMap: data: str colors: dict def generate(name: str, icon: IconMap, x0=0, y0=0, w=None, h=None): """ Creates xpm file with given name, given draw as string, colors as dict. Extra args are for generate parts of xpm. """ icon_lines = icon.data.split("\n") if w is None: w = len(icon_lines[0]) if h is None: h = len(icon_lines) x1 = x0 + w y1 = y0 + h colors = {} lines = [line[x0:x1] for line in icon_lines[y0:y1]] for line in lines: for c in line: if c not in colors: colors[c] = icon.colors[c] xpmlines = [ "/* XPM */", f'static char * {name.replace("-", "_")} = {{', f'"{w} {h} {len(colors)} 1", ' ] xpmlines.extend(f'"{i[0]}\tc {i[1]}", ' for i in list(colors.items())) xpmlines.extend(f'"{i}", ' for i in lines) xpmlines.append("};") with open(f"{name}.xpm", "w") as f: f.write(linesep.join(xpmlines)) def hole_pos(txt): """ Detects a hole on a xpm string, used to find border sizes.""" lines = txt.split("\n") for i, line in enumerate(lines): if " " in line: return line.find(" "), i raise ValueError def hole_size(txt): """ Detects hole on a xpm string, used to find border sizes.""" lastwidth = 0 inhole = 0 for line in txt.split("\n"): if " " in line: lastwidth = line.count(" ") inhole += 1 elif inhole > 0: return lastwidth, inhole raise ValueError def build_xfwm4(icons: dict, active: IconMap, inactive: IconMap): for name, icon in icons.items(): generate(name, icon) alines = active.data.split("\n") ilines = inactive.data.split("\n") alw, alh = (len(alines[0]), len(alines)) ilw, ilh = (len(ilines[0]), len(ilines)) ''' Find corner length on a xpm string.''' acw = len(active.data.split("+")[0]) icw = len(inactive.data.split("+")[0]) ahx, ahy = hole_pos(active.data) ihx, ihy = hole_pos(inactive.data) ahw, ahh = hole_size(active.data) ihw, ihh = hole_size(inactive.data) abw, abh = (alw - ahx - ahw, alh - ahy - ahh) ibw, ibh = (ilw - ihx - ihw, ilh - ihy - ihh) # top-left generate("top-left-active", active, 0, 0, acw, ahy) generate("top-left-inactive", inactive, 0, 0, icw, ihy) # left generate("left-active", active, 0, ahy, ahx, ahh) generate("left-inactive", inactive, 0, ihy, ihx, ihh) # bottom-left generate("bottom-left-active", active, 0, ahy + ahh, ahx, abh) generate("bottom-left-inactive", inactive, 0, ihy + ihh, ihx, ibh) # top-right generate("top-right-active", active, alw - acw, 0, acw, ahy) generate("top-right-inactive", inactive, ilw - icw, 0, icw, ihy) # right generate("right-active", active, ahx + ahw, ahy, abw, ahh) generate("right-inactive", inactive, ihx + ihw, ihy, ibw, ihh) # bottom-right generate("bottom-right-active", active, ahx + ahw, ahy + ahh, abw, abh) generate("bottom-right-inactive", inactive, ihx + ihw, ihy + ihh, ibw, ibh) # top for i in range(1, 6): generate(f"title-{i}-active", active, acw, 0, alw - 2 * acw, ahy) generate(f"title-{i}-inactive", inactive, icw, 0, alw - 2 * icw, ihy) # bottom generate("bottom-active", active, ahx, ahy + ahh, ahw, ibh) generate("bottom-inactive", inactive, ihx, ihy + ihh, ihw, ibh) def build_unity(icons: dict): for name, icon in icons.items(): generate(name, icon) xpm2png(Path(f"{name}.xpm"), Path(f"{name}.png")) for i in ("close", "maximize", "minimize", "menu", "unmaximize"): try: shutil.copy2(f"{i}_focused_normal.png", f"{i}.png") except FileNotFoundError as e: print(f"Can't copy {i}_focused_normal.png to {i}.png: {e.strerror} '{e.filename}'" )