diff --git a/novelwriter/assets/icons/remix_filled.icons b/novelwriter/assets/icons/remix_filled.icons new file mode 100644 index 00000000..f811c500 --- /dev/null +++ b/novelwriter/assets/icons/remix_filled.icons @@ -0,0 +1,106 @@ +# This file is automatically generated. Do not edit. + +# Meta +meta:name = Remix Icon - Filled +meta:author = Remix Icon +meta:license = Apache 2.0 + +# Icons +icon:alert_error = +icon:alert_info = +icon:alert_question = +icon:alert_warn = +icon:cls_archive = +icon:cls_character = +icon:cls_custom = +icon:cls_entity = +icon:cls_none = +icon:cls_novel = +icon:cls_object = +icon:cls_plot = +icon:cls_template = +icon:cls_timeline = +icon:cls_trash = +icon:cls_world = +icon:prj_folder = +icon:prj_document = +icon:prj_title = +icon:prj_chapter = +icon:prj_scene = +icon:prj_note = +icon:fmt_bold = +icon:fmt_italic = +icon:fmt_mark = +icon:fmt_strike = +icon:fmt_subscript = +icon:fmt_superscript = +icon:fmt_underline = +icon:fmt_toolbar = +icon:search = +icon:search_cancel = +icon:search_case = +icon:search_loop = +icon:search_preserve = +icon:search_project = +icon:search_regex = +icon:search_replace = +icon:search_word = +icon:bullet-off = +icon:bullet-on = +icon:unfold-hide = +icon:unfold-show = +icon:sb_build = +icon:sb_novel = +icon:sb_outline = +icon:sb_project = +icon:sb_search = +icon:add = +icon:bookmarks = +icon:browse = +icon:build_settings = +icon:cancel = +icon:checked = +icon:chevron_down = +icon:chevron_left = +icon:chevron_right = +icon:chevron_up = +icon:close = +icon:copy = +icon:document_add = +icon:document = +icon:edit = +icon:exclude = +icon:export = +icon:filter = +icon:fit_height = +icon:fit_width = +icon:folder = +icon:font = +icon:import = +icon:language = +icon:lines = +icon:list = +icon:margin_bottom = +icon:margin_left = +icon:margin_right = +icon:margin_top = +icon:maximise = +icon:minimise = +icon:more_arrow = +icon:more_vertical = +icon:noncheckable = +icon:open = +icon:panel = +icon:pin = +icon:quote = +icon:refresh = +icon:remove = +icon:revert = +icon:settings = +icon:star = +icon:stats = +icon:text = +icon:timer_off = +icon:timer = +icon:unchecked = +icon:view = diff --git a/novelwriter/assets/icons/remix_outline.icons b/novelwriter/assets/icons/remix_outline.icons new file mode 100644 index 00000000..ecf7e9ab --- /dev/null +++ b/novelwriter/assets/icons/remix_outline.icons @@ -0,0 +1,106 @@ +# This file is automatically generated. Do not edit. + +# Meta +meta:name = Remix Icon - Outline +meta:author = Remix Icon +meta:license = Apache 2.0 + +# Icons +icon:alert_error = +icon:alert_info = +icon:alert_question = +icon:alert_warn = +icon:cls_archive = +icon:cls_character = +icon:cls_custom = +icon:cls_entity = +icon:cls_none = +icon:cls_novel = +icon:cls_object = +icon:cls_plot = +icon:cls_template = +icon:cls_timeline = +icon:cls_trash = +icon:cls_world = +icon:prj_folder = +icon:prj_document = +icon:prj_title = +icon:prj_chapter = +icon:prj_scene = +icon:prj_note = +icon:fmt_bold = +icon:fmt_italic = +icon:fmt_mark = +icon:fmt_strike = +icon:fmt_subscript = +icon:fmt_superscript = +icon:fmt_underline = +icon:fmt_toolbar = +icon:search = +icon:search_cancel = +icon:search_case = +icon:search_loop = +icon:search_preserve = +icon:search_project = +icon:search_regex = +icon:search_replace = +icon:search_word = +icon:bullet-off = +icon:bullet-on = +icon:unfold-hide = +icon:unfold-show = +icon:sb_build = +icon:sb_novel = +icon:sb_outline = +icon:sb_project = +icon:sb_search = +icon:add = +icon:bookmarks = +icon:browse = +icon:build_settings = +icon:cancel = +icon:checked = +icon:chevron_down = +icon:chevron_left = +icon:chevron_right = +icon:chevron_up = +icon:close = +icon:copy = +icon:document_add = +icon:document = +icon:edit = +icon:exclude = +icon:export = +icon:filter = +icon:fit_height = +icon:fit_width = +icon:folder = +icon:font = +icon:import = +icon:language = +icon:lines = +icon:list = +icon:margin_bottom = +icon:margin_left = +icon:margin_right = +icon:margin_top = +icon:maximise = +icon:minimise = +icon:more_arrow = +icon:more_vertical = +icon:noncheckable = +icon:open = +icon:panel = +icon:pin = +icon:quote = +icon:refresh = +icon:remove = +icon:revert = +icon:settings = +icon:star = +icon:stats = +icon:text = +icon:timer_off = +icon:timer = +icon:unchecked = +icon:view = diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py index 4c90aa73..b636ac3c 100644 --- a/novelwriter/tools/manusbuild.py +++ b/novelwriter/tools/manusbuild.py @@ -189,7 +189,7 @@ class GuiManuscriptBuild(NDialog): self.buttonBox.addButton(self.btnOpen, QtRoleAction) self.btnBuild = QPushButton( - SHARED.theme.getIcon("manuscript", "blue"), self.tr("&Build"), self + SHARED.theme.getIcon("sb_build", "blue"), self.tr("&Build"), self ) self.btnBuild.setIconSize(bSz) self.btnBuild.setAutoDefault(True) diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py index c0ea46f5..07501af1 100644 --- a/novelwriter/tools/manuscript.py +++ b/novelwriter/tools/manuscript.py @@ -490,7 +490,7 @@ class GuiManuscript(NToolDialog): for key, name in self._builds.builds(): bItem = QListWidgetItem() bItem.setText(name) - bItem.setIcon(SHARED.theme.getIcon("manuscript", "blue")) + bItem.setIcon(SHARED.theme.getIcon("build_settings", "blue")) bItem.setData(self.D_KEY, key) self.buildList.addItem(bItem) self._buildMap[key] = bItem diff --git a/pkgutils.py b/pkgutils.py index aa4ddad6..8e0d5cbf 100755 --- a/pkgutils.py +++ b/pkgutils.py @@ -35,7 +35,7 @@ import zipfile from pathlib import Path -from utils.icon_themes import processFontAwesome, processMaterialIcons +from utils.icon_themes import processFontAwesome, processMaterialIcons, processRemix CURR_DIR = Path(__file__).parent SETUP_DIR = CURR_DIR / "setup" @@ -391,6 +391,18 @@ def buildIconTheme(args: argparse.Namespace) -> None: }, }) + if style in ("all", "remix"): + processRemix(workDir, iconsDir, { + "remix_outline": { + "name": "Remix Icon - Outline", + "filled": False, + }, + "remix_filled": { + "name": "Remix Icon - Filled", + "filled": True, + }, + }) + print("Done") print("") diff --git a/utils/icon_themes.py b/utils/icon_themes.py index 01a5bdf6..53d974d5 100644 --- a/utils/icon_themes.py +++ b/utils/icon_themes.py @@ -27,10 +27,7 @@ from pathlib import Path from xml.etree import ElementTree as ET UTILS = Path(__file__).parent - ET.register_namespace("", "http://www.w3.org/2000/svg") -MATERIAL_REPO = "https://github.com/google/material-design-icons.git" -FONT_AWESOME_REPO = "https://github.com/FortAwesome/Font-Awesome.git" ICONS = [ "alert_error", "alert_info", @@ -81,15 +78,16 @@ ICONS = [ "unfold-hide", "unfold-show", - "sb_project", - "sb_novel", - "sb_search", - "sb_outline", "sb_build", + "sb_novel", + "sb_outline", + "sb_project", + "sb_search", "add", "bookmarks", "browse", + "build_settings", "cancel", "checked", "chevron_down", @@ -112,7 +110,6 @@ ICONS = [ "language", "lines", "list", - "manuscript", "margin_bottom", "margin_left", "margin_right", @@ -194,7 +191,7 @@ def _cloneRepo(repoPath: Path, repoUrl: str) -> None: def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None: """Process material icons of a given spec and write output file.""" srcRepo = workDir / "material-design-icons" - _cloneRepo(srcRepo, MATERIAL_REPO) + _cloneRepo(srcRepo, "https://github.com/google/material-design-icons.git") for file, job in jobs.items(): name: str = job["name"] @@ -211,10 +208,10 @@ def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None: iconSrc = srcRepo / "symbols" / "web" for key, icon in _loadMap("material_symbols").items(): if kind: - fileNmae = f"{icon}_{kind}_24px.svg" + fileName = f"{icon}_{kind}_24px.svg" else: - fileNmae = f"{icon}_24px.svg" - iconFile = iconSrc / icon / f"materialsymbols{style}" / fileNmae + fileName = f"{icon}_24px.svg" + iconFile = iconSrc / icon / f"materialsymbols{style}" / fileName if iconFile.is_file(): icons[key] = ET.fromstring(iconFile.read_text(encoding="utf-8")) else: @@ -231,7 +228,7 @@ def processMaterialIcons(workDir: Path, iconsDir: Path, jobs: dict) -> None: def processFontAwesome(workDir: Path, iconsDir: Path, jobs: dict) -> None: """Process Font Awesome icons of a given spec and write output file.""" srcRepo = workDir / "Font-Awesome" - _cloneRepo(srcRepo, FONT_AWESOME_REPO) + _cloneRepo(srcRepo, "https://github.com/FortAwesome/Font-Awesome.git") for file, job in jobs.items(): name: str = job["name"] @@ -271,3 +268,46 @@ def processFontAwesome(workDir: Path, iconsDir: Path, jobs: dict) -> None: print("") return + + +def processRemix(workDir: Path, iconsDir: Path, jobs: dict) -> None: + """Process Remix icons of a given spec and write output file.""" + srcRepo = workDir / "RemixIcon" + _cloneRepo(srcRepo, "https://github.com/Remix-Design/RemixIcon.git") + + for file, job in jobs.items(): + name: str = job["name"] + style = "fill" if job["filled"] else "line" + + print(f"Processing: {name}") + + icons: dict[str, ET.Element] = {} + iconSrc = srcRepo / "icons" + iconGroups = [x for x in iconSrc.iterdir() if x.is_dir()] + for key, icon in _loadMap("remix").items(): + if icon.endswith(("-line", "-fill")): + fileName = f"{icon}.svg" + else: + fileName = f"{icon}-{style}.svg" + for group in iconGroups: + iconFile = group / fileName + if iconFile.is_file(): + break + else: + fileName = f"{icon}.svg" + for group in iconGroups: + iconFile = group / fileName + if iconFile.is_file(): + break + else: + print(f"Not Found: {fileName}") + continue + + icons[key] = ET.fromstring(iconFile.read_text(encoding="utf-8")) + + target = iconsDir / f"{file}.icons" + _writeThemeFile(target, name, "Remix Icon", "Apache 2.0", icons) + + print("") + + return diff --git a/utils/remix.json b/utils/remix.json new file mode 100644 index 00000000..f62a9ee6 --- /dev/null +++ b/utils/remix.json @@ -0,0 +1,108 @@ +{ + "alert_error": "error-warning", + "alert_info": "information", + "alert_question": "question", + "alert_warn": "alarm-warning", + + "cls_archive": "archive", + "cls_character": "group", + "cls_custom": "price-tag-3", + "cls_entity": "building", + "cls_none": "checkbox-blank", + "cls_novel": "git-repository", + "cls_object": "key-2", + "cls_plot": "puzzle-2", + "cls_template": "folder-add", + "cls_timeline": "hourglass", + "cls_trash": "delete-bin", + "cls_world": "earth", + + "prj_folder": "folder-6", + "prj_document": "file-text", + "prj_title": "file-text", + "prj_chapter": "file-text", + "prj_scene": "file-text", + "prj_note": "file-4", + + "fmt_bold": "bold", + "fmt_italic": "italic", + "fmt_mark": "mark-pen", + "fmt_strike": "strikethrough", + "fmt_subscript": "subscript", + "fmt_superscript": "superscript", + "fmt_underline": "underline", + "fmt_toolbar": "font-color", + + "search": "search-line", + "search_cancel": "close", + "search_case": "font-size", + "search_loop": "loop-right", + "search_preserve": "font-size-2", + "search_project": "file-search", + "search_regex": "asterisk", + "search_replace": "find-replace-line", + "search_word": "space", + + "bullet-off": "checkbox-blank-circle-line", + "bullet-on": "checkbox-blank-circle-fill", + "unfold-hide": "arrow-right-s-fill", + "unfold-show": "arrow-down-s-fill", + + "sb_build": "stack", + "sb_novel": "booklet", + "sb_outline": "table-view", + "sb_project": "file-edit", + "sb_search": "file-search", + + "add": "add", + "bookmarks": "bookmark", + "browse": "folder-2", + "build_settings": "file-settings", + "cancel": "prohibited-2", + "checked": "checkbox", + "chevron_down": "arrow-down-s-line", + "chevron_left": "arrow-left-s-line", + "chevron_right": "arrow-right-s-line", + "chevron_up": "arrow-up-s-line", + "close": "close-large", + "copy": "file-copy", + "document_add": "file-add", + "document": "file-text", + "edit": "edit", + "exclude": "close-circle", + "export": "export", + "filter": "filter-2", + "fit_height": "expand-height-line", + "fit_width": "expand-width-line", + "folder": "folder-6", + "font": "font-sans", + "import": "import", + "language": "translate-2", + "lines": "menu-2", + "list": "list-unordered", + "margin_bottom": "skip-down-line", + "margin_left": "skip-left-line", + "margin_right": "skip-right-line", + "margin_top": "skip-up-line", + "maximise": "fullscreen", + "minimise": "fullscreen-exit", + "more_arrow": "arrow-right-s-fill", + "more_vertical": "more-2", + "noncheckable": "checkbox-indeterminate", + "open": "file-upload", + "panel": "layout-bottom", + "pin": "pushpin", + "project_copy": "", + "quote": "double-quotes-l", + "refresh": "refresh-line", + "remove": "subtract", + "revert": "reset-left", + "settings": "settings-2", + "star": "star-fill", + "stats": "numbers", + "text": "file-text", + "timer_off": "pause", + "timer": "timer", + "unchecked": "checkbox-blank", + "view": "eye-fill" +}