From cf940df32d173221c275c94d414b48054b54aa05 Mon Sep 17 00:00:00 2001 From: Zooka <136661366+ZookaOnGit@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:59:26 +0700 Subject: [PATCH 1/3] Create RadioButton.lua Initial creation with no label at the moment. - getSelected() - setSelected(int) - takes an amount of radio buttons you want to create with variable `amount`, defaults to 2 --- src/resources/RadioButton.lua | 175 ++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/resources/RadioButton.lua diff --git a/src/resources/RadioButton.lua b/src/resources/RadioButton.lua new file mode 100644 index 0000000..6998163 --- /dev/null +++ b/src/resources/RadioButton.lua @@ -0,0 +1,175 @@ +local RadioButton = { + parent = Geyser.Container, + name = 'RadioButtonClass', + radioButtonLocation = "https://demonnic.github.io/image-assets/radio-button.png", + radioButtonSelectedLocation = "https://demonnic.github.io/image-assets/radio-button-selected.png", + selected = 0, + amount = 2, + buttons = {} +} + +RadioButton.__index = RadioButton +setmetatable(RadioButton, RadioButton.parent) + +local directory = getMudletHomeDir() .. "/radiobutton/" +local saveFile = directory .. "fileLocations.lua" +if not io.exists(directory) then + lfs.mkdir(directory) +end + + +function RadioButton:new(cons, container) + cons = cons or {} + local consType = type(cons) + if consType ~= "table" then + printError(f"RadioButton:new(cons, container): cons as table of options expected, got {consType}!", true, true) + end + cons.name = cons.name or Geyser.nameGen("RadioButton") + RadioButton.amount = cons.amount or 2 + local me = self.parent:new(cons, container) + setmetatable(me, self) + me:createComponents() + return me +end + + +function RadioButton:createDisplay() + + local vboxContainer = Geyser.Container:new({ x = 0, y = 0, + width = "100%", + height = "100%" + }, self) + + for i = 1,RadioButton.amount do + + RadioButton.buttons[i] = Geyser.Button:new({ + name = "Radio" .. i, + x = 0, + y = (i-1)*25, + width = 25, + height = 25, + color = "white", + style = "background-color: white; border-image: url("..self.radioButtonFile..");", + msg = "", + tooltip = "", + clickFunction = function() self:setSelected(i) end, + twoState = false, + state = "up", + toolTipDuration = 0 + }, vboxContainer) + end + +end + + +function RadioButton:createComponents() + + self:obtainImages() + self:createDisplay() + +end + + +function RadioButton:obtainImages() + local locations = self:getFileLocs() + local radioButtonURL = self.radioButtonLocation + local radioButtonSelectedURL = self.radioButtonSelectedLocation + local radioButtonFile = locations[radioButtonURL] + local radioButtonSelectedFile = locations[radioButtonSelectedURL] + local locationsChanged = false + if not (radioButtonFile and io.exists(radioButtonFile)) then + if not radioButtonFile then + radioButtonFile = directory .. self.name .. "/radio-button.png" + locations[radioButtonURL] = radioButtonFile + locationsChanged = true + end + if radioButtonURL:match("^http") then + self:downloadFile(radioButtonURL, radioButtonFile) + elseif io.exists(radioButtonURL) then + radioButtonFile = radioButtonURL + locations[radioButtonURL] = radioButtonFile + locationsChanged = true + end + end + if not (radioButtonSelectedFile and io.exists(radioButtonSelectedFile)) then + if not radioButtonSelectedFile then + radioButtonSelectedFile = directory .. self.name .. "/radio-button-selected.png" + locations[radioButtonSelectedURL] = radioButtonSelectedFile + locationsChanged = true + end + if radioButtonSelectedURL:match("^http") then + self:downloadFile(radioButtonSelectedURL, radioButtonSelectedFile) + elseif io.exists(radioButtonSelectedURL) then + radioButtonSelectedFile = radioButtonSelectedURL + locations[radioButtonSelectedURL] = radioButtonSelectedFile + locationsChanged = true + end + end + self.radioButtonFile = radioButtonFile + self.radioButtonSelectedFile = radioButtonSelectedFile + if locationsChanged then + table.save(saveFile, locations) + end +end + + +function RadioButton:downloadFile(url, fileName) + local parts = fileName:split("/") + parts[#parts] = nil + local dirName = table.concat(parts, "/") .. "/" + if not io.exists(dirName) then + lfs.mkdir(dirName) + end + local uname = "radiobutton" + local handlerName = self.name .. url + local handler = function(event, ...) + local args = {...} + local file = #args == 1 and args[1] or args[2] + if file ~= fileName then + return true + end + if event == "sysDownloadDone" then + debugc(f"INFO:RadioButton successfully downloaded {file}") + stopNamedEventHandler(uname, handlerName .. "error") + return false + end + cecho(f"\nERROR:RadioButton had an issue downloading an image file to {file}: {args[1]}\n") + stopNamedEventHandler(uname, handlerName .. "done") + end + registerNamedEventHandler(uname, handlerName .. "done", "sysDownloadDone", handler, true) + registerNamedEventHandler(uname, handlerName .. "error", "sysDownloadError", handler, true) + downloadFile(fileName, url) +end + + +function RadioButton:getFileLocs() + local locations = {} + if io.exists(saveFile) then + table.load(saveFile, locations) + end + return locations +end + +function RadioButton:setSelected(clicked) + + -- set all buttons unselected + for i = 1,#RadioButton.buttons do + RadioButton.buttons[i]:setStyle("background-color: white; border-image: url(".. self.radioButtonFile ..");") + end + + -- then set the appropriate one + RadioButton.buttons[clicked]:setStyle("background-color: white; border-image: url(".. self.radioButtonSelectedFile ..");") + RadioButton.selected = clicked + + echo("DEBUG: " .. RadioButton.selected .. " selected\n") + +end + +function RadioButton:getSelected() + + return RadioButton.selected + +end + + +return RadioButton From b8e12cf636512c823c714686895c1d509e0433c8 Mon Sep 17 00:00:00 2001 From: Zooka <136661366+ZookaOnGit@users.noreply.github.com> Date: Sun, 14 Jan 2024 04:45:04 +0700 Subject: [PATCH 2/3] Add label support to RadioButton - pass label messages in constructor - setLabels() function --- src/resources/RadioButton.lua | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/resources/RadioButton.lua b/src/resources/RadioButton.lua index 6998163..50de0ce 100644 --- a/src/resources/RadioButton.lua +++ b/src/resources/RadioButton.lua @@ -5,7 +5,9 @@ local RadioButton = { radioButtonSelectedLocation = "https://demonnic.github.io/image-assets/radio-button-selected.png", selected = 0, amount = 2, - buttons = {} + buttons = {}, + labels = {}, + labelMessages = {} } RadioButton.__index = RadioButton @@ -26,6 +28,7 @@ function RadioButton:new(cons, container) end cons.name = cons.name or Geyser.nameGen("RadioButton") RadioButton.amount = cons.amount or 2 + RadioButton.labelMessages = cons.labelMessages or {"Label 1", "Label 2"} local me = self.parent:new(cons, container) setmetatable(me, self) me:createComponents() @@ -35,13 +38,26 @@ end function RadioButton:createDisplay() - local vboxContainer = Geyser.Container:new({ x = 0, y = 0, - width = "100%", + + local labelContainer = Geyser.VBox:new({ x = 0, y = 0, + width = "100%-25px", + height = "100%" + }, self) + + local buttonContainer = Geyser.VBox:new({ x = "-25r", y = 0, + width = "25px", height = "100%" }, self) for i = 1,RadioButton.amount do + RadioButton.labels[i] = Geyser.Label:new({ + name = "RadioLabel" .. i, + message = RadioButton.labelMessages[i], + color = "white", + fgColor = "black" + }, labelContainer) + RadioButton.buttons[i] = Geyser.Button:new({ name = "Radio" .. i, x = 0, @@ -56,7 +72,7 @@ function RadioButton:createDisplay() twoState = false, state = "up", toolTipDuration = 0 - }, vboxContainer) + }, buttonContainer) end end @@ -171,5 +187,14 @@ function RadioButton:getSelected() end +function RadioButton:setLabels(labelMessages) + + RadioButton.labelMessages = labelMessages + for i = 1, RadioButton.amount do + RadioButton.labels[i]:echo(RadioButton.labelMessages[i]) + end + +end + return RadioButton From b0c44dde9a49e8b61aba2e514204fe3d902be3ba Mon Sep 17 00:00:00 2001 From: Zooka <136661366+ZookaOnGit@users.noreply.github.com> Date: Sat, 3 Feb 2024 14:11:58 +0700 Subject: [PATCH 3/3] Update RadioButton.lua add lua documentation --- src/resources/RadioButton.lua | 66 +++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/src/resources/RadioButton.lua b/src/resources/RadioButton.lua index 50de0ce..a6aaa11 100644 --- a/src/resources/RadioButton.lua +++ b/src/resources/RadioButton.lua @@ -1,3 +1,6 @@ +--- A Geyser object to create a single selection radiobox +-- @classmod RadioButton +-- @author Zooka local RadioButton = { parent = Geyser.Container, name = 'RadioButtonClass', @@ -19,7 +22,30 @@ if not io.exists(directory) then lfs.mkdir(directory) end - +--- Creates a new radio button. +-- @tparam table cons a table containing the options for this radiobutton. +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +--
option namedescriptiondefault
amountThe amount of buttons in this radio button.2
labelMessagesThe text to assign to a specific button. Should be equals to the amount of buttons.{"Label 1", "Label 2"}
+-- @param container The Geyser container for this checkbox function RadioButton:new(cons, container) cons = cons or {} local consType = type(cons) @@ -36,6 +62,10 @@ function RadioButton:new(cons, container) end +--- Create the radiobutton components. +-- @local +-- Creates self.labels[] to hold a display messages. +-- Creates self.buttons[], an amount of Geyser.Buttons with a true/false state. function RadioButton:createDisplay() @@ -78,6 +108,11 @@ function RadioButton:createDisplay() end +--- Creates the components that make up the radiobutton UI. +-- @local +-- Obtains the radiobutton images. +-- Generate white styling for the radiobutton. +-- @todo user generated CSS styling function RadioButton:createComponents() self:obtainImages() @@ -86,6 +121,15 @@ function RadioButton:createComponents() end +--- Obtains the selected and unselected images for the radiobutton. +-- @local +-- Gets the previously saved file locations. +-- Checks if the selected image exists at the radioButtonSelectedLocation. +-- If not, it will download the image from a URL or copy a local file. It saves +-- the new location. +-- Does the same for the unselected image at the radioButtonLocation. +-- Saves any new locations to the save file. +-- Sets self.radioButtonFile and self.radioButtonSelectedFile to the locations of the images. function RadioButton:obtainImages() local locations = self:getFileLocs() local radioButtonURL = self.radioButtonLocation @@ -129,6 +173,15 @@ function RadioButton:obtainImages() end +--- Handles the actual download of a file from a url +-- @param url The url to download the file from +-- @param fileName The location to save the downloaded file +-- @local +-- Creates any missing directories in the file path. +-- Registers named event handlers to handle the download completing or erroring. +-- The completion handler stops the error handler. +-- The error handler prints an error message and stops the completion handler. +-- Downloads the file from the url to the fileName location. function RadioButton:downloadFile(url, fileName) local parts = fileName:split("/") parts[#parts] = nil @@ -158,6 +211,8 @@ function RadioButton:downloadFile(url, fileName) end +--- Responsible for reading the file locations from disk and returning them +-- @local function RadioButton:getFileLocs() local locations = {} if io.exists(saveFile) then @@ -166,6 +221,9 @@ function RadioButton:getFileLocs() return locations end + +--- Set the state of the radiobutton. +-- @param clicked integer, the button position number as referenced in the constructor function RadioButton:setSelected(clicked) -- set all buttons unselected @@ -177,16 +235,20 @@ function RadioButton:setSelected(clicked) RadioButton.buttons[clicked]:setStyle("background-color: white; border-image: url(".. self.radioButtonSelectedFile ..");") RadioButton.selected = clicked - echo("DEBUG: " .. RadioButton.selected .. " selected\n") +-- echo("DEBUG: " .. RadioButton.selected .. " selected\n") end +--- Return which button is selected +-- @return the integer of the button currently selected function RadioButton:getSelected() return RadioButton.selected end +--- Set the labels of the buttons to new ones. +-- @param labelMessages table of strings containing the messages function RadioButton:setLabels(labelMessages) RadioButton.labelMessages = labelMessages