Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/box-resources.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[简体中文](box-resources.md) | [English](box-resources.en.md)

Verified against current local implementations on 2026-10-08. Both hosts use unified annotation management and resource previews. This document describes the current data and operation contracts; see [Feature Parity](feature-parity.en.md) for entry points and verification status.
Verified against current local implementations on 2026-10-13. Both hosts use unified annotation management and resource previews. This document describes the current data and operation contracts; see [Feature Parity](feature-parity.en.md) for entry points and verification status.

## Authoring and Published Files

Expand Down Expand Up @@ -33,7 +33,7 @@ Historical `version` / `boxes` and `version` / `points` authoring formats are no

## Annotation Management

The unified entry provides import, capture, temporary screenshot drops, filename or Template category search, editing, source-image viewing, Template annotation swaps, deletion, and publication. Swapping preserves the existing Template operation scope in both hosts; Rect / Point remain editable in the unified editor.
The unified entry provides import, capture, temporary screenshot drops, filename, Template, Box, or Point name search, editing, source-image viewing, Template annotation swaps, deletion, and publication. Swapping preserves the existing Template operation scope in both hosts; Rect / Point remain editable in the unified editor.

Template swaps between differently sized images scale and clamp coordinates, show image sizes and annotation counts before confirmation, and verify source annotations and image sizes again before saving.

Expand All @@ -53,10 +53,14 @@ Side and wide previews support Template / Rect / Point modes and name/expression
| Rect | `self.pos.<path>.to_box()` |
| Point | `self.pos.<path>` |

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.
Single click inserts; double click copies. Buttons expose the same actions. View original resolves the unique name against current authoring annotations, opens the existing unified editor in Template / Rect / Point mode, and selects and reveals the target. Missing annotations produce a resource warning without falling back to stale card or runtime atlas coordinates. 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.

Box / Point names in annotation management are search indexes only. They do not appear as image metadata or create persisted source fields. Lookup uses the existing `category_id` / `image_id` relationships.

`self.pos` completion remains hierarchical by dot-separated path. Intermediate nodes contain only the path segment. Leaves show `Box · width×height` or `Point · (x, y)`. Source previews are generated only when a leaf is selected; completion details share the Hover formatter. Boxes use `.to_box()` and show bbox geometry. Points use direct position expressions and pixel coordinates, with a cross marking the location. Position hints work directly from unpublished authoring data. When Rect and Point share a name, existing references preserve the expression type: `.to_box()` selects Rect, while a direct position expression prefers Point. A direct reference remains supported when only Rect exists. Completion without a suffix keeps one path candidate and combines both resource details instead of duplicating namespace entries.

## Unified Publication

Select Template / Rect / Point, then configure the selected resources. All configuration and cancellation decisions precede writes. Position failure or rejected overwrite stops subsequent Template writes. Templates retain existing packing and enum generation, including class-name and project-reference checks before overwriting enums.
Expand Down
10 changes: 7 additions & 3 deletions docs/box-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[简体中文](box-resources.md) | [English](box-resources.en.md)

2026-10-08 按当前本地实现复核。两端使用统一标注管理和资源预览,本文说明当前数据与操作契约。完整入口及验证状态见 [功能对齐表](feature-parity.md)。
2026-10-13 按当前本地实现复核。两端使用统一标注管理和资源预览,本文说明当前数据与操作契约。完整入口及验证状态见 [功能对齐表](feature-parity.md)。

## 工作文件与发布文件

Expand Down Expand Up @@ -33,7 +33,7 @@ Rect / Point 名称至少包含两个由句点分隔的 Python 标识符,例

## 标注管理

统一入口提供导入、截图、临时截图拖入、按文件名或 Template 分类搜索、编辑、查看原图、交换 Template 标注、删除和发布。交换保持两端现有 Template 操作范围;Rect / Point 可在统一编辑器中修改。
统一入口提供导入、截图、临时截图拖入、按文件名、Template、Box 或 Point 名称搜索、编辑、查看原图、交换 Template 标注、删除和发布。交换保持两端现有 Template 操作范围;Rect / Point 可在统一编辑器中修改。

交换不同尺寸原图的 Template 标注时按比例映射并钳制边界,确认前显示尺寸和标注数量;保存前核对源标注与图片尺寸是否变化。

Expand All @@ -53,10 +53,14 @@ Rect / Point 名称至少包含两个由句点分隔的 Python 标识符,例
| Rect | `self.pos.<路径>.to_box()` |
| Point | `self.pos.<路径>` |

单击插入,双击复制;按钮提供相同动作和带位置提示的原图查看。没有 Python 编辑器时复制引用并说明原因。Template 预览不会用尚未发布的工作标注填充运行时库;Rect / Point 提示跟随当前工作标注,编辑后不需要先发布才能得到代码提示。
单击插入,双击复制;按钮提供相同动作;“查看原图”按当前唯一名称从工作标注中反查原图,打开已有统一编辑器,切到对应 Template / Rect / Point 模式,选中并显示目标。找不到当前标注时提示资源缺失,不使用旧卡片或运行时图集坐标打开其他原图。没有 Python 编辑器时复制引用并说明原因。Template 预览不会用尚未发布的工作标注填充运行时库;Rect / Point 提示跟随当前工作标注,编辑后不需要先发布才能得到代码提示。

两端 `Ctrl+Alt+T` 打开资源预览,`Ctrl+Alt+S` 截图到标注管理;macOS 使用相应的 `Cmd+Alt` 组合。发布入口位于标注管理,资源预览不提供另一个发布链。

标注管理的 Box / Point 名称只用于搜索筛选,不显示为图片元信息,也不写入额外来源字段。反查始终沿用现有 `category_id` / `image_id` 关系。

`self.pos` 继续按句点逐层补全。中间节点只有路径段;叶子显示 `Box · 宽×高` 或 `Point · (x, y)`。选中叶子后才生成原图位置预览,详情与 Hover 共用。Box 使用 `.to_box()` 表达式并显示 bbox;Point 使用直接位置表达式和像素坐标,预览以十字标记定位。未发布的工作标注可直接用于位置提示;同名 Rect / Point 的已有引用按表达式区分类型:`.to_box()` 指向 Rect,直接位置表达式优先匹配 Point;仅有 Rect 时仍支持直接引用。没有后缀信息的补全叶子保留一个路径候选,并汇总两类详情,不增加重复路径项。

## 统一发布

