Advertisement
hevohevo

ComputerCraft Tutorial: h2touchpanel_API_incomplete

Feb 19th, 2014
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.88 KB | None | 0 0
  1. This is incomplete program.
  2. -- #################################
  3. -- h2touchpanel API
  4. -- (hevohevo's TouchPanel API)
  5. -- version 0.2
  6. -- http://hevohevo.hatenablog.com/
  7.  
  8. -- #######################
  9. -- Notice
  10. -- This API rewrite peripheral.wrap()
  11.  
  12. -- #######################
  13. -- how to use
  14. -- 1. install this program
  15. --   > pastebin get XXXXXX h2touchpanel
  16. -- 2. insert into your code
  17. --   > os.loadAPI("h2touchpanel")
  18. -- 3. You can use some functions. As follows:
  19.  
  20. --[[
  21. os.loadAPI("h2touchpanel")
  22.  
  23. -- define function for button-command
  24.  
  25.   -- button_config: "name"(string) and "cmd"(function) are required.
  26. local bCfg = {}
  27. bCfg[1]={name="Up", cmd=turtle.up}
  28. bCfg[2]={name="Fwd", cmd=turtle.forward}
  29. bCfg[3]={name="Down", cmd=turtle.down}
  30. bCfg[4]={name="<=", cmd=turtle.turnLeft}
  31. bCfg[5]={name="Back", cmd=turtle.back}
  32. bCfg[6]={name="=>", cmd=turtle.turnRight}
  33. bCfg[7]={name="backP", cmd=panel.backPage}
  34. bCfg[8]={name="ref", cmd=turtle.refuel}
  35. bCfg[9]={name="nextP", cmd=panel.nextPage}
  36. bCfg[10]={name="place", cmd=turtle.place}
  37. bCfg[11]={name="dig", cmd=turtle.dig}
  38. bCfg[12]={name="attack", cmd=turtle.attack}
  39. bCfg[13]={name="place", cmd=turtle.place}
  40. bCfg[14]={name="dig", cmd=turtle.dig}
  41. bCfg[15]={name="attack", cmd=turtle.attack}
  42. bCfg[16]={name="backP", cmd=panel.backPage}
  43. bCfg[17]={name="ref", cmd=turtle.refuel}
  44. bCfg[18]={name="nextP", cmd=panel.nextP}
  45.  
  46.  
  47. -- panelOpt = {topPos=1, leftPos=1, rightPos=nil, bottomPos=nil, scale=0.5,
  48. --             fgColor=colors.white, bgPattern={colors.blue, colors.lightBlue}}
  49. local panelOpt={}
  50.  
  51. -- makePanel(btn_cfg, col, row, monitor, opt) returns Panel-Object
  52. local p1 = h2touchpanel.makePanel(bCfg, 3, 2, mon, panelOpt)
  53. p1:draw() -- same as p1.draw(p1): draw touch-panel-buttons into mon
  54.  
  55. while true do
  56.   -- same as p1.pullButtonPushEvent(p1, monitor_side):
  57.   --      return two params, event "button_push" and a pushed button.
  58.   local event, b1 = p1:pullButtonPushEvent()
  59.  
  60.   p1:drawPushedButtonEffect(b1)   -- draw pushed button effect on monitor
  61.   b1:run()   -- run function
  62. end
  63. --]]
  64.  
  65. -- #####################################
  66. -- Object Oriented Programming
  67.  
  68. -- Color name for pp (pretty print) function
  69. local cName = {
  70.   1 = 'white',
  71.   2 = 'orange',
  72.   4 = 'magenta',
  73.   8 = 'lightBlue',
  74.   16 = 'yellow',
  75.   32 = 'lime',
  76.   64 = 'pink',
  77.   128 = 'gray',
  78.   256 = 'lightGray',
  79.   512 = 'cyan',
  80.   1024 = 'purple',
  81.   2048 = 'blue',
  82.   4096 = 'brown',
  83.   8192 = 'green',
  84.   16384 = 'red',
  85.   32768 = 'black'
  86. }
  87. -- #######################################
  88. -- overwrite peripheral.wrap in Peripheral API
  89. -- add new function: peripheral_func_table.getSide()
  90. if not _G.peripheral.wrap_org then
  91.   _G.peripheral.wrap_org = peripheral.wrap
  92.   _G.peripheral.wrap = function(side)
  93.     local tbl = peripheral.wrap_org(side)
  94.     if tbl then
  95.       tbl.getSide = function() return side end
  96.     end
  97.     return tbl
  98.   end
  99. end
  100.  
  101. -- #######################################
  102. -- add new functions and overwrite in Turtle API
  103. -- turtle.select_org(n)
  104. -- turtle.select(n)
  105. -- turtle.getSelectedSlot()
  106. -- turtle.selectNext()
  107. -- turtle.selectPrev()
  108. if not _G.turtle.select_org then
  109.   turtle.select_org = turtle.select_org or turtle.select
  110.   turtle.select = function(slot)
  111.     turtle.select_org(slot)
  112.     local func = function (x)
  113.         slot = slot + x
  114.         return (((slot-1) % 16)+1)
  115.     end
  116.     turtle.selectNext = function() return turtle.select_org(func(1)) end
  117.     turtle.selectPrev = function() return turtle.select_org(func(-1)) end
  118.     turtle.getSelectedSlot = function() return func(0) end
  119.     return true
  120.   end
  121.   turtle.select(1)
  122. end
  123.  
  124. -- #######################################
  125. -- Coordinate Object
  126. local Coordinate = {}
  127. Coordinate.new = function(_x,_y)
  128.   local obj = {}
  129.   obj.x = _x
  130.   obj.y = _y
  131.   return setmetatable(obj,{__index = Coordinate})
  132. end
  133.  
  134. Coordinate.pp = function(self) print("(",self.x,',',self.y,")") end
  135. Coordinate.width = function(startP, goalP) return math.abs(goalP.x - startP.x)+1 end
  136. Coordinate.height = function(startP, goalP) return math.abs(goalP.y - startP.y)+1 end
  137. Coordinate.midpoint = function(startP, goalP, floor_flag)
  138.   local x = startP.x + startP:width(goalP)/2
  139.   local y = startP.y + startP:height(goalP)/2
  140.   if floor_flag then
  141.     return Coordinate.new(math.floor(x),math.floor(y))
  142.   else
  143.     return Coordinate.new(x,y)
  144.   end
  145. end
  146.  
  147. -- Rectangle Object
  148. local Rectangle= {}
  149. Rectangle.new = function(_startX, _startY, _goalX, _goalY, _color)
  150.   local obj = {}
  151.   obj.start = Coordinate.new(_startX, _startY)
  152.   obj.goal = Coordinate.new(_goalX, _goalY)
  153.   obj.bgcolor = _color
  154.   return setmetatable(obj,{__index = Rectangle})
  155. end
  156.  
  157. Rectangle.draw = function(self,mon)
  158.   mon.setBackgroundColor(self.bgcolor)
  159.   for y=self.start.y, self.goal.y do
  160.     mon.setCursorPos(self.start.x, y)
  161.     for x=self.start.x, self.goal.x do
  162.       mon.write(" ")
  163.     end
  164.   end
  165. end
  166.  
  167.  
  168. -- Button Object
  169. local Button = {}
  170. Button.new = function(_name, _cmd, _startX, _startY, _goalX, _goalY, _fgColor, _bgColor)
  171.   local obj = Rectangle.new(_startX, _startY, _goalX, _goalY, _bgColor)
  172.   obj.name = _name
  173.   obj.fgColor = _fgColor
  174.   obj.cmd = _cmd
  175.   return setmetatable(obj,{__index = Button})
  176. end
  177.  
  178. Button.pp = function(self)
  179.   local str_cmd = self.cmd
  180.   if type(self.cmd) == "function" then
  181.     str_cmd = "a function"
  182.   elseif not self.cmd then
  183.     str_cmd = "do-nothing"
  184.   end
  185.   print(string.format("%s: (%d,%d)-(%d,%d), %d, %s",
  186.     self.name, self.start.x, self.start.y, self.goal.x, self.goal.y, cName[self.bgcolor], str_cmd))
  187. end
  188.  
  189. Button.draw = function(self,mon)
  190.   Rectangle.draw(self, mon)-- draw a rectangle
  191.   -- draw button label into the rectangle
  192.   local bWidth = self.start:width(self.goal)
  193.   local bHeight = self.start:height(self.goal)
  194.   local name = self.name
  195.   local label = string.sub(self.name, 1, bWidth)
  196.   local length = string.len(label)
  197.   local midpoint = self.start:midpoint(self.goal)    
  198.   mon.setCursorPos(math.floor(midpoint.x - length/2), math.floor(midpoint.y))
  199.   mon.write(label)
  200. end
  201.  
  202. Button.isWithin = function(self, point)
  203.   local _within = function(n,start,goal)
  204.     return n>=start and n<=goal
  205.   end
  206.   return _within(point.x, self.start.x, self.goal.x) and _within(point.y, self.start.y, self.goal.y)
  207. end
  208.  
  209. Button.evalCmd = function(self)
  210.   if not self.cmd or self.cmd=="" then
  211.     return false
  212.   elseif type(self.cmd) == "string" then
  213.     return assert(loadstring(self.cmd), "invalid cmd: this string is invalid.")()
  214.   elseif type(self.cmd) == "function" then
  215.     return self.cmd()
  216.   else
  217.     return assert(false, "invalid cmd: cmd is function or function-string")
  218.   end
  219. end
  220.  
  221. Button.run = Button.evalCmd
  222.  
  223. -- Panel Object
  224. -- OPTION = {topPos=1, leftPos=1, rightPos=(monitor width), bottomPos=(monitor hight),
  225. --           scale=0.5, fgColor=colors.white, bgPattern={colors.blue, colors.lightBlue}}
  226. local Panel = {}
  227. Panel._makeButtons = function(_bCfg, _col, _row, _mon, _opt)
  228.   local opt = _opt or {}
  229.   local point0 = Coordinate.new((opt.leftPos or 1), (opt.topPos or 1)) -- left-top point
  230.   local point1 = Coordinate.new(_mon.getSize()) -- right-bottom point
  231.   point1.x = opt.rightPos or point1.x
  232.   point1.y = opt.bottomPos or point1.y
  233.   local panelW, panelH = point0:width(point1), point0:height(point1)
  234.   local btnW = math.floor(panelW/_col)
  235.   local btnH = math.floor(panelH/_row)
  236.   local margin_w, margin_h = (panelW % _col), (panelH % _row)
  237.   local margin_left,margin_top = math.floor(margin_w/2), math.floor(margin_h/2)
  238.   local margin_right, margin_bottom = margin_w - margin_left, margin_h - margin_top
  239.   local fgColor = opt.fgColor or colors.white
  240.   local colorRing = function(i) -- make background color pattern
  241.     local array = {colors.blue, colors.lightBlue, colors.cyan}
  242.     if _col%2 == 1 then array = {colors.blue, colors.lightBlue} end
  243.     array = opt.bgPattern or array
  244.     return array[((i-1)%(#array))+1]
  245.   end
  246.  
  247.   local btns = {}
  248.   local i = 1 -- table index
  249.   local minY = point0.y
  250.   local maxY = minY+btnH-1 + margin_top
  251.   for row=1,_row do
  252.     local minX = point0.x
  253.     local maxX = minX+btnW-1+ margin_left
  254.     for col=1, _col do
  255.       if _bCfg[i] then -- make a button by the button_config
  256.         btns[i] = Button.new(_bCfg[i]["name"], _bCfg[i]["cmd"], minX, minY, maxX, maxY, fgColor, colorRing(i))
  257.       else -- make a blank button
  258.         btns[i] = Button.new("--", nil, minX, minY, maxX, maxY, fgColor, colorRing(i))
  259.       end
  260.       --calculate next
  261.       i = i+1
  262.       minX = maxX +1
  263.       maxX = minX + btnW-1
  264.       if col==_col-1 then maxX = maxX + margin_right end
  265.     end
  266.     minY = maxY +1
  267.     maxY = minY + btnH-1
  268.     if row==_row-1 then maxY = maxY + margin_bottom end
  269.   end
  270.   return btns
  271. end
  272.  
  273. Panel.new = function(_bCfg, _col, _row, _mon, _opt)
  274.   local opt = _opt or {}
  275.   if _mon.setTextScale then _mon.setTextScale(opt.scale or 0.5) end
  276.   local obj= {}
  277.   obj.col=_col
  278.   obj.row=_row
  279.   obj.total = _col*_row
  280.   obj.mon = _mon
  281.  
  282.   obj.btns= Panel._makeButtons(_bCfg, _col, _row, _mon, opt)
  283.  
  284.   return setmetatable(obj,{__index = Panel})
  285. end
  286.  
  287. Panel.pp = function(self)
  288.   print("Panel: ",self.col,'x',self.row)
  289.   print("   Btns: ",#self.btns)
  290.  
  291.   for i,b in ipairs(self.btns) do
  292.     b:pp()
  293.   end
  294. end
  295.  
  296. Panel.draw = function(self)
  297.   self.mon.setBackgroundColor(colors.gray)
  298.   self.mon.clear()
  299.   for i,b in ipairs(self.btns) do
  300.     b:draw(self.mon)
  301.   end
  302. end
  303.  
  304. Panel.drawPushedButtonEffect = function(self, btn, _sec)
  305.   self.mon.setBackgroundColor(colors.gray)
  306.   self.mon.clear()
  307.   btn:draw(self.mon)
  308.   sleep(_sec or 0.5)
  309.   self:draw()
  310. end
  311.  
  312. Panel.whichButton = function(self, x, y)
  313.   local pushedBtn = false
  314.   for i,b in ipairs(self.btns) do
  315.     if b:isWithin(Coordinate.new(x,y)) then
  316.       pushedBtn = b
  317.       break
  318.     end
  319.   end
  320.   return pushedBtn
  321. end
  322.  
  323. Panel._pullEvent= function(self)
  324.   local params = {os.pullEvent()}
  325.   local pushedBtn  = false
  326.  
  327.   -- params, 1:'monitor_touch', 2:side, 3:x, 4:y, (advanced_monitor)
  328.   -- params, 1:'mouse_click', 2:mouse_btn, 3:x, 4:y, (terminal)
  329.   if (self.mon.setTextScale and params[1] == "monitor_touch" and self.mon.getSide() == params[2])
  330.     or (self.mon == _G.term and params[1] == "mouse_click") then
  331.       pushedBtn = whichButton(self.btns, params[3], params[4])
  332.       if pushedBtn then
  333.         params[1] = "button_push"
  334.         params[2] = pushedBtn
  335.       end
  336.   else
  337.     -- do nothing
  338.   end
  339.  
  340.   return unpack(params)
  341. end
  342.  
  343. Panel.pullEvent = function(self, filter)
  344.   local params = false
  345.  
  346.   repeat
  347.     params = self._pullEvent()
  348.   until filter == params[1]
  349.  
  350.   return unpack(params)
  351. end
  352.  
  353.  
  354. -- PanelGroup Object
  355. local PanelGroup = {}
  356. PanelGroup._makePanels = function(self, _bCfg, _col, _row, _mon, _opt)
  357.   local results = {}
  358.   local num = _col*_row
  359.   local page = math.ceil(#_bCfg/num)
  360.   local makeArray = function(_array, minIndex, maxIndex)
  361.     local tmp = {}
  362.     for i=minIndex, maxIndex do
  363.       table.insert(tmp, _array[i])
  364.     end
  365.     return tmp
  366.   end
  367.  
  368.   for p=1, page do
  369.     table.insert(results, Panel.new(makeArray(_bCfg, 1+num*(page-1), num*page), _co, _row, _mon, _opt))
  370.   end
  371.  
  372.   return results
  373. end
  374.  
  375. PanelGroup.new = function(self, _bCfg, _col, _row, _mon, _opt)
  376.   local obj = {}
  377.   local panelId = 1
  378.   obj.panels = self._makePanels()
  379.   obj.selectedPanel = function(self)
  380.     return self.panels[((panelId-1)%(#self.panels))+1]
  381.   end
  382.   obj.selectNext = function(self)
  383.     obj.selectedPanelId = obj.selectedPanelId + 1
  384.     return self.panels[((panelId-1)%(#self.panels))+1]
  385.   end
  386.   obj.selectPrev = function(self)
  387.     self.selectedPanelId = self.selectedPanelId - 1
  388.     return self.panels[((panelId-1)%(#self.panels))+1]
  389.   end
  390. end
  391.  
  392. PanelGroup.draw = function(self)
  393.   self:selectedPanel():draw()
  394. end
  395. PanelGroup.pullEvent = function(self, filter)
  396.   self:selectedPanel():pullEvent(self, filter)
  397. end
  398.  
  399. -- ########################
  400. -- API Functions
  401. function makePanel(bCfg, col, row, mon, opt)
  402.   return PanelGroup:new(bCfg, col, row, mon, opt)
  403. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement