Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- #################################
- -- h2touchpanel API
- -- (hevohevo's TouchPanel API)
- -- version 0.1d
- -- http://hevohevo.hatenablog.com/
- -- #######################
- -- how to use
- -- 1. install this program
- -- > pastebin get XXXXXX h2touchpanel
- -- 2. insert into your code
- -- > os.loadAPI("h2touchpanel")
- -- 3. You can use some functions. As follows:
- --[[
- os.loadAPI("h2touchpanel")
- -- define function for button-command
- local myNewFunc = function() print("hello") end
- local runProgram = function() sleep(2) shell.run("hevo2.lua") end
- -- button_config: "name"(string) and "cmd"(function) are required.
- local bCfg = {}
- bCfg[1]={name="open", cmd=function() rs.setOutput("right", true) end}
- bCfg[2]={name="close", cmd=function() rs.setOutput("right", false) end}
- bCfg[3]={name="pass", cmd=myNewFunc}
- bCfg[4]={name="sleep", cmd=runProgram}
- -- panelOpt = {topPos=1, leftPos=1, rightPos=nil, bottomPos=nil, scale=0.5,
- -- fgColor=colors.white, bgPattern={colors.blue, colors.lightBlue}}
- local panelOpt={}
- -- makePanel(btn_cfg, col, row, monitor, opt) returns Panel-Object
- local p1 = h2touchpanel.makePanel(bCfg, 3, 2, mon, panelOpt)
- p1:draw() -- same as p1.draw(p1): draw touch-panel-buttons into mon
- while true do
- -- same as p1.pullButtonPushEvent(p1, monitor_side):
- -- return two params, event "button_push" and a pushed button.
- local event, b1 = p1:pullButtonPushEvent()
- p1:drawPushedButtonEffect(b1) -- draw pushed button effect on monitor
- b1:run() -- run function
- end
- --]]
- -- #####################################
- -- Object Oriented Programming
- -- Coordinate Object
- local Coordinate = {}
- Coordinate.new = function(_x,_y)
- local obj = {}
- obj.x = _x
- obj.y = _y
- return setmetatable(obj,{__index = Coordinate})
- end
- Coordinate.pp = function(self) print("(",self.x,',',self.y,")") end
- Coordinate.width = function(startP, goalP) return math.abs(goalP.x - startP.x)+1 end
- Coordinate.height = function(startP, goalP) return math.abs(goalP.y - startP.y)+1 end
- Coordinate.midpoint = function(startP, goalP, floor_flag)
- local x = startP.x + startP:width(goalP)/2
- local y = startP.y + startP:height(goalP)/2
- if floor_flag then
- return Coordinate.new(math.floor(x),math.floor(y))
- else
- return Coordinate.new(x,y)
- end
- end
- -- Rectangle Object
- local Rectangle= {}
- Rectangle.new = function(_startX, _startY, _goalX, _goalY, _color)
- local obj = {}
- obj.start = Coordinate.new(_startX, _startY)
- obj.goal = Coordinate.new(_goalX, _goalY)
- obj.bgcolor = _color
- return setmetatable(obj,{__index = Rectangle})
- end
- Rectangle.draw = function(self,mon)
- mon.setBackgroundColor(self.bgcolor)
- for y=self.start.y, self.goal.y do
- mon.setCursorPos(self.start.x, y)
- for x=self.start.x, self.goal.x do
- mon.write(" ")
- end
- end
- end
- -- Button Object
- local Button = {}
- Button.new = function(_name, _cmd, _startX, _startY, _goalX, _goalY, _fgColor, _bgcolor)
- local obj = Rectangle.new(_startX, _startY, _goalX, _goalY, _bgcolor)
- obj.name = _name
- obj.fgColor = _fgColor
- obj.cmd = _cmd
- obj.toggle_flag = false
- return setmetatable(obj,{__index = Button})
- end
- Button.pp = function(self)
- local str_cmd = self.cmd
- if type(self.cmd) == "function" then
- str_cmd = "a function"
- elseif not self.cmd then
- str_cmd = "do-nothing"
- end
- print(string.format("%s: (%d,%d)-(%d,%d), %d, %s",
- self.name, self.start.x, self.start.y, self.goal.x, self.goal.y, self.bgcolor, str_cmd))
- end
- Button.draw = function(self,mon)
- Rectangle.draw(self, mon)-- draw a rectangle
- -- draw button label into the rectangle
- local bWidth = self.start:width(self.goal)
- local bHeight = self.start:height(self.goal)
- local name = self.name
- local label = string.sub(self.name, 1, bWidth)
- local length = string.len(label)
- local midpoint = self.start:midpoint(self.goal)
- mon.setCursorPos(math.floor(midpoint.x - length/2), math.floor(midpoint.y))
- mon.write(label)
- end
- Button.isWithin = function(self, point)
- local _within = function(n,start,goal)
- return n>=start and n<=goal
- end
- return _within(point.x, self.start.x, self.goal.x) and _within(point.y, self.start.y, self.goal.y)
- end
- Button.evalCmd = function(self)
- if not self.cmd or self.cmd=="" then
- return false
- elseif type(self.cmd) == "string" then
- return assert(loadstring(self.cmd), "invalid cmd: this string is invalid.")()
- elseif type(self.cmd) == "function" then
- return self.cmd()
- else
- return assert(false, "invalid cmd: cmd is function or function-string")
- end
- end
- Button.run = Button.evalCmd
- -- Panel Object
- -- OPTION = {topPos=1, leftPos=1, rightPos=nil, bottomPos=nil, scale=0.5,
- -- fgColor=colors.white, bgPattern={colors.blue, colors.lightBlue}}
- local Panel = {}
- Panel._makeButtons = function(_bCfg, _col, _row, _mon, _opt)
- local opt = _opt or {}
- local point0 = Coordinate.new((opt.leftPos or 1), (opt.topPos or 1)) -- left-top point
- local point1 = Coordinate.new(_mon.getSize()) -- right-bottom point
- point1.x = opt.rightPos or point1.x
- point1.y = opt.bottomPos or point1.y
- local panel_w, panel_h = point0:width(point1), point0:height(point1)
- local btn_w = math.floor(panel_w/_col)
- local btn_h = math.floor(panel_h/_row)
- local margin_w, margin_h = (panel_w % _col), (panel_h % _row)
- local margin_left,margin_top = math.floor(margin_w/2), math.floor(margin_h/2)
- local margin_right, margin_bottom = margin_w - margin_left, margin_h - margin_top
- local fgColor = opt.fgColor or colors.white
- local colorRing = function(i) -- make background color pattern
- local array = {colors.blue, colors.lightBlue, colors.cyan}
- if _col%2 == 1 then array = {colors.blue, colors.lightBlue} end
- array = opt.bgPattern or array
- return array[((i-1)%(#array))+1]
- end
- local btns = {}
- local i = 1 -- table index
- local min_y = point0.y
- local max_y = min_y+btn_h-1 + margin_top
- for row=1,_row do
- local min_x = point0.x
- local max_x = min_x+btn_w-1+ margin_left
- for col=1, _col do
- if _bCfg[i] then -- make a button by the button_config
- btns[i] = Button.new(_bCfg[i]["name"], _bCfg[i]["cmd"], min_x, min_y, max_x, max_y, fgColor, colorRing(i))
- else -- make a blank button
- btns[i] = Button.new("--", nil, min_x, min_y, max_x, max_y, fgColor, colorRing(i))
- end
- --calculate next
- i = i+1
- min_x = max_x +1
- max_x = min_x + btn_w-1
- if col==_col-1 then max_x = max_x + margin_right end
- end
- min_y = max_y +1
- max_y = min_y + btn_h-1
- if row==_row-1 then max_y = max_y + margin_bottom end
- end
- return btns
- end
- Panel.new = function(_bCfg, _col, _row, _mon, _opt)
- local opt = _opt or {}
- if _mon.setTextScale then _mon.setTextScale(opt.scale or 0.5) end
- local obj= {}
- obj.col=_col
- obj.row=_row
- obj.total = _col*_row
- obj.mon = _mon
- obj.btns= Panel._makeButtons(_bCfg, _col, _row, _mon, opt)
- return setmetatable(obj,{__index = Panel})
- end
- Panel.pp = function(self)
- print("Panel: ",self.col,'x',self.row)
- print(" Btns: ",#self.btns)
- for i,b in ipairs(self.btns) do
- b:pp()
- end
- end
- Panel.draw = function(self)
- self.mon.setBackgroundColor(colors.gray)
- self.mon.clear()
- for i,b in ipairs(self.btns) do
- b:draw(self.mon)
- end
- end
- Panel.drawPushedButtonEffect = function(self, btn, _sec)
- self.mon.setBackgroundColor(colors.gray)
- self.mon.clear()
- btn:draw(self.mon)
- sleep(_sec or 0.5)
- self:draw()
- end
- Panel.pullButtonPushEvent = function(self, mon_side)
- local pushed_btn = false
- local whichButton = function(btns,x,y)
- for i,b in ipairs(btns) do
- if b:isWithin(Coordinate.new(x,y)) then
- pushed_btn = b
- break
- end
- end
- end
- repeat
- if self.mon.setTextScale then -- when self.mon is advanced_monitor
- local event, side, x, y = os.pullEvent("monitor_touch")
- if not mon_side or mon_side == side then
- whichButton(self.btns, x, y)
- end
- else -- when self.mon is term
- local event, mouse, x, y = os.pullEvent("mouse_click")
- whichButton(self.btns, x, y)
- end
- until pushed_btn
- return "button_push", pushed_btn
- end
- -- ########################
- -- API Functions
- function makePanel(bCnfg, col, row, mon, opt)
- return Panel.new(bCnfg, col, row, mon, opt)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement