PPGのイベントを動的に追加する その2

前回の記事に続いて、『PPGのイベントを動的に追加する その2』です。
前回の記事では、最初からイベントの数が決まっている場合限定でしたが、今回はPPG内の他のパラメータによってイベントが増減する、というケースについて考えてみました。

で、とりあえず出来あがったのがコレ↓↓↓

function XSILoadPlugin( in_reg )
{
	in_reg.Author = "";
	in_reg.Name = "AutoEventFunction";
	in_reg.Email = "";
	in_reg.Help = 	"";
	in_reg.Major = 1;
	in_reg.Minor = 0;
	
	in_reg.RegisterCommand("AutoEventFunction","AutoEventFunction");//コマンド
	in_reg.RegisterProperty( "AutoEventFunction" );// プロパティ

	return true;
}

function AutoEventFunction_Init( in_ctxt )
{
	var oCmd;
	oCmd = in_ctxt.Source;
	oCmd.Description = "";
	oCmd.ReturnValue = true;
	return true;
}

function AutoEventFunction_Execute( io_Context )
{
	//選択オブジェクト内にカスタムプロパティ作成
	var oProp = Selection(0).AddProperty("AutoEventFunction",false);
	InspectObj(oProp,null,null,siLock);
	return oProp;
}

function AutoEventFunction_OnInit(io_Context )
{
	MakeParam();	//パラメータ作成
	PPG.Refresh();	//レイアウトの作成
	MakeLayout();
}

//パラメータの作成
function MakeParam(){
	var oProp = PPG.Inspected.Item(0);
	oProp.AddParameter2("iCount",siInt4,0);//ボタンの数を定義する
}

//レイアウトの作成
function MakeLayout( io_Context )
{
	var oProp = PPG.Inspected.Item(0);
	var oLayout = PPG.Inspected.Item(0).PPGLayout;
	oLayout.Clear();

	oLayout.AddItem("iCount","ボタンの数");

	//iCountパラメータの数値からボタンを生成
	for(var i = 1; i <= oProp.iCount.value; i++)var oItem = oLayout.AddButton( i ,"ぼたん" + i);
}

//ボタンの数のパラメータイベント定義
function AutoEventFunction_iCount_OnChanged(){
	MakeLayout();//レイアウト再描画
	PPG.Refresh();
}

//**************動的イベントの作成********************
try{
	var oProp = PPG.Inspected.Item(0);
	var sInclude = "";
	for(var i = 1; i <= oProp.iCount.value; i++){
		sInclude += "function AutoEventFunction_" + i + "_OnClicked(){logmessage(\"ボタン"+ i + "を押したよー!!\");}";
	}
	eval(sInclude);
	logmessage("AutoEventFunction:自動生成ボタンイベント関数を読み込んだよ!")
}catch( e ){
	logmessage("AutoEventFunction:PPGが表示されてなかったから自動生成イベント関数は読み込まなかった")
}
//******************動的イベントの作成END**********

適当なファイル名で保存して、C:\users\ユーザー名\Autodesk\Softimage_(バージョン)\Application\Plugins などプラグインが読み込まれる場所に適当に放り込んじゃってください。
その後、適当なオブジェクトを選択した状態で AutoEventFunction(); のコマンドを実行すれば、カスタムプロパティがオブジェクト内に出来ます。

↓こんな感じのカスタムプロパティが出現

前回と同じく、イベントの記述は事前に準備はしていません。
早速数値のパラメータを動かしてみて下さい。そうすると、ボタンが現れたと思います。
これは数値パラメータのイベントを先に仕込んでおいて、パラメータが変更される度にPPGを再描画、ボタンをパラメータの数だけ表示するようにしているためです。

//iCountパラメータの数値からボタンを生成
for(var i = 1; i <= oProp.iCount.value; i++)var oItem = oLayout.AddButton( i ,"ぼたん" + i);

通常であれば、ボタンだけ表示されて動作しないのですが、ボタンを押してみると「ボタン○を押したよー」とボタンに応じたイベントが起っております。
(単純な動作なので、あんまり凄みはないですけどね…)

この「他のパラメータによってイベントが追加される」という動作はAutoEventFunction_iCount_OnChanged関数内のPPG.Refresh();というところが一番のポイントになっています。
数値パラメータを変化させてみると、ログに「自動生成ボタンイベント関数を読み込んだよ!」と毎回表示されます。
これは、PPG.Refresh();を行うことで、Softimageがプラグインを再度読みに行ってると言うことです。
この挙動を利用しています。

整理すると、

  1. パラメータが変化、イベント処理が発生!!
  2. PPG.Refresh();でリフレッシュ!
  3. Softimageがプラグインファイルを再読み込みする
  4. 動的イベントの作成の処理が走り、数値パラメータの値からボタンイベントを自動生成する

ということですね。

動的イベントの作成の処理は

//**************動的イベントの作成********************
try{
	var oProp = PPG.Inspected.Item(0);
	var sInclude = "";
	for(var i = 1; i <= oProp.iCount.value; i++){
		sInclude += "function AutoEventFunction_" + i + "_OnClicked(){logmessage(\"ボタン"+ i + "を押したよー!!\");}";
	}
	eval(sInclude);
	logmessage("AutoEventFunction:自動生成ボタンイベント関数を読み込んだよ!")
}catch( e ){
	logmessage("AutoEventFunction:PPGが表示されてなかったから自動生成イベント関数は読み込まなかった")
}
//******************動的イベントの作成END**********

の部分です。

try{}catch( e ){}が入っているのは、追加の処理がPPGが表示されていることを前提に書かれているからです。
もっとちゃんとしてる書き方もあると思いますが、とりあえずこれで動くからOKです。
ちなみに、今回のPPGと別のPPGが同時に表示されている場合などは考慮してないので、PPGの名前やタイプを確かめる等の処理を入れておかないと何かしらエラーが出そうな気もします。

以上、「PPGのイベントを動的に追加する」でした。m(_ _)m