Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- math.round = function(n)
- return math.floor(n + .5)
- end
- local function inheritsFrom(baseClass)
- local new_class = {}
- local class_mt = {__index = new_class}
- new_class.new = function()
- local newinst = {}
- setmetatable(newinst, class_mt)
- return newinst
- end
- if baseClass then
- setmetatable(new_class, {__index = baseClass})
- end
- return new_class
- end
- -------------------------------------------------------------
- -------------------------------------------------------------
- -- GUI Server class --
- -------------------------------------------------------------
- -------------------------------------------------------------
- local BUTTON_LEFT = 1;
- local BUTTON_RIGHT = 2;
- local BUTTON_W_UP = 3;
- local BUTTON_W_DOWN = 4;
- local BUTTON_W = 5;
- local gui_event = {
- x = 0;
- y = 0;
- button = BUTTON_LEFT;
- key = 0;
- }
- gui_event.__index = gui_event
- gui_event.new = function()
- local t = {}
- setmetatable(t, gui_event)
- return t
- end
- local gui_server = {
- children = nil;
- width = 100; -- %
- height = 100; -- %
- x = 0;
- y = 0;
- parent = nil;
- parentIndex = 1;
- hasBgColor = true;
- bgColor = colors.lightBlue;
- isParent = false;
- }
- gui_server.__index = gui_server
- gui_server.new = function(x, y, w, h, c)
- local t = {
- x = x;
- y = y;
- width = w;
- height = h;
- isParent = true;
- }
- t.children = (c == nil or type(c) ~= "table") and {} or c;
- setmetatable(t, gui_server)
- return t
- end
- function gui_server:addChild(c)
- if self.isParent then
- c.parent = self
- c.parentIndex = #self.children + 1
- table.insert(self.children, c)
- end
- end
- function gui_server:removeChild(i)
- if self.isParent then
- table.remove(self.children, i)
- for l = i, #self.children do
- self.children[i]:setIndex(self.children[i].parentIndex - 1)
- end
- end
- end
- function gui_server:pxSize()
- if self.parent == nil then
- local w, h = term.getSize()
- return math.round(w / 100 * self.width), math.round(h / 100 * self.height)
- end
- local w, h = self.parent:pxSize()
- return math.round(w / 100 * self.width), math.round(h / 100 * self.height)
- end
- function gui_server:pxPosLocal()
- if self.parent == nil then
- local w, h = term.getSize()
- return math.round(w / 100 * self.x), math.round(h / 100 * self.y)
- end
- local w, h = self.parent:pxSize()
- return math.round(w / 100 * self.x), math.round(h / 100 * self.y)
- end
- function gui_server:pxPosGlobal()
- if self.parent == nil then
- local w, h = term.getSize()
- return math.round(w / 100 * self.x), math.round(h / 100 * self.y)
- end
- local w, h = self.parent:pxSize()
- local pX, pY = self.parent:pxPosGlobal()
- -- print("w, h = " .. w .. ", " .. h)
- return math.round(w / 100 * self.x) + pX, math.round(h / 100 * self.y) + pY
- end
- function gui_server:removeSelf()
- if self.parent ~= nil then
- self.parent:removeChild(self.parentIndex)
- end
- end
- function gui_server:onMouseEvent(ev)
- -- print("Pressed button " .. ev.button .. " at (" .. ev.x .. ", " .. ev.y .. ")")
- if self.isParent then
- for _, c in ipairs(self.children) do
- c:onMouseEvent(ev)
- end
- end
- end
- function gui_server:onKeyEvent(ev)
- -- print("Pressed key " .. ev.key)
- if self.isParent then
- for _, c in ipairs(self.children) do
- c:onKeyEvent(ev)
- end
- end
- end
- function gui_server:draw()
- if self.hasBgColor then
- term.setBackgroundColor(self.bgColor)
- local w, h = self:pxSize()
- local x, y = self:pxPosGlobal()
- for _x = 0, w do
- for _y = 0, h do
- term.setCursorPos(_x + x, _y + x)
- io.write(" ")
- end
- end
- end
- if self.isParent then
- for _, c in ipairs(self.children) do
- c:draw()
- end
- end
- end
- function gui_server:redraw()
- if self.parent == nil then
- -- Do the drawing
- self:draw()
- return
- end
- self.parent:draw()
- end
- -------------------------------------------------------------
- -------------------------------------------------------------
- -- GUI Button class --
- -------------------------------------------------------------
- -------------------------------------------------------------
- local gui_button = inheritsFrom(gui_server)
- function gui_button:init(text, x, y, w, h)
- self.textColor = colors.black
- self.bgColor = colors.white
- self.text = text
- self.x = x
- self.y = y
- self.width = w
- self.height = h
- self.onClick = function(x, y) end
- end
- function gui_button:draw()
- term.setTextColor(self.textColor)
- if self.hasBgColor then
- term.setBackgroundColor(self.bgColor)
- local w, h = self:pxSize()
- local x, y = self:pxPosGlobal()
- -- print("x, y = " .. x .. ", " .. y)
- for _x = 0, w - 1 do
- for _y = 0, h - 1 do
- -- print("Drawing at (" .. _x + x .. ", " .. _y + y .. ")")
- term.setCursorPos(_x + x, _y + y)
- io.write(" ")
- end
- end
- end
- local pX, pY = self:pxPosGlobal()
- -- print(pX .. ", " .. pY)
- local w, h = self:pxSize()
- local cX, cY = math.floor(pX + w / 2) - self.text:len() / 2, math.floor(pY + h / 2)
- term.setCursorPos(cX, cY)
- io.write(self.text:sub(1, (self.text:len() > w - 1 and w - 1 or self.text:len())))
- end
- function gui_button:onMouseEvent(ev)
- local _x, _y = self:pxPosGlobal()
- local w, h = self:pxSize()
- if ev.x >= _x and ev.x < _x + w and ev.y >= _y and ev.y < _y + h then
- self.onClick(ev.x, ev.y)
- end
- end
- -------------------------------------------------------------
- -------------------------------------------------------------
- -- GUI Textbox class --
- -------------------------------------------------------------
- -------------------------------------------------------------
- local gui_textbox = inheritsFrom(gui_server)
- function gui_textbox:init(text, x, y, w, m_ch)
- self.text = text
- self.textColor = colors.black
- self.bgColor = colors.white
- self.replaceChar = nil
- self.chars = {}
- for i = 1, text:len() do
- table.insert(self.chars, text:sub(i, i))
- end
- local _w, h = term.getSize()
- self.x = x
- self.y = y
- self.width = w or 30
- self.height = 100 / h
- local sW, sH = self:pxSize()
- while sH ~= 1 do
- self.height = self.height - 0.2
- sW, sH = self:pxSize()
- end
- self.m_ch = m_ch or false
- self.__onClick = function(x, y)
- self:edit()
- end
- self.onClick = function(x, y) end
- end
- function gui_textbox:draw()
- term.setTextColor(self.textColor)
- if self.hasBgColor then
- term.setBackgroundColor(self.bgColor)
- local w, h = self:pxSize()
- local x, y = self:pxPosGlobal()
- -- print("x, y = " .. x .. ", " .. y)
- for _x = 0, w - 1 do
- for _y = 0, h - 1 do
- -- print("Drawing at (" .. _x + x .. ", " .. _y + y .. ")")
- term.setCursorPos(_x + x, _y + y)
- io.write(" ")
- end
- end
- end
- local pX, pY = self:pxPosGlobal()
- -- print(pX .. ", " .. pY)
- local w, h = self:pxSize()
- local cX, cY = pX, math.floor(pY + h / 2)
- term.setCursorPos(cX, cY)
- local line = self.text
- local _line = line
- if self.replaceChar then
- line = ""
- for i = 1, _line:len() do
- line = line .. self.replaceChar:sub(1, 1)
- end
- end
- io.write(line:sub(1, (line:len() > w - 1 and w - 1 or line:len())))
- end
- function gui_textbox:edit()
- local pX, pY = self:pxPosGlobal()
- -- print(pX .. ", " .. pY)
- local w, h = self:pxSize()
- term.setCursorPos(pX, math.floor(pY + h / 2))
- term.setCursorBlink( true )
- local line = self.text
- local cursorX = line:len()
- local chars = {}
- for i = 1, self.text:len() do
- table.insert(chars, self.text:sub(i, i))
- end
- local function redraw(r_ch)
- term.setTextColor(self.textColor)
- term.setBackgroundColor(self.bgColor)
- term.setCursorPos(pX, math.floor(pY + h / 2))
- line = ""
- for _, c in ipairs(chars) do
- line = line .. c
- end
- local _line = line
- if self.replaceChar then
- line = ""
- for i = 1, _line:len() do
- line = line .. self.replaceChar:sub(1, 1)
- end
- end
- for i = 1, w do
- io.write(" ")
- end
- term.setCursorPos(pX, math.floor(pY + h / 2))
- local currentX = pX
- if line:len() >= w - 1 and cursorX >= w - 1 then
- io.write(line:sub(cursorX - (w - 2), cursorX))
- currentX = pX + cursorX - line:sub(1, cursorX - (w - 1)):len()
- elseif line:len() >= w - 1 and cursorX < w - 1 then
- io.write(line:sub(1, w - 1))
- currentX = pX + cursorX
- else
- io.write(line)
- currentX = pX + cursorX
- end
- line = _line
- term.setCursorPos(currentX, math.floor(pY + h / 2))
- end
- redraw(self.replaceChar)
- while true do
- local ev, key = os.pullEvent()
- if ev == "key" then
- if key == keys.left then
- if cursorX > 0 then
- cursorX = cursorX - 1
- end
- elseif key == keys.right then
- if cursorX < line:len() then
- cursorX = cursorX + 1
- end
- elseif key == keys.enter then
- break
- elseif key == keys.backspace then
- if cursorX > 0 then
- table.remove(chars, cursorX)
- cursorX = cursorX - 1
- end
- elseif key == keys.delete then
- if cursorX < line:len() then
- table.remove(chars, cursorX + 1)
- end
- end
- elseif ev == "char" then
- table.insert(chars, cursorX + 1, key)
- cursorX = cursorX + 1
- end
- redraw()
- end
- term.setCursorBlink(false)
- self.text = line
- end
- function gui_textbox:setText(t)
- self.text = t
- for i = 1, t:len() do
- self.chars[i] = t:sub(i, i)
- end
- end
- function gui_textbox:onMouseEvent(ev)
- local _x, _y = self:pxPosGlobal()
- local w, h = self:pxSize()
- if ev.x >= _x and ev.x < _x + w and ev.y >= _y and ev.y < _y + h then
- self.__onClick(ev.x, ev.y)
- self.onClick(ev.x, ev.y)
- end
- end
- local x = gui_server.new(0, 0, 100, 100)
- local button = gui_button.new()
- button:init("Exit", 25, 45, 50, 15)
- button.textColor = colors.black
- button.onClick = function()
- term.setCursorPos(0, 0)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- print(os.version())
- error()
- end
- local tb = gui_textbox.new()
- tb:init("Textbox", 25, 15, 50)
- x:addChild(button)
- x:addChild(tb)
- x:redraw()
- while true do
- local ev, p1, p2, p3, p4 = os.pullEvent()
- local gui_ev = gui_event.new()
- if ev == "mouse_click" then
- gui_ev.button = p1
- if p1 == 3 then
- gui_ev.button = BUTTON_W
- end
- gui_ev.x = p2
- gui_ev.y = p3
- x:onMouseEvent(gui_ev)
- elseif ev == "mouse_scroll" then
- gui_ev.button = p1 == 1 and BUTTON_W_DOWN or BUTTON_W_UP
- gui_ev.x = p2
- gui_ev.y = p3
- x:onMouseEvent(gui_ev)
- elseif ev == "key" then
- gui_ev.key = p1
- x:onKeyEvent(gui_ev)
- end
- x:redraw()
- end
Advertisement
Add Comment
Please, Sign In to add comment