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

index ? error with custom button API

Started by allennf, 31 December 2014 - 02:24 PM
allennf #1
Posted 31 December 2014 - 03:24 PM
Hello,
I am trying to write a button drawing API (using this tutorial: http://www.computerc...torial-part-ii/). Whenever I attempt to load the API and create a button, I get this error: "b:83: attempt to index ? (a nil value). I am confused because line 83 is not even interacting with any of the tables I have made.

This is the API (named b)

function button(width, height, label, backgroundColorNormal, backgroundColorPressed, textColorNormal, textColorPressed, hasBorder, borderColorNormal, backgroundColorPressed, startColumn, startRow, isPressed, defaultBackgroundColor, defaultTextColor)
button = {}
button.height = height or 1
button.width = width or 1
button.label = label or ""
button.backgroundColorNormal = backgroundColorNormal or colors.black
button.backgroundColorPressed = backgroundColorPressed or colors.white
button.textColorNormal = textColorNormal or colors.white
button.textColorPressed = textColorPressed or colors.black
button.hasBorder = hasBorder or false
button.borderColorNormal = borderColorNormal or backgroundColorNormal
button.borderColorPressed = borderColorPressed or backgroundColorPressed
button.defaultBackgroundColor = defaultBackgroundColor or colors.black
button.defaultTextColor = defaultTextColor or colors.white
button.startColumn = startColumn or 1
button.startRow = startRow or 1
button.isPressed = isPressed or false

function button.draw(display,isPressed,startColumn,startRow)
if not button.width then
error("Required button argument missing or invalid")
end
display = display or term
if isPressed == false or isPressed then
button.isPressed = isPressed
else
isPressed = button.isPressed
end

local width = button.width
local height = button.height
local label = button.label
local labelPad = 2

if hasBorder == true then
if width < 3 then
width = 3
end
if height < 3 then
height = 3
end

if not isPressed then
if not display.isColor() then
display.setBackgroundColor(colors.white)
else
display.setBackgroundColor(button.borderColorNormal)
end
else
if not display.isColor() then
display.setBackgroundColor(colors.white)
else
display.setBackgroundColor(button.borderColorPressed)
end
end

display.setCursorPos(startColumn,startRow)
display.write(string.rep(" ",width))
for row = 2, height - 1 do
display.setCursorPos(startColumn,startRow + row -1)
display.write(" ")
display.setCursorPos(startColumn + width - 1,startRow + row - 1)
display.write(" ")
end
display.setCursorPos(startColumn,startRow + height - 1)
display.write(string.rep(" ",width))

startColumn = startColumn + 1
startRow = startRow + 1
width = width - 2
height = height - 2
end
end
if not isPressed then
if not display.isColor() then
display.setBackgroundColor(colors.black)
display.setTextColor(colors.white)
else
display.setBackgroundColor(button.backgroundColorNormal)
display.setTextColor(button.textColorNormal)
end
else
if not display.isColor() then
		  display.setBackgroundColor(colors.white)
		  display.setTextColor(colors.black)
		else
		  display.setBackgroundColor(button.backgroundColorPressed)
		  display.setTextColor(button.textColorPressed)
		end
end

for row = startRow, startRow + height - 1 do
display.setCursorPos(startColumn, row)
display.write(string.rep(" ",width))
end

if width <3 then
labelPad = 0
end
if #label > width - labelPad then
label = label:sub(1,width - labelPad)
end

display.setCursorPos(startColumn + math.floor((width - #label) / 2),startRow + math.floor((height-1)/2))
display.write(label)

if not display.isColor() then
display.setBackgroundColor(colors.black)
display.setTextColor(colors.white)
else
display.setBackgroundColor(button.defaultBackgroundColor)
display.setTextColor(button.defaultTextColor)
end

return button

end

This is the program I am using to load the API and create a button (named test)


os.loadAPI("b")

local mon = peripheral.wrap("top")
local confirm = b.button(10,3,"OK", colors.blue, colors.red, colors,white, colors.yellow, true, colors.lightBlue, colors.pink, 2, 2, true, colors.black, colors.white)

b.confirm.draw(mon,true)
sleep(3)
b.confirm.draw(mon, false)


Thanks for helping!
Grim Reaper #2
Posted 31 December 2014 - 06:15 PM
You're trying to use a field/member in 'b' that doesn't exist: confirm.

When you type

b.confirm.draw (mon, true)
, lua looks into the table 'b' and tries to find the table called 'confirm.' However, 'confirm' is a table that exists outside of 'b.' Therefore, it can't find the 'confirm' table in the table 'b,' so it throws the error you're seeing.

To fix this, simply remove the 'b.' from your lines so that you're indexing the proper table: 'confirm.'

Fixed code:

confirm.draw (mon, true)
sleep (3)
confirm.draw (mon, false)
allennf #3
Posted 31 December 2014 - 06:49 PM
You're trying to use a field/member in 'b' that doesn't exist: confirm.

When you type

b.confirm.draw (mon, true)
, lua looks into the table 'b' and tries to find the table called 'confirm.' However, 'confirm' is a table that exists outside of 'b.' Therefore, it can't find the 'confirm' table in the table 'b,' so it throws the error you're seeing.

To fix this, simply remove the 'b.' from your lines so that you're indexing the proper table: 'confirm.'

Fixed code:

confirm.draw (mon, true)
sleep (3)
confirm.draw (mon, false)

Okay, I changed test to:

os.loadAPI("b")

local mon = peripheral.wrap("top")
local confirm = b.button()

confirm.draw(mon,true)
sleep(3)
confirm.draw(mon,false)


Now I have the error: "test:4: attempt to call nil"
Edited on 31 December 2014 - 07:35 PM
Bomb Bloke #4
Posted 31 December 2014 - 11:35 PM
Line 4 calls b.button(); if that's nil, then your API isn't correctly loaded. What's odd is that I'd expect that to generate another indexing error. Hmm. Try rebooting your computer, and if that doesn't sort it:

os.loadAPI("b")

for funcName,_ in pairs(b) do
  print(funcName)
end
Edited on 31 December 2014 - 10:37 PM