Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- ComputerCraft GUI library by DennouNeko
- Distributed under CC BY-NC-SA license:
- -Attribution required
- -Only non-commercial uses are permitted
- -Adaptations must be shared under same terms
- --]]
- -- TODO: type checking for arguments and sanity checks
- local expect = dofile("rom/modules/main/cc/expect.lua").expect
- local gui = {}
- local function isInside(elem, px, py)
- local x1,y1 = elem.getPosition()
- local cx,cy = elem.getSize()
- local x2,y2 = x1+cx-1,y1+cy-1
- return x1 <= px and px <= x2 and y1 <= py and py <= y2
- end
- function gui.version()
- return "libGUI v1.0.2"
- end
- -- Creates a new, raw gui element -
- -- a wrapper for window/terminal.
- -- If position and dimensions are not
- -- specified, it fills whole parent terminal.
- function gui.create(parent, x, y, cx, cy, text)
- if x == nil or y == nil then
- x,y = 1,1
- end
- if cx == nil or cy == nil then
- cx,cy = parent.getSize()
- end
- local self = window.create(parent, x, y, cx, cy)
- self.text = text or ""
- self.type = nil
- self.child = {}
- function self.setText(newText)
- self.text = newText or ""
- end
- function self.addChild(child)
- self.child[#self.child+1] = child
- end
- function self.onClick(px, py)
- local hit = false
- for k,v in pairs(self.child) do
- local dx,dy = v.getPosition()
- if v.isVisible() and isInside(v, px, py) then
- hit = v.onClick(px-dx+1, py-dy+1)
- end
- if hit then break end
- end
- --if not hit then
- -- nothing to do when clicked background
- --end
- return hit
- end
- function self.colorSwap(newFg, newBg)
- local bg = self.getBackgroundColor()
- local fg = self.getTextColor()
- newFg = newFg or fg
- newBg = newBg or bg
- self.setBackgroundColor(newBg)
- self.setTextColor(newFg)
- return fg, bg
- end
- local _redraw = self.redraw
- function self.redraw()
- _redraw()
- for k,v in pairs(self.child) do
- if v.isVisible() then
- v.redraw()
- end
- end
- end
- return self
- end
- function gui.window(parent, x, y, cx, cy, title)
- local self = gui.create(parent, x, y, cx, cy, title)
- self.type = "window"
- local _color_fg = colors.white
- local _color_bg = colors.lightGray
- self.setBackgroundColor(_color_bg)
- self.setTextColor(_color_fg)
- self.clear()
- local _redraw = self.redraw
- function self.redraw()
- _redraw()
- -- backup current colors and set first used colors
- local fg,bg = parent.colorSwap(colors.white, colors.blue)
- local title1 = tostring(self.text):sub(1,cx-1)
- local fullTitle = " " .. title1 .. string.rep(" ", cx-1 - #title1) .. "X"
- parent.setCursorPos(x-1, y-1)
- parent.write(fullTitle)
- for py = y,y+cy do
- parent.setBackgroundColor(colors.white)
- parent.setCursorPos(x-1,py)
- parent.write(" ")
- parent.setBackgroundColor(colors.gray)
- parent.setCursorPos(x+cx,py)
- parent.write(" ")
- end
- parent.setCursorPos(x,y+cy)
- parent.write(string.rep(" ", cx+1))
- -- restore original colors
- parent.colorSwap(fg, bg)
- end
- parent.addChild(self)
- return self
- end
- function gui.button(parent, x, y, cx, cy, label, func, param)
- local self = gui.create(parent, x, y, cx, cy, label)
- self.type = "button"
- local _state = false
- local _color_off = colors.red
- local _color_on = colors.lime
- function self.setState(state)
- _state = state
- end
- function self.getState()
- return _state
- end
- function self.setColors(color_on, color_off)
- _color_on = color_on or _color_on
- _color_off = color_off or _color_off
- end
- function self.toggle()
- _state = not _state
- return _state
- end
- function self.redraw()
- local color
- if _state then
- color = _color_on
- else
- color = _color_off
- end
- local py = math.floor(cy / 2) + 1
- local px = math.floor((cx - #self.text) / 2) + 1
- local fg,bg = self.colorSwap(colors.white, color)
- --for ly = y,y+cy-1 do
- -- temp.setCursorPos(x,ly)
- -- temp.write(string.rep(" ", cx))
- --end
- self.clear()
- self.setCursorPos(px, py)
- self.write(self.text)
- self.colorSwap(fg, bg)
- end
- function self.onClick(px,py)
- if func ~= nil then
- func(self, param)
- elseif doDebug then
- print("No handler for button \"" .. tostring(self.text) .. "\"")
- end
- return true
- end
- parent.addChild(self)
- return self
- end
- function gui.progress(parent, x, y, cx, cy, isVertical, clickCallback, param)
- local self = gui.create(parent, x, y, cx, cy, nil)
- self.type = "progress"
- local _color_fg = colors.blue
- local _color_bg = colors.black
- local _min = 0
- local _max = 100
- local _pos = 0
- function self.setRange(min, max)
- _min = math.min(min,max)
- _max = math.max(min,max)
- self.setProgress(_pos)
- end
- function self.setProgress(pos)
- _pos = math.max(_min,math.min(_max,pos))
- end
- function self.setColors(color_fg, color_bg)
- _color_fg = color_fg or _color_fg
- _colot_bg = color_bg or _color_bg
- end
- function self.redraw()
- local fg,bg = self.colorSwap(colors.white, _color_bg)
- local p = (_pos - _min) / (_max - _min)
- self.clear()
- self.setBackgroundColor(_color_fg)
- -- at this point p is a value between 0 and 1
- -- representing progress between 0% and 100%
- if not isVertical then
- -- convert it to bar width
- local pw = math.floor(p * cx + 0.5)
- local line = string.rep(" ", pw)
- for py = 1,cy do
- self.setCursorPos(1,py)
- self.write(line)
- end
- else
- -- convert it to bar height
- p = math.floor((1 - p) * cy + 0.5) + 1
- local line = string.rep(" ", cx)
- for py = p,cy do
- self.setCursorPos(1,py)
- self.write(line)
- end
- end
- self.colorSwap(fg, bg)
- end
- function self.onClick(px, py)
- if clickCallback == nil then
- return false
- end
- local pos = 0
- if not isVertical then
- pos = (px - 1) / (cx - 1)
- else
- pos = 1 - (py - 1) / (cy - 1)
- end
- pos = math.floor(pos * (_max - _min))
- clickCallback(self, param, pos)
- return true
- end
- parent.addChild(self)
- return self
- end
- function gui.label(parent, x, y, cx, cy, text, align)
- local self = gui.create(parent, x, y, cx, cy)
- self.type = "label"
- text = text or ""
- align = align or "TL"
- local _color_fg = colors.black
- local _color_bg = colors.lightGray
- function self.setText(_text, _align)
- text = _text or ""
- align = _align or align
- end
- function self.setColors(color_fg, color_bg)
- _color_fg = color_fg or _color_fg
- _color_bg = color_bg or _color_bg
- end
- function self.redraw()
- local valign = align:sub(1,1)
- local halign = align:sub(2,2)
- local px,py
- if halign == "L" or halign == "l" then
- px = 1
- elseif halign == "R" or halign == "r" then
- px = cx - #text + 1
- elseif halign == "C" or halign == "c" then
- px = math.floor((cx - #text) / 2) + 1
- end
- if valign == "T" or valign == "t" then
- py = 1
- elseif valign == "B" or valign == "b" then
- py = cy
- elseif valign == "C" or valign == "c" then
- py = math.floor(cx / 2) + 1
- end
- local fg,bg = self.colorSwap(_color_fg, _color_bg)
- self.clear()
- self.setCursorPos(px, py)
- self.write(text)
- self.colorSwap(fg, bg)
- end
- parent.addChild(self)
- return self
- end
- return gui
Advertisement
Add Comment
Please, Sign In to add comment