KaoSDlanor

layer API

Feb 13th, 2013
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.36 KB | None | 0 0
  1. local function max(tPar) --find the highest numeric index
  2.     local count=0
  3.     for k,v in pairs(tPar) do
  4.         if (tonumber(k) or 0)>(tonumber(count) or 0) then count=k end
  5.     end
  6.     return count
  7. end
  8.  
  9. local function min(tPar) --find the lowest numeric index
  10.     local count=1/0
  11.     for k,v in pairs(tPar) do
  12.         count=math.min(tonumber(k) or count,count)
  13.     end
  14.     return count
  15. end
  16.  
  17. local bWritten=true
  18. local tsym={w=1,o=2,m=4,B=8,y=16,l=32,P=64,g=128,G=256,c=512,p=1024,b=2048,z=4096,q=8192,r=16384,a=32768}
  19. layers={render=function()
  20.     term.native.setBackgroundColor(layers[min(layers)].getBackgroundColor())
  21.     term.native.clear()
  22.     local pos={term.native.getCursorPos()}
  23.     for k,v in pairs(layers) do
  24.         if type(v)=="table" then
  25.             v.render()
  26.         end
  27.     end
  28.     term.native.setCursorPos(unpack(pos))
  29. end,scroll=function(nLines)
  30.     for k,v in pairs(layers) do
  31.         if type(v)=="table" and v.linked then
  32.             v.scroll(nLines,true)
  33.         end
  34.     end
  35. end}
  36. term.newLayer=function(index,tParams)
  37.     local redirected=false
  38.     tParams=tParams or {}
  39.     local layer=setmetatable({},{__index=term.native,__type="layer"})
  40.     table.insert(layers,index or #layers+1,layer)
  41.     layer.linked=tParams.linked or false
  42.     layer.showscroll=tParams.showscroll or false
  43.     layer.scrolling=tParams.scrolling or true
  44.     layer.scrolled=layer.linked and term.scrolled or 1
  45.     local record=setmetatable({text={},tcol={},tback={}},{__call=function(self)
  46.         for k,v in pairs(self) do
  47.             local rem={}
  48.             for row,tLine in pairs(v) do
  49.                 local cont=false
  50.                 for a,b in pairs(tLine) do
  51.                     cont=true
  52.                 end
  53.                 if not cont then
  54.                     table.insert(rem,row)
  55.                 end
  56.             end
  57.             for a,b in pairs(rem) do
  58.                 v[a]=nil
  59.             end
  60.         end
  61.     end})
  62.     for k,v in pairs(record) do setmetatable(v,{__index=function(self,index) if (tonumber(index) or 1)<=1 then return nil end self[index]={} return self[index] end,__newindex=function(self,index,value) if (tonumber(index) or 1)<=1 then return nil end rawset(self,index,value) end}) end
  63.     layer.record=record
  64.    
  65.     layer.native={}
  66.     layer.native.getSize=term.native.getSize
  67.        
  68.     layer.getSize=function()
  69.         local size={term.native.getSize()}
  70.         return size[1]-(layer.showscroll and 1 or 0),size[2]
  71.     end
  72.    
  73.     local lX,lY=1,1
  74.     layer.setCursorPos=function(x,y)
  75.         if type(x)=="number" and type(y)=="number" then
  76.             lX=math.floor(x)
  77.             lY=math.floor(y)
  78.            
  79.             if redirected then
  80.                 if lX>0 and lY>0 then
  81.                     layer.setCursorBlink(nil,false)
  82.                 else
  83.                     layer.setCursorBlink(nil,true)
  84.                 end
  85.                 term.native.setCursorPos(lX,lY)
  86.             end
  87.            
  88.             return true
  89.         end
  90.         return false
  91.     end
  92.    
  93.     layer.getCursorPos=function()
  94.         return lX,lY
  95.     end
  96.     local gcp=layer.getCursorPos
  97.    
  98.     local tCol=colors.white
  99.     local tCols={}
  100.     for k,v in pairs(colors) do if type(v)=="number" then tCols[v]=k end end
  101.    
  102.    
  103.     colors.isColor=function(num)
  104.         return tCols[num]~=nil
  105.     end
  106.    
  107.     layer.setTextColor=function(col)
  108.         if colors.isColor(col) then
  109.             tCol=col
  110.             return true
  111.         end
  112.         return false
  113.     end
  114.     layer.setTextColour=layer.setTextColor
  115.    
  116.     local tBack=colors.black
  117.     layer.setBackgroundColor=function(col)
  118.         if colors.isColor(col) then
  119.             tBack=col
  120.             return true
  121.         end
  122.         return false
  123.     end
  124.     layer.setBackgroundColour=layer.setBackgroundColor
  125.    
  126.     layer.getTextColor=function()
  127.         return tCol
  128.     end
  129.     layer.getTextColour=layer.getTextColor
  130.    
  131.     layer.getBackgroundColor=function()
  132.         return tBack
  133.     end
  134.     layer.getBackgroundColour=layer.getBackgroundColor
  135.    
  136.     layer.clear=function()
  137.         for _,tRec in pairs(record) do
  138.             local t={}
  139.             for index,_ in pairs(tRec) do
  140.                 t[index]=true
  141.             end
  142.             for k,v in pairs(t) do
  143.                 tRec[k]=nil
  144.             end
  145.         end
  146.         if not layer.linked then
  147.             layer.scrolled=1
  148.         end
  149.         layer.render()
  150.     end
  151.    
  152.     layer.clearLine=function()
  153.         for _,tRec in pairs(record) do
  154.             tRec[lY+layer.scrolled]=nil
  155.         end
  156.     end
  157.    
  158.    
  159.    
  160.     layer.write=function(sText,bScroll,bIndent)
  161.         if lY<1 then return 0 end
  162.         local size={layer.getSize()}
  163.         local pos={gcp()}
  164.         local fPos={layer.getCursorPos()}
  165.         local nLinesPrinted=0
  166.         sText=tostring(sText)
  167.         local tS="w"
  168.         local bS="a"
  169.         for k,v in pairs(tsym) do
  170.             if v==layer.getTextColor() then tS=k end
  171.             if v==layer.getBackgroundColor() then bS=k end
  172.         end
  173.         local function isrt(t,tex,len)
  174.             for x=lX,lX+len-1 do
  175.                 t[lY+layer.scrolled][x]=tex:sub(x-lX+1,x-lX+1)
  176.             end
  177.         end
  178.         while #sText~=0 do
  179.             local cPos={layer.getCursorPos()}
  180.            
  181.             if cPos[1]>size[1] then --goto next line if current cursor is past the end if the screen and refresh current pos
  182.                 layer.setCursorPos(bIndent and cPos[1] or 1,cPos[2]+1)
  183.                 cPos={layer.getCursorPos()}
  184.             end
  185.            
  186.             if cPos[2]>size[2] then --if cursor is past the end of the screen then scroll down until that line is the bottom and set cursorpos to be the last line
  187.                 layer.scroll(cPos[2]-size[2])
  188.                 cPos={cPos[1],size[2]}
  189.                 layer.setCursorPos(cPos[1],size[2])
  190.             elseif cPos[2]<1 then
  191.                 local offset=math.min(1-cPos[2],layer.scrolled-1)
  192.                 layer.scroll(-offset)
  193.                 layer.setCursorPos(cPos[1],cPos[2]+offset)
  194.                 cPos={cPos[1],cPos[2]+offset}
  195.             end
  196.            
  197.             local len=math.min(bScroll and size[1]-cPos[1]+1 or #sText,sText:find("\n") or #sText) --get the length of the string to be printed, the length to the end of the line, the length to the next \n or the length of the entire string
  198.             local str=sText:sub(1,len):gsub("\n","") --the actual string to be printed
  199.             isrt(record.text,str,len)
  200.             isrt(record.tcol,string.rep(tS,#str),len)
  201.             isrt(record.tback,string.rep(bS,#str),len)
  202.             sText=sText:sub(len+1)
  203.             nLinesPrinted=nLinesPrinted+1
  204.             if #sText~=0 then
  205.                 layer.setCursorPos(bIndent and fPos[1] or 1,cPos[2]+1)
  206.             else
  207.                 layer.setCursorPos(((nLinesPrinted==1 or bIndent) and cPos[1] or 1)+len,cPos[2])
  208.             end
  209.         end
  210.         bWritten=true
  211.         --layers.render()
  212.         return nLinesPrinted
  213.     end
  214.    
  215.     layer.render=function(offsetX,offsetY,limX,limY)
  216.         local pos={term.native.getCursorPos()}
  217.         local col=term.getTextColor()
  218.         local back=term.getBackgroundColor()
  219.         for y,tLine in pairs(record.text) do
  220.             local newy=y+(offsetY or 1)-1
  221.             if newy<=(limY or y) then
  222.                 for x=1,math.min(max(tLine),({term.native.getSize()})[1]) do
  223.                     local newx=x+(offsetX or 1)-1
  224.                     if newx<=(limX or x) then
  225.                         if tsym[record.tback[y][x]] and newy-layer.scrolled>0 then
  226.                             term.native.setCursorPos(newx,newy-layer.scrolled)
  227.                             term.native.setTextColor(tsym[record.tcol[y][x]])
  228.                             term.native.setBackgroundColor(tsym[record.tback[y][x]])
  229.                             term.native.write(record.text[y][x])
  230.                         end
  231.                     end
  232.                 end
  233.             end
  234.         end
  235.         if layer.showscroll then
  236.             local size={layer.native.getSize()}
  237.             local barSpace=size[2]-3
  238.             local sizeY=math.max((max(layer.record.text)-1),layer.scrolled+size[2]-1)
  239.             local nBarSize=math.floor(barSpace*size[2]/sizeY)
  240.             local nBarPos=math.min(math.ceil((barSpace)*(layer.scrolled-1)/sizeY),barSpace)+2
  241.             for y=1,size[2] do
  242.                 term.native.setCursorPos(size[1],y)
  243.                 term.native.setBackgroundColor(y>=nBarPos and y<=nBarPos+nBarSize and colors.white or colors.black)
  244.                 term.native.write(" ")
  245.             end
  246.             term.native.setTextColor(colors.white)
  247.             term.native.setBackgroundColor(colors.black)
  248.             term.native.setCursorPos(size[1],1)
  249.             term.native.write("^")
  250.             term.native.setCursorPos(size[1],size[2])
  251.             term.native.write("v")
  252.         end
  253.         term.native.setCursorPos(unpack(pos))
  254.         term.native.setTextColor(col)
  255.         term.native.setBackgroundColor(back)
  256.     end
  257.  
  258.     layer.scroll=function(nLines,bFromTop)
  259.         if layer.scrolling then
  260.             if layer.linked and not bFromTop then
  261.                 layers.scroll(nLines)
  262.             else
  263.                 layer.scrolled=layer.scrolled+(tonumber(nLines) or 1)
  264.                 if layer.scrolled<1 then
  265.                     layer.scrolled=1
  266.                 end
  267.             end
  268.             bWritten=true
  269.         end
  270.     end
  271.  
  272.     layer.delete=function()
  273.         for k,v in pairs(layers) do
  274.             if layer==v then
  275.                 table.remove(layers,k)
  276.                 break
  277.             end
  278.         end
  279.         local tIndexes={}
  280.         for k,v in pairs(layer) do
  281.             tIndexes[k]=true
  282.         end
  283.         for k,v in pairs(tIndexes) do
  284.             layer[k]=nil
  285.         end
  286.     end
  287.    
  288.     layer.getTextAt=function(x,y,len)
  289.         if rawget(record.text,y+layer.scrolled) then
  290.             local str=""
  291.             for cx=x,x+(len or 1)-1 do
  292.                 str=str..(record.text[y+layer.scrolled][cx] or " ")
  293.             end
  294.             return str,tsym[record.tcol[y+layer.scrolled][x]],tsym[record.tback[y+layer.scrolled][x]]
  295.         end
  296.         return string.rep(" ",x+(len or 1)-1)
  297.     end
  298.    
  299.     local scb=term.native.setCursorBlink
  300.     local cb=true
  301.     local disableBlink=false
  302.     layer.setCursorBlink=function(bOn,bDisable)
  303.         if bDisable~=nil then
  304.             disableBlink=bDisable
  305.             if not bDisable then
  306.                 scb(cb)
  307.             else
  308.                 scb(false)
  309.             end
  310.         else
  311.             cb=bOn
  312.             if not bOn or not disableBlink then
  313.                 scb(bOn)
  314.             end
  315.         end
  316.     end
  317.    
  318.     layer.getCursorBlink=function(bOn,bDisable)
  319.         return cb
  320.     end
  321.    
  322.     layer.redirect=function()
  323.         redirected=true
  324.     end
  325.    
  326.     layer.restore=function()
  327.         redirected=false
  328.     end
  329.     return layer
  330. end
  331.  
  332. term.newWindow=function(x1,y1,x2,y2,index)
  333.     local window=term.newLayer(index)
  334.     local rd=window.render
  335.     window.render=function()
  336.         return rd(x1,y1,x2,y2)
  337.     end
  338.     local gs=window.getSize
  339.     window.getSize=function()
  340.         return x2-x1,y2-y1
  341.     end
  342.     return window
  343. end
  344.  
  345. customTerm=term.newLayer(1,{linked=true,showscroll=true})
  346.  
  347. local rd=term.redirect
  348. setfenv(rd,setmetatable({type=nativeType},{__index=getfenv(rd)}))
  349. setmetatable(term,{__index=term.native})
  350. local tRedirectStack={}
  351. term.redirect=function(tRedirectTarget)
  352.     if type(tRedirectTarget)=="table" then
  353.         for k,v in pairs(term.native) do
  354.             if not tRedirectTarget[k] then
  355.                 error("cannot redirect. missing function "..k,2)
  356.             end
  357.         end
  358.         getmetatable(term).__index=tRedirectTarget
  359.         if tRedirectTarget.redirect and type(tRedirectTarget.redirect)=="function" then
  360.             tRedirectTarget.redirect()
  361.         end
  362.         rd(tRedirectTarget)
  363.         if #tRedirectStack>=1 and type(tRedirectStack[1].restore)=="function" then
  364.             tRedirectStack[1].restore()
  365.         end
  366.         table.insert(tRedirectStack,1,tRedirectTarget)
  367.     end
  368. end
  369.  
  370. local rstre=term.restore
  371. term.restore=function()
  372.     if #tRedirectStack>1 then
  373.         rstre()
  374.         if tRedirectStack[1].restore then tRedirectStack[1].restore() end
  375.         table.remove(tRedirectStack,1)
  376.         getmetatable(term).__index=tRedirectStack[1]
  377.         if tRedirectStack[1].redirect and type(tRedirectStack[1].redirect)=="function" then
  378.             tRedirectStack[1].redirect()
  379.         end
  380.     end
  381. end
  382.  
  383. local yld=coroutine.yield
  384. coroutine.yield=function(...)
  385.     if bWritten then
  386.         layers.render()
  387.         bWritten=false
  388.     end
  389.     return yld(...)
  390. end
  391.  
  392. term.redirect(customTerm)
Advertisement
Add Comment
Please, Sign In to add comment