Initial commit
This commit is contained in:
commit
209ba130c0
4852 changed files with 1517959 additions and 0 deletions
269
.config/lite-xl/libraries/widget/selectbox.lua
Normal file
269
.config/lite-xl/libraries/widget/selectbox.lua
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
--
|
||||
-- SelectBox Widget.
|
||||
-- @copyright Jefferson Gonzalez
|
||||
-- @license MIT
|
||||
--
|
||||
|
||||
local common = require "core.common"
|
||||
local style = require "core.style"
|
||||
local Widget = require "libraries.widget"
|
||||
local ListBox = require "libraries.widget.listbox"
|
||||
|
||||
---@class widget.selectbox : widget
|
||||
---@field private list_container widget
|
||||
---@field private list widget.listbox
|
||||
---@field private selected integer
|
||||
---@field private hover_text renderer.color
|
||||
local SelectBox = Widget:extend()
|
||||
|
||||
---Constructor
|
||||
---@param parent widget
|
||||
---@param label string
|
||||
function SelectBox:new(parent, label)
|
||||
SelectBox.super.new(self, parent)
|
||||
self.type_name = "widget.selectbox"
|
||||
self.size.x = 200 + (style.padding.x * 2)
|
||||
self.size.y = self:get_font():get_height() + (style.padding.y * 2)
|
||||
self.list_container = Widget()
|
||||
self.list_container:set_size(
|
||||
self.size.x - self.list_container.border.width,
|
||||
150
|
||||
)
|
||||
self.list = ListBox(self.list_container)
|
||||
self.list.border.width = 0
|
||||
self.list:enable_expand(true)
|
||||
self.selected = 0
|
||||
|
||||
local list_on_row_click = self.list.on_row_click
|
||||
self.list.on_row_click = function(this, idx, data)
|
||||
list_on_row_click(this, idx, data)
|
||||
if idx ~= 1 then
|
||||
self.selected = idx-1
|
||||
self:on_selected(idx-1, data)
|
||||
self:on_change(self.selected)
|
||||
end
|
||||
self.list_container:hide_animated(true)
|
||||
end
|
||||
|
||||
self:set_label(label or "select")
|
||||
end
|
||||
|
||||
---Set the text displayed when no item is selected.
|
||||
---@param text string
|
||||
function SelectBox:set_label(text)
|
||||
SelectBox.super.set_label(self, "- "..text.." -")
|
||||
if not self.list.rows[1] then
|
||||
self.list:add_row({"- "..text.." -"})
|
||||
else
|
||||
self.list.rows[1][1] = "- "..text.." -"
|
||||
end
|
||||
end
|
||||
|
||||
---Add selectable option to the selectbox.
|
||||
---@param text widget.styledtext|string
|
||||
---@param data any
|
||||
function SelectBox:add_option(text, data)
|
||||
if type(text) == "string" then
|
||||
self.list:add_row({ text }, data)
|
||||
else
|
||||
self.list:add_row(text, data)
|
||||
end
|
||||
end
|
||||
|
||||
---Check if a text is longer than the given maximum width and if larger returns
|
||||
---a chopped version with the overflow_chars appended to it.
|
||||
---@param text string
|
||||
---@param max_width number
|
||||
---@param font widget.font Default is style.font
|
||||
---@param overflow_chars? string Default is '...'
|
||||
---@return string chopped_text
|
||||
---@return boolean overflows True if the text overflows
|
||||
function SelectBox:text_overflow(text, max_width, font, overflow_chars)
|
||||
font = self:get_font(font)
|
||||
overflow_chars = overflow_chars or "..."
|
||||
|
||||
local overflow = false
|
||||
local overflow_chars_width = font:get_width(overflow_chars)
|
||||
|
||||
if font:get_width(text) > max_width then
|
||||
overflow = true
|
||||
for i = 1, #text do
|
||||
local reduced_text = text:sub(1, #text - i)
|
||||
if
|
||||
font:get_width(reduced_text) + overflow_chars_width
|
||||
<=
|
||||
max_width
|
||||
then
|
||||
text = reduced_text .. "…"
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return text, overflow
|
||||
end
|
||||
|
||||
---Set the active option index.
|
||||
---@param idx integer
|
||||
function SelectBox:set_selected(idx)
|
||||
if self.list.rows[idx+1] then
|
||||
self.selected = idx
|
||||
self.list:set_selected(idx+1)
|
||||
else
|
||||
self.selected = 0
|
||||
self.list:set_selected()
|
||||
end
|
||||
self:on_change(self.selected)
|
||||
end
|
||||
|
||||
---Get the currently selected option index.
|
||||
---@return integer
|
||||
function SelectBox:get_selected()
|
||||
return self.selected
|
||||
end
|
||||
|
||||
---Get the currently selected option text.
|
||||
---@return string|nil
|
||||
function SelectBox:get_selected_text()
|
||||
if self.selected > 0 then
|
||||
return self.list:get_row_text(self.selected + 1)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get the currently selected option associated data.
|
||||
---@return any|nil
|
||||
function SelectBox:get_selected_data()
|
||||
if self.selected > 0 then
|
||||
return self.list:get_row_data(self.selected + 1)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Repositions the listbox container according to the selectbox position
|
||||
---and available screensize.
|
||||
function SelectBox:reposition_container()
|
||||
local y1 = self.position.y + self:get_height()
|
||||
local y2 = self.position.y - self.list:get_height()
|
||||
|
||||
local _, h = system.get_window_size()
|
||||
|
||||
if y1 + self.list:get_height() <= h then
|
||||
self.list_container:set_position(
|
||||
self.position.x,
|
||||
y1
|
||||
)
|
||||
else
|
||||
self.list_container:set_position(
|
||||
self.position.x,
|
||||
y2
|
||||
)
|
||||
end
|
||||
|
||||
self.list_container.size.x = self.size.x - (self.border.width * 2)
|
||||
end
|
||||
|
||||
---Overrided to destroy the floating listbox container.
|
||||
function SelectBox:destroy_childs()
|
||||
SelectBox.super.destroy_childs(self)
|
||||
self.list_container:destroy()
|
||||
end
|
||||
|
||||
--
|
||||
-- Events
|
||||
--
|
||||
|
||||
---Overwrite to listen to on_selected events.
|
||||
---@param item_idx integer
|
||||
---@param item_data widget.listbox.row
|
||||
---@diagnostic disable-next-line
|
||||
function SelectBox:on_selected(item_idx, item_data) end
|
||||
|
||||
function SelectBox:on_mouse_enter(...)
|
||||
SelectBox.super.on_mouse_enter(self, ...)
|
||||
self.hover_text = style.accent
|
||||
end
|
||||
|
||||
function SelectBox:on_mouse_leave(...)
|
||||
SelectBox.super.on_mouse_leave(self, ...)
|
||||
self.hover_text = nil
|
||||
end
|
||||
|
||||
function SelectBox:on_click(button, x, y)
|
||||
SelectBox.super.on_click(self, button, x, y)
|
||||
|
||||
if button == "left" then
|
||||
self:reposition_container()
|
||||
|
||||
self.list_container.border.color = style.caret
|
||||
|
||||
self.list_container:toggle_visible(true, true)
|
||||
|
||||
self.list:resize_to_parent()
|
||||
end
|
||||
end
|
||||
|
||||
function SelectBox:update()
|
||||
if not SelectBox.super.update(self) then return false end
|
||||
|
||||
local font = self:get_font()
|
||||
|
||||
self.size.y = font:get_height() + style.padding.y * 2
|
||||
|
||||
if
|
||||
self.list_container.visible
|
||||
and
|
||||
self.list_container.position.y ~= self.position.y + self:get_height()
|
||||
then
|
||||
self:reposition_container()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SelectBox:draw()
|
||||
if not SelectBox.super.draw(self) then return false end
|
||||
|
||||
local font = self:get_font()
|
||||
|
||||
local icon_width = style.icon_font:get_width("+")
|
||||
|
||||
local max_width = self.size.x
|
||||
- icon_width
|
||||
- (style.padding.x * 2) -- left/right paddings
|
||||
- (style.padding.x / 2) -- space between icon and text
|
||||
|
||||
local item_text = self.selected == 0 and
|
||||
self.label or self.list:get_row_text(self.selected+1)
|
||||
|
||||
local text = self:text_overflow(item_text, max_width, font)
|
||||
|
||||
-- draw label or selected item
|
||||
common.draw_text(
|
||||
font,
|
||||
self.hover_text or self.foreground_color or style.text,
|
||||
text,
|
||||
"left",
|
||||
self.position.x + style.padding.x,
|
||||
self.position.y,
|
||||
self.size.x - style.padding.x,
|
||||
self.size.y
|
||||
)
|
||||
|
||||
-- draw arrow down icon
|
||||
common.draw_text(
|
||||
style.icon_font,
|
||||
self.hover_text or self.foreground_color or style.text,
|
||||
"-",
|
||||
"right",
|
||||
self.position.x,
|
||||
self.position.y,
|
||||
self.size.x - style.padding.x,
|
||||
self.size.y
|
||||
)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
return SelectBox
|
||||
Loading…
Add table
Add a link
Reference in a new issue