-
Notifications
You must be signed in to change notification settings - Fork 0
Creating your own Widget
This is a guide on how to create your own widget for cctinker. This guide assumes you have a basic understanding of how cctinker works.
In this Tutorial we will create a Toggle switch.
First create a function with the like this: function screenObject:widgetName(args)
. This function will be called when you want to create a widget.
Then you can use the _checkArgs
function to check if all required arguments are present. This isn't required, but it is recommended.
function screenObject:toggleSwitch(args)
self:_checkArgs(args, {"x", "y", "text"})
end
The first argument of the _checkArgs()
function is the table of arguments, the second is a table of required arguments. If any of the required arguments are missing, an error will be thrown.
Now you can create the widget. The first thing you should do is create a table for the widget. This table will be used to store the widget's state. You can store anything in this table, but it is recommended to store the widget's position, size and text with the shown names.
The following values are required for a widget to work:
type = "widgetType", -- The type of the widget, this value is required
id = "widgetId", -- The id of the widget, this value is required
x = 1, -- The x position of the widget
y = 1, -- The y position of the widget
width = 1, -- The width of the widget
height = 1, -- The height of the widget
Using this on our example widget, we get the following:
function screen:toggleSwitch(args)
self:_checkArgs(args, {"x", "y", "text"}) -- Error if required args are missing
local switchObject = {
type = "toggleSwitch", -- The type of the widget, this value is required
id = args.id or self:_generateId(), -- The id of the widget, this value is required
x = args.x,
y = args.y,
width = #args.text + 4, -- The width of the widget is the length of the text + 4
height = 1, -- The height of the widget is 1
text = args.text,
color = args.color or colors.white, -- The color of the text, default is white
background = args.background or colors.black, -- The background color, default is black
state = args.state or false, -- The state of the switch, default is off
}
end
Widgets can subscribe to events using functions. The function will be called when the event is emitted.
To subscribe to add one of the following functions to your widget:
Called when the user clicks the mouse on the widget.
Called when the user clicks the mouse on the screen outside the widgetd.
Called when the user scrolls the mouse wheel while the mouse is over the widget.
Called when the user types a character on the keyboard.
Called when a key is pressed.
Called when the user pastes text into the widget.
Meaning If your widget be clicked, you need to add a event_click
function to the widget table. This function will be called with the arguments x, y, button
when the widget is clicked. X and Y beeing the position of the click, and button the mouse button that was clicked.
As our example widget is a toggle switch, we want to change the state when it is clicked. We can do this by changing the state
value in the widget table.
You should also call the callback
function from the arguments, if it is present.
function screen:toggleSwitch(args)
self:_checkArgs(args, {"x", "y", "text"}) -- Error if required args are missing
local switchObject = {
type = "toggleSwitch", -- The type of the widget, this value is required
id = args.id or self:_generateId(), -- The id of the widget, this value is required
x = args.x,
y = args.y,
width = #args.text + 4, -- The width of the widget is the length of the text + 4
height = 1, -- The height of the widget is 1
text = args.text,
color = args.color or colors.white, -- The color of the text, default is white
background = args.background or colors.black, -- The background color, default is black
state = args.state or false, -- The state of the switch, default is off
}
switchObject.event_click = function(x, y, button)
switchObject.state = not switchObject.state -- Toggle the state
if args.callback then
args.callback(x, y, button, switchObject.state) -- Call the callback function if it exists
end
end
end
Now we need to draw the widget. We can do this by adding a draw
function to the widget table.
Not all the normal term functions are available for widgets. The following functions are available:
write(text)
blit(text, textColor, backgroundColor)
getCursorPos() -> x, y
setCursorPos(x, y)
getTextColor() -> color
setTextColor(color)
getBackgroundColor() -> color
setBackgroundColor(color)
The setCursorBlink
function works a bit different from the normal function from the term object, it takes three arguments now: setCursorBlink(blink, x, y)
blink say if the blink is enabled and x, y specifies the position of the blinking cursor.
The functions get called directly on self
like this: self:write("Hello, World!")
function screen:toggleSwitch(args)
self:_checkArgs(args, {"x", "y", "text"}) -- Error if required args are missing
local switchObject = {
type = "toggleSwitch", -- The type of the widget, this value is required
id = args.id or self:_generateId(), -- The id of the widget, this value is required
x = args.x,
y = args.y,
width = #args.text + 4, -- The width of the widget is the length of the text + 4
height = 1, -- The height of the widget is 1
text = args.text,
color = args.color or colors.white, -- The color of the text, default is white
background = args.background or colors.black, -- The background color, default is black
state = args.state or false, -- The state of the switch, default is off
}
switchObject.click = function(x, y, button)
switchObject.state = not switchObject.state -- Toggle the state
if args.callback then
args.callback(x, y, button, switchObject.state) -- Call the callback function if it exists
end
end
switchObject.draw = function()
self.term.setCursorPos(switchObject.x, switchObject.y) -- Set the cursor position to the x and y of the widget
if switchObject.state then -- If the state is true, draw the switch in the on position
self:setTextColor(colors.white)
self:setBackgroundColor(colors.lime)
self:write(" |")
else -- If the state is false, draw the switch in the off position
self:setTextColor(colors.white)
self:setBackgroundColor(colors.red)
self:write("| ")
end
self:setTextColor(switchObject.color)
self:setBackgroundColor(switchObject.background)
self:write(" " .. switchObject.text) -- Draw the text
end
end
Now we need to add the widget to the screen. We can do this by adding the widget table to the screenObjects
table, which stores all currently displayed screenObjects. Then return the widget table.
This is the final code for our widget:
function screen:toggleSwitch(args)
self:_checkArgs(args, {"x", "y", "text"}) -- Error if required args are missing
local switchObject = {
type = "toggleSwitch", -- The type of the widget, this value is required
id = args.id or self:_generateId(), -- The id of the widget, this value is required
x = args.x,
y = args.y,
width = #args.text + 4, -- The width of the widget is the length of the text + 4
height = 1, -- The height of the widget is 1
text = args.text,
color = args.color or colors.white, -- The color of the text, default is white
background = args.background or colors.black, -- The background color, default is black
state = args.state or false, -- The state of the switch, default is off
}
switchObject.click = function(x, y, button)
switchObject.state = not switchObject.state -- Toggle the state
if args.callback then
args.callback(x, y, button, switchObject.state) -- Call the callback function if it exists
end
end
switchObject.draw = function()
self.term.setCursorPos(switchObject.x, switchObject.y) -- Set the cursor position to the x and y of the widget
if switchObject.state then -- If the state is true, draw the switch in the on position
self:setTextColor(colors.white)
self:setBackgroundColor(colors.lime)
self:write(" |")
else -- If the state is false, draw the switch in the off position
self:setTextColor(colors.white)
self:setBackgroundColor(colors.red)
self:write("| ")
end
self:setTextColor(switchObject.color)
self:setBackgroundColor(switchObject.background)
self:write(" " .. switchObject.text) -- Draw the text
end
self.screenObjects[switchObject.id] = switchObject -- Add the widget to the screenObjects table
return switchObject -- Return the widget
end
You can use the widget like any other widget.
local switch = screen:toggleSwitch({x = 1, y = 1, text = "Toggle"})
This is the result:
cctinker is licensed under the MIT LICENSE | © 2023 Loewe_111