141 lines
3.1 KiB
Lua
141 lines
3.1 KiB
Lua
--
|
|
-- CheckBox Widget.
|
|
-- @copyright Jefferson Gonzalez
|
|
-- @license MIT
|
|
--
|
|
|
|
local style = require "core.style"
|
|
local Widget = require "libraries.widget"
|
|
|
|
---@class widget.checkbox : widget
|
|
---@field private checked boolean
|
|
local CheckBox = Widget:extend()
|
|
|
|
---Constructor
|
|
---@param parent widget
|
|
---@param label string
|
|
function CheckBox:new(parent, label)
|
|
CheckBox.super.new(self, parent)
|
|
self.type_name = "widget.checkbox"
|
|
self.checked = false
|
|
self:set_label(label or "")
|
|
self.animating = false
|
|
self.animating_color = style.caret
|
|
end
|
|
|
|
---Set the checkbox label and recalculates the widget size.
|
|
---@param text string
|
|
function CheckBox:set_label(text)
|
|
CheckBox.super.set_label(self, text)
|
|
|
|
local _, _, bw, _ = self:get_box_rect()
|
|
|
|
local font = self:get_font()
|
|
|
|
self.size.x = font:get_width(self.label) + bw + (style.padding.x / 2)
|
|
self.size.y = font:get_height()
|
|
end
|
|
|
|
---Change the status of the checkbox.
|
|
---@param checked boolean
|
|
function CheckBox:set_checked(checked)
|
|
self.checked = checked
|
|
self:on_change(self.checked)
|
|
end
|
|
|
|
---Get the status of the checkbox.
|
|
---@return boolean
|
|
function CheckBox:is_checked()
|
|
return self.checked
|
|
end
|
|
|
|
---Called when the checkbox is (un)checked.
|
|
---@param checked boolean
|
|
function CheckBox:on_checked(checked) end
|
|
|
|
function CheckBox:on_mouse_enter(...)
|
|
CheckBox.super.on_mouse_enter(self, ...)
|
|
self.hover_text = style.accent
|
|
self.hover_back = style.dim
|
|
end
|
|
|
|
function CheckBox:on_mouse_leave(...)
|
|
CheckBox.super.on_mouse_leave(self, ...)
|
|
self.hover_text = nil
|
|
self.hover_back = nil
|
|
end
|
|
|
|
function CheckBox:on_click()
|
|
self.checked = not self.checked
|
|
self:on_checked(self.checked)
|
|
self:on_change(self.checked)
|
|
|
|
self.animating = true
|
|
self.animating_color = {table.unpack(style.caret)}
|
|
local target_color = {table.unpack(style.caret)}
|
|
|
|
if self.checked then
|
|
self.animating_color[4] = 0
|
|
target_color[4] = 255
|
|
else
|
|
self.animating_color[4] = 255
|
|
target_color[4] = 0
|
|
end
|
|
self:animate(self.animating_color, {table.unpack(target_color)}, {
|
|
on_complete = function()
|
|
self.animating = false
|
|
end
|
|
})
|
|
end
|
|
|
|
function CheckBox:get_box_rect()
|
|
local size = 1.6
|
|
local font = self:get_font()
|
|
local fh = font:get_height() / size
|
|
return
|
|
self.position.x,
|
|
self.position.y + (fh / (size * 2)),
|
|
font:get_width("x") + 4,
|
|
fh
|
|
end
|
|
|
|
function CheckBox:update()
|
|
if not CheckBox.super.update(self) then return false end
|
|
|
|
-- update size
|
|
self:set_label(self.label)
|
|
|
|
return true
|
|
end
|
|
|
|
function CheckBox:draw()
|
|
if not self:is_visible() then return false end
|
|
|
|
local bx, by, bw, bh = self:get_box_rect()
|
|
|
|
self:draw_border(bx, by, bw, bh)
|
|
|
|
renderer.draw_rect(
|
|
bx, by, bw, bh,
|
|
self.hover_back or self.background_color or style.background
|
|
)
|
|
|
|
if self.animating then
|
|
renderer.draw_rect(bx + 2, by + 2, bw-4, bh-4, self.animating_color)
|
|
elseif self.checked then
|
|
renderer.draw_rect(bx + 2, by + 2, bw-4, bh-4, style.caret)
|
|
end
|
|
|
|
renderer.draw_text(
|
|
self:get_font(),
|
|
self.label,
|
|
self.position.x + bw + (style.padding.x / 2),
|
|
self.position.y,
|
|
self.hover_text or self.foreground_color or style.text
|
|
)
|
|
|
|
return true
|
|
end
|
|
|
|
|
|
return CheckBox
|