nlve/tools/make_icons.py

139 lines
5.3 KiB
Python
Raw Normal View History

Значки Icons8, окно «О программе» с указанием авторства Значки заменены на присланные. Они вшиты в программу модулем uIconData, который собирается из icons_online командой tools/make_icons.py — правятся исходные картинки, а не он. Размер выбран под кнопку: двадцать четыре точки в клетке двадцать восемь, уменьшение делает convert, пропорции сохранены — все исходники квадратные. Цвет значку задаётся при отрисовке: берётся прозрачность точки, а цвет — тот, каким сейчас рисуется кнопка. Поэтому один значок годится и для тёмной кнопки, и для оранжевой, и для недоступной. Перекрашенные запоминаются: цветов ровно три. Значок программы стал значком окна. Значок самого файла под Windows задаётся не отсюда, а ресурсом при сборке — это осталось как было. Окно «О программе» (Справка → О программе). Две вкладки: «Библиотеки и авторство» и «Что умеет». Первая обязательна — бесплатная лицензия Icons8 требует ссылку на каждый значок; заодно там перечислено всё, на чём программа держится, и под какой лицензией. Списки разные по системам: под Linux ffmpeg и libmpv ставит пакетный менеджер, под Windows их скачивает сама программа, и это разные сборки. Вкладки свои, а не TPageControl: системные вкладки под Windows остались бы светлой полосой поверх тёмного окна. Текст показывается нашим журналом — его можно выделить и скопировать, так что ссылку из списка получится взять в браузер. Перенос по словам свой: ссылки не рвутся, отступ списка сохраняется на продолжениях. Свои рисованные значки из icons/ убраны: они больше не используются, и держать рядом два набора значило бы путать.
2026-08-22 10:54:30 +03:00
#!/usr/bin/env python3
"""
Готовит модуль с данными значков из файлов в icons_online.
Зачем модулем, а не файлами рядом с программой: программа не должна
зависеть от того, лежит ли что-то в её каталоге. Значки маленькие, все
вместе занимают единицы килобайт.
Размер выбран под кнопку: у неё двадцать восемь точек стороны, значку
достаётся клетка двадцать четыре на двадцать четыре. Уменьшение делает
convert с обычным сглаживанием, пропорции при этом сохраняются — все
исходники квадратные, растягивать нечего.
Запуск: python3 tools/make_icons.py
"""
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
SRC = ROOT / 'icons_online'
OUT = ROOT / 'src' / 'uIconData.pas'
# Имя в программе -> файл исходника и сторона в точках.
# Для «схлопывания» берётся вариант на шестьдесят четыре точки: чем крупнее
# исходник, тем чище получается уменьшение.
ICONS = [
('Snap', 'icons8-магнит-30.png', 24),
('Ripple', 'icons8-merge-vertical-64.png', 24),
('Log', 'icons8-property-30.png', 24),
('Glue', 'icons8-клей-30.png', 24),
('Target', 'icons8-цель-30.png', 24),
Выделение по времени, рез по краям промежутка, курсор идёт за резом Режимов выделения стало два, переключаются клавишей D и кнопкой внизу, режим показан её значком. Рамкой по клипам — как было. По времени — протяжка отмечает промежуток по всем дорожкам сразу, он остаётся виден пунктиром, и S режет все дорожки по обоим его краям. Выделенной после этого остаётся ровно середина: следующим действием её обычно удаляют, а выделение на старых клипах убрало бы не то. Курсор теперь идёт за резом: после S встаёт на место реза (в режиме по времени — на начало промежутка), после удаления куска — на место стыка, после схлопывания дыры — туда же. Раньше в это место приходилось попадать мышью заново. Рез кладётся на кадровую сетку: между кадрами времени нет, и рез на доле кадра оставлял бы в монтаже время, которого не бывает. Выделение рамкой требует настоящего перекрытия, а не касания краями: сосед, кончающийся ровно на краю рамки, попадал в выделение из-за разницы в последнем знаке дробей. Кнопка журнала и строка состояния сдвинуты вправо: переключатель выделения встал в один ряд с прилипанием и схлопыванием. Значки — icons8, набор ios-glyphs, авторство дописано в attribution.txt. Набора «ios26» на их раздаче нет (404), взят ближайший по виду к нынешним. Проверки: рез по курсору и по краям промежутка, кадровая сетка, выделение середины, курсор после удаления и после схлопывания.
2026-09-29 23:58:30 +03:00
('SelectClips', 'icons8-select-all-90.png', 24),
('SelectRange', 'icons8-width-90.png', 24),
Значки Icons8, окно «О программе» с указанием авторства Значки заменены на присланные. Они вшиты в программу модулем uIconData, который собирается из icons_online командой tools/make_icons.py — правятся исходные картинки, а не он. Размер выбран под кнопку: двадцать четыре точки в клетке двадцать восемь, уменьшение делает convert, пропорции сохранены — все исходники квадратные. Цвет значку задаётся при отрисовке: берётся прозрачность точки, а цвет — тот, каким сейчас рисуется кнопка. Поэтому один значок годится и для тёмной кнопки, и для оранжевой, и для недоступной. Перекрашенные запоминаются: цветов ровно три. Значок программы стал значком окна. Значок самого файла под Windows задаётся не отсюда, а ресурсом при сборке — это осталось как было. Окно «О программе» (Справка → О программе). Две вкладки: «Библиотеки и авторство» и «Что умеет». Первая обязательна — бесплатная лицензия Icons8 требует ссылку на каждый значок; заодно там перечислено всё, на чём программа держится, и под какой лицензией. Списки разные по системам: под Linux ffmpeg и libmpv ставит пакетный менеджер, под Windows их скачивает сама программа, и это разные сборки. Вкладки свои, а не TPageControl: системные вкладки под Windows остались бы светлой полосой поверх тёмного окна. Текст показывается нашим журналом — его можно выделить и скопировать, так что ссылку из списка получится взять в браузер. Перенос по словам свой: ссылки не рвутся, отступ списка сохраняется на продолжениях. Свои рисованные значки из icons/ убраны: они больше не используются, и держать рядом два набора значило бы путать.
2026-08-22 10:54:30 +03:00
]
# Значок самой программы: отдельно, потому что окну нужен формат ico —
# только его умеет читать TIcon в LCL.
APP_ICON = ('icons8-показ-видеокадров-30.png', 32)
def make_ico(path: Path, side: int) -> bytes:
out = subprocess.run(
['convert', str(path), '-background', 'none', '-alpha', 'on',
'-resize', '%dx%d' % (side, side), 'ico:-'],
check=True, capture_output=True)
return out.stdout
def scale(path: Path, side: int) -> bytes:
out = subprocess.run(
['convert', str(path), '-background', 'none', '-alpha', 'on',
'-resize', '%dx%d' % (side, side), 'png:-'],
check=True, capture_output=True)
return out.stdout
def pascal_bytes(data: bytes, indent: str = ' ') -> str:
parts = []
for i in range(0, len(data), 16):
chunk = ', '.join('$%02X' % b for b in data[i:i + 16])
parts.append(indent + chunk)
return ',\n'.join(parts)
def main() -> int:
if not SRC.is_dir():
print('нет каталога с исходниками:', SRC, file=sys.stderr)
return 1
blocks = []
names = []
for name, filename, side in ICONS:
path = SRC / filename
if not path.is_file():
print('нет файла:', path, file=sys.stderr)
return 1
data = scale(path, side)
names.append((name, len(data)))
blocks.append(
' { %s, %d на %d точек }\n'
' Icon%sData: array[0..%d] of Byte = (\n%s\n );'
% (filename, side, side, name, len(data) - 1, pascal_bytes(data)))
app_src, app_side = APP_ICON
app_path = SRC / app_src
if not app_path.is_file():
print('нет файла:', app_path, file=sys.stderr)
return 1
app_data = make_ico(app_path, app_side)
names.append(('App (ico)', len(app_data)))
blocks.append(
' { %s, значок окна, %d на %d точек, формат ico }\n'
' IconAppData: array[0..%d] of Byte = (\n%s\n );'
% (app_src, app_side, app_side, len(app_data) - 1,
pascal_bytes(app_data)))
text = '''{
uIconData — значки, вшитые в программу.
Собран из файлов в icons_online командой:
python3 tools/make_icons.py
Правится не он, а исходные картинки: этот файл переписывается целиком.
Значки взяты у Icons8 и требуют указания авторства — оно есть в окне
«О программе», вкладка «Библиотеки и авторство». Ссылки на каждый значок
лежат в icons_online/attribution.txt.
Картинки чёрные на прозрачном фоне. Цвет им задаётся при отрисовке:
берётся прозрачность точки, а цвет — тот, каким сейчас рисуется кнопка.
Поэтому один и тот же значок годится и для тёмной кнопки, и для
оранжевой.
}
unit uIconData;
{$mode objfpc}{$H+}
interface
const
%s
implementation
end.
''' % ('\n\n'.join(blocks))
OUT.write_text(text, encoding='utf-8')
print('записан', OUT)
for name, size in names:
print(' %-8s %d байт' % (name, size))
return 0
if __name__ == '__main__':
sys.exit(main())