Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- term = require("term")
- local component = require("component")
- local event = require("event")
- local unicode = require("unicode")
- gpu = term.gpu()
- function newForm(gpu, textBoxes)
- local self = {}
- self.gpu = gpu
- self.textBoxes = textBoxes
- local firstBox = nil
- local previousBox = nil
- for index,box in ipairs(self.textBoxes) do
- if firstBox == nil then
- firstBox = box
- end
- if previousBox ~= nil then
- previousBox.nextBox = box
- end
- box.gpu = gpu
- box:fullRender()
- box.form = self
- previousBox = box
- end
- if previousBox ~= nil and previousBox ~= firstBox then
- previousBox.nextBox = firstBox
- end
- function self:changeColors(background, border, value, hint)
- for index,box in ipairs(self.textBoxes) do
- box:changeColors(background, border, value, hint)
- end
- end
- function self:changeBackgoundColor(color)
- for index,box in ipairs(self.textBoxes) do
- box:changeBackgroundColor(color)
- end
- end
- function self:changeBorderColor(color)
- for index,box in ipairs(self.textBoxes) do
- box:changeBorderColor(color)
- end
- end
- function self:changeValueColor(color)
- for index,box in ipairs(self.textBoxes) do
- box:changeValueColor(color)
- end
- end
- function self:changeHintTextColor(color)
- for index,box in ipairs(self.textBoxes) do
- box:changeHintTextColor(color)
- end
- end
- function self:checkForFocus(x, y)
- for index,box in ipairs(self.textBoxes) do
- if box:isClickInRange(x,y) then
- box:onFocus(x)
- end
- end
- end
- return self
- end
- function newTextbox(x,y,width,onValueChanged,initialValue,hintText)
- local self = {}
- self.hintText = hintText or ""
- self.value = initialValue or ""
- self.previousValue = self.value
- self.gpu = nil
- self.scrollPosition = 1
- self.x = x
- self.y = y
- self.cursor = 1
- self.width = width
- self.form = nil
- --default cruddy colors
- self.backgroundColor = 0x0000FF
- self.borderColor = 0x0000FF
- self.valueColor = 0x0000FF
- self.hintTextColor = 0x0000FF
- function self:changeColors(background, border, value, hint)
- self.backgroundColor, self.borderColor, self.valueColor, self.hintTextColor =
- background or self.backgroundColor, border or self.borderColor,
- value or self.valueColor, hint or self.hintTextColor
- self:fullRender()
- end
- function self:changeBackgoundColor(color) self.backgroundColor = color self:fullRender() end
- function self:changeBorderColor(color) self.borderColor = color self:fullRender() end
- function self:changeValueColor(color) self.valueColor = color self:fullRender() end
- function self:changeHintTextColor(color) self.hintTextColor = color self:fullRender() end
- self.active = false
- self.onValueChanged = onValueChanged or function(newValue) end
- self.nextBox = nil
- function self:setValue(val)
- self.value = val
- self.cursor = 1
- self.scrollPosition = 1
- self:render()
- end
- function self:clear()
- self:setValue("")
- end
- function self:fullRender()
- self.gpu.setBackground(self.backgroundColor)
- self.gpu.setForeground(self.borderColor)
- local topLine = unicode.char(0x2554)
- local bottomLine = unicode.char(0x255A)
- for i=1,self.width,1 do
- topLine = topLine..unicode.char(0x2550)
- bottomLine = bottomLine..unicode.char(0x2550)
- end
- topLine = topLine..unicode.char(0x2557)
- bottomLine = bottomLine..unicode.char(0x255D)
- self.gpu.set(self.x-1,self.y-1,topLine)
- self.gpu.set(self.x-1,self.y+1,bottomLine)
- self.gpu.set(self.x-1,self.y,unicode.char(0x2551))
- self.gpu.set(self.x+self.width,self.y,unicode.char(0x2551))
- self:render()
- end
- function self:render()
- if self.cursor - self.scrollPosition >= self.width then
- self.scrollPosition = self.cursor - self.width + 1
- end
- self.gpu.setBackground(self.backgroundColor)
- self.gpu.setForeground(self.valueColor)
- self.gpu.fill(self.x,self.y,self.width,1," ")
- if string.len(self.value) > 0 then
- self.gpu.set(self.x,self.y,string.sub(self.value,self.scrollPosition,self.scrollPosition+self.width-1))
- elseif string.len(self.hintText) > 0 then
- self.gpu.setForeground(self.hintTextColor)
- self.gpu.set(self.x,self.y,self.hintText)
- self.gpu.setForeground(self.valueColor)
- end
- self:moveCursor()
- end
- function self:moveCursor()
- if self.cursor > string.len(self.value) then
- self.cursor = string.len(self.value)+1
- end
- term.setCursor(self.x+self.cursor-self.scrollPosition,self.y)
- end
- function self:isClickInRange(mouseX,mouseY)
- return mouseY == self.y and mouseX >= self.x and mouseX <= self.x + self.width - 1
- end
- function self:onFocus(mouseX)
- mouseX = mouseX or self.x+string.len(self.value)
- self.cursor = mouseX-self.x+self.scrollPosition
- self:render()
- term.setCursorBlink(true)
- self.active = true
- self.previousValue = self.value
- local goToNext = false
- local lastX,lastY = nil,nil
- while self.active do
- local eventType, p1, p2, p3, p4, p5 = term.pull()
- if eventType == "touch" then
- local screenAddress, x, y, button, player = p1, p2, p3, p4, p5
- if self:isClickInRange(x,y) then
- self.cursor = x-self.x+self.scrollPosition
- self:moveCursor()
- else
- self.active = false
- lastX,lastY = x,y
- end
- elseif eventType == "key_down" then
- lastX, lastY = nil,nil
- local keyboardAddress, chr, code, player = p1, p2, p3, p4
- -- code 15 = tab
- -- printable char range = 32-126
- if chr >= 32 and chr <= 126 then
- self.value = string.sub(self.value,1,self.cursor-1)..unicode.char(chr)..string.sub(self.value,self.cursor)
- self.cursor = self.cursor+1
- if self.cursor - self.scrollPosition > self.width then
- self.scrollPosition = self.scrollPosition + 1
- end
- self:render()
- elseif code == 14 then --backspace
- if string.len(self.value) > 0 and self.cursor > 1 then
- self.value = string.sub(self.value,1,self.cursor-2)..string.sub(self.value,self.cursor)
- self.cursor = self.cursor-1
- if self.cursor - self.scrollPosition < 2 and self.scrollPosition > 1 then
- self.scrollPosition = self.cursor - 1
- end
- self:render()
- end
- elseif code == 203 then --left
- if self.cursor > 1 then
- self.cursor = self.cursor-1
- if self.scrollPosition > 1 and self.cursor - self.scrollPosition < 1 then
- self.scrollPosition = self.cursor
- end
- self:render()
- end
- elseif code == 205 then --right
- if self.cursor <= string.len(self.value) then
- self.cursor = self.cursor+1
- self:render()
- end
- elseif code == 28 then --enter
- self.active = false
- elseif code == 211 then --delete
- if string.len(self.value) > 0 and self.cursor <= string.len(self.value) then
- self.value = string.sub(self.value,1,self.cursor-1)..string.sub(self.value,self.cursor+1)
- self:render()
- end
- elseif code == 199 then --home
- if self.cursor > 1 then
- self.cursor = 1
- self.scrollPosition = 1
- self:render()
- end
- elseif code == 207 then --end
- if self.cursor <= string.len(self.value) then
- self.cursor = string.len(self.value) + 1
- self:render()
- end
- elseif code == 15 then
- if self.nextBox ~= nil then
- goToNext = true
- self.active = false
- end
- end
- end
- end
- --blur control
- self.cursor = 1
- self.scrollPosition = 1
- self:render()
- if self.value ~= self.previousValue then
- self.onValueChanged(self.value)
- end
- if goToNext then
- self.nextBox:onFocus()
- end
- if self.form ~= nil and lastX ~= nil and lastY ~= nil then
- self.form:checkForFocus(lastX,lastY)
- end
- end
- return self
- end
- ----------------------------------------------------------------
- backgroundColor = 0x333333
- textColor = 0x00FF00
- hintTextColor = 0xCCCCCC
- gpu.setBackground(backgroundColor)
- term.clear()
- local form = newForm(gpu,{
- newTextbox(5,5,15), newTextbox(22,5,15), newTextbox(39,5,15),
- newTextbox(5,8,15), newTextbox(22,8,15), newTextbox(39,8,15),
- newTextbox(5,11,15), newTextbox(22,11,15), newTextbox(39,11,15),
- newTextbox(20,20,15,function(newValue) term.setCursor(4,30) term.write("you entered "..newValue) end)
- })
- form:changeColors(backgroundColor, 0xFFFFFF, textColor, hintTextColor)
- local cont = true
- while cont do
- local eventType, p1, p2, p3, p4, p5 = event.pull()
- if eventType == "touch" then
- local x,y = p2,p3
- for index,box in ipairs(form.textBoxes) do
- if box:isClickInRange(x,y) then
- box:onFocus(x)
- end
- end
- elseif eventType == "key_down" then
- if p3 == 14 then --self is backspace probably
- for k,v in ipairs(form.textBoxes) do
- v:clear()
- end
- cont = false
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- term.clear()
- term.setCursor(1,1)
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement