diff --git a/README.en.md b/README.en.md index 534aca8a..fab52f26 100644 --- a/README.en.md +++ b/README.en.md @@ -8,7 +8,7 @@ **Bring ok-script's language keys, OCR fixes, templates, skills and task data straight into your VS Code workflow.** -Language key completion · OCR fix hints · Template browsing · Task launching · Character skill management +Language key completion · OCR fix hints · Run / Parameters / Resources (inbox→draft→published) · Character skill management [![VS Code Marketplace](https://img.shields.io/badge/VS%20Code%20Marketplace-ok--script%20Toolkit-007ACC?logo=visualstudiocode&logoColor=white)](https://marketplace.visualstudio.com/items?itemName=AliceJump.ok-script-toolkit) [![JetBrains Marketplace](https://img.shields.io/badge/JetBrains%20Marketplace-ok--script%20Toolkit-000000?logo=jetbrains&logoColor=white)](https://plugins.jetbrains.com/plugin/34091-ok-script-toolkit) @@ -23,7 +23,7 @@ Language key completion · OCR fix hints · Template browsing · Task launching --- -A VS Code extension that brings ok-script language keys, OCR fixes, templates, skill effects, and task data directly into your Python development workflow. It also includes built-in template browsing, task launching, and character skill management panels. +A VS Code extension that brings ok-script language keys, OCR fixes, templates, skill effects, and task data directly into your Python development workflow. It also includes a **Run** tree, **Parameters** inspector, unified **Resources** workbench (inbox / draft / published), and Character & Skill Manager. > [!TIP] > The demo images at the beginning of each feature section below are clickable — if the GIFs don't load, click the links to view them. @@ -53,7 +53,7 @@ See [feature and documentation parity](docs/feature-parity.en.md) for current ho | [Code development assistance](#code-development-assistance) | Complete and explain `self.lang`, OCR regex, and skill effect IDs in the editor | | [Template management](#template-management) | Browse templates in a grid, click to insert `fL.`, with thumbnail preview | | [Temp screenshots](#temp-screenshots) | 10-slot scratch area in the activity bar — box-select to copy normalized coordinates | -| [Task launcher](#task-launcher) | Auto-generate parameter forms from `config.py` and run tasks, without writing to the target project's config | +| [Run](#run-task-tree) | Auto-generate parameter forms from `config.py` and run tasks, without writing to the target project's config | | [Character skill management](#character-skill-management) | Visual management and diagnostics for characters / skills / effects / enhancement groups | | [Multi-language support](#multi-language-support) | UI supports 6 languages; data hints follow the target project | @@ -77,15 +77,19 @@ When editing Python code, the extension automatically detects ok-script-specific ### Template Management

- Template panel: search, thumbnail preview, and quick insert + Resource Preview: search, thumbnail preview, and quick insert

-- **Template panel**: Open via the sidebar icon or `Ctrl+Alt+T` shortcut (requires focus on a Python editor). Displays all workspace templates in a thumbnail grid with real-time name search and filtering. -- **Quick insert**: Click a card to insert `fL.` at the editor cursor, double-click to copy to clipboard, or use **View Original** to open the source. VS Code template and box galleries use a shared 500 ms card double-click window; clicks beyond that window are independent single clicks. The insert, copy and source buttons act immediately. +- **Resource Preview**: Open via the sidebar icon or `Ctrl+Alt+T` shortcut (requires focus on a Python editor). Displays published template / box / point resources in a thumbnail grid with real-time name search and filtering. When there is nothing to show, it lists the COCO paths it actually checked and offers an **Open Annotation Management** button. +- **Quick insert**: Thumbnail cards behave the same in Resource Preview, Annotation Management and Temp Screenshots — **click = select**, **double-click / Enter = primary action** (in Resource Preview: insert `fL.` at the editor cursor), `Ctrl+C` copies the reference; the insert / copy / view-original buttons on the card act immediately. Cards are reachable with Tab and move with the arrow keys / Home / End. - **Template code hints**: Type `fL.` or `FeatureList.` to complete template names with size info. Hover shows thumbnail preview, dimensions, and source info. -- You can also open a larger grid view in the editor area via the command **ok-script Toolkit: Open Template Panel in Editor**. -- Supports both sidebar (template panel and template asset views) and large editor window browsing modes. -- **Swap annotations**: in the template assets panel (annotation manager), the **⇄** button at the bottom-right of a thumbnail card swaps that image's whole annotation set with another image in the same list — the fix for "annotated the wrong image / images are in the wrong order". The target is picked from thumbnails (template names are mostly numeric, so names alone are not enough). When the two images differ in size, box coordinates are **scaled proportionally** and the confirmation dialog spells out both sizes. The swap is written in one go and **cannot be undone**, so it always asks before saving. +- You can also open a larger grid view in the editor area via the command **ok-script Toolkit: Open Resource Preview in Editor**. +- Supports both sidebar (Resource Preview and Annotation Management views) and large editor window browsing modes. +- **Reveal / Find References**: hovering `fL.xxx` in Python shows **Reveal in Resources** and **Find References** links under the preview (only these two extension commands are trusted). **Find Template References…** (editor context menu or Command Palette) searches workspace Python files for `fL.xxx`, `self.pos.xxx` and string keys `"xxx"`, lists them in a QuickPick and jumps on Enter (comment lines skipped). +- **Explorer "Open with Annotation Editor"**: shown only on `.png/.jpg/.jpeg/.webp`. The image must already be registered in Annotation Management. +- **Publish preview**: after choosing publish options and before anything is written, a read-only list shows the files to be written and templates that are new / overwritten / removed from published (compared by name; publishing re-crops and re-packs, so coordinates are not comparable). Enter on **Publish** writes; Esc writes nothing. +- **Annotation Management**: double-click / Enter / `E` opens the annotation editor, `Delete` deletes (after a confirmation). The delete button sits alone in the card's top-right corner, apart from view / swap. The **Open Annotation Editor…** command lets you pick an image directly. +- **Swap annotations**: in Annotation Management, the **Swap annotations** button (codicon `arrow-swap`) at the bottom-right of a thumbnail card swaps that image's whole annotation set with another image in the same list — the fix for "annotated the wrong image / images are in the wrong order". The target is picked from thumbnails (template names are mostly numeric, so names alone are not enough). When the two images differ in size, box coordinates are **scaled proportionally** and the confirmation dialog spells out both sizes. The swap is written in one go and always asks before saving; the completion notification has an **Undo** button that restores both images' original annotations as long as neither image changed since. ```python self.wait_click_feature(feature=fL.give_gift, time_out=10) @@ -110,20 +114,20 @@ Box resource management reuses source annotation images and the COCO editor. Edi | Enqueue | `Ctrl+V` to paste a clipboard image, click "Screenshot" to capture the game window, or drag image files in directly | | 0.1s carousel | Cycles through all screenshots at 100ms intervals, useful for observing buttons with movement boundaries | | Box-select copy | In "Box Select Coords" mode, box-select to copy `x,y,tox,toy` normalized coordinates to the clipboard | -| Import to annotation | The **→** button on the top-right of a thumbnail card imports that shot into the annotation manager (copies into `ok_templates` and registers COCO) | +| Import to annotation | The **Add to Annotation Management** button (codicon `arrow-right`) at the bottom-right of a thumbnail card imports that shot into Annotation Management (copies into `ok_templates` and registers COCO); delete is in the top-right corner | Details: - The carousel and box-select are independent — the carousel keeps playing during box-select, and the selection box stays in place after release, making it easy to compare and fine-tune repeatedly. - Normalized coordinates are scaled to 0..1 based on image width/height, with 4 decimal places. Scroll zoom and middle-click/blank-area drag panning are also supported. - After box-select, the **box remains and can be adjusted** (with 8-directional handles and full drag support, same interaction as the template annotation box): **coordinates are re-copied on creation and after each adjustment**; the box itself is never written to annotation data or saved to disk. Click outside the box (beyond the frame and handles) to clear it. -- Note: Cross-Webview drag-and-drop is not available in VS Code (each webview is an iframe with a different origin, `dataTransfer` is blocked), so the **→** button is the reliable entry point for import. +- Note: Cross-Webview drag-and-drop is not available in VS Code (each webview is an iframe with a different origin, `dataTransfer` is blocked), so the **Add to Annotation Management** button is the reliable entry point for import. - The **annotation editor** also supports this mode: click "Coords (C)" in the toolbar or press `C` to enter box-select mode, copying the same `x,y,tox,toy` normalized coordinates without creating an annotation box or modifying COCO. The resulting box also has handles for fine-tuning, with coordinates re-copied after each adjustment; clicking outside the box in non-interactive areas clears it. Override with `copyCoords` in `okScriptToolkit.annotationKeybindings`. -### Task Launcher +### Run (Task Tree)

- Task launcher: parameter form and run log + Console: parameter form and run log

- Automatically parses all one-time tasks and trigger tasks from the target project's `src/config.py` / `config.py`, generating complete parameter configuration forms. @@ -137,7 +141,10 @@ Details: - **No target-project config pollution**: While the executor runs, all ok-framework reads/writes to `configs/` and screenshots are redirected into the workspace sandbox `.vscode/ok-script-toolkit/`, so **the target project's config files and screenshots stay untouched** (`devices.json` is bridged by copy so the game connection is reused). Tweak parameters freely while debugging without dirtying the project. - The executor can be paused/resumed at any time (globally suspending polling and tasks), and you can "stop the current task" without closing the executor. Run logs are output to a dedicated output channel. - **Global config takeover**: the target project's global config groups (visible groups of the ok framework's GlobalConfig) are parsed by the probe as well and shown as parameter snapshots in the console's "Config" segment — edits save instantly and can be reset to defaults; changes are pushed live to the running executor via `gparams`, and the full snapshot is injected as `OK_TOOLKIT_GCONFIG` at executor launch. Still sandbox-only — the target project's config is never touched. -- **Console view**: the task launcher and toolbox live together in the "ok-script console" with four segments (Tasks / Game / Config / Accounts); a health bar in the header reflects executor state in real time, and when idle the detail panel shows the run center (current task / execution queue / trigger polling). Task rows reveal a read-only summary on hover. +- **Console view**: task running and the game connection live together in the **Console** with four segments (Tasks / Game / Config / Accounts); a health bar in the header reflects executor state in real time, and when idle the detail panel shows the run center (current task / execution queue / trigger polling). Task rows reveal a read-only summary on hover. In a narrow sidebar the segment navigation collapses to an icon rail (≤640px) or a top segmented bar (≤480px). +- **Status bar and commands**: the status bar shows the executor state (idle / starting / running task + queued count / paused) and opens the Console on click. The Console view title bar and the Command Palette offer Run Task… / Start / Pause / Resume / Stop Current Task / Stop Executor / Show Logs / Connect Game, shown or hidden by executor state. The number of running + queued tasks appears as the view badge. +- **Errors in place**: a missing project path, a missing Python interpreter or an executor crash is shown in the Console banner with next-step buttons (Set Project Path / Set Python Path / Show Logs / Retry). Only when the Console is hidden does it fall back to a notification (with the same buttons). +- The **Character & Skill Manager** entry lives in the Config segment. It is hidden, together with its Command Palette command, when no character data is detected (neither `characterMasterFile` nor `characterSkillsDirectory` exists). ### Character Skill Management @@ -152,8 +159,8 @@ Run the command **ok-script Toolkit: Open Character Skill Management Panel** to ### Multi-language Support -- The extension UI (notifications, output channel, hover, template panel, task launcher, toolbox, and character skill management panel) supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and Spanish, defaulting to the VS Code display language. -- The sidebar is split into three independent activity bar containers: **ok-script Toolbox** (toolbox + task launcher), **ok-script Templates** (template panel + template assets), and **ok-script Temp Shots**. +- The extension UI (notifications, output channel, hover, Resource Preview, Annotation Management, Console, and the Character & Skill Manager) supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and Spanish, defaulting to the VS Code display language. +- The sidebar is split into three independent activity bar containers: **ok-script Tools** (Console), **ok-script Resources** (Resource Preview + Annotation Management), and **ok-script Temp Shots**. UI icons use VS Code codicons throughout. - Language data in code hints always uses the target project's own locale and original protocol values, unaffected by the plugin UI language. > [!NOTE] @@ -184,6 +191,8 @@ See [DEVELOPMENT.en.md](DEVELOPMENT.en.md) for project structure, JetBrains vers ## Configuration +In the Settings UI the options are grouped into 5 categories: **ok-script: Code Hints**, **Resources & Annotation**, **Screenshots**, **Console & Tasks**, and **Character Data**. + | Setting | Default | Description | |---|---|---| | `okScriptToolkit.langDirectory` | `assets/lang` | lang JSON directory (relative to workspace root) | @@ -196,15 +205,15 @@ See [DEVELOPMENT.en.md](DEVELOPMENT.en.md) for project structure, JetBrains vers | `okScriptToolkit.labelEnumPath` | empty | Path of the generated `LabelEnum.py` (relative to workspace root, with or without `.py`); empty follows the project convention. Maps to `labelEnum.path` | | `okScriptToolkit.labelEnumName` | empty | Class name of the generated enum; empty derives it from the file name. Maps to `labelEnum.name`. ⚠️ Project code imports this class by name, so renaming it breaks those imports — you will be asked to confirm before an existing file is overwritten | | `okScriptToolkit.effectsFile` | `src/data/effects.py` | Skill effect ID definition file (`EffectType` enum + `EFFECT_DESCRIPTIONS`), relative to workspace root | -| `okScriptToolkit.okScriptProjectPath` | empty | ok-script project root for the task launcher; tries the current workspace when empty | -| `okScriptToolkit.okScriptPython` | empty | Python for the task launcher; prefers `/.venv/Scripts/python.exe` when empty | +| `okScriptToolkit.okScriptProjectPath` | empty | ok-script project root used by the Console to run tasks; tries the current workspace when empty | +| `okScriptToolkit.okScriptPython` | empty | Python used by the Console; prefers `/.venv/Scripts/python.exe` when empty | | `okScriptToolkit.captureMethod` | `auto` | Game window capture method: `auto` / `wgc` / `bitblt` / `foreground` | | `okScriptToolkit.characterProjectPath` | empty | Data project for the character skill management panel; uses `okScriptProjectPath` or current workspace when empty | | `okScriptToolkit.characterMasterFile` | `assets/data/characters.json` | Character master table JSON | | `okScriptToolkit.characterSkillsDirectory` | `assets/data/character_skills` | Character skills JSON directory | | `okScriptToolkit.characterLocaleFile` | `assets/lang/characters.json` | Character name multi-language JSON | | `okScriptToolkit.characterAvatarTemplateRegex` | `^battle[_-]?icon[_-]?` | Character avatar template name regex; uses the first capture group if present, otherwise the name after the matched prefix, matched against the character master table's English slug; defaults to `battleicon`, `battle_icon`, and `battle-icon` prefixes | -| `okScriptToolkit.okTemplatesDirectory` | `ok_templates` | ok_templates folder name (relative to workspace root), used by the template asset manager | +| `okScriptToolkit.okTemplatesDirectory` | `ok_templates` | ok_templates folder name (relative to workspace root), used by Annotation Management | | `okScriptToolkit.annotationKeybindings` | see defaults | Annotation editor keyboard shortcuts; values are key names with modifier prefixes like `ctrl+z` | ### Project Convention File `ok-script-toolkit.json` @@ -284,15 +293,22 @@ Command categories display as "ok-script 工具箱" / "ok-script Toolkit" depend | Command | Shortcut | Description | |---|---|---| -| `ok-script 工具箱: Open Template Gallery` | `Ctrl+Alt+T` (macOS `Cmd+Alt+T`, requires Python editor focus) | Focus the template sidebar view in the activity bar | -| `ok-script 工具箱: Open Template Gallery in Editor` | — | Open a large grid view in the editor area | -| `ok-script 工具箱: Open Task Launcher` | — | Focus the task launcher view in the activity bar | -| `ok-script 工具箱: Open Character & Skill Manager` | — | Open the character, skill, effect, enhancement group, and name localization management page | -| `ok-script 工具箱: Open Template Assets` | — | Open the template asset management panel in the editor area | -| `ok-script 工具箱: Open Annotation Editor` | — | Prompts to click an image in the template asset panel to enter the COCO annotation editor (the command itself does not open the editor directly) | -| `ok-script 工具箱: Open Temp Screenshots` | — | Focus the temp screenshots view in the activity bar | -| `ok-script 工具箱: Screenshot to Template Assets` | `Ctrl+Alt+S` (macOS `Cmd+Alt+S`) | Open the template asset panel and take a screenshot immediately. Reuses the panel's own screenshot action; the shot is registered into COCO. Rebindable in Keyboard Shortcuts | -| `ok-script 工具箱: Project Convention vs My Settings` | — | List the settings that take part in the precedence chain and show **which layer each effective value comes from** (my settings / project convention / built-in default). Rows you have overridden carry a Revert button that drops your override and goes back to the project convention. Exists to fix "once I changed it, I can never see what the team changed" | +| `ok-script Toolkit: Find Template References…` | — | Find `fL.xxx` / `self.pos.xxx` / `"xxx"` usages in workspace Python files and jump; also in the Python editor context menu | +| `ok-script Toolkit: Open with Annotation Editor` | — | Explorer image context menu (png/jpg/jpeg/webp only); without an argument it asks for an image | +| `ok-script Toolkit: Capture to Inbox` | `Ctrl+Alt+S` (macOS `Cmd+Alt+S`; also the Windows global hotkey) | Capture into the Resources inbox (temp shots). Same destination as the system-wide RegisterHotKey path | +| `ok-script Toolkit: Open Resource Preview` | `Ctrl+Alt+T` (macOS `Cmd+Alt+T`, requires Python editor focus) | Focus the Resource Preview view in the activity bar | +| `ok-script Toolkit: Open Resource Preview in Editor` | — | Open a large grid view in the editor area | +| `ok-script Toolkit: Open Console` | — | Focus the Console view in the activity bar | +| `ok-script Toolkit: Console: Run Task…` | — | Pick a loaded one-time task and queue it (starts the executor first if needed) | +| `ok-script Toolkit: Console: Start / Pause / Resume Executor, Stop Current Task, Stop Executor` | — | Same logic as the Console buttons; shown in the Command Palette and view title bar according to executor state | +| `ok-script Toolkit: Console: Refresh Tasks / Show Logs / Connect Game / Disconnect Game` | — | Re-parse the task list, open the output channel, connect or disconnect the game window | +| `ok-script Toolkit: Open Character & Skill Manager` | — | Open the character, skill, effect, enhancement group, and name localization management page; hidden in the Command Palette when no character data is detected | +| `ok-script Toolkit: Open Annotation Management` | — | Open Annotation Management in the editor area | +| `ok-script Toolkit: Open Annotation Editor…` | — | Pick an image from Annotation Management (with annotation counts) and open the COCO annotation editor directly | +| `ok-script Toolkit: Publish Resources…` | — | Open Annotation Management and go straight into publishing: choose Template / Rect / Point, then publish | +| `ok-script Toolkit: Open Temp Screenshots` | — | Focus the temp screenshots view in the activity bar | +| `ok-script Toolkit: Screenshot to Annotation Management` | — (`Ctrl+Alt+S` now goes to Capture to Inbox) | Open Annotation Management and take a screenshot immediately. Reuses the panel's own screenshot action; the shot is registered into COCO. Rebindable in Keyboard Shortcuts | +| `ok-script Toolkit: Project Convention vs My Settings` | — | List the settings that take part in the precedence chain and show **which layer each effective value comes from** (my settings / project convention / built-in default). Rows you have overridden carry a Revert button that drops your override and goes back to the project convention. Exists to fix "once I changed it, I can never see what the team changed" | ## Update Not Taking Effect diff --git a/README.md b/README.md index 8bfdaa4c..511af891 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ **把 ok-script 的语言、OCR、模板、技能和任务数据,直接搬进 VS Code 的开发流程。** -语言键补全 · OCR 修正提示 · 模板浏览 · 任务启动 · 角色技能管理 +语言键补全 · OCR 修正提示 · 运行 / 参数 / 资源(收件箱→草稿→已发布)· 角色技能管理 [![VS Code Marketplace](https://img.shields.io/badge/VS%20Code%20Marketplace-ok--script%20Toolkit-007ACC?logo=visualstudiocode&logoColor=white)](https://marketplace.visualstudio.com/items?itemName=AliceJump.ok-script-toolkit) [![JetBrains Marketplace](https://img.shields.io/badge/JetBrains%20Marketplace-ok--script%20Toolkit-000000?logo=jetbrains&logoColor=white)](https://plugins.jetbrains.com/plugin/34091-ok-script-toolkit) @@ -23,7 +23,7 @@ --- -VS Code 扩展,为 ok-script 项目的 Python 开发提供语言键、OCR 修正、模板和技能效果的数据提示,同时内置模板浏览、任务启动和角色技能管理面板,让 ok-script 的语言、OCR、模板、技能和任务数据直接进入开发流程。 +VS Code 扩展,为 ok-script 项目的 Python 开发提供语言键、OCR 修正、模板和技能效果的数据提示,同时内置**运行**(原生任务树)、**参数**检查器、**资源**工作台(收件箱 / 草稿 / 已发布)和角色技能管理,让 ok-script 的语言、OCR、模板、技能和任务数据直接进入开发流程。 > [!TIP] > 下面每个功能章节开头的演示图都是可点的——如果动图没加载出来,直接点开链接看。 @@ -52,8 +52,8 @@ PyCharm / IntelliJ IDEA 用户请装 JetBrains 版:[ok-script Toolkit for JetB |---|---| | [代码开发辅助](#代码开发辅助) | 在编辑器内补全和解释 `self.lang`、OCR 正则与技能效果 ID | | [模板管理](#模板管理) | 网格浏览模板,单击插入 `fL.<名称>`,支持缩略图预览 | -| [临时截图](#临时截图) | 活动栏里的 10 张暂存区,框选即可复制归一化坐标 | -| [任务启动](#任务启动) | 从 `config.py` 自动生成参数表单并运行任务,全程不写目标项目配置 | +| [资源](#资源收件箱草稿已发布) | 单一「资源」视图:收件箱(原临时截图)+ 草稿 / 已发布 | +| [运行](#运行任务树) | 原生 TreeView:游戏 / 执行器 / 触发与一次性任务;参数在「参数」视图 | | [角色技能管理](#角色技能管理) | 角色 / 技能 / 效果 / 强化组的可视化管理与诊断 | | [多语言支持](#多语言支持) | 界面支持 6 种语言,数据提示跟随目标项目 | @@ -77,15 +77,16 @@ PyCharm / IntelliJ IDEA 用户请装 JetBrains 版:[ok-script Toolkit for JetB ### 模板管理

- 模板面板:搜索、缩略图预览与快速插入 + 资源预览:搜索、缩略图预览与快速插入

-- **模板面板**:通过侧边栏图标或 `Ctrl+Alt+T` 快捷键(需聚焦 Python 编辑器时生效)打开,网格展示工作区全部模板的缩略图,支持按名称实时搜索和过滤。 -- **快速插入**:单击卡片将 `fL.<模板名>` 插入编辑器光标处,双击复制到剪贴板,使用「查看原图」按钮打开来源。VS Code 模板与框图库统一使用 500 ms 的卡片双击窗口;超过窗口的点击分别按单击处理。插入、复制和查看原图按钮立即执行。 +- **资源预览**:通过侧边栏图标或 `Ctrl+Alt+T` 快捷键(需聚焦 Python 编辑器时生效)打开,网格展示已发布的模板 / 框 / 点资源缩略图,支持按名称实时搜索和过滤。没有资源时会列出实际检查过的 COCO 路径,并提供「打开标注管理」按钮。 +- **快速插入**:缩略图卡片的手势在资源预览、标注管理、临时截图三处一致——**单击 = 选中**,**双击 / Enter = 主操作**(资源预览里是把 `fL.<模板名>` 插入编辑器光标处),`Ctrl+C` 复制引用;卡片右下角的「插入 / 复制 / 查看原图」按钮立即执行。卡片可用 Tab 进入、方向键 / Home / End 移动。 - **模板代码提示**:输入 `fL.` 或 `FeatureList.` 补全模板名称并显示尺寸,悬停显示缩略图预览、尺寸和来源信息。 -- 也可通过命令 **ok-script 工具箱: 在编辑器中打开模板面板** 在编辑器区打开更大的网格视图。 -- 支持侧边栏(模板面板和模板素材两个视图)和编辑器大窗口两种浏览方式。 -- **交换标注**:在模板素材面板(标注管理)里,缩略图卡片右下角的 **⇄** 按钮可以把这张图与同一列表内另一张图的标注**整套互换** —— 修"标错了图 / 图片顺序反了"用。选择目标时按缩略图挑(模板名多是数字序号,光看名字选不出来)。两张图尺寸不同时,框坐标会**按比例缩放**,并在确认框里写明缩放前后的尺寸;交换是整体写盘、**不可撤销**的,所以落盘前一定会先确认。 +- 也可通过命令 **ok-script 工具箱: 在编辑器中打开资源预览** 在编辑器区打开更大的网格视图。 +- 支持侧边栏(「资源预览」和「标注管理」两个视图)和编辑器大窗口两种浏览方式。 +- **标注管理**:双击 / Enter / `E` 打开标注编辑器,`Delete` 删除(会先确认);删除按钮单独放在卡片右上角,与查看 / 交换分开。也可以用命令 **打开标注编辑器…** 从图片列表里直接选图。 +- **交换标注**:在标注管理里,缩略图卡片右下角的「交换标注」按钮(codicon `arrow-swap`)可以把这张图与同一列表内另一张图的标注**整套互换** —— 修"标错了图 / 图片顺序反了"用。选择目标时按缩略图挑(模板名多是数字序号,光看名字选不出来)。两张图尺寸不同时,框坐标会**按比例缩放**,并在确认框里写明缩放前后的尺寸。交换是整体写盘,落盘前一定会先确认;完成后的通知里有「撤销」按钮,只要两张图在此之后没被改过,就能一键恢复原来的标注。 ```python self.wait_click_feature(feature=fL.give_gift, time_out=10) @@ -97,33 +98,36 @@ self.wait_click_feature(feature=fL.give_gift, time_out=10) 框资源管理复用标注原图与 COCO 编辑器,支持编辑框、从模板生成包围框,并显式发布归一化位置表。框画廊提供裁剪预览、来源定位及 `self.pos` 引用的插入、复制、补全和 Hover。工作文件与运行时文件分开,游戏中的加载由业务项目负责。详见 [框资源设计](docs/box-resources.md)。 -### 临时截图 +### 资源(收件箱 → 草稿 → 已发布)

临时截图:轮播与框选复制归一化坐标

-**ok-script 临时截图** 是活动栏上的**独立容器**(有自己的图标),里面是一个最多 10 张的暂存区(超出自动淘汰最早一张),用于快速取素材: +活动栏只保留一个 **ok-script** 容器。其中的 **资源** 视图上部是**收件箱**(原「临时截图」,最多 10 张,超出淘汰最早一张),下部是**草稿 / 已发布**切换: | 能力 | 说明 | |---|---| | 入列 | `Ctrl+V` 粘贴剪贴板图片、点「截屏」截取游戏窗口,或直接把图片文件拖进来 | | 0.1s 轮播 | 按 100ms 间隔循环播放全部截图,方便观察有移动界限的按钮等目标 | | 框选复制 | 在「框选坐标」模式下框选,把 `x,y,tox,toy` 归一化坐标复制到剪贴板 | -| 导入标注 | 缩略图卡片右上角的 **→** 按钮把该张导入「标注管理」(即复制进 `ok_templates` 并登记 COCO) | +| 导入标注 | 缩略图卡片右下角的「添加到标注管理」按钮(codicon `arrow-right`)把该张导入「标注管理」(即复制进 `ok_templates` 并登记 COCO);删除按钮在右上角 | 细节说明: - 轮播与框选相互独立——框选期间轮播不停,选框松手后保留在原位,便于反复比对微调。 - 归一化坐标按图片宽高归一化到 0..1,保留 4 位小数,同样支持滚轮缩放、中键/空白拖拽平移。 - 框选完成后**框会保留并可继续调整**(带 8 向手柄、可整体拖动,交互与模板标注框一致):**创建时与每次调整结束都会重新复制一次当前框的坐标**;框本身不写入标注数据、不落盘。点击图片的非交互部分(框体与手柄之外)即清除。 -- 注:VS Code 的跨 Webview 拖拽不可用(各 webview 是不同 origin 的 iframe,`dataTransfer` 被屏蔽),所以 **→** 按钮是导入的可靠入口。 +- 注:VS Code 的跨 Webview 拖拽不可用(各 webview 是不同 origin 的 iframe,`dataTransfer` 被屏蔽),所以「添加到标注管理」按钮是导入的可靠入口。 +- **在资源中定位 / 查找引用**:Python 里悬停 `fL.xxx` 时,预览下方有「在资源中定位」「查找引用」两个链接(只放行这两条本插件命令)。「查找模板引用…」也可从编辑器右键或命令面板运行:在工作区 Python 文件里找 `fL.xxx`、`self.pos.xxx` 和字符串键 `"xxx"`,列在 QuickPick 里,回车跳转(跳过注释行)。 +- **资源管理器右键「用标注编辑器打开」**:只在 `.png/.jpg/.jpeg/.webp` 上出现。图片需已在标注管理里登记,否则会提示先导入。 +- **发布预览**:选完发布选项、真正写盘前,会弹出只读列表:将写入的文件,以及模板「新增 / 覆盖 / 将从已发布中移除」(按模板名比较;发布会重新裁切装箱,坐标不可比)。在「发布」上回车才写入,Esc 什么都不写。 - **标注编辑器**同样支持该模式:工具栏「坐标 (C)」或按 `C` 键后框选,直接复制同样的 `x,y,tox,toy` 归一化坐标,不会创建标注框、不改动 COCO。得到的框同样带手柄可继续微调,每次调整结束重新复制;点击图片非交互部分清除。快捷键可用 `okScriptToolkit.annotationKeybindings` 的 `copyCoords` 覆盖。 -### 任务启动 +### 运行(任务树)

- 任务启动:参数表单与运行日志 + 控制台:参数表单与运行日志

- 从目标项目的 `src/config.py` / `config.py` 自动解析所有一次性任务和触发任务,生成完整的参数配置表单。 @@ -138,7 +142,10 @@ self.wait_click_feature(feature=fL.give_gift, time_out=10) - **不污染目标项目配置**:执行器运行时,ok 框架对 `configs/` 与截图的读写全部改道到工作区的沙箱目录 `.vscode/ok-script-toolkit/`,**目标项目的配置文件与截图全程保持原样**(`devices.json` 做桥接拷贝以复用游戏连接)。调试时可以放心地改参数试跑,不会弄脏项目。 - 执行器可随时暂停/恢复(全局挂起轮询与任务),也可以「停止当前任务」而不关闭执行器;运行日志输出到专属输出频道。 - **全局配置接管**:目标项目的全局配置组(ok 框架 GlobalConfig 的可见分组)由探针一并解析,在控制台「配置」分段以参数快照呈现——修改即保存、可一键恢复默认;改动经 `gparams` 即时推送给运行中的执行器,执行器启动时以 `OK_TOOLKIT_GCONFIG` 注入全量快照。同样只写沙箱、不碰目标项目配置。 -- **控制台视图**:任务启动器与工具箱统一在「ok-script 控制台」的四个分段(任务 / 游戏 / 配置 / 账号)里管理;顶栏健康度条实时反映执行器状态,空闲时详情面板显示运行中心(当前任务 / 执行队列 / 触发轮询),任务卡悬停弹出只读摘要。 +- **运行视图**:原生 TreeView,展示游戏连接、执行器、触发任务(勾选=启用)、一次性任务(按组)、全局配置与账号;行内可运行 / 打开参数 / 停止。 +- **参数视图**:跟随「运行」里的选中项,编辑沙箱覆盖(自动保存并在执行器运行时推送)。 +- **状态栏与命令**:状态栏左侧显示执行器状态,点击打开「运行」;标题栏和命令面板提供启动 / 暂停 / 停止 / 日志 / 连接游戏等,按状态显隐。运行中 + 排队数显示为视图徽标。 +- **角色技能管理入口**在「配置」分段;未检测到角色数据(`characterMasterFile` / `characterSkillsDirectory` 都不存在)时隐藏,命令面板里的同名命令也一并隐藏。 ### 角色技能管理 @@ -157,8 +164,8 @@ self.wait_click_feature(feature=fL.give_gift, time_out=10) ### 多语言支持 -- 扩展界面(通知、输出频道、hover、模板面板、任务启动器、工具箱和角色技能管理面板)支持简体中文、繁体中文、英文、日文、韩文和西班牙文,默认跟随 VS Code 显示语言。 -- 侧边栏分为 **ok-script 工具**(工具箱 + 任务启动)、**ok-script 模板**(模板面板 + 模板素材)和 **ok-script 临时截图** 三个独立活动栏容器。 +- 扩展界面(通知、输出频道、hover、资源预览、标注管理、控制台和角色技能管理面板)支持简体中文、繁体中文、英文、日文、韩文和西班牙文,默认跟随 VS Code 显示语言。 +- 侧边栏只有一个 **ok-script** 活动栏容器,内含 **运行**(TreeView)、**参数**(检查器)、**资源**(收件箱 + 草稿/已发布)。界面图标统一使用 VS Code codicons。 - 代码提示中的语言数据始终使用目标项目自身的 locale 和原始协议值,不受插件界面语言影响。 > [!NOTE] @@ -189,6 +196,8 @@ self.wait_click_feature(feature=fL.give_gift, time_out=10) ## 配置 +设置界面按用途分为 5 个分类:**ok-script:代码提示**、**资源与标注**、**截图**、**控制台与任务**、**角色数据**。 + | 配置项 | 默认值 | 说明 | |---|---|---| | `okScriptToolkit.langDirectory` | `assets/lang` | lang JSON 目录(相对工作区根) | @@ -201,15 +210,15 @@ self.wait_click_feature(feature=fL.give_gift, time_out=10) | `okScriptToolkit.labelEnumPath` | 空 | 生成 `LabelEnum.py` 的路径(相对目标项目根,带不带 `.py` 都可以);留空则跟随项目约定和 `config.py`。对应项目文件的 `labelEnum.path` | | `okScriptToolkit.labelEnumName` | 空 | 生成枚举的类名;留空则由文件名推导。对应项目文件的 `labelEnum.name`。⚠️ 项目代码按这个名字 import,改名会让那些 import 失效 —— 覆盖已有文件前会先请你确认 | | `okScriptToolkit.effectsFile` | `src/data/effects.py` | 技能效果 ID 定义文件(`EffectType` 枚举与 `EFFECT_DESCRIPTIONS`),相对工作区根目录 | -| `okScriptToolkit.okScriptProjectPath` | 空 | 任务启动器使用的 ok-script 项目根目录;为空时尝试使用当前工作区 | -| `okScriptToolkit.okScriptPython` | 空 | 任务启动器使用的 Python;为空时优先使用目标项目 `.venv/Scripts/python.exe` | +| `okScriptToolkit.okScriptProjectPath` | 空 | 控制台运行任务使用的 ok-script 项目根目录;为空时尝试使用当前工作区 | +| `okScriptToolkit.okScriptPython` | 空 | 控制台运行任务使用的 Python;为空时优先使用目标项目 `.venv/Scripts/python.exe` | | `okScriptToolkit.captureMethod` | `auto` | 游戏窗口截图方式:`auto` / `wgc` / `bitblt` / `foreground` | | `okScriptToolkit.characterProjectPath` | 空 | 角色技能管理面板的数据项目;为空时使用 `okScriptProjectPath` 或当前工作区 | | `okScriptToolkit.characterMasterFile` | `assets/data/characters.json` | 角色主表 JSON | | `okScriptToolkit.characterSkillsDirectory` | `assets/data/character_skills` | 角色技能 JSON 目录 | | `okScriptToolkit.characterLocaleFile` | `assets/lang/characters.json` | 角色名称多语言 JSON | | `okScriptToolkit.characterAvatarTemplateRegex` | `^battle[_-]?icon[_-]?` | 角色头像模板名正则;有捕获组时使用第一组,否则使用匹配前缀后的剩余名称,与角色主表英文 slug 匹配;默认兼容 `battleicon`、`battle_icon` 和 `battle-icon` 前缀 | -| `okScriptToolkit.okTemplatesDirectory` | `ok_templates` | ok_templates 文件夹名(相对工作区根),供模板素材管理器使用 | +| `okScriptToolkit.okTemplatesDirectory` | `ok_templates` | ok_templates 文件夹名(相对工作区根),供标注管理使用 | | `okScriptToolkit.annotationKeybindings` | 见默认值 | 标注编辑器的键盘快捷键;值为按键名,支持 `ctrl+z` 等修饰符前缀 | ### 项目约定文件 `ok-script-toolkit.json` @@ -296,14 +305,20 @@ self.wait_click_ocr(match=self.lang.zip_line_mixin.k_2f4f4a2f, ...) | 命令 | 快捷键 | 说明 | |---|---|---| -| `ok-script 工具箱: 打开模板面板` | `Ctrl+Alt+T`(macOS `Cmd+Alt+T`,需聚焦 Python 编辑器) | 聚焦活动栏中的模板侧边栏视图 | -| `ok-script 工具箱: 在编辑器中打开模板面板` | — | 在编辑器区打开大窗口网格视图 | -| `ok-script 工具箱: 打开任务启动` | — | 聚焦活动栏中的任务启动器视图 | -| `ok-script 工具箱: 打开角色技能管理面板` | — | 打开角色、技能、效果、强化组和名称本地化管理页 | -| `ok-script 工具箱: 打开模板素材` | — | 在编辑器区打开模板素材管理大窗口面板 | -| `ok-script 工具箱: 打开标注编辑器` | — | 提示在模板素材面板中点击图片以进入 COCO 标注编辑器(命令本身不直接打开编辑器) | +| `ok-script 工具箱: 打开资源预览` | `Ctrl+Alt+T`(macOS `Cmd+Alt+T`,需聚焦 Python 编辑器) | 聚焦「资源」视图 | +| `ok-script 工具箱: 截到收件箱` | `Ctrl+Alt+S`(macOS `Cmd+Alt+S`;Windows 系统级热键同键) | 截图进入资源收件箱;VS Code 键位与 RegisterHotKey 全局热键共用此终点(原「截图并打开标注管理」仍保留为另一条命令) | +| `ok-script 工具箱: 打开控制台` | — | 聚焦「运行」视图 | +| `ok-script 工具箱: 控制台:运行任务…` | — | 从已加载的一次性任务里选一个入队(执行器未启动时会先启动) | +| `ok-script 工具箱: 控制台:启动执行器 / 暂停执行器 / 继续执行器 / 停止当前任务 / 关闭执行器` | — | 与控制台按钮同一套逻辑;按执行器状态在命令面板和视图标题栏里显隐 | +| `ok-script 工具箱: 控制台:刷新任务 / 查看日志 / 连接游戏 / 断开游戏` | — | 重新解析任务列表、打开输出频道、连接或断开游戏窗口 | +| `ok-script 工具箱: 打开角色技能管理` | — | 打开角色、技能、效果、强化组和名称本地化管理页;未检测到角色数据时在命令面板中隐藏 | +| `ok-script 工具箱: 打开标注管理` | — | 在编辑器区打开标注管理大窗口面板 | +| `ok-script 工具箱: 打开标注编辑器…` | — | 从标注管理的图片列表中选一张(显示标注数),直接打开 COCO 标注编辑器 | +| `ok-script 工具箱: 发布资源…` | — | 打开标注管理并直接进入发布流程:选择 Template / Rect / Point 后发布 | | `ok-script 工具箱: 打开临时截图` | — | 聚焦活动栏中的临时截图视图 | -| `ok-script 工具箱: 截图并打开模板素材` | `Ctrl+Alt+S`(macOS `Cmd+Alt+S`) | 打开模板素材管理面板并立即截图。复用面板自己的截图动作,截图会登记进 COCO。键位可在「键盘快捷方式」里改 | +| `ok-script 工具箱: 截图并打开标注管理` | —(`Ctrl+Alt+S` 已改给「截到收件箱」) | 打开标注管理面板并立即截图。复用面板自己的截图动作,截图会登记进 COCO。键位可在「键盘快捷方式」里改 | +| `ok-script 工具箱: 查找模板引用…` | — | 在工作区 Python 文件里找 `fL.xxx` / `self.pos.xxx` / `"xxx"` 的引用并跳转;也在 Python 编辑器右键菜单里 | +| `ok-script 工具箱: 用标注编辑器打开` | — | 资源管理器图片右键(仅 png/jpg/jpeg/webp);命令面板里不带参数时先选图片 | | `ok-script 工具箱: 项目约定 vs 我的设置` | — | 列出参与取值链的设置项,显示每一项的**生效值来自哪一层**(我的设置 / 项目约定 / 内置默认)。被个人设置覆盖过的项带一个「恢复」按钮,一键回到项目约定。用于解决"我改过一次就再也看不到团队改了什么" | ## 更新后不生效 diff --git a/docs/box-resources.en.md b/docs/box-resources.en.md index a2485b59..da7adc79 100644 --- a/docs/box-resources.en.md +++ b/docs/box-resources.en.md @@ -55,7 +55,7 @@ Side and wide previews support Template / Rect / Point modes and name/expression Single click inserts; double click copies. Buttons expose the same actions and annotated source previews. Without a Python editor, the reference is copied with an explanation. Template previews never fill an absent runtime library with unpublished authoring data. Rect / Point hints follow current authoring data without requiring publication first. -Both hosts use `Ctrl+Alt+T` for resource previews and `Ctrl+Alt+S` for capture into annotation management; macOS uses the corresponding `Cmd+Alt` combinations. Publication belongs to annotation management, with no separate publishing chain in previews. +Both hosts use `Ctrl+Alt+T` for resource previews and `Ctrl+Alt+S` for capture into the Resources inbox (VS Code keybinding and the Windows global hotkey share this destination); macOS uses the corresponding `Cmd+Alt` combinations. Publication belongs to annotation management, with no separate publishing chain in previews. ## Unified Publication diff --git a/docs/box-resources.md b/docs/box-resources.md index 6a296b93..105ba850 100644 --- a/docs/box-resources.md +++ b/docs/box-resources.md @@ -55,7 +55,7 @@ Rect / Point 名称至少包含两个由句点分隔的 Python 标识符,例 单击插入,双击复制;按钮提供相同动作和带位置提示的原图查看。没有 Python 编辑器时复制引用并说明原因。Template 预览不会用尚未发布的工作标注填充运行时库;Rect / Point 提示跟随当前工作标注,编辑后不需要先发布才能得到代码提示。 -两端 `Ctrl+Alt+T` 打开资源预览,`Ctrl+Alt+S` 截图到标注管理;macOS 使用相应的 `Cmd+Alt` 组合。发布入口位于标注管理,资源预览不提供另一个发布链。 +两端 `Ctrl+Alt+T` 打开资源预览,`Ctrl+Alt+S` 截图到资源收件箱(VS Code 键位与 Windows 系统级热键同一终点);macOS 使用相应的 `Cmd+Alt` 组合。发布入口位于标注管理,资源预览不提供另一个发布链。 ## 统一发布 diff --git a/docs/design-system.en.md b/docs/design-system.en.md index 3daa363a..47f31f08 100644 --- a/docs/design-system.en.md +++ b/docs/design-system.en.md @@ -2,7 +2,7 @@ [简体中文](design-system.md) | [English](design-system.en.md) -> This is the authoritative UI specification for the entire project. All webview panels (console / templatePanel / templateAssetPanel / tempScreenshots / annotationPanel / characterManager / boxPanel) must follow it. +> This is the authoritative UI specification for the entire project. All webview panels (console / templatePanel / templateAssetPanel / tempScreenshots / annotationPanel / characterManager) must follow it. > Implementation sources: `media/shared/tokens.css` (design tokens) and `media/shared/controls.css` (shared controls). > **Pages compose these classes; they must not independently redefine visual rules.** @@ -55,7 +55,7 @@ Buttons of the same kind share height (`--control-h-sm/md/lg`), padding (`--spac ## 4. Shared Size Scale -- Spacing: `--space-xs(4) / sm(6) / md(10) / lg(14) / xl(20)`. +- Spacing: `--space-xs(4) / sm(8) / md(12) / lg(16) / xl(24)`. - Control height: `--control-h-sm(24) / md(30) / lg(34)`. - Radius: `--radius-sm(5) / md(8) / lg(11) / pill`. - Font size: `--font-xs(11) / sm(12) / md(13) / lg(15)`; weights only `--weight-regular(400)` / `--weight-medium(500)`. @@ -95,8 +95,13 @@ media/shared/tokens.css Colors · Typography · Spacing · Radius · Border media/shared/controls.css Button(primary/secondary/mini/ghost/icon) · Input · Select · Checkbox/Switch · Tag · Card · Toolbar · SectionTitle · Empty/Broken/Hint · Divider · Clickability rules ([role=button], actual-button/clickable-row categories) + · .has-codicon / .is-icon-only (icon button alignment and size) +media/shared/codicons/ @vscode/codicons 0.0.36 (codicon.css + codicon.ttf, vendored unchanged) +media/shared/icons.js OkIcons.icon / label / iconOnly — the single way panels create icons ``` +**Icon rule (2026-10-09):** UI icons always use codicons (the same set as native VS Code UI). Emoji and Unicode glyphs (`▶ ⚙ ⇄ ⟲ + 👁 × ↻` and similar) are no longer used: they drift with the font and screen readers read out the symbol names. Icon-only buttons must have both `title` and `aria-label` (`OkIcons.iconOnly` handles this). One meaning, one icon: sync defaults `sync`, restore factory defaults `discard`, swap annotations `arrow-swap`, delete `trash`, view original `go-to-file` / `eye`. Panel HTML must load `__SHARED_CODICONS_URI__` and `__SHARED_ICONS_URI__`, and the CSP must include `font-src __CSP_SOURCE__`. + Connect a new panel in **three steps; omitting any step silently breaks styling**: 1. In `index.html`, load `__SHARED_TOKENS_URI__` → `__SHARED_CONTROLS_URI__` → panel styles in that order. This is cascade precedence; panel styles may override the shared layer. @@ -122,7 +127,7 @@ Connect a new panel in **three steps; omitting any step silently breaks styling* ## Implementation Progress -2026-10-01 addendum: box panels/galleries share `media/boxPanel`, connected through `src/boxPanels.ts` and included in the static audit. The table and six-panel record below describe the 2026-09-23 migration baseline, not a reason to omit newer panels. +2026-10-09 addendum: the standalone box panel/gallery (`media/boxPanel`, `src/boxPanels.ts`) was folded into the unified annotation editor and resource preview and has been removed; the position-preview helpers used by hover and completion now live in `src/positionPreview.ts`. The table and six-panel record below describe the 2026-09-23 migration baseline; new panels must still be registered in the static audit. | Stage | Work | Status | |---|---|---| diff --git a/docs/design-system.md b/docs/design-system.md index 658228ba..97e4e36a 100644 --- a/docs/design-system.md +++ b/docs/design-system.md @@ -3,7 +3,7 @@ [简体中文](design-system.md) | [English](design-system.en.md) > 本文件是全项目 UI 的唯一权威规范。所有 webview 面板(console / templatePanel / -> templateAssetPanel / tempScreenshots / annotationPanel / characterManager / boxPanel)必须遵循。 +> templateAssetPanel / tempScreenshots / annotationPanel / characterManager)必须遵循。 > 实现真源:`media/shared/tokens.css`(Design Tokens)+ `media/shared/controls.css`(共享控件), > **页面只负责组合这些类,不得自行重定义视觉规则。** @@ -59,7 +59,7 @@ Dialog·Modal / 状态提示 / Loading / 空状态 / 错误状态。同类组件 ## 4. 统一尺寸体系 -- 间距:`--space-xs(4) / sm(6) / md(10) / lg(14) / xl(20)` +- 间距:`--space-xs(4) / sm(8) / md(12) / lg(16) / xl(24)` - 控件高度:`--control-h-sm(24) / md(30) / lg(34)` - 圆角:`--radius-sm(5) / md(8) / lg(11) / pill` - 字号:`--font-xs(11) / sm(12) / md(13) / lg(15)`;字重仅 `--weight-regular(400)` / `--weight-medium(500)` @@ -106,8 +106,18 @@ media/shared/tokens.css Colors · Typography · Spacing · Radius · Border media/shared/controls.css Button(主/次/迷你/幽灵/图标) · Input · Select · Checkbox/Switch · Tag · Card · Toolbar · SectionTitle · Empty/Broken/Hint · Divider · 可点击性硬规范([role=button]、真按钮/行级区分层清单) + · .has-codicon / .is-icon-only(图标按钮的对齐与尺寸) +media/shared/codicons/ @vscode/codicons 0.0.36(codicon.css + codicon.ttf,原样内置) +media/shared/icons.js OkIcons.icon / label / iconOnly —— 面板里生成图标的唯一入口 ``` +**图标规范(2026-10-09)**:界面图标一律用 codicon(与 VS Code 原生 UI 同源), +不再用 emoji 或 Unicode 符号(`▶ ⚙ ⇄ ⟲ + 👁 × ↻` 等字形随字体漂移、读屏会念出符号名)。 +仅图标的按钮必须同时有 `title` 与 `aria-label`(`OkIcons.iconOnly` 自动处理)。 +同一语义只用一个图标:同步默认值 `sync`、恢复出厂 `discard`、交换标注 `arrow-swap`、删除 `trash`、 +查看原图 `go-to-file` / `eye`。面板 HTML 需引入 `__SHARED_CODICONS_URI__` 与 `__SHARED_ICONS_URI__`, +CSP 需含 `font-src __CSP_SOURCE__`。 + 新增面板接入方式(**三步,缺一步样式就静默失效**): 1. `index.html` 按顺序引入 `__SHARED_TOKENS_URI__` → `__SHARED_CONTROLS_URI__` → 面板自身样式 @@ -138,7 +148,7 @@ media/shared/controls.css Button(主/次/迷你/幽灵/图标) · Input · Se ## 落地进度 -2026-10-01 补充:框面板与框画廊共用 `media/boxPanel`,由 `src/boxPanels.ts` 接入共享层,静态审计已包含此目录。下表与“六个面板”记录的是 2026-09-23 的迁移基线,不能据此漏掉新增面板。 +2026-10-09 补充:独立的框面板 / 框画廊(`media/boxPanel`、`src/boxPanels.ts`)已并入统一标注编辑器与资源预览并被移除;悬停与补全使用的位置预览逻辑移到 `src/positionPreview.ts`。下表与“六个面板”记录的是 2026-09-23 的迁移基线,新增面板仍须登记进静态审计。 | 阶段 | 内容 | 状态 | |---|---|---| diff --git a/docs/feature-parity.en.md b/docs/feature-parity.en.md index 7402ad85..32428a0b 100644 --- a/docs/feature-parity.en.md +++ b/docs/feature-parity.en.md @@ -56,3 +56,14 @@ Business projects load published files. The plugin provides current declarations - Confirmed code differences are closed, and the main PR gitlink pins the companion child PR commit. Merge child PR #30 first, then confirm or update the gitlink to a commit reachable from child `main` and verify main CI before merging the main PR. Unmerged code is not released functionality. No actual IDE interaction, game screenshot or business-project runtime acceptance was performed. Full Plugin Verifier API compatibility was not run; build, structure checks and automated regression do not replace those checks. + +## UI P2 parity checklist (done in VS Code, pending in JetBrains; no JetBrains UI changes this round) + +| Item | VS Code (`ui/p2-polish`) | Suggested JetBrains approach | Status | +| --- | --- | --- | --- | +| Image context menu "Open with Annotation Editor" | `explorer/context`, only `.png/.jpg/.jpeg/.webp` | Project View `AnAction`, visibility by extension in `update()` | Pending | +| Find template references | `findTemplateReferences`: `fL.x` / `self.pos.x` / `"x"` → QuickPick → jump | `ReferencesSearch` / custom Find Usages searcher with the same regexes | Pending | +| Command links in template hover | `MarkdownString.isTrusted.enabledCommands` allowlist of two commands | Links in `DocumentationProvider` | Pending | +| Publish preview | Read-only list of files + template add/overwrite/remove (by name) before writing | Read-only list before the publish dialog; write semantics unchanged | Pending | +| Resources drafts listed by template name | Fixed: draft cards use the annotation category name, matching `fL.` | Same in the resource list | Check | +| Activation smoke test | `scripts/test_activation_smoke.js` (mocked vscode module) | `gradlew test` exists; could add an action-registration check | Optional | diff --git a/docs/feature-parity.md b/docs/feature-parity.md index d0fac54b..631473c1 100644 --- a/docs/feature-parity.md +++ b/docs/feature-parity.md @@ -56,3 +56,14 @@ - 本轮代码差异已补齐,主仓 PR 的 gitlink 指向子仓 PR 的配套提交。必须先合并子仓 PR #30,再确认或更新 gitlink 到子仓 `main` 可达的提交并核对主仓 CI,最后合并主仓;未合并代码不作为已发布功能。 没有执行真实 IDE 交互、真实游戏截图或业务项目运行验收,也未执行完整 Plugin Verifier API 兼容性检查;构建、结构和自动回归的成功不代替这些验收。 + +## UI P2 对齐清单(VS Code 已做,JetBrains 待办;本轮不改 JetBrains UI) + +| 项 | VS Code(`ui/p2-polish`) | JetBrains 建议做法 | 状态 | +| --- | --- | --- | --- | +| 图片右键「用标注编辑器打开」 | `explorer/context`,仅 `.png/.jpg/.jpeg/.webp` | Project View `AnAction`,`update()` 按扩展名显隐 | 待办 | +| 查找模板引用 | `findTemplateReferences`:`fL.x` / `self.pos.x` / `"x"` → QuickPick 跳转 | `ReferencesSearch` 或 Find Usages 自定义 searcher,复用同一正则 | 待办 | +| 模板悬停命令链接 | `MarkdownString.isTrusted.enabledCommands` 白名单两条命令 | `DocumentationProvider` 里用 `psi_element://` / 自定义 action 链接 | 待办 | +| 发布预览 | 写盘前只读列出文件 + 模板新增/覆盖/移除(按名字比较) | 发布对话框前插入只读列表;不改写入语义 | 待办 | +| 资源视图草稿按模板名列出 | 修正:草稿卡片按标注类别名,与 `fL.<名字>` 对齐 | 资源列表同样按类别名 | 核对 | +| 激活冒烟测试 | `scripts/test_activation_smoke.js`(模拟 vscode 模块) | 已有 `gradlew test`,可补 action 注册检查 | 可选 | diff --git a/docs/interaction-parity-audit.en.md b/docs/interaction-parity-audit.en.md index a2bb7cfc..3a3b9cdc 100644 --- a/docs/interaction-parity-audit.en.md +++ b/docs/interaction-parity-audit.en.md @@ -8,6 +8,9 @@ This report compares the pages actually registered in the baseline source, cover This is a source audit, without interactive or screenshot verification in either IDE. “No corresponding entry in the current page” does not mean that no implementation exists elsewhere in the plugin. Theme, scaling, focus, and keyboard behavior still need real IDE verification. Shared Python code, formats, or passing tests do not establish interaction parity. + + +> P1 (2026-10-11): VS Code now uses a single activity-bar container with Run TreeView / Parameters / Resources. JetBrains toolWindow merge and Tree parity remain pending (plan.md §11). ## 1. Registered entry points and organization | ID | Item | VS Code | JetBrains | User-visible difference | @@ -27,7 +30,7 @@ Sources: [parent registration](../package.json), [VS Code task page](../media/co | 06 | Template / Rect / Point modes | Three adjacent buttons, with the active mode highlighted | Mode combo box | All modes are immediately visible on one side; the other requires opening a dropdown | | 07 | Insert, copy, source buttons | Three persistent buttons at the bottom right of every thumbnail, directly bound to that card | Insert/copy/open in the top toolbar operate through `selectedValue`; no buttons inside the card | Direct target-card actions versus selecting a target and then using the toolbar | | 08 | Selection and target feedback | No list selection state used by these buttons; each button captures its resource | Single-selection `JBList`; renderer changes background, text, and border for selection | Persistent selection and toolbar dependence differ | -| 09 | Single/double-click timing | Delayed single-click insertion, double-click copy, fixed 500 ms window; card buttons execute immediately | Same basic gestures, using system `awt.multiClickInterval` or a 500 ms fallback; insertion also checks that selection still matches the clicked item | Gesture results broadly match, but timing and selection dependencies differ | +| 09 | Single/double-click timing | (Since 2026-10-09) click = select, double-click / Enter = insert, Ctrl+C = copy, no delay window; card buttons execute immediately; all three thumbnail grids share these gestures and support arrow keys | Still click-to-insert and double-click copy, using system `awt.multiClickInterval` or a 500 ms fallback; insertion also checks that selection still matches the clicked item | **Needs sync**: VS Code moved to "click selects / double-click or Enter runs the primary action"; JetBrains `ThumbnailActions.kt` has not followed yet | | 10 | Grid and card geometry | Responsive CSS grid, 118 px minimum column width, 96 px thumbnail area, left-aligned names | `JList.HORIZONTAL_WRAP`, fixed cell width of 120 plus scaled margins, scaled 72 thumbnail height, centered 10 pt bold names truncated by character count | Density, space usage, alignment, and truncation differ; values are source constants rather than measured screen pixels | | 11 | Counts, empty/loading states | Filter/total counts, successful/failed thumbnail counts, explicit empty/no-match messages | Current preview component contains only toolbar, search, and list; failed loading results become an empty collection without equivalent count/empty/failure widgets | Empty data and loading failure are less distinguishable in this page; this does not assess every lower-level error path | diff --git a/docs/interaction-parity-audit.md b/docs/interaction-parity-audit.md index 59cf0359..541bec6e 100644 --- a/docs/interaction-parity-audit.md +++ b/docs/interaction-parity-audit.md @@ -8,6 +8,9 @@ 这是源码核对,未启动两个 IDE 做交互或截图验收。源码明确没有的入口写为“当前页面无对应入口”;不能据此推断整个插件没有任何实现。主题、缩放、焦点与键盘的实际表现仍需真实 IDE 验证。共享 Python、数据格式或测试通过,也不代表交互一致。 + + +> P1(2026-10-11):VS Code 已合并为单一活动栏「ok-script」+ 运行 TreeView / 参数 / 资源工作台。JetBrains 端 toolWindow 合并与 Tree 对齐仍待同步(见 plan.md §11)。 ## 1. 实际入口与页面组织 | 编号 | 对照项 | VS Code | JetBrains | 用户可感知的差异 | @@ -27,7 +30,7 @@ | 06 | Template / Rect / Point 切换 | 三个并排按钮,当前模式按钮突出显示 | 下拉框选择模式 | 一端直接可见三个模式,另一端需要打开下拉框 | | 07 | 插入、复制、原图按钮 | 每张缩略图右下角常驻三个按钮,直接操作该卡片 | 顶部工具栏的插入、复制、打开按钮,通过 `selectedValue` 操作选中项;卡片内无按钮 | 直接点目标卡片按钮,与先选目标再点顶部按钮,两条操作路径不同 | | 08 | 选中反馈与目标 | 卡片无用于这些按钮的列表选中态;每个按钮闭包绑定自身资源 | `JBList` 单选;渲染器按选中态改变背景、文字和边框 | 另一端有持续选中项,顶部按钮依赖它;操作目标的表达方式不同 | -| 09 | 单击/双击判定 | 卡片单击延迟插入,双击复制;统一使用 500 ms;卡片按钮立即执行 | 同样单击插入、双击复制,但等待系统 `awt.multiClickInterval`,不可用时才是 500 ms;插入还要求当前选中项与点击项相同 | 单击/双击结果大体相同,但时序与选中依赖不同 | +| 09 | 单击/双击判定 | (2026-10-09 起)单击 = 选中、双击 / Enter = 插入、Ctrl+C = 复制,无延迟窗口;卡片按钮立即执行;三处缩略图同一套手势并支持方向键 | 仍是单击插入、双击复制,等待系统 `awt.multiClickInterval`,不可用时才是 500 ms;插入还要求当前选中项与点击项相同 | **待同步**:VS Code 已改为「单击选中 / 双击或 Enter 主操作」,JetBrains 端 `ThumbnailActions.kt` 尚未跟进 | | 10 | 网格与卡片规格 | CSS 自适应网格,最小列宽 118 px;缩略图区域 96 px;名称靠左 | `JList.HORIZONTAL_WRAP`,固定格宽为 120 加缩放边距;缩略图 72 加宿主缩放;名称居中,10 pt 粗体,按字符截短 | 排列密度、空间利用、标题对齐和截断方式不同;数值来自源码,非实测像素 | | 11 | 计数、空态、缩略图状态 | 展示筛选数/总数、加载成功/失败数;无资源、无匹配有明确文字 | 当前预览组件只有工具栏、搜索和列表;加载结果异常回退为空集合,没有同等计数、空态和失败统计控件 | 空列表与加载失败更难从页面区分;这里未判断全部底层错误处理 | diff --git a/docs/project-config.en.md b/docs/project-config.en.md index 87b90008..8633c735 100644 --- a/docs/project-config.en.md +++ b/docs/project-config.en.md @@ -276,16 +276,16 @@ Committing these would impose one person's machine/preferences on colleagues. ### 6.4 Screenshot Shortcut (Not Project Configuration) -**Goal:** screenshot → annotation template management. Target **template asset management** (`openTemplateAssets` / `ShowTemplateAssetsAction`), whose own screenshot action saves and refreshes assets, rather than temporary screenshots (`showTempScreenshots` / `ShowTempShotsAction`). +**Goal:** one unified shortcut for screenshot → Resources inbox. Default destination is the **Resources inbox** (`captureToInbox` / temp screenshot store; annotate or promote to drafts from there), not the standalone "Screenshot to Annotation Management" panel path. `screenshotToTemplate` remains an explicit command but no longer owns the default binding. **IDE scope:** keybindings are personal. Project configuration would impose them on colleagues. VS Code and IntelliJ already have native keymap editors; do not invent another system. | Host | Approach | |---|---| -| VS Code | Add `okScriptToolkit.screenshotToTemplate` to `contributes.commands`, with a default in `contributes.keybindings` and no `when` restriction; users edit Keyboard Shortcuts | +| VS Code | `okScriptToolkit.captureToInbox` defaults to `Ctrl+Alt+S` and lands in the Resources inbox; `okScriptToolkit.screenshotToTemplate` remains available without a default binding. On Windows the RegisterHotKey global hotkey shares the inbox destination. Users can rebind in Keyboard Shortcuts | | JetBrains | Add `AnAction` and a default keybinding under `plugin.xml` actions; users edit Settings → Keymap | -Open the annotation template management panel and invoke its screenshot action. **Reuse existing `handleScreenshot`; do not add capture implementation.** +Behavior: reuse the same `captureGameWindow` implementation and write a lossless BMP into the inbox store. The system-wide hotkey intentionally avoids stealing focus from the game window. ## 7. Migration and Compatibility diff --git a/docs/project-config.md b/docs/project-config.md index 8f719031..4cd38429 100644 --- a/docs/project-config.md +++ b/docs/project-config.md @@ -349,21 +349,20 @@ import 得到(只是拿不到新标签),不会报错;而改类名是** ### 6.4 截图快捷键(新增,**不进项目配置**) -**要什么**:一个"截图 → 进标注模板管理"的快捷键。默认目标是**标注模板管理** -(`openTemplateAssets` / `ShowTemplateAssetsAction`,其面板自带截图动作: -截图落盘后刷新素材列表),而**不是**临时截图(`showTempScreenshots` / -`ShowTempShotsAction`)。 +**要什么**:一个「截图 → 进资源收件箱」的统一快捷键。默认目标是**资源收件箱** +(`captureToInbox` / 临时截图存储,随后可在资源视图里标注或送入草稿),而不是单独的 +「截图并打开标注管理」面板路径。`screenshotToTemplate` 仍保留为显式命令,但不再占用默认键位。 **为什么是 IDE 级**:键位是个人偏好。放进项目配置会强加给同事,而且 VS Code 与 IntelliJ 各有原生 keymap 编辑器,用户改键位本来就该走那里 —— 插件不该自造一套。 | 端 | 做法 | |---|---| -| VS Code | `contributes.commands` 新增 `okScriptToolkit.screenshotToTemplate`;`contributes.keybindings` 给它一个默认键位(不加 `when` 限制,任何文件都能按)。用户可在「键盘快捷方式」里改 | +| VS Code | `contributes.commands` 提供 `okScriptToolkit.captureToInbox`(默认 `Ctrl+Alt+S`,进资源收件箱)与 `okScriptToolkit.screenshotToTemplate`(无默认键位,仍可打开标注管理并截图);Windows 另有 RegisterHotKey 系统级同键,终点同为收件箱。用户可在「键盘快捷方式」里改 | | JetBrains | 新增 `AnAction`(放在 `plugin.xml` 的 `actions` 里给默认键位);用户可在「设置 → 按键映射」里改 | -行为:打开标注模板管理面板并触发它的截图动作。**不新增截图实现** —— 复用面板已有的 -`handleScreenshot`。 +行为:调用与面板相同的 `captureGameWindow` 实现,把无损 BMP 写入收件箱存储。 +系统级热键刻意不抢焦点,以免打断游戏窗口。 ## 7. 迁移与兼容 diff --git a/docs/testing.en.md b/docs/testing.en.md new file mode 100644 index 00000000..b51b4382 --- /dev/null +++ b/docs/testing.en.md @@ -0,0 +1,16 @@ +# Testing + +`npm test` runs entirely in Node — no VS Code, display or network: + +- Pure unit tests (`scripts/test_*.js`, against `out/`): tree model, publish diff, publish preview, template reference finder, hover link snapshot, … +- Webview tests load `media/*/index.html` and scripts in jsdom. +- Contract tests: `test_command_contract.js` (declared / registered / NLS / menus / when), `verify:l10n`, design-system audit. +- **Activation smoke test** `test_activation_smoke.js`: loads `package.json` `main` with a permissive mocked `vscode` module, calls `activate()`, and asserts every declared command is registered and every view has a provider. + +## Limitations + +- `@vscode/test-electron` is not a dependency; it downloads VS Code and needs a display (xvfb on Linux), which this sandbox and CI lack. There is no real Extension Host integration test and **no screenshot regression**. +- The mock only proves registration, not UI behaviour; webview rendering, the Python executor and real game screenshots still need manual acceptance. +- UI screenshots (`/workspace/ok-toolkit-ui-shots/`) are headless-Chrome renders of webview HTML — visual reference, not an automated baseline. + +To add real integration tests later: add `@vscode/test-electron` + `@vscode/test-cli`, run under `xvfb-run` in CI, and move the smoke assertions into `suite/extension.test.ts`. diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 00000000..217b7d14 --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,16 @@ +# 测试说明 + +`npm test` 全部在 Node 里跑,不需要 VS Code、显示器或网络: + +- 纯逻辑单测(`scripts/test_*.js`,读 `out/`):树模型、发布差异、发布预览、模板引用查找、悬停链接快照等。 +- Webview 测试用 jsdom 加载 `media/*/index.html` 与脚本。 +- 契约测试:`test_command_contract.js`(命令声明 / 注册 / NLS / 菜单 / when)、`verify:l10n`、设计系统审计。 +- **激活冒烟测试** `test_activation_smoke.js`:用宽松的 `vscode` 模拟模块加载 `package.json` 的 `main`,调用 `activate()`,断言每个声明的命令都已注册、每个视图都有 provider。 + +## 局限 + +- 依赖里没有 `@vscode/test-electron`;它要下载 VS Code 并需要显示器(Linux 上要 xvfb),当前沙箱和 CI 都不具备,所以没有真实 Extension Host 集成测试,也**没有截图回归**。 +- 模拟模块只验证“注册了”,不验证 UI 行为;webview 渲染、Python 执行器、真实游戏截图仍需人工验收。 +- UI 截图(`/workspace/ok-toolkit-ui-shots/`)由 headless Chrome 渲染 webview HTML 得到,是视觉参考而非自动比对基线。 + +以后要上真集成测试:加 `@vscode/test-electron` + `@vscode/test-cli`,CI 用 `xvfb-run`,把冒烟测试里的断言搬进 `suite/extension.test.ts` 即可。 diff --git a/l10n/bundle.l10n.es.json b/l10n/bundle.l10n.es.json index c138962c..e35f1511 100644 --- a/l10n/bundle.l10n.es.json +++ b/l10n/bundle.l10n.es.json @@ -71,7 +71,6 @@ "No Python editor is available; copied instead: {text}": "No hay un editor de Python disponible; se copió en su lugar: {text}", "ok-script-toolkit: Generating source image annotation…": "ok-script-toolkit: Generando anotación de la imagen original…", "Failed to generate annotated image: source image could not be decoded or was missing": "No se pudo generar la imagen anotada: no se pudo decodificar la imagen original o falta el archivo", - "Template Gallery": "Galería de plantillas", "Category": "Categoría", "Description": "Descripción", "Current": "Actual", @@ -140,14 +139,12 @@ "Connecting to game window…": "Conectando a la ventana del juego (inicia el juego automáticamente si no está en ejecución)…", "Failed to connect game window: {error}": "Error al conectar con la ventana del juego: {error}", "Failed to disconnect game window: {error}": "Error al desconectar la ventana del juego: {error}", - "Reusing game connection from toolbox: {title} (PID {pid})": "Reutilizando la conexión del juego del kit de herramientas: {title} (PID {pid})", "▶ Enabling debug overlay…": "▶ Activando la superposición de depuración…", "⏹ Disabling debug overlay…": "⏹ Desactivando la superposición de depuración…", "⏹ Debug overlay: disabled": "⏹ Superposición de depuración: desactivada", "ok-script Overlay Host": "Anfitrión de superposición de ok-script", "Overlay host ready: Alt+Right-click two corners in the game to copy box coordinates.": "Superposición residente: pulse Alt+clic derecho en dos esquinas del juego para copiar las coordenadas.", "Overlay host stopped.": "Anfitrión de superposición detenido.", - "Added to template assets: {name}": "Añadido a recursos de plantillas: {name}", "Annotation Editor": "Editor de anotaciones", "Auto-detected window config: {config}": "Configuración de ventana detectada: {config}", "Built-in default": "Valor predeterminado", @@ -157,7 +154,6 @@ "Deleted: {name}": "Eliminado: {name}", "Effective value and where it comes from. Use the button to drop your override.": "Valor efectivo y su origen. Usa el botón para quitar tu anulación.", "Enter game window title pattern (regex), or leave empty for all windows": "Introduce el patrón de título de la ventana (regex), o déjalo vacío para todas las ventanas", - "Failed to add to template assets: {error}": "No se pudo añadir a recursos de plantillas: {error}", "Failed to delete: {name}": "No se pudo eliminar: {name}", "Deleted the record for {name}, but the temporary file is still at {path}.": "Se eliminó el registro de {name}, pero el archivo temporal sigue en {path}.", "Failed to save screenshot.": "No se pudo guardar la captura.", @@ -181,7 +177,6 @@ "Screenshot saved: {name}": "Captura guardada: {name}", "Screenshot script not found. capture_game_window.py is missing from the extension.": "No se encontró el script de captura. Falta capture_game_window.py en la extensión.", "Source: {layer}": "Origen: {layer}", - "Template Assets": "Recursos de plantillas", "The dragged screenshot is no longer available.": "La captura arrastrada ya no está disponible.", "enhancementFallbackName": "Mejora {index}", "importImagesFilter": "Imágenes", @@ -198,7 +193,6 @@ "Not set — follows the project convention": "Sin configurar — sigue la convención del proyecto", "LabelEnum class name (leave empty to follow the project convention)": "Nombre de la clase LabelEnum (vacío para seguir la convención del proyecto)", "e.g. assets/data/LabelEnum.py or src/label_enum.py": "p. ej. assets/data/LabelEnum.py o src/label_enum.py", - "Please click an image in the Template Assets panel to open the annotation editor.": "Haz clic en una imagen del panel «Recursos de plantilla» para abrir el editor de anotaciones.", "The target file currently defines class {old}.": "El archivo de destino define actualmente la clase {old}.", "The target file already exists but its class name could not be recognized.": "El archivo de destino ya existe, pero no se pudo reconocer su nombre de clase.", "This save will rename it to {new}.": "Este guardado la renombrará a {new}.", @@ -260,5 +254,64 @@ "Could not publish positions: {error}": "No se pudieron publicar las posiciones: {error}", "Published positions: {files}": "Posiciones publicadas: {files}", "Resource Preview": "Vista previa de recursos", - "No annotations available to publish.": "No hay anotaciones disponibles para publicar." + "No annotations available to publish.": "No hay anotaciones disponibles para publicar.", + "Annotation Management": "Gestión de anotaciones", + "Added to Annotation Management: {name}": "Añadido a Gestión de anotaciones: {name}", + "Failed to add to Annotation Management: {error}": "No se pudo añadir a Gestión de anotaciones: {error}", + "Reusing the Console game connection: {title} (PID {pid})": "Reutilizando la conexión del juego de la consola: {title} (PID {pid})", + "This image is not in Annotation Management yet. Add it there first.": "Esta imagen aún no está en Gestión de anotaciones. Añádela primero.", + "Open Annotation Management": "Abrir gestión de anotaciones", + "No images to annotate yet. Capture or import one in Annotation Management first.": "Aún no hay imágenes para anotar. Captura o importa una en Gestión de anotaciones.", + "{count} annotations": "{count} anotaciones", + "Select an image to annotate": "Selecciona una imagen para anotar", + "ok-script Executor": "Ejecutor de ok-script", + "ok-script: idle": "ok-script: inactivo", + "ok-script: starting…": "ok-script: iniciando…", + "ok-script: paused": "ok-script: en pausa", + "ok-script: ready": "ok-script: listo", + "Executor is not running. Click to open the Console.": "El ejecutor no está en marcha. Haz clic para abrir la consola.", + "Executor is starting. Click to open the Console.": "El ejecutor se está iniciando. Haz clic para abrir la consola.", + "Executor is paused. Click to open the Console.": "El ejecutor está en pausa. Haz clic para abrir la consola.", + "Running: {task} · queued: {count}. Click to open the Console.": "En ejecución: {task} · en cola: {count}. Haz clic para abrir la consola.", + "Executor is ready · {count} trigger task(s) enabled. Click to open the Console.": "Ejecutor listo · {count} tarea(s) de activación habilitada(s). Haz clic para abrir la consola.", + "{count} task(s) running or queued": "{count} tarea(s) en ejecución o en cola", + "{count} temporary screenshot(s) waiting to be sorted": "{count} captura(s) temporal(es) por ordenar", + "No one-time tasks are loaded yet. Open the Console and wait for the task list to load.": "Aún no se han cargado tareas únicas. Abre la consola y espera a que se cargue la lista.", + "Select a task to queue": "Selecciona una tarea para poner en cola", + "Select a task to run (the executor will start first)": "Selecciona una tarea para ejecutar (primero se iniciará el ejecutor)", + "Show Logs": "Ver registros", + "Set Project Path": "Configurar ruta del proyecto", + "Set Python Path": "Configurar ruta de Python", + "Retry": "Reintentar", + "Reload Tasks": "Recargar tareas", + "Stop Executor": "Detener ejecutor", + "Executor closed": "Ejecutor cerrado", + "Executor exited with code {code}": "El ejecutor terminó con el código {code}", + "Undo": "Deshacer", + "Annotations changed after the swap, so it cannot be undone automatically.": "Las anotaciones cambiaron después del intercambio; no se puede deshacer automáticamente.", + "Failed to undo the swap.": "No se pudo deshacer el intercambio.", + "Swap undone: '{first}' and '{second}' have their original annotations again.": "Intercambio deshecho: '{first}' y '{second}' recuperan sus anotaciones originales.", + "Running / queued tasks": "En ejecución / en cola", + "Inbox screenshots": "Capturas de la bandeja", + "Screenshot failed": "Error al capturar", + "Failed to add screenshot to drafts: {error}": "No se pudo añadir a borradores: {error}", + "Open Parameters": "Abrir parámetros", + "paramsSandboxHint": "Solo en el sandbox · se envía al ejecutor si está activo", + "Resource expression (e.g. fL.btn_claim)": "Expresión de recurso (p. ej. fL.btn_claim)", + "Use as ok-script project": "Usar como proyecto ok-script", + "Reveal in Resources": "Mostrar en Recursos", + "Find References": "Buscar referencias", + "Select a template to find references": "Elige una plantilla", + "No references to “{name}” found in Python files.": "No hay referencias a “{name}” en archivos Python.", + "{count} reference(s) to “{name}”": "{count} referencia(s) a “{name}”", + "new": "nuevo", + "overwrite": "sobrescribir", + "removed from published": "se quitará de publicado", + "Write the files below": "Escribir los archivos siguientes", + "Files to write": "Archivos a escribir", + "Templates: {add} new · {keep} overwrite · {remove} removed": "Plantillas: {add} nuevas · {keep} sobrescritas · {remove} quitadas", + "Publish preview": "Vista previa de publicación", + "Review what will be written. Enter on “Publish” to continue, Esc to cancel.": "Revisa lo que se escribirá. Enter en “Publicar” para seguir, Esc para cancelar.", + "Screenshot inbox is not ready.": "La bandeja de capturas aún no está lista.", + "Screenshot saved to inbox: {name}": "Captura guardada en la bandeja: {name}" } diff --git a/l10n/bundle.l10n.ja.json b/l10n/bundle.l10n.ja.json index 1898721d..8a3643e3 100644 --- a/l10n/bundle.l10n.ja.json +++ b/l10n/bundle.l10n.ja.json @@ -71,7 +71,6 @@ "No Python editor is available; copied instead: {text}": "利用可能な Python エディターがないためコピーしました: {text}", "ok-script-toolkit: Generating source image annotation…": "ok-script-toolkit: 元画像の注釈を生成しています…", "Failed to generate annotated image: source image could not be decoded or was missing": "注釈画像を生成できませんでした。元画像をデコードできないか、ファイルがありません。", - "Template Gallery": "テンプレートギャラリー", "Category": "カテゴリ", "Description": "説明", "Current": "現在", @@ -140,14 +139,12 @@ "Connecting to game window…": "ゲームウィンドウに接続中(未起動なら自動で起動します)…", "Failed to connect game window: {error}": "ゲームウィンドウへの接続に失敗しました: {error}", "Failed to disconnect game window: {error}": "ゲームウィンドウの接続解除に失敗しました: {error}", - "Reusing game connection from toolbox: {title} (PID {pid})": "ツールボックスのゲーム接続を再利用: {title}(PID {pid})", "▶ Enabling debug overlay…": "▶ デバッグ オーバーレイを有効化中…", "⏹ Disabling debug overlay…": "⏹ デバッグ オーバーレイを無効化中…", "⏹ Debug overlay: disabled": "⏹ デバッグ オーバーレイ: 無効", "ok-script Overlay Host": "ok-script オーバーレイホスト", "Overlay host ready: Alt+Right-click two corners in the game to copy box coordinates.": "オーバーレイ常駐中:ゲーム画面の2点を Alt+右クリックすると枠座標がクリップボードにコピーされます。", "Overlay host stopped.": "オーバーレイホストを停止しました。", - "Added to template assets: {name}": "テンプレートアセットに追加しました: {name}", "Annotation Editor": "アノテーションエディター", "Auto-detected window config: {config}": "ウィンドウ設定を自動検出: {config}", "Built-in default": "組み込みの既定値", @@ -157,7 +154,6 @@ "Deleted: {name}": "削除しました: {name}", "Effective value and where it comes from. Use the button to drop your override.": "有効値とその由来。ボタンで自分の上書きを解除できます。", "Enter game window title pattern (regex), or leave empty for all windows": "ゲームウィンドウのタイトル正規表現を入力(空欄ですべてのウィンドウ)", - "Failed to add to template assets: {error}": "テンプレートアセットへの追加に失敗: {error}", "Failed to delete: {name}": "削除に失敗: {name}", "Deleted the record for {name}, but the temporary file is still at {path}.": "{name} の記録は削除しましたが、一時ファイルが {path} に残っています。", "Failed to save screenshot.": "スクリーンショットの保存に失敗しました。", @@ -181,7 +177,6 @@ "Screenshot saved: {name}": "スクリーンショットを保存しました: {name}", "Screenshot script not found. capture_game_window.py is missing from the extension.": "スクリーンショットスクリプトが見つかりません。拡張機能に capture_game_window.py がありません。", "Source: {layer}": "由来: {layer}", - "Template Assets": "テンプレートアセット", "The dragged screenshot is no longer available.": "ドラッグされたスクリーンショットは存在しません。", "enhancementFallbackName": "強化 {index}", "importImagesFilter": "画像", @@ -198,7 +193,6 @@ "Not set — follows the project convention": "未設定 — プロジェクト規約に従います", "LabelEnum class name (leave empty to follow the project convention)": "LabelEnum クラス名(空欄ならプロジェクト規約に従います)", "e.g. assets/data/LabelEnum.py or src/label_enum.py": "例: assets/data/LabelEnum.py または src/label_enum.py", - "Please click an image in the Template Assets panel to open the annotation editor.": "アノテーションエディターを開くには、「テンプレートアセット」パネルで画像をクリックしてください。", "The target file currently defines class {old}.": "対象ファイルの現在のクラス名は {old} です。", "The target file already exists but its class name could not be recognized.": "対象ファイルは既に存在しますが、クラス名を判別できませんでした。", "This save will rename it to {new}.": "この保存で {new} に改名されます。", @@ -260,5 +254,64 @@ "Could not publish positions: {error}": "位置リソースを公開できませんでした: {error}", "Published positions: {files}": "位置リソースを公開しました: {files}", "Resource Preview": "リソースプレビュー", - "No annotations available to publish.": "公開できるアノテーションはありません。" + "No annotations available to publish.": "公開できるアノテーションはありません。", + "Annotation Management": "アノテーション管理", + "Added to Annotation Management: {name}": "アノテーション管理に追加しました: {name}", + "Failed to add to Annotation Management: {error}": "アノテーション管理への追加に失敗: {error}", + "Reusing the Console game connection: {title} (PID {pid})": "コンソールのゲーム接続を再利用: {title}(PID {pid})", + "This image is not in Annotation Management yet. Add it there first.": "この画像はまだアノテーション管理にありません。先に追加してください。", + "Open Annotation Management": "アノテーション管理を開く", + "No images to annotate yet. Capture or import one in Annotation Management first.": "アノテーションできる画像がまだありません。先にアノテーション管理でキャプチャまたはインポートしてください。", + "{count} annotations": "{count} 件のアノテーション", + "Select an image to annotate": "アノテーションする画像を選択", + "ok-script Executor": "ok-script エグゼキューター", + "ok-script: idle": "ok-script: 待機中", + "ok-script: starting…": "ok-script: 起動中…", + "ok-script: paused": "ok-script: 一時停止中", + "ok-script: ready": "ok-script: 準備完了", + "Executor is not running. Click to open the Console.": "エグゼキューターは起動していません。クリックしてコンソールを開きます。", + "Executor is starting. Click to open the Console.": "エグゼキューターを起動しています。クリックしてコンソールを開きます。", + "Executor is paused. Click to open the Console.": "エグゼキューターは一時停止中です。クリックしてコンソールを開きます。", + "Running: {task} · queued: {count}. Click to open the Console.": "実行中: {task} · 待機: {count}。クリックしてコンソールを開きます。", + "Executor is ready · {count} trigger task(s) enabled. Click to open the Console.": "エグゼキューター準備完了 · トリガータスク {count} 件有効。クリックしてコンソールを開きます。", + "{count} task(s) running or queued": "{count} 件のタスクが実行中または待機中", + "{count} temporary screenshot(s) waiting to be sorted": "未整理の一時スクリーンショット {count} 枚", + "No one-time tasks are loaded yet. Open the Console and wait for the task list to load.": "一回限りのタスクがまだ読み込まれていません。コンソールを開いてタスク一覧の読み込みを待ってください。", + "Select a task to queue": "キューに追加するタスクを選択", + "Select a task to run (the executor will start first)": "実行するタスクを選択(先にエグゼキューターを起動します)", + "Show Logs": "ログを表示", + "Set Project Path": "プロジェクトパスを設定", + "Set Python Path": "Python パスを設定", + "Retry": "再試行", + "Reload Tasks": "タスクを再読み込み", + "Stop Executor": "エグゼキューターを停止", + "Executor closed": "エグゼキューターを終了しました", + "Executor exited with code {code}": "エグゼキューターが終了しました(終了コード {code})", + "Undo": "元に戻す", + "Annotations changed after the swap, so it cannot be undone automatically.": "交換後にアノテーションが変更されたため、自動で元に戻せません。", + "Failed to undo the swap.": "交換を元に戻せませんでした。", + "Swap undone: '{first}' and '{second}' have their original annotations again.": "交換を元に戻しました: '{first}' と '{second}' は元のアノテーションに戻りました。", + "Running / queued tasks": "実行中 / 待機タスク", + "Inbox screenshots": "受信箱のスクリーンショット", + "Screenshot failed": "キャプチャに失敗しました", + "Failed to add screenshot to drafts: {error}": "下書きへの追加に失敗:{error}", + "Open Parameters": "パラメータを開く", + "paramsSandboxHint": "サンドボックスにのみ保存 · 実行中はエグゼキュータへ送出", + "Resource expression (e.g. fL.btn_claim)": "リソース式(例: fL.btn_claim)", + "Use as ok-script project": "ok-script プロジェクトとして使う", + "Reveal in Resources": "リソースで表示", + "Find References": "参照を検索", + "Select a template to find references": "参照を検索するテンプレートを選択", + "No references to “{name}” found in Python files.": "Python ファイルに “{name}” の参照はありません。", + "{count} reference(s) to “{name}”": "“{name}” の参照 {count} 件", + "new": "新規", + "overwrite": "上書き", + "removed from published": "公開版から削除", + "Write the files below": "以下のファイルを書き込む", + "Files to write": "書き込むファイル", + "Templates: {add} new · {keep} overwrite · {remove} removed": "テンプレート:新規 {add} · 上書き {keep} · 削除 {remove}", + "Publish preview": "公開プレビュー", + "Review what will be written. Enter on “Publish” to continue, Esc to cancel.": "書き込み内容を確認。「公開」で Enter、Esc で取消。", + "Screenshot inbox is not ready.": "スクリーンショット受信箱の準備ができていません。", + "Screenshot saved to inbox: {name}": "スクリーンショットを受信箱に保存しました: {name}" } diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 657ce40a..04ae8ba6 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -120,7 +120,6 @@ "No Python editor is available; copied instead: {text}": "No Python editor is available; copied instead: {text}", "ok-script-toolkit: Generating source image annotation…": "ok-script-toolkit: Generating source image annotation…", "Failed to generate annotated image: source image could not be decoded or was missing": "Failed to generate annotated image: source image could not be decoded or was missing", - "Template Gallery": "Template Gallery", "Category": "Category", "Description": "Description", "Current": "Current", @@ -134,7 +133,6 @@ "Source": "Source", "At runtime, fix_match_regex translates this pattern using ocr.po before calling re.compile.": "At runtime, fix_match_regex translates this pattern using ocr.po before calling re.compile.", "{count} keys": "{count} keys", - "Please click an image in the Template Assets panel to open the annotation editor.": "Please click an image in the Template Assets panel to open the annotation editor.", "LabelEnum.py file path (relative to workspace root, leave empty to skip)": "LabelEnum.py file path (relative to workspace root, leave empty to skip)", "Enum file path must be relative and stay within the workspace root.": "Enum file path must be relative and stay within the workspace root.", "Enum file path": "Enum file path", @@ -149,14 +147,12 @@ "Connecting to game window…": "Connecting to game window (auto-starts the game if not running)…", "Failed to connect game window: {error}": "Failed to connect game window: {error}", "Failed to disconnect game window: {error}": "Failed to disconnect game window: {error}", - "Reusing game connection from toolbox: {title} (PID {pid})": "Reusing game connection from toolbox: {title} (PID {pid})", "▶ Enabling debug overlay…": "▶ Enabling debug overlay…", "⏹ Disabling debug overlay…": "⏹ Disabling debug overlay…", "⏹ Debug overlay: disabled": "⏹ Debug overlay: disabled", "ok-script Overlay Host": "ok-script Overlay Host", "Overlay host ready: Alt+Right-click two corners in the game to copy box coordinates.": "Overlay host ready: Alt+Right-click two corners in the game to copy box coordinates.", "Overlay host stopped.": "Overlay host stopped.", - "Added to template assets: {name}": "Added to template assets: {name}", "Annotation Editor": "Annotation Editor", "Auto-detected window config: {config}": "Auto-detected window config: {config}", "Built-in default": "Built-in default", @@ -166,7 +162,6 @@ "Deleted: {name}": "Deleted: {name}", "Effective value and where it comes from. Use the button to drop your override.": "Effective value and where it comes from. Use the button to drop your override.", "Enter game window title pattern (regex), or leave empty for all windows": "Enter game window title pattern (regex), or leave empty for all windows", - "Failed to add to template assets: {error}": "Failed to add to template assets: {error}", "Failed to delete: {name}": "Failed to delete: {name}", "Deleted the record for {name}, but the temporary file is still at {path}.": "Deleted the record for {name}, but the temporary file is still at {path}.", "Failed to save screenshot.": "Failed to save screenshot.", @@ -190,7 +185,6 @@ "Screenshot saved: {name}": "Screenshot saved: {name}", "Source: {layer}": "Source: {layer}", "Screenshot script not found. capture_game_window.py is missing from the extension.": "Screenshot script not found. capture_game_window.py is missing from the extension.", - "Template Assets": "Template Assets", "The dragged screenshot is no longer available.": "The dragged screenshot is no longer available.", "enhancementFallbackName": "Enhancement {index}", "importImagesFilter": "Images", @@ -260,5 +254,64 @@ "Could not publish positions: {error}": "Could not publish positions: {error}", "Published positions: {files}": "Published positions: {files}", "Resource Preview": "Resource Preview", - "No annotations available to publish.": "No annotations available to publish." + "No annotations available to publish.": "No annotations available to publish.", + "Annotation Management": "Annotation Management", + "Added to Annotation Management: {name}": "Added to Annotation Management: {name}", + "Failed to add to Annotation Management: {error}": "Failed to add to Annotation Management: {error}", + "Reusing the Console game connection: {title} (PID {pid})": "Reusing the Console game connection: {title} (PID {pid})", + "This image is not in Annotation Management yet. Add it there first.": "This image is not in Annotation Management yet. Add it there first.", + "Open Annotation Management": "Open Annotation Management", + "No images to annotate yet. Capture or import one in Annotation Management first.": "No images to annotate yet. Capture or import one in Annotation Management first.", + "{count} annotations": "{count} annotations", + "Select an image to annotate": "Select an image to annotate", + "ok-script Executor": "ok-script Executor", + "ok-script: idle": "ok-script: idle", + "ok-script: starting…": "ok-script: starting…", + "ok-script: paused": "ok-script: paused", + "ok-script: ready": "ok-script: ready", + "Executor is not running. Click to open the Console.": "Executor is not running. Click to open the Console.", + "Executor is starting. Click to open the Console.": "Executor is starting. Click to open the Console.", + "Executor is paused. Click to open the Console.": "Executor is paused. Click to open the Console.", + "Running: {task} · queued: {count}. Click to open the Console.": "Running: {task} · queued: {count}. Click to open the Console.", + "Executor is ready · {count} trigger task(s) enabled. Click to open the Console.": "Executor is ready · {count} trigger task(s) enabled. Click to open the Console.", + "{count} task(s) running or queued": "{count} task(s) running or queued", + "{count} temporary screenshot(s) waiting to be sorted": "{count} temporary screenshot(s) waiting to be sorted", + "No one-time tasks are loaded yet. Open the Console and wait for the task list to load.": "No one-time tasks are loaded yet. Open the Console and wait for the task list to load.", + "Select a task to queue": "Select a task to queue", + "Select a task to run (the executor will start first)": "Select a task to run (the executor will start first)", + "Show Logs": "Show Logs", + "Set Project Path": "Set Project Path", + "Set Python Path": "Set Python Path", + "Retry": "Retry", + "Reload Tasks": "Reload Tasks", + "Stop Executor": "Stop Executor", + "Executor closed": "Executor closed", + "Executor exited with code {code}": "Executor exited with code {code}", + "Undo": "Undo", + "Annotations changed after the swap, so it cannot be undone automatically.": "Annotations changed after the swap, so it cannot be undone automatically.", + "Failed to undo the swap.": "Failed to undo the swap.", + "Swap undone: '{first}' and '{second}' have their original annotations again.": "Swap undone: '{first}' and '{second}' have their original annotations again.", + "Running / queued tasks": "Running / queued tasks", + "Inbox screenshots": "Inbox screenshots", + "Screenshot failed": "Screenshot failed", + "Failed to add screenshot to drafts: {error}": "Failed to add screenshot to drafts: {error}", + "Open Parameters": "Open Parameters", + "paramsSandboxHint": "Saved to the sandbox only · pushed to the executor when running", + "Resource expression (e.g. fL.btn_claim)": "Resource expression (e.g. fL.btn_claim)", + "Use as ok-script project": "Use as ok-script project", + "Reveal in Resources": "Reveal in Resources", + "Find References": "Find References", + "Select a template to find references": "Select a template to find references", + "No references to “{name}” found in Python files.": "No references to “{name}” found in Python files.", + "{count} reference(s) to “{name}”": "{count} reference(s) to “{name}”", + "new": "new", + "overwrite": "overwrite", + "removed from published": "removed from published", + "Write the files below": "Write the files below", + "Files to write": "Files to write", + "Templates: {add} new · {keep} overwrite · {remove} removed": "Templates: {add} new · {keep} overwrite · {remove} removed", + "Publish preview": "Publish preview", + "Review what will be written. Enter on “Publish” to continue, Esc to cancel.": "Review what will be written. Enter on “Publish” to continue, Esc to cancel.", + "Screenshot inbox is not ready.": "Screenshot inbox is not ready.", + "Screenshot saved to inbox: {name}": "Screenshot saved to inbox: {name}" } diff --git a/l10n/bundle.l10n.ko.json b/l10n/bundle.l10n.ko.json index 62bf6bbe..805c0250 100644 --- a/l10n/bundle.l10n.ko.json +++ b/l10n/bundle.l10n.ko.json @@ -71,7 +71,6 @@ "No Python editor is available; copied instead: {text}": "사용 가능한 Python 편집기가 없어 대신 복사했습니다: {text}", "ok-script-toolkit: Generating source image annotation…": "ok-script-toolkit: 원본 이미지 주석 생성 중…", "Failed to generate annotated image: source image could not be decoded or was missing": "주석 이미지를 생성하지 못했습니다. 원본 이미지를 디코딩할 수 없거나 파일이 없습니다.", - "Template Gallery": "템플릿 갤러리", "Category": "분류", "Description": "설명", "Current": "현재", @@ -140,14 +139,12 @@ "Connecting to game window…": "게임 창에 연결하는 중(실행 중이 아니면 자동으로 시작)…", "Failed to connect game window: {error}": "게임 창 연결 실패: {error}", "Failed to disconnect game window: {error}": "게임 창 연결 해제 실패: {error}", - "Reusing game connection from toolbox: {title} (PID {pid})": "도구 상자의 게임 연결 재사용: {title}(PID {pid})", "▶ Enabling debug overlay…": "▶ 디버그 오버레이 활성화 중…", "⏹ Disabling debug overlay…": "⏹ 디버그 오버레이 비활성화 중…", "⏹ Debug overlay: disabled": "⏹ 디버그 오버레이: 꺼짐", "ok-script Overlay Host": "ok-script 오버레이 호스트", "Overlay host ready: Alt+Right-click two corners in the game to copy box coordinates.": "오버레이 상주 중: 게임 화면의 두 모서리를 Alt+오른쪽 클릭하면 좌표가 클립보드에 복사됩니다.", "Overlay host stopped.": "오버레이 호스트가 중지되었습니다.", - "Added to template assets: {name}": "템플릿 에셋에 추가됨: {name}", "Annotation Editor": "어노테이션 편집기", "Auto-detected window config: {config}": "창 설정 자동 감지: {config}", "Built-in default": "내장 기본값", @@ -157,7 +154,6 @@ "Deleted: {name}": "삭제됨: {name}", "Effective value and where it comes from. Use the button to drop your override.": "적용 값과 그 출처입니다. 버튼으로 내 재정의를 해제할 수 있습니다.", "Enter game window title pattern (regex), or leave empty for all windows": "게임 창 제목 정규식을 입력하세요(비우면 모든 창)", - "Failed to add to template assets: {error}": "템플릿 에셋 추가 실패: {error}", "Failed to delete: {name}": "삭제 실패: {name}", "Deleted the record for {name}, but the temporary file is still at {path}.": "{name} 기록은 삭제했지만 임시 파일이 {path}에 남아 있습니다.", "Failed to save screenshot.": "스크린샷 저장에 실패했습니다.", @@ -181,7 +177,6 @@ "Screenshot saved: {name}": "스크린샷 저장됨: {name}", "Screenshot script not found. capture_game_window.py is missing from the extension.": "스크린샷 스크립트를 찾을 수 없습니다. 확장에 capture_game_window.py 가 없습니다.", "Source: {layer}": "출처: {layer}", - "Template Assets": "템플릿 에셋", "The dragged screenshot is no longer available.": "드래그한 스크린샷이 더 이상 존재하지 않습니다.", "enhancementFallbackName": "강화 {index}", "importImagesFilter": "이미지", @@ -198,7 +193,6 @@ "Not set — follows the project convention": "설정 안 됨 — 프로젝트 규약을 따름", "LabelEnum class name (leave empty to follow the project convention)": "LabelEnum 클래스 이름(비워 두면 프로젝트 규약을 따름)", "e.g. assets/data/LabelEnum.py or src/label_enum.py": "예: assets/data/LabelEnum.py 또는 src/label_enum.py", - "Please click an image in the Template Assets panel to open the annotation editor.": "주석 편집기를 열려면 \"템플릿 에셋\" 패널에서 이미지를 클릭하세요.", "The target file currently defines class {old}.": "대상 파일의 현재 클래스 이름은 {old} 입니다.", "The target file already exists but its class name could not be recognized.": "대상 파일이 이미 있지만 클래스 이름을 인식하지 못했습니다.", "This save will rename it to {new}.": "이번 저장으로 {new} 로 이름이 바뀝니다.", @@ -260,5 +254,64 @@ "Could not publish positions: {error}": "위치 리소스를 게시할 수 없습니다: {error}", "Published positions: {files}": "게시된 위치 리소스: {files}", "Resource Preview": "리소스 미리보기", - "No annotations available to publish.": "게시할 주석이 없습니다." + "No annotations available to publish.": "게시할 주석이 없습니다.", + "Annotation Management": "어노테이션 관리", + "Added to Annotation Management: {name}": "어노테이션 관리에 추가됨: {name}", + "Failed to add to Annotation Management: {error}": "어노테이션 관리 추가 실패: {error}", + "Reusing the Console game connection: {title} (PID {pid})": "콘솔의 게임 연결 재사용: {title}(PID {pid})", + "This image is not in Annotation Management yet. Add it there first.": "이 이미지는 아직 어노테이션 관리에 없습니다. 먼저 추가하세요.", + "Open Annotation Management": "어노테이션 관리 열기", + "No images to annotate yet. Capture or import one in Annotation Management first.": "어노테이션할 이미지가 아직 없습니다. 먼저 어노테이션 관리에서 캡처하거나 가져오세요.", + "{count} annotations": "어노테이션 {count}개", + "Select an image to annotate": "어노테이션할 이미지 선택", + "ok-script Executor": "ok-script 실행기", + "ok-script: idle": "ok-script: 유휴", + "ok-script: starting…": "ok-script: 시작 중…", + "ok-script: paused": "ok-script: 일시 중지됨", + "ok-script: ready": "ok-script: 준비됨", + "Executor is not running. Click to open the Console.": "실행기가 실행 중이 아닙니다. 클릭하면 콘솔이 열립니다.", + "Executor is starting. Click to open the Console.": "실행기를 시작하는 중입니다. 클릭하면 콘솔이 열립니다.", + "Executor is paused. Click to open the Console.": "실행기가 일시 중지되었습니다. 클릭하면 콘솔이 열립니다.", + "Running: {task} · queued: {count}. Click to open the Console.": "실행 중: {task} · 대기: {count}. 클릭하면 콘솔이 열립니다.", + "Executor is ready · {count} trigger task(s) enabled. Click to open the Console.": "실행기 준비됨 · 트리거 작업 {count}개 활성화. 클릭하면 콘솔이 열립니다.", + "{count} task(s) running or queued": "작업 {count}개 실행 또는 대기 중", + "{count} temporary screenshot(s) waiting to be sorted": "정리 대기 중인 임시 스크린샷 {count}개", + "No one-time tasks are loaded yet. Open the Console and wait for the task list to load.": "일회성 작업이 아직 로드되지 않았습니다. 콘솔을 열고 작업 목록이 로드될 때까지 기다리세요.", + "Select a task to queue": "대기열에 추가할 작업 선택", + "Select a task to run (the executor will start first)": "실행할 작업 선택(먼저 실행기를 시작합니다)", + "Show Logs": "로그 보기", + "Set Project Path": "프로젝트 경로 설정", + "Set Python Path": "Python 경로 설정", + "Retry": "다시 시도", + "Reload Tasks": "작업 다시 로드", + "Stop Executor": "실행기 종료", + "Executor closed": "실행기가 종료되었습니다", + "Executor exited with code {code}": "실행기가 종료되었습니다(종료 코드 {code})", + "Undo": "실행 취소", + "Annotations changed after the swap, so it cannot be undone automatically.": "교환 후 어노테이션이 변경되어 자동으로 되돌릴 수 없습니다.", + "Failed to undo the swap.": "교환을 되돌리지 못했습니다.", + "Swap undone: '{first}' and '{second}' have their original annotations again.": "교환 취소됨: '{first}'와 '{second}'가 원래 어노테이션으로 돌아갔습니다.", + "Running / queued tasks": "실행 중 / 대기 작업", + "Inbox screenshots": "받은편지함 스크린샷", + "Screenshot failed": "스크린샷 실패", + "Failed to add screenshot to drafts: {error}": "초안에 스크린샷 추가 실패: {error}", + "Open Parameters": "매개 변수 열기", + "paramsSandboxHint": "샌드박스에만 저장 · 실행 중이면 실행기로 전송", + "Resource expression (e.g. fL.btn_claim)": "리소스 식(예: fL.btn_claim)", + "Use as ok-script project": "ok-script 프로젝트로 사용", + "Reveal in Resources": "리소스에서 표시", + "Find References": "참조 찾기", + "Select a template to find references": "참조를 찾을 템플릿 선택", + "No references to “{name}” found in Python files.": "Python 파일에서 “{name}” 참조를 찾지 못했습니다.", + "{count} reference(s) to “{name}”": "“{name}” 참조 {count}개", + "new": "신규", + "overwrite": "덮어쓰기", + "removed from published": "게시본에서 제거", + "Write the files below": "아래 파일 쓰기", + "Files to write": "쓸 파일", + "Templates: {add} new · {keep} overwrite · {remove} removed": "템플릿: 신규 {add} · 덮어쓰기 {keep} · 제거 {remove}", + "Publish preview": "게시 미리보기", + "Review what will be written. Enter on “Publish” to continue, Esc to cancel.": "쓸 내용을 확인하세요. “게시”에서 Enter, Esc로 취소.", + "Screenshot inbox is not ready.": "스크린샷 받은편지함이 준비되지 않았습니다.", + "Screenshot saved to inbox: {name}": "스크린샷이 받은편지함에 저장됨: {name}" } diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json index ecd7c75a..f5cf4ad1 100644 --- a/l10n/bundle.l10n.zh-cn.json +++ b/l10n/bundle.l10n.zh-cn.json @@ -120,7 +120,6 @@ "No Python editor is available; copied instead: {text}": "没有可用的 Python 编辑器,已改为复制:{text}", "ok-script-toolkit: Generating source image annotation…": "ok-script-toolkit:正在生成原图标注…", "Failed to generate annotated image: source image could not be decoded or was missing": "生成标注图失败:原图解码失败或文件缺失", - "Template Gallery": "模板面板", "Category": "分类", "Description": "描述", "Current": "当前", @@ -140,14 +139,12 @@ "Connecting to game window…": "正在连接游戏窗口(游戏未运行时会自动启动)…", "Failed to connect game window: {error}": "连接游戏窗口失败:{error}", "Failed to disconnect game window: {error}": "断开游戏窗口失败:{error}", - "Reusing game connection from toolbox: {title} (PID {pid})": "复用工具箱游戏连接:{title}(PID {pid})", "▶ Enabling debug overlay…": "▶ 正在开启调试浮层…", "⏹ Disabling debug overlay…": "⏹ 正在关闭调试浮层…", "⏹ Debug overlay: disabled": "⏹ 调试浮层:已关闭", "ok-script Overlay Host": "ok-script 浮层宿主", "Overlay host ready: Alt+Right-click two corners in the game to copy box coordinates.": "浮层已常驻:Alt+右键点游戏画面两个角,框选坐标自动复制到剪贴板。", "Overlay host stopped.": "浮层宿主已停止。", - "Added to template assets: {name}": "已添加到模板素材: {name}", "Annotation Editor": "标注编辑器", "Auto-detected window config: {config}": "自动识别窗口配置: {config}", "Built-in default": "内置默认", @@ -157,7 +154,6 @@ "Deleted: {name}": "已删除: {name}", "Effective value and where it comes from. Use the button to drop your override.": "生效值及其来源。点按钮可清除你的覆盖。", "Enter game window title pattern (regex), or leave empty for all windows": "输入游戏窗口标题正则,留空表示匹配所有窗口", - "Failed to add to template assets: {error}": "添加到模板素材失败: {error}", "Failed to delete: {name}": "删除失败: {name}", "Deleted the record for {name}, but the temporary file is still at {path}.": "已删除 {name} 的记录,但临时文件还在 {path}。", "Failed to save screenshot.": "截图保存失败。", @@ -181,7 +177,6 @@ "Screenshot saved: {name}": "截图已保存: {name}", "Screenshot script not found. capture_game_window.py is missing from the extension.": "未找到截图脚本,扩展缺少 capture_game_window.py。", "Source: {layer}": "来源:{layer}", - "Template Assets": "模板素材", "The dragged screenshot is no longer available.": "被拖拽的截图已不存在。", "enhancementFallbackName": "强化 {index}", "importImagesFilter": "图片", @@ -198,7 +193,6 @@ "Not set — follows the project convention": "未设置 —— 跟随项目约定", "LabelEnum class name (leave empty to follow the project convention)": "LabelEnum 类名(留空则跟随项目约定)", "e.g. assets/data/LabelEnum.py or src/label_enum.py": "例如 assets/data/LabelEnum.py 或 src/label_enum.py", - "Please click an image in the Template Assets panel to open the annotation editor.": "请先在「模板资源」面板中单击一张图片,以打开标注编辑器。", "The target file currently defines class {old}.": "目标文件当前的类名是 {old}。", "The target file already exists but its class name could not be recognized.": "目标文件已存在,但没能识别出它的类名。", "This save will rename it to {new}.": "这次保存会把它改名为 {new}。", @@ -260,5 +254,64 @@ "Could not publish positions: {error}": "无法发布位置资源:{error}", "Published positions: {files}": "已发布位置资源:{files}", "Resource Preview": "资源预览", - "No annotations available to publish.": "没有可发布的标注。" + "No annotations available to publish.": "没有可发布的标注。", + "Annotation Management": "标注管理", + "Added to Annotation Management: {name}": "已添加到标注管理:{name}", + "Failed to add to Annotation Management: {error}": "添加到标注管理失败:{error}", + "Reusing the Console game connection: {title} (PID {pid})": "复用控制台的游戏连接:{title}(PID {pid})", + "This image is not in Annotation Management yet. Add it there first.": "这张图片还不在标注管理中,请先添加。", + "Open Annotation Management": "打开标注管理", + "No images to annotate yet. Capture or import one in Annotation Management first.": "还没有可标注的图片。请先在标注管理中截图或导入。", + "{count} annotations": "{count} 个标注", + "Select an image to annotate": "选择要标注的图片", + "ok-script Executor": "ok-script 执行器", + "ok-script: idle": "ok-script:空闲", + "ok-script: starting…": "ok-script:启动中…", + "ok-script: paused": "ok-script:已暂停", + "ok-script: ready": "ok-script:就绪", + "Executor is not running. Click to open the Console.": "执行器未启动。点击打开控制台。", + "Executor is starting. Click to open the Console.": "执行器启动中。点击打开控制台。", + "Executor is paused. Click to open the Console.": "执行器已暂停。点击打开控制台。", + "Running: {task} · queued: {count}. Click to open the Console.": "运行中:{task} · 排队:{count}。点击打开控制台。", + "Executor is ready · {count} trigger task(s) enabled. Click to open the Console.": "执行器就绪 · 已启用 {count} 个触发任务。点击打开控制台。", + "{count} task(s) running or queued": "{count} 个任务运行或排队中", + "{count} temporary screenshot(s) waiting to be sorted": "{count} 张临时截图待整理", + "No one-time tasks are loaded yet. Open the Console and wait for the task list to load.": "尚未加载一次性任务。请打开控制台,等任务列表加载完成。", + "Select a task to queue": "选择要加入队列的任务", + "Select a task to run (the executor will start first)": "选择要运行的任务(将先启动执行器)", + "Show Logs": "查看日志", + "Set Project Path": "设置项目路径", + "Set Python Path": "设置 Python 路径", + "Retry": "重试", + "Reload Tasks": "重新加载任务", + "Stop Executor": "关闭执行器", + "Executor closed": "执行器已关闭", + "Executor exited with code {code}": "执行器异常退出(退出码 {code})", + "Undo": "撤销", + "Annotations changed after the swap, so it cannot be undone automatically.": "交换之后标注又有改动,无法自动撤销。", + "Failed to undo the swap.": "撤销交换失败。", + "Swap undone: '{first}' and '{second}' have their original annotations again.": "已撤销交换:「{first}」和「{second}」恢复了原来的标注。", + "Running / queued tasks": "运行中 / 排队任务", + "Inbox screenshots": "收件箱截图", + "Screenshot failed": "截图失败", + "Failed to add screenshot to drafts: {error}": "无法把截图加入草稿:{error}", + "Open Parameters": "打开参数", + "paramsSandboxHint": "仅写入沙箱 · 执行器运行中时会推送", + "Resource expression (e.g. fL.btn_claim)": "资源表达式(例如 fL.btn_claim)", + "Use as ok-script project": "用作 ok-script 项目", + "Reveal in Resources": "在资源中定位", + "Find References": "查找引用", + "Select a template to find references": "选择要查找引用的模板", + "No references to “{name}” found in Python files.": "Python 文件中没有找到 “{name}” 的引用。", + "{count} reference(s) to “{name}”": "“{name}” 共 {count} 处引用", + "new": "新增", + "overwrite": "覆盖", + "removed from published": "将从已发布中移除", + "Write the files below": "写入下列文件", + "Files to write": "将写入的文件", + "Templates: {add} new · {keep} overwrite · {remove} removed": "模板:新增 {add} · 覆盖 {keep} · 移除 {remove}", + "Publish preview": "发布预览", + "Review what will be written. Enter on “Publish” to continue, Esc to cancel.": "确认将写入的内容。在「发布」上按 Enter 继续,Esc 取消。", + "Screenshot inbox is not ready.": "截图收件箱尚未就绪。", + "Screenshot saved to inbox: {name}": "截图已保存到收件箱: {name}" } diff --git a/l10n/bundle.l10n.zh-tw.json b/l10n/bundle.l10n.zh-tw.json index 47f5500e..489bc6ef 100644 --- a/l10n/bundle.l10n.zh-tw.json +++ b/l10n/bundle.l10n.zh-tw.json @@ -71,7 +71,6 @@ "No Python editor is available; copied instead: {text}": "沒有可用的 Python 編輯器,已改為複製:{text}", "ok-script-toolkit: Generating source image annotation…": "ok-script-toolkit:正在產生原圖標註…", "Failed to generate annotated image: source image could not be decoded or was missing": "產生標註圖失敗:原圖無法解碼或檔案遺失", - "Template Gallery": "模板面板", "Category": "分類", "Description": "描述", "Current": "目前", @@ -140,14 +139,12 @@ "Connecting to game window…": "正在連線遊戲視窗(遊戲未執行時會自動啟動)…", "Failed to connect game window: {error}": "連線遊戲視窗失敗:{error}", "Failed to disconnect game window: {error}": "中斷遊戲視窗連線失敗:{error}", - "Reusing game connection from toolbox: {title} (PID {pid})": "複用工具箱遊戲連線:{title}(PID {pid})", "▶ Enabling debug overlay…": "▶ 正在開啟除錯浮層…", "⏹ Disabling debug overlay…": "⏹ 正在關閉除錯浮層…", "⏹ Debug overlay: disabled": "⏹ 除錯浮層:已關閉", "ok-script Overlay Host": "ok-script 浮層宿主", "Overlay host ready: Alt+Right-click two corners in the game to copy box coordinates.": "浮層已常駐:Alt+右鍵點遊戲畫面兩個角,框選座標自動複製到剪貼簿。", "Overlay host stopped.": "浮層宿主已停止。", - "Added to template assets: {name}": "已加入模板素材: {name}", "Annotation Editor": "標註編輯器", "Auto-detected window config: {config}": "自動辨識視窗設定: {config}", "Built-in default": "內建預設", @@ -157,7 +154,6 @@ "Deleted: {name}": "已刪除: {name}", "Effective value and where it comes from. Use the button to drop your override.": "生效值及其來源。點按鈕可清除你的覆寫。", "Enter game window title pattern (regex), or leave empty for all windows": "輸入遊戲視窗標題正則,留空表示符合所有視窗", - "Failed to add to template assets: {error}": "加入模板素材失敗: {error}", "Failed to delete: {name}": "刪除失敗: {name}", "Deleted the record for {name}, but the temporary file is still at {path}.": "已刪除 {name} 的記錄,但暫存檔還在 {path}。", "Failed to save screenshot.": "截圖儲存失敗。", @@ -181,7 +177,6 @@ "Screenshot saved: {name}": "截圖已儲存: {name}", "Screenshot script not found. capture_game_window.py is missing from the extension.": "找不到截圖腳本,擴充功能缺少 capture_game_window.py。", "Source: {layer}": "來源:{layer}", - "Template Assets": "模板素材", "The dragged screenshot is no longer available.": "被拖曳的截圖已不存在。", "enhancementFallbackName": "強化 {index}", "importImagesFilter": "圖片", @@ -198,7 +193,6 @@ "Not set — follows the project convention": "未設定 —— 跟隨專案約定", "LabelEnum class name (leave empty to follow the project convention)": "LabelEnum 類別名稱(留空則跟隨專案約定)", "e.g. assets/data/LabelEnum.py or src/label_enum.py": "例如 assets/data/LabelEnum.py 或 src/label_enum.py", - "Please click an image in the Template Assets panel to open the annotation editor.": "請先在「範本資源」面板中點選一張圖片,以開啟標註編輯器。", "The target file currently defines class {old}.": "目標檔案目前的類名是 {old}。", "The target file already exists but its class name could not be recognized.": "目標檔案已存在,但無法辨識它的類名。", "This save will rename it to {new}.": "這次儲存會將它改名為 {new}。", @@ -260,5 +254,64 @@ "Could not publish positions: {error}": "無法發佈位置資源:{error}", "Published positions: {files}": "已發佈位置資源:{files}", "Resource Preview": "資源預覽", - "No annotations available to publish.": "沒有可發佈的標註。" + "No annotations available to publish.": "沒有可發佈的標註。", + "Annotation Management": "標註管理", + "Added to Annotation Management: {name}": "已加入標註管理:{name}", + "Failed to add to Annotation Management: {error}": "加入標註管理失敗:{error}", + "Reusing the Console game connection: {title} (PID {pid})": "複用控制台的遊戲連線:{title}(PID {pid})", + "This image is not in Annotation Management yet. Add it there first.": "這張圖片還不在標註管理中,請先加入。", + "Open Annotation Management": "開啟標註管理", + "No images to annotate yet. Capture or import one in Annotation Management first.": "還沒有可標註的圖片。請先在標註管理中截圖或匯入。", + "{count} annotations": "{count} 個標註", + "Select an image to annotate": "選擇要標註的圖片", + "ok-script Executor": "ok-script 執行器", + "ok-script: idle": "ok-script:閒置", + "ok-script: starting…": "ok-script:啟動中…", + "ok-script: paused": "ok-script:已暫停", + "ok-script: ready": "ok-script:就緒", + "Executor is not running. Click to open the Console.": "執行器未啟動。點擊開啟控制台。", + "Executor is starting. Click to open the Console.": "執行器啟動中。點擊開啟控制台。", + "Executor is paused. Click to open the Console.": "執行器已暫停。點擊開啟控制台。", + "Running: {task} · queued: {count}. Click to open the Console.": "執行中:{task} · 排隊:{count}。點擊開啟控制台。", + "Executor is ready · {count} trigger task(s) enabled. Click to open the Console.": "執行器就緒 · 已啟用 {count} 個觸發任務。點擊開啟控制台。", + "{count} task(s) running or queued": "{count} 個任務執行或排隊中", + "{count} temporary screenshot(s) waiting to be sorted": "{count} 張臨時截圖待整理", + "No one-time tasks are loaded yet. Open the Console and wait for the task list to load.": "尚未載入一次性任務。請開啟控制台,等任務列表載入完成。", + "Select a task to queue": "選擇要加入佇列的任務", + "Select a task to run (the executor will start first)": "選擇要執行的任務(將先啟動執行器)", + "Show Logs": "查看日誌", + "Set Project Path": "設定專案路徑", + "Set Python Path": "設定 Python 路徑", + "Retry": "重試", + "Reload Tasks": "重新載入任務", + "Stop Executor": "關閉執行器", + "Executor closed": "執行器已關閉", + "Executor exited with code {code}": "執行器異常結束(結束碼 {code})", + "Undo": "復原", + "Annotations changed after the swap, so it cannot be undone automatically.": "交換之後標註又有變動,無法自動復原。", + "Failed to undo the swap.": "復原交換失敗。", + "Swap undone: '{first}' and '{second}' have their original annotations again.": "已復原交換:「{first}」和「{second}」恢復了原本的標註。", + "Running / queued tasks": "執行中 / 排隊任務", + "Inbox screenshots": "收件匣截圖", + "Screenshot failed": "截圖失敗", + "Failed to add screenshot to drafts: {error}": "無法把截圖加入草稿:{error}", + "Open Parameters": "開啟參數", + "paramsSandboxHint": "僅寫入沙箱 · 執行器執行中時會推送", + "Resource expression (e.g. fL.btn_claim)": "資源運算式(例如 fL.btn_claim)", + "Use as ok-script project": "用作 ok-script 專案", + "Reveal in Resources": "在資源中定位", + "Find References": "尋找參考", + "Select a template to find references": "選擇要尋找參考的模板", + "No references to “{name}” found in Python files.": "Python 檔案中沒有找到 “{name}” 的參考。", + "{count} reference(s) to “{name}”": "“{name}” 共 {count} 處參考", + "new": "新增", + "overwrite": "覆寫", + "removed from published": "將從已發佈中移除", + "Write the files below": "寫入下列檔案", + "Files to write": "將寫入的檔案", + "Templates: {add} new · {keep} overwrite · {remove} removed": "模板:新增 {add} · 覆寫 {keep} · 移除 {remove}", + "Publish preview": "發佈預覽", + "Review what will be written. Enter on “Publish” to continue, Esc to cancel.": "確認將寫入的內容。在「發佈」上按 Enter 繼續,Esc 取消。", + "Screenshot inbox is not ready.": "截圖收件匣尚未就緒。", + "Screenshot saved to inbox: {name}": "截圖已儲存到收件匣: {name}" } diff --git a/l10n/webview.en.json b/l10n/webview.en.json index 3398866f..a0a197c9 100644 --- a/l10n/webview.en.json +++ b/l10n/webview.en.json @@ -123,7 +123,7 @@ "valueLabel": "Value", "confirmDelete": "Delete “{name}”?\nA .bak backup is created before saving.", "copied": "Copied: {text}", - "taskTitle": "ok-script Task Launcher", + "taskTitle": "ok-script Console", "noTasks": "No tasks found.\nConfigure the project path first.", "parameters": "Parameters", "collapseParameters": "Collapse Parameters", @@ -244,11 +244,10 @@ "accountReadFailed": "Store file could not be parsed (see executor output).", "overriddenTasksLabel": "Overridden tasks", "templatesSearch": "Search template names…", - "templatesTitle": "Template Gallery", - "templatesHint": "Click=insert · Double-click=copy · Use the bottom-right buttons for direct actions", + "templatesTitle": "Resource Preview", + "templatesHint": "Double-click / Enter = insert · Ctrl+C = copy · Buttons on each card for direct actions", "templatesCount": "{shown}/{total} templates", "noTemplates": "No templates found.", - "noTemplatesWithHint": "No templates found.\nMake sure the workspace contains assets/coco_annotations.json\n(or ok_tasks/assets/coco_annotations.json).", "noTemplateMatch": "No templates match “{query}”.", "viewOriginal": "View source image with highlighted bounds", "thumbnailStats": "{loaded} thumbnails loaded", @@ -256,11 +255,8 @@ "thumbnailLoadFailed": "Thumbnail failed to load", "templateSize": "Size: {width}×{height}", "templateSource": "Source: {path}", - "templateAssetsTitle": "Template Assets", - "boxAssetsTitle": "Box Assets", + "templateAssetsTitle": "Annotation Management", "templateAssetsHint": "Click an image or its edit button to open annotations", - "noTemplateAssets": "No template assets yet.\nClick Import to add images.", - "noTemplateAssetsHint": "No template assets.", "screenshotSaved": "Screenshot saved: {name}", "screenshotFailed": "Screenshot failed: {error}", "noClipboardImage": "No image in clipboard.", @@ -326,8 +322,8 @@ "tempEmpty": "No temp screenshots yet.\nPress Ctrl+V to paste, or click Capture.", "tempCount": "{shown}/{total}", "tempDelete": "Delete", - "tempSendToAssets": "Add to annotation manager", - "tempDragHint": "Drag onto the annotation manager to import", + "tempSendToAssets": "Add to Annotation Management", + "tempDragHint": "Drag onto Annotation Management to import", "tempCoordCopied": "Copied coordinates: {text}", "assetDropHint": "Release to import into ok_templates", "uncategorized": "Uncategorized", @@ -359,7 +355,7 @@ "publish": "Publish", "assetsHint": "Click an image or its edit button to edit boxes. Publish writes the runtime file.", "galleryHint": "Click inserts to_box(). Double-click copies the attribute path.", - "assetsEmpty": "No template images yet. Add them in Template Assets.", + "assetsEmpty": "No template images yet. Add them in Annotation Management.", "galleryEmpty": "No runtime boxes yet. Publish them from Box Assets.", "insertExpression": "Insert expression", "copyExpression": "Copy expression", @@ -384,7 +380,37 @@ "annotationModeLabel": "Resource type", "sharedHistoryTooltip": "Undo and redo across all resource modes.", "conflictFields": "Fields", - "resourcesTitle": "Resource Preview", - "resourcesSearch": "Search resource names or expressions…", - "resourcesEmpty": "No resources in this mode." + "resourcesTitle": "Resources", + "resourcesSearch": "Search name / category / fL.xxx", + "resourcesEmpty": "No resources in this mode.", + "assetsEmptyTitle": "No images to annotate yet", + "assetsEmptyBody": "Capture or import an image, or drag one in from Temp Shots.", + "openAnnotationSource": "Open source file", + "previewEmptyTemplateTitle": "No published templates yet", + "previewEmptyTemplateBody": "Resource Preview shows published resources. Annotate images in Annotation Management, then publish them.", + "previewEmptyPositionBody": "Draw boxes or points in Annotation Management (Box / Point mode).", + "previewCheckedPaths": "Checked:\n{paths}", + "openAnnotationManagement": "Open Annotation Management", + "assetCardHint": "Double-click / Enter / E: open annotation editor · Delete: delete", + "tempGridLabel": "Temporary screenshots", + "paramsEmptyTitle": "No selection", + "paramsEmptyBody": "Select a task, trigger, or global group in the Run view.", + "paramsNoFields": "This item has no configurable fields.", + "paramsSandboxHint": "Saved to the sandbox only · pushed to the executor when running", + "inboxTitle": "Inbox", + "inboxCount": "{n}/{max}", + "inboxEmpty": "Empty — capture with Ctrl+Alt+S or the toolbar camera.", + "modeDraft": "Draft", + "modePublished": "Published", + "kindTemplate": "Template", + "kindRect": "Box", + "kindPoint": "Point", + "publishEllipsis": "Publish…", + "resourcesHint": "Double-click / Enter = primary · E = annotate · Ctrl+C = copy", + "libCount": "{n} items", + "draftEmpty": "No draft images yet. Capture to the inbox and press E.", + "publishedEmpty": "No published templates yet. Annotate drafts, then Publish…", + "unpublishedCount": "{n} unpublished", + "allPublished": "All in sync with published", + "inspectorSelected": "Selected" } diff --git a/l10n/webview.es.json b/l10n/webview.es.json index 74ebe990..745b23b9 100644 --- a/l10n/webview.es.json +++ b/l10n/webview.es.json @@ -123,7 +123,7 @@ "valueLabel": "Valor", "confirmDelete": "¿Eliminar «{name}»?\nSe creará automáticamente una copia .bak antes de guardar.", "copied": "Copiado: {text}", - "taskTitle": "Lanzador de tareas de ok-script", + "taskTitle": "Consola ok-script", "noTasks": "No se encontraron tareas.\nConfigure primero la ruta del proyecto.", "parameters": "Parámetros", "collapseParameters": "Contraer parámetros", @@ -244,11 +244,10 @@ "accountReadFailed": "No se pudo analizar el archivo del almacén (ver la salida del ejecutor).", "overriddenTasksLabel": "Tareas con anulaciones", "templatesSearch": "Buscar nombres de plantillas…", - "templatesTitle": "Galería de plantillas", - "templatesHint": "Clic=insertar · Doble clic=copiar · Use los botones inferiores derechos para acciones directas", + "templatesTitle": "Vista previa de recursos", + "templatesHint": "Doble clic / Enter = insertar · Ctrl+C = copiar · Usa los botones de cada tarjeta para acciones directas", "templatesCount": "{shown}/{total} plantillas", "noTemplates": "No se encontraron plantillas.", - "noTemplatesWithHint": "No se encontraron plantillas.\nCompruebe que el espacio de trabajo contiene assets/coco_annotations.json\n(o ok_tasks/assets/coco_annotations.json).", "noTemplateMatch": "No hay plantillas que coincidan con «{query}».", "viewOriginal": "Ver la imagen original con la posición resaltada", "thumbnailStats": "{loaded} miniaturas cargadas", @@ -256,11 +255,8 @@ "thumbnailLoadFailed": "Error al cargar la miniatura", "templateSize": "Tamaño: {width}×{height}", "templateSource": "Origen: {path}", - "templateAssetsTitle": "Template Assets", - "boxAssetsTitle": "Box Assets", + "templateAssetsTitle": "Gestión de anotaciones", "templateAssetsHint": "Pulse la imagen o el botón de editar para abrir anotaciones", - "noTemplateAssets": "No template assets yet.\nClick Import to add images.", - "noTemplateAssetsHint": "No template assets.", "screenshotSaved": "Screenshot saved: {name}", "screenshotFailed": "Screenshot failed: {error}", "noClipboardImage": "No image in clipboard.", @@ -326,8 +322,8 @@ "tempEmpty": "Aún no hay capturas temporales.\nPulsa Ctrl+V para pegar o haz clic en Capturar.", "tempCount": "{shown}/{total}", "tempDelete": "Eliminar", - "tempSendToAssets": "Añadir al gestor de anotaciones", - "tempDragHint": "Arrastra al gestor de anotaciones para importar", + "tempSendToAssets": "Añadir a Gestión de anotaciones", + "tempDragHint": "Arrastra a Gestión de anotaciones para importar", "tempCoordCopied": "Coordenadas copiadas: {text}", "assetDropHint": "Suelta para importar en ok_templates", "uncategorized": "Uncategorized", @@ -359,7 +355,7 @@ "publish": "Publish", "assetsHint": "Pulse la imagen o el botón de editar para editar cuadros. Publicar escribe el archivo de ejecución.", "galleryHint": "Click inserts to_box(). Double-click copies the attribute path.", - "assetsEmpty": "No template images yet. Add them in Template Assets.", + "assetsEmpty": "Aún no hay imágenes de plantilla. Añádelas en Gestión de anotaciones.", "galleryEmpty": "No runtime boxes yet. Publish them from Box Assets.", "insertExpression": "Insertar expresión", "copyExpression": "Copiar expresión", @@ -384,7 +380,37 @@ "annotationModeLabel": "Tipo de recurso", "sharedHistoryTooltip": "Deshacer y rehacer en todos los modos de recursos.", "conflictFields": "Campos", - "resourcesTitle": "Vista previa de recursos", - "resourcesSearch": "Buscar nombres o expresiones de recursos…", - "resourcesEmpty": "No hay recursos en este modo." + "resourcesTitle": "Recursos", + "resourcesSearch": "Buscar nombre / categoría / fL.xxx", + "resourcesEmpty": "No hay recursos en este modo.", + "assetsEmptyTitle": "Aún no hay imágenes para anotar", + "assetsEmptyBody": "Captura o importa una imagen, o arrástrala desde Capturas temporales.", + "openAnnotationSource": "Abrir archivo de origen", + "previewEmptyTemplateTitle": "Aún no hay plantillas publicadas", + "previewEmptyTemplateBody": "La vista previa muestra recursos publicados. Anota imágenes en Gestión de anotaciones y luego publícalas.", + "previewEmptyPositionBody": "Dibuja cajas o puntos en Gestión de anotaciones (modo Box / Point).", + "previewCheckedPaths": "Rutas comprobadas:\n{paths}", + "openAnnotationManagement": "Abrir gestión de anotaciones", + "assetCardHint": "Doble clic / Enter / E: abrir editor de anotaciones · Supr: eliminar", + "tempGridLabel": "Capturas temporales", + "paramsEmptyTitle": "Sin selección", + "paramsEmptyBody": "Selecciona una tarea, disparador o grupo global en Ejecutar.", + "paramsNoFields": "Este elemento no tiene campos.", + "paramsSandboxHint": "Solo en el sandbox · se envía al ejecutor si está activo", + "inboxTitle": "Bandeja", + "inboxCount": "{n}/{max}", + "inboxEmpty": "Vacía — captura con Ctrl+Alt+S o la cámara", + "modeDraft": "Borrador", + "modePublished": "Publicado", + "kindTemplate": "Plantilla", + "kindRect": "Caja", + "kindPoint": "Punto", + "publishEllipsis": "Publicar…", + "resourcesHint": "Doble clic / Enter = principal · E = anotar · Ctrl+C = copiar", + "libCount": "{n} elementos", + "draftEmpty": "Aún no hay borradores. Captura a la bandeja y pulsa E.", + "publishedEmpty": "Aún no hay publicados. Anota borradores y Publicar…", + "unpublishedCount": "{n} sin publicar", + "allPublished": "Todo sincronizado", + "inspectorSelected": "Seleccionado" } diff --git a/l10n/webview.ja.json b/l10n/webview.ja.json index 05c6ee8f..ed4f390b 100644 --- a/l10n/webview.ja.json +++ b/l10n/webview.ja.json @@ -123,7 +123,7 @@ "valueLabel": "値", "confirmDelete": "「{name}」を削除しますか?\n保存前に .bak バックアップを自動作成します。", "copied": "コピーしました: {text}", - "taskTitle": "ok-script タスク起動", + "taskTitle": "ok-script コンソール", "noTasks": "タスクが見つかりません。\n先にプロジェクトパスを設定してください。", "parameters": "パラメータ", "collapseParameters": "パラメーターを折りたたむ", @@ -244,11 +244,10 @@ "accountReadFailed": "ストアファイルを解析できません(実行器の出力を参照)。", "overriddenTasksLabel": "上書きありのタスク", "templatesSearch": "テンプレート名を検索…", - "templatesTitle": "テンプレートギャラリー", - "templatesHint": "クリック=挿入 · ダブルクリック=コピー · 右下のボタンで直接操作", + "templatesTitle": "リソースプレビュー", + "templatesHint": "ダブルクリック / Enter = 挿入 · Ctrl+C = コピー · カード右下のボタンで直接操作", "templatesCount": "{shown}/{total} テンプレート", "noTemplates": "テンプレートが見つかりません。", - "noTemplatesWithHint": "テンプレートが見つかりません。\nワークスペースに assets/coco_annotations.json\n(または ok_tasks/assets/coco_annotations.json)があることを確認してください。", "noTemplateMatch": "「{query}」に一致するテンプレートがありません。", "viewOriginal": "位置を強調表示した元画像を表示", "thumbnailStats": "サムネイル {loaded} 件を読み込み", @@ -256,11 +255,8 @@ "thumbnailLoadFailed": "サムネイルの読み込みに失敗", "templateSize": "サイズ: {width}×{height}", "templateSource": "ソース: {path}", - "templateAssetsTitle": "Template Assets", - "boxAssetsTitle": "Box Assets", + "templateAssetsTitle": "アノテーション管理", "templateAssetsHint": "画像または編集ボタンをクリックしてアノテーションを開く", - "noTemplateAssets": "No template assets yet.\nClick Import to add images.", - "noTemplateAssetsHint": "No template assets.", "screenshotSaved": "Screenshot saved: {name}", "screenshotFailed": "Screenshot failed: {error}", "noClipboardImage": "No image in clipboard.", @@ -327,7 +323,7 @@ "tempCount": "{shown}/{total}", "tempDelete": "削除", "tempSendToAssets": "アノテーション管理に追加", - "tempDragHint": "アノテーション管理へドラッグして取り込みます", + "tempDragHint": "アノテーション管理へドラッグしてインポート", "tempCoordCopied": "座標をコピーしました: {text}", "assetDropHint": "ドロップして ok_templates に取り込みます", "uncategorized": "Uncategorized", @@ -359,7 +355,7 @@ "publish": "Publish", "assetsHint": "画像または編集ボタンをクリックして枠を編集。公開後に実行時ファイルへ反映されます。", "galleryHint": "Click inserts to_box(). Double-click copies the attribute path.", - "assetsEmpty": "No template images yet. Add them in Template Assets.", + "assetsEmpty": "テンプレート元画像がありません。アノテーション管理で追加してください。", "galleryEmpty": "No runtime boxes yet. Publish them from Box Assets.", "insertExpression": "式を挿入", "copyExpression": "式をコピー", @@ -384,7 +380,37 @@ "annotationModeLabel": "リソースの種類", "sharedHistoryTooltip": "すべてのリソースモードで元に戻す・やり直す。", "conflictFields": "フィールド", - "resourcesTitle": "リソースプレビュー", - "resourcesSearch": "リソース名や式を検索…", - "resourcesEmpty": "このモードにはリソースがありません。" + "resourcesTitle": "リソース", + "resourcesSearch": "名前 / カテゴリ / fL.xxx", + "resourcesEmpty": "このモードにはリソースがありません。", + "assetsEmptyTitle": "アノテーションする画像がまだありません", + "assetsEmptyBody": "スクリーンショットを撮るか画像をインポートしてください。一時スクリーンショットからドラッグすることもできます。", + "openAnnotationSource": "ソースファイルを開く", + "previewEmptyTemplateTitle": "公開済みのテンプレートがまだありません", + "previewEmptyTemplateBody": "リソースプレビューには公開済みのリソースだけが表示されます。アノテーション管理で注釈を付けてから公開してください。", + "previewEmptyPositionBody": "アノテーション管理の Box / Point モードで注釈を付けてください。", + "previewCheckedPaths": "確認したパス:\n{paths}", + "openAnnotationManagement": "アノテーション管理を開く", + "assetCardHint": "ダブルクリック / Enter / E: アノテーションエディターを開く · Delete: 削除", + "tempGridLabel": "一時スクリーンショット", + "paramsEmptyTitle": "選択なし", + "paramsEmptyBody": "「実行」ビューでタスク / トリガー / グローバル設定を選択してください。", + "paramsNoFields": "設定可能なフィールドはありません。", + "paramsSandboxHint": "サンドボックスにのみ保存 · 実行中はエグゼキュータへ送出", + "inboxTitle": "受信箱", + "inboxCount": "{n}/{max}", + "inboxEmpty": "空です · Ctrl+Alt+S かツールバーでキャプチャ", + "modeDraft": "下書き", + "modePublished": "公開済み", + "kindTemplate": "テンプレ", + "kindRect": "枠", + "kindPoint": "点", + "publishEllipsis": "公開…", + "resourcesHint": "ダブルクリック / Enter = 主操作 · E = 注釈 · Ctrl+C = コピー", + "libCount": "{n} 件", + "draftEmpty": "下書き画像がありません。受信箱にキャプチャして E。", + "publishedEmpty": "公開済みテンプレートがありません。下書きを注釈してから公開…", + "unpublishedCount": "未公開 {n} 件", + "allPublished": "公開版と一致", + "inspectorSelected": "選択中" } diff --git a/l10n/webview.ko.json b/l10n/webview.ko.json index da49596a..785dfd2e 100644 --- a/l10n/webview.ko.json +++ b/l10n/webview.ko.json @@ -123,7 +123,7 @@ "valueLabel": "값", "confirmDelete": "“{name}”을(를) 삭제하시겠습니까?\n저장 전에 .bak 백업을 자동 생성합니다.", "copied": "복사됨: {text}", - "taskTitle": "ok-script 작업 실행", + "taskTitle": "ok-script 콘솔", "noTasks": "작업을 찾을 수 없습니다.\n먼저 프로젝트 경로를 설정하세요.", "parameters": "매개변수", "collapseParameters": "매개변수 접기", @@ -244,11 +244,10 @@ "accountReadFailed": "스토어 파일을 해석할 수 없습니다(실행기 출력 참조).", "overriddenTasksLabel": "재정의가 있는 작업", "templatesSearch": "템플릿 이름 검색…", - "templatesTitle": "템플릿 갤러리", - "templatesHint": "클릭=삽입 · 더블클릭=복사 · 오른쪽 아래 버튼으로 바로 실행", + "templatesTitle": "리소스 미리보기", + "templatesHint": "더블클릭 / Enter = 삽입 · Ctrl+C = 복사 · 카드 오른쪽 아래 버튼으로 바로 실행", "templatesCount": "{shown}/{total} 템플릿", "noTemplates": "템플릿을 찾을 수 없습니다.", - "noTemplatesWithHint": "템플릿을 찾을 수 없습니다.\n작업 영역에 assets/coco_annotations.json\n(또는 ok_tasks/assets/coco_annotations.json)이 있는지 확인하세요.", "noTemplateMatch": "“{query}”와 일치하는 템플릿이 없습니다.", "viewOriginal": "위치를 강조 표시한 원본 이미지 보기", "thumbnailStats": "미리 보기 {loaded}개 불러옴", @@ -256,11 +255,8 @@ "thumbnailLoadFailed": "미리 보기 불러오기 실패", "templateSize": "크기: {width}×{height}", "templateSource": "소스: {path}", - "templateAssetsTitle": "Template Assets", - "boxAssetsTitle": "Box Assets", + "templateAssetsTitle": "어노테이션 관리", "templateAssetsHint": "이미지 또는 편집 버튼을 클릭하여 주석 편집기 열기", - "noTemplateAssets": "No template assets yet.\nClick Import to add images.", - "noTemplateAssetsHint": "No template assets.", "screenshotSaved": "Screenshot saved: {name}", "screenshotFailed": "Screenshot failed: {error}", "noClipboardImage": "No image in clipboard.", @@ -327,7 +323,7 @@ "tempCount": "{shown}/{total}", "tempDelete": "삭제", "tempSendToAssets": "어노테이션 관리에 추가", - "tempDragHint": "어노테이션 관리로 드래그해 가져오기", + "tempDragHint": "어노테이션 관리로 끌어다 놓아 가져오기", "tempCoordCopied": "좌표 복사됨: {text}", "assetDropHint": "놓으면 ok_templates 로 가져옵니다", "uncategorized": "Uncategorized", @@ -359,7 +355,7 @@ "publish": "Publish", "assetsHint": "이미지 또는 편집 버튼을 클릭하여 박스를 편집하세요. 게시하면 런타임 파일에 반영됩니다.", "galleryHint": "Click inserts to_box(). Double-click copies the attribute path.", - "assetsEmpty": "No template images yet. Add them in Template Assets.", + "assetsEmpty": "템플릿 원본 이미지가 없습니다. 어노테이션 관리에서 추가하세요.", "galleryEmpty": "No runtime boxes yet. Publish them from Box Assets.", "insertExpression": "표현식 삽입", "copyExpression": "표현식 복사", @@ -384,7 +380,37 @@ "annotationModeLabel": "리소스 유형", "sharedHistoryTooltip": "모든 리소스 모드에서 실행 취소 및 다시 실행합니다.", "conflictFields": "필드", - "resourcesTitle": "리소스 미리보기", - "resourcesSearch": "리소스 이름 또는 표현식 검색…", - "resourcesEmpty": "이 모드에 리소스가 없습니다." + "resourcesTitle": "리소스", + "resourcesSearch": "이름 / 범주 / fL.xxx", + "resourcesEmpty": "이 모드에 리소스가 없습니다.", + "assetsEmptyTitle": "어노테이션할 이미지가 아직 없습니다", + "assetsEmptyBody": "스크린샷을 찍거나 이미지를 가져오세요. 임시 스크린샷에서 끌어다 놓을 수도 있습니다.", + "openAnnotationSource": "소스 파일 열기", + "previewEmptyTemplateTitle": "게시된 템플릿이 아직 없습니다", + "previewEmptyTemplateBody": "리소스 미리보기에는 게시된 리소스만 표시됩니다. 어노테이션 관리에서 주석을 단 뒤 게시하세요.", + "previewEmptyPositionBody": "어노테이션 관리의 Box / Point 모드로 주석을 다세요.", + "previewCheckedPaths": "확인한 경로:\n{paths}", + "openAnnotationManagement": "어노테이션 관리 열기", + "assetCardHint": "더블클릭 / Enter / E: 어노테이션 편집기 열기 · Delete: 삭제", + "tempGridLabel": "임시 스크린샷", + "paramsEmptyTitle": "선택 없음", + "paramsEmptyBody": "실행 보기에서 작업·트리거·전역 그룹을 선택하세요.", + "paramsNoFields": "구성할 필드가 없습니다.", + "paramsSandboxHint": "샌드박스에만 저장 · 실행 중이면 실행기로 전송", + "inboxTitle": "받은편지함", + "inboxCount": "{n}/{max}", + "inboxEmpty": "비어 있음 · Ctrl+Alt+S 또는 도구 모음으로 캡처", + "modeDraft": "초안", + "modePublished": "게시됨", + "kindTemplate": "템플릿", + "kindRect": "박스", + "kindPoint": "점", + "publishEllipsis": "게시…", + "resourcesHint": "더블클릭 / Enter = 기본 · E = 주석 · Ctrl+C = 복사", + "libCount": "{n}개", + "draftEmpty": "초안 이미지 없음. 받은편지함에 캡처 후 E.", + "publishedEmpty": "게시된 템플릿 없음. 초안을 주석한 뒤 게시…", + "unpublishedCount": "미게시 {n}개", + "allPublished": "게시본과 일치", + "inspectorSelected": "선택됨" } diff --git a/l10n/webview.zh-cn.json b/l10n/webview.zh-cn.json index 98019830..0c520303 100644 --- a/l10n/webview.zh-cn.json +++ b/l10n/webview.zh-cn.json @@ -123,7 +123,7 @@ "valueLabel": "值", "confirmDelete": "确定删除“{name}”吗?\n保存前会自动创建 .bak 备份。", "copied": "已复制:{text}", - "taskTitle": "ok-script 任务启动", + "taskTitle": "ok-script 控制台", "noTasks": "未找到任务。\n请先在设置中配置项目路径。", "parameters": "参数", "collapseParameters": "收起参数", @@ -244,11 +244,10 @@ "accountReadFailed": "存储文件无法解析(详情见执行器输出)。", "overriddenTasksLabel": "有覆盖的任务", "templatesSearch": "搜索模板名…", - "templatesTitle": "模板面板", - "templatesHint": "单击=插入 · 双击=复制 · 右下角按钮可直接操作", + "templatesTitle": "资源预览", + "templatesHint": "双击 / Enter = 插入 · Ctrl+C = 复制 · 卡片右下角按钮可直接操作", "templatesCount": "{shown}/{total} 个模板", "noTemplates": "未找到任何模板。", - "noTemplatesWithHint": "未找到任何模板。\n请确认工作区存在 assets/coco_annotations.json\n(或 ok_tasks/assets/coco_annotations.json)。", "noTemplateMatch": "没有匹配“{query}”的模板。", "viewOriginal": "查看原图(红框标注位置)", "thumbnailStats": "缩略图 {loaded} 成功", @@ -256,11 +255,8 @@ "thumbnailLoadFailed": "缩略图加载失败", "templateSize": "尺寸: {width}×{height}", "templateSource": "来源: {path}", - "templateAssetsTitle": "模板素材管理", - "boxAssetsTitle": "框资源管理", + "templateAssetsTitle": "标注管理", "templateAssetsHint": "单击或点击编辑按钮打开标注编辑器", - "noTemplateAssets": "暂无模板素材。\n点击 Import 导入图片。", - "noTemplateAssetsHint": "暂无模板素材。", "screenshotSaved": "截图已保存: {name}", "screenshotFailed": "截图保存失败: {error}", "noClipboardImage": "剪贴板中没有图片。", @@ -384,7 +380,37 @@ "annotationModeLabel": "资源类型", "sharedHistoryTooltip": "跨资源模式撤销和重做。", "conflictFields": "字段", - "resourcesTitle": "资源预览", - "resourcesSearch": "搜索资源名或表达式…", - "resourcesEmpty": "当前模式没有资源。" + "resourcesTitle": "资源", + "resourcesSearch": "搜索名称 / 类别 / fL.xxx", + "resourcesEmpty": "当前模式没有资源。", + "assetsEmptyTitle": "还没有可标注的图片", + "assetsEmptyBody": "截图或导入图片,也可以把「临时截图」里的图拖到这里。", + "openAnnotationSource": "打开源文件", + "previewEmptyTemplateTitle": "还没有已发布的模板", + "previewEmptyTemplateBody": "资源预览只显示已发布的资源。请先在标注管理中标注,再点「发布」。", + "previewEmptyPositionBody": "请在标注管理中用 Box / Point 模式标注。", + "previewCheckedPaths": "已检查:\n{paths}", + "openAnnotationManagement": "打开标注管理", + "assetCardHint": "双击 / Enter / E:打开标注编辑器 · Delete:删除", + "tempGridLabel": "临时截图", + "paramsEmptyTitle": "未选择项", + "paramsEmptyBody": "在「运行」视图中选择任务、触发任务或全局配置组。", + "paramsNoFields": "此项没有可配置字段。", + "paramsSandboxHint": "仅写入沙箱 · 执行器运行中时会推送", + "inboxTitle": "收件箱", + "inboxCount": "{n}/{max}", + "inboxEmpty": "空 · 用 Ctrl+Alt+S 或工具栏相机截图", + "modeDraft": "草稿", + "modePublished": "已发布", + "kindTemplate": "模板", + "kindRect": "框", + "kindPoint": "点", + "publishEllipsis": "发布…", + "resourcesHint": "双击 / Enter = 主操作 · E = 标注 · Ctrl+C = 复制", + "libCount": "{n} 项", + "draftEmpty": "还没有草稿图片。截到收件箱后按 E。", + "publishedEmpty": "还没有已发布的模板。先标注草稿,再点「发布…」。", + "unpublishedCount": "{n} 项未发布", + "allPublished": "与已发布版本一致", + "inspectorSelected": "选中" } diff --git a/l10n/webview.zh-tw.json b/l10n/webview.zh-tw.json index 2c273ce5..5461da96 100644 --- a/l10n/webview.zh-tw.json +++ b/l10n/webview.zh-tw.json @@ -123,7 +123,7 @@ "valueLabel": "值", "confirmDelete": "確定要刪除「{name}」嗎?\n儲存前會自動建立 .bak 備份。", "copied": "已複製:{text}", - "taskTitle": "ok-script 任務啟動", + "taskTitle": "ok-script 控制台", "noTasks": "找不到任務。\n請先在設定中配置專案路徑。", "parameters": "參數", "collapseParameters": "收合參數", @@ -244,11 +244,10 @@ "accountReadFailed": "儲存檔案無法解析(詳見執行器輸出)。", "overriddenTasksLabel": "有覆寫的任務", "templatesSearch": "搜尋模板名稱…", - "templatesTitle": "模板面板", - "templatesHint": "單擊=插入 · 雙擊=複製 · 右下角按鈕可直接操作", + "templatesTitle": "資源預覽", + "templatesHint": "雙擊 / Enter = 插入 · Ctrl+C = 複製 · 卡片右下角按鈕可直接操作", "templatesCount": "{shown}/{total} 個模板", "noTemplates": "找不到任何模板。", - "noTemplatesWithHint": "找不到任何模板。\n請確認工作區存在 assets/coco_annotations.json\n(或 ok_tasks/assets/coco_annotations.json)。", "noTemplateMatch": "沒有符合「{query}」的模板。", "viewOriginal": "檢視原圖(標示位置)", "thumbnailStats": "已載入 {loaded} 個縮圖", @@ -256,11 +255,8 @@ "thumbnailLoadFailed": "縮圖載入失敗", "templateSize": "尺寸:{width}×{height}", "templateSource": "來源:{path}", - "templateAssetsTitle": "模板素材管理", - "boxAssetsTitle": "框資源管理", + "templateAssetsTitle": "標註管理", "templateAssetsHint": "單擊或點擊編輯按鈕開啟標註編輯器", - "noTemplateAssets": "暂无模板素材。\n点击 Import 导入图片。", - "noTemplateAssetsHint": "暂无模板素材。", "screenshotSaved": "截图已保存: {name}", "screenshotFailed": "截图保存失败: {error}", "noClipboardImage": "剪贴板中没有图片。", @@ -384,7 +380,37 @@ "annotationModeLabel": "資源類型", "sharedHistoryTooltip": "跨資源模式復原和重做。", "conflictFields": "欄位", - "resourcesTitle": "資源預覽", - "resourcesSearch": "搜尋資源名稱或運算式…", - "resourcesEmpty": "目前模式沒有資源。" + "resourcesTitle": "資源", + "resourcesSearch": "搜尋名稱 / 類別 / fL.xxx", + "resourcesEmpty": "目前模式沒有資源。", + "assetsEmptyTitle": "還沒有可標註的圖片", + "assetsEmptyBody": "截圖或匯入圖片,也可以把「臨時截圖」裡的圖拖到這裡。", + "openAnnotationSource": "開啟原始檔", + "previewEmptyTemplateTitle": "還沒有已發布的模板", + "previewEmptyTemplateBody": "資源預覽只顯示已發布的資源。請先在標註管理中標註,再點「發布」。", + "previewEmptyPositionBody": "請在標註管理中用 Box / Point 模式標註。", + "previewCheckedPaths": "已檢查:\n{paths}", + "openAnnotationManagement": "開啟標註管理", + "assetCardHint": "雙擊 / Enter / E:開啟標註編輯器 · Delete:刪除", + "tempGridLabel": "臨時截圖", + "paramsEmptyTitle": "未選擇項目", + "paramsEmptyBody": "在「執行」檢視中選擇任務、觸發任務或全域設定組。", + "paramsNoFields": "此項目沒有可設定欄位。", + "paramsSandboxHint": "僅寫入沙箱 · 執行器執行中時會推送", + "inboxTitle": "收件匣", + "inboxCount": "{n}/{max}", + "inboxEmpty": "空 · 用 Ctrl+Alt+S 或工具列相機截圖", + "modeDraft": "草稿", + "modePublished": "已發佈", + "kindTemplate": "模板", + "kindRect": "框", + "kindPoint": "點", + "publishEllipsis": "發佈…", + "resourcesHint": "雙擊 / Enter = 主操作 · E = 標註 · Ctrl+C = 複製", + "libCount": "{n} 項", + "draftEmpty": "還沒有草稿圖片。截到收件匣後按 E。", + "publishedEmpty": "還沒有已發佈的模板。先標註草稿,再點「發佈…」。", + "unpublishedCount": "{n} 項未發佈", + "allPublished": "與已發佈版本一致", + "inspectorSelected": "選中" } diff --git a/media/annotationPanel/app.js b/media/annotationPanel/app.js index 52ee399d..32ebafc5 100644 --- a/media/annotationPanel/app.js +++ b/media/annotationPanel/app.js @@ -214,7 +214,9 @@ document.getElementById('undoBtn').disabled = !canUndo(); document.getElementById('redoBtn').disabled = !canRedo(); document.getElementById('undoBtn').title = t('undo') + ' (' + keybindings.undo + ')'; + document.getElementById('undoBtn').setAttribute('aria-label', t('undo')); document.getElementById('redoBtn').title = t('redo') + ' (' + keybindings.redo + ')'; + document.getElementById('redoBtn').setAttribute('aria-label', t('redo')); } function parseKeybinding(kb) { @@ -1104,7 +1106,9 @@ document.getElementById('hideAllBtn').textContent = t('hideAllAnnotations'); document.getElementById('onlyCurrentBtn').textContent = t('showOnlyCurrent'); document.getElementById('prevBtn').title = t('prevImage'); + document.getElementById('prevBtn').setAttribute('aria-label', t('prevImage')); document.getElementById('nextBtn').title = t('nextImage'); + document.getElementById('nextBtn').setAttribute('aria-label', t('nextImage')); document.getElementById('emptyMsg').textContent = t('noImageLoaded'); updateModeUi(); } @@ -1163,6 +1167,7 @@ } else { img = null; imgData = null; canvas.style.display = 'none'; emptyMsg.style.display = 'flex'; syncAnnotationList(); } + renderImageStrip(msg); document.getElementById('navInfo').textContent = `${msg.filename} (${msg.currentIndex + 1}/${msg.totalImages})`; document.getElementById('prevBtn').disabled = msg.currentIndex <= 0; document.getElementById('nextBtn').disabled = msg.currentIndex >= msg.totalImages - 1; @@ -1171,6 +1176,38 @@ window.addEventListener('resize', resize); resize(); + + function renderImageStrip(msg) { + const strip = document.getElementById('imageStrip'); + if (!strip) return; + const names = msg.imageNames || []; + strip.replaceChildren(); + names.forEach((name, index) => { + const btn = document.createElement('button'); + btn.type = 'button'; + btn.className = 'image-strip__item' + (index === msg.currentIndex ? ' is-active' : ''); + btn.title = name; + btn.textContent = String(index + 1); + btn.addEventListener('click', () => vscode.postMessage({ type: 'navigate', index })); + strip.appendChild(btn); + }); + } + + function updateInspector(ann) { + const box = document.getElementById('annotationInspector'); + if (!box) return; + if (!ann) { box.hidden = true; return; } + box.hidden = false; + document.getElementById('inspectorTitle').textContent = t('inspectorSelected') || 'Selected'; + document.getElementById('inspectorName').value = ann.category || ann.categoryName || ''; + document.getElementById('inspectorX').value = Math.round(ann.x ?? ann.bbox?.[0] ?? 0); + document.getElementById('inspectorY').value = Math.round(ann.y ?? ann.bbox?.[1] ?? 0); + document.getElementById('inspectorW').value = Math.round(ann.w ?? ann.bbox?.[2] ?? 0); + document.getElementById('inspectorH').value = Math.round(ann.h ?? ann.bbox?.[3] ?? 0); + const expr = document.getElementById('inspectorExpr'); + if (expr) expr.textContent = ann.category ? ('fL.' + ann.category) : ''; + } + updateStaticText(); vscode.postMessage({ type:'ready' }); })(); \ No newline at end of file diff --git a/media/annotationPanel/conflict.css b/media/annotationPanel/conflict.css index 490be09c..8f160448 100644 --- a/media/annotationPanel/conflict.css +++ b/media/annotationPanel/conflict.css @@ -10,9 +10,9 @@ flex-direction: column; gap: var(--space-sm); max-height: 52%; - padding: var(--space-sm); - border: var(--border-width) solid var(--border); - border-radius: var(--radius-sm); + padding: var(--space-md); + border: var(--border-width) solid color-mix(in srgb, var(--border) 50%, transparent); + border-radius: var(--radius-md); background: var(--bg-container-raised); overflow: hidden; } @@ -39,8 +39,8 @@ display: flex; flex-direction: column; gap: var(--space-xs); - padding: var(--space-xs); - border: var(--border-width) solid var(--border); + padding: var(--space-sm); + border: var(--border-width) solid transparent; border-radius: var(--radius-sm); background: var(--bg-row); } diff --git a/media/annotationPanel/index.html b/media/annotationPanel/index.html index 6a04c72a..9d6f5a97 100644 --- a/media/annotationPanel/index.html +++ b/media/annotationPanel/index.html @@ -2,7 +2,8 @@ - + + @@ -27,14 +28,15 @@ - - + +
- - + +
+
@@ -52,6 +54,17 @@
+
@@ -151,6 +164,7 @@

Bounding Box

}, true); })(); + diff --git a/media/annotationPanel/style.css b/media/annotationPanel/style.css index b9f6db6e..4d030128 100644 --- a/media/annotationPanel/style.css +++ b/media/annotationPanel/style.css @@ -26,7 +26,7 @@ body { display: inline-flex; gap: 2px; padding: 2px; - border: var(--border-width) solid var(--border); + border: var(--border-width) solid color-mix(in srgb, var(--border) 55%, transparent); border-radius: var(--radius-sm); background: var(--bg-container); } @@ -77,8 +77,8 @@ body { display: flex; flex-direction: column; gap: var(--space-sm); - padding: var(--space-sm); - border-left: var(--border-width) solid var(--border); + padding: var(--space-md); + border-left: var(--border-width) solid color-mix(in srgb, var(--border) 55%, transparent); background: var(--bg-container); min-height: 0; } @@ -107,7 +107,7 @@ body { align-items: center; gap: var(--space-sm); min-height: var(--control-h-sm); - padding: 0 var(--space-xs); + padding: var(--space-xs) var(--space-sm); background: var(--bg-row); border-radius: var(--radius-sm); font-size: var(--font-sm); @@ -188,9 +188,9 @@ canvas { .modal { background: var(--bg-container-raised); - border: var(--border-width) solid var(--border); + border: var(--border-width) solid color-mix(in srgb, var(--border) 55%, transparent); border-radius: var(--radius-lg); - padding: var(--space-lg) 22px; + padding: var(--space-lg) var(--space-xl); min-width: 340px; box-shadow: var(--shadow-lg); } @@ -209,3 +209,34 @@ canvas { justify-content: center; color: var(--text-muted); } + +/* P1: source image strip + selection inspector */ +.editor-body { display: flex; } +.image-strip { + flex: 0 0 72px; + display: flex; + flex-direction: column; + gap: 6px; + overflow-y: auto; + padding: var(--space-xs); + border-right: 1px solid color-mix(in srgb, var(--border) 55%, transparent); + background: var(--bg-container); +} +.image-strip__item { + width: 56px; height: 40px; border: 1px solid var(--border); border-radius: var(--radius-sm); + background: var(--bg-row); cursor: pointer; overflow: hidden; padding: 0; +} +.image-strip__item.is-active { border-color: var(--border-strong); box-shadow: 0 0 0 1px var(--border-strong); } +.image-strip__item img { width: 100%; height: 100%; object-fit: cover; display: block; } +.annotation-inspector { + margin-top: var(--space-sm); + padding-top: var(--space-sm); + border-top: 1px solid color-mix(in srgb, var(--border) 55%, transparent); + display: grid; gap: 6px; +} +.inspector-row { display: grid; gap: 2px; font-size: var(--font-xs); color: var(--muted); } +.inspector-row input { width: 100%; } +.inspector-xywh { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; } +.inspector-xywh label { display: grid; gap: 2px; font-size: var(--font-2xs); color: var(--muted); } +.inspector-xywh input { width: 100%; min-width: 0; } +.inspector-expr { font-family: var(--font-mono); font-size: var(--font-2xs); color: var(--muted); word-break: break-all; } diff --git a/media/characterManager/app.js b/media/characterManager/app.js index 1a9008b2..7553ef52 100644 --- a/media/characterManager/app.js +++ b/media/characterManager/app.js @@ -20,6 +20,7 @@ function localizeStaticUi() { document.querySelector('.title').textContent = t('charactersTitle'); $('globalSearch').placeholder = t('searchCharacters'); $('refresh').title = t('refresh'); + $('refresh').setAttribute('aria-label', t('refresh')); const tabs = { characters: 'charactersTab', effects: 'effectsTab', locales: 'localesTab', issues: 'issuesTab' }; for (const node of document.querySelectorAll('.tab')) { const badge = node.querySelector('.badge'); @@ -38,8 +39,8 @@ function localizeStaticUi() { $('effectUsage').options[1].textContent = t('usedOnly'); $('effectUsage').options[2].textContent = t('unusedOnly'); $('effectUsage').options[3].textContent = t('unknownOnly'); - $('addEffectCategory').textContent = `+ ${t('addEffectCategory')}`; - $('addEffect').textContent = `+ ${t('addEffect')}`; + OkIcons.label($('addEffectCategory'), 'add', t('addEffectCategory')); + OkIcons.label($('addEffect'), 'add', t('addEffect')); document.querySelector('.locale-toolbar > span:first-child').textContent = t('localizationMatrix'); document.querySelector('.locale-toolbar > span:last-child').textContent = t('localizationHint'); $('issueSearch').placeholder = t('searchIssues'); @@ -49,8 +50,9 @@ function localizeStaticUi() { $('issueSeverity').options[3].textContent = t('info'); $('loading').firstElementChild.textContent = t('readingCharacterData'); $('modalClose').title = t('close'); - $('modalCancel').textContent = `× ${t('cancel')}`; - $('modalSave').textContent = `✓ ${t('save')}`; + $('modalClose').setAttribute('aria-label', t('close')); + OkIcons.label($('modalCancel'), 'close', t('cancel')); + OkIcons.label($('modalSave'), 'check', t('save')); } function clear(node) { node.replaceChildren(); } @@ -60,8 +62,10 @@ function element(tag, className, content) { if (content !== undefined) node.textContent = text(content); return node; } -function button(label, className, handler, title) { +/** icon 为 codicon 名(可选) */ +function button(label, className, handler, title, icon) { const node = element('button', className, label); + if (icon) OkIcons.label(node, icon, label); if (title) node.title = title; node.addEventListener('click', handler); return node; @@ -220,9 +224,9 @@ function showModal(title, build, onSubmit, saveText) { $('modalBody').appendChild(form); const actionLabel = saveText || t('save'); const actionKind = actionLabel === t('add') ? 'action-add' : actionLabel === t('modify') ? 'action-edit' : 'action-save'; - const actionIcon = actionLabel === t('add') ? '+ ' : actionLabel === t('modify') ? '✎ ' : '✓ '; + const actionIcon = actionLabel === t('add') ? 'add' : actionLabel === t('modify') ? 'edit' : 'check'; $('modalSave').className = `action-button ${actionKind}`; - $('modalSave').textContent = actionIcon + actionLabel; + OkIcons.label($('modalSave'), actionIcon, actionLabel); modalSubmit = () => onSubmit(controls); $('modalBackdrop').classList.add('show'); form.querySelector('input,select,textarea')?.focus(); @@ -433,7 +437,7 @@ function renderCharacterDetail(character) { $('characterDetail').appendChild(header); if (!character.skills.length) { $('characterDetail').appendChild(element('div', 'empty', t('noSkills'))); return; } const sectionTitle = element('div', 'section-title'); - sectionTitle.append(element('span', '', t('skillsAndEnhancements')), button(`+ ${t('addSkill')}`, 'action-button action-add compact', () => showSkillEditor(character, null))); + sectionTitle.append(element('span', '', t('skillsAndEnhancements')), button(t('addSkill'), 'action-button action-add compact', () => showSkillEditor(character, null), undefined, 'add')); $('characterDetail').appendChild(sectionTitle); for (const skill of character.skills) { const card = element('article', 'skill-card'); @@ -446,8 +450,8 @@ function renderCharacterDetail(character) { skillMeta.appendChild(makeChip(skillTypeLabel(skill.skillType))); if (skill.element) skillMeta.appendChild(makeChip(skill.element)); if (skill.hasEnhancement) skillMeta.appendChild(makeChip(t('enhancedState'))); - skillMeta.appendChild(button(`✎ ${t('modify')}`, 'action-button action-edit compact', () => showSkillEditor(character, skill), t('modifySkill'))); - if (skill.source === 'custom') skillMeta.appendChild(button(`× ${t('delete')}`, 'action-button action-delete compact', () => confirmDelete(skill.name, () => mutate({ action: 'deleteSkill', characterId: character.characterId, skillId: skill.skillId })))); + skillMeta.appendChild(button(t('modify'), 'action-button action-edit compact', () => showSkillEditor(character, skill), t('modifySkill'), 'edit')); + if (skill.source === 'custom') skillMeta.appendChild(button(t('delete'), 'action-button action-delete compact', () => confirmDelete(skill.name, () => mutate({ action: 'deleteSkill', characterId: character.characterId, skillId: skill.skillId })), undefined, 'trash')); else skillMeta.appendChild(makeChip(t('syncedSkillLocked'))); skillMeta.appendChild(button(`↗ ${t('open')}`, 'action-button action-open compact', () => postOpen('character', { characterId: character.characterId, skillId: skill.skillId }), t('openSource'))); head.appendChild(skillMeta); card.appendChild(head); @@ -463,7 +467,7 @@ function renderCharacterDetail(character) { const block = element('section', 'enhancement'); const enhancementHead = element('div', 'enhancement-head'); const name = element('div', 'enhancement-name', enhancement.name); if (enhancement.visiblePulse) name.appendChild(element('span', 'pulse', t('visiblePulse'))); const enhancementActions = element('div', 'enhancement-actions'); - enhancementActions.append(button(`✎ ${t('modify')}`, 'action-button action-edit compact', () => showEnhancementEditor(character, skill, enhancement, index), t('modifyEnhancement')), button(`× ${t('delete')}`, 'action-button action-delete compact', () => confirmDelete(enhancement.name, () => mutate({ action: 'deleteEnhancement', characterId: character.characterId, skillId: skill.skillId, enhancementIndex: index })))); + enhancementActions.append(button(t('modify'), 'action-button action-edit compact', () => showEnhancementEditor(character, skill, enhancement, index), t('modifyEnhancement'), 'edit'), button(t('delete'), 'action-button action-delete compact', () => confirmDelete(enhancement.name, () => mutate({ action: 'deleteEnhancement', characterId: character.characterId, skillId: skill.skillId, enhancementIndex: index }))), undefined, 'trash')); enhancementHead.append(name, enhancementActions); block.appendChild(enhancementHead); if (enhancement.triggerText) block.appendChild(element('div', 'enhancement-trigger', enhancement.triggerText)); if (enhancement.enhancementEffect) block.appendChild(element('div', 'item-sub', enhancement.enhancementEffect)); @@ -507,7 +511,7 @@ function renderCharacterDetail(character) { } body.appendChild(block); } - body.appendChild(button(`+ ${t('addEnhancement')}`, 'action-button action-add compact add-enhancement-action', () => showEnhancementEditor(character, skill, null, -1))); + body.appendChild(button(t('addEnhancement'), 'action-button action-add compact add-enhancement-action', () => showEnhancementEditor(character, skill, null, -1), undefined, 'add')); card.appendChild(body); $('characterDetail').appendChild(card); } } diff --git a/media/characterManager/characterManager.css b/media/characterManager/characterManager.css index 5323e71c..4ab3b7c8 100644 --- a/media/characterManager/characterManager.css +++ b/media/characterManager/characterManager.css @@ -27,31 +27,29 @@ button.icon { padding: 4px 7px; min-width: 28px; } button.utility-button { width: 30px; height: 30px; - border-color: var(--border); + border-color: color-mix(in srgb, var(--border) 55%, transparent); background: var(--bg-control); color: var(--text-primary); padding: 0; font-size: var(--font-lg); - box-shadow: var(--shadow-sm); } button.utility-button:hover { - border-color: color-mix(in srgb, var(--accent) 65%, var(--border)); + border-color: var(--border); background: var(--bg-control-hover); } button.action-button { display: inline-flex; align-items: center; justify-content: center; - gap: 5px; + gap: var(--space-xs); min-height: 30px; - border-color: var(--border); + border-color: color-mix(in srgb, var(--border) 55%, transparent); padding: 4px 10px; font-weight: var(--weight-medium); line-height: 1.2; white-space: nowrap; - box-shadow: var(--shadow-sm); } -button.action-button:hover { box-shadow: var(--shadow); } +button.action-button:hover { border-color: var(--border); } button.action-button:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; } button.action-button.compact { min-height: 26px; padding: 3px 8px; font-size: var(--font-xs); } button.action-add, button.action-save { @@ -61,14 +59,14 @@ button.action-add, button.action-save { } button.action-add:hover, button.action-save:hover { background: var(--btn-bg-hover); } button.action-edit { - border-color: color-mix(in srgb, var(--accent) 65%, var(--border)); + border-color: color-mix(in srgb, var(--border) 60%, transparent); background: var(--btn-secondary-bg); color: var(--btn-secondary-fg); } button.action-edit:hover { background: var(--btn-secondary-bg-hover); } button.action-open { - border-color: color-mix(in srgb, var(--info) 60%, var(--border)); - background: color-mix(in srgb, var(--info) 9%, var(--surface)); + border-color: color-mix(in srgb, var(--border) 55%, transparent); + background: color-mix(in srgb, var(--info) 8%, var(--surface)); color: var(--text-primary); } button.action-open:hover { background: color-mix(in srgb, var(--info) 18%, var(--hover)); } @@ -94,7 +92,7 @@ input::placeholder, textarea::placeholder { color: var(--input-placeholder); } border-bottom: 1px solid var(--border); background: var(--bg-container-raised); } -.title-row { min-height: 42px; display: flex; gap: 10px; align-items: center; padding: 7px 12px; } +.title-row { min-height: 42px; display: flex; gap: var(--space-md); align-items: center; padding: var(--space-sm) var(--space-md); } .title { font-size: var(--font-lg); font-weight: var(--weight-bold); white-space: nowrap; } #project { color: var(--muted); font-size: var(--font-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .spacer { flex: 1; } @@ -126,12 +124,12 @@ input::placeholder, textarea::placeholder { color: var(--input-placeholder); } flex: 0 0 auto; display: grid; grid-template-columns: repeat(7, minmax(92px, 1fr)); - gap: 6px; - padding: 8px 10px; - border-bottom: 1px solid var(--border); + gap: var(--space-sm); + padding: var(--space-sm) var(--space-md); + border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); background: var(--surface2); } -.metric { border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); padding: 6px 8px; } +.metric { border: 1px solid color-mix(in srgb, var(--border) 40%, transparent); border-radius: var(--radius-sm); background: var(--bg-row); padding: var(--space-sm) var(--space-sm); } .metric-value { font-size: var(--font-xl); font-weight: var(--weight-bold); } .metric-label { color: var(--muted); font-size: var(--font-2xs); margin-top: 1px; } .metric.error .metric-value { color: var(--danger); } @@ -225,10 +223,10 @@ input::placeholder, textarea::placeholder { color: var(--input-placeholder); } .chip { display: inline-flex; align-items: center; - gap: 4px; - border: 1px solid var(--border); + gap: var(--space-xs); + border: 1px solid color-mix(in srgb, var(--border) 50%, transparent); border-radius: var(--radius-pill); - background: var(--surface); + background: var(--bg-row); padding: 2px 7px; font-size: var(--font-xs); } @@ -262,7 +260,7 @@ input::placeholder, textarea::placeholder { color: var(--input-placeholder); } .locale-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .section-title { display: flex; align-items: center; gap: 6px; font-size: var(--font-md); font-weight: var(--weight-bold); margin: 13px 0 7px; } .section-title > .action-button { margin-left: 3px; } -.skill-card { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); margin-bottom: 8px; overflow: hidden; } +.skill-card { border: 1px solid color-mix(in srgb, var(--border) 45%, transparent); border-radius: var(--radius-md); background: var(--surface); margin-bottom: var(--space-sm); overflow: hidden; } .skill-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border); } .skill-name { font-size: var(--font-lg); font-weight: var(--weight-bold); } .skill-id { color: var(--muted); font-family: var(--font-mono); font-size: var(--font-2xs); } @@ -335,10 +333,10 @@ input::placeholder, textarea::placeholder { color: var(--input-placeholder); } } .enhancement { border-left: 3px solid var(--accent); - padding: 7px 9px; - margin-top: 8px; - background: color-mix(in srgb, var(--accent) 7%, transparent); - border-radius: 0 4px 4px 0; + padding: var(--space-sm) var(--space-md); + margin-top: var(--space-sm); + background: color-mix(in srgb, var(--accent) 6%, transparent); + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; } .enhancement-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; min-height: 30px; } .enhancement-name { flex: 1 1 auto; min-width: 0; font-weight: var(--weight-bold); } @@ -415,7 +413,7 @@ th.sticky { z-index: 4; background: var(--bg-container); } max-height: 90vh; display: flex; flex-direction: column; - border: 1px solid var(--border); + border: 1px solid color-mix(in srgb, var(--border) 55%, transparent); border-radius: var(--radius-lg); background: var(--bg-container); box-shadow: var(--shadow-lg); @@ -457,7 +455,7 @@ th.sticky { z-index: 4; background: var(--bg-container); } .effect-select { min-height: 210px; font-family: var(--font-mono); font-size: var(--font-xs); } .effect-editor-hint { color: var(--muted); font-size: var(--font-2xs); margin-top: 4px; } .effect-params { display: flex; flex-direction: column; gap: 6px; max-height: 310px; overflow: auto; } -.effect-param-row { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px 7px; background: var(--surface); } +.effect-param-row { border: 1px solid color-mix(in srgb, var(--border) 45%, transparent); border-radius: var(--radius-sm); padding: var(--space-sm); background: var(--bg-row); } .effect-param-title { font-family: var(--font-mono); font-size: var(--font-xs); font-weight: var(--weight-bold); margin-bottom: 5px; } .effect-param-desc { color: var(--muted); font-size: var(--font-2xs); margin-bottom: 5px; } .effect-param-grid { display: grid; grid-template-columns: repeat(4, minmax(70px, 1fr)); gap: 5px; } diff --git a/media/characterManager/index.html b/media/characterManager/index.html index c4eb05f4..f26f364a 100644 --- a/media/characterManager/index.html +++ b/media/characterManager/index.html @@ -3,8 +3,9 @@ - + + @@ -17,7 +18,7 @@
- +