diff --git a/button.lua b/button.lua index 31264a7..90111ca 100644 --- a/button.lua +++ b/button.lua @@ -11,7 +11,9 @@ local expect = require "cc.expect".expect -- DO NOT COPY THIS LINE ---@param fgColor color|nil The color of the button text (defaults to white) ---@param bgColor color|nil The color of the button (defaults to light gray) ---@param clickedColor color|nil The color of the button when clicked (defaults to gray) -function PrimeUI.button(win, x, y, text, action, fgColor, bgColor, clickedColor) +---@param periphName string|nil The name of the monitor peripheral, or nil (set if you're using a monitor - events will be filtered to that monitor) +function PrimeUI.button(win, x, y, text, action, fgColor, bgColor, clickedColor, periphName) + expect(1, win, "table") expect(1, win, "table") expect(2, x, "number") expect(3, y, "number") @@ -20,6 +22,7 @@ function PrimeUI.button(win, x, y, text, action, fgColor, bgColor, clickedColor) fgColor = expect(6, fgColor, "number", "nil") or colors.white bgColor = expect(7, bgColor, "number", "nil") or colors.gray clickedColor = expect(8, clickedColor, "number", "nil") or colors.lightGray + periphName = expect(9, periphName, "string", "nil") -- Draw the initial button. win.setCursorPos(x, y) win.setBackgroundColor(bgColor) @@ -27,11 +30,11 @@ function PrimeUI.button(win, x, y, text, action, fgColor, bgColor, clickedColor) win.write(" " .. text .. " ") -- Get the screen position and add a click handler. PrimeUI.addTask(function() + local screenX, screenY = PrimeUI.getWindowPos(win, x, y) local buttonDown = false while true do local event, button, clickX, clickY = os.pullEvent() - local screenX, screenY = PrimeUI.getWindowPos(win, x, y) - if event == "mouse_click" and button == 1 and clickX >= screenX and clickX < screenX + #text + 2 and clickY == screenY then + if event == "mouse_click" and periphName == nil and button == 1 and clickX >= screenX and clickX < screenX + #text + 2 and clickY == screenY then -- Initiate a click action (but don't trigger until mouse up). buttonDown = true -- Redraw the button with the clicked background color. @@ -39,12 +42,16 @@ function PrimeUI.button(win, x, y, text, action, fgColor, bgColor, clickedColor) win.setBackgroundColor(clickedColor) win.setTextColor(fgColor) win.write(" " .. text .. " ") - elseif event == "mouse_up" and button == 1 and buttonDown then + elseif (event == "monitor_touch" and periphName == button and clickX >= screenX and clickX < screenX + #text + 2 and clickY == screenY) + or (event == "mouse_up" and button == 1 and buttonDown) then -- Finish a click event. if clickX >= screenX and clickX < screenX + #text + 2 and clickY == screenY then -- Trigger the action. - if type(action) == "string" then PrimeUI.resolve("button", action) - else action() end + if type(action) == "string" then + PrimeUI.resolve("button", action) + else + action() + end end -- Redraw the original button state. win.setCursorPos(x, y) @@ -54,4 +61,4 @@ function PrimeUI.button(win, x, y, text, action, fgColor, bgColor, clickedColor) end end end) -end \ No newline at end of file +end diff --git a/clickRegion.lua b/clickRegion.lua new file mode 100644 index 0000000..f212f28 --- /dev/null +++ b/clickRegion.lua @@ -0,0 +1,42 @@ +local PrimeUI = require "util" -- DO NOT COPY THIS LINE +local expect = require "cc.expect".expect -- DO NOT COPY THIS LINE +-- Start copying below this line. -- + +--- Creates a clickable region on screen without any content. +---@param win window The window to draw on +---@param x number The X position of the button +---@param y number The Y position of the button +---@param width number The width of the inner box +---@param height number The height of the inner box +---@param action function|string A function to call when clicked, or a string to send with a `run` event +---@param periphName string|nil The name of the monitor peripheral, or nil (set if you're using a monitor - events will be filtered to that monitor) +function PrimeUI.clickRegion(win, x, y, width, height, action, periphName) + expect(1, win, "table") + expect(2, x, "number") + expect(3, y, "number") + expect(4, width, "number") + expect(5, height, "number") + expect(6, action, "function", "string") + expect(7, periphName, "string", "nil") + PrimeUI.addTask(function() + -- Get the screen position and add a click handler. + local screenX, screenY = PrimeUI.getWindowPos(win, x, y) + local buttonDown = false + while true do + local event, button, clickX, clickY = os.pullEvent() + if (event == "monitor_touch" and periphName == button) + or (event == "mouse_down" and button == 1 and periphName == nil) then + -- Finish a click event. + if clickX >= screenX and clickX < screenX + width + and clickY >= screenY and clickY < screenY + height then + -- Trigger the action. + if type(action) == "string" then + PrimeUI.resolve("clickRegion", action) + else + action() + end + end + end + end + end) +end