マリオネット・スクリプト解説講座

第41回「カスタムダイアログ その1」

ArchitectLandmarkSpotlightDesigner2023

今回はスクリプトでカスタムダイアログを作成する方法について解説します。カスタムダイアログは非常に奥が深く、いかに分かりやすく使いやすいインターフェースを構築するか開発者の腕の見せ所です。

カスタムダイアログは、Vectorworks内に別ウインドウを表示して、なにか情報を表示したり、ボタンやフィールドを設置して値を入力させたり、開発者がレイアウトをすべて設計することができるインターフェースです。

スクリプトでは、Dialogs – Modern・Dialogs – Modern – Browserカテゴリとして、カスタムダイアログのレイアウトや動作をコントロールするAPIがバージョン2023時点で336個用意されています。

APIが多数用意され、開発者サイトやフォーラムではサンプルレイアウトをいくつも見つけることができますが、なんでもできそうな反面、なにから手をつけたらいいのか戸惑います。

カスタムダイアログ解説その1では、基本のレイアウトと、最小限の動作のコントロールについて解説します。

リソースマネージャからスクリプトのリソースを準備しましょう。VectorScriptとPythonどちらも解説しますのでお好きな言語を選択してください。

41-1. カスタムダイアログの定義

まずはカスタムダイアログを定義するところから始まります。

    • VectorScript
dialogID := CreateLayout( 'タイトル', False, 'OK', 'キャンセル' );
    • Python
dialogID = vs.CreateLayout( 'タイトル', False, 'OK', 'キャンセル' )

ここで定義するのは、白紙の設計図です。この時点では、タイトルと、OKボタン、キャンセルボタンのみが設定された空っぽの状態です。この白紙の設計図にアイテムを書き足していきます。

CreateLayoutではカスタムダイアログの識別番号が割り当てられ、dialogIDに返します。このdialogIDはカスタムダイアログをコントロールする番号として使用しますので、上書き等しないように注意しましょう。

41-2. アイテムの追加とレイアウト

今回は固定のテキスト、テキストの入力フィールド、プッシュボタン、プルダウンメニューを追加してみます。次のような完成イメージでレイアウトしていきます。

カスタムダイアログでは、設置するアイテムにそれぞれ固有の番号を持たせ、番号を指定してアイテムの動作をコントロールします。番号は任意に設定することができますが、重複を避ける必要があります。

OKボタン、キャンセルボタンはアイテムとして扱われており、固有の番号を持っています。

    • OKボタン:1
    • キャンセルボタン:2

これらの番号は追加するアイテムでは使用することができませんので注意が必要です。

それでは、アイテムを追加します。

    •  VectorScript
CreateStaticText( dialogID, 3, '名前:', 10 ); {固定文字列を作成}
CreateEditText( dialogID, 4, '名称未設定', 20 ); {文字列入力フィールドを作成}
CreatePushButton( dialogID, 5, '初期値に戻す' ); {プッシュボタンを作成}
CreateStaticText( dialogID, 6, '属性:', 10 ); {固定文字列を作成}
CreatePullDownMenu( dialogID, 7, 16); {プルダウンメニューを作成}
    • Python
vs.CreateStaticText( dialogID, 3, '名前:', 10 ) #{固定文字列を作成}
vs.CreateEditText( dialogID, 4, '名称未設定', 20 ) #{文字列入力フィールドを作成}
vs.CreatePushButton( dialogID, 5, '初期値に戻す' ) #{プッシュボタンを作成}
vs.CreateStaticText( dialogID, 6, '属性:', 10 ) #{固定文字列を作成}
vs.CreatePullDownMenu( dialogID, 7, 16) #{プルダウンメニューを作成}

CreateStaticTextCreateEditText等を使用してダイアログ内にアイテムを作成します。作成時に、アイテムの番号の割り振りと、アイテムの表示サイズの指定、アイテムの種類によっては初期値を設定します。

次に、これらのアイテムをどこに配置するのかを指定します。

    • VectorScript
SetFirstLayoutItem( dialogID, 3 ); {3番のアイテムをひとつめに配置する}
SetRightItem( dialogID, 3, 4, 0, 0 ); {3番の右に4番のアイテムを配置する}
SetRightItem( dialogID, 4, 5, 0, 0 ); {4番の右に5番のアイテムを配置する}
SetBelowItem( dialogID, 3, 6, 0, 0); {3番の下に6番のアイテムを配置する}
SetRightItem( dialogID, 6, 7, 0, 0 ); {6番の右に7番のアイテムを配置する}
    • Python
vs.SetFirstLayoutItem( dialogID, 3 ) #{3番のアイテムをひとつめに配置する}
vs.SetRightItem( dialogID, 3, 4, 0, 0 ) #{3番の右に4番のアイテムを配置する}
vs.SetRightItem( dialogID, 4, 5, 0, 0 ) #{4番の右に5番のアイテムを配置する}
vs.SetBelowItem( dialogID, 3, 6, 0, 0) #{3番の下に6番のアイテムを配置する}
vs.SetRightItem( dialogID, 6, 7, 0, 0 ) #{6番の右に7番のアイテムを配置する}

カスタムダイアログ内のレイアウトではひとつめに配置するアイテムを基準に位置が決まります。ひとつめに配置するアイテムは、SetFirstLayoutItemで指定します。

ひとつめのアイテムはカスタムダイアログ内の左上に配置されますので、これを意識しながら残りのアイテムを並べていきます。SetRightItemSetBelowItemを使用して、アイテム1の右隣、アイテム1の下のように位置を決定します。

41-3. 実行とコールバック関数

レイアウトが済んだらRunLayoutDaialogNで実行します。

    • VectorScript
result := RunLayoutDialogN( dialogID, CallBack, False );
    • Python
result = vs.RunLayoutDialogN( dialogID, CallBack, False )

RunLayoutDaialogNではコールバック関数を定義します。コールバック関数とはカスタムダイアログを表示している時に複数回呼び出される関数で、ダイアログの実行中に表示や動作をコントロールすることができます。

ダイアログをはじめて表示するとき、ダイアログを閉じるとき、OKボタンが押されたとき、フィールドに値が入力されたときなど、ダイアログ実行中に発生するイベントを検知してコールバック関数を呼び出します。イベントの内容は番号で区別され、OKボタンを押すなどのアイテムを操作したときのイベント番号はアイテムごとに定義した固有の番号と一致します。

それでは、コールバック関数を定義します。

    • VectorScript
PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
VAR
    gettext4, gettext7, resulttext : STRING;
BEGIN
    CASE item OF
        12255: { ダイアログを初めて表示 }
        BEGIN
            { 7番のアイテム(プルダウン)に選択肢を登録 }
            AddChoice( dialogID, 7, 'かたい', 1 );
            AddChoice( dialogID, 7, 'ふつう', 2 );
            AddChoice( dialogID, 7, 'やわらかい', 3 );
        END;

        5: { 初期値に戻すボタンを押した }
        BEGIN
            { 4番のアイテム(文字フィールド)に初期値を反映 }
            SetItemText( dialogID, 4, '名称未設定' );
        END;

        1: { OKボタンを押した }
        BEGIN
            GetItemText( dialogID, 4, gettext4 );
            GetItemText( dialogID, 7, gettext7 );
            resulttext := Concat( gettext4, ', ', gettext7 );
            AlrtDialog( resulttext );
        END;
    END;
END;
    • Python
def CallBack( item, data ):

    if item == 12255: #{ ダイアログを初めて表示 }
        #{ 7番のアイテム(プルダウン)に選択肢を登録 }
        vs.AddChoice( dialogID, 7, 'かたい', 1 )
        vs.AddChoice( dialogID, 7, 'ふつう', 2 )
        vs.AddChoice( dialogID, 7, 'やわらかい', 3 )

    elif item == 5: #{ 初期値に戻すボタンを押した }
        #{ 4番のアイテム(文字フィールド)に初期値を反映 }
        vs.SetItemText( dialogID, 4, '名称未設定' )

    elif item == 1: #{ OKボタンを押した }
        gettext4 = vs.GetItemText( dialogID, 4 )
        gettext7 = vs.GetItemText( dialogID, 7 )
        resulttext = vs.Concat( gettext4, ', ', gettext7 )
        vs.AlrtDialog( resulttext )

    return item

コールバック関数の名前は自由ですが、引数の数は2つと決まっています。

    • VectorScript
Procedure CallBack( var item:longint; data:longint );
    • Python
def CallBack( item, data ):

itemはイベント番号です。dataは発生したイベントに補助データがあればここに格納されます。

itemで受け取ったイベント番号ごとに、処理を記述します。

12255は初めてダイアログを表示した時に発生するイベントです。初期値の設定等を行います。ここではプルダウンメニューに選択肢を登録しています。

    • VectorScript
12255: { ダイアログを初めて表示 }
BEGIN
    { 7番のアイテム(プルダウン)に選択肢を登録 }
    AddChoice( dialogID, 7, 'かたい', 1 );
    AddChoice( dialogID, 7, 'ふつう', 2 );
    AddChoice( dialogID, 7, 'やわらかい', 3 );
END;
    • Python
if item == 12255: #{ ダイアログを初めて表示 }
    #{ 7番のアイテム(プルダウン)に選択肢を登録 }
    vs.AddChoice( dialogID, 7, 'かたい', 1 )
    vs.AddChoice( dialogID, 7, 'ふつう', 2 )
    vs.AddChoice( dialogID, 7, 'やわらかい', 3 )

今回、初期値に戻すボタンを設置しました。その名前の通り、ボタンが押された時にフィールドの値を初期値に設定する処理を書きます。

    • VectorScript
5: { 初期値に戻すボタンを押した }
BEGIN
    { 4番のアイテム(文字フィールド)に初期値を反映 }
    SetItemText( dialogID, 4, '名称未設定' );
END;
    • Python
elif item == 5: #{ 初期値に戻すボタンを押した }
    #{ 4番のアイテム(文字フィールド)に初期値を反映 }
    vs.SetItemText( dialogID, 4, '名称未設定' )

OKボタン(1)または、キャンセルボタン(2)が押されると、カスタムダイアログが終了します。ここではOKボタンが押された時のみ、ダイアログの入力結果を表示するようにしています。

    • VectorScript
1: { OKボタンを押した }
BEGIN
    GetItemText( dialogID, 4, gettext4 );
    GetItemText( dialogID, 7, gettext7 );
    resulttext := Concat( gettext4, ', ', gettext7 );
    AlrtDialog( resulttext );
END;
    • Python
elif item == 1: #{ OKボタンを押した }
    gettext4 = vs.GetItemText( dialogID, 4 )
    gettext7 = vs.GetItemText( dialogID, 7 )
    resulttext = vs.Concat( gettext4, ', ', gettext7 )
    vs.AlrtDialog( resulttext )

41-4. 動作確認

以上で一通りのコーディングができたので、動作を確認します。作成したスクリプト全体を示します。

    • VectorScript
PROCEDURE CunstomDialog;
VAR
    dialogID, result : LONGINT;
    
    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        gettext4, gettext7, resulttext : STRING;
    BEGIN
        CASE item OF
            12255:  { ダイアログを初めて表示 }
            BEGIN
                { 7番のアイテム(プルダウン)に選択肢を登録 }
                AddChoice( dialogID, 7, 'かたい', 1 );
                AddChoice( dialogID, 7, 'ふつう', 2 );
                AddChoice( dialogID, 7, 'やわらかい', 3 );
            END;

            5:          { 初期値に戻すボタンを押した }
            BEGIN
                { 4番のアイテム(文字フィールド)に初期値を反映 }
                SetItemText( dialogID, 4, '名称未設定' );
            END;

            1:          { OKボタンを押した }
            BEGIN
                GetItemText( dialogID, 4, gettext4 );
                GetItemText( dialogID, 7, gettext7 );
                resulttext := Concat( gettext4, ', ', gettext7 );
                AlrtDialog( resulttext );
            END;
        END;
    END;

BEGIN
    { カスタムダイアログ定義 }
    dialogID := CreateLayout( 'タイトル', False, 'OK', 'キャンセル' );

    { アイテム定義 }
    CreateStaticText( dialogID, 3, '名前:', 10 );             {固定文字列を作成}
    CreateEditText( dialogID, 4, '名称未設定', 20 );     {文字列入力フィールドを作成}
    CreatePushButton( dialogID, 5, '初期値に戻す' );  {プッシュボタンを作成}
    CreateStaticText( dialogID, 6, '属性:', 10 );             {固定文字列を作成}
    CreatePullDownMenu( dialogID, 7, 16);                   {プルダウンメニューを作成}

    { アイテムのレイアウト }
    SetFirstLayoutItem( dialogID, 3 );      {3番のアイテムをひとつめに配置する}
    SetRightItem( dialogID, 3, 4, 0, 0 );       {3番の右に4番のアイテムを配置する}
    SetRightItem( dialogID, 4, 5, 0, 0 );       {4番の右に5番のアイテムを配置する}
    SetBelowItem( dialogID, 3, 6, 0, 0);    {3番の下に6番のアイテムを配置する}
    SetRightItem( dialogID, 6, 7, 0, 0 );       {6番の右に7番のアイテムを配置する}
 
   { 実行 }
    result := RunLayoutDialogN( dialogID, CallBack, False );
END;
Run( CunstomDialog );
    • Python
def CunstomDialog():

    def CallBack( item, data ):

        if item == 12255:       #{ ダイアログを初めて表示 }
            #{ 7番のアイテム(プルダウン)に選択肢を登録 }
            vs.AddChoice( dialogID, 7, 'かたい', 1 )
            vs.AddChoice( dialogID, 7, 'ふつう', 2 )
            vs.AddChoice( dialogID, 7, 'やわらかい', 3 )

        elif item == 5:         #{ 初期値に戻すボタンを押した }
            #{ 4番のアイテム(文字フィールド)に初期値を反映 }
            vs.SetItemText( dialogID, 4, '名称未設定' )

        elif item == 1:         #{ OKボタンを押した }
            gettext4 = vs.GetItemText( dialogID, 4 )
            gettext7 = vs.GetItemText( dialogID, 7 )
            resulttext = vs.Concat( gettext4, ', ', gettext7 )
            vs.AlrtDialog( resulttext )

        return item

    #{ カスタムダイアログ定義 }
    dialogID = vs.CreateLayout( 'タイトル', False, 'OK', 'キャンセル' )

    #{ アイテム定義 }
    vs.CreateStaticText( dialogID, 3, '名前:', 10 )               #{固定文字列を作成}
    vs.CreateEditText( dialogID, 4, '名称未設定', 20 )       #{文字列入力フィールドを作成}
    vs.CreatePushButton( dialogID, 5, '初期値に戻す' )    #{プッシュボタンを作成}
    vs.CreateStaticText( dialogID, 6, '属性:', 10 )               #{固定文字列を作成}
    vs.CreatePullDownMenu( dialogID, 7, 16)                 #{プルダウンメニューを作成}

    #{ アイテムのレイアウト }
    vs.SetFirstLayoutItem( dialogID, 3 )        #{3番のアイテムをひとつめに配置する}
    vs.SetRightItem( dialogID, 3, 4, 0, 0 )     #{3番の右に4番のアイテムを配置する}
    vs.SetRightItem( dialogID, 4, 5, 0, 0 )     #{4番の右に5番のアイテムを配置する}
    vs.SetBelowItem( dialogID, 3, 6, 0, 0)      #{3番の下に6番のアイテムを配置する}
    vs.SetRightItem( dialogID, 6, 7, 0, 0 )     #{6番の右に7番のアイテムを配置する}

    #{ 実行 }
    result = vs.RunLayoutDialogN( dialogID, CallBack, False )

CunstomDialog()

スクリプトパレットからカスタムダイアログを実行します。

レイアウトした通りに表示されています。

もしも次のような表示になった場合、SetBelowItemなどのレイアウトの忘れやアイテム番号の重複が考えられます。

プルダウンに選択肢が設定されていることや、「初期値に戻す」ボタンの動きも確認します。

最後にOKボタンを押して入力結果が表示されることを確認します。

この機能を利用できる製品

Architect

Vectorworks Architect

建築設計や内装、ディスプレイデザインに対応した先進的なBIM・インテリア設計支援機能、拡張機能、さらには豊富な建築向けのデータライブラリを搭載した建築/内装業界向け製品
詳細情報 購入ページ

Landmark

Vectorworks Landmark

地形モデルや多彩な植栽、灌水設備計画等に対応するランドスケープデザイン機能、さらには豊富な造園向けのデータライブラリを搭載した都市計画/造園業界向け製品
詳細情報 購入ページ

Spotlight

Vectorworks Spotlight

ステージプランニングやライティング計画に対応した先進的な舞台照明計画支援機能、さらには各種メーカー製のトラスや照明機材、音響機器等の豊富なデータライブラリを搭載したエンタテインメント業界向け製品
詳細情報 購入ページ

Designer

Vectorworks Design Suite

専門分野別(建築設計/ディスプレイデザイン、ランドスケープデザイン、ステージデザイン&スポットライトプランニング)の設計支援機能、拡張機能、さらには豊富なデータライブラリを搭載した最上位の製品
詳細情報 購入ページ