mad1231999

GUI!!!

Jan 26th, 2013
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.51 KB | None | 0 0
  1. math.round = function(n)
  2.     return math.floor(n + .5)
  3. end
  4.  
  5. local function inheritsFrom(baseClass)
  6.     local new_class = {}
  7.     local class_mt = {__index = new_class}
  8.  
  9.     new_class.new = function()
  10.         local newinst = {}
  11.         setmetatable(newinst, class_mt)
  12.         return newinst
  13.     end
  14.  
  15.     if baseClass then
  16.         setmetatable(new_class, {__index = baseClass})
  17.     end
  18.  
  19.     return new_class
  20. end
  21.  
  22. -------------------------------------------------------------
  23. -------------------------------------------------------------
  24. --                    GUI Server class                     --
  25. -------------------------------------------------------------
  26. -------------------------------------------------------------
  27. local BUTTON_LEFT = 1;
  28. local BUTTON_RIGHT = 2;
  29. local BUTTON_W_UP = 3;
  30. local BUTTON_W_DOWN = 4;
  31. local BUTTON_W = 5;
  32.  
  33. local gui_event = {
  34.     x = 0;
  35.     y = 0;
  36.     button = BUTTON_LEFT;
  37.     key = 0;
  38. }
  39. gui_event.__index = gui_event
  40.  
  41. gui_event.new = function()
  42.     local t = {}
  43.     setmetatable(t, gui_event)
  44.  
  45.     return t
  46. end
  47.  
  48. local gui_server = {
  49.     children = nil;
  50.     width = 100; -- %
  51.     height = 100; -- %
  52.     x = 0;
  53.     y = 0;
  54.     parent = nil;
  55.     parentIndex = 1;
  56.     hasBgColor = true;
  57.     bgColor = colors.lightBlue;
  58.     isParent = false;
  59. }
  60. gui_server.__index = gui_server
  61.  
  62. gui_server.new = function(x, y, w, h, c)
  63.     local t = {
  64.         x = x;
  65.         y = y;
  66.         width = w;
  67.         height = h;
  68.         isParent = true;
  69.     }
  70.     t.children = (c == nil or type(c) ~= "table") and {} or c;
  71.     setmetatable(t, gui_server)
  72.  
  73.     return t
  74. end
  75.  
  76. function gui_server:addChild(c)
  77.     if self.isParent then
  78.         c.parent = self
  79.         c.parentIndex = #self.children + 1
  80.         table.insert(self.children, c)
  81.     end
  82. end
  83.  
  84. function gui_server:removeChild(i)
  85.     if self.isParent then
  86.         table.remove(self.children, i)
  87.  
  88.         for l = i, #self.children do
  89.             self.children[i]:setIndex(self.children[i].parentIndex - 1)
  90.         end
  91.     end
  92. end
  93.  
  94. function gui_server:pxSize()
  95.     if self.parent == nil then
  96.         local w, h = term.getSize()
  97.  
  98.         return math.round(w / 100 * self.width), math.round(h / 100 * self.height)
  99.     end
  100.  
  101.     local w, h = self.parent:pxSize()
  102.  
  103.     return math.round(w / 100 * self.width), math.round(h / 100 * self.height)
  104. end
  105.  
  106. function gui_server:pxPosLocal()
  107.     if self.parent == nil then
  108.         local w, h = term.getSize()
  109.         return math.round(w / 100 * self.x), math.round(h / 100 * self.y)
  110.     end
  111.  
  112.     local w, h = self.parent:pxSize()
  113.  
  114.     return math.round(w / 100 * self.x), math.round(h / 100 * self.y)
  115. end
  116.  
  117. function gui_server:pxPosGlobal()
  118.     if self.parent == nil then
  119.         local w, h = term.getSize()
  120.         return math.round(w / 100 * self.x), math.round(h / 100 * self.y)
  121.     end
  122.  
  123.     local w, h = self.parent:pxSize()
  124.     local pX, pY = self.parent:pxPosGlobal()
  125.  
  126.     -- print("w, h = " .. w .. ", " .. h)
  127.  
  128.     return math.round(w / 100 * self.x) + pX, math.round(h / 100 * self.y) + pY
  129. end
  130.  
  131. function gui_server:removeSelf()
  132.     if self.parent ~= nil then
  133.         self.parent:removeChild(self.parentIndex)
  134.     end
  135. end
  136.  
  137. function gui_server:onMouseEvent(ev)
  138.     -- print("Pressed button " .. ev.button .. " at (" .. ev.x .. ", " .. ev.y .. ")")
  139.  
  140.     if self.isParent then
  141.         for _, c in ipairs(self.children) do
  142.             c:onMouseEvent(ev)
  143.         end
  144.     end
  145. end
  146.  
  147. function gui_server:onKeyEvent(ev)
  148.     -- print("Pressed key " .. ev.key)
  149.  
  150.     if self.isParent then
  151.         for _, c in ipairs(self.children) do
  152.             c:onKeyEvent(ev)
  153.         end
  154.     end
  155. end
  156.  
  157. function gui_server:draw()
  158.     if self.hasBgColor then
  159.         term.setBackgroundColor(self.bgColor)
  160.         local w, h = self:pxSize()
  161.         local x, y = self:pxPosGlobal()
  162.  
  163.         for _x = 0, w do
  164.             for _y = 0, h do
  165.                 term.setCursorPos(_x + x, _y + x)
  166.                 io.write(" ")
  167.             end
  168.         end
  169.     end
  170.  
  171.     if self.isParent then
  172.         for _, c in ipairs(self.children) do
  173.             c:draw()
  174.         end
  175.     end
  176. end
  177.  
  178. function gui_server:redraw()
  179.     if self.parent == nil then
  180.         -- Do the drawing
  181.         self:draw()
  182.         return
  183.     end
  184.  
  185.     self.parent:draw()
  186. end
  187.  
  188.  
  189.  
  190. -------------------------------------------------------------
  191. -------------------------------------------------------------
  192. --                    GUI Button class                     --
  193. -------------------------------------------------------------
  194. -------------------------------------------------------------
  195. local gui_button = inheritsFrom(gui_server)
  196.  
  197. function gui_button:init(text, x, y, w, h)
  198.     self.textColor = colors.black
  199.     self.bgColor = colors.white
  200.     self.text = text
  201.     self.x = x
  202.     self.y = y
  203.     self.width = w
  204.     self.height = h
  205.     self.onClick = function(x, y) end
  206. end
  207.  
  208. function gui_button:draw()
  209.     term.setTextColor(self.textColor)
  210.  
  211.     if self.hasBgColor then
  212.         term.setBackgroundColor(self.bgColor)
  213.         local w, h = self:pxSize()
  214.         local x, y = self:pxPosGlobal()
  215.  
  216.         -- print("x, y = " .. x .. ", " .. y)
  217.  
  218.         for _x = 0, w - 1 do
  219.             for _y = 0, h - 1 do
  220.                 -- print("Drawing at (" .. _x + x .. ", " .. _y + y .. ")")
  221.                 term.setCursorPos(_x + x, _y + y)
  222.                 io.write(" ")
  223.             end
  224.         end
  225.     end
  226.  
  227.     local pX, pY = self:pxPosGlobal()
  228.     -- print(pX .. ", " .. pY)
  229.     local w, h = self:pxSize()
  230.     local cX, cY = math.floor(pX + w / 2) - self.text:len() / 2, math.floor(pY + h / 2)
  231.     term.setCursorPos(cX, cY)
  232.     io.write(self.text:sub(1, (self.text:len() > w - 1 and w - 1 or self.text:len())))
  233. end
  234.  
  235. function gui_button:onMouseEvent(ev)
  236.     local _x, _y = self:pxPosGlobal()
  237.     local w, h = self:pxSize()
  238.  
  239.     if ev.x >= _x and ev.x < _x + w and ev.y >= _y and ev.y < _y + h then
  240.         self.onClick(ev.x, ev.y)
  241.     end
  242. end
  243.  
  244.  
  245.  
  246. -------------------------------------------------------------
  247. -------------------------------------------------------------
  248. --                    GUI Textbox class                    --
  249. -------------------------------------------------------------
  250. -------------------------------------------------------------
  251. local gui_textbox = inheritsFrom(gui_server)
  252.  
  253. function gui_textbox:init(text, x, y, w, m_ch)
  254.     self.text = text
  255.     self.textColor = colors.black
  256.     self.bgColor = colors.white
  257.     self.replaceChar = nil
  258.     self.chars = {}
  259.  
  260.     for i = 1, text:len() do
  261.         table.insert(self.chars, text:sub(i, i))
  262.     end
  263.  
  264.     local _w, h = term.getSize()
  265.  
  266.     self.x = x
  267.     self.y = y
  268.     self.width = w or 30
  269.     self.height = 100 / h
  270.  
  271.     local sW, sH = self:pxSize()
  272.    
  273.     while sH ~= 1 do
  274.         self.height = self.height - 0.2
  275.         sW, sH = self:pxSize()
  276.     end
  277.  
  278.     self.m_ch = m_ch or false
  279.     self.__onClick = function(x, y)
  280.         self:edit()
  281.     end
  282.     self.onClick = function(x, y) end
  283. end
  284.  
  285. function gui_textbox:draw()
  286.     term.setTextColor(self.textColor)
  287.  
  288.     if self.hasBgColor then
  289.         term.setBackgroundColor(self.bgColor)
  290.         local w, h = self:pxSize()
  291.         local x, y = self:pxPosGlobal()
  292.  
  293.         -- print("x, y = " .. x .. ", " .. y)
  294.  
  295.         for _x = 0, w - 1 do
  296.             for _y = 0, h - 1 do
  297.                 -- print("Drawing at (" .. _x + x .. ", " .. _y + y .. ")")
  298.                 term.setCursorPos(_x + x, _y + y)
  299.                 io.write(" ")
  300.             end
  301.         end
  302.     end
  303.  
  304.     local pX, pY = self:pxPosGlobal()
  305.     -- print(pX .. ", " .. pY)
  306.     local w, h = self:pxSize()
  307.     local cX, cY = pX, math.floor(pY + h / 2)
  308.     term.setCursorPos(cX, cY)
  309.    
  310.     local line = self.text
  311.     local _line = line
  312.  
  313.     if self.replaceChar then
  314.         line = ""
  315.  
  316.         for i = 1, _line:len() do
  317.             line = line .. self.replaceChar:sub(1, 1)
  318.         end
  319.     end
  320.  
  321.     io.write(line:sub(1, (line:len() > w - 1 and w - 1 or line:len())))
  322. end
  323.  
  324. function gui_textbox:edit()
  325.     local pX, pY = self:pxPosGlobal()
  326.     -- print(pX .. ", " .. pY)
  327.     local w, h = self:pxSize()
  328.     term.setCursorPos(pX, math.floor(pY + h / 2))
  329.     term.setCursorBlink( true )
  330.  
  331.     local line = self.text
  332.     local cursorX = line:len()
  333.     local chars = {}
  334.  
  335.     for i = 1, self.text:len() do
  336.         table.insert(chars, self.text:sub(i, i))
  337.     end
  338.  
  339.     local function redraw(r_ch)
  340.         term.setTextColor(self.textColor)
  341.         term.setBackgroundColor(self.bgColor)
  342.         term.setCursorPos(pX, math.floor(pY + h / 2))
  343.  
  344.         line = ""
  345.  
  346.         for _, c in ipairs(chars) do
  347.             line = line .. c
  348.         end
  349.  
  350.         local _line = line
  351.  
  352.         if self.replaceChar then
  353.             line = ""
  354.  
  355.             for i = 1, _line:len() do
  356.                 line = line .. self.replaceChar:sub(1, 1)
  357.             end
  358.         end
  359.  
  360.         for i = 1, w do
  361.             io.write(" ")
  362.         end
  363.  
  364.         term.setCursorPos(pX, math.floor(pY + h / 2))
  365.  
  366.         local currentX = pX
  367.  
  368.         if line:len() >= w - 1 and cursorX >= w - 1 then
  369.             io.write(line:sub(cursorX - (w - 2), cursorX))
  370.             currentX = pX + cursorX - line:sub(1, cursorX - (w - 1)):len()
  371.         elseif line:len() >= w - 1 and cursorX < w - 1 then
  372.             io.write(line:sub(1, w - 1))
  373.             currentX = pX + cursorX
  374.         else
  375.             io.write(line)
  376.             currentX = pX + cursorX
  377.         end
  378.  
  379.         line = _line
  380.  
  381.         term.setCursorPos(currentX, math.floor(pY + h / 2))
  382.     end
  383.  
  384.     redraw(self.replaceChar)
  385.  
  386.     while true do
  387.         local ev, key = os.pullEvent()
  388.  
  389.         if ev == "key" then
  390.             if key == keys.left then
  391.                 if cursorX > 0 then
  392.                     cursorX = cursorX - 1
  393.                 end
  394.             elseif key == keys.right then
  395.                 if cursorX < line:len() then
  396.                     cursorX = cursorX + 1
  397.                 end
  398.             elseif key == keys.enter then
  399.                 break
  400.             elseif key == keys.backspace then
  401.                 if cursorX > 0 then
  402.                     table.remove(chars, cursorX)
  403.                     cursorX = cursorX - 1
  404.                 end
  405.             elseif key == keys.delete then
  406.                 if cursorX < line:len() then
  407.                     table.remove(chars, cursorX + 1)
  408.                 end
  409.             end
  410.         elseif ev == "char" then
  411.             table.insert(chars, cursorX + 1, key)
  412.             cursorX = cursorX + 1
  413.         end
  414.  
  415.         redraw()
  416.     end
  417.  
  418.     term.setCursorBlink(false)
  419.     self.text = line
  420. end
  421.  
  422. function gui_textbox:setText(t)
  423.     self.text = t
  424.  
  425.     for i = 1, t:len() do
  426.         self.chars[i] = t:sub(i, i)
  427.     end
  428. end
  429.  
  430. function gui_textbox:onMouseEvent(ev)
  431.     local _x, _y = self:pxPosGlobal()
  432.     local w, h = self:pxSize()
  433.  
  434.     if ev.x >= _x and ev.x < _x + w and ev.y >= _y and ev.y < _y + h then
  435.         self.__onClick(ev.x, ev.y)
  436.         self.onClick(ev.x, ev.y)
  437.     end
  438. end
  439.  
  440. local x = gui_server.new(0, 0, 100, 100)
  441.  
  442. local button = gui_button.new()
  443. button:init("Exit", 25, 45, 50, 15)
  444. button.textColor = colors.black
  445. button.onClick = function()
  446.     term.setCursorPos(0, 0)
  447.     term.setBackgroundColor(colors.black)
  448.     term.setTextColor(colors.white)
  449.     term.clear()
  450.     print(os.version())
  451.     error()
  452. end
  453.  
  454. local tb = gui_textbox.new()
  455. tb:init("Textbox", 25, 15, 50)
  456.  
  457. x:addChild(button)
  458. x:addChild(tb)
  459. x:redraw()
  460.  
  461. while true do
  462.     local ev, p1, p2, p3, p4 = os.pullEvent()
  463.  
  464.     local gui_ev = gui_event.new()
  465.  
  466.     if ev == "mouse_click" then
  467.         gui_ev.button = p1
  468.         if p1 == 3 then
  469.             gui_ev.button = BUTTON_W
  470.         end
  471.         gui_ev.x = p2
  472.         gui_ev.y = p3
  473.         x:onMouseEvent(gui_ev)
  474.     elseif ev == "mouse_scroll" then
  475.         gui_ev.button = p1 == 1 and BUTTON_W_DOWN or BUTTON_W_UP
  476.         gui_ev.x = p2
  477.         gui_ev.y = p3
  478.         x:onMouseEvent(gui_ev)
  479.     elseif ev == "key" then
  480.         gui_ev.key = p1
  481.         x:onKeyEvent(gui_ev)
  482.     end
  483.    
  484.     x:redraw()
  485. end
Advertisement
Add Comment
Please, Sign In to add comment