dotfiles/.config/lite-xl/libraries/widget/dialog.lua

163 lines
3.3 KiB
Lua

--
-- Dialog object that serves as base to implement other dialogs.
-- @copyright Jefferson Gonzalez
-- @license MIT
--
local core = require "core"
local style = require "core.style"
local Widget = require "libraries.widget"
local Button = require "libraries.widget.button"
local Label = require "libraries.widget.label"
---@class widget.dialog : widget
---@field protected title widget.label
---@field protected close widget.button
---@field protected panel widget
local Dialog = Widget:extend()
---Constructor
---@param title string
function Dialog:new(title)
Dialog.super.new(self)
self.type_name = "widget.dialog"
self.draggable = true
self.scrollable = false
-- minimum width and height
self.size.mx = 400
self.size.my = 150
self.title = Label(self, "")
self.close = Button(self, "")
self.close:set_icon("X")
self.close.border.width = 0
self.close:toggle_background(false)
self.close.padding.x = 4
self.close.padding.y = 0
self.panel = Widget(self)
self.panel.border.width = 0
self.panel.scrollable = true
local this = self
function self.close:on_click()
this:on_close()
this:hide()
end
self:set_title(title or "")
end
---Returns the widget where you can add child widgets to this dialog.
---@return widget
function Dialog:get_panel()
return self.panel
end
---Change the dialog title.
---@param text string|widget.styledtext
function Dialog:set_title(text)
self.title:set_label(text)
end
---Calculate the dialog size, centers it relative to screen and shows it.
function Dialog:show()
Dialog.super.show(self)
self:update()
self:centered()
end
---Called when the user clicks the close button of the dialog.
function Dialog:on_close()
self:hide()
end
function Dialog:update()
if not Dialog.super.update(self) then return false end
local width = math.max(
self.title:get_width() + (style.padding.x * 3) + self.close:get_width(),
self.size.mx,
self.size.x
)
local height = math.max(
self.title:get_height() + (style.padding.y * 3),
self.size.my,
self.size.y
)
self:set_size(width, height)
self.title:set_position(
style.padding.x / 2,
style.padding.y / 2
)
self.close:set_position(
self.size.x - self.close.size.x - (style.padding.x / 2),
style.padding.y / 2
)
self.panel:set_position(
0,
self.title:get_bottom() + (style.padding.y / 2)
)
self.panel:set_size(
self.size.x,
self.size.y - self.title.size.y - style.padding.y
)
return true
end
---We overwrite default draw function to draw the title background.
function Dialog:draw()
if not self:is_visible() then return false end
Dialog.super.draw(self)
self:draw_border()
if self.background_color then
self:draw_background(self.background_color)
else
self:draw_background(
self.parent and style.background or style.background2
)
end
if #self.childs > 0 then
core.push_clip_rect(
self.position.x,
self.position.y,
self.size.x,
self.size.y
)
end
-- draw the title background
renderer.draw_rect(
self.position.x,
self.position.y,
self.size.x, self.title:get_height() + style.padding.y,
style.selection
)
for i=#self.childs, 1, -1 do
self.childs[i]:draw()
end
if #self.childs > 0 then
core.pop_clip_rect()
end
return true
end
return Dialog