ダイアグラム作成エディター
MPS のダイアグラム表化サポートは言語デザイナーが彼らの概念にグラフィカルエディターを提供することを可能にします。ダイアグラムは通常、ボックスで表されるブロックと、ボックスを結ぶ線で表されるコネクターで構成されています。ブロックとコネクターはどちらも、基礎となるモデルからのノードを視覚化したものです。
ポート(オプション)は、ブロックの形状上の事前定義された場所であり、コネクターを接続できます。MPS では、入力ポートと出力ポートの 2 種類のポートを使用できます。
任意選択で、利用可能なブロックのパレットをダイアグラムの横に表示することができるため、ユーザは、ダイアグラムに追加する必要があるボックスの種類をすばやく選ぶことができます。
要素の追加
エディターの空き領域をダブルクリックすると、ブロックが追加されます。ブロックの種類は、パレットで特定のブロックの種類を有効にするか、空き領域をクリックした後に表示されるポップアップの補完メニューから選択することによって選択されます。
コネクターは、ブロックの出力端子から別のブロックまたは同じブロックの入力端子にドラッグすることによって作成されます。
サンプル
MPS には、ダイアグラムエディターのサンプルがバンドルされています。componentDependencies または mindMaps サンプルプロジェクトを試して、ダイアグラムの作成方法を最初に理解することができます。
依存関係
言語でダイアグラムエディターを定義できるようにするためには、その言語は必要な依存関係と使用言語を適切に設定する必要があります。
jetbrains.mps.lang.editor.diagram- ダイアグラムを定義するための言語
jetbrains.mps.lang.editor.figures (オプション)- カスタム視覚要素を定義するための言語 (ブロックとコネクター)
jetbrains.jetpad および jetbrains.mps.lang.editor.diagram.runtime- ダイアグラムのレンダリングと動作を処理するランタイムライブラリ
ダイアグラム定義
ダイアグラムのルートとなるはずの概念から始めましょう。そのノードのダイアグラムエディターには、ダイアグラムエディターセルが含まれます。
ダイアグラムセルには、ダイアグラムの一部となるすべてのノードを保持するためのコンテンツパラメーターが必要です。この場合、すべてのコンポーネント(ブロックとしてレンダリングされます)とそれらの依存関係(コネクターとしてレンダリングされます)を渡します。これらのノードがレンダリングされる方法は、後で説明するように、それぞれのエディター定義によって定義されます。
インスペクター 要素の作成ハンドラーで定義できます。これらは、ダイアグラムに新しいビジュアルブロックが作成されるたびに呼び出されます。各ハンドラーには、設定するいくつかのプロパティがあります。
名前 - 補完メニューにし、パレットに新しい要素を作成するオプションを表現するために任意の名前
コンテナー - 新しく作成されたノードを追加する必要があるノードのコレクション
概念 - ハンドラーを介して作成されるノードの概念。デフォルトではコンテナー内のノードのタイプになりますが、代わりにサブタイプを指定できます。
on create- モデルに追加されてダイアグラムにレンダリングされる前に、ノードを操作できるハンドラー。通常、名前は意味のある値に設定され、画面上のブロックの位置がモデルに保存されます。
複数の要素作成ハンドラーを定義することができます。
同様に、コネクター作成を処理するために、ダイアグラムセルにコネクター作成ハンドラーを定義できます。要素作成ハンドラーについてすでに説明した属性に加えて、コネクター作成ハンドラーには以下の特定の属性があります。
作成可能 - ブール値を返し、指定されたプロパティを持つコネクターを合法的に構築してダイアグラムに追加できるかどうかを示す概念関数。
oncreate -now コネクターの作成を処理する概念関数。
これらの関数の from パラメーターと to パラメーターは、新しい接続のソースノードとターゲットノード(ブロックまたはポートで表される)を指定します。
これらの関数の fromId および toId パラメーターは、新しい接続のソースノードとターゲットノード(ブロックまたはポートで表される)の ID を指定します。
ユーザーがエディターをダブルクリックすると、要素が作成されます。複数の要素タイプが利用可能な場合は、補完ポップアップメニューが表示されます。
コネクターは、ユーザーがソースブロックまたはその出力ポートからターゲットブロックまたはその入力ポートにドラッグすると作成されます。
パレット
オプションのパレットを使用すると、開発者はダイアグラム内をダブルクリックまたはドラッグするたびに、作成するブロックとリンクの種類を選択できます。パレットはダイアグラムエディターセル用に定義されており、作成コンポーネントの指定とは別に、視覚的なグループ化とパレットアイテムの分離を可能にします。
ブロック
ブロックとしてダイアグラム表化に参加したいノードの概念は、x/y 座標、サイズ、色、タイトルなどの有用なダイアグラム表化品質を保持するプロパティを提供する必要があります。
さらに、ノードは、コネクターが視覚的に接続できる入力ポートと出力ポートを提供する必要があります。
次に、エディターはダイアグラムノードセルを使用します。
ダイアグラムノードセルでは、フィギュアを指定する必要があります。これは、jetpad フレームワークを使用してブロックの視覚的なレイアウトを定義する Figure クラスへの参照です。MPS には、jetbrains.mps.lang.editor.figures.library ソリューションに事前定義された一連のグラフィックシェイプが付属しており、インポートして使用できます。各ダイアグラムは、ダイアグラムの視覚的特性を保持するいくつかのプロパティフィールドを公開する場合があります。すべての Figure パラメーターは、エディター定義で指定する必要があります。ほとんどの場合、概念で定義されているノードのプロパティにマッピングします。
パラメーターの値は、エーテル # 文字で先頭に追加ノードのプロパティへの参照、または BaseLanguage 表現かもしれません。これを使用して、式内から編集されたノードを参照できます。
ノードが入力ポートと出力ポートを定義している場合は、ダイアグラムに表示されるように、ここでもパラメーターとして指定する必要があります。ここでも、ポートを指定するには、ノードのプロパティを参照するか、# 文字を前に付けた BaseLanguage 式を使用できます。
カスタム図
または、独自の図を定義することもできます。これらは BaseLanguage の jetbrains.jetpad.projectional.view.View インターフェース(またはその子孫)を実装するクラスと @Figure アノテーションを付けています。@FigureParameter アノテーションを使用して、幅、高さなどのプロパティフィールドを区別します。
MovableContentView インターフェースは、Figure クラスに追加のパラメーターを提供します。
jetbrains.mps.lang.editor.figures.library を研究することで、jetpad ライブラリとその内部動作をよりよく理解できるようになります。
コネクター
コネクターで表されるノードは、ダイアグラム作成プロパティを保持する必要はありません。バージョン 3.1 では、コネクターは視覚的にカスタマイズできず、常に黒い実線で表示されます。これは、MPS の以下のバージョンのうちの 1 つでおそらく変わるでしょう。
ノードのエディターには、ダイアグラムコネクターセルを含める必要があります。
セルには、コネクターのソースとターゲットが必要です。これらはポートにすることができます。
またはノード自体:
値が再び # 文字で先頭に追加ノードのプロパティまたは BaseLanguage 式への直接参照することがあります。
レンダリングポート
入力ポートと出力ポートは、それぞれ入力ポートと出力ポートのエディターセルを使用する必要があります。ポートのレンダリングは MPS 3.1 でカスタマイズできませんが、それ以降のバージョンで有効になる可能性があります。
暗黙的ポートの使用
状況によっては、モデル内で直接ポートを表現できないことがあります。ブロックとコネクターのみを使用したいのですが、ポートはどういうわけかモデルから派生する必要があります。このケースは簡単にサポートできます。
ポートの表現を決めます。各ポートは、番号や文字列などの一意の識別子で表されます。
ブロックの概念に、識別子のコレクションを返す動作メソッドを定義させる - 入力ポートと出力ポートに別々に
メソッドを使用して inputPorts および outputPorts パラメーターを DiagramNode エディターセルに提供します
コネクターエディターのセルで、ブロックのノードをソースとターゲットとして参照します。# シンボルの後に要求された ID を追加します