From c825fb3f743474c0a48b830200a20dd44875c454 Mon Sep 17 00:00:00 2001 From: "ry.yamafuji" Date: Sat, 7 Jun 2025 19:59:28 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B9=E3=83=86=E3=83=83=E3=83=971=E5=AE=9F?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pg_task.md | 56 +++++++++++++++++++++++ docs/tips.md | 117 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 19 ++++++-- src/extension.ts | 11 ++++- 4 files changed, 197 insertions(+), 6 deletions(-) create mode 100644 docs/pg_task.md create mode 100644 docs/tips.md diff --git a/docs/pg_task.md b/docs/pg_task.md new file mode 100644 index 0000000..f797e8e --- /dev/null +++ b/docs/pg_task.md @@ -0,0 +1,56 @@ +# ImageMarkPengent 実装タスク + +## 0. チュートリアル:現状の拡張機能をビルド・実行する + +1. 依存パッケージのインストール(初回のみ) + ```sh + yarn install + ``` +2. ビルド + ```sh + yarn compile + ``` +3. VSCodeでこのプロジェクト(imagemarkpengent)を開く +4. F5キー(または「実行とデバッグ」→「拡張機能のデバッグ」)で新しいVSCodeウィンドウが起動し、拡張機能が有効化される +5. コマンドパレット(Ctrl+Shift+P)で `Hello World` コマンドを実行できる + + + + +--- + +## 概要 +VSCode拡張機能「ImageMarkPengent」の実装タスク一覧です。 + +--- + +## 実装ステップ + +### 1. コマンド登録と右クリックメニュー対応 +- [x] `package.json` にコマンドを登録する +- [x] `explorer/context` メニューに「Open in ImageMarkPengent」を追加 +- [ ] 対象拡張子を `.png` / `.jpg` / `.jpeg` に限定 + +### 2. WebViewで画像表示 +- [ ] コマンド実行時にWebViewパネルを開く +- [ ] 画像ファイルを `` または `` で表示 +- [ ] 画像の上に描き込み可能な `canvas` を重ねる + +### 3. 赤丸マーク描画機能 +- [ ] WebView内でJavaScriptにより `` へ赤丸を描画 +- [ ] クリック座標を取得し、赤丸を描画・保持 +- [ ] 複数マークの描画・再描画に対応 + +### 4. 加工画像の保存機能 +- [ ] WebViewに「保存」ボタンを設置 +- [ ] `canvas.toDataURL()` で画像データを取得 +- [ ] `vscode.postMessage()` で拡張機能側に送信 +- [ ] 拡張機能側でファイル保存(別名保存も対応) + +--- + +## 今後の拡張案(任意) +- 番号付きマーカーや矢印の追加 +- マークの色やサイズ変更 +- Undo/Redo機能 +- 他画像フォーマット対応 \ No newline at end of file diff --git a/docs/tips.md b/docs/tips.md new file mode 100644 index 0000000..b74eaff --- /dev/null +++ b/docs/tips.md @@ -0,0 +1,117 @@ +# VSCode拡張機能開発TIPS(ImageMarkPengent) + +## Vscodeの起動イメージ + +```mermaid +flowchart TD + A["拡張機能の起動"] --> B["コマンドやイベントリスナーを登録"] + B --> C["Disposableをcontext.subscriptionsにpush"] + C --> D["拡張機能の終了"] + D --> E["VSCodeが自動でdispose()を呼び出し、リソース解放"] +``` + + +## よく使うAPI・ポイント + +- `vscode.window.showInformationMessage('メッセージ')` + - 右下に情報メッセージを表示できる。デバッグやユーザー通知に便利。 + +- `console.log('メッセージ')` + - 拡張機能のデバッグ用ログ。VSCodeの「出力」→「拡張機能のログ」で確認できる。 + +- `vscode.commands.registerCommand('コマンドID', () => { ... })` + - コマンドIDはpackage.jsonのcontributes.commandsで定義したものと一致させる必要がある。 + - コマンドの実装はこのコールバック内に記述。 + +- `context.subscriptions.push(オブジェクト)` + - 登録したコマンドやイベントリスナーは、context.subscriptionsにpushしておくと拡張機能の終了時に自動でクリーンアップされる。 + - もう少しかみ砕くと拡張機能が無効化・アンロードされたときに、イベントリスナーやコマンドなどのリソースを自動で解放してくれるという意味です。 + - pushしない場合、拡張機能が終了してもコマンドやリスナーが残り続け、メモリリークや予期しない動作の原因になります。 + +- `activate(context: vscode.ExtensionContext)` + - 拡張機能が有効化されたときに一度だけ呼ばれる初期化関数。 + +- `deactivate()` + - 拡張機能が無効化されたときに呼ばれるクリーンアップ関数。 + +--- + +## その他 +- コマンドの追加や変更を行った場合は、VSCodeの再起動や拡張機能の再読み込み(Reload)を行うと反映されやすい。 + +--- + +## コマンド登録と右クリックメニュー対応 + +### コマンドの登録 + +1. `package.json`にコマンドを登録する +2. contributes.commands に新しいコマンド(例: imagemarkpengent.openImageEditor)を追加 +3. activationEvents にコマンドのonCommandイベントを追加 + * VSCode拡張機能が「いつ有効化(起動)」されるかを決めるトリガーを定義するものです。 + * VSCodeの拡張機能は、「VSCodeの起動時」や「特定のファイルを開いたとき」など、必要なタイミングで初めてメモリにロードされ、activate関数が呼ばれます。 + + +| 設定値 | 説明 | +| ----------------------- | ------------------------------------------------------------ | +| "onCommand:コマンドID" | 指定したコマンドが実行されたときに拡張機能を有効化 | +| "onLanguage:言語ID" | 指定した言語のファイルが開かれたとき | +| "onFileSystem:スキーム" | 指定したファイルシステムスキームのリソースにアクセスしたとき | +| "*" | VSCode起動時に必ず有効化(非推奨:重くなるため) | + + + +```json +"activationEvents": [ + "onCommand:imagemarkpengent.openImageEditor" +], +"contributes": { + "commands": [ + { + "command": "imagemarkpengent.openImageEditor", + "title": "Open in ImageMarkPengent" + } + ], +} +``` + +### 右クリックメニューに対応する + +1. `package.json`にコマンドを登録する +2. contributes.menus に`explorer/context`を追加する + * explorer/context は エクスプローラー(ファイルツリー)で右クリックしたときのコンテキストメニュー +3. menuの内容を追加する + * groupはメニュー内でのコマンドの表示位置を指定するためのグループ名です + * "navigation": ファイルやフォルダをナビゲーション・開く + +```json +"contributes": { + "menus": { + "explorer/context": [ + { + "command": "imagemarkpengent.openImageEditor", + "when": "resourceExtname =~ /\\.(png|jpg|jpeg)$/", + "group": "navigation" + } + ] + } +} +``` + +### 対象拡張子を `.png` / `.jpg` / `.jpeg` に限定 + +基本的には、explorer/context メニューの when 句で拡張子を限定すれば十分ですが +「コマンドの実行自体を拡張子で制御したい」場合は、コマンド実装側でも拡張子チェックを行うのが安全です。 + +#### コマンド側の実装例 + + +```js +vscode.commands.registerCommand('imagemarkpengent.openImageEditor', (uri: vscode.Uri) => { + if (!uri || !uri.fsPath.match(/\.(png|jpg|jpeg)$/i)) { + vscode.window.showWarningMessage('対応画像ファイル(.png, .jpg, .jpeg)を選択してください。'); + return; + } + // ここに画像編集処理 +}); +``` diff --git a/package.json b/package.json index 6f5b1a5..b9d49d3 100644 --- a/package.json +++ b/package.json @@ -9,15 +9,26 @@ "categories": [ "Other" ], - "activationEvents": [], + "activationEvents": [ + "onCommand:imagemarkpengent.openImageEditor" + ], "main": "./out/extension.js", "contributes": { "commands": [ { - "command": "imagemarkpengent.helloWorld", - "title": "Hello World" + "command": "imagemarkpengent.openImageEditor", + "title": "Open in ImageMarkPengent" } - ] + ], + "menus": { + "explorer/context": [ + { + "command": "imagemarkpengent.openImageEditor", + "when": "resourceExtname =~ /\\.(png|jpg|jpeg)$/", + "group": "navigation" + } + ] + } }, "scripts": { "vscode:prepublish": "yarn run compile", diff --git a/src/extension.ts b/src/extension.ts index ed78ee4..adde206 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -14,12 +14,19 @@ export function activate(context: vscode.ExtensionContext) { // Now provide the implementation of the command with registerCommand // The commandId parameter must match the command field in package.json const disposable = vscode.commands.registerCommand('imagemarkpengent.helloWorld', () => { - // The code you place here will be executed every time your command is executed - // Display a message box to the user vscode.window.showInformationMessage('Hello World from ImageMarkPengent!'); }); + const disposableOpenImageEditor = vscode.commands.registerCommand('imagemarkpengent.openImageEditor', (uri: vscode.Uri) => { + if (!uri || !uri.fsPath.match(/\.(png|jpg|jpeg)$/i)) { + vscode.window.showWarningMessage('対応画像ファイル(.png, .jpg, .jpeg)を選択してください。'); + return; + } + vscode.window.showInformationMessage('画像編集コマンドが呼び出されました: ' + uri.fsPath); + }); + context.subscriptions.push(disposable); + context.subscriptions.push(disposableOpenImageEditor); } // This method is called when your extension is deactivated