先选择 Template / Rect / Point,再完成所选资源的配置。全部配置与取消决定发生在写盘前;位置拒绝覆盖或发布失败后不继续写模板。模板仍使用已有打包与枚举生成链,覆盖已有枚举前核对类名变化和项目引用。
Expand Down
2 changes: 1 addition & 1 deletion jetbrains
Submodule jetbrains updated 22 files
+3 −4 build.gradle.kts
+1 −1 src/main/kotlin/com/alicejump/okscripttoolkit/core/AnnotatedImageCache.kt
+12 −7 src/main/kotlin/com/alicejump/okscripttoolkit/core/AnnotatedSourcePreview.kt
+62 −0 src/main/kotlin/com/alicejump/okscripttoolkit/core/ResourceAuthoring.kt
+12 −11 src/main/kotlin/com/alicejump/okscripttoolkit/editor/OkCompletionContributor.kt
+11 −0 src/main/kotlin/com/alicejump/okscripttoolkit/editor/OkDocumentationProvider.kt
+59 −89 src/main/kotlin/com/alicejump/okscripttoolkit/editor/OkEditorSupport.kt
+6 −19 src/main/kotlin/com/alicejump/okscripttoolkit/ui/PreviewCardToolWindows.kt
+7 −27 src/main/kotlin/com/alicejump/okscripttoolkit/ui/TemplatesToolWindowFactory.kt
+35 −0 src/main/kotlin/com/alicejump/okscripttoolkit/ui/UnifiedAnnotationEditor.kt
+21 −0 src/main/kotlin/com/alicejump/okscripttoolkit/ui/UnifiedAnnotationUi.kt
+11 −6 src/main/kotlin/com/alicejump/okscripttoolkit/ui/UnifiedPublishToolWindows.kt
+7 −0 src/main/resources/html/position-documentation.html
+8 −0 src/main/resources/html/template-documentation.html
+2 −0 src/main/resources/messages/OkScriptToolkitAnnotationBundle.properties
+2 −0 src/main/resources/messages/OkScriptToolkitAnnotationBundle_es.properties
+2 −0 src/main/resources/messages/OkScriptToolkitAnnotationBundle_ja.properties
+2 −0 src/main/resources/messages/OkScriptToolkitAnnotationBundle_ko.properties
+2 −0 src/main/resources/messages/OkScriptToolkitAnnotationBundle_zh_CN.properties
+2 −0 src/main/resources/messages/OkScriptToolkitAnnotationBundle_zh_TW.properties
+33 −0 src/test/kotlin/com/alicejump/okscripttoolkit/core/AnnotatedSourcePreviewTest.kt
+42 −0 src/test/kotlin/com/alicejump/okscripttoolkit/editor/PositionReferenceTest.kt
3 changes: 2 additions & 1 deletion l10n/bundle.l10n.es.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,6 @@
"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.",
"The resource was not found in current annotations: {name}": "No se encontró el recurso en las anotaciones actuales: {name}"
}
3 changes: 2 additions & 1 deletion l10n/bundle.l10n.ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,6 @@
"Could not publish positions: {error}": "位置リソースを公開できませんでした: {error}",
"Published positions: {files}": "位置リソースを公開しました: {files}",
"Resource Preview": "リソースプレビュー",
"No annotations available to publish.": "公開できるアノテーションはありません。"
"No annotations available to publish.": "公開できるアノテーションはありません。",
"The resource was not found in current annotations: {name}": "現在のアノテーションにリソースが見つかりません: {name}"
}
3 changes: 2 additions & 1 deletion l10n/bundle.l10n.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,6 @@
"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.",
"The resource was not found in current annotations: {name}": "The resource was not found in current annotations: {name}"
}
3 changes: 2 additions & 1 deletion l10n/bundle.l10n.ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,6 @@
"Could not publish positions: {error}": "위치 리소스를 게시할 수 없습니다: {error}",
"Published positions: {files}": "게시된 위치 리소스: {files}",
"Resource Preview": "리소스 미리보기",
"No annotations available to publish.": "게시할 주석이 없습니다."
"No annotations available to publish.": "게시할 주석이 없습니다.",
"The resource was not found in current annotations: {name}": "현재 어노테이션에서 리소스를 찾을 수 없습니다: {name}"
}
3 changes: 2 additions & 1 deletion l10n/bundle.l10n.zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,6 @@
"Could not publish positions: {error}": "无法发布位置资源:{error}",
"Published positions: {files}": "已发布位置资源:{files}",
"Resource Preview": "资源预览",
"No annotations available to publish.": "没有可发布的标注。"
"No annotations available to publish.": "没有可发布的标注。",
"The resource was not found in current annotations: {name}": "当前标注中未找到资源:{name}"
}
3 changes: 2 additions & 1 deletion l10n/bundle.l10n.zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,6 @@
"Could not publish positions: {error}": "無法發佈位置資源:{error}",
"Published positions: {files}": "已發佈位置資源:{files}",
"Resource Preview": "資源預覽",
"No annotations available to publish.": "沒有可發佈的標註。"
"No annotations available to publish.": "沒有可發佈的標註。",
"The resource was not found in current annotations: {name}": "目前標註中找不到資源:{name}"
}
2 changes: 1 addition & 1 deletion l10n/webview.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"accountStoreSeeOutput": "See the \"ok-script Console\" output channel for details.",
"accountReadFailed": "Store file could not be parsed (see executor output).",
"overriddenTasksLabel": "Overridden tasks",
"templatesSearch": "Search template names…",
"templatesSearch": "Search image / Template / Box / Point names…",
"templatesTitle": "Template Gallery",
"templatesHint": "Click=insert · Double-click=copy · Use the bottom-right buttons for direct actions",
"templatesCount": "{shown}/{total} templates",
Expand Down
2 changes: 1 addition & 1 deletion l10n/webview.es.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"accountStoreSeeOutput": "Consulte el canal de salida \"ok-script Console\" para más detalles.",
"accountReadFailed": "No se pudo analizar el archivo del almacén (ver la salida del ejecutor).",
"overriddenTasksLabel": "Tareas con anulaciones",
"templatesSearch": "Buscar nombres de plantillas…",
"templatesSearch": "Buscar nombres de imagen / Template / Box / Point…",
"templatesTitle": "Galería de plantillas",
"templatesHint": "Clic=insertar · Doble clic=copiar · Use los botones inferiores derechos para acciones directas",
"templatesCount": "{shown}/{total} plantillas",
Expand Down
2 changes: 1 addition & 1 deletion l10n/webview.ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"accountStoreSeeOutput": "詳細は出力チャンネル「ok-script Console」を参照。",
"accountReadFailed": "ストアファイルを解析できません(実行器の出力を参照)。",
"overriddenTasksLabel": "上書きありのタスク",
"templatesSearch": "テンプレート名を検索…",
"templatesSearch": "画像 / Template / Box / Point 名を検索…",
"templatesTitle": "テンプレートギャラリー",
"templatesHint": "クリック=挿入 · ダブルクリック=コピー · 右下のボタンで直接操作",
"templatesCount": "{shown}/{total} テンプレート",
Expand Down
2 changes: 1 addition & 1 deletion l10n/webview.ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"accountStoreSeeOutput": "자세한 원인은 출력 채널 \"ok-script Console\"을 참조하세요.",
"accountReadFailed": "스토어 파일을 해석할 수 없습니다(실행기 출력 참조).",
"overriddenTasksLabel": "재정의가 있는 작업",
"templatesSearch": "템플릿 이름 검색…",
"templatesSearch": "이미지 / Template / Box / Point 이름 검색…",
"templatesTitle": "템플릿 갤러리",
"templatesHint": "클릭=삽입 · 더블클릭=복사 · 오른쪽 아래 버튼으로 바로 실행",
"templatesCount": "{shown}/{total} 템플릿",
Expand Down
2 changes: 1 addition & 1 deletion l10n/webview.zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"accountStoreSeeOutput": "具体原因见输出频道「ok-script Console」。",
"accountReadFailed": "存储文件无法解析(详情见执行器输出)。",
"overriddenTasksLabel": "有覆盖的任务",
"templatesSearch": "搜索模板名…",
"templatesSearch": "搜索图片 / Template / Box / Point 名称…",
"templatesTitle": "模板面板",
"templatesHint": "单击=插入 · 双击=复制 · 右下角按钮可直接操作",
"templatesCount": "{shown}/{total} 个模板",
Expand Down
2 changes: 1 addition & 1 deletion l10n/webview.zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
"accountStoreSeeOutput": "具體原因見輸出頻道「ok-script Console」。",
"accountReadFailed": "儲存檔案無法解析(詳見執行器輸出)。",
"overriddenTasksLabel": "有覆寫的任務",
"templatesSearch": "搜尋模板名稱…",
"templatesSearch": "搜尋圖片 / Template / Box / Point 名稱…",
"templatesTitle": "模板面板",
"templatesHint": "單擊=插入 · 雙擊=複製 · 右下角按鈕可直接操作",
"templatesCount": "{shown}/{total} 個模板",
Expand Down
23 changes: 19 additions & 4 deletions media/annotationPanel/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,8 @@
if (msg.type !== 'load') return;

const incomingMode = msg.annotationMode || annotationMode;
if (pendingMode && incomingMode !== pendingMode) return;
if (pendingMode && incomingMode !== pendingMode && !msg.focusName) return;
if (msg.focusName) { pendingMode = null; modeLoading = false; }
if (pendingMode === incomingMode) { pendingMode = null; modeLoading = false; }
const newImageKey = msg.filename || '';
const imageChanged = currentImageKey && currentImageKey !== newImageKey;
Expand All @@ -1150,16 +1151,30 @@
listSignature = '';
updateStaticText();

function focusResource() {
if (!msg.focusName || !img) return;
const index = annotations.findIndex(ann => ann.category === msg.focusName);
if (index < 0) return;
const ann = annotations[index];
hiddenSet().delete(ann.category);
selectOnly(index);
if (!pointMode) scale = Math.max(fitScale, Math.min(scale,
Math.max(1, canvas.width - 40) / ann.w, Math.max(1, canvas.height - 40) / ann.h));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
offsetX = canvas.width / 2 - (ann.x + (pointMode ? 0 : ann.w / 2)) * scale;
offsetY = canvas.height / 2 - (ann.y + (pointMode ? 0 : ann.h / 2)) * scale;
recalcOffset();
canvas.focus();
}
const needImageLoad = !img || imageChanged;
if (msg.imageBase64 && needImageLoad) {
img = new Image();
img.onload = () => {
emptyMsg.style.display = 'none'; canvas.style.display = 'block';
recalcFit(); scale = fitScale; recalcOffset(); loadImgData(); paint();
recalcFit(); scale = fitScale; recalcOffset(); loadImgData(); focusResource(); paint();
};
img.src = msg.imageBase64;
} else if (msg.imageBase64 && img) {
emptyMsg.style.display = 'none'; canvas.style.display = 'block'; paint();
emptyMsg.style.display = 'none'; canvas.style.display = 'block'; focusResource(); paint();
} else {
img = null; imgData = null; canvas.style.display = 'none'; emptyMsg.style.display = 'flex'; syncAnnotationList();
}
Expand All @@ -1173,4 +1188,4 @@
resize();
updateStaticText();
vscode.postMessage({ type:'ready' });
})();
})();
2 changes: 1 addition & 1 deletion media/templateAssetPanel/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
for (const [name, card] of cards) {
const meta = metas.find(m => m.name === name);
const ok = !q || name.toLowerCase().includes(q) ||
(meta && meta.categories.some(c => c.toLowerCase().includes(q)));
(meta && [...meta.categories, ...(meta.searchNames || [])].some(c => c.toLowerCase().includes(q)));
card.style.display = ok ? '' : 'none';
if (ok) shown++;
}
Expand Down
2 changes: 1 addition & 1 deletion media/templatePanel/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
ThumbnailActions.button('+', t('insertExpression'), () => vscode.postMessage({ type: 'insert', expression: meta.expression })),
ThumbnailActions.button('⧉', t('copyExpression'), () => vscode.postMessage({ type: 'copy', expression: meta.expression })),
ThumbnailActions.button('👁', t('viewOriginal'), () => vscode.postMessage({
type: 'open', imagePath: meta.imagePath, name: meta.name, bbox: JSON.stringify(meta.bbox),
type: 'open', mode: meta.kind, name: meta.name,
})),
);
box.appendChild(actions);
Expand Down
Loading
Loading