-- Contains user interface elements require("oct_utils") require("termbox_defs") -- visible_textboxes is a global list of all textboxes we can cycle through -- it is, in principle, a circular list -- the top of the list is the currently selected textbox -- upon a switch (i.e. TAB key), the list is rotated registered_textboxes = {} function create_textbox(id, pos_x, pos_y, max_length, label) t = oct_tb_sprite_new() t["x"] = pos_x t["y"] = pos_y t["shape"] = label .. string.rep("_", max_length) -- what is displayed to user t["fg"] = TB_WHITE local textbox = {} textbox["sprite"] = t textbox["contents"] = "" -- what is returned when box is submitted textbox["max_length"] = max_length textbox["id"] = id textbox["label"] = label return textbox end function update_registered_textboxes_appearance() -- textbox at front is focused, set to green registered_textboxes[1]["sprite"]["fg"] = TB_GREEN -- set all other textboxes to unfocused (white colored) for i=2,#registered_textboxes do registered_textboxes[i]["sprite"]["fg"] = TB_WHITE end end function register_textbox(textbox) already_registered = false; for i=1,#registered_textboxes do if (registered_textboxes[i] == textbox) then already_registered = true end end if (already_registered) then OCT_LOG_WARNING("Attempted to register an already-registered textbox") else table.insert(registered_textboxes, 1, textbox) end update_registered_textboxes_appearance() end function unregister_textbox(textbox) removed = false for i=1,#registered_textboxes do if (registered_textboxes[i] == textbox) then table.remove(registered_textboxes, i) textbox["sprite"]["fg"] = TB_WHITE removed = true end end if not removed then OCT_LOG_WARNING("Attempted to unregister an unregistered textbox") end update_registered_textboxes_appearance() end function textbox_contents_to_shape(contents, max_length) l = string.len(contents) ret_str = "" if (l < max_length+1) then ret_str = contents n_underscores = max_length - l ret_str = ret_str .. string.rep("_", n_underscores) else -- show only the last max_length characters ret_str = string.sub(contents, -max_length) end return ret_str end function handle_textbox(key, ch) local to_return = nil if (registered_textboxes[1] == nil) then OCT_LOG_WARNING("Called handle_textbox when no textboxes are registered") else -- Convert ch from a character code to a character ch = string.char(ch) -- if nothing was pressed, ch is '\0' (null byte) if (ch ~= '\0') then -- Update the contents of the textbox, this isn't displayed by default registered_textboxes[1]["contents"] = registered_textboxes[1]["contents"] .. ch end if (key == TB_KEY_BACKSPACE2 or key == TB_KEY_BACKSPACE) then registered_textboxes[1]["contents"] = string.sub(registered_textboxes[1]["contents"], 1, string.len(registered_textboxes[1]["contents"])-1) end -- Update the user-visible sprite if (registered_textboxes[1]) then registered_textboxes[1]["sprite"]["shape"] = registered_textboxes[1]["label"] .. textbox_contents_to_shape(registered_textboxes[1]["contents"], registered_textboxes[1]["max_length"]) end -- Submit our registered textboxes if (key == TB_KEY_ENTER) then to_return = {} for i=1,#registered_textboxes do curr = registered_textboxes[i] to_return[curr["id"]] = curr["contents"] end end -- Rotate the registered textboxes if (key == TB_KEY_TAB) then table.insert(registered_textboxes, 1, table.remove(registered_textboxes)) update_registered_textboxes_appearance() end end return to_return end