· 8 years ago · Nov 20, 2017, 09:10 AM
1--Copy by Labamichnetvoll
2-- Modified from the Touchpoint API by Lyqyd as posted on the following URL
3-- http://www.computercraft.info/forums2/index.php?/topic/14784-touchpoint-api/
4-- Added a feature to create hollow boxes to the API
5
6
7local function setupLabel(buttonLen, minY, maxY, name)
8 local labelTable = {}
9 if type(name) == "table" then
10 for i = 1, #name do
11 labelTable[i] = name[i]
12 end
13 name = name.label
14 elseif type(name) == "string" then
15 local buttonText = string.sub(name, 1, buttonLen - 2)
16 if #buttonText < #name then
17 buttonText = " "..buttonText.." "
18 else
19 local labelLine = string.rep(" ", math.floor((buttonLen - #buttonText) / 2))..buttonText
20 buttonText = labelLine..string.rep(" ", buttonLen - #labelLine)
21 end
22 for i = 1, maxY - minY + 1 do
23 if maxY == minY or i == math.floor((maxY - minY) / 2) + 1 then
24 labelTable[i] = buttonText
25 else
26 labelTable[i] = string.rep(" ", buttonLen)
27 end
28 end
29 end
30 return labelTable, name
31end
32
33local Button = {
34 draw = function(self)
35 local old = term.redirect(self.mon)
36 term.setTextColor(colors.white)
37 term.setBackgroundColor(colors.black)
38 for name, boxData in pairs(self.boxList) do
39 term.setBackgroundColor(boxData.bgColor)
40 term.setTextColor(boxData.color)
41 local EndX = boxData.xStart + boxData.xSize - 1
42 local EndY = boxData.yStart + boxData.ySize - 1
43 term.setCursorPos(boxData.xStart, boxData.yStart)
44 term.write(string.rep(" ", boxData.xSize-1))
45 term.setCursorPos(boxData.xStart, EndY)
46 term.write(string.rep(" ", boxData.xSize-1))
47 for i = boxData.yStart, EndY do
48 term.setCursorPos(boxData.xStart, i)
49 term.write(" ")
50 term.setCursorPos(EndX, i)
51 term.write(" ")
52 end
53 end
54 for name, buttonData in pairs(self.buttonList) do
55 if buttonData.active then
56 term.setBackgroundColor(buttonData.activeColor)
57 term.setTextColor(buttonData.activeText)
58 else
59 term.setBackgroundColor(buttonData.inactiveColor)
60 term.setTextColor(buttonData.inactiveText)
61 end
62 for i = buttonData.yMin, buttonData.yMax do
63 term.setCursorPos(buttonData.xMin, i)
64 term.write(buttonData.label[i - buttonData.yMin + 1])
65 end
66 end
67 if old then
68 term.redirect(old)
69 else
70 term.restore()
71 end
72 end,
73 add = function(self, name, func, xMin, yMin, xMax, yMax, inactiveColor, activeColor, inactiveText, activeText)
74 local label, name = setupLabel(xMax - xMin + 1, yMin, yMax, name)
75 if self.buttonList[name] then error("button "..name.." already exists", 2) end
76 local x, y = self.mon.getSize()
77 if xMin < 1 or yMin < 1 or xMax > x or yMax > y then error("button "..name.." out of bounds", 2) end
78 self.buttonList[name] = {
79 func = func,
80 xMin = xMin,
81 yMin = yMin,
82 xMax = xMax,
83 yMax = yMax,
84 active = false,
85 inactiveColor = inactiveColor or colors.red,
86 activeColor = activeColor or colors.lime,
87 inactiveText = inactiveText or colors.white,
88 activeText = activeText or colors.white,
89 label = label,
90 }
91 for i = xMin, xMax do
92 for j = yMin, yMax do
93 if self.clickMap[i][j] ~= nil then
94 --undo changes
95 for k = xMin, xMax do
96 for l = yMin, yMax do
97 if self.clickMap[k][l] == name then
98 self.clickMap[k][l] = nil
99 end
100 end
101 end
102 self.buttonList[name] = nil
103 error("overlapping button", 2)
104 end
105 self.clickMap[i][j] = name
106 end
107 end
108 end,
109 addBox = function(self, name, xStart, xSize, yStart, ySize, color, bgColor)
110 if self.boxList[name] then error("Box "..name.." already exists", 2) end
111 local x, y = self.mon.getSize()
112 if xStart < 1 or yStart < 1 or xStart+xSize-1 > x or yStart+ySize-1 > y then error("Box "..name.." out of bounds", 2) end
113 self.boxList[name] = {
114 xStart = xStart,
115 yStart = yStart,
116 xSize = xSize,
117 ySize = ySize,
118 color = color,
119 bgColor = bgColor,
120 }
121 end,
122 remove = function(self, name)
123 if self.buttonList[name] then
124 local button = self.buttonList[name]
125 for i = button.xMin, button.xMax do
126 for j = button.yMin, button.yMax do
127 self.clickMap[i][j] = nil
128 end
129 end
130 self.buttonList[name] = nil
131 end
132 end,
133 removeBox = function(self, name)
134 if self.boxList[name] then
135 self.boxList[name] = nil
136 end
137 end,
138 run = function(self)
139 while true do
140 self:draw()
141 local event = {self:handleEvents(os.pullEvent(self.side == "term" and "mouse_click" or "monitor_touch"))}
142 if event[1] == "button_click" then
143 self.buttonList[event[2]].func()
144 end
145 end
146 end,
147 handleEvents = function(self, ...)
148 local event = {...}
149 if #event == 0 then event = {os.pullEvent()} end
150 if (self.side == "term" and event[1] == "mouse_click") or (self.side ~= "term" and event[1] == "monitor_touch" and event[2] == self.side) then
151 local clicked = self.clickMap[event[3]][event[4]]
152 if clicked and self.buttonList[clicked] then
153 return "button_click", clicked
154 end
155 end
156 return unpack(event)
157 end,
158 toggleButton = function(self, name, noDraw)
159 self.buttonList[name].active = not self.buttonList[name].active
160 if not noDraw then self:draw() end
161 end,
162 flash = function(self, name, duration)
163 self:toggleButton(name)
164 sleep(tonumber(duration) or 0.15)
165 self:toggleButton(name)
166 end,
167 rename = function(self, name, newName)
168 self.buttonList[name].label, newName = setupLabel(self.buttonList[name].xMax - self.buttonList[name].xMin + 1, self.buttonList[name].yMin, self.buttonList[name].yMax, newName)
169 if not self.buttonList[name] then error("no such button", 2) end
170 if name ~= newName then
171 self.buttonList[newName] = self.buttonList[name]
172 self.buttonList[name] = nil
173 for i = self.buttonList[newName].xMin, self.buttonList[newName].xMax do
174 for j = self.buttonList[newName].yMin, self.buttonList[newName].yMax do
175 self.clickMap[i][j] = newName
176 end
177 end
178 end
179 self:draw()
180 end,
181}
182
183function new(monSide)
184 local buttonInstance = {
185 side = monSide or "term",
186 mon = monSide and peripheral.wrap(monSide) or term.current(),
187 buttonList = {},
188 boxList = {},
189 clickMap = {},
190 }
191 local x, y = buttonInstance.mon.getSize()
192 for i = 1, x do
193 buttonInstance.clickMap[i] = {}
194 end
195 setmetatable(buttonInstance, {__index = Button})
196 return buttonInstance
197end