Files
Bagshui/Components/Ui.SearchBox.lua
T
OEVG 896f46f0d1
enUS Localization Update Announcement / localization-update-announcement (push) Canceled after 0s
Bagshui 1.6.4
2026-10-30 15:55:43 +00:00

195 lines
6.1 KiB
Lua

-- Bagshui UI Class: Search Boxes
Bagshui:AddComponent(function()
local Ui = Bagshui.prototypes.Ui
--- Create a new search box.
---@param name string Unique name for the search box (will be passed to `Ui:CreateElementName()`).
---@param parent table Parent frame.
---@param width number Default: 85.
---@param height number Default: 18.
---@param onTextChanged function? OnTextChanged script.
---@param onEnterPressed function? OnEnterPressed script.
---@param onIconClick function? OnClick for search icon.
---@param placeholderText string? Text to display when the search box is empty.
---@return table searchBox
function Ui:CreateSearchBox(name, parent, width, height, onTextChanged, onEnterPressed, onIconClick, placeholderText)
width = width or 85
height = height or 18
local searchBox = self:CreateEditBox(name, parent)
searchBox.bagshuiData = {}
searchBox:SetWidth(width)
searchBox:SetHeight(height)
searchBox:SetHistoryLines(10)
-- Add behaviors.
-- Focus gained.
local oldOnEditFocusGained = searchBox:GetScript("OnEditFocusGained")
searchBox:SetScript("OnEditFocusGained", function()
oldOnEditFocusGained()
Bagshui:CloseMenus()
self:UpdateSearchBoxState(_G.this)
_G.this:HighlightText()
end)
-- Focus lost.
local oldOnEditFocusLost = searchBox:GetScript("OnEditFocusLost")
searchBox:SetScript("OnEditFocusLost", function()
oldOnEditFocusLost()
_G.this.bagshuiData.hasFocus = false
self:UpdateSearchBoxState(_G.this)
_G.this:HighlightText(0, 0)
end)
-- Text changed.
searchBox:SetScript("OnTextChanged", function(this)
this = this or _G.this
local searchText = this:GetText()
_G.this.bagshuiData.searchText = (type(searchText) == "string" and string.len(searchText) > 0) and searchText
or nil
self:UpdateSearchBoxState(this)
if onTextChanged then
onTextChanged()
end
end)
-- Focus and history management based on keyboard input.
searchBox:SetScript("OnEnterPressed", function()
_G.this:AddHistoryLine(_G.this:GetText())
if onEnterPressed then
onEnterPressed()
end
_G.this:ClearFocus()
end)
searchBox:SetScript("OnEscapePressed", function()
if string.len(_G.this:GetText() or "") > 0 then
_G.this:AddHistoryLine(_G.this:GetText())
_G.this:SetText("")
else
_G.this:ClearFocus()
end
end)
searchBox:SetScript("OnTabPressed", function()
_G.this:AddHistoryLine(_G.this:GetText())
_G.this:ClearFocus()
end)
-- Mouse events.
searchBox:SetScript("OnEnter", function()
_G.this.bagshuiData.mouseIsOver = true
self:UpdateSearchBoxState(_G.this)
end)
searchBox:SetScript("OnLeave", function()
_G.this.bagshuiData.mouseIsOver = false
self:UpdateSearchBoxState(_G.this)
end)
-- Add search icon.
searchBox.bagshuiData.searchIcon = self:CreateIconButton({
name = name .. "SearchIcon",
parentFrame = searchBox,
tooltipGroupElement = parent,
anchorPoint = "LEFT",
xOffset = 2,
width = height - 5,
height = height - 5,
onClick = function()
searchBox:SetFocus()
if onIconClick then
onIconClick()
end
end,
texture = "Search",
tooltipTitle = L.Search,
})
-- Add placeholder text.
searchBox.bagshuiData.placeholder = searchBox:CreateFontString(nil, nil, "GameFontHighlightSmall")
-- Need enough left offset for the rectangle cursor to not obscure it.
searchBox.bagshuiData.placeholder:SetPoint("LEFT", searchBox.bagshuiData.searchIcon, "RIGHT", 7, 0)
searchBox.bagshuiData.placeholder:SetPoint("RIGHT", searchBox, "RIGHT", -5, 0)
searchBox.bagshuiData.placeholder:SetJustifyH("LEFT")
searchBox.bagshuiData.placeholder:SetVertexColor(1, 1, 1, 0.4)
searchBox.bagshuiData.placeholder:SetText(placeholderText or "")
-- Add clear ("x") icon.
searchBox.bagshuiData.clearIcon = self:CreateIconButton({
name = name .. "ClearIcon",
parentFrame = searchBox,
vertexColor = BS_COLOR.GRAY,
tooltipGroupElement = parent,
anchorPoint = "RIGHT",
anchorToPoint = "RIGHT",
xOffset = -2,
width = 12,
height = 12,
onClick = function()
searchBox:SetFocus()
searchBox:SetText("")
end,
hoverVertexColor = BS_COLOR.YELLOW,
textureDir = "UI",
texture = "Clear",
tooltipTitle = L.Clear,
})
-- Move the left end of the text away from the search icon.
searchBox:SetTextInsets(18, 0, 0, 0)
-- Set initial state.
self:UpdateSearchBoxState(searchBox)
return searchBox
end
--- Manage search box colors and icon visibility.
---@param searchBox table Return value from `Ui:CreateSearchBox()`.
function Ui:UpdateSearchBoxState(searchBox)
if type(searchBox) ~= "table" then
return
end
local backdropOpacity = 0.25
local backdropBorderColorR = BsSkin.editBoxBorderColor[1]
local backdropBorderColorG = BsSkin.editBoxBorderColor[2]
local backdropBorderColorB = BsSkin.editBoxBorderColor[3]
local backdropBorderOpacity = BsSkin.editBoxBorderColor[4]
if searchBox.bagshuiData.hasFocus then
backdropOpacity = 0.5
backdropBorderColorR = NORMAL_FONT_COLOR.r
backdropBorderColorG = NORMAL_FONT_COLOR.g
backdropBorderColorB = NORMAL_FONT_COLOR.b
backdropBorderOpacity = 0.75
elseif searchBox.bagshuiData.mouseIsOver then
backdropBorderOpacity = 0.75
end
searchBox:SetBackdropColor(0, 0, 0, backdropOpacity)
searchBox:SetBackdropBorderColor(
backdropBorderColorR,
backdropBorderColorG,
backdropBorderColorB,
backdropBorderOpacity
)
-- Show clear ("x") icon if there is text, hide if not.
-- Do the inverse to the placeholder text.
searchBox.bagshuiData.clearIcon[searchBox.bagshuiData.searchText and "Show" or "Hide"](
searchBox.bagshuiData.clearIcon
)
searchBox.bagshuiData.placeholder[searchBox.bagshuiData.searchText and "Hide" or "Show"](
searchBox.bagshuiData.placeholder
)
end
end)