diff --git a/src/IDCField.lua b/src/IDCField.lua new file mode 100644 index 0000000..bad8192 --- /dev/null +++ b/src/IDCField.lua @@ -0,0 +1,115 @@ +local component = require("component") +local classes = require("src/classes") +local event = require("event") +local Button = require("src/Button") + +local gpu = component.gpu + +local IDCField = classes.class() + +function IDCField:init(x, y, w, h, label, bg, fg, textBg, idcs) + self.x = x + self.y = y + self.w = w + self.h = h + self.label = label + self.bg = bg + self.fg = fg + self.textBg = textBg + self.closeBtn = Button.new(x + w - 6, y, 5, 1, "X", RED, TEXT_WHITE) + self.idcs = idcs +end + +function IDCField:draw() + gpu.setBackground(self.bg) + gpu.fill(self.x, self.y, self.w, self.h, " ") + gpu.setForeground(self.fg) + gpu.set(self.x + self.w/2 - string.len(self.label)/2, self.y + 1, self.label) + gpu.setBackground(self.textBg) + gpu.fill(self.x + 1, self.y + 3, self.w - 2, self.h - 4, " ") + self.closeBtn:draw() +end + +function IDCField:hide() + gpu.setBackground(BACKGROUND) + gpu.fill(self.x, self.y, self.w, self.h, " ") +end + +function IDCField:readInput() + local entries = self:showIdcList() + local editing = true + while editing do + local _, _, x, y = event.pull(1, "touch") + + -- check click position + if x ~= nil and y ~= nil and x >= self.x + 1 and x < (self.x + self.w - 2) and y >= self.y + 4 and y < (self.y + self.h - 2) then + local entryNum + if y >= self.y + 4 + entries then + -- new entry + gpu.fill(self.x + 2, self.y + 4 + entries, self.w - 4, 2, " ") + entryNum = entries + else + -- edit entry + entryNum = y - self.y - 4 + end + + local newEntry = self:readLine(entryNum) + if string.len(newEntry) == 36 or string.len(newEntry) == 0 then + self.idcs[entryNum + 1] = newEntry + end + entries = self:showIdcList() + end + + if self.closeBtn:clicked(x, y) then + self.closeBtn:setBackground(RED_BRIGHT) + editing = false + end + end +end + +function IDCField:readLine(lineNum) + local text = "" + local typing = true + gpu.setForeground(TEXT_WHITE) + while typing do + gpu.fill(self.x + 2, self.y + 4 + lineNum, self.w - 4, 1, " ") + gpu.set(self.x + 2, self.y + 4 + lineNum, text .. "_") + local _,_,key = event.pull("key_down") + + if string.len(text) == 36 or key == 13 then + typing = false + elseif key == 8 and string.len(text) > 0 then + text = text:sub(1, -2) + elseif key ~= nil and ((key >= 48 and key <= 57) or (key >= 97 and key <= 122) or key == 45) then + text = text .. string.char(key) + end + + -- separators + if string.len(text) == 8 or string.len(text) == 13 or string.len(text) == 18 or string.len(text) == 23 then + text = text .. "-" + end + end + + gpu.set(self.x + 2, self.y + 4 + lineNum, text .. " ") + return text +end + +function IDCField:showIdcList() + local entries = 0 + gpu.setBackground(self.textBg) + + for k, v in pairs(self.idcs) do + if k ~= "n" then + gpu.set(61 + 2, 14 + entries + 4, v) + entries = entries + 1 + end + end + + gpu.setForeground(GREY_LIGHT) + gpu.set(61 + 2, 14 + entries + 4, "> Click here to add new entry or") + gpu.set(61 + 2, 14 + entries + 5, " click existing entry to edit it") + + return entries +end + +return IDCField diff --git a/src/app.lua b/src/app.lua index 54bdb0c..a38a1d2 100644 --- a/src/app.lua +++ b/src/app.lua @@ -25,8 +25,10 @@ GREY_LIGHT = 0xA0A0A0 -- disabled controls foreground local graphics = require("src/graphics") local Button = require("src/Button") local AddressField = require("src/AddressField") +local IDCField = require("src/IDCField") local stargate = component.stargate +local gpu = component.gpu -- draw static graphics graphics.draw() @@ -42,7 +44,7 @@ end updateExitBtn() -- iris button -local irisBtn = Button.new(4, 3, 34, 3, "IRIS", CYAN, TEXT_WHITE) +local irisBtn = Button.new(4, 3, 16, 3, "IRIS", CYAN, TEXT_WHITE) function updateIrisBtn() irisBtn:setBackground(CYAN) local irisState = stargate.irisState() @@ -59,6 +61,26 @@ function updateIrisBtn() end updateIrisBtn() +-- iris auto close button +local autoClose = false +local autoCloseBtn = Button.new(22, 3, 16, 3, "AUTOCLOSE: OFF", CYAN, TEXT_WHITE) +function updateAutoCloseBtn() + if autoClose then + autoCloseBtn:setLabel("AUTOCLOSE: ON") + autoCloseBtn:setBackground(CYAN_LIGHT) + else + autoCloseBtn:setLabel("AUTOCLOSE: OFF") + autoCloseBtn:setBackground(CYAN) + end + local irisState = stargate.irisState() + if irisState == "Offline" then + autoCloseBtn:lock() + else + autoCloseBtn:unlock() + end +end +updateAutoCloseBtn() + -- terminate connection button local terminateBtn = Button.new(4, 7, 34, 3, "TERMINATE CONNECTION", RED_DARK, TEXT_WHITE) function updateTerminateBtn() @@ -73,11 +95,11 @@ end updateTerminateBtn() -- address field -local addressFld = AddressField.new(4, 11, 34, 5, "ENTER ADDRESS", CYAN, TEXT_WHITE, BACKGROUND) +local addressFld = AddressField.new(4, 11+1, 34, 5, "ENTER ADDRESS", CYAN, TEXT_WHITE, BACKGROUND) addressFld:draw() -- dial button -local dialBtn = Button.new(4, 17, 34, 3, "DIAL", CYAN, TEXT_WHITE) +local dialBtn = Button.new(4, 17+1, 34, 3, "DIAL", CYAN, TEXT_WHITE) function updateDialBtn() dialBtn:setBackground(CYAN) local gateState, _, _ = stargate.stargateState() @@ -89,7 +111,15 @@ function updateDialBtn() end updateDialBtn() +-- configuration button +local configBtn = Button.new(4, 43+3, 34, 3, "GDO CONFIGURATION", CYAN, TEXT_WHITE) +configBtn:draw() + +-- IDC field +local idcField = IDCField.new(61, 14, 40, 22, "VALID IDCS", CYAN, TEXT_WHITE, BACKGROUND, stargate.getValidIDCs()) + -- main loop +local prevState = "Idle" local run = true while run do -- update gate and iris state @@ -113,12 +143,6 @@ while run do graphics.emptyGate() end - elseif gateState == "Closing" then - -- clear chevrons - for i = 1, 9 do - graphics.drawChevron(i, " ", BACKGROUND) - end - elseif gateState == "Connected" then if irisState == "Closed" then -- wormhole is connected, but iris is closed @@ -128,6 +152,11 @@ while run do graphics.drawWormhole() end else + -- clear chevrons + for i = 1, 9 do + graphics.drawChevron(i, " ", BACKGROUND) + end + if irisState == "Closed" then -- iris is closed graphics.drawIris() @@ -141,8 +170,8 @@ while run do local _, _, x, y = event.pull(1, "touch") -- update control elements - graphics.drawRemoteInfo(addressFld.address, stargate.energyToDial(addressFld.address)) - graphics.drawLocalGateInfo(stargate.localAddress(), stargate.energyAvailable(), irisState) + graphics.drawRemoteInfo(4, 21+2, addressFld.address, stargate.energyToDial(addressFld.address)) + graphics.drawLocalGateInfo(4, 31+2, stargate.localAddress(), stargate.energyAvailable(), irisState) -- exit button updateExitBtn() @@ -164,6 +193,15 @@ while run do end end + -- iris autoclose button + updateAutoCloseBtn() + if autoCloseBtn:clicked(x, y) then + autoClose = not autoClose + end + if autoClose and gateState == "Connected" and direction == "Incoming" and prevState == "Dialling" then + stargate.closeIris() + end + -- terminate button updateTerminateBtn() if terminateBtn:clicked(x, y) then @@ -194,6 +232,37 @@ while run do end end + -- config button + if configBtn:clicked(x, y) then + configBtn:setBackground(CYAN_LIGHT) + + -- open IDC window + idcField:draw() + idcField:readInput() + + -- close IDC window + idcField:hide() + graphics.drawGate() + configBtn:setBackground(CYAN) + + -- remove existing stargate IDCs + for k, v in pairs(stargate.getValidIDCs()) do + if k ~= "n" then + stargate.removeIDC(v) + end + end + -- add new IDCs + for k, v in pairs(idcField.idcs) do + if k ~= "n" then + stargate.addIDC(v) + end + end + idcField.idcs = stargate.getValidIDCs() + end + + -- save current gate state + prevState = gateState + end -- reset colors diff --git a/src/graphics.lua b/src/graphics.lua index fbbf0bb..86bf7f2 100644 --- a/src/graphics.lua +++ b/src/graphics.lua @@ -12,8 +12,8 @@ function graphics.draw() graphics.drawGate() graphics.drawGateControls() graphics.drawStatusWindow() - graphics.drawRemoteInfo() - graphics.drawLocalGateInfo() + graphics.drawRemoteInfo(4, 21+2) + graphics.drawLocalGateInfo(4, 31+2) end function graphics.drawBorders() @@ -469,55 +469,55 @@ function graphics.drawStateMsg(state, direction) end end -function graphics.drawRemoteInfo(address, energy) +function graphics.drawRemoteInfo(x, y, address, energy) gpu.setBackground(CYAN) - gpu.fill(4, 21, 34, 9, " ") + gpu.fill(x, y, 34, 9, " ") gpu.setBackground(BACKGROUND) - gpu.fill(5, 24, 32, 5, " ") + gpu.fill(x+1, y+3, 32, 5, " ") gpu.setBackground(CYAN) gpu.setForeground(TEXT_WHITE) - gpu.set(4 + 17 - string.len("REMOTE GATE DATA")/2, 22, "REMOTE GATE DATA") + gpu.set(x + 17 - string.len("REMOTE GATE DATA")/2, y+1, "REMOTE GATE DATA") gpu.setBackground(BACKGROUND) if address == nil or string.len(address) < 7 then - gpu.set(6, 25, "ADDRESS: INVALID") + gpu.set(x+2, y+4, "ADDRESS: INVALID") else - gpu.set(6, 25, "ADDRESS: " .. address) + gpu.set(x+2, y+4, "ADDRESS: " .. address) end if energy == nil then - gpu.set(6, 27, "ENERGY TO DIAL: N/A") + gpu.set(x+2, y+6, "ENERGY TO DIAL: N/A") else - gpu.set(6, 27, "ENERGY TO DIAL: " .. math.floor(energy + 0.5)) + gpu.set(x+2, y+6, "ENERGY TO DIAL: " .. math.floor(energy + 0.5)) end end -function graphics.drawLocalGateInfo(address, energy, iris) +function graphics.drawLocalGateInfo(x, y, address, energy, iris) gpu.setBackground(CYAN) - gpu.fill(4, 31, 34, 11, " ") + gpu.fill(x, y, 34, 11, " ") gpu.setBackground(BACKGROUND) - gpu.fill(5, 34, 32, 7, " ") + gpu.fill(x+1, y+3, 32, 7, " ") gpu.setBackground(CYAN) gpu.setForeground(TEXT_WHITE) - gpu.set(4 + 17 - string.len("LOCAL GATE DATA")/2, 32, "LOCAL GATE DATA") + gpu.set(x + 17 - string.len("LOCAL GATE DATA")/2, y+1, "LOCAL GATE DATA") gpu.setBackground(BACKGROUND) if address == nil then - gpu.set(6, 35, "ADDRESS: UNKNOWN") + gpu.set(x+2, y+4, "ADDRESS: UNKNOWN") else - gpu.set(6, 35, "ADDRESS: " .. address) + gpu.set(x+2, y+4, "ADDRESS: " .. address) end if energy == nil then - gpu.set(6, 37, "AVAILABLE ENERGY: N/A") + gpu.set(x+2, y+6, "AVAILABLE ENERGY: N/A") else - gpu.set(6, 37, "AVAILABLE ENERGY: " .. math.floor(energy + 0.5)) + gpu.set(x+2, y+6, "AVAILABLE ENERGY: " .. math.floor(energy + 0.5)) end if iris == nil then - gpu.set(6, 39, "IRIS STATE: UNKNOWN") + gpu.set(x+2, y+8, "IRIS STATE: UNKNOWN") else - gpu.set(6, 39, "IRIS STATE: " .. iris) + gpu.set(x+2, y+8, "IRIS STATE: " .. iris) end end