« スクリプトで動画ファイルの作成 | トップページ | ユーザスクリプトでC4D標準オブジェクトを追加 »

スクリプトでモーダルダイアログ

あぁ、もうそろそろダイアログが必要だろうか?
ダイアログは、どうするんだ?
モードレスダイアログは無理かなぁ。まぁ数値入力ならモーダルダイアログで充分だよね。でもオブジェクトのドロップができると良いんだけどね。

/*
モーダルダイアログ実験
08.06.02
*/


class test_dialog : GeModalDialog//モーダルダイアログを継承したtest_dialog
{
  public:
    test_dialog(); //コンストラクタ
    CreateLayout();//ダイアログのレイアウト
}

test_dialog::test_dialog(){super();}//コンストラクタ

test_dialog::CreateLayout()//レイアウト
{
 
}

main(doc , op)
{
  var t_dialog = new(test_dialog);//test_dialogクラスのt_dialogを作る
  t_dialog->Open(-1 , -1);        //ダイアログを画面のマウスポインタの位置に開く
}

これで実行してみよう。実行したらマウスポインタの位置に空のダイアログが開きます。モーダルダイアログなので、ダイアログ以外のコントロールが利かなくなりました。では空のダイアログを閉じて、次のコードをtest_dialog::CreateLayout()にタイプします。

test_dialog::CreateLayout() //レイアウト
{
  SetTitle("テストダイアログ");//ダイアログのタイトル
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "test group" , 0);
    AddStaticText(1001 , 0 , 0 , 0 , "testX" , 0);
    AddEditText(1002, 0, 150, 0 );
    AddStaticText(1003 , 0 , 0 , 0 , "testY" , 0);
    AddEditText(1004, 0, 150, 0 );
  AddGroupEnd();
}

これで実行すれば2つの入力フィールドの小さなダイアログが開きます。タイプはできますが、まだ何も機能しません…

Testdialog

SetTitle()関数は、ダイアログのタイトルだね。テキストを渡します。

AddGroupBeginV()関数はアイテムのグループ化でAddGroupEnd()関数まで。
BeginVだから横に並びます。もちろんBiginHもあるよ。第1引数はID、第2はフラッグでBFV_SCALEFITはスペースに合わせて横位置をフィットさせる。3番目は横に並ぶアイテム数。4番目はグループ名、5番目はいまいち分かりません。

AddStaticText()関数は、固定されたテキスト。引数の1番目はID。2番目はフラッグ?、3番目は横幅、4番目は高さ、5番目がテキスト、6番目がボーダースタイル?

addEditText()関数は、テキスト入力用のフィールド。引数の1番目がID。2番目はフラッグ?、3番目が横幅、4番目が高さ。

フラッグは共通なのかな?ボーダースタイルは?

LayoutFlagだそうですね。でもBFV_SCALEFITは見当たらない。でも下の定数をスクリプトマネージャの入力しても定数として明示されないなぁ。使えないのかな?
FIT_V
FIT_H
CENTER_V
CENTER_H
ALIGN_LEFT
ALIGN_RIGHT
ALIGN_TOP
ALIGN_BOTTOM
SCALE_H
SCALE_V

BoderStyleだそうです。こっちは使えたなぁ。

BORDER_GROUP_IN Border_group_in
BORDER_NONE Border_none
BORDER_THIN_IN Border_thin_in
BORDER_THIN_OUT Border_thin_out
BORDER_IN Border_in
BORDER_OUT Border_out
BORDER_GROUP_OUT Border_group_out
BORDER_OUT2 Border_out2
BORDER_OUT3 Border_out3
BORDER_BLACK Border_black
BORDER_GROUP_TOP Border_group_top

あと必要なのが、OK/キャンセルボタンだね。AddButton()で良いのかな?
AddDlgGroup()らしいね。OKとCANCELの前にDR_DLGGROUP_を付けろってマニュアルに載ってるね。引数は?2つの定数のビット単位の論理演算(or = `|`)?決まり事?マニュアルは分かりずらいね。
最終的なCreateLayout()メンバ関数は

test_dialog::CreateLayout() //最終レイアウト
{
  SetTitle("テストダイアログ");//ダイアログのタイトル
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "test group" , 0);
    AddStaticText(1001 , 0 , 0 , 0 , "testX" , 0);
    AddEditText(1002, 0, 150, 0 );
    AddStaticText(1003 , 0 , 0 , 0 , "testY" , 0);
    AddEditText(1004, 0, 150, 0 );
  AddGroupEnd();
  AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);
}

この状況で実行してみると…

Testdialog2

横が長くなってしまった。サイズの調整はどうするんだろう?分からないね。でもOK/キャンセルボタンを押したら自動的にダイアログが閉じますね。

入力されたデータを吸い出すには…
GeDialogクラスのCommand()メンバ関数。引数は、idとmsg。test_dialogクラスの宣言にCommand(id , msg);を追加。
更にCommand()の宣言。

test_dialog::Command(id , msg){
  println("Command id :" , id);  //試しにプリント
  println("Command msg :" , msg);//試しにプリント
}

