diff --git a/common.lua b/common.lua index ac5f0e9..e71d616 100644 --- a/common.lua +++ b/common.lua @@ -23,3 +23,7 @@ function mooncontroller.tablecopy_change_env(t, env, seen) end return n end + +function mooncontroller.terminal_clear(pos) + minetest.get_meta(pos):set_string("terminal_text","") +end diff --git a/controller.lua b/controller.lua index b75236a..a1a044d 100644 --- a/controller.lua +++ b/controller.lua @@ -62,63 +62,6 @@ local function ignore_event(event, meta) end end ------------------------ --- Formspec creation -- ------------------------ - -local function update_formspec(pos) - local meta = minetest.get_meta(pos) - local code = minetest.formspec_escape(meta:get_string("code")) - local errmsg = minetest.formspec_escape(meta:get_string("errmsg")) - local tab = meta:get_int("tab") - if tab < 1 or tab > 4 then tab = 1 end - - --Default theme settings - local textcolor = "#ffffff" - local bg_img = "jeija_luac_background.png" - local run_img = "jeija_luac_runbutton.png" - local close_img = "jeija_close_window.png" - - --If Dreambuilder's theming engine is in use, then override those - if minetest.global_exists("dreambuilder_theme") then - textcolor = dreambuilder_theme.editor_text_color - bg_img = dreambuilder_theme.name.."_jeija_luac_background.png" - run_img = dreambuilder_theme.name.."_jeija_luac_runbutton.png" - close_img = dreambuilder_theme.name.."_jeija_close_window.png" - end - - local fs = "formspec_version[4]" - .."size[15,12]" - .."style_type[label,textarea,field;font=mono]" - .."style_type[textarea;textcolor="..textcolor.."]" - .."background[0,0;15,12;"..bg_img.."]" - .."tabheader[0,0;tab;Code,Terminal,Help,Examples;"..tab.."]" - .."image_button_exit[14.5,0;0.425,0.4;"..close_img..";exit;]" - - if tab == 1 then - --Code tab - fs = fs.."label[0.1,10;"..errmsg.."]" - .."textarea[0.25,0.6;14.5,9.05;code;;"..code.."]" - .."image_button[6.25,10.25;2.5,1;"..run_img..";program;]" - elseif tab == 2 then - --Terminal tab - local termtext = minetest.formspec_escape(meta:get_string("terminal_text")) - fs = fs.."textarea[0.25,0.6;14.5,9.05;;;"..termtext.."]" - .."field[0.25,9.85;12.5,1;terminal_input;;]" - .."button[12.75,9.85;2,1;terminal_send;Send]" - .."button[12.75,10.85;2,1;terminal_clear;Clear]" - .."field_close_on_enter[terminal_input;false]" - elseif tab == 3 then - --Help tab - fs = fs..mooncontroller.lc_docs.generate_help_formspec(meta:get_int("help_selidx")) - elseif tab == 4 then - --Examples tab - fs = fs..mooncontroller.lc_docs.generate_example_formspec(meta:get_int("example_selidx")) - .."image_button[6.25,10.25;2.5,1;"..run_img..";program_example;]" - end - - meta:set_string("formspec",fs) -end ------------------------- -- Parsing and running -- @@ -132,9 +75,6 @@ local function terminal_write(pos,text,nolf) meta:set_string("terminal_text",newtext) end -local function terminal_clear(pos) - minetest.get_meta(pos):set_string("terminal_text","") -end local function get_safe_print(pos) return function (param,nolf) @@ -153,7 +93,7 @@ end local function get_clear(pos) return function() - terminal_clear(pos) + mooncontroller.terminal_clear(pos) end end @@ -706,7 +646,7 @@ local function reset_formspec(pos, meta, code, errmsg) meta:mark_as_private("code") meta:set_string("errmsg",tostring(errmsg or "")) meta:mark_as_private("errmsg") - update_formspec(pos) + mooncontroller.update_formspec(pos) end local function reset_meta(pos, code, errmsg) @@ -716,7 +656,7 @@ local function reset_meta(pos, code, errmsg) end -- Wraps run_inner with LC-reset-on-error -local function run(pos, event) +function mooncontroller.run(pos, event) if minetest.get_item_group(minetest.get_node(pos).name,"mesecons_luacontroller") <= 0 then return false,"Luacontroller no longer exists" end @@ -749,7 +689,7 @@ local function on_nodetimer_interrupt(pos) local event = {} event.type = "interrupt" event.iid = i - run(pos,event) + mooncontroller.run(pos,event) end interrupts = minetest.deserialize(meta:get_string("interrupts")) or {} --Reload as it may have changed for _,i in ipairs(current) do @@ -782,7 +722,7 @@ mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid) -- There is no luacontroller anymore / it has been reprogrammed / replaced / burnt if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end if (minetest.registered_nodes[minetest.get_node(pos).name].is_burnt) then return end - run(pos, {type="interrupt", iid = iid}) + mooncontroller.run(pos, {type="interrupt", iid = iid}) end) mesecon.queue:add_function("lc_digiline_relay", function (pos, channel, luac_id, msg) @@ -820,92 +760,20 @@ local digiline = { effector = { action = function(pos, _, channel, msg) msg = clean_and_weigh_digiline_message(msg) - run(pos, {type = "digiline", channel = channel, msg = msg}) + mooncontroller.run(pos, {type = "digiline", channel = channel, msg = msg}) end } } -local function get_program(pos) +function mooncontroller.get_program(pos) local meta = minetest.get_meta(pos) return meta:get_string("code") end -local function set_program(pos, code) +function mooncontroller.set_program(pos, code) reset(pos) reset_meta(pos, code) - return run(pos, {type="program"}) -end - -local function on_receive_fields(pos, _, fields, sender) - local meta = minetest.get_meta(pos) - if fields.tab then - meta:set_int("tab",fields.tab) - update_formspec(pos) - else - local tab = meta:get_int("tab") - if tab < 1 or tab > 4 then tab = 1 end - if tab == 1 then - --Code tab - if not fields.program then - return - end - local name = sender:get_player_name() - if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then - minetest.record_protection_violation(pos, name) - return - end - meta:set_string("terminal_text","") - local ok, err = set_program(pos, fields.code) - if not ok then - -- it's not an error from the server perspective - minetest.log("action", "Lua controller programming error: " .. tostring(err)) - end - elseif tab == 2 then - --Terminal tab - if fields.exit or fields.quit then return end - local name = sender:get_player_name() - if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then - minetest.record_protection_violation(pos, name) - return - end - if fields.terminal_clear then - terminal_clear(pos) - update_formspec(pos) - return - end - run(pos,{type="terminal",text=fields.terminal_input}) - elseif tab == 3 then - --Help tab - if fields.help_list then - local event = minetest.explode_textlist_event(fields.help_list) - if event.type == "CHG" then - meta:set_int("help_selidx",event.index) - update_formspec(pos) - end - end - elseif tab == 4 then - --Examples tab - if fields.example_list then - local event = minetest.explode_textlist_event(fields.example_list) - if event.type == "CHG" then - meta:set_int("example_selidx",event.index) - update_formspec(pos) - end - elseif fields.program_example then - local name = sender:get_player_name() - if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then - minetest.record_protection_violation(pos, name) - return - end - local selidx = meta:get_int("example_selidx") - selidx = math.max(1,math.min(selidx,#mooncontroller.lc_docs.example_order)) - local code = mooncontroller.lc_docs.examples[mooncontroller.lc_docs.example_order[selidx]] - meta:set_string("terminal_text","") - meta:set_int("tab",1) - set_program(pos,code) - end - end - end + return mooncontroller.run(pos, {type="program"}) end for a = 0, 1 do -- 0 = off 1 = on @@ -952,7 +820,7 @@ for d = 0, 1 do rules = input_rules[cid], action_change = function (pos, _, rule_name, new_state) mooncontroller.update_real_port_states(pos, rule_name, new_state) - run(pos, {type=new_state, pin=rule_name}) + mooncontroller.run(pos, {type=new_state, pin=rule_name}) end, }, receptor = { @@ -960,8 +828,8 @@ for d = 0, 1 do rules = output_rules[cid] }, luacontroller = { - get_program = get_program, - set_program = set_program, + get_program = mooncontroller.get_program, + set_program = mooncontroller.set_program, }, } @@ -985,7 +853,7 @@ for d = 0, 1 do selection_box = selection_box, node_box = node_box, on_construct = reset_meta, - on_receive_fields = on_receive_fields, + on_receive_fields = mooncontroller.on_receive_fields, sounds = default.node_sound_stone_defaults(), mesecons = mesecons, digiline = digiline, @@ -1034,7 +902,7 @@ minetest.register_node(mooncontroller.BASENAME .. "_burnt", { selection_box = selection_box, node_box = node_box, on_construct = reset_meta, - on_receive_fields = on_receive_fields, + on_receive_fields = mooncontroller.on_receive_fields, sounds = default.node_sound_stone_defaults(), virtual_portstates = {a = false, b = false, c = false, d = false}, mesecons = { diff --git a/init.lua b/init.lua index ff1e05c..5f00cd8 100644 --- a/init.lua +++ b/init.lua @@ -6,6 +6,7 @@ mooncontroller = { dofile(MP.."/docmanager.lua") dofile(MP.."/common.lua") +dofile(MP.."/ui.lua") dofile(MP.."/libraries.lua") dofile(MP.."/port_states.lua") dofile(MP.."/controller.lua") diff --git a/ui.lua b/ui.lua new file mode 100644 index 0000000..575f50b --- /dev/null +++ b/ui.lua @@ -0,0 +1,130 @@ +----------------------- +-- Formspec creation -- +----------------------- + +function mooncontroller.update_formspec(pos) + local meta = minetest.get_meta(pos) + local code = minetest.formspec_escape(meta:get_string("code")) + local errmsg = minetest.formspec_escape(meta:get_string("errmsg")) + local tab = meta:get_int("tab") + if tab < 1 or tab > 4 then tab = 1 end + + --Default theme settings + local textcolor = "#ffffff" + local bg_img = "jeija_luac_background.png" + local run_img = "jeija_luac_runbutton.png" + local close_img = "jeija_close_window.png" + + --If Dreambuilder's theming engine is in use, then override those + if minetest.global_exists("dreambuilder_theme") then + textcolor = dreambuilder_theme.editor_text_color + bg_img = dreambuilder_theme.name.."_jeija_luac_background.png" + run_img = dreambuilder_theme.name.."_jeija_luac_runbutton.png" + close_img = dreambuilder_theme.name.."_jeija_close_window.png" + end + + local fs = "formspec_version[4]" + .."size[15,12]" + .."style_type[label,textarea,field;font=mono]" + .."style_type[textarea;textcolor="..textcolor.."]" + .."background[0,0;15,12;"..bg_img.."]" + .."tabheader[0,0;tab;Code,Terminal,Help,Examples;"..tab.."]" + .."image_button_exit[14.5,0;0.425,0.4;"..close_img..";exit;]" + + if tab == 1 then + --Code tab + fs = fs.."label[0.1,10;"..errmsg.."]" + .."textarea[0.25,0.6;14.5,9.05;code;;"..code.."]" + .."image_button[6.25,10.25;2.5,1;"..run_img..";program;]" + elseif tab == 2 then + --Terminal tab + local termtext = minetest.formspec_escape(meta:get_string("terminal_text")) + fs = fs.."textarea[0.25,0.6;14.5,9.05;;;"..termtext.."]" + .."field[0.25,9.85;12.5,1;terminal_input;;]" + .."button[12.75,9.85;2,1;terminal_send;Send]" + .."button[12.75,10.85;2,1;terminal_clear;Clear]" + .."field_close_on_enter[terminal_input;false]" + elseif tab == 3 then + --Help tab + fs = fs..mooncontroller.lc_docs.generate_help_formspec(meta:get_int("help_selidx")) + elseif tab == 4 then + --Examples tab + fs = fs..mooncontroller.lc_docs.generate_example_formspec(meta:get_int("example_selidx")) + .."image_button[6.25,10.25;2.5,1;"..run_img..";program_example;]" + end + + meta:set_string("formspec",fs) +end + + +function mooncontroller.on_receive_fields(pos, _, fields, sender) + local meta = minetest.get_meta(pos) + if fields.tab then + meta:set_int("tab",fields.tab) + mooncontroller.update_formspec(pos) + else + local tab = meta:get_int("tab") + if tab < 1 or tab > 4 then tab = 1 end + if tab == 1 then + --Code tab + if not fields.program then + return + end + local name = sender:get_player_name() + if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then + minetest.record_protection_violation(pos, name) + return + end + meta:set_string("terminal_text","") + local ok, err = mooncontroller.set_program(pos, fields.code) + if not ok then + -- it's not an error from the server perspective + minetest.log("action", "Lua controller programming error: " .. tostring(err)) + end + elseif tab == 2 then + --Terminal tab + if fields.exit or fields.quit then return end + local name = sender:get_player_name() + if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then + minetest.record_protection_violation(pos, name) + return + end + if fields.terminal_clear then + mooncontroller.terminal_clear(pos) + mooncontroller.update_formspec(pos) + return + end + mooncontroller.run(pos,{type="terminal",text=fields.terminal_input}) + elseif tab == 3 then + --Help tab + if fields.help_list then + local event = minetest.explode_textlist_event(fields.help_list) + if event.type == "CHG" then + meta:set_int("help_selidx",event.index) + mooncontroller.update_formspec(pos) + end + end + elseif tab == 4 then + --Examples tab + if fields.example_list then + local event = minetest.explode_textlist_event(fields.example_list) + if event.type == "CHG" then + meta:set_int("example_selidx",event.index) + mooncontroller.update_formspec(pos) + end + elseif fields.program_example then + local name = sender:get_player_name() + if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then + minetest.record_protection_violation(pos, name) + return + end + local selidx = meta:get_int("example_selidx") + selidx = math.max(1,math.min(selidx,#mooncontroller.lc_docs.example_order)) + local code = mooncontroller.lc_docs.examples[mooncontroller.lc_docs.example_order[selidx]] + meta:set_string("terminal_text","") + meta:set_int("tab",1) + mooncontroller.set_program(pos,code) + end + end + end +end