Skip to content

Instantly share code, notes, and snippets.

@TobleMiner
Last active August 29, 2015 14:21
Show Gist options
  • Save TobleMiner/0fac3eb4714164b75df9 to your computer and use it in GitHub Desktop.
Save TobleMiner/0fac3eb4714164b75df9 to your computer and use it in GitHub Desktop.
local window = tui.Window.create(uiManager)
window:setSize(39, 26)
local label = tui.Label.create(uiManager)
label:setPos(2, 3)
label:setText("Hello World")
label:setOnclick(function() print("Click") end)
window:addChild(label)
local layout = tui.ReactorLayout.create(uiManager)
layout:setPos(4, 5)
window:addChild(layout)
layout:setReactor(reactor)
local gauge = tui.ReactorTempGauge.create(uiManager)
gauge:setSize(32, 2)
gauge:setPos(3, 22)
window:addChild(gauge)
gauge:setReactor(reactor)
local timerId = os.startTimer(0.5)
while(true) do
local event, timer = os.pullEvent("timer")
if(timer == timerId) then
layout:update()
gauge:update()
local temp = reactor:getTemp()
label:setText(tostring(temp).." degC -> "..string.format("%.2f", reactor.tempRate))
timerId = os.startTimer(0.5)
end
end
parallel.waitForAll(function() uiManager:renderThread() end,
function() uiManager:touchThread() end)
function inherits(child, parent)
local meta = getmetatable(child)
child._b = { }
for k,v in pairs(getmetatable(parent)) do
if(meta[k] == nil) then
meta[k] = v
else
child._b[k] = v
end
end
setmetatable(child, meta)
for k,v in pairs(parent) do
if(type(v) ~= "function") then
child[k] = v
end
end
end
function drawBox(mon, posX, posY, width, height, color)
mon.setBackgroundColor(color)
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
if(y == 0 or x == 0 or y == height - 1 or x == width - 1) then
mon.setCursorPos(posX + x, posY + y)
mon.write(" ")
end
end
end
end
function drawFilledBox(mon, posX, posY, width, height, color)
mon.setBackgroundColor(color)
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
mon.setCursorPos(posX + x, posY + y)
mon.write(" ")
end
end
end
local BASE_EVENT_NAME = "tui_update_"
local TOUCH_EVENT_NAME = "monitor_touch"
Tui = { }
Tui.__index = Tui
function Tui.create(mon, side)
local tui = { }
setmetatable(tui, Tui)
tui.components = { }
tui.mon = mon
tui.side = side
tui.event_name = BASE_EVENT_NAME..tostring(tui)
return tui
end
function Tui:addComponent(comp)
self.components[tostring(comp)] = comp
end
function Tui:renderThread()
self.mon.clear()
while(true) do
local event, id = os.pullEvent(self.event_name)
local comp = self.components[id]
comp:render(self.mon)
end
end
function Tui:touchThread()
while(true) do
local event, side, x, y = os.pullEvent(TOUCH_EVENT_NAME)
if(side == self.side) then
for k,v in pairs(self.components) do
if(v.visible and v.onclick ~= nil) then
local posX, posY = v:getPos(true)
local width, height = v:getSize()
if(posX <= x and x <= posX + width
and posY <= y and y <= posY + height) then
v.onclick()
end
end
end
else
os.queueEvent(event, side, x, y) --maybe?
end
end
end
Component = { }
Component.__index = Component
function Component.create(tui)
local component = { }
setmetatable(component, Component)
component.x = 1
component.y = 1
component.width = 0
component.height = 0
component.bgcolor = colors.black
component.fgcolor = colors.white
component.visible = true
component.parent = nil
component.children = { }
component.tui = tui
component.onclick = nil
component.widthLast = component.width
component.heightLast = component.height
component.xLast = component.x
component.yLast = component.y
return component
end
function Component:update()
if(not self.visible) then
return
end
os.queueEvent(self.tui.event_name, tostring(self))
for k,v in pairs(self.children) do
v:update()
end
end
function Component:setPos(x, y)
self.x = x
self.y = y
self:update()
end
function Component:setSize(width, height)
self.width = width
self.height = height
self:update()
end
function Component:setVisible(visible)
self.visible = visible
self:update()
end
function Component:addChild(child)
table.insert(self.children, child)
child.parent = self
self:update()
end
function Component:removeChild(child)
for k,v in pairs(self.children) do
if(child == v) then
table.remove(self.children, k)
child.parent = nil
self:update()
return true
end
end
return false
end
function Component:render(mon)
if(self.parent ~= nil and
(self.widthLast ~= self.width or self.heightLast ~= self.height or
self.x ~= self.xLast or self.y ~= self.yLast)) then
self.widthLast = self.width
self.heightLast = self.height
self.xLast = self.x
self.yLast = self.y
self.parent:update()
end
return false
end
function Component:getPos(absolute)
if(self.parent ~= nil and absolute) then
local offsetX, offsetY = self.parent:getPos()
return offsetX + self.x, offsetY + self.y
else
return self.x, self.y
end
end
function Component:getSize()
return self.width, self.height
end
function Component:setOnclick(listener)
self.onclick = listener
end
Window = { }
Window.__index = Window
function Window.create(tui)
local window = { }
setmetatable(window, Window)
inherits(window, Component.create())
window.tui = tui
tui:addComponent(window)
window:update()
return window
end
function Window:render(mon)
self._b.render(self)
local x, y = self:getPos(true)
local width, height = self:getSize()
drawBox(mon, x, y,width, height, self.fgcolor)
drawFilledBox(mon, x + 1, y + 1, width - 2, height - 2, self.bgcolor)
end
Label = { }
Label.__index = Label
function Label.create(tui)
local label = { }
setmetatable(label, Label)
inherits(label, Component.create())
label.text = ""
label.tui = tui
tui:addComponent(label)
label:update()
return label
end
function Label:setText(text)
self.text = text
self.width = #text
self.height = 1
self:update()
end
function Label:render(mon)
self._b.render(self)
local x, y = self:getPos(true)
local width, height = self:getSize()
drawFilledBox(mon, x, y, width, height, self.bgcolor)
mon.setBackgroundColor(self.bgcolor)
mon.setTextColor(self.fgcolor)
mon.setCursorPos(x, y)
mon.write(self.text)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment