💬

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

2024/11/02に公開

まえがき

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

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

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

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

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

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

コントロールの追加

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

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"
}


ボタン表示に直った

ID で取得できるようにする

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

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

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

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

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

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

  • 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 を追加する
                    { CCS_AddString = "One",   CCID_AddID = "One"},
                    { CCS_AddString = "Two",   CCID_AddID = "Two"},
                    { CCS_AddString = "Three", CCID_AddID = "Three"},
                    { CCS_AddString = "Four",  CCID_AddID = "Four"},
                    CC_LabelPosition = "Horizontal",
                },
                MultiButton = {  -- マルチボタンの属性
                    LINKS_Name = "マルチボタン",
                    LINKID_DataType = "FuID",    -- データタイプを Number -> FuID に変更
                    INPID_InputControl = "MultiButtonIDControl",
                    INP_Integer = false,
                    { MBTNC_AddButton = "Zero",  MBTNCID_AddID = "Zero"},    -- アイテムに ID を追加する
                    { MBTNC_AddButton = "One",   MBTNCID_AddID = "One"},
                    { MBTNC_AddButton = "Two",   MBTNCID_AddID = "Two"},
                    { MBTNC_AddButton = "Three", MBTNCID_AddID = "Three"},
                    { MBTNC_AddButton = "Four",  MBTNCID_AddID = "Four"},
                    MBTNC_StretchToFit = true,
                    MBTNC_ForceButtons = true,    -- ←これを追加するとボタン表示になる
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}

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


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

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

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


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

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

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

注意点とか

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

マルチボタンは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では指定できません。
指定するとマルチボタンを押してもボタンが変更されなくなるので注意が必要です。

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

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 を追加する
                    { CCS_AddString = "One",   CCID_AddID = "One"},
                    { CCS_AddString = "Two",   CCID_AddID = "Two"},
                    { CCS_AddString = "Three", CCID_AddID = "Three"},
                    { CCS_AddString = "Four",  CCID_AddID = "Four"},
                    INPID_DefaultID = "Two",     -- 初期表示アイテムの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 を追加する
                    { MBTNC_AddButton = "One",   MBTNCID_AddID = "One"},
                    { MBTNC_AddButton = "Two",   MBTNCID_AddID = "Two"},
                    { MBTNC_AddButton = "Three", MBTNCID_AddID = "Three"},
                    { MBTNC_AddButton = "Four",  MBTNCID_AddID = "Four"},
                    INPID_DefaultID = "Four",     -- 初期表示アイテムのID
                    MBTNC_StretchToFit = true,
                    --MBTNC_Type = "Toggle",      -- トグルタイプは併用不可(ボタンが操作できなくなる)
                    MBTNC_ForceButtons = true,    -- ←これを追加するとボタン表示になる
                }
            }
        }
    },
    ActiveTool = "TextPlus1"
}


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

あとがき

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

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

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

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

Discussion