Advertisement
jille_Jr

CC: Display API - Latest release

Nov 19th, 2013
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.58 KB | None | 0 0
  1. -- display API
  2. -- made by akaJag
  3. -- work in progress
  4.  
  5. function round(num)
  6.     if type(num) ~= "number" then return num end
  7.     if num%1<.5 then num=math.floor(num) end
  8.     if num%1>=.5 then num=math.ceil(num) end
  9.     return num
  10. end
  11.  
  12. function setupdaterate(class,s)
  13.     class.updaterate = s
  14. end
  15.  
  16. function getupdaterate(class)
  17.     return class.updaterate
  18. end
  19.  
  20. function removepixles(class)
  21.     local w,h = class.obj.getSize()
  22.    
  23.     -- check row
  24.     local width = next(class.pixles)
  25.     while width do
  26.         if width > w or width < 0 then
  27.             -- remove row
  28.             local tmpw = width
  29.             width = next(class.pixles,width)
  30.             class.pixles[tmpw] = nil
  31.         else
  32.             -- check column
  33.             local height = next(class.pixles[width])
  34.             while height do
  35.                 if height > h or height < 0 then
  36.                     -- remove column
  37.                     local tmph = height
  38.                     height = next(class.pixles[width],height)
  39.                     class.pixles[width][tmph] = nil
  40.                 else
  41.                     -- next iteration
  42.                     height = next(class.pixles[width],height)
  43.                 end
  44.             end
  45.             -- next iteration
  46.             width = next(class.pixles,width)
  47.         end
  48.     end
  49. end
  50.  
  51. function fixpixles(class)
  52.     local w,h = class.obj.getSize()
  53.     for width = 1,w do
  54.         if class.pixles[width] == nil then class.pixles[width] = {} end
  55.         for height = 1,h do
  56.             if class.pixles[width][height] == nil then
  57.                 class.pixles[width][height] = {sym=" ",bg=colors.black,fg=colors.white}
  58.             end
  59.         end
  60.     end
  61. end
  62.  
  63. -- returns:
  64. --  (number) update time
  65. function update(class)
  66.     local startupdate = os.clock()
  67.    
  68.     class:removepixles()
  69.     class:fixpixles()
  70.    
  71.     local endupdate = os.clock()
  72.     return endupdate - startupdate
  73. end
  74.  
  75. function draw(class)
  76.     local startdraw = os.clock()
  77.    
  78.     for w in pairs(class.pixles) do
  79.         for h,pixle in pairs(class.pixles[w]) do
  80.             class.obj.setCursorPos(w,h)
  81.             class.obj.setBackgroundColor(pixle.bg or colors.black)
  82.             class.obj.setTextColor(pixle.fg or colors.white)
  83.             class.obj.write(pixle.sym or " ")
  84.         end
  85.     end
  86.    
  87.     local enddraw = os.clock()
  88.     return enddraw - startdraw
  89. end
  90.  
  91. -- can be used in a parallel loop
  92. -- dont forget to do prepareloop() before running
  93. -- stop it with stoploop()
  94. function loop(class)
  95.     if not running then return end
  96.     local s = class:update()
  97.     s = s + class:draw()
  98.     sleep(updaterate - s)
  99. end
  100.  
  101. function prepareloop(class)
  102.     class.looprunning = true
  103.     class.looptime = os.clock()
  104. end
  105.  
  106. -- returns the time the loop has been on
  107. function stoploop()
  108.     class.looprunning = false
  109.     return os.clock - class.looptime
  110. end
  111.  
  112. function setcolor(class,fg,bg)
  113.     class.fgcolor = fg or class.fgcolor
  114.     class.bgcolor = bg or class.bgcolor
  115. end
  116.  
  117. function getcolor(class)
  118.     return class.fgcolor,class.bgcolor
  119. end
  120.  
  121. function setfgcolor(class,col)
  122.     class.fgcolor = col
  123. end
  124.  
  125. function getfgcolor(class)
  126.     return class.fgcolor
  127. end
  128.  
  129. function setbgcolor(class,col)
  130.     class.bgcolor = col
  131. end
  132.  
  133. function getbgcolor(class)
  134.     return class.bgcolor
  135. end
  136.  
  137. -- stroke is only used with "line" draw mode
  138. function setstroke(class,var)
  139.     class.stroke=var
  140. end
  141.  
  142. function getstroke(class)
  143.     return class.stroke
  144. end
  145.  
  146. -- clears the entire screen
  147. -- bg = only change background, ignore text
  148. function clear(class,bg)
  149.     for w in pairs(class.pixles) do
  150.         for h,pixle in pairs(class.pixles[w]) do
  151.             class.pixles[w][h].bg = class.bgcolor
  152.             if bg ~= true then
  153.                 class.pixles[w][h].sym = " "
  154.             end
  155.         end
  156.     end
  157. end
  158.  
  159. -- trans = transparant option
  160. function write(class,str,x,y,trans)
  161.     x=round(x) y=round(y)
  162.    
  163.     -- utf8 to utf32
  164.     local strtotbl = function(str)
  165.         local tbl = {}
  166.         for uchar in str:gmatch("([%z\1-\127\194-\244][\128-\191]*)") do
  167.             table.insert(tbl,uchar)
  168.         end
  169.         return tbl
  170.     end
  171.    
  172.     local text = strtotbl(str)
  173.    
  174.     for count = 1,#text do
  175.         if class.pixles[x+count-1] then
  176.             if class.pixles[x+count-1][y] then
  177.                 class.pixles[x+count-1][y].sym = text[count]
  178.                 class.pixles[x+count-1][y].fg = class.fgcolor
  179.                 if trans ~= true then
  180.                     class.pixles[x+count-1][y].bg = class.bgcolor
  181.                 end
  182.             end
  183.         end
  184.     end
  185. end
  186.  
  187. function line(class,x1,y1,x2,y2,bg)
  188.     -- Bresenham's algorithm
  189.     local dx = x2 - x1
  190.     if dx < 0 then dx = -dx end
  191.     local dy = y2 - y1
  192.     if dy < 0 then dy = -dy end
  193.    
  194.     local sx,sy
  195.     if x1 < x2 then sx = 1
  196.     else sx = -1 end
  197.     if y1 < y2 then sy = 1
  198.     else sy = -1 end
  199.    
  200.     local err = dx - dy
  201.    
  202.     repeat
  203.         local x,y = round(x1),round(y1)
  204.         if class.pixles[x] then
  205.             if class.pixles[x][y] then
  206.                 class.pixles[x][y].bg = class.bgcolor
  207.                 if bg ~= true then
  208.                     class.pixles[x][y].sym = " "
  209.                 end
  210.             end
  211.         end
  212.        
  213.         if x1 == x2 and y1 == y2 then break end
  214.         local e2 = 2*err
  215.         if e2 > -dy then
  216.             err = err - dy
  217.             x1 = x1 + sx
  218.         end
  219.         if e2 < dx then
  220.             err = err + dx
  221.             y1 = y1 + sy
  222.         end
  223.     until false
  224. end
  225.  
  226. -- supported modes: fill, line
  227. -- bg = only set background color
  228. function rect(class,mode,x1,y1,x2,y2,bg)
  229.     x1=round(x1) y1=round(y1) x2=round(x2) y2=round(y2)
  230.     if mode == "fill" then
  231.         for x = x1,x2 do
  232.             for y = y1,y2 do
  233.                 if class.pixles[x] ~= nil then
  234.                     if class.pixles[x][y] ~= nil then
  235.                         class.pixles[x][y].bg = class.bgcolor
  236.                         if bg ~= true then
  237.                             class.pixles[x][y].sym = " "
  238.                         end
  239.                     end
  240.                 end
  241.             end
  242.         end
  243.     elseif mode == "line" then
  244.         -- top line
  245.         for x = x1,x2 do
  246.             for y = y1,y1+class.stroke-1 do
  247.                 if class.pixles[x] ~= nil then
  248.                     if class.pixles[x][y] ~= nil then
  249.                         class.pixles[x][y].bg = class.bgcolor
  250.                         if bg ~= true then
  251.                             class.pixles[x][y].sym = " "
  252.                         end
  253.                     end
  254.                 end
  255.             end
  256.         end
  257.         -- bottom line
  258.         for x = x1,x2 do
  259.             for y = y2-class.stroke+1,y2 do
  260.                 if class.pixles[x] ~= nil then
  261.                     if class.pixles[x][y] ~= nil then
  262.                         class.pixles[x][y].bg = class.bgcolor
  263.                         if bg ~= true then
  264.                             class.pixles[x][y].sym = " "
  265.                         end
  266.                     end
  267.                 end
  268.             end
  269.         end
  270.         -- right line
  271.         for x = x2-class.stroke+1,x2 do
  272.             for y = y1,y2 do
  273.                 if class.pixles[x] ~= nil then
  274.                     if class.pixles [x][y] ~= nil then
  275.                         class.pixles[x][y].bg = class.bgcolor
  276.                         if bg ~= true then
  277.                             class.pixles[x][y].sym = " "
  278.                         end
  279.                     end
  280.                 end
  281.             end
  282.         end
  283.         -- left line
  284.         for x = x1,x1+class.stroke-1 do
  285.             for y = y1,y2 do
  286.                 if class.pixles[x] ~= nil then
  287.                     if class.pixles [x][y] ~= nil then
  288.                         class.pixles[x][y].bg = class.bgcolor
  289.                         if bg ~= true then
  290.                             class.pixles[x][y].sym = " "
  291.                         end
  292.                     end
  293.                 end
  294.             end
  295.         end
  296.     end
  297. end
  298.  
  299. -- supported modes: fill, line
  300. -- bg = only set background color
  301. function circle(class,mode,x,y,r,bg)
  302.     x=round(x) y=round(y)
  303.     for w in pairs(class.pixles) do
  304.         for h in pairs(class.pixles[w]) do
  305.             -- pythagrias sats
  306.             -- a^2 + b^2 = c^2
  307.             local dis = math.sqrt((w-x)^2 + (h-y)^2)
  308.             if dis <= r then
  309.                 if mode == "fill" or
  310.                 (mode == "line" and dis >= r-class.stroke) then
  311.                     if class.pixles[w] ~= nil then
  312.                         if class.pixles[w][h] ~= nil then
  313.                             class.pixles[w][h].bg = class.bgcolor
  314.                             if bg ~= true then
  315.                                 class.pixles[w][h].sym = " "
  316.                             end
  317.                         end
  318.                     end
  319.                 end
  320.             end
  321.         end
  322.     end
  323. end
  324.  
  325. -- x,y = top left corner of text field
  326. -- w = width of text field
  327. -- l = max lenght of text
  328. -- c = make the text look like a certain character
  329. -- trans = transparent
  330. -- callback = function, gets events as parameters, if returns true then exit
  331. function read(class,x,y,w,l,initstr,c,trans,callback)
  332.     -- set functions
  333.     local strtotbl = function(str)
  334.         local tbl = {}
  335.         for uchar in str:gmatch("([%z\1-\127\194-\244][\128-\191]*)") do
  336.             table.insert(tbl,uchar)
  337.         end
  338.         return tbl
  339.     end
  340.  
  341.     local tbltostr = function(tbl)
  342.         local str = ""
  343.         for _,value in pairs(tbl) do
  344.             str=str..tostring(value)
  345.         end
  346.         return str
  347.     end
  348.    
  349.     local add = function(tbl,index,element)
  350.         for i = table.maxn(tbl),index,-1 do
  351.             tbl[i+1] = tbl[i]
  352.         end
  353.         tbl[index] = element
  354.     end
  355.  
  356.     local remove = function(tbl,index)
  357.         local max = table.maxn(tbl)
  358.         for i = index+1,max do
  359.             tbl[i-1] = tbl[i]
  360.         end
  361.         tbl[max] = nil
  362.     end
  363.    
  364.     -- check/correct arguments
  365.     x=round(x) y=round(y) w=round(w) l=round(l)
  366.     if type(l)~="number" then l=-1 end
  367.     if type(initstr)~="string" then initstr="" end
  368.     local running = true
  369.     local text = strtotbl(initstr)
  370.     local padding = table.maxn(text)-w
  371.     local cursor = table.maxn(text)+1
  372.    
  373.     callback = callback or function(ev,p1,p2,p3,p4,p5)
  374.         if ev == "key" and p1 == keys.enter then
  375.             return true
  376.         end
  377.     end
  378.    
  379.     while running do
  380.         -- fix cursor and padding
  381.         if cursor > table.maxn(text) then cursor = table.maxn(text) end
  382.         if cursor < 0 then cursor = 0 end
  383.         if padding > table.maxn(text)-1 then padding = table.maxn(text)-1 end
  384.         if padding < 0 then padding = 0 end
  385.        
  386.         -- drawing
  387.         if trans ~= true then
  388.             class:rect("fill",x,y,x+w,y,false)
  389.         end
  390.         if type(c) == "string" then
  391.             local str = c:rep(math.floor(table.maxn(text)/#c)) .. c:sub(1,table.maxn(text)%#c)
  392.             class:write(str:sub(padding+1,padding+w+1),x,y,true)
  393.         else
  394.             for pos = padding+1,math.min(table.maxn(text),w+padding+1) do
  395.                 if text[pos] then
  396.                     class:write(text[pos],x+pos-padding-1,y,true)
  397.                 end
  398.             end
  399.         end
  400.        
  401.         class:update()
  402.         class:draw()
  403.        
  404.         if cursor-padding <= w and cursor-padding >= 0 then
  405.             class.obj.setCursorPos(x+cursor-padding,y)
  406.             class.obj.setTextColor(class:getfgcolor())
  407.             class.obj.setCursorBlink(true)
  408.         end
  409.        
  410.         local ev,p1,p2,p3,p4,p5 = os.pullEvent()
  411.        
  412.         class.obj.setCursorBlink(false)
  413.        
  414.         if callback(ev,p1,p2,p3,p4,p5) == true then
  415.             local str = tbltostr(text)
  416.             return str,ev,p1,p2,p3,p4,p5
  417.         end
  418.         if ev == "key" then
  419.             if p1 == keys.left then
  420.                 -- move left
  421.                 cursor = cursor - 1
  422.                 if cursor<padding then padding = padding - 1 end
  423.             elseif p1 == keys.right then
  424.                 -- move right
  425.                 cursor = cursor + 1
  426.                 if cursor-padding > w then padding = padding + 1 end
  427.             elseif p1 == keys.backspace then
  428.                 -- remove a character
  429.                 --local num = cursor-1
  430.                 --if num < 0 then num = 0 end
  431.                 --text = text:sub(1,num) .. text:sub(cursor+1)
  432.                 remove(text,cursor)
  433.                 cursor = cursor - 1
  434.                 if cursor<padding then padding = padding - 1 end
  435.             elseif p1 == keys.delete then
  436.                 -- remove a character
  437.                 if text[cursor+1] then
  438.                     remove(text,cursor+1)
  439.                 end
  440.                 --text = text:sub(1,cursor) .. text:sub(cursor+2)
  441.             elseif p1 == keys.home then
  442.                 -- jump to start
  443.                 cursor = 0
  444.                 padding = 0
  445.             elseif p1 == keys["end"] then
  446.                 -- jump to end
  447.                 cursor = table.maxn(text)
  448.                 padding = table.maxn(text)-w
  449.             end
  450.         elseif ev == "char" then
  451.             if table.maxn(text) < l or l <= 0 then -- check length limit
  452.                 -- add a character
  453.                 --text = text:sub(1,cursor) .. p1 .. text:sub(cursor+1)
  454.                 add(text,cursor+1,p1)
  455.                 cursor = cursor + 1
  456.                 if cursor-padding > w then padding = padding + 1 end
  457.             end
  458.         elseif (ev == "mouse_click" and class.type == "term")
  459.         or (ev == "monitor_touch" and class.type == "monitor" and p1 == class.path) then
  460.             -- move cursor
  461.             -- x=p2, y=p3
  462.             if p2<x then p2=x end
  463.             if p2>x+w then p2=x+w end
  464.             cursor = p2-x+padding
  465.         elseif ev == "mouse_scroll" then
  466.             -- scrolling left/right
  467.             padding = padding + p1
  468.         end
  469.     end
  470. end
  471.  
  472. function load(objpath)
  473.     local startload = os.clock()
  474.    
  475.     tobj = {}
  476.    
  477.     -- object variables
  478.     objpath = objpath or "N/A"
  479.     if peripheral.isPresent(objpath)
  480.     and peripheral.getType(objpath) == "monitor" then
  481.         tobj.obj = peripheral.wrap(objpath or "N/A")
  482.         tobj.type = "monitor"
  483.         tobj.path = objpath
  484.         tobj.eventname = "monitor_touch"
  485.     else
  486.         tobj.type = "term"
  487.         tobj.obj = term
  488.         tobj.path = "N/A"
  489.         tobj.eventname = "mouse_click"
  490.     end
  491.    
  492.     -- variables
  493.     tobj.pixles = {}
  494.     tobj.updaterate = 0.2
  495.     tobj.looprunning = false
  496.     tobj.looptime = 0
  497.     tobj.stroke = 1
  498.     tobj.bgcolor = colors.black
  499.     tobj.fgcolor = colors.white
  500.    
  501.     -- misc functions
  502.     tobj.setupdaterate = setupdaterate
  503.     tobj.getupdaterate = getupdaterate
  504.     tobj.removepixles = removepixles
  505.     tobj.fixpixles = fixpixles
  506.     tobj.update = update
  507.     tobj.draw = draw
  508.     tobj.loop = loop
  509.     tobj.prepareloop = prepareloop
  510.     tobj.stoploop = stoploop
  511.    
  512.     -- color functions
  513.     tobj.setcolor = setcolor
  514.     tobj.setfgcolor = setfgcolor
  515.     tobj.setbgcolor = setbgcolor
  516.     tobj.getcolor = getcolor
  517.     tobj.getfgcolor = getfgcolor
  518.     tobj.getbgcolor = getbgcolor
  519.     tobj.setstroke = setstroke
  520.     tobj.getstroke = getstroke
  521.     -- british
  522.     tobj.setcolour = setcolor
  523.     tobj.setfgcolour = setfgcolor
  524.     tobj.setbgcolour = setbgcolor
  525.     tobj.getcolour = getcolor
  526.     tobj.getfgcolour = getfgcolor
  527.     tobj.getbgcolour = getbgcolor
  528.    
  529.     -- drawing functions
  530.     tobj.clear = clear
  531.     tobj.write = write
  532.     tobj.line = line
  533.     tobj.rect = rect
  534.     tobj.circle = circle
  535.     tobj.read = read
  536.    
  537.     tobj:removepixles()
  538.     tobj:fixpixles()
  539.    
  540.     local endload = os.clock()
  541.     return tobj,endload-startload
  542. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement