SHOW:
|
|
- or go back to the newest paste.
1 | --[[ | |
2 | The MIT License (MIT) | |
3 | ||
4 | Copyright (c) 2013 Lyqyd | |
5 | ||
6 | Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | of this software and associated documentation files (the "Software"), to deal | |
8 | in the Software without restriction, including without limitation the rights | |
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | copies of the Software, and to permit persons to whom the Software is | |
11 | furnished to do so, subject to the following conditions: | |
12 | ||
13 | The above copyright notice and this permission notice shall be included in | |
14 | all copies or substantial portions of the Software. | |
15 | ||
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | THE SOFTWARE. | |
23 | --]] | |
24 | ||
25 | local function setupLabel(buttonLen, minY, maxY, name) | |
26 | local labelTable = {} | |
27 | if type(name) == "table" then | |
28 | for i = 1, #name do | |
29 | labelTable[i] = name[i] | |
30 | end | |
31 | name = name.label | |
32 | elseif type(name) == "string" then | |
33 | local buttonText = string.sub(name, 1, buttonLen - 2) | |
34 | if #buttonText < #name then | |
35 | buttonText = " "..buttonText.." " | |
36 | else | |
37 | local labelLine = string.rep(" ", math.floor((buttonLen - #buttonText) / 2))..buttonText | |
38 | buttonText = labelLine..string.rep(" ", buttonLen - #labelLine) | |
39 | end | |
40 | for i = 1, maxY - minY + 1 do | |
41 | if maxY == minY or i == math.floor((maxY - minY) / 2) + 1 then | |
42 | labelTable[i] = buttonText | |
43 | else | |
44 | labelTable[i] = string.rep(" ", buttonLen) | |
45 | end | |
46 | end | |
47 | end | |
48 | return labelTable, name | |
49 | end | |
50 | ||
51 | local Button = { | |
52 | draw = function(self) | |
53 | local old = term.redirect(self.mon) | |
54 | term.setTextColor(colors.white) | |
55 | term.setBackgroundColor(colors.black) | |
56 | term.clear() | |
57 | for name, buttonData in pairs(self.buttonList) do | |
58 | if buttonData.active then | |
59 | term.setBackgroundColor(buttonData.activeColor) | |
60 | term.setTextColor(buttonData.activeText) | |
61 | else | |
62 | term.setBackgroundColor(buttonData.inactiveColor) | |
63 | term.setTextColor(buttonData.inactiveText) | |
64 | end | |
65 | for i = buttonData.yMin, buttonData.yMax do | |
66 | term.setCursorPos(buttonData.xMin, i) | |
67 | term.write(buttonData.label[i - buttonData.yMin + 1]) | |
68 | end | |
69 | end | |
70 | if old then | |
71 | term.redirect(old) | |
72 | else | |
73 | term.restore() | |
74 | end | |
75 | end, | |
76 | add = function(self, name, func, xMin, yMin, xMax, yMax, inactiveColor, activeColor, inactiveText, activeText) | |
77 | local label, name = setupLabel(xMax - xMin + 1, yMin, yMax, name) | |
78 | if self.buttonList[name] then error("button already exists", 2) end | |
79 | local x, y = self.mon.getSize() | |
80 | if xMin < 1 or yMin < 1 or xMax > x or yMax > y then error("button out of bounds", 2) end | |
81 | self.buttonList[name] = { | |
82 | func = func, | |
83 | xMin = xMin, | |
84 | yMin = yMin, | |
85 | xMax = xMax, | |
86 | yMax = yMax, | |
87 | active = false, | |
88 | inactiveColor = inactiveColor or colors.red, | |
89 | activeColor = activeColor or colors.lime, | |
90 | inactiveText = inactiveText or colors.white, | |
91 | activeText = activeText or colors.white, | |
92 | label = label, | |
93 | } | |
94 | for i = xMin, xMax do | |
95 | for j = yMin, yMax do | |
96 | if self.clickMap[i][j] ~= nil then | |
97 | --undo changes | |
98 | for k = xMin, xMax do | |
99 | for l = yMin, yMax do | |
100 | if self.clickMap[k][l] == name then | |
101 | self.clickMap[k][l] = nil | |
102 | end | |
103 | end | |
104 | end | |
105 | self.buttonList[name] = nil | |
106 | error("overlapping button", 2) | |
107 | end | |
108 | self.clickMap[i][j] = name | |
109 | end | |
110 | end | |
111 | end, | |
112 | remove = function(self, name) | |
113 | if self.buttonList[name] then | |
114 | local button = self.buttonList[name] | |
115 | for i = button.xMin, button.xMax do | |
116 | for j = button.yMin, button.yMax do | |
117 | self.clickMap[i][j] = nil | |
118 | end | |
119 | end | |
120 | self.buttonList[name] = nil | |
121 | end | |
122 | end, | |
123 | run = function(self) | |
124 | while true do | |
125 | self:draw() | |
126 | local event = {self:handleEvents(os.pullEvent(self.side == "term" and "mouse_click" or "monitor_touch"))} | |
127 | if event[1] == "button_click" then | |
128 | self.buttonList[event[2]].func() | |
129 | end | |
130 | end | |
131 | end, | |
132 | handleEvents = function(self, ...) | |
133 | local event = {...} | |
134 | if #event == 0 then event = {os.pullEvent()} end | |
135 | if (self.side == "term" and event[1] == "mouse_click") or (self.side ~= "term" and event[1] == "monitor_touch" and event[2] == self.side) then | |
136 | local clicked = self.clickMap[event[3]][event[4]] | |
137 | if clicked and self.buttonList[clicked] then | |
138 | return "button_click", clicked | |
139 | end | |
140 | end | |
141 | return unpack(event) | |
142 | end, | |
143 | toggleButton = function(self, name, noDraw) | |
144 | self.buttonList[name].active = not self.buttonList[name].active | |
145 | if not noDraw then self:draw() end | |
146 | end, | |
147 | setActive = function(self, name, noDraw) | |
148 | self.buttonList[name].active = true | |
149 | if not noDraw then self:draw() end | |
150 | end, | |
151 | setInactive = function(self, name, noDraw) | |
152 | self.buttonList[name].active = false | |
153 | if not noDraw then self:draw() end | |
154 | end, | |
155 | flash = function(self, name, duration) | |
156 | self:toggleButton(name) | |
157 | sleep(tonumber(duration) or 0.15) | |
158 | self:toggleButton(name) | |
159 | end, | |
160 | rename = function(self, name, newName) | |
161 | self.buttonList[name].label, newName = setupLabel(self.buttonList[name].xMax - self.buttonList[name].xMin + 1, self.buttonList[name].yMin, self.buttonList[name].yMax, newName) | |
162 | if not self.buttonList[name] then error("no such button", 2) end | |
163 | if name ~= newName then | |
164 | self.buttonList[newName] = self.buttonList[name] | |
165 | self.buttonList[name] = nil | |
166 | for i = self.buttonList[newName].xMin, self.buttonList[newName].xMax do | |
167 | for j = self.buttonList[newName].yMin, self.buttonList[newName].yMax do | |
168 | self.clickMap[i][j] = newName | |
169 | end | |
170 | end | |
171 | end | |
172 | self:draw() | |
173 | end, | |
174 | getState = function(self, name) | |
175 | - | function new(monSide) |
175 | + | |
176 | end, | |
177 | clear = function(self) | |
178 | self.mon.setBackgroundColor(colors.black) | |
179 | self.mon.clear() | |
180 | end, | |
181 | } | |
182 | ||
183 | function new(monSide, textScale) | |
184 | local buttonInstance = { | |
185 | side = monSide or "term", | |
186 | mon = monSide and peripheral.wrap(monSide) or term.current(), | |
187 | buttonList = {}, | |
188 | clickMap = {}, | |
189 | } | |
190 | if monSide ~= nil and textScale ~= nil then | |
191 | buttonInstance.mon.setTextScale(textScale) | |
192 | end | |
193 | local x, y = buttonInstance.mon.getSize() | |
194 | for i = 1, x do | |
195 | buttonInstance.clickMap[i] = {} | |
196 | end | |
197 | setmetatable(buttonInstance, {__index = Button}) | |
198 | return buttonInstance | |
199 | end |