aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/route_ui.lua
diff options
context:
space:
mode:
authorSingularis <singularis@volny.cz>2025-04-21 07:21:53 +0200
committerorwell <orwell@bleipb.de>2025-05-27 20:22:01 +0200
commit95a5586e0fe196e2291acaf128b8d1b4f8a32510 (patch)
tree6cc5ff9a64e533c8d9262f965e2246dfa2b3da24 /advtrains_interlocking/route_ui.lua
parent1d6913cec797b3848c93e8c6b16c3b6b2711d38c (diff)
downloadadvtrains-95a5586e0fe196e2291acaf128b8d1b4f8a32510.tar.gz
advtrains-95a5586e0fe196e2291acaf128b8d1b4f8a32510.tar.bz2
advtrains-95a5586e0fe196e2291acaf128b8d1b4f8a32510.zip
[advtrains] přechod na Advtrains 2.5.0 (první pokus)
- [ch_core/lib] drobná oprava - [advtrains_attachment_offset_patch] použití initial_properties
Diffstat (limited to 'advtrains_interlocking/route_ui.lua')
-rw-r--r--advtrains_interlocking/route_ui.lua222
1 files changed, 193 insertions, 29 deletions
diff --git a/advtrains_interlocking/route_ui.lua b/advtrains_interlocking/route_ui.lua
index 0903b27..3fb5bc6 100644
--- a/advtrains_interlocking/route_ui.lua
+++ b/advtrains_interlocking/route_ui.lua
@@ -3,6 +3,7 @@
local atil = advtrains.interlocking
local ildb = atil.db
+local F = advtrains.formspec
-- TODO duplicate
local lntrans = { "A", "B" }
@@ -10,9 +11,10 @@ local function sigd_to_string(sigd)
return minetest.pos_to_string(sigd.p).." / "..lntrans[sigd.s]
end
+-- indexed by pname
+local sel_rpartcache = {}
-
-function atil.show_route_edit_form(pname, sigd, routeid)
+function atil.show_route_edit_form(pname, sigd, routeid, sel_rpartidx)
if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then
minetest.chat_send_player(pname, attrans("Insufficient privileges to use this!"))
@@ -30,16 +32,18 @@ function atil.show_route_edit_form(pname, sigd, routeid)
-- construct textlist for route information
local tab = {}
- local function itab(t)
+ local tabref = {}
+ local function itab(rseg, t, rty, rpara)
tab[#tab+1] = minetest.formspec_escape(string.gsub(t, ",", " "))
+ tabref[#tab] = { [rty] = true, param = rpara, seg = rseg, idx = #tab }
end
- itab("TCB "..sigd_to_string(sigd).." ("..tcbs.signal_name..") Route #"..routeid)
+ itab(1, "("..(tcbs.signal_name or "+")..") Route #"..routeid, "signal", sigd)
-- this code is partially copy-pasted from routesetting.lua
-- we start at the tc designated by signal
local c_sigd = sigd
local i = 1
- local c_tcbs, c_ts_id, c_ts, c_rseg, c_lckp
+ local c_tcbs, c_ts_id, c_ts, c_rseg
while c_sigd and i<=#route do
c_tcbs = ildb.get_tcbs(c_sigd)
if not c_tcbs then
@@ -54,50 +58,127 @@ function atil.show_route_edit_form(pname, sigd, routeid)
c_ts = ildb.get_ts(c_ts_id)
c_rseg = route[i]
- c_lckp = {}
- itab(""..i.." Vjezd "..sigd_to_string(c_sigd).." -> Ús. "..(c_ts and c_ts.name or "-").." -> Výjezd "..(c_rseg.next and sigd_to_string(c_rseg.next) or "KONEC"))
+ local signame = "-"
+ if c_tcbs and c_tcbs.signal then signame = c_tcbs.signal_name or "o" end
+ itab(i, ""..i.." "..sigd_to_string(c_sigd).." ("..signame..")", "signal", c_sigd)
+ itab(i, "= "..(c_ts and c_ts.name or c_ts_id).." ="..(c_rseg.call_on and " [CO]" or ""), "section", c_ts_id)
if c_rseg.locks then
for pts, state in pairs(c_rseg.locks) do
- local pos = minetest.string_to_pos(pts)
- itab(" Zámek: "..pts.." -> "..state)
+ local pos = advtrains.decode_pos(pts)
+ itab(i, "Zámek "..pts.." -> "..state, "lock", pos)
if not advtrains.is_passive(pos) then
itab("-!- Na "..pts.." není žádná pasivní komponenta. Prosím, přenastavte cestu!")
break
end
end
end
+ -- sanity check, is section at next the same as the current?
+ local nvar = c_rseg.next
+ if nvar then
+ local re_tcbs = ildb.get_tcbs({p = nvar.p, s = (nvar.s==1) and 2 or 1})
+ if not re_tcbs or not re_tcbs.ts_id or re_tcbs.ts_id~=c_ts_id then
+ itab(i, "-!- At "..sigd_to_string(c_sigd)..".Section Start and End do not match!", "err", nil)
+ break
+ end
+ end
-- advance
- c_sigd = c_rseg.next
+ c_sigd = nvar
i = i + 1
end
if c_sigd then
local e_tcbs = ildb.get_tcbs(c_sigd)
- itab("Konec cesty: "..sigd_to_string(c_sigd).." ("..(e_tcbs and e_tcbs.signal_name or "-")..")")
+ local signame = "-"
+ if e_tcbs and e_tcbs.signal then signame = e_tcbs.signal_name or "o" end
+ itab(i, "E "..sigd_to_string(c_sigd).." ("..signame..")", "end", c_sigd)
else
- itab("Cesta je slepá")
+ itab(i, "E (none)", "end", nil)
end
- form = form.."textlist[0.5,2;7.75,3.9;rtelog;"..table.concat(tab, ",").."]"
+ if not sel_rpartidx then sel_rpartidx = 1 end
+ form = form.."textlist[0.5,2;3.5,3.9;routelog;"..table.concat(tab, ",")..";"..(sel_rpartidx or 1)..";false]"
- form = form.."button[0.5,6;3,1;back;<<< Zpět na signalizaci]"
- form = form.."button[4.5,6;2,1;aspect;Signál...]"
- form = form.."button[6.5,6;2,1;delete;Smazat cestu]"
+ -- to the right of rtelog, controls are displayed for the thing in focus
+ -- What is in focus is determined by the parameter sel_rpartidx
+
+ local sel_rpart = tabref[sel_rpartidx]
+ --atdebug("sel rpart",sel_rpart)
+
+ if sel_rpart and sel_rpart.signal then
+ -- get TCBS here and rseg selected
+ local s_tcbs = ildb.get_tcbs(sel_rpart.param)
+ local rseg = route[sel_rpart.seg]
+ -- main aspect list
+ local signalpos = s_tcbs and s_tcbs.signal
+ if signalpos and rseg then
+ form = form..F.label(4.5, 2, "Signal Aspect:")
+ local ndef = signalpos and advtrains.ndb.get_ndef(signalpos)
+ if ndef and ndef.advtrains and ndef.advtrains.main_aspects then
+ local entries = { "<Default Aspect>" }
+ local sel = 1
+ for i, mae in ipairs(ndef.advtrains.main_aspects) do
+ entries[i+1] = mae.description
+ if mae.name == rseg.main_aspect then
+ sel = i+1
+ end
+ end
+ form = form..F.dropdown(4.5, 3.0, 4, "sa_main_aspect", entries, sel, true)
+ end
+ -- checkbox for assign distant signal
+ local assign_dst = rseg.assign_dst
+ if assign_dst == nil then
+ assign_dst = (sel_rpart.seg~=1) -- special behavior when assign_dst is nil (and not false):
+ -- defaults to false for the very first signal and true for all others (= minimal user configuration overhead)
+ -- Note: on save, the value will be fixed at either false or true
+ end
+ form = form..string.format("checkbox[4.5,4.0;sa_distant;Announce distant signal;%s]", assign_dst)
+ else
+ form = form..F.label(4.5, 2, "No Signal at this TCB")
+ end
+ elseif sel_rpart and sel_rpart.section then
+ local rseg = route[sel_rpart.seg]
+ if rseg then
+ form = form..F.label(4.5, 2, "Section Options:")
+ -- checkbox for call-on
+ form = form..string.format("checkbox[4.5,4.0;se_callon;Call-on (section may be occupied);%s]", rseg.call_on)
+ end
+ elseif sel_rpart and sel_rpart.err then
+ form = form.."textarea[4.5,2.5;4,4;errorta;Error:;"..tab[sel_rpartidx].."]"
+ else
+ form = form..F.label(4.5, 2, "<< Select a route part to edit options")
+ end
+
+ form = form.."button[0.5,6;1,1;prev;<<<]"
+ form = form.."button[1.5,6;1,1;back;"..routeid.."/"..#tcbs.routes.."]"
+ form = form.."button[2.5,6;1,1;next;>>>]"
+
+
+ --if route.smartroute_generated or route.default_autoworking then
+ -- form = form.."button[3.5,6;2,1;noautogen;Clr Autogen]"
+ --end
+ form = form.."button[5.5,6;3,1;delete;Delete Route]"
+ form = form.."button[0.5,7;3,1;back;Back to signal]"
+ form = form.."button[3.5,7;2,1;clone;Clone Route]"
+ form = form.."button[5.5,7;3,1;newfrom;New From Route]"
--atdebug(route.ars)
form = form.."style[ars;font=mono]"
- form = form.."textarea[0.8,7.3;5,3;ars;Pravidla ARS;"..atil.ars_to_text(route.ars).."]"
- form = form.."button[5.5,7.23;3,1;savears;Uložit pravidla ARS]"
+ form = form.."textarea[0.8,8.3;5,3;ars;ARS Rule List;"..atil.ars_to_text(route.ars).."]"
+ form = form.."button[5.5,8.23;3,1;savears;Save ARS List]"
- minetest.show_formspec(pname, "at_il_routeedit_"..minetest.pos_to_string(sigd.p).."_"..sigd.s.."_"..routeid, form)
-
+ local formname = "at_il_routeedit_"..minetest.pos_to_string(sigd.p).."_"..sigd.s.."_"..routeid
+ minetest.show_formspec(pname, formname, form)
+ -- record selected entry from routelog for receive fields callback
+ sel_rpartcache[pname] = sel_rpart
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
local pname = player:get_player_name()
+ -- retreive sel_rpart from the cache in any case and clear it out
+ local sel_rpart = sel_rpartcache[pname]
if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then
return
end
@@ -118,26 +199,90 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local route = tcbs.routes[routeid]
if not route then return end
+ if fields.prev then
+ atil.show_route_edit_form(pname, sigd, routeid - 1)
+ return
+ end
+ if fields.next then
+ atil.show_route_edit_form(pname, sigd, routeid + 1)
+ return
+ end
+
if fields.setname and fields.name then
route.name = fields.name
end
- if fields.aspect then
- local suppasp = advtrains.interlocking.signal_get_supported_aspects(tcbs.signal)
-
- local callback = function(pname, asp)
- route.aspect = asp
- advtrains.interlocking.show_route_edit_form(pname, sigd, routeid)
+ if fields.sa_main_aspect and sel_rpart and sel_rpart.signal then
+ local idx = tonumber(fields.sa_main_aspect)
+ -- get TCBS here and rseg selected
+ local s_tcbs = ildb.get_tcbs(sel_rpart.param)
+ local rseg = route[sel_rpart.seg]
+ -- main aspect list
+ local signalpos = s_tcbs and s_tcbs.signal
+ if rseg then
+ rseg.main_aspect = nil
+ if idx > 1 then
+ local ndef = signalpos and advtrains.ndb.get_ndef(signalpos)
+ if ndef and ndef.advtrains and ndef.advtrains.main_aspects then
+ rseg.main_aspect = ndef.advtrains.main_aspects[idx - 1].name
+ end
+ end
end
-
- advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, route.name, callback, route.aspect or advtrains.interlocking.GENERIC_FREE)
- return
end
+ if fields.sa_distant and sel_rpart and sel_rpart.signal then
+ local rseg = route[sel_rpart.seg]
+ if rseg then
+ rseg.assign_dst = minetest.is_yes(fields.sa_distant)
+ end
+ end
+ if fields.se_callon and sel_rpart and sel_rpart.section then
+ local rseg = route[sel_rpart.seg]
+ if rseg then
+ rseg.call_on = minetest.is_yes(fields.se_callon)
+ -- reshow form to update CO marker
+ atil.show_route_edit_form(pname, sigd, routeid, sel_rpart.idx)
+ return
+ end
+ end
+
+ --if fields.noautogen then
+ -- route.smartroute_generated = nil
+ -- route.default_autoworking = nil
+ -- -- reshow form for the button to disappear
+ -- atil.show_route_edit_form(pname, sigd, routeid, sel_rpart and sel_rpart.idx)
+ -- return
+ --end
+
if fields.delete then
-- if something set the route in the meantime, make sure this doesn't break.
atil.route.update_route(sigd, tcbs, nil, true)
table.remove(tcbs.routes, routeid)
advtrains.interlocking.show_signalling_form(sigd, pname)
+ -- cleanup
+ sel_rpartcache[pname] = nil
+ return
+ end
+
+ if fields.clone then
+ -- if something set the route in the meantime, make sure this doesn't break.
+ atil.route.update_route(sigd, tcbs, nil, true)
+ local rcopy = table.copy(route)
+ rcopy.name = route.name.."_copy"
+ rcopy.smartroute_generated = nil
+ table.insert(tcbs.routes, routeid+1, rcopy)
+ advtrains.interlocking.show_signalling_form(sigd, pname)
+ -- cleanup
+ sel_rpartcache[pname] = nil
+ return
+ end
+
+ if fields.newfrom then
+ advtrains.interlocking.init_route_prog(pname, sigd, route)
+ minetest.close_formspec(pname, formname)
+ tcbs.ars_ignore_next = nil
+ -- cleanup
+ sel_rpartcache[pname] = nil
+ return
end
if fields.ars and fields.savears then
@@ -147,6 +292,25 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.back then
advtrains.interlocking.show_signalling_form(sigd, pname)
+ -- cleanup
+ sel_rpartcache[pname] = nil
+ return
+ end
+
+ -- if an entry was selected in the textlist (and its not the current one) update the form
+ if fields.routelog then
+ local prev_idx = sel_rpart and sel_rpart.idx or 1
+ local tev = minetest.explode_textlist_event(fields.routelog)
+ local new_idx = tev and tev.index
+ if new_idx and new_idx ~= prev_idx then
+ atil.show_route_edit_form(pname, sigd, routeid, new_idx)
+ return
+ end
+ end
+
+ if fields.quit then
+ -- cleanup
+ sel_rpartcache[pname] = nil
end
end