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

新着記事第63回「リストブラウザ その1」

ArchitectLandmarkSpotlightDesigner2025

今回は、スクリプトを使用して、リストブラウザを表示するカスタムダイアログを作成します。その1では、基本編としてシンプルなリストブラウザの作成とデータの追加の方法を紹介します。

リストブラウザは、文字列や画像のアイテムをリストで表示し、ユーザーがそれらを選択・ソートできるUIコンポーネントです。Vectorworksのクラスやレイヤのオーガナイザダイアログボックスでも使用されています。

リストブラウザはカスタマイズ性が高く、関連する関数・手続きが多く用意されています。慣れるまではなかなか実装が難しい仕組みの一つですが、使いこなすと非常に便利な機能ですので、この記事を参考にぜひチャレンジしてみてください。

63-1. カスタムダイアログのレイアウト

まずはベースとなる空のカスタムダイアログを作成します。ここでは 第42回「カスタムダイアログ その2」 の記事で紹介したサンプルプログラムを使用します。

リストブラウザをダイアログのレイアウトに追加するには CreateLB を使用します。CreateLBではリストブラウザの見た目の大きさのみを設定します。

リストブラウザのみ追加したシンプルなダイアログのコードは次のようになります。

VectorScript

PROCEDURE CustomDialog;
CONST
    kOK = 1;
    kCancel = 2;
    kLB = 3;
VAR
    dialogID, result : longint;

    { コールバック関数 }
    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        value : BOOLEAN;
    BEGIN
        CASE item OF
            kOK : 
            BEGIN
            END;
        END;
    END;

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

    { アイテムの作成 }
    CreateLB(dialogID, kLB, 30, 15);

    { アイテムのレイアウト }
    SetFirstLayoutItem(dialogID, kLB);

    { 実行 }
    result := RunLayoutDialogN( dialogID, CallBack, False );

END;
RUN( CustomDialog );

Python

def CustomDialog():
    kOK = 1
    kCancel = 2
    kLB = 3

    #{ コールバック関数 }
    def CallBack( item, data ):
        if item == kOK:
            pass

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

    #{ アイテムの作成 }
    vs.CreateLB(dialogID, kLB, 30, 15)

    #{ アイテムのレイアウト }
    vs.SetFirstLayoutItem(dialogID, kLB)

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

CustomDialog()

ここでは、kLBの名前でコンポーネントIDを管理します。

実行するとリストブラウザが表示されます。まだデータを設定していないので、リストブラウザは空の状態です。

63-2. 列のフォーマット

リストブラウザにデータを流し込む前に、リストブラウザの各列がどのような情報を表示するのか、事前に定義する必要があります。

列の定義はダイアログのコールバック関数の中で実行する必要があります。ダイアログ起動直後に一度だけ実行されるイニシャライズイベントのタイミングが適切でしょう。イニシャライズイベントのキーは12255です。VectorScriptでは定数SetupDialogCとしてキーが用意されています。

VectorScript

{ コールバック関数 }
    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        value : BOOLEAN;
    BEGIN
        CASE item OF
            SetupDialogC : 
            BEGIN
            END;

            kOK : 
            BEGIN
            END;
        END;
    END;

Python

    #{ コールバック関数 }
    def CallBack( item, data ):
        if item == 12255:
            pass
        elif item == kOK:
            pass

作成したレイアウトdialogIDのリストブラウザコンポーネントkLBに対して、InsertLBColumnを使用して列を追加します。列の名前のほか挿入位置と列の幅を設定します。

ここでは次のとおり列を追加します。リストブラウザでは行番号、列番号ともに0始まりです。

    • 0列目:チェック欄
    • 1列名:シンボル定義の名前

VectorScript

            SetupDialogC : 
            BEGIN
                col := InsertLBColumn(dialogID, kLB, 0, 'チェック欄', 50);
                col := InsertLBColumn(dialogID, kLB, 1, 'シンボル名', 100);
            END;

