📜

【DaVinci Resolve】コンボボックスの選択文字列を取得する方法

2024/11/02に公開

まえがき

こんにちは。火注ゆかなです。
最近急に冷えてきましたね。私も喉の調子が悪い日が続いています。みなさんは大丈夫でしょうか?

今回の話題はインスペクタのコンボボックスとマルチボタンについてです。
こういうのですね。ユーザーコントロールで追加できます。

コンボボックスとマルチボタンは値を取得すると、選択したアイテムやボタンに応じて0 ~ アイテム数の数値を返却します。
でもこれ、ちょっと使いづらいですよね?
数値で取得できた方が良い場面もありますが、選択した文字列が返ってくる方が直感的でわかりやすいと思いますし、その方が楽な場面もあります。

で、そういう選択文字列を取得するための設定方法が We Suck Less フォーラムで投稿されていましたので、その内容を紹介します。
https://www.steakunderwater.com/wesuckless/viewtopic.php?t=3835

……一応言い訳させてもらうと、今回の記事の内容は丸パクリじゃないですからね。
件の投稿に気付く前に Fusion SDK でも それっぽいの見つけましたし!
だからちゃんと補足情報もあります。本当ですよ?

更新履歴

  • 2024/11/6
    • 文字列で取得する方法と ID で取得する方法の 2 通りに分けました
    • 項目を整理しました

コンボボックス・マルチボタンで文字列取得する方法

コントロールの追加

まず、コントロールの追加方法について簡単におさらいしておきましょう。

Fusion ページのノードを右クリックし、コントロールを編集をクリックすると編集用のウィンドウが表示されます。
名前にはコントロール横に表示するラベル名を、IDには他のコントロールと被らない識別用 ID を設定してください。
入力にはコントロールの種類を選択して、コンボボックスとマルチボタンの場合はウィンドウの右側で選択アイテムを設定します。


コンボボックスの編集例

マルチボタンの編集例

これでコントロールが追加できましたが、この方法で追加したマルチボタンは何故かコンボボックスになります。

「コントロールの編集」で追加したマルチボタンはコンボボックス表示になる

マルチボタンの表示を直す

マルチボタンの表示をボタン形式に直しましょう。

まず、ノードを選択してコピーし、テキストエディタに貼り付けます。
するとこんな風になります。(実際にはインデントや改行がされてないことが多いですが)

add_control.setting
{
    Tools = ordered() {
        TextPlus1 = TextPlus {
            CtrlWZoom = false,
            Inputs = {
                GlobalIn = Input { Value = 100, },
                GlobalOut = Input { Value = 428, },
                Font = Input { Value = "Open Sans", },
                Style = Input { Value = "Bold", },
                VerticalJustificationNew = Input { Value = 3, },
                HorizontalJustificationNew = Input { Value = 3, }
            },
            ViewInfo = OperatorInfo { Pos = { 275, 115.5 } },
            UserControls = ordered() {    -- 追加したコントロールのリスト
                ComboBox = {    -- コンボボックスの属性
                    LINKS_Name = "コンボボックス",
                    LINKID_DataType = "Number",
                    INPID_InputControl = "ComboControl",
                    INP_Integer = false,
                    { CCS_AddString = "Zero" },
                    { CCS_AddString = "One" },
                    { CCS_AddString = "Two" },
                    { CCS_AddString = "Three" },
                    { CCS_AddString = "Four" },
                    CC_LabelPosition = "Horizontal",
                },
                MultiButton = {  -- マルチボタンの属性
                    LINKS_Name = "マルチボタン",
                    LINKID_DataType = "Number",
                    INPID_InputControl = "MultiButtonControl",
                    INP_Integer = false,
                    { MBTNC_AddButton = "Zero" },
                    { MBTNC_AddButton = "One" },
                    { MBTNC_AddButton = "Two" },
                    { MBTNC_AddButton = "Three" },
                    { MBTNC_AddButton = "Four" },
                    MBTNC_StretchToFit = true,
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}

その後、マルチボタンの属性にMBTNC_ForceButtons = trueを追加し、編集後のテキストをコピー → ノードを右クリックしてペーストで置換すればボタン表示になります。
(ショートカットCtrl+Vだと選択ノードを置き換えるのではなく、新しくノードが追加されます)

add_control_button.setting
{
    Tools = ordered() {
        TextPlus1 = TextPlus {
            CtrlWZoom = false,
            Inputs = {
                GlobalIn = Input { Value = 100, },
                GlobalOut = Input { Value = 428, },
                Font = Input { Value = "Open Sans", },
                Style = Input { Value = "Bold", },
                VerticalJustificationNew = Input { Value = 3, },
                HorizontalJustificationNew = Input { Value = 3, }
            },
            ViewInfo = OperatorInfo { Pos = { 275, 115.5 } },
            UserControls = ordered() {    -- 追加したコントロールのリスト
                ComboBox = {    -- コンボボックスの属性
                    LINKS_Name = "コンボボックス",
                    LINKID_DataType = "Number",
                    INPID_InputControl = "ComboControl",
                    INP_Integer = false,
                    { CCS_AddString = "Zero" },
                    { CCS_AddString = "One" },
                    { CCS_AddString = "Two" },
                    { CCS_AddString = "Three" },
                    { CCS_AddString = "Four" },
                    CC_LabelPosition = "Horizontal",
                },
                MultiButton = {  -- マルチボタンの属性
                    LINKS_Name = "マルチボタン",
                    LINKID_DataType = "Number",
                    INPID_InputControl = "MultiButtonControl",
                    INP_Integer = false,
                    { MBTNC_AddButton = "Zero" },
                    { MBTNC_AddButton = "One" },
                    { MBTNC_AddButton = "Two" },
                    { MBTNC_AddButton = "Three" },
                    { MBTNC_AddButton = "Four" },
                    MBTNC_StretchToFit = true,
                    MBTNC_ForceButtons = true,    -- ←これを追加するとボタン表示になる
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}


ボタン表示に直った

文字列で取得できるようにする

さて、追加したコントロールをそのまま参照すると、前述の通り選択位置に応じた数値が返却されます。

コンボボックス・マルチボタンの値を参照すると選択位置が返ってくる

コンボボックスの選択アイテムの文字列を参照したい場合、対応する文字列を何らかの形で持っておく必要があります。
スクリプトや Fuse なら self:SetData(key, value)等でテーブルで保持することもできますが、コントロールに設定するエクスプレッションではiifで条件分岐するくらいしかありません。
選択肢が 1 つや 2 つなら良いかもしれませんが 10 や 20 になるとお手上げです。

なので、コンボボックスの選択結果を指定の文字列で返すコントロールに書き換えましょう。

コントロールの設定を書き換える

まず、マルチボタンの表示を直した時のように、ノードをテキストエディタへコピペしてください。
その後、以下の項目を修正します。

  • LINKID_DataType : FuID に変更
  • INPID_InputControl : ComboIDControl または MultiButtonIDControl に変更
change_to_string_control.setting
{
    Tools = ordered() {
        TextPlus1 = TextPlus {
            CtrlWZoom = false,
            Inputs = {
                GlobalIn = Input { Value = 100, },
                GlobalOut = Input { Value = 428, },
                Font = Input { Value = "Open Sans", },
                Style = Input { Value = "Bold", },
                VerticalJustificationNew = Input { Value = 3, },
                HorizontalJustificationNew = Input { Value = 3, }
            },
            ViewInfo = OperatorInfo { Pos = { 275, 115.5 } },
            UserControls = ordered() {    -- 追加したコントロールのリスト
                ComboBox = {    -- コンボボックスの属性
                    LINKS_Name = "コンボボックス",
                    LINKID_DataType = "FuID",    -- データタイプを Number -> FuID に変更
                    INPID_InputControl = "ComboIDControl",  -- ComboControl -> ComboIDControl に変更
                    INP_Integer = false,
                    { CCS_AddString = "Zero",  },
                    { CCS_AddString = "One",   },
                    { CCS_AddString = "Two",   },
                    { CCS_AddString = "Three", },
                    { CCS_AddString = "Four",  },
                    CC_LabelPosition = "Horizontal",
                },
                MultiButton = {  -- マルチボタンの属性
                    LINKS_Name = "マルチボタン",
                    LINKID_DataType = "FuID",    -- データタイプを Number -> FuID に変更
                    INPID_InputControl = "MultiButtonIDControl",
                    INP_Integer = false,
                    { MBTNC_AddButton = "Zero",  },
                    { MBTNC_AddButton = "One",   },
                    { MBTNC_AddButton = "Two",   },
                    { MBTNC_AddButton = "Three", },
                    { MBTNC_AddButton = "Four",  },
                    MBTNC_StretchToFit = true,
                    MBTNC_ForceButtons = true,    -- ←これを追加するとボタン表示になる
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}

修正し終わったら Fusion ページへ貼り付けます。
この状態で先ほどと同じように値を参照すると、表示文字列が返ってくるようになりました。


選択したアイテムの文字列が返ってきた

表示文字列とは異なる ID で取得できるようにする

表示文字列を取得できるようになりましたが、表示されてる文字列ではなく、対応する文字列を取得するようにしたいという場合もあるでしょう。
早い話、スクリプトでは半角英数字の方が処理しやすくて都合が良いです。
でも GUI としてユーザに表示するなら日本語の方がわかりやすいですよね。 そういう時に使い分けられます。

そういう場合、選択アイテムの属性に CCID_AddIDMBTNCID_AddID を追加すればOKです。

コントロールの設定を書き換える

ノードをテキストエディタへコピペして、以下の項目を修正します。

  • LINKID_DataType : FuID に変更
  • INPID_InputControl : ComboIDControl または MultiButtonIDControl に変更
  • 選択アイテム : CCID_AddID または MBTNCID_AddID を追加
change_to_id_control.setting
{
    Tools = ordered() {
        TextPlus1 = TextPlus {
            CtrlWZoom = false,
            Inputs = {
                GlobalIn = Input { Value = 100, },
                GlobalOut = Input { Value = 428, },
                Font = Input { Value = "Open Sans", },
                Style = Input { Value = "Bold", },
                VerticalJustificationNew = Input { Value = 3, },
                HorizontalJustificationNew = Input { Value = 3, }
            },
            ViewInfo = OperatorInfo { Pos = { 275, 115.5 } },
            UserControls = ordered() {    -- 追加したコントロールのリスト
                ComboBox = {    -- コンボボックスの属性
                    LINKS_Name = "コンボボックス",
                    LINKID_DataType = "FuID",    -- データタイプを Number -> FuID に変更
                    INPID_InputControl = "ComboIDControl",  -- ComboControl -> ComboIDControl に変更
                    INP_Integer = false,
                    { CCS_AddString = "Zero",  CCID_AddID = "Zero_ID"},    -- アイテムに ID を追加する
                    { CCS_AddString = "One",   CCID_AddID = "One_ID"},
                    { CCS_AddString = "Two",   CCID_AddID = "Two_ID"},
                    { CCS_AddString = "Three", CCID_AddID = "Three_ID"},
                    { CCS_AddString = "Four",  CCID_AddID = "Four_ID"},
                    CC_LabelPosition = "Horizontal",
                },
                MultiButton = {  -- マルチボタンの属性
                    LINKS_Name = "マルチボタン",
                    LINKID_DataType = "FuID",    -- データタイプを Number -> FuID に変更
                    INPID_InputControl = "MultiButtonIDControl",
                    INP_Integer = false,
                    { MBTNC_AddButton = "Zero",  MBTNCID_AddID = "Zero_ID"},    -- アイテムに ID を追加する
                    { MBTNC_AddButton = "One",   MBTNCID_AddID = "One_ID"},
                    { MBTNC_AddButton = "Two",   MBTNCID_AddID = "Two_ID"},
                    { MBTNC_AddButton = "Three", MBTNCID_AddID = "Three_ID"},
                    { MBTNC_AddButton = "Four",  MBTNCID_AddID = "Four_ID"},
                    MBTNC_StretchToFit = true,
                    MBTNC_ForceButtons = true,    -- ←これを追加するとボタン表示になる
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}

修正し終わったら Fusion ページへ貼り付けます。
この状態で先ほどと同じように値を参照すると、対応する ID が返ってくるようになりました。

選択したアイテムに対応する ID が返ってきた

その他

エクスプレッションで参照する

選択アイテムの文字列をエクスプレッションで参照する場合、ComboBox.Valueという風に記述してください。


文字列を返すコントロールの値は.Valueを付けること

これは文字列を返すコントロール全般に当てはまります。
文字列を返すコントロールの値はstring型ではなくcdata型であるためです。

フレームレンダースクリプトを記述する時も引っかかりやすいポイントですね。

デフォルト値を指定する方法

選択アイテムの属性値が CCS_AddString のみか、CCID_AddID も追加しているかで少し変わります。
個人的には CCS_AddString のみの場合の手法はあまりオススメしません。(備忘録として記述はしておきますが)
デフォルト値を設定するならCCID_AddID も追加した場合の手法をオススメします。

選択アイテムの属性値が CCS_AddString のみの場合

以下の通りに属性値を修正・追記します。

  • LINKID_DataType : Text に変更
  • INPS_DefaultText : 初期表示したいアイテムの文字列を指定します。
{
    Tools = ordered() {
        TextPlus1 = TextPlus {
            CtrlWZoom = false,
            Inputs = {
                GlobalIn = Input { Value = 100, },
                GlobalOut = Input { Value = 428, },
                Font = Input { Value = "Open Sans", },
                Style = Input { Value = "Bold", },
                VerticalJustificationNew = Input { Value = 3, },
                HorizontalJustificationNew = Input { Value = 3, }
            },
            ViewInfo = OperatorInfo { Pos = { 275, 115.5 } },
            UserControls = ordered() {    -- 追加したコントロールのリスト
                ComboBox = {    -- コンボボックスの属性
                    LINKS_Name = "コンボボックス",
                    LINKID_DataType = "Text",    -- データタイプを Number -> Text に変更
                    INPID_InputControl = "ComboIDControl",  -- ComboControl -> ComboIDControl に変更
                    INP_Integer = false,
                    { CCS_AddString  = "Zero",  },
                    { CCS_AddString  = "One",   },
                    { CCS_AddString  = "Two",   },
                    { CCS_AddString  = "Three", },
                    { CCS_AddString  = "Four",  },
                    INPS_DefaultText = "Two",     -- 初期表示アイテムの文字列
                    CC_LabelPosition = "Horizontal",
                },
                MultiButton = {  -- マルチボタンの属性
                    LINKS_Name = "マルチボタン",
                    LINKID_DataType = "Text",    -- データタイプを Number -> Text に変更
                    INPID_InputControl = "MultiButtonIDControl",
                    INP_Integer = false,
                    { MBTNC_AddButton = "Zero", },
                    { MBTNC_AddButton = "One",  },
                    { MBTNC_AddButton = "Two",  },
                    { MBTNC_AddButton = "Three",},
                    { MBTNC_AddButton = "Four", },
                    INPS_DefaultText = "Four",     -- 初期表示アイテムの文字列
                    MBTNC_StretchToFit = true,
                    MBTNC_ForceButtons = true,    -- ←これを追加するとボタン表示になる
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}


コンボボックスでは Two 、マルチボタンでは Four が初期表示されるようになった

選択アイテムの属性値に CCID_AddID も追加している場合

INPID_DefaultID属性を追加し、初期表示したいアイテムの ID を指定します。

{
    Tools = ordered() {
        TextPlus1 = TextPlus {
            CtrlWZoom = false,
            Inputs = {
                GlobalIn = Input { Value = 100, },
                GlobalOut = Input { Value = 428, },
                Font = Input { Value = "Open Sans", },
                Style = Input { Value = "Bold", },
                VerticalJustificationNew = Input { Value = 3, },
                HorizontalJustificationNew = Input { Value = 3, }
            },
            ViewInfo = OperatorInfo { Pos = { 275, 115.5 } },
            UserControls = ordered() {    -- 追加したコントロールのリスト
                ComboBox = {    -- コンボボックスの属性
                    LINKS_Name = "コンボボックス",
                    LINKID_DataType = "FuID",    -- データタイプを Number -> FuID に変更
                    INPID_InputControl = "ComboIDControl",  -- ComboControl -> ComboIDControl に変更
                    INP_Integer = false,
                    { CCS_AddString = "Zero",  CCID_AddID = "Zero_ID"},    -- アイテムに ID を追加する
                    { CCS_AddString = "One",   CCID_AddID = "One_ID"},
                    { CCS_AddString = "Two",   CCID_AddID = "Two_ID"},
                    { CCS_AddString = "Three", CCID_AddID = "Three_ID"},
                    { CCS_AddString = "Four",  CCID_AddID = "Four_ID"},
                    INPID_DefaultID = "Two_ID",     -- 初期表示アイテムの ID
                    CC_LabelPosition = "Horizontal",
                },
                MultiButton = {  -- マルチボタンの属性
                    LINKS_Name = "マルチボタン",
                    LINKID_DataType = "FuID",    -- データタイプを Number -> FuID に変更
                    INPID_InputControl = "MultiButtonIDControl",
                    INP_Integer = false,
                    { MBTNC_AddButton = "Zero",  MBTNCID_AddID = "Zero_ID"},    -- アイテムに ID を追加する
                    { MBTNC_AddButton = "One",   MBTNCID_AddID = "One_ID"},
                    { MBTNC_AddButton = "Two",   MBTNCID_AddID = "Two_ID"},
                    { MBTNC_AddButton = "Three", MBTNCID_AddID = "Three_ID"},
                    { MBTNC_AddButton = "Four",  MBTNCID_AddID = "Four_ID"},
                    INPID_DefaultID = "Four_ID",     -- 初期表示アイテムの ID
                    MBTNC_StretchToFit = true,
                    MBTNC_ForceButtons = true,    -- ←これを追加するとボタン表示になる
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}


コンボボックスでは Two 、マルチボタンでは Four が初期表示されるようになった

マルチボタンはトグルタイプと併用不可

マルチボタンはMBTNC_Type = "Toggle"を属性に追加するとトグルタイプになります。
デフォルトのノーマルタイプがラジオボタン(一つをONにすると他がOFFになる)のような挙動をするのに対して、トグルタイプはチェックボックスのように複数選択が可能になります。

Zero と Two が同時に押された状態になっている

ノーマルタイプだと押したボタンの位置によって0 ~ ボタン数-1の数値を返しますが、トグルタイプはボタンのON/OFF状態をビットで返します。
例えば、上の画像だと5つのボタンがあります。
各ボタンのON/OFF状態をON = 1 OFF = 0として並べると、全部OFFなら00000ですし、全部ONなら11111になります。

で、先ほどの画像では Zero(1桁目)Two(3桁目)がONになっていました。これをビットで表すと00101になります。
(ビットとボタンの配置で左右が逆になるので、ちょっと混乱するかもしれません。)

ビットは2進数なので、これを10進数に変換するには 2^{N-1} を合計します。N は桁数です。
上記の例だと1桁目なら 2^{1-1}=12^{3-1}=4 で、合計 5 になるわけですね。

ビット演算ができればマルチボタン(トグルタイプ)のフラグ管理が楽にできると思います。
まあ、 DaVinci Resolve が対応してるのは Lua5.1 なのでビット演算できないんですけど。(Lua でビット演算できるのは Lua5.2 から)
https://秀丸マクロ.net/lua_tips/?lua_reference_lib_bit32
ビット演算を使いたいなら Python を使うべきですかね。

本題に戻りますが、トグルタイプはMultiButtonIDControlでは指定できません。
指定するとマルチボタンを押してもボタンが変更されなくなるので注意が必要です。

あとがき

コンボボックス・マルチボタンで選択アイテムの文字列を取得できるようにする方法についての説明は以上となります。
この設定ができるとエクスプレッションやスクリプトでコンボボックス周りの処理がスマートになるかもしれません。ならないかもしれません。
とりあえず前回よりは需要があるはず。

私も Fuse を組んでて「選択アイテムに対応した ID を直接取得できれば楽なのに」と悩んでたところなので、少なくとも私には有益な情報でした。

DaVinci Resolve の開発陣がもっと詳細な資料を出してくれれば助かるのですが。

それでは、この記事が皆様のお役に立てば幸いです。

Discussion