« C4D ユーザスクリプトでモーダルダイアログの学習-02 | トップページ | C4D ユーザスクリプトでモーダルダイアログの学習-04 »

C4D ユーザスクリプトでモーダルダイアログの学習-03

ダイアログのレイアウトも何とかなりそうなので…
次は、ダイアログを開いたときの初期値の入力と、入力された数値の取得。

これは、最初の記事で取り上げたので、難しくないと思います。

GeUserDialogクラスのInit()/AskClose()を使いますね。

では、今回使うスクリプトは前回のスクリプトを少し付け加えます。
ダイアログの初期化とダイアログの終了、最後にダイアログから読み取った値をコンソールに表示します。

/*
ダイアログのレイアウトの学習
2009.8.2
*/


//test_dialogクラス==========================================

class test_dialog:GeModalDialog
{
  public:
    var valu;

    test_dialog();
    CreateLayout();
    Init();//ダイアログの初期化
    AskClose();//ダイアログの終了

}

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

//ダイアログの初期化-----------------
test_dialog::Init()
{
 
}


//ダイアログレイアウト-------------
test_dialog::CreateLayout()
{
  SetTitle("test_dialogs");//ダイアログのタイトル設定

  //ウィジェットやグループを…

  AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);
}

//ダイアログの終了-----------------
test_dialog::AskClose()
{
 
}



//main==========================================
main(doc , op)
{
  var dlg = new(test_dialog);

  dlg->Open(-1 , -1);
  if(!dlg->GetResult())return;

  println("ok");
  var c;
  for(c = 0 ; c < sizeof(dlg->valu) ; c++)
  {
    println(dlg->valu[c]);
  }

}

それでは、はじめましょう。

ダイアログの学習の一番最初に行ったAddEditNumber()で追加したウィジェットへの数値の設定はSetFloat(id , value)でした。
逆に、ウィジェットからの数値の取得はGetFloat(id)でしたね。
難しくはないですね。

ダイアログレイアウトは前回のものを流用します。


まずは…
AddCheckbox()

  AddGroupBeginV(10000 , BFH_SCALEFIT , 1 , "group-1" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(10 , 5 , 10 , 5);

    AddCheckbox(1000 , BFH_SCALEFIT , 0 , 0 , "チェックボックス");

  AddGroupEnd();

EditNumberがGetFloat()/SetFloat()だから、GetBool()/SetBool()だと思ったら…

SetCheckbox(id , value)/GetCheckbox(id)でした。

まずは変数の初期化をコンストラクタ内で…
今回は、この記事の都合上、配列を使うことにしました。

//コンストラクタ-----------------
test_dialog::test_dialog()
{
  super();
  valu = new(array , 1);
  valu[0] = TRUE;
}

ウィジェットのIDは1000。

//ダイアログの初期化-----------------
test_dialog::Init()
{
  SetCheckbox(1000 , valu[0]);
}

//ダイアログの終了-----------------
test_dialog::AskClose()
{
  valu[0] = GetCheckbox(1000);
}

これで、準備は整いました。実行します。

Dialog_35

何も設定しないでダイアログを開くと、チェックボックスはチェックされていませんが、修正後のスクリプトを実行すると、チェックされています。
問題ありません。

コンソールには…

ok
1

が表示されているので、ダイアログからの読み取りも問題ないです。
ダイアログでの変更も、コンソールに表示された値は変化するので問題なしです。


次は…
AddEditText()
AddMultiLineEditText()
AddStaticText()

  AddGroupBeginV(10000 , BFH_SCALEFIT , 1 , "group-1" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(10 , 5 , 10 , 5);

    AddEditText(1000 , BFH_SCALEFIT , 0 , 0);
    AddMultiLineEditText(1001 , BFH_SCALEFIT , 0 , 50 , 0);
    AddStaticText(1002 , BFH_SCALEFIT , 0 , 0 , "テキスト" , BORDER_GROUP_IN);

  AddGroupEnd();

StaticTextからの取得する事は、無いと思いますが、計算結果などをコンソールではなくダイアログに表示する場合に必要になるでしょう。

この3つはテキストなのでGetString()/SetString()を使います。

とりあえず、コンストラクタで変数の初期化。

//コンストラクタ-----------------
test_dialog::test_dialog()
{
  super();
  valu = new(array , 3);
  valu[0] = "C4D";
  valu[1] = "Cinema 4D";
  valu[2] = "BodyPaint";
}

ウィジェットのIDは、1000/1001/1002ですね。

//ダイアログの初期化-----------------
test_dialog::Init()
{
  SetString(1000 , valu[0]);
  SetString(1001 , valu[1]);
  SetString(1002 , valu[2]);
}

for()を使っても良かったのですが、3つだったのでダイレクトに…

//ダイアログの終了-----------------
test_dialog::AskClose()
{
  var c;
  for(c = 0 ; c < 3 ; c++)
  {
    valu[c] = GetString(1000 + c);
  }
}

ダイアログからの取得は、for()を使ってみました。

実行します。

Dialog_36

レイアウトの設定では、StaticTextは「テキスト」になっていましたが、ダイアログを開くとダイアログの初期化で設定した"BodyPaint"に変更されています。

コンソールは…

ok
C4D
Cinema 4D
Body Paint

と、表示されました。
ダイアログ中で変更しても、変更したようにコンソールに表示されるので、問題なしです。


次は…
AddEditNumber()
AddEditNumberArrows()
AddSlider()
AddEditSlider()

  AddGroupBeginV(10000 , BFH_SCALEFIT , 1 , "group-1" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(10 , 5 , 10 , 5);

    AddEditNumber(1000 , BFH_SCALEFIT , 0 , 0);
    AddEditNumberArrows(1001 , BFH_SCALEFIT , 0 , 0);
    AddSlider(1002 , BFH_SCALEFIT , 0 , 0);
    AddEditSlider(1003 , BFH_SCALEFIT , 0 , 0);

  AddGroupEnd();

ダイアログの学習の最初でEditNumberの数値の取り扱いは、GetFloat()/SetFloat()でしたよね。
この4つのウィジェットは数値を扱うものなのですが、SetString()/GetString()でも値が設定/取得ができてしまいます。
これは、テキストの数式にも対応しているからなのでしょう。

EditText等を確認したスクリプトのレイアウトだけを上のEditNumberに変更した結果です。

Dialog_37

そのままOKを押すと、コンソールには、EditText等を試したスクリプトと同じ結果になります。

ok
C4D
Cinema 4D
Body Paint

テキストを流し込める事、テキストを取得できる事は覚えておきましょう。

では、SetFloat()/GetFloat()で試してみましょう。

コンストラクタでの変数の初期化は、適当な数値を入れます。

//コンストラクタ-----------------
test_dialog::test_dialog()
{
  super();
  valu = new(array , 4);
  valu[0] = 100.4;
  valu[1] = 35;
  valu[2] = 25.6;
  valu[3] = 2;
}

ダイアログの初期化は…

//ダイアログの初期化-----------------
test_dialog::Init()
{
  SetFloat(1000 , valu[0] , 10.0 , 200.0 , 1.0);
  SetFloat(1001 , valu[1] , 20.0 , 100.0 , 1.0);
  SetFloat(1002 , valu[2] , 20.0 , 100.0 , 1.0);
  SetFloat(1003 , valu[3] ,  0.0 , 100.0 , 0.1);
}

SetFloat()は既に使っているので分かっていると、思います。
SetFloat(id , 数値 , 最小値 , 最大値 , ステップ)ですね。

ダイアログの終了です。

//ダイアログの終了-----------------
test_dialog::AskClose()
{
  var c;
  for(c = 0 ; c < 4 ; c++)
  {
    valu[c] = GetFloat(1000 + c);
  }
}

実行した結果です。

Dialog_38

コンソールの結果です。

ok
100.400002
35.000000
25.600000
2.000000

最小値、最大値、ステップ値も設定通りに働いている事も確認してください。


次は…
AddColorField()
AddColorChooser()

  AddGroupBeginV(10000 , BFH_SCALEFIT , 1 , "group-1" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(10 , 5 , 10 , 5);

    AddColorField(1000 , BFH_SCALEFIT , 50 , 50);
    AddColorChooser(1001 , BFH_SCALEFIT , 0 , 0 , 0);

  AddGroupEnd();

ColorFieldの値の適用/取得はSetColorField(id , color)/GetColor(id)です。

ColorChooserの値は、rgbカラーと明るさbrightの2つです。
ColorChooserへの値の適用は、SetColorChooser(id , rgb-color , bright , max-bright , flag)

ColorChooserからのrgbカラーの取得はGetColor(id)です。
明るさの取得は、GetBrightness()です。

SetColorChooser()のflagに設定する値です。

NO_COLOR カラースライダーが見えなくなる。
NO_BRIGHTNESS 明るさのスライダーが見えなくなる。

SDKには、このように説明されているが…

NO_COLOR
Dialog_40

NO_BRIGHTNESS
Dialog_39

NO_BRIGHTNESSで明るさスライダーは消えているけど…
NO_COLORでは、RGBスライダーが消えていません。

なぜカラースライダーが消えないのかは、理由がわからないので保留して進みます。

NO_COLORやNOBRIGHTNESSは…
AddColorChooser()DR_COLORFIELD_NO_BRIGHTNESSDR_COLORFIELD_NO_COLORと対で使うのだろう…
レイアウトでAddColorChooser()にDR_COLORFIELD_NO_BRIGHTNESSやDR_COLORFIELD_NO_COLORを指定して配置すれば、カラースライダーや明るさスライダーは最初から無い状態にできますし…

では、変数の初期化です。

//コンストラクタ-----------------
test_dialog::test_dialog()
{
  super();
  valu = new(array , 3);
  valu[0] = vector(1.0 , 0.5 , 0.0);
  valu[1] = vector(0.0 , 1.0 , 0.5);
  valu[2] = 0.8;
}

ダイアログの初期化

//ダイアログの初期化-----------------
test_dialog::Init()
{
  SetColorField(1000 , valu[0]);
  SetColorChooser(1001 , valu[1] , valu[2] , 5.0 , 0.0);
}

ダイアログの終了

//ダイアログの終了-----------------
test_dialog::AskClose()
{
  var c;
  for(c = 0 ; c < 2 ; c++)
  {
    valu[c] = GetColor(1000 + c);
  }
  valu[2] = GetBrightness(1001);
}

実行した結果です。

Dialog_41

ok
[1.000000,0.500000,0.000000]
[0.000000,1.000000,0.500000]
0.800000

ダイアログでの変更が、コンソールにも反映されているか確認してください。


次は…
AddRadioGroupV()
AddRadioGroupH()
AddComboBox()
AddPopupButton()

  AddGroupBeginV(10000 , BFH_SCALEFIT , 1 , "group-1" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(10 , 5 , 10 , 5);

    AddGroupBeginV(20000 , BFH_SCALEFIT , 1 , "group-1" , 0);
      AddGroupBorder(BORDER_GROUP_IN);

      AddRadioGroupV(1000 , BFH_SCALEFIT , 5);
        AddItem(1000 , 0 , "item 0");
        AddItem(1000 , 1 , "item 1");
        AddItem(1000 , 2 , "item 2");
        AddItem(1000 , 3 , "item 3");
        AddItem(1000 , 4 , "item 4");

    AddGroupEnd();

    AddGroupBeginH(30000 , BFH_SCALEFIT , 1 , "group-2" , 0);
      AddGroupBorder(BORDER_GROUP_IN);

      AddRadioGroupH(1001 , BFH_SCALEFIT , 5);
        AddItem(1001 , 0 , "item 0");
        AddItem(1001 , 1 , "item 1");
        AddItem(1001 , 2 , "item 2");
        AddItem(1001 , 3 , "item 3");
        AddItem(1001 , 4 , "item 4");

      AddComboBox(1002 , BFH_LEFT , 0 , 0);
        AddItem(1002 , 0 , "item 0");
        AddItem(1002 , 1 , "item 1");
        AddItem(1002 , 2 , "item 2");
        AddItem(1002 , 3 , "item 3");
        AddItem(1002 , 4 , "item 4");

      AddPopupButton(1003 , BFH_LEFT , 0 , 0);
        AddItem(1003 , 0 , "item 0");
        AddItem(1003 , 1 , "item 1");
        AddItem(1003 , 2 , "item 2");
        AddItem(1003 , 3 , "item 3");
        AddItem(1003 , 4 , "item 4");

    AddGroupEnd();

  AddGroupEnd();

ラジオボタン/コンボボックス/ポップアップボタンのサブアイテムのIDを取得します。
ラジオボタンはダイアログをただ開いただけだと、どのボタンも選択されていません。
これを設定するにはSetItem(id , sub-id)で設定します。
取得は、GetItem(id)です。

では、変数の初期化から…

//コンストラクタ-----------------
test_dialog::test_dialog()
{
  super();
  valu = new(array , 4);
  valu[0] = 2;
  valu[1] = 1;
  valu[2] = 3;
  valu[3] = 4;
}

ダイアログの初期化

//ダイアログの初期化-----------------
test_dialog::Init()
{
  SetItem(1000 , valu[0]);
  SetItem(1001 , valu[1]);
  SetItem(1002 , valu[2]);
  SetItem(1003 , valu[3]);
}

ダイアログの終了

//ダイアログの終了-----------------
test_dialog::AskClose()
{
  var c;
  for(c = 0 ; c < 4 ; c++){
    valu[c] = GetItem(1000 + c);
  }
}

これも、実行すると問題なく、ラジオボタンが初期化されます。
ダイアログで、値を変更したらコンソールの表示も変化することを確認してください。

Dialog_42

ok
2
1
3
4

ポップアップのアイテムには、チェックマークが付いていないので、何が選ばれているか分かりません。


次は…
AddEditSlider()を使って、整数メートルラジアンパーセントでの適用/取得です。

  AddGroupBeginV(10000 , BFH_SCALEFIT , 1 , "group-1" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(10 , 5 , 10 , 5);

    AddEditSlider(1000 , BFH_SCALEFIT , 0 , 0);
    AddEditSlider(1001 , BFH_SCALEFIT , 0 , 0);
    AddEditSlider(1002 , BFH_SCALEFIT , 0 , 0);
    AddEditSlider(1003 , BFH_SCALEFIT , 0 , 0);
    AddEditSlider(1004 , BFH_SCALEFIT , 0 , 0);

  AddGroupEnd();

整数は、SetInt(id , 数値 , 最小値 , 最大値 , ステップ値)/GetInt(id)
メートルは、SetMeter(id , 数値 , 最小値 , 最大値 , ステップ値)/GetMeter(id)
度は、SetDegree(id , 数値 , 最小値 , 最大値 , ステップ値)/GetDegree(id)
ラジアンは、SetRadians(id , 数値 , 最小値 , 最大値 , ステップ値)/GetRadians(id)
パーセントは、SetPercent(id , 数値 , 最小値 , 最大値 , ステップ値)/GetPercent(id)

引数は同じです。

変数の初期化

//コンストラクタ-----------------
test_dialog::test_dialog()
{
  super();
  valu = new(array , 5);
  valu[0] = 2;
  valu[1] = 10.0;
  valu[2] = 3.0;
  valu[3] = 3.14;
  valu[4] = 20.5;
}

ダイアログの初期化

//ダイアログの初期化-----------------
test_dialog::Init()
{
    SetInt(1000 , valu[0] , 0 , 50 , 1);
    SetMeter(1001 , valu[1] , 0.0 , 1000.0 , 0.1);
    SetDegree(1002 , valu[2] , 0.0 , 360.0 , 0.1);
    SetRadians(1003 , valu[3] , 0.0 , PI2 , 0.01);
    SetPercent(1004 , valu[4] , 0.0 , 100.0 , 0.1);
}

ダイアログの終了

//ダイアログの終了-----------------
test_dialog::AskClose()
{
  valu[0] = GetInt(1000);
  valu[1] = GetMeter(1001);
  valu[2] = GetDegree(1002);
  valu[3] = GetRadians(1003);
  valu[4] = GetPercent(1004);
}

結果です。

Dialog_43

ok
2
10.000000
3.000000
3.140000
20.500000

整数とメートルは、全く問題ないですね。
度は、三角関数を使う場合はラジアンに変換しないといけないですね。
ラジアンは、ダイアログでは度に変換され、ダイアログからはラジアンに変換されるので、使うなら、こちらではないだろうか。
パーセントは、20.5%がそのまま20.500000で入出力されています。
できれば100% = 1.00000の方が計算で使うときに取り扱いしやすいので、取得後は0.01倍する必要がありますね。そうすると入力は100倍するのか…

メートル、度、パーセントを1つで適用する事ができるSetFloatWithUnits()があります。
SetFloatWithUnits(id , 数値 , 最小値 , 最大値 , ステップ値 , フラグ)

FORMAT_METER メートル
FORMAT_DEGREE
FORMAT_PERCENT パーセント

  AddGroupBeginV(10000 , BFH_SCALEFIT , 1 , "group-1" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(10 , 5 , 10 , 5);

    AddEditSlider(1000 , BFH_SCALEFIT , 0 , 0);
    AddEditSlider(1001 , BFH_SCALEFIT , 0 , 0);
    AddEditSlider(1002 , BFH_SCALEFIT , 0 , 0);

  AddGroupEnd();

変数の初期化

//コンストラクタ-----------------
test_dialog::test_dialog()
{
  super();
  valu = new(array , 3);
  valu[0] = 2.5;
  valu[1] = 3.14;
  valu[2] = 0.205;
}

ダイアログの初期化

//ダイアログの初期化-----------------
test_dialog::Init()
{
    SetFloatWithUnits(1000 , valu[0] , 0.0 , 100.0 , 0.1 , FORMAT_METER);
    SetFloatWithUnits(1001 , valu[1] , 0.0 ,   PI2 , 0.1 , FORMAT_DEGREE);
    SetFloatWithUnits(1002 , valu[2] , 0.0 ,   1.0 , 0.1 , FORMAT_PERCENT);
}

ダイアログの終了

//ダイアログの終了-----------------
test_dialog::AskClose()
{
  var c;
  for(c = 0 ; c < 3 ; c++){
    valu[c] = GetFloat(1000 + c);
  }
}

実行結果です。

Dialog_44

ok
2.500000
2.140000
0.205000

こちらのSetFloatWithUnits()を使うと、ラジアンとパーセントは…
内部でラジアンで扱い、度数変換、ダイアログで度数表示、ラジアン変換
内部で実数、パーセント変換、ダイアログでパーセント表示、実数変換

こちらの方が、計算する時には取り扱いし易いのだ…

これで、ある程度はダイアログを使う事が出来るようになったと思う…
思うだけ…実際はどうだろう…

|

« C4D ユーザスクリプトでモーダルダイアログの学習-02 | トップページ | C4D ユーザスクリプトでモーダルダイアログの学習-04 »