Advertisement
Redxone

[CC] - MultiWindow Demo

Jul 21st, 2017
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.51 KB | None | 0 0
  1. term.clear()
  2. local w, h = term.getSize()
  3. selOff = 0
  4. clearColor = colors.black
  5. _SelectedWindow = 0
  6. _Windows = {}
  7. _Windows.structOrder = {}
  8. running = true
  9. _readIndex = 0
  10. _windowsBoundsSX = 1
  11. _windowsBoundsSY = 1
  12. _windowsBoundsMX = w
  13. _windowsBoundsMY = h-1
  14. runningWindow = false
  15.  
  16. function addWindow(wname,x,y,w,h,ev,parent,shadow)
  17.      parent = parent or term.current()
  18.      shadow = shadow or false
  19.      ev = ev or (function(self,e) end)
  20.     _Windows[#_Windows+1] = {name=wname,win=window.create(parent,x,y,w,h), winX = x, winY = y, winW = w, winH = h, winShadow = shadow,winNumber=#_Windows+1, update=ev}
  21.     _Windows.structOrder[#_Windows.structOrder+1] = #_Windows
  22.     os.queueEvent("window_created",#_Windows)
  23. end
  24.  
  25. function getWindow(ind)
  26.     return _Windows[ind].win
  27. end
  28.  
  29.  
  30. -- By name functions, DO NOT use in realtime execution, super slow.
  31. function getWindowByName(winname)
  32.     -- Search for window
  33.     for i = 1, #_Windows do
  34.         if(_Windows[i].name == winname)then
  35.             return _Windows[i].win
  36.         end
  37.     end
  38. end
  39.  
  40. function getWindowNameID(winname)
  41.     -- Search for window
  42.     for i = 1, #_Windows do
  43.         if(_Windows[i].name == winname)then
  44.             return i
  45.         end
  46.     end
  47. end
  48.  
  49. function getFrontWindow()
  50.     return _Windows[_Windows.structOrder[#_Windows.structOrder]].win
  51. end
  52.  
  53. function getFrontIndex()
  54.     return tonumber(_Windows.structOrder[#_Windows.structOrder])
  55. end
  56.  
  57. function getWindowByOrder(ind)
  58.     return _Windows[_Windows.structOrder[ind]].win
  59. end
  60.  
  61. function renderWindows(shd)
  62.     for i = 1, #_Windows.structOrder do
  63.         if(shd)then
  64.             --if(_Windows[ind].winShadow)then
  65.             --  _Windows[ind]:winShadow()
  66.             --else
  67.                 local wx, wy, ww, wh = getWindowSize(_Windows.structOrder[i])
  68.                 paintutils.drawFilledBox(wx+1,wy+1,ww+wx,wh+wy,colors.black)
  69.             --end
  70.         end
  71.         _Windows[_Windows.structOrder[i]].win.redraw()
  72.     end
  73. end
  74.  
  75. function wrapWindow(win,draws)
  76.     local otrm = term.current()
  77.     term.redirect(_Windows[win].win)
  78.     draws()
  79.     term.redirect(otrm)
  80. end
  81.  
  82. function moveToFront(ind)
  83.     local parse = 0
  84.     for i = 1, #_Windows.structOrder do
  85.         if(_Windows.structOrder[i] == ind)then
  86.             parse = i
  87.         end
  88.     end
  89.     if(parse == 0)then return false end
  90.     table.remove(_Windows.structOrder, parse)
  91.     _Windows.structOrder[#_Windows.structOrder+1] = ind
  92. end
  93.  
  94. function undrawWindow(ind, col)
  95.     local wx, wy, ww, wh = getWindowSize(ind)
  96.     paintutils.drawFilledBox(wx,wy,ww+wx,wh+wy,col)
  97. end
  98.  
  99. function moveWindow(ind,x,y,rd)
  100.     rd = rd or true
  101.     if( x >= _windowsBoundsSX and y >= _windowsBoundsSY
  102.     and x+_Windows[ind].winW <= _windowsBoundsMX and y+_Windows[ind].winH <= _windowsBoundsMY)then
  103.         if(rd)then
  104.             undrawWindow(ind,clearColor)
  105.         end
  106.         _Windows[ind].win.reposition(x,y,_Windows[ind].winW,_Windows[ind].winH)
  107.         _Windows[ind].winX = x
  108.         _Windows[ind].winY = y
  109.     --else
  110.     --  winSel = false
  111.     end
  112. end
  113.  
  114. function setBackColor(col)
  115.     clearColor = col
  116.     term.setBackgroundColor(col)
  117.     term.clear()
  118. end
  119.  
  120. function isWindowOpen(ind)
  121.     for i = 1, #_Windows.structOrder do
  122.         if(_Windows.structOrder[i] == ind)then
  123.             return true
  124.         end
  125.     end
  126.     return false
  127. end
  128.  
  129. function setWindowsBounds(sx,sy,mx,my)
  130.     _windowsBoundsSX = sx
  131.     _windowsBoundsSY = sx
  132.     _windowsBoundsMX = mx
  133.     _windowsBoundsMY = mx
  134. end
  135.  
  136. function checkPointRect(x,y,bx,by,bw,bh)
  137.     return (x >= bx and y >= by and x <= bx+bw and y <= by+bh)
  138. end
  139.  
  140. function getWindowedInput(x,y,e,buffer,mask,size)
  141.     term.setCursorBlink(false)
  142.     local w, h   = term.getSize()
  143.     local ev, key = e[1], e[2]
  144.     size = size or w-x
  145.     mask = mask or ""
  146.     buffer = buffer or ""
  147.  
  148.     if(ev == "char")then
  149.         if(_readIndex == #buffer+1)then
  150.             buffer = buffer .. key
  151.         else
  152.             buffer = buffer:sub(1,_readIndex) .. key .. buffer:sub(_readIndex+1)
  153.         end
  154.         _readIndex = _readIndex + 1
  155.     elseif(ev == "key")then
  156.         if(key == keys.left)then
  157.             if(_readIndex >= 1)then _readIndex = _readIndex - 1 end
  158.         elseif(key == keys.right)then
  159.             if(_readIndex < #buffer)then _readIndex = _readIndex + 1 end
  160.         elseif(key == keys.enter)then
  161.             _readIndex = 0
  162.             term.setCursorBlink(false)
  163.             return buffer, true
  164.         elseif(key == keys.home)then  
  165.             _readIndex = 0
  166.         elseif(key == keys['end'])then  
  167.             _readIndex = #buffer
  168.         elseif(key == keys.delete)then
  169.                 buffer = buffer:sub(1,_readIndex) .. buffer:sub(_readIndex+2,-1)
  170.         elseif(key == keys.backspace and #buffer > 0)then
  171.             if(_readIndex >= 1)then
  172.                 if(_readIndex == #buffer+1)then
  173.                     buffer = buffer:sub(1,-2)
  174.                 else
  175.                     buffer = buffer:sub(1,_readIndex-1) .. buffer:sub(_readIndex+1,-1)
  176.                 end
  177.                 _readIndex = _readIndex - 1
  178.             end
  179.         end
  180.     end
  181.     -- Render the stuff.
  182.     local drawStr = buffer:sub(1,size+1)
  183.     local cursorInd = _readIndex
  184.     if(_readIndex > size)then
  185.         cursorInd = _readIndex - (_readIndex-size)+1
  186.         drawStr = buffer:sub((_readIndex-size),_readIndex)
  187.     end
  188.     if(mask ~= "")then
  189.         local rnch = math.random(1,#mask)
  190.         drawStr = string.rep(mask:sub(rnch,rnch),#drawStr)
  191.     end
  192.     term.setCursorPos(x, y)
  193.     write(string.rep(" ",size+1))
  194.     term.setCursorPos(x, y)
  195.     write(drawStr)
  196.     term.setCursorPos(x+cursorInd, y)
  197.     term.setCursorBlink(true)
  198.     return buffer, false
  199. end
  200.  
  201.  
  202. function closeWindow(ind)
  203.     -- Take window out of structure.
  204.     local parse = 0
  205.     for i = 1, #_Windows.structOrder do
  206.         if(_Windows.structOrder[i] == ind)then
  207.             parse = i
  208.         end
  209.     end
  210.     if(parse == 0)then return false end
  211.     table.remove(_Windows.structOrder, parse)
  212.     undrawWindow(ind,clearColor)
  213.     winSel = false
  214.     os.queueEvent("window_minimized",ind)
  215. end
  216.  
  217. function checkBehind(ind)
  218.     local winInd = 0
  219.     local wx, wy, ww, wh = getWindowSize(ind)
  220.     for i = 1, #_Windows.structOrder do
  221.         if(_Windows.structOrder[i] == ind)then
  222.             winInd = i
  223.         elseif(winInd ~= 0)then
  224.             local sx, sy, sw, sh = getWindowSize(i)
  225.             if( wx+ww < sx+sw and sx > wx and
  226.                 sy > wy and wy+wh < sy+sh )then
  227.                 return _Windows.structOrder[i]
  228.             end
  229.         end
  230.     end
  231.     return ind
  232. end
  233.  
  234. function getWindowObject(ind)
  235.     return _Windows[ind]
  236. end
  237.  
  238. function openWindow(ind)
  239.     -- Place window of ID, into structure.
  240.     for i = 1, #_Windows.structOrder do
  241.         if(_Windows.structOrder[i] == ind)then
  242.             return false
  243.         end
  244.     end
  245.     _Windows.structOrder[#_Windows.structOrder+1] = ind
  246.     renderWindows(1)
  247.     os.queueEvent("window_maximized",ind)
  248. end
  249.  
  250. function deleteWindow(ind)
  251.     -- Take window out of structure.
  252.     local parse = 0
  253.     for i = 1, #_Windows.structOrder do
  254.         if(_Windows.structOrder[i] == ind)then
  255.             parse = i
  256.         end
  257.     end
  258.     if(parse == 0)then return false end
  259.     table.remove(_Windows.structOrder, parse)
  260.     undrawWindow(ind,clearColor)
  261.     winSel = false
  262.     table.remove(_Windows,ind)
  263.     os.queueEvent("window_closed",ind)
  264. end
  265.  
  266. function _CallWindowEvent(ind,e)
  267.     local parse = 0
  268.     for i = 1, #_Windows.structOrder do
  269.         if(_Windows.structOrder[i] == ind)then
  270.             parse = i
  271.         end
  272.     end
  273.     if(parse ~= 0)then
  274.         _Windows[ind]:update(e)
  275.     end
  276. end
  277.  
  278. function updateWindows(e, rd)
  279.     rd = rd or true
  280.     if(#_Windows.structOrder > 0)then
  281.         -- Window draging/selecting.
  282.         if(e[1] == "mouse_drag" and winSel)then
  283.                 term.current().setVisible(false)
  284.                 moveWindow(getFrontIndex(),e[3]-selOff,e[4],rd)
  285.                 renderWindows(1)
  286.                 term.current().setVisible(true)
  287.         end
  288.         if(e[1] == "mouse_click" or e[1] == "mouse_drag")then
  289.             winSel = false
  290.             for i = #_Windows.structOrder, 1, -1 do
  291.                 local win = _Windows.structOrder[i]
  292.                 if(e[3] >= _Windows[win].winX and  e[3] <= _Windows[win].winX+_Windows[win].winW and
  293.                        e[4] >= _Windows[win].winY and  e[4] <= _Windows[win].winY+_Windows[win].winH and
  294.                        not (e[3] >= _Windows[getFrontIndex()].winX and  e[3] <= _Windows[getFrontIndex()].winX+_Windows[getFrontIndex()].winW and
  295.                             e[4] >= _Windows[getFrontIndex()].winY and  e[4] <= _Windows[getFrontIndex()].winY+_Windows[getFrontIndex()].winH and isWindowOpen(getFrontIndex())) )then
  296.                     moveToFront(win)
  297.                     term.current().setVisible(false)
  298.                     renderWindows(1)
  299.                     term.current().setVisible(true)
  300.                     winSel = false
  301.                 elseif(e[3] >= _Windows[win].winX and e[3] <= _Windows[win].winX+_Windows[win].winW and e[4] == _Windows[win].winY)then
  302.                     if(not (e[3] >= _Windows[getFrontIndex()].winX and  e[3] <= _Windows[getFrontIndex()].winX+_Windows[getFrontIndex()].winW and
  303.                             e[4] >= _Windows[getFrontIndex()].winY and  e[4] <= _Windows[getFrontIndex()].winY+_Windows[getFrontIndex()].winH and isWindowOpen(getFrontIndex()))
  304.                             or win == getFrontIndex())then
  305.                         winSel = true
  306.                         selOff = (e[3] - _Windows[win].winX)
  307.                         moveToFront(win)
  308.                         term.current().setVisible(false)
  309.                         renderWindows(1)
  310.                         term.current().setVisible(true)
  311.                     end
  312.                 end
  313.             end
  314.         end
  315.         if(e[1] == "mouse_up" and winSel)then
  316.             winSel = false
  317.         end
  318.         _CallWindowEvent(getFrontIndex(),e)
  319.     end
  320. end
  321.  
  322. function getWindowSize(ind)
  323.     return _Windows[ind].winX, _Windows[ind].winY, _Windows[ind].winW, _Windows[ind].winH
  324. end
  325.  
  326. function getWindowProperty(ind,prop)
  327.     return _Windows[ind][prop]
  328. end
  329.  
  330.  
  331. function runWindowsDemo(ind)
  332.     if(ind == 1)then
  333.         setBackColor(colors.lightBlue)
  334.         addWindow("One",5,5,10,10,function(self, e)
  335.             if(e[1] == "mouse_click")then
  336.                 if(e[3] == self.winX+self.winW-1 and e[4] == self.winY)then
  337.                     closeWindow(self.winNumber)
  338.                     renderWindows(1)
  339.                 end
  340.             end
  341.         end)
  342.         addWindow("Two",20,5,20,10,function(self, e)
  343.             local old = term.current()
  344.             term.redirect(self.win)
  345.                 term.setBackgroundColor(colors.blue)
  346.                 term.setCursorPos(3,3)
  347.                 write("Test:           ")
  348.                 term.setCursorPos(8,3)
  349.                 self.winPut, self.isDone = getWindowedInput(8,3,e,self.winPut,"",10)
  350.                 if(self.isDone)then
  351.                     self.winPut = ""
  352.                     self.isDone = false
  353.                 end
  354.             term.redirect(old)
  355.             if(e[1] == "mouse_click")then
  356.                 if(e[3] == self.winX+self.winW-1 and e[4] == self.winY)then
  357.                     closeWindow(self.winNumber)
  358.                     renderWindows(1)
  359.                 end
  360.             elseif(e[1] == "key" and e[2] == keys.y)then
  361.                 if(not isWindowOpen(1))then openWindow(1) end
  362.             end
  363.         end)
  364.         getWindowObject(2).winPut = ""
  365.         getWindowObject(2).isDone = false
  366.         addWindow("Static",10,4,20,12)
  367.         getWindowByName("Static").setBackgroundColor(colors.lightGray)
  368.         getWindowByName("Static").clear()
  369.         wrapWindow(getWindowNameID("Static"), function()
  370.             paintutils.drawLine(1,1,20,1,colors.blue)
  371.             term.setCursorPos(1,1)
  372.             write("Can't close me!")
  373.             --term.setCursorPos(20,1)
  374.             --term.blit("X","0","7")
  375.         end)
  376.         getWindowByName("One").setBackgroundColor(colors.lightGray)
  377.         getWindowByName("One").clear()
  378.         wrapWindow(getWindowNameID("One"), function()
  379.             paintutils.drawLine(1,1,10,1,colors.blue)
  380.             term.setCursorPos(1,1)
  381.             write("Window 1!")
  382.             term.setCursorPos(10,1)
  383.             term.blit(":","0","7")
  384.  
  385.         end)
  386.         getWindowByName("Two").setBackgroundColor(colors.lightGray)
  387.         getWindowByName("Two").clear()
  388.         wrapWindow(getWindowNameID("Two"),function()
  389.             paintutils.drawLine(1,1,20,1,colors.blue)
  390.             term.setCursorPos(1,1)
  391.             write("Window Two!")
  392.             term.setCursorPos(20,1)
  393.             term.blit(":","0","7")
  394.             term.setBackgroundColor(colors.lightGray)
  395.             term.setCursorPos(2,5)
  396.             write("Press Y to open \n window 1.")
  397.         end)   
  398.         renderWindows(1)
  399.         _winTray = {}
  400.         function update()
  401.             while running do
  402.                 local e = {os.pullEvent()}
  403.                 -- Simple optimization "hack" to speed up draging windows around.
  404.                 if(e[1] ~= "mouse_drag")then
  405.                     term.setCursorPos(1, h)
  406.                     term.setBackgroundColor(colors.blue)
  407.                     term.clearLine()
  408.                     term.setCursorPos(1, h)
  409.                     if(e[1] == "window_minimized")then
  410.                         _winTray[#_winTray+1] = {winNumber = e[2],name=getWindowProperty(e[2],"name")}
  411.                     elseif(e[1] == "window_maximized")then
  412.                         for i = 1, #_winTray do
  413.                             if(e[2] == _winTray[i].winNumber)then
  414.                                 table.remove(_winTray, i)
  415.                             end
  416.                         end
  417.                     end
  418.                     for i = 1, #_winTray do
  419.                         term.setBackgroundColor(colors.gray)
  420.                         write(_winTray[i].name:sub(1,4))
  421.                         term.setBackgroundColor(colors.blue)
  422.                         write(" ")
  423.                         if(e[1] == "mouse_click" and e[3] >= (i-1)*4 and e[3] <= ((i-1)*4)+3 and e[4] == h)then
  424.                             openWindow(_winTray[i].winNumber)
  425.                             table.remove(_winTray, i)
  426.                             break
  427.                         end
  428.                     end
  429.                 end
  430.                 updateWindows(e)
  431.             end
  432.         end
  433.         update()
  434.     elseif(ind == 2)then
  435.         local usr, pss = "Admin", "password"
  436.         local running = true
  437.         term.setBackgroundColor(colors.cyan)
  438.         term.clear()
  439.         setBackColor(colors.cyan)
  440.         addWindow("Password",10,8,20,8,
  441.         function(self, e)
  442.           term.setTextColor(colors.white)
  443.           term.setBackgroundColor(colors.blue)
  444.           local isDone = false
  445.           if(self.cinput == 1)then
  446.               self.winusr, isDone = getWindowedInput(
  447.               self.winX+7,self.winY+2,e,self.winusr,"",8)
  448.               if(isDone)then
  449.                 self.cinput = 2
  450.               end
  451.           else
  452.               self.winpss, isDone = getWindowedInput(
  453.               self.winX+7, self.winY+4,e,self.winpss,"*",8)
  454.               if(isDone)then
  455.                  if(self.winusr == usr and self.winpss == pss)then
  456.                      running = false
  457.                      term.setBackgroundColor(colors.black)
  458.                      term.setTextColor(colors.white)
  459.                      term.clear()
  460.                      term.setCursorPos(1,1)
  461.                  else
  462.                     self.winusr = ""
  463.                     self.winpss = ""
  464.                     self.cinput = 1  
  465.                     self.win.redraw()    
  466.                  end
  467.               end
  468.           end
  469.           if(e[1] == "mouse_click" and e[3] == self.winX+self.winW-1 and e[4] == self.winY)then
  470.              term.setCursorBlink(false)
  471.              closeWindow(1)
  472.           end
  473.         end)
  474.         getWindowObject(1).winusr = ""
  475.         getWindowObject(1).winpss = ""
  476.         getWindowObject(1).cinput = 1
  477.         wrapWindow(1,function()
  478.           local w, h = term.getSize()
  479.           term.setBackgroundColor(colors.white)
  480.           term.clear()
  481.           term.setCursorPos(1,1)
  482.           term.setBackgroundColor(colors.gray)
  483.           term.clearLine()
  484.           term.setTextColor(colors.white)
  485.           write("Enter Password")
  486.           term.setCursorPos(w,1)
  487.           term.setBackgroundColor(colors.red)
  488.           write("X")
  489.           term.setBackgroundColor(colors.white)
  490.           term.setCursorPos(2,3)
  491.           term.setTextColor(colors.black)
  492.           write("User: ")
  493.           term.setBackgroundColor(colors.blue)
  494.           write(string.rep(" ",9))
  495.           term.setBackgroundColor(colors.white)
  496.           write("\n\n Pass: ")
  497.           term.setBackgroundColor(colors.blue)
  498.           write(string.rep(" ",9))
  499.         end)
  500.         closeWindow(1)
  501.         while running do
  502.           local e = {os.pullEvent()}
  503.           updateWindows(e)
  504.           if(e[1] == "key" and e[2] == keys.g and not isWindowOpen(1) )then
  505.             openWindow(1)
  506.             sleep(0.1)
  507.           end
  508.         end
  509.     end
  510. end
  511.  
  512. local targs = { ... }
  513. if(#targs < 1)then error("Usage: " .. shell.resolveProgram(shell.getRunningProgram()) .. " <demo number (1/2)>") end
  514. runWindowsDemo(tonumber(targs[1]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement