From d1a0d8f2654d6ee64c1a43de7958b1eadfaff6b0 Mon Sep 17 00:00:00 2001 From: "Y. Wang" Date: Fri, 10 Jun 2022 22:21:54 +0200 Subject: Use tabs to switch between signaling and IP forms --- .gitignore | 1 + advtrains/formspec.lua | 36 +++++- advtrains_interlocking/signal_api.lua | 11 +- advtrains_interlocking/signal_aspect_ui.lua | 165 ++++++++++++++++++------ advtrains_interlocking/signal_aspects.lua | 2 +- advtrains_interlocking/signal_main_ui.lua | 0 advtrains_interlocking/spec/signal_api_spec.lua | 3 +- advtrains_interlocking/tcb_ts_ui.lua | 25 ++-- 8 files changed, 176 insertions(+), 67 deletions(-) create mode 100644 advtrains_interlocking/signal_main_ui.lua diff --git a/.gitignore b/.gitignore index b3180de..bef77f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ ## Eclipse project files & directories .project .settings +luacov.* diff --git a/advtrains/formspec.lua b/advtrains/formspec.lua index 91e300d..aa5aa69 100644 --- a/advtrains/formspec.lua +++ b/advtrains/formspec.lua @@ -1,6 +1,14 @@ local sformat = string.format local fsescape = minetest.formspec_escape +local function make_list(entries) + local t = {} + for k, v in ipairs(entries) do + t[k] = fsescape(v) + end + return table.concat(t, ",") +end + local function f_button_exit(x, y, w, h, id, text) return sformat("button_exit[%f,%f;%f,%f;%s;%s]", x, y, w, h, id, text) end @@ -10,12 +18,8 @@ local function S_button_exit(x, y, w, h, id, ...) end local function f_dropdown(x, y, w, id, entries, sel, indexed) - local t = {} - for k, v in pairs(entries) do - t[k] = fsescape(v) - end return sformat("dropdown[%f,%f;%f;%s;%s;%d%s]", - x, y, w, id, table.concat(t, ","), + x, y, w, id, make_list(entries), sel or 1, indexed and ";true" or "") end @@ -28,10 +32,32 @@ local function S_label(x, y, ...) return f_label(x, y, attrans(...)) end +local function f_tabheader(x, y, w, h, id, entries, sel, transparent, border) + local st = {string.format("%f,%f",x, y)} + if h then + if w then + st[#st+1] = string.format("%f,%f", w, h) + else + st[#st+1] = tostring(h) + end + end + st[#st+1] = tostring(id) + st[#st+1] = make_list(entries) + st[#st+1] = tostring(sel) + if transparent ~= nil then + st[#st+1] = tostring(transparent) + if border ~= nil then + st[#st+1] = tostring(border) + end + end + return string.format("tabheader[%s]", table.concat(st, ";")) +end + return { button_exit = f_button_exit, S_button_exit = S_button_exit, dropdown = f_dropdown, label = f_label, S_label = S_label, + tabheader = f_tabheader, } diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua index a25e1f6..5b3baf8 100644 --- a/advtrains_interlocking/signal_api.lua +++ b/advtrains_interlocking/signal_api.lua @@ -272,7 +272,10 @@ function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, advtrains.interlocking.show_ip_form(pos, pname) return end + advtrains.interlocking.show_signal_form(pos, node, pname) +end +function advtrains.interlocking.show_signal_form(pos, node, pname) local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos) if sigd then advtrains.interlocking.show_signalling_form(sigd, pname) @@ -288,7 +291,7 @@ function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, advtrains.interlocking.show_signal_aspect_selector( pname, ndef.advtrains.supported_aspects, - "Set aspect manually", callback, + pos, callback, isasp) else --static signal - only IP @@ -332,7 +335,7 @@ function advtrains.interlocking.signal_get_aspect(pos) local asp = get_supposed_aspect(pos) if not asp then asp = advtrains.interlocking.signal_get_real_aspect(pos) - set_supposed_aspect(pos) + set_supposed_aspect(pos, asp) end return asp end @@ -372,6 +375,7 @@ function advtrains.interlocking.show_ip_form(pos, pname, only_notset) return end local form = "size[7,5]label[0.5,0.5;Signal at "..minetest.pos_to_string(pos).."]" + form = form .. advtrains.interlocking.make_signal_formspec_tabheader(pname, pos, 7, 2) advtrains.interlocking.db.check_for_duplicate_ip(pos) local pts, connid = advtrains.interlocking.db.get_ip_by_signalpos(pos) if pts then @@ -394,6 +398,9 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) local pname = player:get_player_name() + if advtrains.interlocking.handle_signal_formspec_tabheader_fields(pname, fields) then + return true + end if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then return end diff --git a/advtrains_interlocking/signal_aspect_ui.lua b/advtrains_interlocking/signal_aspect_ui.lua index edf3ab1..4b41187 100644 --- a/advtrains_interlocking/signal_aspect_ui.lua +++ b/advtrains_interlocking/signal_aspect_ui.lua @@ -1,63 +1,136 @@ local F = advtrains.formspec local players_aspsel = {} -local function make_signal_aspect_selector_t1(suppasp, purpose, isasp) - local form = {"size[7,7.5]"} - form[#form+1] = F.S_label(0.5, 0.5, "Select signal aspect") - form[#form+1] = F.label(0.5, 1, purpose) +local function describe_t1_main_aspect(spv) + if spv == 0 then + return attrans("Danger (halt)") + elseif spv == -1 then + return attrans("Continue at maximum speed") + elseif not spv then + return attrans("Continue with current speed limit") + else + return attrans("Continue with the speed limit of @1", tostring(spv)) + end +end + +local function describe_t1_shunt_aspect(shunt) + if shunt then + return attrans("Shunting allowed") + else + return attrans("No shunting") + end +end + +local function describe_t1_distant_aspect(spv) + if spv == 0 then + return attrans("Expect to stop at the next signal") + elseif spv == -1 then + return attrans("Expect to continue at maximum speed") + elseif not spv then + return attrans("No distant signal information") + else + return attrans("Expect to continue with a speed limit of @1", tostring(spv)) + end +end + +advtrains.interlocking.describe_t1_main_aspect = describe_t1_main_aspect +advtrains.interlocking.describe_t1_shunt_aspect = describe_t1_shunt_aspect +advtrains.interlocking.describe_t1_distant_aspect = describe_t1_distant_aspect + +local function describe_supported_aspects_t1(suppasp, isasp) + local t = {} - form[#form+1] = F.S_label(0.5, 1.5, "Main aspect") local entries = {} local selid = 1 for idx, spv in ipairs(suppasp.main) do - local entry if isasp and spv == isasp.main then selid = idx end - if spv == 0 then - entry = attrans("Danger (halt)") - elseif spv == -1 then - entry = attrans("Continue at maximum speed") - elseif not spv then - entry = attrans("Continue with current speed limit") - else - entry = attrans("Continue with the speed limit of @1", spv) - end - entries[idx] = entry + entries[idx] = describe_t1_main_aspect(spv) end - form[#form+1] = F.dropdown(0.5, 2, 6, "main", entries, selid, true) + t.main = entries + t.main_current = selid - form[#form+1] = F.S_label(0.5, 3, "Shunt aspect") if suppasp.shunt == nil then - local st = 1 - if isasp and isasp.shunt then st = 2 end - local entries = { - attrans("No shunting"), - attrans("Shunting allowed"), + selid = 1 + if isasp and isasp.shunt then + selid = 2 + end + entries = { + describe_t1_shunt_aspect(false), + describe_t1_shunt_aspect(true), } - form[#form+1] = F.dropdown(0.5, 3.5, 6, "shunt_free", entries, st, true) + t.shunt = entries + t.shunt_current = selid end - form[#form+1] = F.S_label(0.5, 4.5, "Distant aspect") - local entries = {} - local selid = 1 + entries = {} + selid = 1 for idx, spv in ipairs(suppasp.dst) do - local entry if isasp and spv == isasp.dst then selid = idx end - if spv == 0 then - entry = attrans("Expect to stop at the next signal") - elseif spv == -1 then - entry = attrans("Expect to continue at maximum speed") - elseif not spv then - entry = attrans("No information on distant signal") - else - entry = attrans("Expect to continue with a speed limit of @1", spv) - end - entries[idx] = entry + entries[idx] = describe_t1_distant_aspect(spv) end - form[#form+1] = F.dropdown(0.5, 5, 6, "dst", entries, selid, true) + t.dst = entries + t.dst_current = selid + return t +end + +advtrains.interlocking.describe_supported_aspects_t1 = describe_supported_aspects_t1 + +local signal_tabheader_map = {} + +local function make_signal_formspec_tabheader(pname, pos, width, selid) + signal_tabheader_map[pname] = pos + local options = { + attrans("Signal aspect"), + attrans("Influence point"), + attrans("Distant signalling"), + } + return F.tabheader(0, 0, nil, nil, "signal_tab", options, selid) +end + +local function handle_signal_formspec_tabheader_fields(pname, fields) + local n = tonumber(fields.signal_tab) + local pos = signal_tabheader_map[pname] + if not (n and pos) then + return false + end + if n == 1 then + local node = advtrains.ndb.get_node(pos) + advtrains.interlocking.show_signal_form(pos, node, pname) + elseif n == 2 then + advtrains.interlocking.show_ip_form(pos, pname) + end + return true +end + +advtrains.interlocking.make_signal_formspec_tabheader = make_signal_formspec_tabheader +advtrains.interlocking.handle_signal_formspec_tabheader_fields = handle_signal_formspec_tabheader_fields + +local function make_signal_aspect_selector_t1(suppasp, purpose, isasp) + local form = {"size[7,7.25]"} + local t = describe_supported_aspects_t1(suppasp, isasp) + if type(purpose) == "table" then + form[#form+1] = make_signal_formspec_tabheader(purpose.pname, purpose.pos, 7, 1) + purpose = "" + end + form[#form+1] = F.S_label(0.5, 0.5, "Select signal aspect") + form[#form+1] = F.label(0.5, 1, purpose) + + form[#form+1] = F.S_label(0.5, 1.5, "Main aspect") + form[#form+1] = F.dropdown(0.5, 2, 6, "main", t.main, t.main_current, true) + + form[#form+1] = F.S_label(0.5, 3, "Shunt aspect") + if t.shunt then + form[#form+1] = F.dropdown(0.5, 3.5, 6, "shunt_free", t.shunt, t.shunt_current, true) + else + form[#form+1] = F.S_label(0.5, 3.5, "The shunt aspect cannot be changed") + end + + form[#form+1] = F.S_label(0.5, 4.5, "Distant aspect") + form[#form+1] = F.dropdown(0.5, 5, 6, "dst", t.dst, t.dst_current, true) form[#form+1] = F.S_button_exit(0.5, 6, 6, 1, "save", "Save signal aspect") return table.concat(form) @@ -69,6 +142,10 @@ local function make_signal_aspect_selector_t2(suppasp, purpose, isasp) if not def then return nil end + if type(purpose) == "table" then + form[#form+1] = make_signal_formspec_tabheader(purpose.pname, purpose.pos, 7, 1) + purpose = "" + end form[#form+1] = F.S_label(0.5, 0.5, "Select signal aspect") form[#form+1] = F.label(0.5, 1, purpose) @@ -93,6 +170,9 @@ function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_ info = {}, } local purpose = p_purpose or "" + if type(p_purpose) == "table" then + purpose = {pname = pname, pos = p_purpose} + end local form if suppasp.type == 2 then @@ -106,13 +186,13 @@ function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_ local token = advtrains.random_id() minetest.show_formspec(pname, "at_il_sigaspdia_"..token, form) - minetest.after(1, function() + --minetest.after(1, function() players_aspsel[pname] = { suppasp = suppasp, callback = callback, token = token, } - end) + --end) end local function usebool(sup, val, free) @@ -147,6 +227,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if psl then if formname == "at_il_sigaspdia_"..psl.token then local suppasp = psl.suppasp + if handle_signal_formspec_tabheader_fields(pname, fields) then + return true + end if fields.save then local asp if suppasp.type == 2 then diff --git a/advtrains_interlocking/signal_aspects.lua b/advtrains_interlocking/signal_aspects.lua index a70d176..eebb4ba 100644 --- a/advtrains_interlocking/signal_aspects.lua +++ b/advtrains_interlocking/signal_aspects.lua @@ -1,4 +1,4 @@ -type2defs = {} +local type2defs = {} local function register_type2(def) local t = {type = 2} diff --git a/advtrains_interlocking/signal_main_ui.lua b/advtrains_interlocking/signal_main_ui.lua new file mode 100644 index 0000000..e69de29 diff --git a/advtrains_interlocking/spec/signal_api_spec.lua b/advtrains_interlocking/spec/signal_api_spec.lua index 2659380..cd7a1d1 100644 --- a/advtrains_interlocking/spec/signal_api_spec.lua +++ b/advtrains_interlocking/spec/signal_api_spec.lua @@ -4,8 +4,7 @@ mineunit("core") _G.advtrains = { interlocking = { - aspects = sourcefile("signal_aspects"), - --aspects = fixture("../../signal_aspects"), + aspects = fixture("../../signal_aspects"), }, ndb = { get_node = minetest.get_node, diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua index 0cc10da..b3b8221 100755 --- a/advtrains_interlocking/tcb_ts_ui.lua +++ b/advtrains_interlocking/tcb_ts_ui.lua @@ -608,7 +608,8 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle if not tcbs.signal_name then tcbs.signal_name = "Signal at "..minetest.pos_to_string(sigd.p) end if not tcbs.routes then tcbs.routes = {} end - local form = "size[7,10]label[0.5,0.5;Signal at "..minetest.pos_to_string(sigd.p).."]" + local form = "size[7,9.75]label[0.5,0.5;Signal at "..minetest.pos_to_string(sigd.p).."]" + form = form .. advtrains.interlocking.make_signal_formspec_tabheader(pname, tcbs.signal, 7, 1) form = form.."field[0.8,1.5;5.2,1;name;Signal name;"..minetest.formspec_escape(tcbs.signal_name).."]" form = form.."button[5.5,1.2;1,1;setname;Set]" @@ -668,12 +669,7 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle if hasprivs then form = form.."button[0.5,8;2.5,1;newroute;New Route]" form = form.."button[ 3,8;2.5,1;unassign;Unassign Signal]" - form = form.."button[ 3,9;2.5,1;influp;Influence Point]" - end - if tcbs.ars_disabled then - form = form.."button[0.5,9;2.5,1;arsenable;Enable ARS]" - else - form = form.."button[0.5,9;2.5,1;arsdisable;Disable ARS]" + form = form..string.format("checkbox[0.5,8.75;ars;Automatic routesetting;%s]", not tcbs.ars_disabled) end elseif sigd_equal(tcbs.route_origin, sigd) then -- something has gone wrong: tcbs.routeset should have been set... @@ -706,6 +702,10 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) local pname = player:get_player_name() + if string.find(formname, "^at_il_signalling_") + and advtrains.interlocking.handle_signal_formspec_tabheader_fields(pname, fields) then + return true + end if not minetest.check_player_privs(pname, "train_operator") then return end @@ -792,16 +792,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.chat_send_player(pname, "Please cancel route first!") end end - if fields.influp and hasprivs then - advtrains.interlocking.show_ip_form(tcbs.signal, pname) - return - end - if tcbs.ars_disabled and fields.arsenable then - tcbs.ars_disabled = nil - end - if not tcbs.ars_disabled and fields.arsdisable then - tcbs.ars_disabled = true + if fields.ars then + tcbs.ars_disabled = not minetest.is_yes(fields.ars) end if fields.auto then -- cgit v1.2.3