diff --git a/README.md b/README.md index 7e041a3..e7e1e7c 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ SpineViewer/ - 零时长动画按单帧静态姿势预览 - 自动适配并居中 - 用户可主动将当前帧设为当前素材的自定义缩略图;若已有自定义缩略图,替换前会明确确认 -4. **缩略图**:导入时不运行插件缩略图生成器,由 Eagle 自身处理。用户打开 Spine 预览后,可主动将当前帧设为**当前素材**的自定义缩略图;若已有自定义缩略图,替换前会明确确认。手动缩略图会添加 Spine badge 和导出版本号。 +4. **缩略图**:导入时不运行插件缩略图生成器,由 Eagle 自身处理。用户打开 Spine 预览后,仍可用原有按钮将当前帧设为**当前素材**的自定义缩略图。左侧的“为当前资源组生成缩略图…”会先列出已验证的骨骼、atlas 和贴图,明确确认后才批量处理,并始终跳过已有自定义缩略图的素材。手动缩略图会添加 Spine badge 和导出版本号。 --- @@ -77,7 +77,7 @@ SpineViewer/ Eagle 的公开素材 API 不提供任意自定义元数据字段。预乘设置保存在 Eagle 用户数据目录的 `SpineViewer/preview-settings/` 下,以素材库和素材 ID 区分;不修改 Eagle 的 `metadata.json`、标签或注释,也不会随素材导出到其他电脑。 -Atlas 页面路径按不可信输入处理:插件拒绝绝对路径、`..`、盘符、UNC、URI 以及越出允许目录的符号链接;跨素材贴图只从当前 Eagle 素材库中已经枚举并验证的素材选择。导入阶段不由插件生成缩略图;手动操作只能设置当前素材。诊断日志默认关闭;显式设置 `SPINEVIEWER_DEBUG_LOG=1` 时仅写系统临时目录。 +Atlas 页面路径按不可信输入处理:插件拒绝绝对路径、`..`、盘符、UNC、URI 以及越出允许目录的符号链接;跨素材贴图只从当前 Eagle 素材库中已经枚举并验证的素材选择。导入阶段不由插件生成缩略图;手动批量操作只作用于明确列出并得到确认的当前资源组,且跳过已有自定义缩略图的素材。诊断日志默认关闭;显式设置 `SPINEVIEWER_DEBUG_LOG=1` 时仅写系统临时目录。 - 将 Spine 导出的一整套文件(`.skel`/`.json` + `.atlas` + `.png` 等)放在**同一个文件夹**并导入 Eagle。 - 点击其中任何一个文件即可预览动画;点击配套的贴图或 atlas 也会自动找到整套资源。 diff --git a/_locales/de_DE.json b/_locales/de_DE.json index 4c49c1e..3f06cac 100644 --- a/_locales/de_DE.json +++ b/_locales/de_DE.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50-Schachbrett, das mit der Leinwand verschoben und skaliert wird und an Blend-Modi teilnimmt", "thumbnail": "Als aktuelles Vorschaubild setzen", "thumbnailTitle": "Aktuellen Frame als benutzerdefiniertes 400×400-Vorschaubild dieses Elements setzen", + "groupThumbnail": "Vorschaubilder für aktuelle Ressourcengruppe erstellen…", + "groupThumbnailTitle": "Aktuelle Spine-Ressourcengruppe prüfen und Vorschaubilder gesammelt erstellen", + "groupDialogTitle": "Vorschaubilder für aktuelle Ressourcengruppe erstellen", + "groupDialogSummary": "{generate} werden erstellt, {skip} werden übersprungen.", + "groupDialogNote": "Nur die unten aufgeführten Elemente werden aktualisiert. Elemente mit eigenen Vorschaubildern werden immer übersprungen.", + "cancel": "Abbrechen", + "groupConfirm": "Erstellen", + "groupWillGenerate": "Wird erstellt", + "groupSkipCustom": "Übersprungen: eigenes Vorschaubild vorhanden", + "groupUnavailable": "Übersprungen: nicht verifizierbar", + "groupNoTargets": "In der aktuellen Ressourcengruppe gibt es keine geeigneten Vorschaubilder.", + "groupGenerating": "Vorschaubilder werden erstellt {current}/{total}…", + "groupComplete": "Fertig: {success} erfolgreich, {skip} übersprungen, {failed} fehlgeschlagen.", "versionTitle": "Spine-Version", "reloadTitle": "Ordner neu laden", "animationList": "Animationsliste", diff --git a/_locales/en.json b/_locales/en.json index 0d44342..de4fc86 100644 --- a/_locales/en.json +++ b/_locales/en.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 checkerboard that pans and zooms with the canvas and participates in blend modes", "thumbnail": "Set current item thumbnail", "thumbnailTitle": "Set the current frame as this item's 400×400 custom thumbnail", + "groupThumbnail": "Generate thumbnails for current asset group…", + "groupThumbnailTitle": "Review the current Spine asset group, then generate thumbnails in a batch", + "groupDialogTitle": "Generate thumbnails for current asset group", + "groupDialogSummary": "Generate {generate} item(s) and skip {skip} item(s).", + "groupDialogNote": "Only the items explicitly listed below will be updated. Items with existing custom thumbnails are always skipped.", + "cancel": "Cancel", + "groupConfirm": "Generate", + "groupWillGenerate": "Will generate", + "groupSkipCustom": "Skipped: custom thumbnail exists", + "groupUnavailable": "Skipped: could not verify", + "groupNoTargets": "There are no eligible thumbnails in the current asset group.", + "groupGenerating": "Generating asset-group thumbnails {current}/{total}…", + "groupComplete": "Asset-group thumbnails complete: {success} succeeded, {skip} skipped, {failed} failed.", "versionTitle": "Spine version", "reloadTitle": "Reload folder", "animationList": "Animation list", diff --git a/_locales/es_ES.json b/_locales/es_ES.json index fe13211..b0694fc 100644 --- a/_locales/es_ES.json +++ b/_locales/es_ES.json @@ -20,6 +20,19 @@ "backgroundTitle": "Fondo de cuadros de 50×50 que se desplaza y escala con el lienzo y participa en los modos de fusión", "thumbnail": "Usar como miniatura actual", "thumbnailTitle": "Usar el fotograma actual como miniatura personalizada de 400×400 de este elemento", + "groupThumbnail": "Generar miniaturas del grupo actual…", + "groupThumbnailTitle": "Revisar el grupo de recursos Spine actual y generar miniaturas por lotes", + "groupDialogTitle": "Generar miniaturas del grupo actual", + "groupDialogSummary": "Se generarán {generate} y se omitirán {skip}.", + "groupDialogNote": "Solo se actualizarán los elementos indicados abajo. Los elementos con miniaturas personalizadas siempre se omiten.", + "cancel": "Cancelar", + "groupConfirm": "Generar", + "groupWillGenerate": "Se generará", + "groupSkipCustom": "Omitido: ya tiene miniatura personalizada", + "groupUnavailable": "Omitido: no se pudo verificar", + "groupNoTargets": "No hay miniaturas disponibles para generar en el grupo actual.", + "groupGenerating": "Generando miniaturas {current}/{total}…", + "groupComplete": "Completado: {success} correctas, {skip} omitidas y {failed} fallidas.", "versionTitle": "Versión de Spine", "reloadTitle": "Recargar carpeta", "animationList": "Lista de animaciones", diff --git a/_locales/ja_JP.json b/_locales/ja_JP.json index b81364d..574c0bf 100644 --- a/_locales/ja_JP.json +++ b/_locales/ja_JP.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 のチェッカー背景。キャンバスの移動・拡大に追従し、ブレンドモードにも参加します", "thumbnail": "現在の項目のサムネイルに設定", "thumbnailTitle": "現在のフレームをこの項目の 400×400 カスタムサムネイルに設定", + "groupThumbnail": "現在のアセットグループのサムネイルを生成…", + "groupThumbnailTitle": "現在の Spine アセットグループを確認して一括生成", + "groupDialogTitle": "現在のアセットグループのサムネイルを生成", + "groupDialogSummary": "{generate} 件を生成し、{skip} 件をスキップします。", + "groupDialogNote": "下に明示された項目だけを更新します。カスタムサムネイルがある項目は必ずスキップします。", + "cancel": "キャンセル", + "groupConfirm": "生成", + "groupWillGenerate": "生成対象", + "groupSkipCustom": "スキップ:カスタムサムネイルあり", + "groupUnavailable": "スキップ:検証できません", + "groupNoTargets": "現在のアセットグループに生成可能なサムネイルはありません。", + "groupGenerating": "アセットグループのサムネイルを生成中 {current}/{total}…", + "groupComplete": "完了:成功 {success}、スキップ {skip}、失敗 {failed}。", "versionTitle": "Spine バージョン", "reloadTitle": "フォルダーを再読み込み", "animationList": "アニメーション一覧", diff --git a/_locales/ko_KR.json b/_locales/ko_KR.json index 40dbb7a..4d86323 100644 --- a/_locales/ko_KR.json +++ b/_locales/ko_KR.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 체커 배경. 캔버스 이동·확대를 따라가며 블렌드 모드에도 참여합니다", "thumbnail": "현재 항목 썸네일로 설정", "thumbnailTitle": "현재 프레임을 이 항목의 400×400 사용자 지정 썸네일로 설정", + "groupThumbnail": "현재 자산 그룹 썸네일 생성…", + "groupThumbnailTitle": "현재 Spine 자산 그룹을 확인한 후 일괄 생성", + "groupDialogTitle": "현재 자산 그룹 썸네일 생성", + "groupDialogSummary": "{generate}개를 생성하고 {skip}개를 건너뜁니다.", + "groupDialogNote": "아래에 명시된 항목만 업데이트합니다. 기존 사용자 지정 썸네일이 있는 항목은 항상 건너뜁니다.", + "cancel": "취소", + "groupConfirm": "생성", + "groupWillGenerate": "생성 예정", + "groupSkipCustom": "건너뛰: 사용자 지정 썸네일 있음", + "groupUnavailable": "건너뛰: 확인할 수 없음", + "groupNoTargets": "현재 자산 그룹에 생성할 수 있는 썸네일이 없습니다.", + "groupGenerating": "자산 그룹 썸네일 생성 중 {current}/{total}…", + "groupComplete": "완료: 성공 {success}, 건너뛰 {skip}, 실패 {failed}.", "versionTitle": "Spine 버전", "reloadTitle": "폴더 다시 불러오기", "animationList": "애니메이션 목록", diff --git a/_locales/ru_RU.json b/_locales/ru_RU.json index cdda9be..6e0b32b 100644 --- a/_locales/ru_RU.json +++ b/_locales/ru_RU.json @@ -20,6 +20,19 @@ "backgroundTitle": "Шахматный фон 50×50: следует за сдвигом и масштабом холста и участвует в режимах смешивания", "thumbnail": "Сделать миниатюрой элемента", "thumbnailTitle": "Установить текущий кадр как пользовательскую миниатюру 400×400 для этого элемента", + "groupThumbnail": "Создать миниатюры для текущей группы…", + "groupThumbnailTitle": "Проверить группу Spine и создать миниатюры пакетно", + "groupDialogTitle": "Создать миниатюры для текущей группы", + "groupDialogSummary": "Будет создано: {generate}; пропущено: {skip}.", + "groupDialogNote": "Будут обновлены только явно указанные ниже элементы. Элементы с пользовательскими миниатюрами всегда пропускаются.", + "cancel": "Отмена", + "groupConfirm": "Создать", + "groupWillGenerate": "Будет создано", + "groupSkipCustom": "Пропущено: есть своя миниатюра", + "groupUnavailable": "Пропущено: не удалось проверить", + "groupNoTargets": "В текущей группе нет подходящих миниатюр.", + "groupGenerating": "Создание миниатюр {current}/{total}…", + "groupComplete": "Готово: {success} успешно, {skip} пропущено, {failed} с ошибкой.", "versionTitle": "Версия Spine", "reloadTitle": "Перезагрузить папку", "animationList": "Список анимаций", diff --git a/_locales/zh_CN.json b/_locales/zh_CN.json index 45090c0..d019130 100644 --- a/_locales/zh_CN.json +++ b/_locales/zh_CN.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 方格背景,随画布移动和缩放,并参与混合模式", "thumbnail": "设为当前素材缩略图", "thumbnailTitle": "将当前帧设为当前素材的 400×400 自定义缩略图", + "groupThumbnail": "为当前资源组生成缩略图…", + "groupThumbnailTitle": "列出当前 Spine 资源组,确认后批量生成缩略图", + "groupDialogTitle": "为当前资源组生成缩略图", + "groupDialogSummary": "将生成 {generate} 项,跳过 {skip} 项。", + "groupDialogNote": "只会更新下列明确列出的素材;已有自定义缩略图的素材会自动跳过。", + "cancel": "取消", + "groupConfirm": "确认生成", + "groupWillGenerate": "将生成", + "groupSkipCustom": "跳过:已有自定义缩略图", + "groupUnavailable": "跳过:无法验证", + "groupNoTargets": "当前资源组没有可生成的缩略图。", + "groupGenerating": "正在生成资源组缩略图 {current}/{total}…", + "groupComplete": "资源组缩略图已完成:成功 {success},跳过 {skip},失败 {failed}。", "versionTitle": "Spine 版本", "reloadTitle": "重新加载目录", "animationList": "动画列表", diff --git a/_locales/zh_TW.json b/_locales/zh_TW.json index d8863f8..08395d6 100644 --- a/_locales/zh_TW.json +++ b/_locales/zh_TW.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 方格背景,隨畫布移動和縮放,並參與混合模式", "thumbnail": "設為目前素材縮圖", "thumbnailTitle": "將目前影格設為目前素材的 400×400 自訂縮圖", + "groupThumbnail": "為目前資源組產生縮圖…", + "groupThumbnailTitle": "列出目前 Spine 資源組,確認後批次產生縮圖", + "groupDialogTitle": "為目前資源組產生縮圖", + "groupDialogSummary": "將產生 {generate} 項,跳過 {skip} 項。", + "groupDialogNote": "只會更新下列明確列出的素材;已有自訂縮圖的素材會自動跳過。", + "cancel": "取消", + "groupConfirm": "確認產生", + "groupWillGenerate": "將產生", + "groupSkipCustom": "跳過:已有自訂縮圖", + "groupUnavailable": "跳過:無法驗證", + "groupNoTargets": "目前資源組沒有可產生的縮圖。", + "groupGenerating": "正在產生資源組縮圖 {current}/{total}…", + "groupComplete": "資源組縮圖已完成:成功 {success},跳過 {skip},失敗 {failed}。", "versionTitle": "Spine 版本", "reloadTitle": "重新載入目錄", "animationList": "動畫清單", diff --git a/release/SpineViewer.eagleplugin b/release/SpineViewer.eagleplugin index bafcd6e..9f26253 100644 Binary files a/release/SpineViewer.eagleplugin and b/release/SpineViewer.eagleplugin differ diff --git a/release/UNIVERSAL_SpineViewer/README.md b/release/UNIVERSAL_SpineViewer/README.md index c14782f..105d7b4 100644 --- a/release/UNIVERSAL_SpineViewer/README.md +++ b/release/UNIVERSAL_SpineViewer/README.md @@ -7,13 +7,13 @@ Eagle 的离线 Spine 骨骼动画预览插件,支持 Spine 3.4–4.3,适用 1. 将同一套骨骼文件(`.skel` / `.skel.bytes` / Spine `.json`)、图集(`.atlas` / `.atlas.txt`)和配套贴图一起导入 Eagle,建议放在同一个 Eagle 文件夹内。 2. 打开骨骼或图集文件即可预览动画,并可切换动画、皮肤、速度、循环、背景和 PMA。 3. 插件不接管导入阶段的缩略图,由 Eagle 自身处理。 -4. 打开预览后,可点击“设为当前素材缩略图”,把当前帧手动设为当前素材的自定义缩略图。已有自定义缩略图时会先询问是否替换。 +4. 打开预览后,原有按钮可把当前帧设为当前素材的自定义缩略图。其左侧的“为当前资源组生成缩略图…”会先明确列出受影响的骨骼、atlas 和贴图,得到确认后才批量生成,并始终跳过已有自定义缩略图的素材。 ## 安全与隐私 - Atlas 贴图只允许安全的相对路径;绝对路径、`..`、盘符、UNC、URI 和越界符号链接会被拒绝。 - 跨素材配对只使用当前 Eagle 素材库中已枚举并验证的文件。 -- 手动设置缩略图只作用于当前素材,不会自动改写其他素材。 +- 单素材按钮只作用于当前素材。资源组按钮会先列出全部受影响素材并要求确认,且不会覆盖已有自定义缩略图。 ## 多语言 diff --git a/release/UNIVERSAL_SpineViewer/_locales/de_DE.json b/release/UNIVERSAL_SpineViewer/_locales/de_DE.json index 4c49c1e..3f06cac 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/de_DE.json +++ b/release/UNIVERSAL_SpineViewer/_locales/de_DE.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50-Schachbrett, das mit der Leinwand verschoben und skaliert wird und an Blend-Modi teilnimmt", "thumbnail": "Als aktuelles Vorschaubild setzen", "thumbnailTitle": "Aktuellen Frame als benutzerdefiniertes 400×400-Vorschaubild dieses Elements setzen", + "groupThumbnail": "Vorschaubilder für aktuelle Ressourcengruppe erstellen…", + "groupThumbnailTitle": "Aktuelle Spine-Ressourcengruppe prüfen und Vorschaubilder gesammelt erstellen", + "groupDialogTitle": "Vorschaubilder für aktuelle Ressourcengruppe erstellen", + "groupDialogSummary": "{generate} werden erstellt, {skip} werden übersprungen.", + "groupDialogNote": "Nur die unten aufgeführten Elemente werden aktualisiert. Elemente mit eigenen Vorschaubildern werden immer übersprungen.", + "cancel": "Abbrechen", + "groupConfirm": "Erstellen", + "groupWillGenerate": "Wird erstellt", + "groupSkipCustom": "Übersprungen: eigenes Vorschaubild vorhanden", + "groupUnavailable": "Übersprungen: nicht verifizierbar", + "groupNoTargets": "In der aktuellen Ressourcengruppe gibt es keine geeigneten Vorschaubilder.", + "groupGenerating": "Vorschaubilder werden erstellt {current}/{total}…", + "groupComplete": "Fertig: {success} erfolgreich, {skip} übersprungen, {failed} fehlgeschlagen.", "versionTitle": "Spine-Version", "reloadTitle": "Ordner neu laden", "animationList": "Animationsliste", diff --git a/release/UNIVERSAL_SpineViewer/_locales/en.json b/release/UNIVERSAL_SpineViewer/_locales/en.json index 0d44342..de4fc86 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/en.json +++ b/release/UNIVERSAL_SpineViewer/_locales/en.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 checkerboard that pans and zooms with the canvas and participates in blend modes", "thumbnail": "Set current item thumbnail", "thumbnailTitle": "Set the current frame as this item's 400×400 custom thumbnail", + "groupThumbnail": "Generate thumbnails for current asset group…", + "groupThumbnailTitle": "Review the current Spine asset group, then generate thumbnails in a batch", + "groupDialogTitle": "Generate thumbnails for current asset group", + "groupDialogSummary": "Generate {generate} item(s) and skip {skip} item(s).", + "groupDialogNote": "Only the items explicitly listed below will be updated. Items with existing custom thumbnails are always skipped.", + "cancel": "Cancel", + "groupConfirm": "Generate", + "groupWillGenerate": "Will generate", + "groupSkipCustom": "Skipped: custom thumbnail exists", + "groupUnavailable": "Skipped: could not verify", + "groupNoTargets": "There are no eligible thumbnails in the current asset group.", + "groupGenerating": "Generating asset-group thumbnails {current}/{total}…", + "groupComplete": "Asset-group thumbnails complete: {success} succeeded, {skip} skipped, {failed} failed.", "versionTitle": "Spine version", "reloadTitle": "Reload folder", "animationList": "Animation list", diff --git a/release/UNIVERSAL_SpineViewer/_locales/es_ES.json b/release/UNIVERSAL_SpineViewer/_locales/es_ES.json index fe13211..b0694fc 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/es_ES.json +++ b/release/UNIVERSAL_SpineViewer/_locales/es_ES.json @@ -20,6 +20,19 @@ "backgroundTitle": "Fondo de cuadros de 50×50 que se desplaza y escala con el lienzo y participa en los modos de fusión", "thumbnail": "Usar como miniatura actual", "thumbnailTitle": "Usar el fotograma actual como miniatura personalizada de 400×400 de este elemento", + "groupThumbnail": "Generar miniaturas del grupo actual…", + "groupThumbnailTitle": "Revisar el grupo de recursos Spine actual y generar miniaturas por lotes", + "groupDialogTitle": "Generar miniaturas del grupo actual", + "groupDialogSummary": "Se generarán {generate} y se omitirán {skip}.", + "groupDialogNote": "Solo se actualizarán los elementos indicados abajo. Los elementos con miniaturas personalizadas siempre se omiten.", + "cancel": "Cancelar", + "groupConfirm": "Generar", + "groupWillGenerate": "Se generará", + "groupSkipCustom": "Omitido: ya tiene miniatura personalizada", + "groupUnavailable": "Omitido: no se pudo verificar", + "groupNoTargets": "No hay miniaturas disponibles para generar en el grupo actual.", + "groupGenerating": "Generando miniaturas {current}/{total}…", + "groupComplete": "Completado: {success} correctas, {skip} omitidas y {failed} fallidas.", "versionTitle": "Versión de Spine", "reloadTitle": "Recargar carpeta", "animationList": "Lista de animaciones", diff --git a/release/UNIVERSAL_SpineViewer/_locales/ja_JP.json b/release/UNIVERSAL_SpineViewer/_locales/ja_JP.json index b81364d..574c0bf 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/ja_JP.json +++ b/release/UNIVERSAL_SpineViewer/_locales/ja_JP.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 のチェッカー背景。キャンバスの移動・拡大に追従し、ブレンドモードにも参加します", "thumbnail": "現在の項目のサムネイルに設定", "thumbnailTitle": "現在のフレームをこの項目の 400×400 カスタムサムネイルに設定", + "groupThumbnail": "現在のアセットグループのサムネイルを生成…", + "groupThumbnailTitle": "現在の Spine アセットグループを確認して一括生成", + "groupDialogTitle": "現在のアセットグループのサムネイルを生成", + "groupDialogSummary": "{generate} 件を生成し、{skip} 件をスキップします。", + "groupDialogNote": "下に明示された項目だけを更新します。カスタムサムネイルがある項目は必ずスキップします。", + "cancel": "キャンセル", + "groupConfirm": "生成", + "groupWillGenerate": "生成対象", + "groupSkipCustom": "スキップ:カスタムサムネイルあり", + "groupUnavailable": "スキップ:検証できません", + "groupNoTargets": "現在のアセットグループに生成可能なサムネイルはありません。", + "groupGenerating": "アセットグループのサムネイルを生成中 {current}/{total}…", + "groupComplete": "完了:成功 {success}、スキップ {skip}、失敗 {failed}。", "versionTitle": "Spine バージョン", "reloadTitle": "フォルダーを再読み込み", "animationList": "アニメーション一覧", diff --git a/release/UNIVERSAL_SpineViewer/_locales/ko_KR.json b/release/UNIVERSAL_SpineViewer/_locales/ko_KR.json index 40dbb7a..4d86323 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/ko_KR.json +++ b/release/UNIVERSAL_SpineViewer/_locales/ko_KR.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 체커 배경. 캔버스 이동·확대를 따라가며 블렌드 모드에도 참여합니다", "thumbnail": "현재 항목 썸네일로 설정", "thumbnailTitle": "현재 프레임을 이 항목의 400×400 사용자 지정 썸네일로 설정", + "groupThumbnail": "현재 자산 그룹 썸네일 생성…", + "groupThumbnailTitle": "현재 Spine 자산 그룹을 확인한 후 일괄 생성", + "groupDialogTitle": "현재 자산 그룹 썸네일 생성", + "groupDialogSummary": "{generate}개를 생성하고 {skip}개를 건너뜁니다.", + "groupDialogNote": "아래에 명시된 항목만 업데이트합니다. 기존 사용자 지정 썸네일이 있는 항목은 항상 건너뜁니다.", + "cancel": "취소", + "groupConfirm": "생성", + "groupWillGenerate": "생성 예정", + "groupSkipCustom": "건너뛰: 사용자 지정 썸네일 있음", + "groupUnavailable": "건너뛰: 확인할 수 없음", + "groupNoTargets": "현재 자산 그룹에 생성할 수 있는 썸네일이 없습니다.", + "groupGenerating": "자산 그룹 썸네일 생성 중 {current}/{total}…", + "groupComplete": "완료: 성공 {success}, 건너뛰 {skip}, 실패 {failed}.", "versionTitle": "Spine 버전", "reloadTitle": "폴더 다시 불러오기", "animationList": "애니메이션 목록", diff --git a/release/UNIVERSAL_SpineViewer/_locales/ru_RU.json b/release/UNIVERSAL_SpineViewer/_locales/ru_RU.json index cdda9be..6e0b32b 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/ru_RU.json +++ b/release/UNIVERSAL_SpineViewer/_locales/ru_RU.json @@ -20,6 +20,19 @@ "backgroundTitle": "Шахматный фон 50×50: следует за сдвигом и масштабом холста и участвует в режимах смешивания", "thumbnail": "Сделать миниатюрой элемента", "thumbnailTitle": "Установить текущий кадр как пользовательскую миниатюру 400×400 для этого элемента", + "groupThumbnail": "Создать миниатюры для текущей группы…", + "groupThumbnailTitle": "Проверить группу Spine и создать миниатюры пакетно", + "groupDialogTitle": "Создать миниатюры для текущей группы", + "groupDialogSummary": "Будет создано: {generate}; пропущено: {skip}.", + "groupDialogNote": "Будут обновлены только явно указанные ниже элементы. Элементы с пользовательскими миниатюрами всегда пропускаются.", + "cancel": "Отмена", + "groupConfirm": "Создать", + "groupWillGenerate": "Будет создано", + "groupSkipCustom": "Пропущено: есть своя миниатюра", + "groupUnavailable": "Пропущено: не удалось проверить", + "groupNoTargets": "В текущей группе нет подходящих миниатюр.", + "groupGenerating": "Создание миниатюр {current}/{total}…", + "groupComplete": "Готово: {success} успешно, {skip} пропущено, {failed} с ошибкой.", "versionTitle": "Версия Spine", "reloadTitle": "Перезагрузить папку", "animationList": "Список анимаций", diff --git a/release/UNIVERSAL_SpineViewer/_locales/zh_CN.json b/release/UNIVERSAL_SpineViewer/_locales/zh_CN.json index 45090c0..d019130 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/zh_CN.json +++ b/release/UNIVERSAL_SpineViewer/_locales/zh_CN.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 方格背景,随画布移动和缩放,并参与混合模式", "thumbnail": "设为当前素材缩略图", "thumbnailTitle": "将当前帧设为当前素材的 400×400 自定义缩略图", + "groupThumbnail": "为当前资源组生成缩略图…", + "groupThumbnailTitle": "列出当前 Spine 资源组,确认后批量生成缩略图", + "groupDialogTitle": "为当前资源组生成缩略图", + "groupDialogSummary": "将生成 {generate} 项,跳过 {skip} 项。", + "groupDialogNote": "只会更新下列明确列出的素材;已有自定义缩略图的素材会自动跳过。", + "cancel": "取消", + "groupConfirm": "确认生成", + "groupWillGenerate": "将生成", + "groupSkipCustom": "跳过:已有自定义缩略图", + "groupUnavailable": "跳过:无法验证", + "groupNoTargets": "当前资源组没有可生成的缩略图。", + "groupGenerating": "正在生成资源组缩略图 {current}/{total}…", + "groupComplete": "资源组缩略图已完成:成功 {success},跳过 {skip},失败 {failed}。", "versionTitle": "Spine 版本", "reloadTitle": "重新加载目录", "animationList": "动画列表", diff --git a/release/UNIVERSAL_SpineViewer/_locales/zh_TW.json b/release/UNIVERSAL_SpineViewer/_locales/zh_TW.json index d8863f8..08395d6 100644 --- a/release/UNIVERSAL_SpineViewer/_locales/zh_TW.json +++ b/release/UNIVERSAL_SpineViewer/_locales/zh_TW.json @@ -20,6 +20,19 @@ "backgroundTitle": "50×50 方格背景,隨畫布移動和縮放,並參與混合模式", "thumbnail": "設為目前素材縮圖", "thumbnailTitle": "將目前影格設為目前素材的 400×400 自訂縮圖", + "groupThumbnail": "為目前資源組產生縮圖…", + "groupThumbnailTitle": "列出目前 Spine 資源組,確認後批次產生縮圖", + "groupDialogTitle": "為目前資源組產生縮圖", + "groupDialogSummary": "將產生 {generate} 項,跳過 {skip} 項。", + "groupDialogNote": "只會更新下列明確列出的素材;已有自訂縮圖的素材會自動跳過。", + "cancel": "取消", + "groupConfirm": "確認產生", + "groupWillGenerate": "將產生", + "groupSkipCustom": "跳過:已有自訂縮圖", + "groupUnavailable": "跳過:無法驗證", + "groupNoTargets": "目前資源組沒有可產生的縮圖。", + "groupGenerating": "正在產生資源組縮圖 {current}/{total}…", + "groupComplete": "資源組縮圖已完成:成功 {success},跳過 {skip},失敗 {failed}。", "versionTitle": "Spine 版本", "reloadTitle": "重新載入目錄", "animationList": "動畫清單", diff --git a/release/UNIVERSAL_SpineViewer/viewer/spine.css b/release/UNIVERSAL_SpineViewer/viewer/spine.css index 621d931..6bc7685 100644 --- a/release/UNIVERSAL_SpineViewer/viewer/spine.css +++ b/release/UNIVERSAL_SpineViewer/viewer/spine.css @@ -75,6 +75,36 @@ } button:hover { background: var(--border); } button.active { background: var(--accent); color: #fff; border-color: var(--accent); } + button.primary { background: var(--accent); color: #fff; border-color: var(--accent); } + button:disabled { cursor: default; opacity: .55; } + .thumb-dialog { + position: absolute; inset: 0; z-index: 40; display: flex; + align-items: center; justify-content: center; padding: 24px; + background: rgba(0, 0, 0, .58); + } + .thumb-dialog.hidden { display: none; } + .thumb-dialog-card { + width: min(620px, 92vw); max-height: min(680px, 88vh); display: flex; + flex-direction: column; gap: 12px; padding: 18px; + background: var(--panel); border: 1px solid var(--border); border-radius: 10px; + box-shadow: 0 16px 48px rgba(0, 0, 0, .45); + } + .thumb-dialog-title { font-size: 16px; font-weight: 600; } + .thumb-dialog-summary, .thumb-dialog-note { color: var(--text-dim); line-height: 1.5; } + .thumb-dialog-list { + min-height: 60px; overflow: auto; border: 1px solid var(--border); + border-radius: 6px; background: var(--bg); + } + .thumb-dialog-row { + display: flex; align-items: center; gap: 10px; padding: 8px 10px; + border-bottom: 1px solid var(--border); + } + .thumb-dialog-row:last-child { border-bottom: 0; } + .thumb-dialog-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + .thumb-dialog-state { flex: none; color: var(--accent); font-size: 12px; } + .thumb-dialog-row.skipped .thumb-dialog-name, + .thumb-dialog-row.skipped .thumb-dialog-state { color: var(--text-dim); } + .thumb-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; } #stage { position: absolute; inset: 0; display: flex; overflow: hidden; } #animationPanel { position: absolute; diff --git a/release/UNIVERSAL_SpineViewer/viewer/spine.html b/release/UNIVERSAL_SpineViewer/viewer/spine.html index 93a1acc..232015c 100644 --- a/release/UNIVERSAL_SpineViewer/viewer/spine.html +++ b/release/UNIVERSAL_SpineViewer/viewer/spine.html @@ -25,6 +25,7 @@ 背景
+ @@ -58,6 +59,18 @@ 0.00 / 0.00 秒 · 0 / 0 帧 +