Here is my code
termW, termH = term.getSize()
running = true
function newObject(type)
local object = {type = type or "object"}
function object:description()
return "I am a "..object.type.." object."
end
return object
end
function newRect(x, y, w, h, backgroundColor, supertype)
local rect = {
x = x or 1,
y = y or 1,
w = w or termW,
h = h or termH,
backgroundColor = backgroundColor
}
super = newObject(supertype or "rect")
setmetatable(rect,{__index = super})
function rect:collidesWithPoint(x,y)
return x >= self.x and x <= self.w and y >= self.y and y <= self.h
end
function rect:collidesWithRect(rect)
local a = {
left = self.x,
right = self.x + self.w,
top = self.y,
bottom = self.y + self.h
}
local b = {
left = rect.x,
right = rect.x + rect.w,
top = rect.y,
bottom = rect.y + rect.h
}
local lMost, rMost, tMost, bMost
if a.left < b.left then
lMost = a
rMost = b
else
lMost = b
rMost = a
end
if a.top < b.top then
tMost = a
bMost = b
else
tMost = b
bMost = a
end
local x = rMost.left - lMost.right
local y = bMost.top - tMost.bottom
return x <= 0 and y <= 0
end
function rect:draw()
if self.backgroundColor then
term.setBackgroundColor(self.backgroundColor)
for x=self.x, self.w do
for y=self.y, self.h do
term.setCursorPos(x,y)
term.write(" ")
end
end
else
error("This rect is non-drawable")
end
end
return rect
end
function newText(x, y, string, textColor, supertype)
local text = {
x = x or 1,
y = y or 1,
string = string or "",
textColor = textColor or colors.white
}
super = newObject(supertype or "text")
setmetatable(text,{__index = super})
function text:draw()
term.setCursorPos(self.x,self.y)
term.setTextColor(self.textColor)
term.write(self.string)
end
return text
end
function newTextButton(x, y, text, backgroundColor, textColor, action, supertype)
local textButton = {
text = newText(x+1,y+1,text,textColor),
rect = newRect(x,y,x+#text+2,y+2,backgroundColor),
action = action or function() end
}
super = newObject(supertype or "textButton")
setmetatable(textButton,{__index = super})
function textButton:draw()
self.rect:draw()
self.text:draw()
end
function textButton:handleEvents(e)
if e[1] == "mouse_click" then
if self:collidesWithPoint(e[2],e[3],e[4]) then
self:action()
end
end
end
end
function newContainer()
local container = { }
super = newObject("container")
setmetatable(container,{__index = super})
function container:addObject(object)
table.insert(self,object)
end
function container:removeObject(object)
table.remove(self,object)
end
function container:drawObjects()
for _,v in pairs(self) do
if v.draw then
v:draw()
end
end
end
function container:handleObjectEvents(e)
for _,v in pairs(self) do
if v.handleEvents then
v:handleEvents(e)
end
end
end
return container
end
function toggleBackgroundColor(self)
if self.backgroundColor == colors.red then
self.backgroundColor = colors.lime
else
self.backgroundColor = colors.red
end
end
function quit()
running = false
end
term.clear()
term.setCursorPos(1,1)
local container = newContainer()
container:addObject(newTextButton(10,10,"Quit",colors.red,colors.white,quit))
container:addObject(newTextButton(3,3,"Toggle",colors.red,colors.white,toggleBackgroundColor))
while running do
container:drawObjects()
container:handleObjectEvents({os.pullEvent()})
end
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1,1)
142 is the 3rd line of this function
function container:handleObjectEvents(e)
for _,v in pairs(self) do
if v.handleEvents then
v:handleEvents(e)
end
end
end