imgui コンボボックスの作成 – FlyWithLua

2023年2月17日

コンポボックスは基本的にそのままで何もしないで選択画面のテキストは切り変わる。
これはあくまで選択が出来るだけで、選択状態を保持することはできない。再起動すると必ずデフォルトに戻る。
7行目の「choice = 1」でデフォルトで最初に表示する位置を設定することはできる。

7行目の「choice = 1」を忘れないように。

-- imgui はフローティング ウィンドウ内でのみ機能するため、最初に作成する必要があります。
combo_box_wnd = float_wnd_create(350, 100, 1, true)
float_wnd_set_title(combo_box_wnd, "imgui Demo")
float_wnd_set_imgui_builder(combo_box_wnd, "combo_box_demo")
float_wnd_set_onclose(combo_box_wnd, "closed_demo")

choice = 1
function combo_box_demo(wnd, x, y)

    local choices = {"Choice 1", "Choice 2", "Choice 3"}    --3つの選択肢を作成

        -- BeginCombo はコンボ ボックスを作成します。 最初のパラメータはラベルで、2 番目のパラメータは現在選択されている選択肢のテキストです。
        if imgui.BeginCombo("Combo Box", choices[choice]) then
            -- すべての選択肢をループする
            for i = 1, #choices do
                -- Selectable 関数は、コンボボックスに選択肢を追加します。
                -- 最初のパラメータはラベルで、2 番目のパラメータはラベルです
                -- この選択肢が現在選択されている場合は true になります。
                if imgui.Selectable(choices[i], choice == i) then
                    -- Selectable は、新しい選択肢が選択されたときに true を返します。その選択肢を選択変数にコピーします。
                    choice = i
                end
            end
            -- _BeginCombo が true を返す場合に限り、_Must_ を呼び出す必要があります。
            -- コンボボックスが現在開いているとき
            imgui.EndCombo()
        end
        
        -- 上記のループを理解するためのより簡単な例を次に示します。前に選択アイコンが表示されるだけのパターン。
        if imgui.BeginCombo("Combo Box 2", "", imgui.constant.ComboFlags.NoPreview) then
            if imgui.Selectable("Choice A", choice == 1) then
                choice = 1
            end
            if imgui.Selectable("Choice B", choice == 2) then
                choice = 2
            end
            if imgui.Selectable("Choice C", choice == 3) then
                choice = 3
            end
            imgui.EndCombo()
        end

end

function closed_demo(wnd)
    -- Tこの関数は、ユーザーがウィンドウを閉じるときに呼び出されます。 
    -- ウィンドウが既に破棄されているため、この関数では imgui 関数の描画または呼び出しは許可されない。
end

画像をコンポボックスで切り替える

画像の場合は切り替えが難しい、テキストを変更している状態でテキストがリンクが切れるのでエラーになってしまう。瞬時に切り替える必要があるのでコンポボックが必要になる。

左のボタン画像をコンポボックスで選択して切り替えることができる。

--カスタムdatarefを作成、"Int"がなので整数のみを扱う。
local edit_window = create_dataref_table("FlyWithLua/edit_window", "Int")
local edit_window = 0                     -- 初期設定のdataref値

local hide = false                        -- 初期設定

local image_path_A_1 = "/tab_img/A-1.png" --画像へのパス(ImageButtonボタンへのリンク)
local image_path_A_2 = "/tab_img/A-2.png"
local image_path_A_3 = "/tab_img/A-3.png"

local choice_A_1 = 1 --初期設定(最初に表示する選択)コンポボックスに必須。無いとエラーになる。
local choice_A_2 = 2 --コンポボックスで使用、外側(ここ)に入れないと選択したとき選択テキストにならない。
local choice_A_3 = 3

--選択肢のテーブルを作成(コンポボックス内に表示されるテキスト)
local choices = { "/tab_img/A-1.png", "/tab_img/A-2.png", "/tab_img/A-3.png" }
-- BeginCombo はコンボ ボックスを作成します。
--最初のパラメータは右端のラベル、2番目はchoices(上のテーブルからの読み込み)、[choice_A_1]はコンポボックスの初期で表示されるテキスト。


---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
button_wnd = float_wnd_create(250, 350, 1, true)
float_wnd_set_title(button_wnd, "Edit") --最初のウインドウタイトル
float_wnd_set_imgui_builder(button_wnd, "button_window")
float_wnd_set_onclick(button_wnd, "button_on_click")


-- 最初に表示されるメインウインドウ、隠さない設定。
-- button_windowをビルド、最初に開くウインドウ、Editボタンを作成、出力テキストも表示。
function button_window(button_wnd, x, y)
    if imgui.Button("Edit", 100, 30) then
        edit_window = 1 -- ここでdataref値「1」に変更すると、2番目のウインドウを表示することになる。
    end

    if imgui.ImageButton(float_wnd_load_image(SCRIPT_DIRECTORY .. image_path_A_1), 120, 65) then
        command_once("sim/view/linear_spot")
    end
    imgui.TextUnformatted(image_path_A_1) --t画像への実際のパス。これが正しいパスがで出ないなら画像も変化しない。

    if imgui.ImageButton(float_wnd_load_image(SCRIPT_DIRECTORY .. image_path_A_2), 120, 65) then
        command_once("sim/view/linear_spot")
    end
    imgui.TextUnformatted(image_path_A_2) --画像への実際のパス。

    if imgui.ImageButton(float_wnd_load_image(SCRIPT_DIRECTORY .. image_path_A_3), 120, 65) then
        command_once("sim/view/linear_spot")
    end
    imgui.TextUnformatted(image_path_A_3) --画像への実際のパス。
end

--これが無いとウインドウをクリックするとEditボタン等の内容が表示されなくなる。
function button_on_click(button_wnd, x, y, state)
end

----------------------------------------------------------------------------------------------------------------------
-- Editボタンで開くウインドウ(開くウインドウの作成と、そのウインドウを閉じる設定になる)
----------------------------------------------------------------------------------------------------------------------
-- Editボタンにより、開け閉めするウインドウ
-- 上のEditボタンクリックでdatarefが「1」になり、hideは初期設定で「false」こなのでウインドウをビルドして表示することになる。
function edit_show_wnd()
    if edit_window == 1 and hide == false then                     --1とfalseならウインドウを作成して表示する。
        edit_wnd = float_wnd_create(250, 150, 1, true)             -- ここで最初のウインドウの作成
        float_wnd_set_title(edit_wnd, "Show Window-1")             --2番目のウインドウタイトル
        float_wnd_set_position(edit_wnd, 100, 500)
        float_wnd_set_imgui_builder(edit_wnd, "ishwwd_on_build_1") -- ここでウインドウ内にボタン等のアイテムを作成する。
        hide = true                                                --これでウインド内が有効になり使えるようになる。falseならウインドウ内をクリックしても反応しないのでCloseボタンを使えない。
    end
end

do_every_draw("edit_show_wnd()")


-- ビルドされたウインドウ内に、Closeボタンとテキストを表示する。
function ishwwd_on_build_1(edit_wnd, x, y)

    if imgui.Button("Close", 100, 50) then
        edit_window = 0 -- ボタンを押したときdatarefを「0」にして、このウインドウを閉じる
    end
    
    -- コンポボックス----------------------------------------------------
    if imgui.BeginCombo("Image_A-1", choices[choice_A_1]) then
        -- hoices(テーブル)のすべての選択肢をループする
        for i = 1, #choices do --i=1は最初から読み込む(3にすると3以下だけしか選択肢が表示されないのでここは1がデフォルト)
            -- Selectable 関数は、コンボボックスに選択肢を追加します。
            -- 最初のパラメータはラベルで、2 番目のパラメータはラベルです
            -- この選択肢が現在選択されている場合は true になります。
            if imgui.Selectable(choices[i], choice_A_1 == i) then
                -- Selectable は、新しい選択肢が選択されたときに true を返します。その選択肢を選択変数にコピーします。
                choice_A_1 = i          --設定分のパス全てが「i」に読みこれ得る

                if choice_A_1 == 1 then --1は選択肢image_path_A_1を選択している。
                    image_path_A_1 = "/tab_img/A-1.png"
                end
                if choice_A_1 == 2 then
                    image_path_A_1 = "/tab_img/A-2.png" --image_path_A_1は画像パス「/tab_img/A-2.png」を指定。
                end
                if choice_A_1 == 3 then
                    image_path_A_1 = "/tab_img/A-3.png"
                end
            end
        end
        -- _BeginCombo が true を返す場合に限り、_Must_ を呼び出す必要があります。
        -- コンボボックスが現在開いているとき
        imgui.EndCombo()
    end
    if imgui.BeginCombo("Image_A-2", choices[choice_A_2]) then
        for i = 1, #choices do
            if imgui.Selectable(choices[i], choice_A_2 == i) then
                choice_A_2 = i

                if choice_A_2 == 1 then
                    image_path_A_2 = "/tab_img/A-1.png"
                end
                if choice_A_2 == 2 then
                    image_path_A_2 = "/tab_img/A-2.png"
                end
                if choice_A_2 == 3 then
                    image_path_A_2 = "/tab_img/A-3.png"
                end
            end
        end
        imgui.EndCombo()
    end
    if imgui.BeginCombo("Image_A-3", choices[choice_A_3]) then
        for i = 1, #choices do
            if imgui.Selectable(choices[i], choice_A_3 == i) then
                choice_A_3 = i

                if choice_A_3 == 1 then
                    image_path_A_3 = "/tab_img/A-1.png"
                end
                if choice_A_3 == 2 then
                    image_path_A_3 = "/tab_img/A-2.png"
                end
                if choice_A_3 == 3 then
                    image_path_A_3 = "/tab_img/A-3.png"
                end
            end
        end
        imgui.EndCombo()
    end
end

edit_wnd = nil -- 無くても動作する。メモリ上のウインドウを空にする(これにより完全に空にする)

-- Closeボタンにより、datarefが「0」になり2番目ウインドウが非表示になる。
-- ポイント、ここにも「and hide == true」を入れること。これを入れないと開け閉めが不安定になる。
function edit_hide_1_wnd()
    if edit_window == 0 and hide == true then
        if edit_wnd then
            float_wnd_destroy(edit_wnd) --ウインドウを隠す関数
            hide = false                --これでウインド内が無効になり使えなくする。
        end
    end
end

do_every_draw("edit_hide_1_wnd()")

未検証

あるサイトに同じようなものがあったのでコピーしている。動作未確認。

flapSet = 1
    local flapsSettings = { "Flap 1", "Flap 2" }

    if imgui.BeginCombo("##flapsetting", flapsSettings[flapSet]) then
        -- Loop over all choices
        for i = 1, #flapsSettings do
            if imgui.Selectable(flapsSettings[i], flapSet == i) then
                flapSet = i
            end
        end

        imgui.EndCombo()
    end
    level = 1
    flighLevel = { "FL250", "FL330", "FL400" }
    if imgui.BeginCombo("##levelset", flighLevel[level]) then
        -- Loop over all choices
        for i = 1, #flighLevel do
            if imgui.Selectable(flighLevel[i], level == i) then
                level = i
            end
        end

        imgui.EndCombo()
    end

    level2 = 1
    flighLevel2 = { "FL100", "FL150", "FL200" }
    if imgui.BeginCombo("##levelset2", flighLevel2[level2], imgui.constant.ComboFlags.NoArrowButton) then
        for i = 1, #flighLevel2 do
            if imgui.Selectable(flighLevel2[i], level2 == i) then
                level2 = i
            end
        end
        imgui.EndCombo()
    end

    level3 = 1
    flighLevel3 = { "FL050", "FL060", "FL070" }
    if imgui.BeginCombo("##levelset3", flighLevel3[level3], imgui.constant.ComboFlags.NoPreview) then
        for i = 1, #flighLevel2 do
            if imgui.Selectable(flighLevel3[i], level3 == i) then
                -- Selectable returns true when a new choice was selected,
                -- we should then copy the choice into our choice variable
                level3 = i
            end
        end
        imgui.EndCombo()
    end