テキストファイルの書き込みと読み込みとSETボタンとSAVEボタンの作成 – FlyWithLua

2023年7月11日

インプットボックスを使って、読み書きの一連の流れを作成してみる。

一番上のボタンはCOM1の左と右の周波数設定を切り替えるたものもで、Activeを選択したら左の周波数がセットされることになり、standbyを選択すると右の周波数がセットされる。
後はインプットボックスに書き込まれた数値を「SAVE」ボタンでファイルに保存することができ、読み込みを設定することにより、インプットボックスの内容を再起動しても保存することが出来るようになる。

-- SETボタンでX-PlaneのCom1に周波数を設定することができる。
-- SAVEボタンで "ExtendedStack.save"に書き込み保存。(ファイルが空白でも書き込みはできる)
-- テキストがファイル内に記述されていないとウインドウは開くが内容が表示されなくなる。
-- "ExtendedStack.save"ファイルが無い場合、自動的に同じ名前のファイルが作成される。
-------------------------------------------------------------------------------------------
--ファルの読み込みが必要

-------------------------------------------------------------------------------------------
-- テキストに保存するためのファイル
--FileNameES = SCRIPT_DIRECTORY .. "ExtendedStack.save"
-------------------------------------------------------------------------------------------
-- ここでは以下のdatarefを読み込むのではなく、こちらから設定した数値に変更することになる。
dataref("COMM1", "sim/cockpit2/radios/actuators/com1_frequency_hz_833", "writable")
dataref("COMM1stdby", "sim/cockpit2/radios/actuators/com1_standby_frequency_hz_833", "writable")
-------------------------------------------------------------------------------------------
local extclick = load_WAV_file(SCRIPT_DIRECTORY .. "ExtendedStackSnd/click.wav")
-------------------------------------------------------------------------------------------
-- datarefの初期設定(最初はこれをアクティブにする)
ComChoice = 1	--datarefの最初の分を指定、2が2番目、最後の方に指定を記述されている。
-------------------------------------------------------------------------------------------
-- 初期設定(最初にluaファイルを読み込んだときこれが表示される)
com1_text = "COM "
com1_mhz = "118.40"
-------------------------------------------------------------------------------------------
--書き込み用のファイルを開く(フィアルには文字が記述してある必要がある)
backupfile = io.open(SCRIPT_DIRECTORY .. "ExtendedStack.save", "r")	--バックアップファイル"ExtendedStack.save"を開く
if backupfile ~= nil then	--もしバックアップファイルが(nil)でない場合、つまり存在する場合。
backupfile:lines()	-- バックアップファイルに1行ずつ記述していく

--以下の設定をするとテキストファイルにちゃんと記述されていないとウインドウ内のコンテンツが表示されなくる。
bucontent = backupfile:lines()	-- バックアップファイルに1行ずつ記述していく
Fctr = 0-- 初期設定
com1_text = bucontent(0) --1行目にcom1のテキストを記述
com1_mhz = bucontent(1) --2行目にcom1の周波数を記述
Fctr = 2	-- 合計2行になる?

backupfile:close()
end
-------------------------------------------------------------------------------------------
-- ウインドウの作成
wnd = float_wnd_create(300, 250, 1, true)
float_wnd_set_title(wnd, "ボタンの基本")        --wnd変数をセット
float_wnd_set_imgui_builder(wnd, "im_on_build") --関数を読み込みセットする
------------------------------------------------------------------------
--メインウインドウをビルドしてその内容を実行する
function im_on_build(wnd, x, y)
-------------------------------------------------
-- COM1 Activeラジオボタン
-- キャプション、ComChoice==1がIDになる
if imgui.RadioButton("COM1 Active", ComChoice == 1) then	--このラジオボタンを押したら
    ComChoice = 1	--これを青色点灯する
end
-------------------------------------------------
imgui.SameLine()
-------------------------------------------------
-- COM1 Standbyラジオボタン
if imgui.RadioButton("COM1 Standby", ComChoice == 2) then
    ComChoice = 2
end
-------------------------------------------------

imgui.TextUnformatted(" ")
-- テキスト入力のバーの描画
-- キャプション、最後の数字は入力できる文字数
-------------------------------------------------------------------------------
-- Com1のNameのインプットバーの作成(テキスト)、変更できるようにするためにはこれがワンセット。
local changed, com1_text_new = imgui.InputText("Name ", com1_text, 18)	-- com1_textが初期設定テキスト"COM"がバーの中に入る
if changed then  
    com1_text = com1_text_new 
end
-------------------------------------------------------------------------------
-- Com1のMhzのインプットバーの作成(周波数)
-- com1_mhzに周波数が入る
local changed, com1_mhz_new = imgui.InputText("Mhz ", com1_mhz, 7)
if changed then 
    com1_mhz = com1_mhz_new  --com1_mhzはセットボタンでcom1_mhz_newに変わる
end
-------------------------------------------------------------------------------
imgui.SameLine()
if imgui.Button("SET ") then
    com1_mhz = SetComHz(com1_mhz) --	 SetComHz関数でセットしたように変わる
end
-------------------------------------------------------------------------------
-- 最初に作成した com1_text = "COM " がここにも入るテスト
imgui.TextUnformatted("")
imgui.TextUnformatted(com1_text)
-- com1_mhz = "118.40"もここに入れて見る(数値も同じ方法)
imgui.TextUnformatted(com1_mhz)
-------------------------------------------------------------------------------

-------------------------------
imgui.TextUnformatted(" ")
--SAVEボタンの作成と実行
imgui.SetWindowFontScale(1.2)
-- もしSAVEボタンが押されたら以下を実行
if imgui.Button("SAVE",60,30) then
    WriteSaveToDisk()	-- ここでWriteSaveToDisk関数を実行する
end

end

-------------------------------------------------------------------------------------------
-- この関数は上で「SET」ボタンを押したときにX-Planeの周波数の変更を実行。
-- 周波数のセット、SetComHz関数、(freq)は引数でプログラムや関数に渡す値(入力)のこと
-- ここでは(freq)は変更するdataref周波数の値になる。
function SetComHz(freq)
freqrt = freq	-- 周波数をfreqrtに変える(freqrtが本当の値になる)
freq = tostring(freq)	--tostringは文字列に変換(ここではfreqに変換されることになる?)
freq = freq:gsub("%.","")	--118.50と数値を書き込むときに「.」を入れる
--------------------------------------
-- 等しくない場合はエラーを入れる
if string.len(freq) ~= 5 then	--文字列freqの長さを返します。つまり5文字でない場合エラー(「.」は数えない)。
    return "ERR"	--戻り値(出力)、 "ERR"を返す、"ERRAR"とすると5文字になるのでできない
end
--------------------------------------
freq = tonumber(freq)	--tonumberは「stringをnumber」数値に変換
--------------------------------------
-- これは上の5文字制限があるので要らないのでは?
-- 入力したテキストが空の場合はエラーを返す
if freq == nil then	--freqが空の場合はエラーを返す
    return "ERR"
end
--------------------------------------
-- これを入れないと、X-Planeの表示が「011850」となってしまうため「118500」としたいので
freq = freq .. "0"
--------------------------------------
-- COM1 Avtiveを選択した場合はCOMM1のdatarefを選択して周波数を書き込み、音を鳴らす
if ComChoice == 1 then
    COMM1 = freq --play_sound(extclick) --ここには周波数と音の2つの要素が入っている
end
--------------------------------------
-- COM2 Standbyを選択した場合はCOMM1stdbyのdatarefを選択して周波数を書き込み、音を鳴らす
if ComChoice == 2 then 
    COMM1stdby = freq --play_sound(extclick) 
end
--------------------------------------
return freqrt	--最後にfreqrtの値を返すのがこの関数の役目
end
-------------------------------------------------------------------------------------------
--  "ExtendedStack.save"ファイルを開いて書き込む
function WriteSaveToDisk()
--local file = io.open(SCRIPT_DIRECTORY .. "KF-Select View.txt", "w")
fileES = io.open(SCRIPT_DIRECTORY .. "ExtendedStack.save", "w")		-- "ExtendedStack.save"ファイルを開き書き込み可能にする
fileES:write(com1_text .. "\n")				-- Com1テキストを書き込む、改行
fileES:write(com1_mhz  .. "\n")			-- Com1テキストを書き込む、改行
-------------------------------------
fileES:close()
end

Com1とNav1の周波数設定

上の設定を参考にスタンバイでなくダイレクトに周波数を設定するようにしたもの。従ってアクティブとスタンバイボタンを外している。

Com周波数(民間の空地通信用)118.000〜136.990まで表示できる。ComとはCommunicationのこと。
アクティブ周波数は118.10から0.05プラスの範囲で入力できる。半端な数値では設定されない。スタンバイは細かく設定できるが、アクティブになったとき0.05刻みに自動的に変換される。

Nav周波数(航行援助無線)108.00〜117.95まで表示できる。
いずれもB737-800の場合で確認、その範囲を過ぎれば最初に戻るか最後の周波数戻る。

-- SETボタンでX-PlaneのCom1に周波数を設定することができる。
-- SAVEボタンで "ExtendedStack.save"に書き込み保存。(ファイルが空白でも書き込みはできる)
-- テキストがファイル内に記述されていないとウインドウは開くが内容が表示されなくなる。
-- "ExtendedStack.save"ファイルが無い場合、自動的に同じ名前のファイルが作成される。
-------------------------------------------------------------------------------------------
-- ここでは以下のdatarefを読み込むのではなく、こちらから設定した数値に変更することになる。
dataref("com1_value", "sim/cockpit/radios/com1_freq_hz", "writable")
dataref("nav1_value", "sim/cockpit/radios/nav1_freq_hz", "writable")
-------------------------------------------------------------------------------------------
--local extclick = load_WAV_file(SCRIPT_DIRECTORY .. "ExtendedStackSnd/click.wav")--音を出す
-------------------------------------------------------------------------------------------
-- 初期設定(最初にluaファイルを読み込んだときこれが表示される)
local com1_text = "118.00"
local nav1_text = "108.00"
-------------------------------------------------------------------------------------------
--書き込み用のファイルを開く(フィアルには文字が記述してある必要がある)
local backupfile = io.open(SCRIPT_DIRECTORY .. "ExtendedStack.save", "r") --バックアップファイル"ExtendedStack.save"を開く
if backupfile ~= nil then                                           --もしバックアップファイルが(nil)でない場合、つまり存在する場合。
    backupfile:lines()                                              -- バックアップファイルに1行ずつ記述していく

    --以下の設定をするとテキストファイルにちゃんと記述されていないとウインドウ内のコンテンツが表示されなくる。
    bucontent = backupfile:lines() -- バックアップファイルに1行ずつ記述していく
    Fctr = 0                   -- 初期設定
    com1_text = bucontent(0)   --1行目にcom1のテキストを記述
    nav1_text = bucontent(1)    --2行目にcom1の周波数を記述
    Fctr = 2                   -- 合計2行になる?

    backupfile:close()
end
-------------------------------------------------------------------------------------------
-- ウインドウの作成
wnd = float_wnd_create(350, 200, 1, true)
float_wnd_set_title(wnd, "ボタンの基本") --wnd変数をセット
float_wnd_set_imgui_builder(wnd, "im_on_build") --関数を読み込みセットする
------------------------------------------------------------------------
--メインウインドウをビルドしてその内容を実行する
function im_on_build(wnd, x, y)
    -- テキスト入力のバーの描画
    -- キャプション、最後の数字は入力できる文字数
    -------------------------------------------------------------------------------
    -- Com1
    --Com1は6桁で表示されているが、実際は5桁で入力する必要がある。6桁で入れると数値が違う表示になる。0.05刻みで入力すること。
    local changed, com1_text_new = imgui.InputText("Com1", com1_text, 10) -- com1_textが初期設定テキスト"COM"がバーの中に入る
    if changed then
        com1_text = com1_text_new
    end
    imgui.SameLine()
    if imgui.Button("SET1") then
        com1_text = SetCom1(com1_text) --	 SetComHz関数でセットしたように変わる
    end
    com1_value_set = string.format("%7.3f", com1_value/100) --小数点を入れる
    imgui.TextUnformatted("Com1 : " .. com1_value_set)-- com1のdaatref値がそのままリアルタイムに入る(X-Planeと同じ数値)
    -------------------------------------------------------------------------------
    -- Nav1
    local changed, com1_mhz_new = imgui.InputText("Nav1", nav1_text, 7)
    if changed then
        nav1_text = com1_mhz_new --com1_mhzはセットボタンでcom1_mhz_newに変わる
    end
    imgui.SameLine()
    if imgui.Button("SET2") then
        nav1_text = SetNav1(nav1_text) --	 SetComHz関数でセットしたように変わる
    end
    local nav1_value_set = string.format("%6.2f", nav1_value/100) --小数点を入れる 
    imgui.TextUnformatted("Nav1: " .. nav1_value_set)-- nav1のdaatref値がそのままリアルタイムに入る
    -------------------------------------------------------------------------------
    --SAVEボタンの作成と実行
    imgui.SetWindowFontScale(1.2)
    -- もしSAVEボタンが押されたら以下を実行
    if imgui.Button("SAVE", 60, 30) then
        WriteSaveToDisk() -- ここでWriteSaveToDisk関数を実行する
    end
    imgui.SetWindowFontScale(1)
    imgui.TextUnformatted("Com 118.000 ~ 136.990  Error if not 5 digits")
    imgui.TextUnformatted("Nav 108.00〜117.95  Error if not 5 digits")
end
-------------------------------------------------------------------------------------------
-- この関数は上で「SET」ボタンを押したときにX-Planeの周波数の変更を実行。
-- 周波数のセット、SetComHz関数、(com1_freq)は引数でプログラムや関数に渡す値(入力)のこと
-- ここでは(com1_freq)は変更するdataref周波数の値になる。
function SetCom1(com1_freq)
    freqrt_com1 = com1_freq         -- 周波数をfreqrtに変える(freqrtが本当の値になる)
    com1_freq = tostring(com1_freq) --tostringは文字列に変換(ここではfreqに変換されることになる?)
    com1_freq = com1_freq:gsub("%.", "") --118.50と数値を書き込むときに「.」を入れる
    --------------------------------------
    -- 等しくない場合はエラーを入れる
    if string.len(com1_freq) ~= 5 then --文字列freqの長さを返します。つまり5文字でない場合エラー(「.」は数えない)。
        return "ERRA"          --戻り値(出力)、 "ERR"を返す、"ERRAR"とすると5文字になるのでできない
    end
    --------------------------------------
    com1_freq = tonumber(com1_freq) --tonumberは「stringをnumber」数値に変換
    --------------------------------------
    -- これは上の5文字制限があるので要らないのでは?
    -- 入力したテキストが空の場合はエラーを返す
    if com1_freq == nil then --freqが空の場合はエラーを返す
        return "ERRRB"
    end
    --------------------------------------
    -- COM2 Standbyを選択した場合はCOMM1stdbyのdatarefを選択して周波数を書き込み、音を鳴らす

    com1_value = com1_freq --play_sound(extclick)

    --------------------------------------
    return freqrt_com1 --最後にfreqrtの値を返すのがこの関数の役目
end
--Nav1
function SetNav1(nav1_freq)
    freqrt_nav1 = nav1_freq         -- 周波数をfreqrtに変える(freqrtが本当の値になる)
    nav1_freq = tostring(nav1_freq) --tostringは文字列に変換(ここではfreqに変換されることになる?)
    nav1_freq = nav1_freq:gsub("%.", "") --118.50と数値を書き込むときに「.」を入れる
    --------------------------------------
    -- 等しくない場合はエラーを入れる
    if string.len(nav1_freq) ~= 5 then --文字列freqの長さを返します。つまり5文字でない場合エラー(「.」は数えない)。
        return "ERRC"          --戻り値(出力)、 "ERR"を返す、"ERRAR"とすると5文字になるのでできない
    end
    --------------------------------------
    nav1_freq = tonumber(nav1_freq) --tonumberは「stringをnumber」数値に変換
    --------------------------------------
    -- これは上の5文字制限があるので要らないのでは?
    -- 入力したテキストが空の場合はエラーを返す
    if nav1_freq == nil then --freqが空の場合はエラーを返す
        return "ERRD"
    end
    --------------------------------------
    -- COM2 Standbyを選択した場合はCOMM1stdbyのdatarefを選択して周波数を書き込み、音を鳴らす

    nav1_value = nav1_freq --play_sound(extclick)

    --------------------------------------
    return freqrt_nav1 --最後にfreqrtの値を返すのがこの関数の役目
end
-------------------------------------------------------------------------------------------
--  "ExtendedStack.save"ファイルを開いて書き込む
function WriteSaveToDisk()
    --local file = io.open(SCRIPT_DIRECTORY .. "KF-Select View.txt", "w")
    fileES = io.open(SCRIPT_DIRECTORY .. "ExtendedStack.save", "w") -- "ExtendedStack.save"ファイルを開き書き込み可能にする
    fileES:write(com1_text .. "\n")                             -- Com1テキストを書き込む、改行
    fileES:write(nav1_text .. "\n")                              -- Com1テキストを書き込む、改行
    -------------------------------------
    fileES:close()
end