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

第42回「カスタムダイアログ その2」

FundamentalsArchitectLandmarkSpotlightDesigner2023

前回に引き続きカスタムダイアログ解説のその2です。今回はスライダーなど特殊なコントロールの作成方法について解説します。

カスタムダイアログでは様々なインターフェースを設置することができます。値を入力させるフィールドを基本として、色を選択したり、画像を表示したり、幅広い操作に対応できます。

幅広い操作に対応するべく特殊なコントロールアイテムの種類も数多くありますが、今回は使用頻度の高そうなものからいくつかピックアップして説明します。

カスタムダイアログ その1 はこちら

解説に入る前に、カスタムダイアログのベースの形をおさらいしておきましょう。

VectorScript:

PROCEDURE CustomDialog;
CONST
    kOK = 1;
    kCancel = 2;
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', 'キャンセル' );

    { アイテムの作成 }

    { アイテムのレイアウト }

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

Python:

def CustomDialog():
    kOK = 1
    kCancel = 2

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

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

    #{ アイテムの作成 }

    #{ アイテムのレイアウト }

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

CustomDialog()

42-1. ラジオボタン

ラジオボタンはCreateRadioButtonで作成します。同じグループ内のラジオボタンは一つしか選択できなくなります。同じグループのラジオボタンではインデックス(アイテム番号)を連続した番号に設定します。

3つのラジオボタンを連続した番号で作成します。

    { アイテムの作成 }
    CreateRadioButton( dialogID, 11, 'ラジオ1' );
    CreateRadioButton( dialogID, 12, 'ラジオ2' );
    CreateRadioButton( dialogID, 13, 'ラジオ3' );

    { アイテムのレイアウト }
    SetFirstLayoutItem( dialogID, 11 );
    SetBelowItem( dialogID, 11, 12, 0, 0 );
    SetBelowItem( dialogID, 12, 13, 0, 0 );

3つのラジオボタンが一つのグループとして認識され、3つのうち一つのラジオボタンを選択できます。

次に、ラジオボタンのグループを複数作成する場合を考えます。

グループボックスのアイテムを作成して、このグループボックス内にラジオボタンを配置することでラジオボタンのグループを定義することができます。

    { アイテムの作成 }
    CreateGroupBox( dialogID, 10, '', True );
    CreateRadioButton( dialogID, 11, 'ラジオ1' );
    CreateRadioButton( dialogID, 12, 'ラジオ2' );
    CreateRadioButton( dialogID, 13, 'ラジオ3' );

    CreateGroupBox( dialogID, 20, '', True );
    CreateRadioButton( dialogID, 21, 'ラジオ4' );
    CreateRadioButton( dialogID, 22, 'ラジオ5' );
    CreateRadioButton( dialogID, 23, 'ラジオ6' );

    { アイテムのレイアウト }
    SetFirstLayoutItem( dialogID, 10 );
    SetFirstGroupItem( dialogID, 10, 11 );
    SetBelowItem( dialogID, 11, 12, 0, 0 );
    SetBelowItem( dialogID, 12, 13, 0, 0 );

    SetBelowItem( dialogID, 10, 20, 0, 0 );
    SetFirstGroupItem( dialogID, 20, 21 );
    SetBelowItem( dialogID, 21, 22, 0, 0 );
    SetBelowItem( dialogID, 22, 23, 0, 0 );

3つのラジオボタンごとに2つのグループとして認識され、グループごとに1つのラジオボタンを選択できます。

ラジオボタンに限らずアイテムのインデックスはコールバック関数で再利用するので、CONSTで名前をつけて定義しておくと便利です。

CONST
    kOK = 1;
    kCancel = 2;
    kRadio1 = 11;
    kRadio2 = 12;
    kRadio3 = 13;
    kRadio4 = 21;
    kRadio5 = 22;
    kRadio6 = 23;

コールバック関数では、GetBooleanItemを使用してラジオボタンの選択状態を取得します。

    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        value : BOOLEAN;
    BEGIN
        CASE item OF
            kOK : 
            BEGIN
                GetBooleanItem( dialogID, kRadio1, value );
                if value then
                    AlrtDialog( 'ラジオ1' );
                GetBooleanItem( dialogID, kRadio2, value );
                if value then
                    AlrtDialog( 'ラジオ2' );
                GetBooleanItem( dialogID, kRadio3, value );
                if value then
                    AlrtDialog( 'ラジオ3' );
                GetBooleanItem( dialogID, kRadio4, value );
                if value then
                    AlrtDialog( 'ラジオ4' );
                GetBooleanItem( dialogID, kRadio5, value );
                if value then
                    AlrtDialog( 'ラジオ5' );
                GetBooleanItem( dialogID, kRadio6, value );
                if value then
                    AlrtDialog( 'ラジオ6' );
            END;
        END;
    END;

選択されているラジオボタンではTrueを返すので、アラートが表示されます。

42-2. スライダーコントロール

スライダーコントールはCreateControlを使用して作成します。

最初にスイライダーのインデックスに名前をつけておきましょう。

CONST
    kOK = 1;
    kCancel = 2;
    kSlider = 30;

CreateControlではスライダーのほかイメージ、カラーパレット等を作成できます。スライダーを作成する場合はコントールの種類に3を指定します。

{ アイテムの作成 }
CreateControl( dialogID, kSlider, 3, '', 10 );

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

CreateControlの第5引数でスライダーの最大値を指定します。最大値を1000に設定する場合は次のようになります。スライダーの刻みは1刻みで固定です。

{ アイテムの作成 }
CreateControl( dialogID, kSlider, 3, '', 1000 );

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

コールバック関数では、SetControlData・GetControlDataを使用してスライダーの値を設定・取得することができます。

    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        value : LONGINT;
    BEGIN
        CASE item OF
            12255 :
            BEGIN
                SetControlData( dialogID, kSlider, 500 ); {初期値を500に設定}
            END;

            kOK : 
            BEGIN
                GetControlData( dialogID, kSlider, value );
                AlrtDialog( Num2Str( 0, value ) );
            END
        END;
    END;

スライダーコントロールでは、スライダーを操作するたびにイベントが発生し、コールバック関数が呼びだされます。

スライダーを操作したイベントのたびに値を取得して、テキストのアイテムに反映するようにすれば、スライダーの現在の値を確認することができます。

{ アイテムの作成 }
CreateControl( dialogID, kSlider, 3, '', 1000 );
CreateStaticText( dialogID, kSlider+1, '500', 5 );

{ アイテムのレイアウト }
SetFirstLayoutItem( dialogID, kSlider );
SetRightItem( dialogID, kSlider, kSlider+1, 0, 0 );
    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        value : LONGINT;
    BEGIN
        CASE item OF
            12255 :
            BEGIN
                SetControlData( dialogID, kSlider, 500 ); {初期値を500に設定}
            END;

            kSlider :
            BEGIN
                GetControlData( dialogID, kSlider, value );
                SetItemText( dialogID, kSlider+1, Num2Str( 0, value ) );
            END;
        END;
    END;

42-3. シンボルプレビュー

シンボルプレビューはVectorworksで作成したシンボルをプレビューイメージで表示できるコントロールです。CreateSymbolDisplayControlで作成することができます。

CONST
    kOK = 1;
    kCancel = 2;
    kSymbol = 40;
{ アイテムの作成 }
CreateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 300, 300, 10, 11, 3 );

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

第7引数でレンダリングの種類、第8引数でビューの方向を指定することができます。

{ アイテムの作成 }
CreateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 300, 300, 10, 0, 9 );

コールバック関数ではUpdateSymbolDisplayControlを使用してシンボルの表示を更新することができます。ビューの方向をラジオボタンで選択してみます。

{ アイテムの作成 }
CreateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 300, 300, 10, 11, 3 );
CreateRadioButton( dialogID, kRadio1, '前' );
CreateRadioButton( dialogID, kRadio2, '斜め右' );

{ アイテムのレイアウト }
SetFirstLayoutItem( dialogID, kSymbol );
SetBelowItem( dialogID, kSymbol, kRadio1, 0, 0 );
SetRightItem( dialogID, kRadio1, kRadio2, 0, 0 );
    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        value : boolean;
    BEGIN
        CASE item OF
            kRadio1 : {前を選択}
            BEGIN
                GetBooleanItem( dialogID, kRadio1, value );
                if value then
                    UpdateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 11, 3 );
            END;

            kRadio2 : {斜め右を選択}
            BEGIN
                GetBooleanItem( dialogID, kRadio2, value );
                if value then
                    UpdateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 11, 9 );
            END;
        END;
    END;

42-4. イメージコントロール

カスタムダイアログでは任意の画像データを表示することができます。CreateImageControl2を使用してイメージコントロールを作成します。

{ アイテムの作成 }
CreateImageControl2( dialogID, kImgCtrl, 50, 50, 'Vectorworks/Standard Images/Active3D.png' );

イメージコントロールではリソースファイルに保存されている画像データを呼び出すことができます。今回はVectorworks本体に内蔵されているイメージリソースを使用する例を紹介します。

まずはVectorworksのイメージリソースを確認します。

※ここではVectorworksのアプリケーションフォルダを操作します。ファイルの内容を変更するとアプリケーションが正常に動作しなくなる場合があります。

Macの場合:

1.ファインダーでVectorworksアプリケーションフォルダを開きます。

2. Vectorworksアプリケーションのコンテキストメニューから「パッケージの内容を表示」を選択します。

3. Contents > Resources > Vectorworks.vwr を探します。

4. Vectorworks.vwrのコンテキストメニューから「パッケージの内容を表示」を選択します。

5. Imagesフォルダを開いて中のイメージファイルを確認します。

Windowsの場合:

1.Vectorworksアプリケーションフォルダを開きます。

2. Vectorworks.vwrを探します。

3. Vectorworks.vwrを複製して任意の場所に保存してください。

4. Vectorworks.vwrの拡張子をzipに変更します。※必ず複製したファイルに対して作業します。

5. Vectorworks.zipを解凍します。

6. 解凍したフォルダ内のImagesフォルダを開いて、イメージファイルを確認します。

確認したImagesフォルダの内容を参考にして、CreateImageControl2で使用するイメージのパスを作成します。Vectorworksのイメージリソースを使用する場合は次のルールでパスを作成します。

    • Vectorworks/Imagesフォルダ以下のイメージファイルのパス

例えばチェックマークのイメージであれば次のようなパスになります。

'Vectorworks/Standard Images/checkdark.png'

CreateImageControl2に適用してカスタムダイアログに表示してみましょう。

{ アイテムの作成 }
CreateImageControl2( dialogID, kImgCtrl, 50, 50, 'Vectorworks/Standard Images/checkdark.png' );

最後に、今回の内容を全て詰めこんでみました。VectorScript、Pythonそれぞれサンプルコードを用意していますので、コーディングの参考にしてください。※変数のバッティング等を回避するために内容を少し変更しています。

VectorScript:

PROCEDURE CustomDialog;
CONST
    kOK = 1;
    kCancel = 2;
    kRadio1 = 11;
    kRadio2 = 12;
    kRadio3 = 21;
    kRadio4 = 22;
    kSlider = 30;
    kSymbol = 40;
    kRadio5 = 41;
    kRadio6 = 42;
    kImgCtrl = 50;
VAR
    dialogID, result : longint;

    PROCEDURE CallBack( VAR item:LONGINT; data:LONGINT );
    VAR
        value_long : LONGINT;
        value_bool : BOOLEAN;
    BEGIN
        CASE item OF
            12255 :
            BEGIN
                SetControlData( dialogID, kSlider, 500 ); {初期値を500に設定}
            END;

            kSlider :
            BEGIN
                GetControlData( dialogID, kSlider, value_long );
                SetItemText( dialogID, kSlider+1, Num2Str( 0, value_long ) );
            END;

            kRadio5 : {前を選択}
            BEGIN
                GetBooleanItem( dialogID, kRadio5, value_bool );
                if value_bool then
                    UpdateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 11, 3 );
            END;

            kRadio6 : {斜め右を選択}
            BEGIN
                GetBooleanItem( dialogID, kRadio6, value_bool );
                if value_bool then
                    UpdateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 11, 9 );
            END;

            kOK : 
            BEGIN
                GetBooleanItem( dialogID, kRadio1, value_bool );
                if value_bool then
                    AlrtDialog( 'ラジオ1' );
                GetBooleanItem( dialogID, kRadio2, value_bool );
                if value_bool then
                    AlrtDialog( 'ラジオ2' );
                GetBooleanItem( dialogID, kRadio3, value_bool );
                if value_bool then
                    AlrtDialog( 'ラジオ3' );
                GetBooleanItem( dialogID, kRadio4, value_bool );
                if value_bool then
                    AlrtDialog( 'ラジオ4' );
            END;
        END;
    END;

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

    { アイテムの作成 }
    CreateStaticText( dialogID, 3, 'ラジオボタン', 20 );
    CreateGroupBox( dialogID, 10, '', True );
    CreateRadioButton( dialogID, kRadio1, 'ラジオ1' );
    CreateRadioButton( dialogID, kRadio2, 'ラジオ2' );
    CreateGroupBox( dialogID, 20, '', True );
    CreateRadioButton( dialogID, kRadio3, 'ラジオ3' );
    CreateRadioButton( dialogID, kRadio4, 'ラジオ4' );

    CreateStaticText( dialogID, 4, 'スライダー', 20 );
    CreateControl( dialogID, kSlider, 3, '', 1000 );
    CreateStaticText( dialogID, kSlider+1, '500', 5 );

    CreateStaticText( dialogID, 5, 'シンボルプレビュー', 20 );
    CreateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 200, 200, 10, 11, 3 );
    CreateRadioButton( dialogID, kRadio5, '前' );
    CreateRadioButton( dialogID, kRadio6, '斜め右' );

    CreateStaticText( dialogID, 6, 'イメージコントロール', 20 );
    CreateImageControl2( dialogID, kImgCtrl, 50, 50, 'Vectorworks/Standard Images/checkdark.png' );

    { アイテムのレイアウト }
    SetFirstLayoutItem( dialogID, 3 );
    SetBelowItem( dialogID, 3, 10, 0, 0 );
    SetFirstGroupItem( dialogID, 10, kRadio1 );
    SetBelowItem( dialogID, kRadio1, kRadio2, 0, 0 );
    SetRightItem( dialogID, 10, 20, 0, 0 );
    SetFirstGroupItem( dialogID, 20, kRadio3 );
    SetBelowItem( dialogID, kRadio3, kRadio4, 0, 0 );

    SetBelowItem( dialogID, 10, 4, 0, 5 );
    SetBelowItem( dialogID, 4, kSlider, 0, 0 );
    SetRightItem( dialogID, kSlider, kSlider+1, 0, 0 );

    SetBelowItem( dialogID, kSlider, 5, 0, 5 );
    SetBelowItem( dialogID, 5, kSymbol, 0, 0 );
    SetBelowItem( dialogID, kSymbol, kRadio5, 0, 0 );
    SetRightItem( dialogID, kRadio5, kRadio6, 0, 0 );

    SetBelowItem( dialogID, kRadio5, 6, 0, 5 );
    SetBelowItem( dialogID, 6, kImgCtrl, 0, 0 );

    result := RunLayoutDialogN( dialogID, callback, False );
END;
RUN( CustomDialog );

Python:

def CustomDialog():
    kOK = 1
    kCancel = 2
    kRadio1 = 11
    kRadio2 = 12
    kRadio3 = 21
    kRadio4 = 22
    kSlider = 30
    kSymbol = 40
    kRadio5 = 41
    kRadio6 = 42
    kImgCtrl = 50

    def callback( item, data ):
        if item == 12255:
            vs.SetControlData( dialogID, kSlider, 500 )

        elif item == kSlider:
            value = vs.GetControlData( dialogID, kSlider )
            vs.SetItemText( dialogID, kSlider+1, vs.Num2Str( 0, value ) )

        elif item == kRadio5:
            if vs.GetBooleanItem( dialogID, kRadio5 ):
                vs.UpdateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 11, 3 )

        elif item == kRadio6:
            if vs.GetBooleanItem( dialogID, kRadio6 ):
                vs.UpdateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 11, 9 )

        elif item == kOK: 
            if vs.GetBooleanItem( dialogID, kRadio1 ):
                vs.AlrtDialog( 'ラジオ1' )
            if vs.GetBooleanItem( dialogID, kRadio2 ):
                vs.AlrtDialog( 'ラジオ2' )
            if vs.GetBooleanItem( dialogID, kRadio3 ):
                vs.AlrtDialog( 'ラジオ3' )
            if vs.GetBooleanItem( dialogID, kRadio4 ):
                vs.AlrtDialog( 'ラジオ4' )


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

    #{ アイテムの作成 }
    vs.CreateStaticText( dialogID, 3, 'ラジオボタン', 20 )
    vs.CreateGroupBox( dialogID, 10, '', True )
    vs.CreateRadioButton( dialogID, kRadio1, 'ラジオ1' )
    vs.CreateRadioButton( dialogID, kRadio2, 'ラジオ2' )
    vs.CreateGroupBox( dialogID, 20, '', True )
    vs.CreateRadioButton( dialogID, kRadio3, 'ラジオ3' )
    vs.CreateRadioButton( dialogID, kRadio4, 'ラジオ4' )

    vs.CreateStaticText( dialogID, 4, 'スライダー', 20 )
    vs.CreateControl( dialogID, kSlider, 3, '', 1000 )
    vs.CreateStaticText( dialogID, kSlider+1, '500', 5 )

    vs.CreateStaticText( dialogID, 5, 'シンボルプレビュー', 20 )
    vs.CreateSymbolDisplayControl( dialogID, kSymbol, '窓-1', 200, 200, 10, 11, 3 )
    vs.CreateRadioButton( dialogID, kRadio5, '前' )
    vs.CreateRadioButton( dialogID, kRadio6, '斜め右' )

    vs.CreateStaticText( dialogID, 6, 'イメージコントロール', 20 )
    vs.CreateImageControl2( dialogID, kImgCtrl, 50, 50, 'Vectorworks/Standard Images/checkdark.png' )

    #{ アイテムのレイアウト }
    vs.SetFirstLayoutItem( dialogID, 3 )
    vs.SetBelowItem( dialogID, 3, 10, 0, 0 )
    vs.SetFirstGroupItem( dialogID, 10, kRadio1 )
    vs.SetBelowItem( dialogID, kRadio1, kRadio2, 0, 0 )
    vs.SetRightItem( dialogID, 10, 20, 0, 0 )
    vs.SetFirstGroupItem( dialogID, 20, kRadio3 )
    vs.SetBelowItem( dialogID, kRadio3, kRadio4, 0, 0 )

    vs.SetBelowItem( dialogID, 10, 4, 0, 5 )
    vs.SetBelowItem( dialogID, 4, kSlider, 0, 0 )
    vs.SetRightItem( dialogID, kSlider, kSlider+1, 0, 0 )

    vs.SetBelowItem( dialogID, kSlider, 5, 0, 5 )
    vs.SetBelowItem( dialogID, 5, kSymbol, 0, 0 )
    vs.SetBelowItem( dialogID, kSymbol, kRadio5, 0, 0 )
    vs.SetRightItem( dialogID, kRadio5, kRadio6, 0, 0 )

    vs.SetBelowItem( dialogID, kRadio5, 6, 0, 5 )
    vs.SetBelowItem( dialogID, 6, kImgCtrl, 0, 0 )

    result = vs.RunLayoutDialogN( dialogID, callback, False )

CustomDialog()

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

Fundamentals

Vectorworks Fundamentals

2D/3D汎用作図機能に、プレゼンボード作成機能や図面と連動できる表計算機能など、数多くの基本作図機能に加え、高品質レンダリング&3Dビジュアライズ機能を搭載したVectorworksシリーズの基本製品
詳細情報 購入ページ

Architect

Vectorworks Architect

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

Landmark

Vectorworks Landmark

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

Spotlight

Vectorworks Spotlight

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

Designer

Vectorworks Design Suite

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