SHARE
TWEET

ComputerCraft Tutorial: h2touchpanel_API_0_1

hevohevo Feb 8th, 2014 1,246 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- #################################
  2. -- h2touchpanel API
  3. -- (hevohevo's TouchPanel API)
  4. -- version 0.1d
  5. -- http://hevohevo.hatenablog.com/
  6.  
  7. -- #######################
  8. -- how to use
  9. -- 1. install this program
  10. --   > pastebin get XXXXXX h2touchpanel
  11. -- 2. insert into your code
  12. --   > os.loadAPI("h2touchpanel")
  13. -- 3. You can use some functions. As follows:
  14. --[[
  15. os.loadAPI("h2touchpanel")
  16.  
  17. -- define function for button-command
  18. local myNewFunc = function() print("hello") end
  19. local runProgram = function() sleep(2) shell.run("hevo2.lua") end
  20.  
  21. -- button_config: "name"(string) and "cmd"(function) are required.
  22. local bCfg = {}
  23. bCfg[1]={name="open", cmd=function() rs.setOutput("right", true) end}
  24. bCfg[2]={name="close", cmd=function() rs.setOutput("right", false) end}
  25. bCfg[3]={name="pass", cmd=myNewFunc}
  26. bCfg[4]={name="sleep", cmd=runProgram}
  27.  
  28.  
  29. -- panelOpt = {topPos=1, leftPos=1, rightPos=nil, bottomPos=nil, scale=0.5,
  30. --             fgColor=colors.white, bgPattern={colors.blue, colors.lightBlue}}
  31. local panelOpt={}
  32.  
  33. -- makePanel(btn_cfg, col, row, monitor, opt) returns Panel-Object
  34. local p1 = h2touchpanel.makePanel(bCfg, 3, 2, mon, panelOpt)
  35. p1:draw() -- same as p1.draw(p1): draw touch-panel-buttons into mon
  36.  
  37. while true do
  38.   -- same as p1.pullButtonPushEvent(p1, monitor_side):
  39.   --      return two params, event "button_push" and a pushed button.
  40.   local event, b1 = p1:pullButtonPushEvent()
  41.  
  42.   p1:drawPushedButtonEffect(b1)   -- draw pushed button effect on monitor
  43.   b1:run()   -- run function
  44. end
  45. --]]
  46.  
  47. -- #####################################
  48. -- Object Oriented Programming
  49.  
  50. -- Coordinate Object
  51. local Coordinate = {}
  52. Coordinate.new = function(_x,_y)
  53.   local obj = {}
  54.   obj.x = _x
  55.   obj.y = _y
  56.   return setmetatable(obj,{__index = Coordinate})
  57. end
  58.  
  59. Coordinate.pp = function(self) print("(",self.x,',',self.y,")") end
  60. Coordinate.width = function(startP, goalP) return math.abs(goalP.x - startP.x)+1 end
  61. Coordinate.height = function(startP, goalP) return math.abs(goalP.y - startP.y)+1 end
  62. Coordinate.midpoint = function(startP, goalP, floor_flag)
  63.   local x = startP.x + startP:width(goalP)/2
  64.   local y = startP.y + startP:height(goalP)/2
  65.   if floor_flag then
  66.     return Coordinate.new(math.floor(x),math.floor(y))
  67.   else
  68.     return Coordinate.new(x,y)
  69.   end
  70. end
  71.  
  72. -- Rectangle Object
  73. local Rectangle= {}
  74. Rectangle.new = function(_startX, _startY, _goalX, _goalY, _color)
  75.   local obj = {}
  76.   obj.start = Coordinate.new(_startX, _startY)
  77.   obj.goal = Coordinate.new(_goalX, _goalY)
  78.   obj.bgcolor = _color
  79.   return setmetatable(obj,{__index = Rectangle})
  80. end
  81.  
  82. Rectangle.draw = function(self,mon)
  83.   mon.setBackgroundColor(self.bgcolor)
  84.   for y=self.start.y, self.goal.y do
  85.     mon.setCursorPos(self.start.x, y)
  86.     for x=self.start.x, self.goal.x do
  87.       mon.write(" ")
  88.     end
  89.   end
  90. end
  91.  
  92.  
  93. -- Button Object
  94. local Button = {}
  95. Button.new = function(_name, _cmd, _startX, _startY, _goalX, _goalY, _fgColor, _bgcolor)
  96.   local obj = Rectangle.new(_startX, _startY, _goalX, _goalY, _bgcolor)
  97.   obj.name = _name
  98.   obj.fgColor = _fgColor
  99.   obj.cmd = _cmd
  100.   obj.toggle_flag = false
  101.   return setmetatable(obj,{__index = Button})
  102. end
  103.  
  104. Button.pp = function(self)
  105.   local str_cmd = self.cmd
  106.   if type(self.cmd) == "function" then
  107.     str_cmd = "a function"
  108.   elseif not self.cmd then
  109.     str_cmd = "do-nothing"
  110.   end
  111.   print(string.format("%s: (%d,%d)-(%d,%d), %d, %s",
  112.     self.name, self.start.x, self.start.y, self.goal.x, self.goal.y, self.bgcolor, str_cmd))
  113. end
  114.  
  115. Button.draw = function(self,mon)
  116.   Rectangle.draw(self, mon)-- draw a rectangle
  117.   -- draw button label into the rectangle
  118.   local bWidth = self.start:width(self.goal)
  119.   local bHeight = self.start:height(self.goal)
  120.   local name = self.name
  121.   local label = string.sub(self.name, 1, bWidth)
  122.   local length = string.len(label)
  123.   local midpoint = self.start:midpoint(self.goal)    
  124.   mon.setCursorPos(math.floor(midpoint.x - length/2), math.floor(midpoint.y))
  125.   mon.write(label)
  126. end
  127.  
  128. Button.isWithin = function(self, point)
  129.   local _within = function(n,start,goal)
  130.     return n>=start and n<=goal
  131.   end
  132.   return _within(point.x, self.start.x, self.goal.x) and _within(point.y, self.start.y, self.goal.y)
  133. end
  134.  
  135. Button.evalCmd = function(self)
  136.   if not self.cmd or self.cmd=="" then
  137.     return false
  138.   elseif type(self.cmd) == "string" then
  139.     return assert(loadstring(self.cmd), "invalid cmd: this string is invalid.")()
  140.   elseif type(self.cmd) == "function" then
  141.     return self.cmd()
  142.   else
  143.     return assert(false, "invalid cmd: cmd is function or function-string")
  144.   end
  145. end
  146.  
  147. Button.run = Button.evalCmd
  148.  
  149. -- Panel Object
  150. -- OPTION = {topPos=1, leftPos=1, rightPos=nil, bottomPos=nil, scale=0.5,
  151. --           fgColor=colors.white, bgPattern={colors.blue, colors.lightBlue}}
  152. local Panel = {}
  153. Panel._makeButtons = function(_bCfg, _col, _row, _mon, _opt)
  154.   local opt = _opt or {}
  155.   local point0 = Coordinate.new((opt.leftPos or 1), (opt.topPos or 1)) -- left-top point
  156.   local point1 = Coordinate.new(_mon.getSize()) -- right-bottom point
  157.   point1.x = opt.rightPos or point1.x
  158.   point1.y = opt.bottomPos or point1.y
  159.   local panel_w, panel_h = point0:width(point1), point0:height(point1)
  160.   local btn_w = math.floor(panel_w/_col)
  161.   local btn_h = math.floor(panel_h/_row)
  162.   local margin_w, margin_h = (panel_w % _col), (panel_h % _row)
  163.   local margin_left,margin_top = math.floor(margin_w/2), math.floor(margin_h/2)
  164.   local margin_right, margin_bottom = margin_w - margin_left, margin_h - margin_top
  165.   local fgColor = opt.fgColor or colors.white
  166.   local colorRing = function(i) -- make background color pattern
  167.     local array = {colors.blue, colors.lightBlue, colors.cyan}
  168.     if _col%2 == 1 then array = {colors.blue, colors.lightBlue} end
  169.     array = opt.bgPattern or array
  170.     return array[((i-1)%(#array))+1]
  171.   end
  172.  
  173.   local btns = {}
  174.   local i = 1 -- table index
  175.   local min_y = point0.y
  176.   local max_y = min_y+btn_h-1 + margin_top
  177.   for row=1,_row do
  178.     local min_x = point0.x
  179.     local max_x = min_x+btn_w-1+ margin_left
  180.     for col=1, _col do
  181.       if _bCfg[i] then -- make a button by the button_config
  182.         btns[i] = Button.new(_bCfg[i]["name"], _bCfg[i]["cmd"], min_x, min_y, max_x, max_y, fgColor, colorRing(i))
  183.       else -- make a blank button
  184.         btns[i] = Button.new("--", nil, min_x, min_y, max_x, max_y, fgColor, colorRing(i))
  185.       end
  186.       --calculate next
  187.       i = i+1
  188.       min_x = max_x +1
  189.       max_x = min_x + btn_w-1
  190.       if col==_col-1 then max_x = max_x + margin_right end
  191.     end
  192.     min_y = max_y +1
  193.     max_y = min_y + btn_h-1
  194.     if row==_row-1 then max_y = max_y + margin_bottom end
  195.   end
  196.   return btns
  197. end
  198.  
  199. Panel.new = function(_bCfg, _col, _row, _mon, _opt)
  200.   local opt = _opt or {}
  201.   if _mon.setTextScale then _mon.setTextScale(opt.scale or 0.5) end
  202.   local obj= {}
  203.   obj.col=_col
  204.   obj.row=_row
  205.   obj.total = _col*_row
  206.   obj.mon = _mon
  207.  
  208.   obj.btns= Panel._makeButtons(_bCfg, _col, _row, _mon, opt)
  209.  
  210.   return setmetatable(obj,{__index = Panel})
  211. end
  212.  
  213. Panel.pp = function(self)
  214.   print("Panel: ",self.col,'x',self.row)
  215.   print("   Btns: ",#self.btns)
  216.  
  217.   for i,b in ipairs(self.btns) do
  218.     b:pp()
  219.   end
  220. end
  221.  
  222. Panel.draw = function(self)
  223.   self.mon.setBackgroundColor(colors.gray)
  224.   self.mon.clear()
  225.   for i,b in ipairs(self.btns) do
  226.     b:draw(self.mon)
  227.   end
  228. end
  229.  
  230. Panel.drawPushedButtonEffect = function(self, btn, _sec)
  231.   self.mon.setBackgroundColor(colors.gray)
  232.   self.mon.clear()
  233.   btn:draw(self.mon)
  234.   sleep(_sec or 0.5)
  235.   self:draw()
  236. end
  237.  
  238. Panel.pullButtonPushEvent = function(self, mon_side)
  239.   local pushed_btn = false
  240.   local whichButton = function(btns,x,y)
  241.     for i,b in ipairs(btns) do
  242.       if b:isWithin(Coordinate.new(x,y)) then
  243.         pushed_btn = b
  244.         break
  245.       end
  246.     end
  247.   end
  248.  
  249.   repeat
  250.     if self.mon.setTextScale then -- when self.mon is advanced_monitor
  251.       local event, side, x, y = os.pullEvent("monitor_touch")
  252.       if not mon_side or mon_side == side  then
  253.         whichButton(self.btns, x, y)
  254.       end
  255.     else -- when self.mon is term
  256.       local event, mouse, x, y = os.pullEvent("mouse_click")
  257.       whichButton(self.btns, x, y)
  258.     end
  259.   until  pushed_btn
  260.  
  261.   return "button_push", pushed_btn
  262. end
  263.  
  264. -- ########################
  265. -- API Functions
  266. function makePanel(bCnfg, col, row, mon, opt)
  267.   return Panel.new(bCnfg, col, row, mon, opt)
  268. end
RAW Paste Data
Pastebin PRO Summer Special!
Get 40% OFF on Pastebin PRO accounts!
Top