Advertisement
1lann

Convorse

Nov 30th, 2014
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.78 KB | None | 0 0
  1. local theme = {
  2.     background = colors.white,
  3.     accent = colors.blue,
  4.     text = colors.black,
  5.     header = colors.white,
  6.     input = colors.white,
  7.     inputText = colors.gray,
  8.     placeholder = colors.lightGray,
  9. }
  10.  
  11. if not term.isColor() then
  12.     theme = {
  13.         background = colors.white,
  14.         accent = colors.black,
  15.         text = colors.black,
  16.         header = colors.white,
  17.         input = colors.white,
  18.         inputText = colors.black,
  19.         placeholder = colors.black,
  20.     }
  21. end
  22.  
  23. local t = {
  24.     bg = term.setBackgroundColor,
  25.     tc = term.setTextColor,
  26.     p = term.setCursorPos,
  27.     gp = term.getCursorPos,
  28.     c = term.clear,
  29.     cl = term.clearLine,
  30.     w = term.write,
  31.     nl = function(num)
  32.         if not num then num = 1 end
  33.         local x, y = term.getCursorPos()
  34.         term.setCursorPos(1, y + num)
  35.     end,
  36.     o = function() term.setCursorPos(1, 1) end,
  37.     db = function(height)
  38.         local x, y = term.getCursorPos()
  39.         for i = 1, height do
  40.             term.setCursorPos(1, y + i - 1)
  41.             term.clearLine()
  42.         end
  43.         term.setCursorPos(x, y)
  44.     end
  45. }
  46.  
  47. local w, h = term.getSize()
  48.  
  49. local function textField(startX, startY, length, startingText, placeholder,
  50.         shouldHideText, eventCallback)
  51.     local horizontalScroll = 1
  52.     local cursorPosition = 1
  53.     local data = startingText
  54.     local eventCallbackResponse = nil
  55.     local method = "enter"
  56.  
  57.     if not data then
  58.         data = ""
  59.     else
  60.         cursorPosition = data:len() + 1
  61.     end
  62.  
  63.     while true do
  64.         term.setCursorBlink(true)
  65.         term.setBackgroundColor(theme.background)
  66.         term.setTextColor(theme.inputText)
  67.  
  68.         term.setCursorPos(startX, startY)
  69.         term.write(string.rep(" ", length))
  70.         term.setCursorPos(startX, startY)
  71.  
  72.         local text = data
  73.         if shouldHideText then
  74.             text = string.rep("*", #data)
  75.         end
  76.         term.write(text:sub(horizontalScroll, horizontalScroll + length - 1))
  77.  
  78.         if #data == 0 and placeholder then
  79.             term.setTextColor(theme.placeholder)
  80.             term.write(placeholder)
  81.         end
  82.  
  83.         term.setCursorPos(startX + cursorPosition - horizontalScroll, startY)
  84.  
  85.         local event = {os.pullEvent()}
  86.         if eventCallback then
  87.             local shouldReturn, response = eventCallback(event)
  88.             if shouldReturn then
  89.                 eventCallbackResponse = response
  90.                 method = "callback"
  91.                 break
  92.             end
  93.         end
  94.  
  95.         local isMouseEvent = event[1] == "mouse_click" or event[1] == "mouse_drag"
  96.  
  97.         if isMouseEvent then
  98.             local inHorizontalBounds = event[3] >= startX and event[3] < startX + length
  99.             local inVerticalBounds = event[4] == startY
  100.             if inHorizontalBounds and inVerticalBounds then
  101.                 local previousX = term.getCursorPos()
  102.                 local position = cursorPosition - (previousX - event[3])
  103.                 cursorPosition = math.min(position, #data + 1)
  104.             end
  105.         elseif event[1] == "char" then
  106.             if term.getCursorPos() >= startX + length - 1 then
  107.                 horizontalScroll = horizontalScroll + 1
  108.             end
  109.  
  110.             cursorPosition = cursorPosition + 1
  111.             local before = data:sub(1, cursorPosition - 1)
  112.             local after = data:sub(cursorPosition, -1)
  113.             data = before .. event[2] .. after
  114.         elseif event[1] == "key" then
  115.             if event[2] == keys.enter then
  116.                 break
  117.             elseif event[2] == keys.left and cursorPosition > 1 then
  118.                 cursorPosition = cursorPosition - 1
  119.                 if cursorPosition <= horizontalScroll and horizontalScroll > 1 then
  120.                     local amount = ((horizontalScroll - cursorPosition) + 1)
  121.                     horizontalScroll = horizontalScroll - amount
  122.                 end
  123.             elseif event[2] == keys.right and cursorPosition <= data:len() then
  124.                 cursorPosition = cursorPosition + 1
  125.                 if 1 >= length - (cursorPosition - horizontalScroll) + 1 then
  126.                     horizontalScroll = horizontalScroll + 1
  127.                 end
  128.             elseif event[2] == keys.backspace and cursorPosition > 1 then
  129.                 data = data:sub(1, cursorPosition - 2) .. data:sub(cursorPosition, -1)
  130.                 cursorPosition = cursorPosition - 1
  131.                 if cursorPosition <= horizontalScroll and horizontalScroll > 1 then
  132.                     local amount = ((horizontalScroll - cursorPosition) + 1)
  133.                     horizontalScroll = horizontalScroll - amount
  134.                 end
  135.             end
  136.         end
  137.     end
  138.  
  139.     term.setCursorBlink(false)
  140.     return method, data, eventCallbackResponse
  141. end
  142.  
  143. local centerField = function(width, placeholder)
  144.     local x, y = t.gp()
  145.     t.p(math.floor(w / 2 - width / 2) + 1, y)
  146.     t.bg(theme.input)
  147.     t.tc(theme.placeholder)
  148.     t.w(placeholder .. string.rep(" ", width - #placeholder))
  149.     t.p(1, y + 1)
  150.     return {math.floor(w / 2 - width / 2) + 1, y}
  151. end
  152.  
  153. local center = function(text)
  154.     local x, y = t.gp()
  155.     t.p(math.floor(w / 2 - text:len() / 2) + 1, y)
  156.     t.w(text)
  157.     t.p(1, y + 1)
  158.     return {math.floor(w / 2 - text:len() / 2) + 1, y}
  159. end
  160.  
  161. local centerButton = function(width, text)
  162.     local x, y = t.gp()
  163.     t.p(math.floor(w / 2 - width / 2) + 1, y)
  164.     t.bg(theme.accent)
  165.     t.tc(theme.header)
  166.     t.w(string.rep(" ", width))
  167.     center(text)
  168.     return {math.floor(w / 2 - width / 2) + 1, y}
  169. end
  170.  
  171. local usernameFieldStart, passwordFieldStart, buttonTopLeft, buttonBottomRight, registerStart
  172.  
  173. local function drawLogin()
  174.     t.bg(theme.background)
  175.     t.c()
  176.  
  177.     t.o()
  178.     t.tc(theme.header)
  179.     t.bg(theme.accent)
  180.     t.db(4)
  181.  
  182.     t.nl()
  183.     center("- Convorse -")
  184.     center("A web chat client")
  185.     t.nl()
  186.  
  187.     t.tc(theme.text)
  188.     t.bg(theme.background)
  189.     t.nl()
  190.     center("Welcome Back")
  191.     t.nl()
  192.     usernameFieldStart = centerField(20, "Username")
  193.     center("--------------------")
  194.     passwordFieldStart = centerField(20, "Password")
  195.     center("--------------------")
  196.     t.nl()
  197.     loginStart = centerButton(20, "Login")
  198.     t.nl()
  199.     t.tc(theme.accent)
  200.     t.bg(theme.background)
  201.     registerStart = center("Need an account?    ")
  202. end
  203.  
  204. local activeField = "username"
  205. local username = ""
  206. local password = ""
  207.  
  208. -- local function textField(posX, posY, length, curData, placeholder, handler)
  209.  
  210. local function loginFocusManager()
  211.     local activeField = "username"
  212.  
  213.     while true do
  214.         local function textHandler(events)
  215.             if events[1] == "mouse_click" then
  216.                 if events[4] == usernameFieldStart[2] and
  217.                 events[3] >= usernameFieldStart[1] and
  218.                 events[3] <= usernameFieldStart[1] + 19 then
  219.                     if activeField ~= "username" then
  220.                         return true, {"username", unpack(events)}
  221.                     end
  222.                 elseif events[4] == passwordFieldStart[2] and
  223.                 events[3] >= passwordFieldStart[1] and
  224.                 events[3] <= passwordFieldStart[1] + 19 then
  225.                     if activeField ~= "password" then
  226.                         return true, {"password", unpack(events)}
  227.                     end
  228.                 elseif events[4] == loginStart[2] and
  229.                 events[3] >= loginStart[1] and events[3] <= buttonBottomRight[1] + 20 then
  230.                     return true, {"login", unpack(events)}
  231.                 elseif events[4] == registerStart[2] and events[3] >= registerStart[1] and events[3] <= registerStart[1] + 16 then
  232.                     return true, {"register", unpack(events)}
  233.                 else
  234.                     return true, {"nothing", unpack(events)}
  235.                 end
  236.             end
  237.         end
  238.  
  239.         if activeField == "nothing" then
  240.             while true do
  241.                 local resp
  242.                 resp, callbackResponse = textHandler({os.pullEvent()})
  243.                 if resp then
  244.                     activeField = callbackResponse[1]
  245.                     break
  246.                 end
  247.             end
  248.         elseif activeField == "username" then
  249.             local resp, data, callback = textField(usernameFieldStart[1], usernameFieldStart[2], 20, username, "Username", false, textHandler)
  250.  
  251.             if resp == "enter" then
  252.                 activeField = "password"
  253.                 username = data
  254.             else
  255.                 activeField = callback[1]
  256.                 username = data
  257.                 os.queueEvent(callback[2], callback[3], callback[4], callback[5])
  258.             end
  259.         elseif activeField == "password" then
  260.             local resp, data, callback = textField(passwordFieldStart[1], passwordFieldStart[2], 20, password, "Password", true, textHandler)
  261.  
  262.             if resp == "enter" then
  263.                 activeField = "nothing"
  264.                 password = data
  265.                 login()
  266.             else
  267.                 activeField = callback[1]
  268.                 password = data
  269.                 os.queueEvent(callback[2], callback[3], callback[4], callback[5])
  270.             end
  271.         elseif activeField == "login" then
  272.             login()
  273.         elseif activeField == "register" then
  274.             register()
  275.         end
  276.     end
  277. end
  278.  
  279. drawLogin()
  280. loginFocusManager()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement