SHARE
TWEET

ComputerCraft Tutorial: h2touchpanel_API_0_1

hevohevo Feb 8th, 2014 1,519 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top