Python

        if item == 12255:
            col = vs.InsertLBColumn(dialogID, kLB, 0, 'チェック欄', 50)
            col = vs.InsertLBColumn(dialogID, kLB, 1, 'シンボル名', 100)

列を追加すると、ヘッダー行に列のタイトルが表示されます。

文字データのみを扱うリストブラウザであればInsertLBColumnのみで運用可能です。今回はチェックの欄で画像データを使用します。SetLBItemDisplayTypeを使用して、列に表示するデータの種類を1番の”画像”に変更します。

boo := SetLBItemDisplayType(dialogID, kLB, 0, 1);

もう1点、チェック欄をクリックするたびにチェックマークの表示をON/OFFできるようにしますので、SetLBControlTypeで制御タイプを3番に指定して複数の状態を切り替えられるに設定します。

boo := SetLBControlType(dialogID, kLB, 0, 3);

VectorScript

            SetupDialogC : 
            BEGIN
                col := InsertLBColumn(dialogID, kLB, 0, 'チェック欄', 50);
                col := InsertLBColumn(dialogID, kLB, 1, 'シンボル名', 100);

                boo := SetLBItemDisplayType(dialogID, kLB, 0, 1);
                boo := SetLBControlType(dialogID, kLB, 0, 3);
            END;

Python

        if item == 12255:
            col = vs.InsertLBColumn(dialogID, kLB, 0, 'チェック欄', 50)
            col = vs.InsertLBColumn(dialogID, kLB, 1, 'シンボル名', 100)

            boo = vs.SetLBItemDisplayType(dialogID, kLB, 0, 1);
            boo = vs.SetLBControlType(dialogID, kLB, 0, 3);

63-3. リストブラウザに画像データを追加する

チェック列で、チェックマークの画像をリストブラウザで使用できるように、画像のリソースを登録します。画像の追加は列の定義と同じくイニシャライズイベントのタイミングで実施します。

今回はチェック欄を作りますので、Vectorworksに内蔵されているイメージリソースからチェックマークとブランクの画像を探します。イメージリソースの参照方法は 42-4. イメージコントロールを参照してください。

AddListBrowserImageにイメージのパスを指定して登録します。AddListBrowserImageの返り値が画像データのIDとなりますので控えておきましょう。

VectorScript

iconBlank := AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Blank.png');
iconCheck := AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Checkmark.png');

Python

icon['blank'] = vs.AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Blank.png')
icon['check'] = vs.AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Checkmark.png')

登録した画像データはリストブラウザコンポーネント上での共有リソースのような扱いです。リスト内のデータのほか、列のタイトルにも使用できます。チェック列のタイトルを文字列からチェックマークの画像に変更します。

VectorScript

boo := SetLBColumnImage( dialogID, kLB, 0, iconCheck );

Python

boo = vs.SetLBColumnImage( dialogID, kLB, 0, icon['check'] )

SetLBControlTypeを3番に設定した列では、列をクリックするたびに登録した画像を切り替えて表示することができます。InsertLBColumnDataItemを使用して切り替えに使用する画像データを登録します。

VectorScript

                ii := InsertLBColumnDataItem( dialogID, kLB, 0, 'UnChecked', iconBlank, -1, 0 );

                ii := InsertLBColumnDataItem( dialogID, kLB, 0, 'Checked', iconCheck, -1, 0 );

Python

            ii = vs.InsertLBColumnDataItem( dialogID, kLB, 0, 'UnChecked', icon['blank'], -1, 0 )
            ii = vs.InsertLBColumnDataItem( dialogID, kLB, 0, 'Checked', icon['check'], -1, 0 )

63-4. リストにデータを追加する

それではリストブラウザにデータを追加していきます。

データの追加はコールバック関数内の任意のタイミングで実施します。ダイアログの起動と同時にデータを表示する場合はイニシャライズイベントで追加しましょう。

ここではドキュメントに登録されているシンボル定義の一覧のデータを追加します。まずはBuildResourceListを使用してシンボル定義の一覧を取得します。

VectorScript

listID := BuildResourceList(16, 0, '', numItems);

Python

listID, numItems = vs.BuildResourceList(16, 0, '')

データの準備ができたら、リストブラウザの行として1つずつ追加していきます。行の追加はInsertLBItemで行い、追加した行のデータの設定にはSetLBItemInfoを使用します。SetLBItemInfoではアイテムの表示内容を設定できます。itemStringには表示する文字列を、imageIndexには表示する画像のIDを入力します。ここでは全てチェックONの状態で表示するように設定します。

VectorScript

                for ii := 0 to numItems - 1 do
                BEGIN
                    row := InsertLBItem(dialogID, kLB, ii, '');
                    boo := SetLBItemInfo(dialogID, kLB, row, 0, '', iconCheck);
                    boo := SetLBItemInfo(dialogID, kLB, row, 1, GetNameFromResourceList(listID, ii+1), 0);
                END;

Python

            for ii in range(numItems):
                row = vs.InsertLBItem(dialogID, kLB, ii, '')
                boo = vs.SetLBItemInfo(dialogID, kLB, row, 0, '', icon['check'])
                boo = vs.SetLBItemInfo(dialogID, kLB, row, 1, vs.GetNameFromResourceList(listID, ii+1), 0)

シンボルの名前の一覧と、それぞれの行にチェックマークが表示されました。

チェックの列をクリックすると、もう一つの画像データであるブランク画像と入れ替わり、チェックが外れるような表現ができます。

63-5. リストからデータを取得

現在のリストブラウザからデータを取得します。データの取得はGetLBItemInfoを使用します。

ここでは、OKボタンを押した時にチェック欄がONのデータのシンボル名のみアラートで表示します。

VectorScript

            kOK : 
            BEGIN
                for row := 0 to GetNumLBItems(dialogID, kLB) - 1 do
                begin
                    boo := GetLBItemInfo(dialogID, kLB, row, 0, itemstring, isCheck);
                    if (isCheck = iconCheck) then
                    begin
                        boo := GetLBItemInfo(dialogID, kLB, row, 1, symname, itemimg);
                        AlrtDialog(Concat('チェックされている行のシンボル名: ', symname));
                    end;
                end;
            END;

Python

        elif item == kOK:
            for row in range(vs.GetNumLBItems(dialogID, kLB)):
                boo, itemstring, isCheck = vs.GetLBItemInfo(dialogID, kLB, row, 0)
                if isCheck == icon['check']:
                    boo, symname, itemimg = vs.GetLBItemInfo(dialogID, kLB, row, 1)
                    vs.AlrtDialog('チェックされている行のシンボル名: ' + symname)

最後に、今回作成したシンプルなリストブラウザのカスタムダイアログのコード全体を示します。

VectorScript

PROCEDURE CustomDialog;
CONST
    kOK = 1;
    kCancel = 2;
    kLB = 3;
VAR
    dialogID, result : longint;
    iconBlank, iconCheck : integer;

    { コールバック関数 }
    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        boo : BOOLEAN;
        col,row, ii : integer;
        listID, numItems : LONGINT;
        itemstring, symname : STRING;
        itemimg, isCheck : INTEGER;
    BEGIN
        CASE item OF
            SetupDialogC : 
            BEGIN
                col := InsertLBColumn(dialogID, kLB, 0, 'チェック欄', 50);
                col := InsertLBColumn(dialogID, kLB, 1, 'シンボル名', 100);

                boo := SetLBItemDisplayType(dialogID, kLB, 0, 1);
                boo := SetLBControlType(dialogID, kLB, 0, 3);

                iconBlank := AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Blank.png');
                iconCheck := AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Checkmark.png');

                boo := SetLBColumnImage( dialogID, kLB, 0, iconCheck );

                ii := InsertLBColumnDataItem( dialogID, kLB, 0, 'UnChecked', iconBlank, -1, 0 );
                ii := InsertLBColumnDataItem( dialogID, kLB, 0, 'Checked', iconCheck, -1, 0 );

                listID := BuildResourceList(16, 0, '', numItems);
                for ii := 0 to numItems - 1 do
                BEGIN
                    row := InsertLBItem(dialogID, kLB, ii, '');
                    boo := SetLBItemInfo(dialogID, kLB, row, 0, '', iconCheck);
                    boo := SetLBItemInfo(dialogID, kLB, row, 1, GetNameFromResourceList(listID, ii+1), 0);
                END;
            END;

            kOK : 
            BEGIN
                for row := 0 to GetNumLBItems(dialogID, kLB) - 1 do
                begin
                    boo := GetLBItemInfo(dialogID, kLB, row, 0, itemstring, isCheck);
                    if (isCheck = iconCheck) then
                    begin
                        boo := GetLBItemInfo(dialogID, kLB, row, 1, symname, itemimg);
                        AlrtDialog(Concat('チェックされている行のシンボル名: ', symname));
                    end;
                end;
            END;

        END;
    END;

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

    { アイテムの作成 }
    CreateLB(dialogID, kLB, 30, 15);

    { アイテムのレイアウト }
    SetFirstLayoutItem(dialogID, kLB);

    { 実行 }
    result := RunLayoutDialogN( dialogID, CallBack, False );
END;
RUN( CustomDialog );

Python

def CustomDialog():
    kOK = 1
    kCancel = 2
    kLB = 3

    icon = {}

    #{ コールバック関数 }
    def CallBack( item, data ):
        if item == 12255:
            col = vs.InsertLBColumn(dialogID, kLB, 0, 'チェック欄', 50)
            col = vs.InsertLBColumn(dialogID, kLB, 1, 'シンボル名', 100)

            boo = vs.SetLBItemDisplayType(dialogID, kLB, 0, 1)
            boo = vs.SetLBControlType(dialogID, kLB, 0, 3)

            icon['blank'] = vs.AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Blank.png')
            icon['check'] = vs.AddListBrowserImage( dialogID, kLB, 'Vectorworks/Standard Images/Checkmark.png')

            boo = vs.SetLBColumnImage( dialogID, kLB, 0, icon['check'] )

            index = vs.InsertLBColumnDataItem( dialogID, kLB, 0, 'UnChecked', icon['blank'], -1, 0 )
            index = vs.InsertLBColumnDataItem( dialogID, kLB, 0, 'Checked', icon['check'], -1, 0 )

            listID, numItems = vs.BuildResourceList(16, 0, '')
            for ii in range(numItems):
                row = vs.InsertLBItem(dialogID, kLB, ii, '')
                boo = vs.SetLBItemInfo(dialogID, kLB, row, 0, '', icon['check'])
                boo = vs.SetLBItemInfo(dialogID, kLB, row, 1, vs.GetNameFromResourceList(listID, ii+1), 0)

        elif item == kOK:
            for row in range(vs.GetNumLBItems(dialogID, kLB)):
                boo, itemstring, isCheck = vs.GetLBItemInfo(dialogID, kLB, row, 0)
                if isCheck == icon['check']:
                    boo, symname, itemimg = vs.GetLBItemInfo(dialogID, kLB, row, 1)
                    vs.AlrtDialog('チェックされている行のシンボル名: ' + symname)

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

    #{ アイテムの作成 }
    vs.CreateLB(dialogID, kLB, 30, 15)

    #{ アイテムのレイアウト }
    vs.SetFirstLayoutItem(dialogID, kLB)

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

CustomDialog()

 

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

Architect

Vectorworks Architect

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

Landmark

Vectorworks Landmark

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

Spotlight

Vectorworks Spotlight

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

Designer

Vectorworks Design Suite

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