This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Axolotl's profile picture

[Lua][Question] Help with menu

Started by Axolotl, 22 January 2013 - 09:25 AM
Axolotl #1
Posted 22 January 2013 - 10:25 AM
I want to make the below menu into a worm style menu but I don't really know where to start. Any help would be greatly appreciated.
I would like "RedNet" to be in the top left, "v1.1.0" in the top right, and the action menu centered on the screen. I also want to try to make it so that you use the arrow keys to select the options instead of typing a number.

while true do
  term.clear()
  term.setCursorPos(1,1)
  print("Welcome to RedNet!")
  print("v1.1.0")
  print("")
  print("Actions:")
  print("1. Receive")
  print("2. Send Message")
  print("3. Broadcast Message")
  print("4. Configure Modem")
  print("5. Announce")
  print("")
  write("Perform action ")
  local var = read()
  if var == "1" then
	receive()
  elseif var == "2" then
	send()
  elseif var == "3" then
	broadcast()
  elseif var == "4" then
	configure()
  elseif var == "5" then
	announce()
  else
	print("This action does not exist.")
  end
end
theoriginalbit #2
Posted 22 January 2013 - 10:31 AM
the easiest way would be to store the menu item in a table. then a variable will be which one is currently selected so that when drawing you can indicate which one is selected… if you want the menu in the middle, not just the string, base the x position based off the longest menu item…




local tMenu = { "Receive", "Send", "Broadcast", "Configure", "Announce" }

local function findLongest()
  local long = #tMenu[1]
  for i = 2, #tMenu do
    local cLen = #tMenu[i]
    if cLen > long then
      long = cLen
    end
  end
  return long
end

local selected = 5
local longest = findLongest() + 4 -- +4 allows for the drawing of the selected thing
local sw, sh = term.getSize()

local function drawMenu()
  for i = 1, #tMenu do
    term.setCursorPos( sw / 2 - longest / 2, sh / 2 - #tMenu / 2 + i ) -- centres by x and y
    if i == selected then
      write( "[ "..tMenu[i].. string.rep( " ", longest - #tMenu[i] ) .." ]" ) -- string rep will add in enough spaces so the closing ] is lined up to the end of all other menu items
    else
      write( "  "..tMenu[i].."  " )
    end
  end
end

then all you need to do is increment the selected when the buttons are pressed…
Edited on 22 January 2013 - 09:58 AM
ikke009 #3
Posted 22 January 2013 - 10:44 AM
To center it get the screen with and hight at the beginning
w,h = os.getSize()

to use the arrow keys to move around in the menu you need to use os.pullEvent("key") instead of read()
if you do something like this

w,h=os.getSize()

term.setCursorPos((w/2)-5,1) --centers it
write("options:")
term.setCursorPos((w/2)-5,2)
write("1. Recieve")
--etc. etc.

while true do
  ev,k = os.pullEvent("key")
  if k = keys.up then
    --insert code to go one option up
  elseif k = keys.down then
    --insert code to go one option down
  elseif k = keys.enter then
    --if sentence here to execute selected option
    break
  end
end

remiX #4
Posted 22 January 2013 - 05:59 PM
w,h = os.getSize()

It's term.getSize()

Here's a complete code with using TheOriginalBit's functions

Spoiler

local tMenu = { "Receive", "Send", "Broadcast", "Configure", "Announce", "Exit" }

local function findLongest(t_table)
	local long = #t_table[1]
	for i = 2, #t_table do
		local cLen = #t_table[i]
		if cLen > long then
			long = cLen
		end
	end
	return long
end

local sw, sh = term.getSize()
local version = "v1.1.0"

local function drawMenu(t_table)
  for i = 1, #t_table do
    term.setCursorPos( sw / 2 - longest / 2, sh / 2 - #t_table / 2 + i ) -- centres by x and y
    if i == selected then
      write( "[ "..t_table[i].. string.rep( " ", longest - #t_table[i] ) .." ]" ) -- string rep will add in enough spaces so the closing ] is lined up to the end of all other menu items
    else
      write( "  "..t_table[i].. string.rep( " ", longest - #t_table[i] ) .."  " )
    end
  end
end

function startMenu(t_table)
	selected = 1
	longest = findLongest(t_table)
	while true do
		drawMenu(t_table)
		_, k = os.pullEventRaw("key")
		if k == keys.up then
			selected = selected - 1
		elseif k == keys.down then
			selected = selected + 1
		elseif k == keys.enter then
			return t_table[selected], selected
		end
		if selected < 1 then selected = #t_table
		elseif selected > #t_table then selected = 1 end
	end
end

function backgroundStuff()
	term.clear()
	term.setCursorPos(1, 1)
	write("RedNet")
	term.setCursorPos(sw - #version + 1, 1)
	write(version)
end

while true do -- Main Loop
	backgroundStuff()
	option, number = startMenu(tMenu)
	if option == "Receive" then

	elseif option == "Send" then

	elseif option == "Broadcast" then

	elseif option == "Configure" then

	elseif option == "Announce" then

	elseif option == "Exit" then
		term.clear()
		term.setCursorPos(1, 1)
		break
	end
end
theoriginalbit #5
Posted 22 January 2013 - 06:08 PM
Here's a complete code with using TheOriginalBit's functions
:D/> … I was planning on finishing that when I got on the computer, it was too annoying on my phone… seems I forgot :P/>