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

[Fixed]Broken Code

Started by CCGrimHaxor, 28 February 2015 - 04:43 PM
CCGrimHaxor #1
Posted 28 February 2015 - 05:43 PM
This is my code:

Spoiler

--[[
	Name: GUI.API
	Creator: account.username
	Modified: Yes
	Creator Profile: http://www.computercraft.info/forums2/index.php?/user/26333-accountusername/
]]--
-- GUI API

black = colors.black
white = colors.white
lightBlue = colors.lightBlue
green = colors.green
yellow = colors.yellow
blue = colors.blue
purple = colors.purple
magenta = colors.magenta
lime = colors.lime
orange = colors.orange
red = colors.red
brown = colors.brown
cyan = colors.cyan
pink = colors.pink
grey = colors.gray
gray = colors.gray
lightGray = colors.lightGray
lightGrey = colors.lightGray

-- Buttons

buttonList = {}
Buttons = {}
Buttons.__index = Buttons

function createButton( name, func )
button = {}
setmetatable(button,Buttons)
button.name = name
button.action = func
return button
end

function Buttons:toggle( newColor,sec )

self:draw( self.x,self.y,self.width,newColor,self.tcolor)

if sec ~= nil then
sleep(sec)
self:draw( self.x,self.y,self.width,self.color,self.tcolor )
end
end


function Buttons:draw( x,y,width,color,tcolor )

table.insert(buttonList,{self.name,x,y,width,self.action})

self.x = x
self.y = y
self.width = width
if self.tcolor == nil then
self.color = color
end
self.tcolor = tcolor

for i = 1,width do
paintutils.drawLine(x, y + i, x + #self.name + 1, y + i, color)
end

term.setCursorPos(x,y + math.ceil(width/2))
term.setTextColor(tcolor)
term.setBackgroundColor(color)
term.write(" "..self.name.." ")
end

function Buttons:trigger()
self.action()
end

function Buttons:remove()
for i = 1,#buttonList do
if self.name == buttonList[i][1] then
table.remove(buttonList,i)
end
end
self = nil
end

function detect( x,y,trigger )
for i = 1,#buttonList do
if x >= buttonList[i][2] and x <= buttonList[i][2] + #buttonList[i][1] + 1 and y >= buttonList[i][3] and y <= buttonList[i][3] + buttonList[i][4] then
if trigger == true then
if buttonList[i][5] ~= nil then
buttonList[i][5]()
end
end
return buttonList[i][1]
end
end
end

-- Progress Bars

barList = {}
Bars = {}
Bars.__index = Bars

function createBar( name )
bar = {}
setmetatable(bar,Bars)
bar.name = name
return bar
end

function Bars:setup( x,y,length,color,pcolor,disp,dispbcolor,tcolor )
self.x,self.y,self.length,self.color,self.pcolor,self.disp,self.dispbcolor,self.tcolor = x,y,length,color,pcolor,disp,dispbcolor,tcolor
end

function Bars:draw( x,y,length,color,pcolor,disp,dispbcolor,tcolor )

if self.x == nil and x ~= nil then
self.x,self.y,self.length,self.color,self.pcolor,self.disp,self.dispbcolor,self.tcolor = x,y,length,color,pcolor,disp,dispbcolor,tcolor
end

self.percent = 0
term.setCursorPos(x,y)
paintutils.drawLine(x,y,x+ length,y,color)
term.setCursorPos(x,y)
if self.percent > 0 then
paintutils.drawLine(x,y,x + length*(self.percent/100),y,pcolor)
end


percentString = tostring(self.percent).."%"
if disp == true then
term.setCursorPos(math.max(x + math.ceil(length/2) - math.ceil(#percentString/2),0) + 1,y-1)
term.setBackgroundColor(dispbcolor)
term.setTextColor(tcolor)
write(percentString)
end
end

function Bars:update( percent )
self.percent = percent
term.setCursorPos(self.x,self.y)
paintutils.drawLine(self.x,self.y,self.x + self.length,self.y,self.color)
term.setCursorPos(self.x,self.y)
if self.percent > 0 then
paintutils.drawLine(self.x,self.y,self.x + self.length*(self.percent/100),self.y,self.pcolor)
end


percentString = tostring(self.percent).."%"
if self.disp == true then
term.setCursorPos(math.max(self.x + math.ceil(self.length/2) - math.ceil(#percentString/2),0) + 1,self.y-1)
term.setBackgroundColor(self.dispbcolor)
term.setTextColor(self.tcolor)
write(percentString)
end
end

-- Textboxs

TextBoxes = {}
TextBoxeList = {}
TextBoxes.__index = TextBoxes

function createTextBox(name)
textbox = {}
setmetatable(textbox, TextBoxes)
textbox.name = name
return textbox
end

function TextBoxes:redraw(self)
term.setBackgroundColor(self.bcolor)
paintutils.drawLine(self.x, self.y, self.x + self.length - 1, self.y, self.bcolor)
term.setCursorPos(self.x, self.y)
write(self.text)
end

function TextBoxes:draw(x, y, length, bcolor, tcolor, text)
term.setBackgroundColor(bcolor)
paintutils.drawLine(x, y, x + length - 1, y, bcolor)
term.setCursorPos(x, y)
write(text)
local tbl = {
x = x,
y = y,
length = length,
bcolor = bcolor,
tcolor = tcolor,
text = text,
name = self.name,
}
table.insert(TextBoxeList, tbl)
end

function detectTxtBox(x,y)
for i,v in pairs(TextBoxeList) do
if x >= v.x and x <= v.x + v.length and y == v.y then
local input = v.text

   term.setCursorBlink(true)
   term.setBackgroundColor(v.bcolor)
   repeat
	 term.setCursorPos(v.x,v.y)
	 term.write(input)

	 local ev, p1 = os.pullEvent()
	 if ev == "char" then
	   if #input < v.length then
		 input = input .. p1
	   end
	 elseif ev == "key" then
	   if p1 == keys.backspace then
		 input = input:sub(1, #input - 1)
	   end
	 end
   until ev == "key" and p1 == keys.enter

   term.setCursorBlink(false)
   v.text = input
end
end
end

-- Boxes

Boxs = {}
Boxs.__index = Boxs

function createDialogueBox( title,body,boxType )
boxes = {}
setmetatable(boxes,Boxs)
boxes.title = title
boxes.body = body
boxes.boxType = boxType
return boxes
end

function Boxs:draw( x,y,width,color,bcolor,tcolor )
ret = nil
self.width = width
self.x = x
self.y = y

if self.boxType == "yn" then																	  -- YN Box

if type(self.body) ~= "table" then
paintutils.drawLine(x, y, x + #self.body + 1, y, bcolor)
term.setCursorPos(x,y)
term.setTextColor(tcolor)
write(self.title)

self.len = #self.body

for i = 1,width do
paintutils.drawLine(x, y + i, x + #self.body, y + i, color)
end

term.setCursorPos(x + 1, y + 2)
term.write(self.body)


term.setCursorPos(x + 1,y + width)
term.setTextColor(tcolor)
term.setBackgroundColor(green)
write(" Yes ")

term.setCursorPos(x + len - 4,y + width)
term.setBackgroundColor(red)
write(" No ")

repeat
event,click,cx,cy = os.pullEvent("mouse_click")

if cx >= x + 1 and cx <= x + 5 and cy == y + width then
ret = true
elseif cx >= x + len - 5 and cx <= x + len - 1  and cy == y + width then
ret = false
end
until ret ~= nil

else

len = 0
for i = 1,#self.body do
if #self.body[i] > len then
len = #self.body[i]
end
end

paintutils.drawLine(x, y, x + len + 1, y, bcolor)
term.setCursorPos(x,y)
term.setTextColor(tcolor)
write(self.title)

for i = 1,width do
paintutils.drawLine(x, y + i, x + len + 1, y + i, color)
end

for i = 1,#self.body do
term.setCursorPos(x + (len/2 - #self.body[i]/2) + 1, y + i + 1)
term.write(self.body[i])
end

term.setCursorPos(x + 1,y + width)
term.setTextColor(tcolor)
term.setBackgroundColor(green)
write(" Yes ")

term.setCursorPos(x + len - 4,y + width)
term.setBackgroundColor(red)
write(" No ")

repeat
event,click,cx,cy = os.pullEvent("mouse_click")

if cx >= x + 1 and cx <= x + 5 and cy == y + width then
ret = true
elseif cx >= x + len - 5 and cx <= x + len - 1  and cy == y + width then
ret = false
end
until ret ~= nil


self.len = len
end

elseif self.boxType == "ok" then																  -- Ok Box
if type(self.body) ~= "table" then

paintutils.drawLine(x, y, x + #self.body + 1, y, bcolor)
term.setCursorPos(x,y)
term.setTextColor(tcolor)
write(self.title)
self.len = #self.body

for i = 1,width do
paintutils.drawLine(x, y + i, x + #self.body, y + i, color)
end

term.setCursorPos(x + 1, y + 2)
term.write(self.body)

term.setCursorPos(x + (self.len/2) - 1,y + width)
term.setTextColor(tcolor)
term.setBackgroundColor(green)
write(" Ok ")


repeat
event,click,cx,cy = os.pullEvent("mouse_click")

if cx > x + (self.len/2 - 4) and cx < x + (self.len/2) and cy == y + width then
ret = true
end
until ret == true

else

len = 0
for i = 1,#self.body do
if #self.body[i] > len then
len = #self.body[i]
end
end
self.len = len

paintutils.drawLine(x, y, x + len + 1, y, bcolor)
term.setCursorPos(x,y)
term.setTextColor(tcolor)
write(self.title)

for i = 1,width do
paintutils.drawLine(x, y + i, x + len + 1, y + i, color)
end

for i = 1,#self.body do
term.setCursorPos(x + (len/2 - #self.body[i]/2) + 1, y + i + 1)
term.write(self.body[i])
end

term.setCursorPos(x + (self.len/2) - 1,y + width)
term.setTextColor(tcolor)
term.setBackgroundColor(green)
write(" Ok ")

repeat
event,click,cx,cy = os.pullEvent("mouse_click")

if cx > x + (len/2 - 4) and cx < x + (len/2) and cy == y + width then
ret = true
end
until ret == true
end
end
return ret
end

function Boxs:clear( color )
paintutils.drawLine(self.x, self.y, self.x + self.len + 1, self.y, color)
for i = 1,self.width do
paintutils.drawLine(self.x, self.y + i, self.x + self.len + 1, self.y + i, color)
end
end

Calling:

os.loadAPI("/BIOS/GUIapi")
os.loadAPI("/BIOS/GUIXAPI")
local w,h = term.getSize()
local running = true
local buttons = {
btnInst = {
  text = "Use Installer",
  x = 2,
  y = 5,
  action = function() tog() end,
  toggle = true,
},
btnDone = {
  text = "Done",
  x = 2,
  y = 12,
  action = function() done() end,
  toggle = false,
},
btnCncl = {
  text = "Cancel",
  x = 9,
  y = 12,
  action = function() cncl() end,
  toggle = false,
},
}
local textboxes = {
txtName = {
  text = "",
  x = 2,
  y = 4,
  length = w - 2,
  hide = false,
  box = nil,
},
txtIPath = {
  text = "",
  x = 2,
  y = 7,
  length = w - 2,
  hide = false,
  box = nil,
},
txtOPath = {
  text = "",
  x = 2,
  y = 9,
  length = w - 2,
  hide = false,
  box = nil,
},
txtAuthor = {
  text = "",
  x = 2,
  y = 11,
  length = w - 2,
  hide = false,
  box = nil,
},
}
local txtBoxs = {}
local btns = {}
local function drawLabels()
term.setCursorPos(2, 3)
write("Name:")
term.setCursorPos(2, 6)
write("Installer Path:")
term.setCursorPos(2, 8)
write("OS Folder Path:")
term.setCursorPos(2, 10)
write("Author:")
end
local function drawTextBoxes()
for i,v in pairs(textboxes) do
  local a = GUIXAPI.createTextBox(i)
  a:draw(v.x, v.y, v.length, colors.lightBlue, colors.white, v.text)
  table.insert(txtBoxs, a)
end
end
local function redrawTextBoxes()
for i,v in pairs(txtBoxs) do
  v:redraw(v)
end
end
local function drawButtons()
for i,v in pairs(buttons) do
  local a = GUIXAPI.createButton(v.text, v.action)
  if v.toggle then
   a:draw(v.x, v.y - 1, 1, colors.green, colors.white)
  else
   a:draw(v.x, v.y - 1, 1, colors.red, colors.white)
  end
  table.insert(btns, a)
end
end
local function draw()
term.setBackgroundColor(colors.blue)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
GUIapi.centerText("Fire-BIOS")
drawLabels()
drawTextBoxes()
drawButtons()
term.setBackgroundColor(colors.blue)
end
function redraw()
term.setBackgroundColor(colors.blue)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
GUIapi.centerText("Fire-BIOS")
drawLabels()
redrawTextBoxes()
drawButtons()
term.setBackgroundColor(colors.blue)
end
function cncl()
running = false
cncl = nil
tog = nil
done = nil
end
function tog()
buttons.btnInst.toggle = not buttons.btnInst.toggle
end
function done()
running = false
cncl = nil
tog = nil
done = nil
end
draw()
while running do
local ev = {os.pullEvent("mouse_click")}
GUIXAPI.detect(ev[3], ev[4], true)
GUIXAPI.detectTxtBox(ev[3], ev[4])
redraw()
end

Took the easy way out:

TextBoxes = {}
TextBoxeList = {}
TextBoxes.__index = TextBoxes
function createTextBox(name)
textbox = {}
setmetatable(textbox, TextBoxes)
textbox.name = name
return textbox
end
function TextBoxes:redraw()
--[[term.setBackgroundColor(self.bcolor)
paintutils.drawLine(self.x, self.y, self.x + self.length - 1, self.y, self.bcolor)
term.setCursorPos(self.x, self.y)
write(self.text)]]--
term.setBackgroundColor(TextBoxeList[self].bcolor)
paintutils.drawLine(TextBoxeList[self].x, TextBoxeList[self].y, TextBoxeList[self].x + TextBoxeList[self].length - 1, TextBoxeList[self].y, TextBoxeList[self].bcolor)
term.setCursorPos(TextBoxeList[self].x, TextBoxeList[self].y)
write(TextBoxeList[self].text)
end
function TextBoxes:draw(x, y, length, bcolor, tcolor, text)
term.setBackgroundColor(bcolor)
paintutils.drawLine(x, y, x + length - 1, y, bcolor)
term.setCursorPos(x, y)
write(text)
local tbl = {
  x = x,
  y = y,
  length = length,
  bcolor = bcolor,
  tcolor = tcolor,
  text = text,
  name = self.name,
}
TextBoxeList[self] = tbl
end
function detectTxtBox(x,y)
for i,v in pairs(TextBoxeList) do
  if x >= v.x and x <= v.x + v.length and y == v.y then
   local input = v.text
	  term.setCursorBlink(true)
	  term.setBackgroundColor(v.bcolor)
	  repeat
		term.setCursorPos(v.x,v.y)
		term.write(input)
		local ev, p1 = os.pullEvent()
		if ev == "char" then
		  if #input < v.length then
			input = input .. p1
		  end
		elseif ev == "key" then
		  if p1 == keys.backspace then
			input = input:sub(1, #input - 1)
		  end
		end
	  until ev == "key" and p1 == keys.enter
	  term.setCursorBlink(false)
	  v.text = input
  end
end
end

Why doesn't it work I don't understand?
Is lua that poorly coded or is it computercraft?
How do I fix it?
When I call redraw it errors. But I always call draw before redraw!
Error: Window Expected Number


Thanks for all your help
Edited on 28 February 2015 - 06:28 PM
Kouksi44 #2
Posted 28 February 2015 - 06:12 PM
The variable self in your redraw function does not exist as you state your function as Textboxes:redraw() rather than Textboxes.redraw(self) . This is not a problem of lua I think.
CCGrimHaxor #3
Posted 28 February 2015 - 06:34 PM
The variable self in your redraw function does not exist as you state your function as Textboxes:redraw() rather than Textboxes.redraw(self) . This is not a problem of lua I think.

Didn't work
Kouksi44 #4
Posted 28 February 2015 - 06:54 PM
How are you calling your redraw function ?

"Didnt work" is no use for nobody. Same error message as before ?
CCGrimHaxor #5
Posted 28 February 2015 - 06:57 PM
How are you calling your redraw function ?

"Didnt work" is no use for nobody. Same error message as before ?
Same updating now with full codes

I added code for calling and the api itself
Kouksi44 #6
Posted 28 February 2015 - 07:03 PM
You can call your function just by using ":". so not "v:redraw(v). but just "v:redraw().

Really not sure if that will fix it but give it try .
CCGrimHaxor #7
Posted 28 February 2015 - 07:05 PM
You can call your function just by using ":". so not "v:redraw(v). but just "v:redraw().

Really not sure if that will fix it but give it try .

Now I get:
Attempt to index ? (a nil value)
valithor #8
Posted 28 February 2015 - 07:13 PM
Okay so lets look at why its erroring before we try to figure it out. You are passing the table TextBoxes to the TextBoxes:redraw function, but the variables you are calling in that function do not exist in that table. So you are passing nil to all of the commands within that function. You store the information in your TextBoxes:draw function in a table called TextBoxeList, but they are not stored in a way that would be accessible to the redraw function as it is (they are stored as individual tables). Your problem is attempting to access variables that do not exist in the table you are attempting to access them from.

Edit: Personally it is hard to read the code with a lot of similarly named variables, so I will hope that knowing the reason why it is erroring is enough for you to find a solution. If not I will continue to try and read the code and help figure it out.
Edited on 28 February 2015 - 06:15 PM
Kouksi44 #9
Posted 28 February 2015 - 07:16 PM
Any information given on the line number the error occurs ?
valithor #10
Posted 28 February 2015 - 07:17 PM
Any information given on the line number the error occurs ?

Everything in the redraw function errors. Because the variables that he is calling do not exist.
CCGrimHaxor #11
Posted 28 February 2015 - 07:22 PM
Any information given on the line number the error occurs ?

First line of redraw

Okay so lets look at why its erroring before we try to figure it out. You are passing the table TextBoxes to the TextBoxes:redraw function, but the variables you are calling in that function do not exist in that table. So you are passing nil to all of the commands within that function. You store the information in your TextBoxes:draw function in a table called TextBoxeList, but they are not stored in a way that would be accessible to the redraw function as it is (they are stored as individual tables). Your problem is attempting to access variables that do not exist in the table you are attempting to access them from.

Edit: Personally it is hard to read the code with a lot of similarly named variables, so I will hope that knowing the reason why it is erroring is enough for you to find a solution. If not I will continue to try and read the code and help figure it out.

But how does detectTxtBox get the variables then????
valithor #12
Posted 28 February 2015 - 07:26 PM
But how does detectTxtBox get the variables then????

It uses the TextBoxeList variable… not the TextBoxes variable. The TextBoxeList variable has all of the textboxes in it. The TextBoxes variable only has the two functions (redraw and draw), and is what you pass to the redraw function.
CCGrimHaxor #13
Posted 28 February 2015 - 07:28 PM
Fixed :D/>
LeviM #14
Posted 28 February 2015 - 07:44 PM
Nice Grim :)/>