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

Help with menu

Started by Hacha, 09 October 2012 - 03:53 AM
Hacha #1
Posted 09 October 2012 - 05:53 AM
I want to do easy menu, but i don't know how it's make…
Who can help me???
Hacha #2
Posted 09 October 2012 - 06:24 AM
What do you think about this?


local w,h = term.getSize()
function printCentred( y, s )
    local x = math.floor((w - string.len(s)) / 2)
    term.setCursorPos(x,y)
    term.clearLine()
    term.write( s )
end
local nOption = 1
local function drawMenu()
    term.clear()
    term.setCursorPos(1,1)
    term.write( "NAME OF MENU" )
    term.setCursorPos(w-11,1)
    if nOption == 1 then
    term.write( "OPTION 1" )
    elseif nOption == 2 then
    term.write( "OPTION 2" )
    else
    term.write( "OPTION 3" )
    end
   
end
term.clear()
local function drawFrontend()
    printCentred( math.floor(h/2) - 3, "" )
    printCentred( math.floor(h/2) - 2, "SELECT AN OPTION" )
    printCentred( math.floor(h/2) - 1, "" )
    printCentred( math.floor(h/2) + 0, ((nOption == 1) and "[ OPTION 1 ]") or "OPTION 1" )
    printCentred( math.floor(h/2) + 1, ((nOption == 2) and "[ OPTION 2 ]") or "OPTION 2" )
    printCentred( math.floor(h/2) + 2, ((nOption == 3) and "[ OPTION 3 ]") or "OPTION 3" )
    printCentred( math.floor(h/2) + 3, "" )
end
drawMenu()
drawFrontend()
while true do
    local e,p = os.pullEvent()
    if e == "key" then
	    local key = p
	    if key == 17 or key == 200 then
		    if nOption > 1 then
			    nOption = nOption - 1
			    drawMenu()
			    drawFrontend()
		    end
	    elseif key == 31 or key == 208 then
		    if nOption < 3 then
			    nOption = nOption + 1
			    drawMenu()
			    drawFrontend()
		    end
	    elseif key == 28 then
		    break
	    end
    end
end
clear()
if nOption == 1 then
    print("Option 1 selected")
elseif nOption == 2 then
    print("Option 2 selected")
else
    print("Option 3 selected")
end
Blockeh #3
Posted 09 October 2012 - 08:31 AM
Firstly, This should be in the "Ask a Pro" Section.
Secondly, There are tutorials already on the forums, have a look before posting.
theoriginalbit #4
Posted 09 October 2012 - 08:34 AM
this is one I use all the time that I wrote myself. However the horizontal menu is untested (I may not have even finished implementing. Cant remember. I always use the vertical one. This will get your table and find the largest menu item and then add [ ] around the selected one.

This is the code just to draw to the screen:
SpoilerGlobal variables that I use:
NOTE: I use the action in my program loop so that the state doesnt change until enter is pressed.

menuButtons = {"New Game", "Highscore", "How To Play", "Settings", "Quit"}
currentState = "menu"
selection = 1
action = menuButtons[selection]

Button Drawing Function

buttonDirs = {"vertical", "horizontal"}
local function DrawButtons(buttons, x, y, selected, direction)
    valid = false
    for i = 1, table.getn(buttonDirs) do
	    if direction == buttonDirs[i] then
		    valid = true
		    break
	    end
    end
   
    if not valid then direction = buttonDirs[1] end
   
    -- Set x and y
    if x == nil then
	    x = sizeX / 2
    end
    if y == nil then
	    y = sizeY / 2 - (table.getn(buttons) / 2)
    end
   
    min = 1
    max = table.getn(buttons)
    -- Get longest menu item
    local length = 0
    for i = min, max do
	    if string.len(buttons[i]) > length then length = string.len(buttons[i]) end
    end
    -- Print menu items
    for i = min, max do
	    -- find and set starting position of menu items
	    xPos = x - (length / 2) - 2
	   
	    if direction == buttonDirs[1] then
		    term.setCursorPos(xPos, y + i)
	    else
		    term.setCursorPos(xPos + 1, y)
	    end
	   
	    -- if its selected menu item draw brackets around it
	    if buttons[i] == selected then
		    write("[ "..buttons[i])
		   
		    if direction == buttonDirs[1] then
			    term.setCursorPos(xPos + length + 2, y + i)
		    else
			    term.setCursorPos(xPos + length + 2, y)
		    end
		   
		    write(" ]")
	    else
		    write("  "..buttons[i])
	    end
    end
end

This is the code that I use to change the menu:
SpoilerNOTE: I have a function to deal with moving the menu up and down as it changes a few variables. But for basic movement all you need is a 'current selection' variable that gets modified and then sent to the drawButtons function.

local function ProcessMenuInput()
    local sEvent, param = os.pullEventRaw()
    if sEvent == "key" then
	    if param == 200 then
		    -- Up
		    moveMenuUp(menuButtons)
	    elseif param == 208 then
		    -- Down
		    moveMenuDown(menuButtons)
	    elseif param == 28 then
		    changeState(action)
	    end
    end
end

This is what my moving menu functions do:
SpoilerNOTE: This will not allow the menu to go beyond the bounds.

local function moveMenuUp(menu)
    selection = selection - 1
    if selection < 1 then selection = 1 end
    action = menu[selection]
end
local function moveMenuDown(menu)
    selection = selection + 1
    if selection > #menu then selection = #menu end
    action = menu[selection]
end
NOTE: This one will send selected to the top when it goes beyond the bottom

local function moveMenuUp(menu)
    selection = selection - 1
    if selection < 1 then selection = #menu end
    action = menu[selection]
end
local function moveMenuDown(menu)
    selection = selection + 1
    if selection > #menu then selection = 1 end
    action = menu[selection]
end
Hacha #5
Posted 09 October 2012 - 02:31 PM
Thank you, guy's :D/>/>