Advertisement
jille_Jr

CC: Display API

Nov 10th, 2013
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.32 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.     for count = 1,#str do
  163.         if class.pixles[x+count-1] then
  164.             if class.pixles[x+count-1][y] then
  165.                 class.pixles[x+count-1][y].sym = str:sub(count,count)
  166.                 class.pixles[x+count-1][y].fg = class.fgcolor
  167.                 if trans ~= true then
  168.                     class.pixles[x+count-1][y].bg = class.bgcolor
  169.                 end
  170.             end
  171.         end
  172.     end
  173. end
  174.  
  175. function line(class,x1,y1,x2,y2,bg)
  176.     -- Bresenham's algorithm
  177.     local dx = x2 - x1
  178.     if dx < 0 then dx = -dx end
  179.     local dy = y2 - y1
  180.     if dy < 0 then dy = -dy end
  181.    
  182.     local sx,sy
  183.     if x1 < x2 then sx = 1
  184.     else sx = -1 end
  185.     if y1 < y2 then sy = 1
  186.     else sy = -1 end
  187.    
  188.     local err = dx - dy
  189.    
  190.     repeat
  191.         local x,y = round(x1),round(y1)
  192.         if class.pixles[x] then
  193.             if class.pixles[x][y] then
  194.                 class.pixles[x][y].bg = class.bgcolor
  195.                 if bg ~= true then
  196.                     class.pixles[x][y].sym = " "
  197.                 end
  198.             end
  199.         end
  200.        
  201.         if x1 == x2 and y1 == y2 then break end
  202.         local e2 = 2*err
  203.         if e2 > -dy then
  204.             err = err - dy
  205.             x1 = x1 + sx
  206.         end
  207.         if e2 < dx then
  208.             err = err + dx
  209.             y1 = y1 + sy
  210.         end
  211.     until false
  212. end
  213.  
  214. -- supported modes: fill, line
  215. -- bg = only set background color
  216. function rect(class,mode,x1,y1,x2,y2,bg)
  217.     x1=round(x1) y1=round(y1) x2=round(x2) y2=round(y2)
  218.     if mode == "fill" then
  219.         for x = x1,x2 do
  220.             for y = y1,y2 do
  221.                 if class.pixles[x] ~= nil then
  222.                     if class.pixles[x][y] ~= nil then
  223.                         class.pixles[x][y].bg = class.bgcolor
  224.                         if bg ~= true then
  225.                             class.pixles[x][y].sym = " "
  226.                         end
  227.                     end
  228.                 end
  229.             end
  230.         end
  231.     elseif mode == "line" then
  232.         -- top line
  233.         for x = x1,x2 do
  234.             for y = y1,y1+class.stroke-1 do
  235.                 if class.pixles[x] ~= nil then
  236.                     if class.pixles[x][y] ~= nil then
  237.                         class.pixles[x][y].bg = class.bgcolor
  238.                         if bg ~= true then
  239.                             class.pixles[x][y].sym = " "
  240.                         end
  241.                     end
  242.                 end
  243.             end
  244.         end
  245.         -- bottom line
  246.         for x = x1,x2 do
  247.             for y = y2-class.stroke+1,y2 do
  248.                 if class.pixles[x] ~= nil then
  249.                     if class.pixles[x][y] ~= nil then
  250.                         class.pixles[x][y].bg = class.bgcolor
  251.                         if bg ~= true then
  252.                             class.pixles[x][y].sym = " "
  253.                         end
  254.                     end
  255.                 end
  256.             end
  257.         end
  258.         -- right line
  259.         for x = x2-class.stroke+1,x2 do
  260.             for y = y1,y2 do
  261.                 if class.pixles[x] ~= nil then
  262.                     if class.pixles [x][y] ~= nil then
  263.                         class.pixles[x][y].bg = class.bgcolor
  264.                         if bg ~= true then
  265.                             class.pixles[x][y].sym = " "
  266.                         end
  267.                     end
  268.                 end
  269.             end
  270.         end
  271.         -- left line
  272.         for x = x1,x1+class.stroke-1 do
  273.             for y = y1,y2 do
  274.                 if class.pixles[x] ~= nil then
  275.                     if class.pixles [x][y] ~= nil then
  276.                         class.pixles[x][y].bg = class.bgcolor
  277.                         if bg ~= true then
  278.                             class.pixles[x][y].sym = " "
  279.                         end
  280.                     end
  281.                 end
  282.             end
  283.         end
  284.     end
  285. end
  286.  
  287. -- supported modes: fill, line
  288. -- bg = only set background color
  289. function circle(class,mode,x,y,r,bg)
  290.     x=round(x) y=round(y)
  291.     for w in pairs(class.pixles) do
  292.         for h in pairs(class.pixles[w]) do
  293.             -- pythagrias sats
  294.             -- a^2 + b^2 = c^2
  295.             local dis = math.sqrt((w-x)^2 + (h-y)^2)
  296.             if dis <= r then
  297.                 if mode == "fill" or
  298.                 (mode == "line" and dis >= r-class.stroke) then
  299.                     if class.pixles[w] ~= nil then
  300.                         if class.pixles[w][h] ~= nil then
  301.                             class.pixles[w][h].bg = class.bgcolor
  302.                             if bg ~= true then
  303.                                 class.pixles[w][h].sym = " "
  304.                             end
  305.                         end
  306.                     end
  307.                 end
  308.             end
  309.         end
  310.     end
  311. end
  312.  
  313. -- x,y = top left corner of text field
  314. -- w = width of text field
  315. -- l = max lenght of text
  316. -- c = make the text look like a certain character
  317. -- trans = transparent
  318. -- callback = function, gets events as parameters, if returns true then exit
  319. function read(class,x,y,w,l,initstr,c,trans,callback)
  320.     x=round(x) y=round(y) w=round(w) l=round(l)
  321.     if type(l)~="number" then l=-1 end
  322.     if type(initstr)~="string" then initstr="" end
  323.     local running = true
  324.     local text = initstr
  325.     local padding = text:len()-w
  326.     local cursor = text:len()
  327.    
  328.     callback = callback or function(ev,p1,p2,p3,p4,p5)
  329.         if ev == "key" and p1 == keys.enter then
  330.             return true
  331.         end
  332.     end
  333.    
  334.     while running do
  335.         -- fix cursor and padding
  336.         if cursor > #text then cursor = #text end
  337.         if cursor < 0 then cursor = 0 end
  338.         if padding > #text-1 then padding = #text-1 end
  339.         if padding < 0 then padding = 0 end
  340.        
  341.         -- drawing
  342.         if trans ~= true then
  343.             class:rect("fill",x,y,x+w,y,false)
  344.         end
  345.         if type(c) == "string" then
  346.             local str = c:rep(math.floor(#text/#c)) .. c:sub(1,#text%#c)
  347.             class:write(str:sub(padding+1,padding+w+1),x,y,true)
  348.         else
  349.             class:write(text:sub(padding+1,padding+w+1),x,y,true)
  350.         end
  351.        
  352.         class:update()
  353.         class:draw()
  354.        
  355.         if cursor-padding <= w and cursor-padding >= 0 then
  356.             class.obj.setCursorPos(x+cursor-padding,y)
  357.             class.obj.setTextColor(class:getfgcolor())
  358.             class.obj.setCursorBlink(true)
  359.         end
  360.        
  361.         local ev,p1,p2,p3,p4,p5 = os.pullEvent()
  362.        
  363.         class.obj.setCursorBlink(false)
  364.        
  365.         if callback(ev,p1,p2,p3,p4,p5) == true then
  366.             return text,ev,p1,p2,p3,p4,p5
  367.         end
  368.         if ev == "key" then
  369.             if p1 == keys.left then
  370.                 -- move left
  371.                 cursor = cursor - 1
  372.                 if cursor<padding then padding = padding - 1 end
  373.             elseif p1 == keys.right then
  374.                 -- move right
  375.                 cursor = cursor + 1
  376.                 if cursor-padding > w then padding = padding + 1 end
  377.             elseif p1 == keys.backspace then
  378.                 -- remove a character
  379.                 local num = cursor-1
  380.                 if num < 0 then num = 0 end
  381.                 text = text:sub(1,num) .. text:sub(cursor+1)
  382.                 cursor = cursor - 1
  383.                 if cursor<padding then padding = padding - 1 end
  384.             elseif p1 == keys.delete then
  385.                 -- remove a character
  386.                 text = text:sub(1,cursor) .. text:sub(cursor+2)
  387.             elseif p1 == keys.home then
  388.                 cursor = 0
  389.                 padding = 0
  390.             elseif p1 == keys["end"] then
  391.                 cursor = text:len()
  392.                 padding = text:len()-w
  393.             end
  394.         elseif ev == "char" then
  395.             if #text < l or l <= 0 then -- check length limit
  396.                 -- add a character
  397.                 text = text:sub(1,cursor) .. p1 .. text:sub(cursor+1)
  398.                 cursor = cursor + 1
  399.                 if cursor-padding > w then padding = padding + 1 end
  400.             end
  401.         elseif (ev == "mouse_click" and class.type == "term")
  402.         or (ev == "monitor_touch" and class.type == "monitor" and p1 == class.path) then
  403.             -- move cursor
  404.             -- x=p2, y=p3
  405.             if p2<x then p2=x end
  406.             if p2>x+w then p2=x+w end
  407.             cursor = p2-x+padding
  408.         elseif ev == "mouse_scroll" then
  409.             -- scrolling left/right
  410.             padding = padding + p1
  411.         end
  412.     end
  413. end
  414.  
  415. function load(objpath)
  416.     local startload = os.clock()
  417.    
  418.     tobj = {}
  419.    
  420.     -- object variables
  421.     objpath = objpath or "N/A"
  422.     if peripheral.isPresent(objpath)
  423.     and peripheral.getType(objpath) == "monitor" then
  424.         tobj.obj = peripheral.wrap(objpath or "N/A")
  425.         tobj.type = "monitor"
  426.         tobj.path = objpath
  427.         tobj.eventname = "monitor_touch"
  428.     else
  429.         tobj.type = "term"
  430.         tobj.obj = term
  431.         tobj.path = "N/A"
  432.         tobj.eventname = "mouse_click"
  433.     end
  434.    
  435.     -- variables
  436.     tobj.pixles = {}
  437.     tobj.updaterate = 0.2
  438.     tobj.looprunning = false
  439.     tobj.looptime = 0
  440.     tobj.stroke = 1
  441.     tobj.bgcolor = colors.black
  442.     tobj.fgcolor = colors.white
  443.    
  444.     -- misc functions
  445.     tobj.setupdaterate = setupdaterate
  446.     tobj.getupdaterate = getupdaterate
  447.     tobj.removepixles = removepixles
  448.     tobj.fixpixles = fixpixles
  449.     tobj.update = update
  450.     tobj.draw = draw
  451.     tobj.loop = loop
  452.     tobj.prepareloop = prepareloop
  453.     tobj.stoploop = stoploop
  454.    
  455.     -- color functions
  456.     tobj.setcolor = setcolor
  457.     tobj.setfgcolor = setfgcolor
  458.     tobj.setbgcolor = setbgcolor
  459.     tobj.getcolor = getcolor
  460.     tobj.getfgcolor = getfgcolor
  461.     tobj.getbgcolor = getbgcolor
  462.     tobj.setstroke = setstroke
  463.     tobj.getstroke = getstroke
  464.     -- british
  465.     tobj.setcolour = setcolor
  466.     tobj.setfgcolour = setfgcolor
  467.     tobj.setbgcolour = setbgcolor
  468.     tobj.getcolour = getcolor
  469.     tobj.getfgcolour = getfgcolor
  470.     tobj.getbgcolour = getbgcolor
  471.    
  472.     -- drawing functions
  473.     tobj.clear = clear
  474.     tobj.write = write
  475.     tobj.line = line
  476.     tobj.rect = rect
  477.     tobj.circle = circle
  478.     tobj.read = read
  479.    
  480.     tobj:removepixles()
  481.     tobj:fixpixles()
  482.    
  483.     local endload = os.clock()
  484.     return tobj,endload-startload
  485. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement