UXP Panelの概念
ご存知の通りUXPもCEP同様ブラウザー、もしくは似たようなシステムがベースのパネルにHTMLとCSSで インターフェースを構築していくのですがパネル自体の核となるシステムのカスタマイズはHTMLではなく JavaScriptとmanifestで構築してゆきます。このパネル周りの構成についてのお話になります。今回のパネルの内容は manifestとも関連するのでmanifestの概要も合わせてご覧ください。
パネルの構成を宣言する
まずどうやってパネルシステムの構築をUXP上で行うかの説明になります。これには uxpモジュールのentrypoints.setupメソッドにパネルの情報及びコマンドから発火させる関数をオブジェクトとして渡してパネルの 仕様を宣言します。ただご存知の通りUXPのプラグインはパネルを複数を持つことができるので パネル毎に仕様を決めないといけません。まずは以下、サンプルになります。尚、entrypointsはmanifestとも連動しているので menifest.jsonのサンプルも載せておきます。
パネルがpanelsとなっているのは配列内に複数のパネルの仕様を定義するためです。今回myPanelというパネルのみ扱っています。 それ以外にもpluginはプラグイン自身、 commandsがプラグインパネルのコマンドメニューから発動させる関数の定義となっています。 尚、今回扱う大部分のオブジェクト要素のほとんどがイベントを感知した時に発火するコールバック関数となっています。 まずはpluginの項目から説明します。
create
Pluginが作成(create)された時に発動するコールバック。このcreateというイベントがよくわかっていませんが おそらくPuginが初めて呼び出された時だと思います。現状Puginが初めて呼び出された時に実際に発火しています。destroy
Pluginが破壊(destroy)された時のイベントです。現状イベントの発火自体確認できていません。 本来プラグインがunload(プラグインパネルから除外)された時に発火すべきイベントなのでしょうか?
次にPanelのオブジェクトになります。前述の通りpanelsとなっているので複数のパネルの仕様を扱えるのですが 実際複数のパネルを扱う場合は一気にコードが複雑化するので今回扱いません。
create
Pluginのcreateイベントのパネル版です。パネルが初めて呼び出された時のイベントなのでしょうか? 実際パネルが初めて呼び出された時に実際に発火しています。destroy
Pluhinのdestoryイベントのパネル版です。現状発火自体確認できていません。show
パネルが表示された時に発火するイベントです。しかし現状パネルを非表示した後に表示しても発火されません。 初めて表示された時に発火されるだけです。createとの違いはありません。hide
パネルが非表示になった時のイベント?のようですが現状発火を確認できません。
尚このコールバック関数内でのthisを通じてパネルの情報をオベジェクトとして取得できます。 コールバックの引数からはパネルの情報、もしくはパネルのBody Elementが取得できます。(manifest4と5で異なるなぜ?)
invokeMenu
これはパネルのメニューアイテムの機能関連の項目になります。 このinvokeMenuはコールバック関数でパネルのメニューアイテムが選択された時に 発火して選択されたメニューアイテムのidを受け取ります。しかし各メニューアイテムの状態 はmenuItemsプロパティに配列として渡せます。このmenuItemsのオブジェクトは id,label,checked,enabledのプロパティを持っています。idがメニューアイテムの id、labelが実際に表示されるメニュー項目の名前、checkedがそのままメニューが チャックボックスのようにチェックされているかどうかの項目、enabledが選べるかどうか になります。idの項目が実際選んだ時にコールバックでinvokeMenuコールバック関数で受け取る 事のできるlabelのidです。このidを元にサンプルコードのように発火させる内容を分岐できます。 さらにmenuItemの中にsubmenuを入れることでメニューアイテムの中にメニューアイテムを入れることができます。
commands
コマンドはそのままプラグインのメニューから発火させるコマンドです。関数を渡すことで渡した関数がコマンドを押した時に発火します。 そのまま渡すこともできるがrun,cancelと通常発火するコマンドの関数とキャンセル時のイベントも定義できますが現状cancelは 発火しないみたいです。
実はパネル上のイベントの大半はまだ使えない
ここまで大体説明しましたが実は上記のイベントは大半が現状使えません。known-issuesでも触れられていますがshowイベントは一度しか発火しない、hideは発火そのものが起きない、commandsのcancelは公式のドキュメントでも現状使えないということになっています。destroyについてはよくわかっていません。
Persistence
Photoshop UXPどうも標準でPersistenceがオンになっているようです。つまりパネルの状態が閉じても維持されるため リセットしたければリロードさせるしかありません。ボタンを押すとカウントされてゆくサンプルを作りましたが パネルを閉じてもカウントの数がリセットされません。
複数のパネルを実装する
UXPでは複数のパネルの実装が簡単にできるようになりました。CEPだと基本一つのExtensionに一つのパネルでしたが UXPでは複数のパネルを実装すること前提のシステムになっています。というわけで実装してみます。
manifestとentrypoints
まずはjsで実装する前にmanifestにパネルの情報を宣言します。パネルの宣言についてはmanifestのパネルの設定をご覧ください。複数パネルを実装する場合はmanifestにパネルの項目を実装する分だけ増やせばいいだけです。
次にentrypointsにパネルの情報を設定します。この時JavaScriptとmanifestのパネルの名前とidは必ず一致してなければならないのに注意してください。
これで基本の準備は出来ました。成功すればプラグインパネルに各パネルのボタンが出てきます。
しかしこの時点ですとパネルの中身は空っぽなので実際にHTMLを構築しなければなりません。
HTML
Reactの実装方法なら公式のサンプルがありますがVanilla.jsの場合サンプルなどないので実装について戸惑うでしょう。しかしここでいつも通りhtmlに 要素を書き込んでいくと思わぬ問題に直面します。試しにHTMLにh1を書き込んでみます。
HTMLに書き込んだら最初のパネル上にのみ表示されました。しかしどうやって他のパネルに表示させれば良いのでしょうか? もしくはどうやって表示させるパネルを指定できるのでしょうか。
uxp-panelを使用する。
HTML内にuxp-panel WebComponentを使うと各種パネルスコープを設定できます。 uxp-panelのpanelidとパネルのmanifest idを一致した部分が連動します。uxp-panel内の スコープは同じid内のパネル内に表示されるようになります。
各種パネルのスコープを設定できました。
JSで要素を追加する場合。
JSで要素を追加する場合ですが普通にdocumentから追加しても最初のパネルに要素が追加されるだけなので ここでもやや特殊なやり方で加えなければなりません。以下のようにdocumentに対して加えるのでなく 各パネルのshowコールバックメソッドで受け取るHTMLオブジェクトに対して加える事により各種パネルの スコープ内に要素の追加をできます。
showコールバックメソッドで受け取るオブジェクトですがmanifest4とmanifest5で少し異なるので注意してください。
参考サイト
- 公式サイト Known Issues
- 公式サイト entrypoints
- Manifest 5 - 2 panels in same plugin?