2022-01-27 01:26:47 +08:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
"""
|
|
|
|
generate-icon-makefiles.py -- Generate icons/(Color|Symbolic)/icon-list.mk
|
|
|
|
Copyright (C) 2022 Jehan
|
|
|
|
|
|
|
|
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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
Usage: generate-icon-makefiles.py
|
|
|
|
"""
|
|
|
|
|
|
|
|
import os.path
|
|
|
|
|
|
|
|
tools_dir = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
icons_dir = os.path.join(tools_dir, '../icons')
|
|
|
|
|
|
|
|
list_dir = os.path.join(icons_dir, 'icon-lists')
|
|
|
|
|
|
|
|
color_mk = os.path.join(icons_dir, 'Color', 'icon-list.mk')
|
|
|
|
symbolic_mk = os.path.join(icons_dir, 'Symbolic', 'icon-list.mk')
|
|
|
|
|
|
|
|
def print_icons(indir, filenames, max_len, prefix, suffix, outfile, endlist=True):
|
|
|
|
icons = []
|
|
|
|
for filename in filenames:
|
|
|
|
icon_list = os.path.join(indir, filename)
|
|
|
|
with open(icon_list, mode='r') as f:
|
|
|
|
icons += [line.strip() for line in f]
|
icons, tools: start grouping icons by their usage.
There are some clear and obvious groups in the icons. For instance, the
Preferences icons are one of them. Looking up the code, we only use them
in 16px (in Preferences side menu) and 48px (in Preferences page
headers). Until now, we were storing in other unrelated size (22px) and
also the lists per-sizes were not consistent. Some icons were missing
here, other there.
With this new organization, the Preferences icons are listed in a single
file, ensuring usage and contents consistency. Also it allows to install
them only for the needed sizes (note that it is possible that they might
be needed in different size, for instance with custom themes; but we
can't just randomly distribute icons in all sizes; or to be more
accurate, this is exactly why we encourage rather the SVG/scalable
icons, so if some people explicitly go for raster icons, they also get
the drawbacks which come with).
Last note: it may be possible that some icons end up in different
"semantic" icon group. This is not a problem with this new organization
as my scripts handle duplicates gracefully.
2022-01-29 07:21:40 +08:00
|
|
|
# Replace comment lines with empty strings.
|
|
|
|
prev_blank = False
|
|
|
|
pop_list = []
|
|
|
|
for i, icon in enumerate(icons):
|
|
|
|
if icon != '' and icon[0] == '#':
|
|
|
|
icons[i] = ''
|
|
|
|
if icons[i] == '':
|
|
|
|
if prev_blank:
|
|
|
|
pop_list += [i]
|
|
|
|
prev_blank = True
|
|
|
|
else:
|
|
|
|
prev_blank = False
|
|
|
|
if icons[i] in icons[:i]:
|
|
|
|
pop_list += [i]
|
|
|
|
pop_list.reverse()
|
|
|
|
for i in pop_list:
|
|
|
|
# Remove successive blanks and duplicate icons.
|
|
|
|
icons.pop(i)
|
2022-01-27 23:18:55 +08:00
|
|
|
# Strip empty lines in extremities.
|
|
|
|
while icons[-1] == '':
|
|
|
|
icons.pop()
|
|
|
|
while icons[0] == '':
|
|
|
|
icons.pop(0)
|
2022-01-27 01:26:47 +08:00
|
|
|
|
|
|
|
if max_len is None:
|
|
|
|
max_len = len(max(icons, key=len)) + len(prefix + suffix)
|
|
|
|
|
2022-01-27 23:18:55 +08:00
|
|
|
prev_empty = False
|
|
|
|
|
2022-01-27 01:26:47 +08:00
|
|
|
# Using tabs, displayed as 8 chars in our coding style. Computing
|
|
|
|
# needed tabs for proper alignment.
|
|
|
|
needed_tabs = int(max_len / 8) + (1 if max_len % 8 != 0 else 0)
|
|
|
|
for icon in icons[:-1]:
|
2022-01-27 23:18:55 +08:00
|
|
|
if icon == '':
|
|
|
|
# Only keep one empty line.
|
|
|
|
if not prev_empty:
|
|
|
|
print("\t\\", file=outfile)
|
|
|
|
prev_empty = True
|
|
|
|
else:
|
|
|
|
icon_path = prefix + icon + suffix
|
|
|
|
tab_mult = needed_tabs - int(len(icon_path) / 8) + 1
|
|
|
|
icon_path = "\t{}{}\\".format(icon_path, "\t" * tab_mult)
|
|
|
|
print(icon_path, file=outfile)
|
|
|
|
prev_empty = False
|
2022-01-27 01:26:47 +08:00
|
|
|
else:
|
|
|
|
if endlist:
|
|
|
|
icon_path = "\t{}".format(prefix) + icons[-1] + suffix
|
|
|
|
print(icon_path, file=outfile)
|
|
|
|
else:
|
|
|
|
icon_path = prefix + icons[-1] + suffix
|
|
|
|
tab_mult = needed_tabs - int(len(icon_path) / 8) + 1
|
|
|
|
icon_path = "\t{}{}\\".format(icon_path, "\t" * tab_mult)
|
|
|
|
print(icon_path, file=outfile)
|
|
|
|
|
|
|
|
return max_len
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
|
|
with open(color_mk, mode='w') as colorf, open(symbolic_mk, mode='w') as symbolicf:
|
2022-01-27 07:59:05 +08:00
|
|
|
top_comment = '''
|
|
|
|
## --------------------------------------------------------------
|
|
|
|
## This file is autogenerated by tools/generate-icon-makefiles.py
|
|
|
|
## --------------------------------------------------------------
|
|
|
|
|
|
|
|
## Modify this script or files inside icons/icon-lists/ instead of this one.
|
|
|
|
## Then run tools/generate-icon-makefiles.py again.
|
|
|
|
'''
|
|
|
|
print(top_comment, file=colorf)
|
|
|
|
print(top_comment, file=symbolicf)
|
|
|
|
|
2022-01-27 01:26:47 +08:00
|
|
|
# Scalable icons.
|
|
|
|
print("scalable_images = \\", file=colorf)
|
|
|
|
print("scalable_images = \\", file=symbolicf)
|
|
|
|
|
|
|
|
# Let's assume that scalable icons are the biggest list since it
|
|
|
|
# should contain nearly all images. So we compute max_len once and
|
|
|
|
# reuse this value on all lists.
|
2022-01-31 22:18:10 +08:00
|
|
|
col_max_len = print_icons(list_dir,
|
2022-02-01 00:59:11 +08:00
|
|
|
['scalable.list',
|
|
|
|
'color-selectors.list', 'controllers.list', 'display-filters.list',
|
2022-02-01 22:26:11 +08:00
|
|
|
'locks.list', 'prefs.list', 'templates.list', 'tools.list'],
|
2022-01-31 22:18:10 +08:00
|
|
|
None, "scalable/", ".svg", colorf)
|
|
|
|
sym_max_len = print_icons(list_dir,
|
2022-02-01 00:59:11 +08:00
|
|
|
['scalable.list',
|
|
|
|
'color-selectors.list', 'controllers.list', 'display-filters.list',
|
2022-02-01 22:26:11 +08:00
|
|
|
'locks.list', 'prefs.list', 'templates.list', 'tools.list'],
|
2022-01-31 22:18:10 +08:00
|
|
|
None, "scalable/", "-symbolic.svg", symbolicf)
|
2022-01-27 01:26:47 +08:00
|
|
|
|
|
|
|
# 12x12 bitmap
|
|
|
|
print("\nicons12_images = \\", file=colorf)
|
|
|
|
print("\nicons12_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_12.list'], col_max_len, "12/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_12.list'], sym_max_len, "12/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 16x16 bitmap
|
|
|
|
print("\nicons16_images = \\", file=colorf)
|
|
|
|
print("\nicons16_images = \\", file=symbolicf)
|
2022-01-31 23:09:28 +08:00
|
|
|
print_icons(list_dir,
|
2022-02-01 00:59:11 +08:00
|
|
|
['bitmap_16.list',
|
|
|
|
'color-selectors.list', 'controllers.list', 'display-filters.list',
|
2022-02-01 22:26:11 +08:00
|
|
|
'locks.list', 'prefs.list', 'templates.list', 'tools.list'],
|
2022-01-31 22:18:10 +08:00
|
|
|
col_max_len, "16/", ".png", colorf)
|
2022-01-31 23:09:28 +08:00
|
|
|
print_icons(list_dir,
|
2022-02-01 00:59:11 +08:00
|
|
|
['bitmap_16.list',
|
|
|
|
'color-selectors.list', 'controllers.list', 'display-filters.list',
|
2022-02-01 22:26:11 +08:00
|
|
|
'locks.list', 'prefs.list', 'templates.list', 'tools.list'],
|
2022-01-31 22:18:10 +08:00
|
|
|
sym_max_len, "16/", "-symbolic.symbolic.png", symbolicf)
|
2022-01-27 01:26:47 +08:00
|
|
|
|
|
|
|
# 18x18 bitmap
|
|
|
|
print("\nicons18_images = \\", file=colorf)
|
|
|
|
print("\nicons18_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_18.list'], col_max_len, "18/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_18.list'], sym_max_len, "18/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 22x22 bitmap
|
|
|
|
print("\nicons22_images = \\", file=colorf)
|
|
|
|
print("\nicons22_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_22.list'], col_max_len, "22/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_22.list'], sym_max_len, "22/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 24x24 bitmap
|
|
|
|
print("\nicons24_images = \\", file=colorf)
|
|
|
|
print("\nicons24_images = \\", file=symbolicf)
|
2022-01-31 23:09:28 +08:00
|
|
|
print_icons(list_dir, ['bitmap_24.list', 'templates.list', 'tools.list'],
|
2022-01-31 22:18:10 +08:00
|
|
|
col_max_len, "24/", ".png", colorf)
|
2022-01-31 23:09:28 +08:00
|
|
|
print_icons(list_dir, ['bitmap_24.list', 'templates.list', 'tools.list'],
|
2022-01-31 22:18:10 +08:00
|
|
|
sym_max_len, "24/", "-symbolic.symbolic.png", symbolicf)
|
2022-01-27 01:26:47 +08:00
|
|
|
|
|
|
|
# 32x32 bitmap
|
|
|
|
print("\nicons32_images = \\", file=colorf)
|
|
|
|
print("\nicons32_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_32.list'], col_max_len, "32/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_32.list'], sym_max_len, "32/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 48x48 bitmap
|
|
|
|
print("\nicons48_images = \\", file=colorf)
|
|
|
|
print("\nicons48_images = \\", file=symbolicf)
|
icons, tools: start grouping icons by their usage.
There are some clear and obvious groups in the icons. For instance, the
Preferences icons are one of them. Looking up the code, we only use them
in 16px (in Preferences side menu) and 48px (in Preferences page
headers). Until now, we were storing in other unrelated size (22px) and
also the lists per-sizes were not consistent. Some icons were missing
here, other there.
With this new organization, the Preferences icons are listed in a single
file, ensuring usage and contents consistency. Also it allows to install
them only for the needed sizes (note that it is possible that they might
be needed in different size, for instance with custom themes; but we
can't just randomly distribute icons in all sizes; or to be more
accurate, this is exactly why we encourage rather the SVG/scalable
icons, so if some people explicitly go for raster icons, they also get
the drawbacks which come with).
Last note: it may be possible that some icons end up in different
"semantic" icon group. This is not a problem with this new organization
as my scripts handle duplicates gracefully.
2022-01-29 07:21:40 +08:00
|
|
|
print_icons(list_dir, ['bitmap_48.list', 'prefs.list'], col_max_len, "48/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_48.list', 'prefs.list'], sym_max_len, "48/", "-symbolic.symbolic.png", symbolicf)
|
2022-01-27 01:26:47 +08:00
|
|
|
|
|
|
|
# 64x64 bitmap
|
|
|
|
print("\nicons64_images = \\", file=colorf)
|
|
|
|
print("\nicons64_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, [ 'bitmap_64-always.list', 'bitmap_64.list'], col_max_len, "64/", ".png", colorf)
|
|
|
|
print_icons(list_dir, [ 'bitmap_64-always.list' ], sym_max_len, "64/", ".png", symbolicf, endlist=False)
|
|
|
|
print_icons(list_dir, [ 'bitmap_64.list'], sym_max_len, "64/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
print("\nicons64_system_images = \\", file=colorf)
|
|
|
|
print("\nicons64_system_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_64-system.list'], col_max_len, "64/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_64-system.list'], sym_max_len, "64/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 96x96 bitmap
|
|
|
|
print("\nicons96_images = \\", file=colorf)
|
|
|
|
print("\nicons96_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_96.list'], col_max_len, "96/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_96.list'], sym_max_len, "96/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 128x128 bitmap
|
|
|
|
print("\nicons128_images = \\", file=colorf)
|
|
|
|
print("\nicons128_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_128.list'], col_max_len, "128/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_128.list'], sym_max_len, "128/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 192x192 bitmap
|
|
|
|
print("\nicons192_images = \\", file=colorf)
|
|
|
|
print("\nicons192_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_192.list'], col_max_len, "192/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_192.list'], sym_max_len, "192/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
# 256x256 bitmap
|
|
|
|
print("\nicons256_images = \\", file=colorf)
|
|
|
|
print("\nicons256_images = \\", file=symbolicf)
|
|
|
|
print_icons(list_dir, ['bitmap_256.list'], col_max_len, "256/", ".png", colorf)
|
|
|
|
print_icons(list_dir, ['bitmap_256.list'], sym_max_len, "256/", "-symbolic.symbolic.png", symbolicf)
|
|
|
|
|
|
|
|
print(file=colorf)
|
|
|
|
print(file=symbolicf)
|
|
|
|
eof = os.path.join(list_dir, "icon-list.mk.eof")
|
|
|
|
with open(eof, mode='r') as f:
|
|
|
|
for line in f:
|
|
|
|
colorf.write(line)
|
|
|
|
symbolicf.write(line)
|
2022-02-01 04:50:21 +08:00
|
|
|
|
|
|
|
# Touch the 2 meson.build to force-trigger their re-processing (hence
|
|
|
|
# re-configuration) at next build. Otherwise even with image list
|
|
|
|
# changed, meson might not see it as it uses the list from the last
|
|
|
|
# configuration.
|
|
|
|
os.utime(os.path.join(icons_dir, 'Color', 'meson.build'), times=None)
|
|
|
|
os.utime(os.path.join(icons_dir, 'Symbolic', 'meson.build'), times=None)
|