Add script to generate theme icon files
This commit is contained in:
+48
@@ -35,6 +35,8 @@ import zipfile
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from utils.material_icons import processMaterialIcons
|
||||
|
||||
CURR_DIR = Path(__file__).parent
|
||||
SETUP_DIR = CURR_DIR / "setup"
|
||||
SIGN_KEY = "D6A9F6B8F227CF7C6F6D1EE84DBBE4B734B0BD08"
|
||||
@@ -323,6 +325,44 @@ def buildSampleZip(args: argparse.Namespace | None = None) -> None:
|
||||
return
|
||||
|
||||
|
||||
##
|
||||
# Import Translations (import-i18n)
|
||||
##
|
||||
|
||||
def buildIconTheme(args: argparse.Namespace) -> None:
|
||||
"""Build an icon theme."""
|
||||
print("")
|
||||
print("Build Icon Theme")
|
||||
print("================")
|
||||
print("")
|
||||
|
||||
workDir = Path(args.sources).absolute()
|
||||
if not workDir.is_dir():
|
||||
print(f"Source directory not found: {workDir}")
|
||||
sys.exit(1)
|
||||
|
||||
iconsDir = CURR_DIR / "novelwriter" / "assets" / "icons"
|
||||
|
||||
style = args.style
|
||||
if style == "material":
|
||||
processMaterialIcons(
|
||||
workDir, iconsDir / "material_outline_normal.icons", "outlined", False, 400
|
||||
)
|
||||
processMaterialIcons(
|
||||
workDir, iconsDir / "material_filled_normal.icons", "outlined", True, 400
|
||||
)
|
||||
processMaterialIcons(
|
||||
workDir, iconsDir / "material_outline_bold.icons", "outlined", False, 700
|
||||
)
|
||||
processMaterialIcons(
|
||||
workDir, iconsDir / "material_filled_bold.icons", "outlined", True, 700
|
||||
)
|
||||
|
||||
print("")
|
||||
|
||||
return
|
||||
|
||||
|
||||
##
|
||||
# Import Translations (import-i18n)
|
||||
##
|
||||
@@ -1414,6 +1454,14 @@ if __name__ == "__main__":
|
||||
# Additional Builds
|
||||
# =================
|
||||
|
||||
# Build Icons
|
||||
cmdIcons = parsers.add_parser(
|
||||
"icons", help="Build icon theme files from source."
|
||||
)
|
||||
cmdIcons.add_argument("sources", help="Working directory for sources.")
|
||||
cmdIcons.add_argument("style", help="What icon style to build.")
|
||||
cmdIcons.set_defaults(func=buildIconTheme)
|
||||
|
||||
# Import Translations
|
||||
cmdImportTS = parsers.add_parser(
|
||||
"qtlimport", help="Import updated i18n files from a Crowdin zip file."
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
novelWriter – Material Icon Theme
|
||||
=================================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright (C) 2019 Veronica Berglyd Olsen and novelWriter contributors
|
||||
|
||||
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/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from lxml import etree
|
||||
|
||||
MATERIAL_REPO = "https://github.com/google/material-design-icons.git"
|
||||
GRADE = ""
|
||||
|
||||
ICON_MAP = {
|
||||
"alert_error": "error",
|
||||
"alert_info": "info",
|
||||
"alert_question": "help",
|
||||
"alert_warn": "warning",
|
||||
|
||||
"cls_archive": "archive",
|
||||
"cls_character": "group",
|
||||
"cls_custom": "label",
|
||||
"cls_entity": "apartment",
|
||||
"cls_none": "close",
|
||||
"cls_novel": "book_2",
|
||||
"cls_object": "key",
|
||||
"cls_plot": "extension",
|
||||
"cls_template": "topic",
|
||||
"cls_timeline": "hourglass_empty",
|
||||
"cls_trash": "delete",
|
||||
"cls_world": "globe",
|
||||
|
||||
"fmt_bold": "format_bold",
|
||||
"fmt_italic": "format_italic",
|
||||
"fmt_mark": "format_ink_highlighter",
|
||||
"fmt_strike": "format_strikethrough",
|
||||
"fmt_subscript": "subscript",
|
||||
"fmt_superscript": "superscript",
|
||||
"fmt_underline": "format_underlined",
|
||||
"fmt_toolbar": "text_format",
|
||||
|
||||
"search_cancel": "close",
|
||||
"search_case": "match_case",
|
||||
"search_loop": "laps",
|
||||
"search_preserve": "text_fields",
|
||||
"search_project": "document_search",
|
||||
"search_regex": "regular_expression",
|
||||
"search_replace": "find_replace",
|
||||
"search_word": "match_word",
|
||||
"search": "search",
|
||||
|
||||
"bullet-off": "radio_button_unchecked",
|
||||
"bullet-on": "radio_button_checked",
|
||||
|
||||
"bookmarks": "bookmarks",
|
||||
"checked": "select_check_box",
|
||||
"chevron_down": "keyboard_arrow_down",
|
||||
"chevron_left": "arrow_back_ios",
|
||||
"chevron_right": "arrow_forward_ios",
|
||||
"chevron_up": "keyboard_arrow_up",
|
||||
"close": "close",
|
||||
"document_add": "note_add",
|
||||
"document": "description",
|
||||
"edit": "edit",
|
||||
"folder": "folder",
|
||||
"item_add": "add",
|
||||
"list": "format_list_bulleted",
|
||||
"maximise": "fullscreen",
|
||||
"minimise": "close_fullscreen",
|
||||
"more_vertical": "more_vert",
|
||||
"noncheckable": "indeterminate_check_box",
|
||||
"project_copy": "folder_copy",
|
||||
"refresh": "refresh",
|
||||
"unchecked": "disabled_by_default",
|
||||
}
|
||||
|
||||
|
||||
def _fixXml(svg: str) -> str:
|
||||
"""Clean up the SVG XML and add needed fields."""
|
||||
xSvg = etree.fromstring(svg) # type: ignore
|
||||
xSvg.set("fill", "#000000")
|
||||
xSvg.set("height", "128")
|
||||
xSvg.set("width", "128")
|
||||
return etree.tostring(xSvg).decode()
|
||||
|
||||
|
||||
def processMaterialIcons(workDir: Path, output: Path, style: str, fill: bool, weight: int) -> None:
|
||||
"""Process material icons of a given spec and write output file."""
|
||||
srcRepo = workDir / "material-design-icons"
|
||||
if not srcRepo.is_dir():
|
||||
subprocess.call(["git", "clone", MATERIAL_REPO, "--depth", "50"], cwd=workDir)
|
||||
else:
|
||||
subprocess.call(["git", "pull"], cwd=srcRepo)
|
||||
|
||||
kind = f"wght{weight}" if weight != 400 else ""
|
||||
kind += "fill1" if fill else ""
|
||||
|
||||
with open(output, mode="w", encoding="utf-8") as icons:
|
||||
iconSrc = srcRepo / "symbols" / "web"
|
||||
for key, name in ICON_MAP.items():
|
||||
if kind:
|
||||
fileNmae = f"{name}_{kind}_24px.svg"
|
||||
else:
|
||||
fileNmae = f"{name}_24px.svg"
|
||||
iconFile = iconSrc / name / f"materialsymbols{style}" / fileNmae
|
||||
if iconFile.is_file():
|
||||
svg = iconFile.read_text(encoding="utf-8")
|
||||
icons.write(f"{key:<15s} = {_fixXml(svg)}\n")
|
||||
print(f"Wrote: {iconFile.stem}")
|
||||
else:
|
||||
print(f"Not Found: {iconFile}")
|
||||
Reference in New Issue
Block a user