mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
162 lines
4.7 KiB
Lua
162 lines
4.7 KiB
Lua
--[[
|
|
| 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
|