追加して実行。KOボタンが押されるとidに1、キャンセルが押されるとidに2が渡されるようです。フィールドに入力するとフィールドのidも渡されるようですね。でも1文字づつ反応している。
このデータを吸い出すにはどうするの?
どうやら、Command()メンバ関数ではなく、AskClose()メンバ関数を使うらしい。Command()メンバ関数と同じようにtest_dialogクラスの宣言に追加、AskClose()の宣言も追加。引数は無し。GeBaseDialog()クラスにGetString()メンバ関数がある。引数はidなのでアイテムのidをここで渡してフィールドから文字列を取得するみたいだね。あ、testX/testYだからEditTextじゃない方がよかったね、EditNumberだ。ま、今はこれでいいや。
では、

test_dialog::AskClose()
{
  println("id 1002 : " , GetString(1002));//試しにプリント
  println("id 1004 : " , GetString(1004));
}

入力したCommand()メンバ関数を削除して実行。
なぜだぁ。プリントはされているけど、AskClose()が必ず2回実行されているみたいだ。しかもキャンセルが押されても実行される。ん?
あぁダイアログが閉じられると実行されるのね。
吸い出したデータはグローバル変数にしよう。
スクリプトの最初に

var text_x , test_y;

って打っておこう。AskClose()も

test_dialog::AskClose()
{
  test_x = GetString(1002);
  test_y = GetString(1004);
}

でOK/キャンセルは?やっぱりCommand()は必要だったかなぁ?
あ、GeModalDialogクラスにGetResult()メンバ関数が在ったなぁ。マニュアルに書いてあるよ。OKたどTRUE、キャンセルだとFALSEだって。じゃあmain()関数に

main(doc , op)
{
  var t_dialog = new(test_dialog);//test_dialogクラスのt_dialogを作る
  t_dialog->Open(-1 , -1);        //ダイアログを画面のマウスポインタの位置に開く
  if(!(t_dialog->GetResult()))return;

  println(test_x , " " , test_y , " ok!!");
}

これで実行して2つのフィールドに適当に文字を入力してOKを押したらコンソールに表示され、キャンセルを押したらコンソールには何も表示されない。一応成功かな?ダイアログが開いたら初期値のデータが入っているようにしたいなら、どうしよう?

スクリプトの一番最初に宣言したグローバル変数を初期化をして

var test_x = "testXだよ" , test_y = "testYだよ";

これをダイアログが開いた時、フィールドに入力済みならいいなぁ。

GeDialogクラスのInit()メンバ関数らしい。じゃあtest_dialogクラスに追加して。Init()の宣言。アイテムから取得するために使ったGeBaseDialogクラスのGetString()メンバ関数の逆SetString();

test_dialog::Init()
{
  SetString(1002 , test_x);
  SetString(1004 , test_y);
}

こんなんで良いのかな?それでは実行。おぉ成功だね。
今回はこれで終了。
その前にやっぱりTestX,testYは文字列じゃなくて数値(浮動小数点)の方が良いよね。

/*
モーダルダイアログ実験
08.06.02
*/


var test_x = 2.56, test_y = 32.05;//適当な数です。

class test_dialog : GeModalDialog
{
  public:
    test_dialog(); //コンストラクタ
    Init();        //初期化
    CreateLayout();//ダイアログレイアウト
    AskClose();    //ダイアログが閉じられたら
}


test_dialog::test_dialog(){super();}//コンストラクタ

test_dialog::Init()//初期化
{
  SetFloat(1002 , test_x , 0 , 100 , 1);//ここを変更
  SetFloat(1004 , test_y , 0 , 100 , 1);//ここも変更
}


test_dialog::CreateLayout() //ダイアログレイアウト
{
  SetTitle("テストダイアログ");//ダイアログのタイトル
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "test group" , 0);
    AddStaticText(1001 , 0 , 0 , 0 , "testX" , 0);
    AddEditNumber(1002 , 0 , 150 , 0);//ここを変更
    AddStaticText(1003 , 0 , 0 , 0 , "testY" , 0);
    AddEditNumber(1004 , 0 , 150 , 0);//ここも変更
  AddGroupEnd();
  AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);

}

test_dialog::AskClose()
{
  test_x = GetFloat(1002);//ここを変更
  test_y = GetFloat(1004);//ここも変更
}


main(doc , op)
{
  var t_dialog = new(test_dialog);   //test_dialogクラスのt_dialogを作る
  t_dialog->Open(-1 , -1);           //ダイアログを画面のマウスポインタの位置に開く
  if(!(t_dialog->GetResult()))return;//キャンセルだったら終了


  println(test_x , " " , test_y , " ok!!");//処理
}

ダイアログを使う最小限のスクリプトかな?ツールとしての処理はmain()関数の後半に処理を書くか、処理を関数にして実行させるかかなぁ。あとtest_dialogクラスのInit()メンバ関数の浮動小数点値をフィールドにセットするSetFloat()の引数、id,変数、最小、最大、ステップと5個必要で、使わなくても省略ができませんね。
今回もいつも通り、理解できなかった部分が幾つか残ってしまったなぁ。

|

« スクリプトで動画ファイルの作成 | トップページ | ユーザスクリプトでC4D標準オブジェクトを追加 »

コメント

この記事へのコメントは終了しました。