Files
wnsrc/gamemodes/sandbox/gamemode/spawnmenu/creationmenu/content/contentsearch.lua

162 lines
4.7 KiB
Lua
Raw Normal View History

2024-08-04 22:55:00 +03:00
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
PANEL.Base = "Panel"
function PANEL:Init()
self.CurrentSearch = ""
self.OldResults = -1
self.RebuildResults = false
self:Dock( TOP )
self:SetHeight( 20 )
self:DockMargin( 0, 0, 0, 3 )
self.Search = self:Add( "DTextEntry" )
self.Search:Dock( FILL )
self.Search:SetPlaceholderText( "#spawnmenu.search" )
self.Search.OnEnter = function() self:RefreshResults() end
self.Search.OnFocusChanged = function( _, b ) if ( b ) then self.ContentPanel:SwitchPanel( self.PropPanel ) end end
self.Search:SetTooltip( "#spawnmenu.enter_search" )
local btn = self.Search:Add( "DImageButton" )
btn:SetImage( "icon16/magnifier.png" )
btn:SetText( "" )
btn:Dock( RIGHT )
btn:DockMargin( 4, 2, 4, 2 )
btn:SetSize( 16, 16 )
btn:SetTooltip( "#spawnmenu.press_search" )
btn.DoClick = function()
self:RefreshResults()
end
self.Search.OnKeyCode = function( p, code )
if ( code == KEY_F1 ) then hook.Run( "OnSpawnMenuClose" ) end
if ( code == KEY_ESCAPE ) then hook.Run( "OnSpawnMenuClose" ) end
end
self.PropPanel = vgui.Create( "ContentContainer", self )
self.PropPanel:SetVisible( false )
self.PropPanel:SetTriggerSpawnlistChange( false )
-- Some sort of placeholder
local Header = self:Add( "ContentHeader" )
Header:SetText( "#spawnmenu.enter_search" )
self.PropPanel:Add( Header )
end
function PANEL:Paint()
-- This is a bit of a hack, if there was a request to rebuild the results from the search indexer
-- Do it when the player next sees the search panel, in case they got the spawnmenu closed
-- Think hook causes unexpected 1 frame duplication of all the elements
if ( self.RebuildResults ) then
self.RebuildResults = false
self:RefreshResults( self.CurrentSearch )
end
end
function PANEL:SetSearchType( stype, hookname )
self.m_strSearchType = stype
hook.Add( hookname, "AddSearchContent_" .. hookname, function( pnlContent, tree, node )
self.ContentPanel = pnlContent
end )
hook.Add( "SearchUpdate", "SearchUpdate_" .. hookname, function()
if ( !g_SpawnMenu:IsVisible() ) then self.RebuildResults = true return end
self:RefreshResults( self.CurrentSearch )
end )
-- This stuff is only for the primary search
if ( hookname != "PopulateContent" ) then return end
g_SpawnMenu.SearchPropPanel = self.PropPanel
hook.Add( "StartSearch", "StartSearch", function()
if ( g_SpawnMenu:IsVisible() ) then return hook.Run( "OnSpawnMenuClose" ) end
hook.Run( "OnSpawnMenuOpen" )
hook.Run( "OnTextEntryGetFocus", self.Search )
self.Search:RequestFocus()
self.Search:SetText( "" )
--
-- If we don't call this we'd have to press F1 twice to close it!
-- It's in a timer because of some good reason that!
--
timer.Simple( 0.1, function() g_SpawnMenu:HangOpen( false ) end )
self.ContentPanel:SwitchPanel( self.PropPanel )
end )
end
function PANEL:RefreshResults( str )
if ( !str ) then -- User tried to search for something
self.CurrentSearch = self.Search:GetText()
str = self.CurrentSearch
self.OldResults = -1
else
-- Don't force open the search when you click away from search while this function is called from cl_search_models.lua
if ( self.ContentPanel.SelectedPanel != self.PropPanel ) then
return
end
end
if ( !str or str == "" ) then return end
local results = search.GetResults( str, self.m_strSearchType, GetConVarNumber( "sbox_search_maxresults" ) )
for id, result in ipairs( results ) do
if ( !IsValid( result.icon ) ) then ErrorNoHalt( "Failed to create icon for " .. ( result.words && isstring( result.words[ 1 ] ) && result.words[ 1 ] || result.text ).. "\n" ) continue end
result.icon:SetParent( vgui.GetWorldPanel() ) -- Don't parent the icons to search panel prematurely
end
-- I know this is not perfect, but this is the best I am willing to do with how the search library was set up
if ( self.OldResults == #results ) then -- No updates, don't rebuild
for id, result in ipairs( results ) do
if ( IsValid( result.icon ) ) then result.icon:Remove() end -- Kill all icons
end
return
end
self.OldResults = #results
self.PropPanel:Clear()
local Header = self:Add( "ContentHeader" )
Header:SetText( #results .. " Results for \"" .. str .. "\"" )
self.PropPanel:Add( Header )
for k, v in ipairs( results ) do
self:AddSearchResult( v.text, v.func, v.icon )
end
self.PropPanel:SetParent( self.ContentPanel )
self.ContentPanel:SwitchPanel( self.PropPanel )
end
function PANEL:AddSearchResult( text, func, icon )
if ( !IsValid( icon ) ) then return end
icon:SetParent( self.PropPanel )
self.PropPanel:Add( icon )
end