732 lines
22 KiB
Lua
732 lines
22 KiB
Lua
|
|
local PANEL = {}
|
|
|
|
AccessorFunc( PANEL, "m_TabID", "TabID" )
|
|
|
|
local expand_all = CreateConVar( "wire_tool_menu_expand_all", 0, {FCVAR_ARCHIVE} )
|
|
local separate_wire_extras = CreateConVar( "wire_tool_menu_separate_wire_extras", 1, {FCVAR_ARCHIVE} )
|
|
local hide_duplicates = CreateConVar( "wire_tool_menu_hide_duplicates", 0, {FCVAR_ARCHIVE} )
|
|
local custom_for_all_tabs = CreateConVar( "wire_tool_menu_custom_menu_for_all_tabs", 0, {FCVAR_ARCHIVE} )
|
|
local tab_width = CreateConVar( "wire_tool_menu_tab_width", -1, {FCVAR_ARCHIVE} )
|
|
local horizontal_divider_width = CreateConVar( "wire_tool_menu_horizontal_divider_width", 0.28, {FCVAR_ARCHIVE} )
|
|
local custom_icons = CreateConVar( "wire_tool_menu_custom_icons", 1, {FCVAR_ARCHIVE} )
|
|
local autocollapse = CreateConVar( "wire_tool_menu_autocollapse", 0, {FCVAR_ARCHIVE} )
|
|
|
|
-- Helper functions
|
|
local function expandall( bool, nodes )
|
|
for i=1,#nodes do
|
|
if nodes[i].m_bExpanded ~= bool then
|
|
nodes[i]:SetExpanded( bool )
|
|
if nodes[i].WireCookieText then cookie.Set( nodes[i].WireCookieText, bool and 1 or 0 ) end
|
|
end
|
|
|
|
if nodes[i].ChildNodes then
|
|
expandall( bool, nodes[i].ChildNodes:GetChildren() )
|
|
end
|
|
end
|
|
end
|
|
|
|
local function expandbycookie( nodes )
|
|
for i=1,#nodes do
|
|
local b = cookie.GetNumber( nodes[i].WireCookieText )
|
|
|
|
if b and b == 1 then
|
|
nodes[i]:SetExpanded( b and b == 1 )
|
|
|
|
if nodes[i].ChildNodes then
|
|
expandbycookie( nodes[i].ChildNodes:GetChildren() )
|
|
end
|
|
else
|
|
nodes[i]:SetExpanded( false )
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
----------------------------------------------------------------------
|
|
-- Init
|
|
----------------------------------------------------------------------
|
|
function PANEL:Init()
|
|
self.Divider = vgui.Create( "DHorizontalDivider", self )
|
|
self.Divider:Dock( FILL )
|
|
self.Divider:SetDividerWidth( 6 )
|
|
|
|
local width = tab_width:GetInt()
|
|
local divider_width = horizontal_divider_width:GetFloat()
|
|
if width > ScrW() * 0.6 then -- too big! you won't be able to see the rest of the spawn menu if it's this big, let's make it smaller
|
|
width = ScrW() * 0.6
|
|
elseif width == -1 then -- set up default value
|
|
width = 390
|
|
if ScrW() > 1600 then width = 548
|
|
elseif ScrW() > 1280 then width = 460 end
|
|
elseif width < 390 then -- too small! you won't be able to see the tools, make it bigger
|
|
width = 390
|
|
end
|
|
|
|
if width ~= tab_width:GetInt() then -- things changed, update convars
|
|
divider_width = 0.28 -- reset horizontal divider width
|
|
RunConsoleCommand( "wire_tool_menu_tab_width", width )
|
|
RunConsoleCommand( "wire_tool_menu_horizontal_divider_width", divider_width )
|
|
end
|
|
|
|
self:SetWide( width )
|
|
self.Divider:SetLeftWidth( width * divider_width )
|
|
|
|
local old = self.Divider.OnMouseReleased
|
|
function self.Divider.OnMouseReleased( ... )
|
|
local width_percent = math.Round(self.Divider:GetLeftWidth() / self:GetWide(),2)
|
|
RunConsoleCommand( "wire_tool_menu_horizontal_divider_width", width_percent )
|
|
old( ... )
|
|
end
|
|
|
|
local LeftPanel = vgui.Create( "DPanel" )
|
|
self.Divider:SetLeft( LeftPanel )
|
|
|
|
local SearchBoxPanel = vgui.Create( "DPanel", LeftPanel )
|
|
SearchBoxPanel:SetTall( 44 )
|
|
SearchBoxPanel:DockPadding( 2,2,2,2 )
|
|
SearchBoxPanel:Dock( TOP )
|
|
|
|
self.SearchBox = vgui.Create( "DTextEntry", SearchBoxPanel )
|
|
self.SearchBox:DockMargin( 2, 2, 2, 0 )
|
|
self.SearchBox:Dock( TOP )
|
|
self:SetupSearchbox()
|
|
|
|
local ExpandAll = vgui.Create( "DCheckBoxLabel", SearchBoxPanel ) -- create this here so that it's below the slider
|
|
|
|
self.List = vgui.Create( "DTree", LeftPanel )
|
|
|
|
ExpandAll:SetText( "Expand All" )
|
|
ExpandAll:SetConVar( "wire_tool_menu_expand_all" )
|
|
ExpandAll:DockMargin( 4, 4, 0, 0 )
|
|
ExpandAll:Dock( BOTTOM )
|
|
|
|
local first = true
|
|
|
|
local parent = self
|
|
local oldval
|
|
function ExpandAll:OnChange( value )
|
|
if oldval == value then return end -- wtfgarry
|
|
oldval = value
|
|
|
|
local childNodes = parent.List:Root().ChildNodes:GetChildren()
|
|
|
|
if first then
|
|
-- this was the only way to get this to run at the right time... garry bypassing hacks wohoo
|
|
-- it works because DCheckBox:OnChange is called when the player first sees the checkbox (aka when they open the wire tool tab)
|
|
first = false
|
|
expandbycookie( childNodes )
|
|
else
|
|
expandall( value, childNodes )
|
|
end
|
|
end
|
|
ExpandAll.Label:SetDark(true)
|
|
|
|
self.List:Dock( FILL )
|
|
|
|
self.SearchList = vgui.Create( "DListView", LeftPanel )
|
|
local x,y = self.List:GetPos()
|
|
local w,h = self.List:GetSize()
|
|
self.SearchList:SetPos( x + w, 160 )
|
|
self.SearchList:SetSize( w, h )
|
|
self.SearchList:SetVisible( false )
|
|
self.SearchList:AddColumn( "Name" )
|
|
self.SearchList:AddColumn( "Category" )
|
|
self.SearchList:SetMultiSelect( false )
|
|
|
|
function self.SearchList:OnClickLine( line )
|
|
-- Deselect old
|
|
local t = self:GetSelected()
|
|
if t and next(t) then
|
|
t[1]:SetSelected(false)
|
|
end
|
|
|
|
line:SetSelected(true) -- Select new
|
|
spawnmenu.ActivateTool( line.Name )
|
|
end
|
|
|
|
self.Content = vgui.Create( "DCategoryList" )
|
|
self.Divider:SetRight( self.Content )
|
|
|
|
local searchlist = self.SearchList
|
|
function LeftPanel:PerformLayout()
|
|
searchlist:SetWide( self:GetWide() )
|
|
end
|
|
|
|
self.ToolTable = {}
|
|
self.OriginalToolTable = {}
|
|
self.CategoryLookup = {}
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
-- ReloadEverything
|
|
-- Called when a user adds/removes favourites or checks/unchecks
|
|
-- the wire extras checkbox
|
|
----------------------------------------------------------------------
|
|
function PANEL:ReloadEverything()
|
|
self.List:Root():Remove()
|
|
self.List:Init()
|
|
self.SearchList:Clear()
|
|
self.SearchBox:SetValue( "" )
|
|
self.SearchBox:OnTextChanged()
|
|
|
|
self.CategoryLookup = {}
|
|
self.ToolTable = {}
|
|
|
|
self:LoadToolsFromTable( self.OriginalToolTable )
|
|
expandbycookie( self.List:Root().ChildNodes:GetChildren() )
|
|
end
|
|
|
|
|
|
----------------------------------------------------------------------
|
|
-- SetupSearchbox
|
|
-- This was so big, I moved it into its own function
|
|
-- rather than doing it in PANEL:Init()
|
|
----------------------------------------------------------------------
|
|
function PANEL:SetupSearchbox()
|
|
local clearsearch = vgui.Create( "DImageButton", self.SearchBox )
|
|
clearsearch:SetMaterial( "icon16/cross.png" )
|
|
local src = self.SearchBox
|
|
function clearsearch:DoClick()
|
|
src:SetValue( "" )
|
|
src:OnTextChanged()
|
|
src:SetValue( "Search..." )
|
|
end
|
|
clearsearch:DockMargin( 2,2,4,2 )
|
|
clearsearch:Dock( RIGHT )
|
|
clearsearch:SetSize( 14, 10 )
|
|
clearsearch:SetVisible( false )
|
|
self.SearchBox.clearsearch = clearsearch
|
|
|
|
-- OnEnter
|
|
local parent = self
|
|
function self.SearchBox:OnEnter( select_next )
|
|
local lines = #parent.SearchList:GetLines()
|
|
if lines > 0 then -- if we have no lines at all, do nothing
|
|
local line = parent.SearchList:GetSelectedLine() or 0
|
|
if select_next then -- if tabbed, select next line
|
|
if lines > line then
|
|
parent.SearchList:OnClickLine( parent.SearchList:GetLine( line+1 ) )
|
|
else
|
|
parent.SearchList:OnClickLine( parent.SearchList:GetLine( 1 ) )
|
|
end
|
|
elseif line == 0 then -- if not tabbed, only select first line if no line is selected
|
|
parent.SearchList:OnClickLine( parent.SearchList:GetLine( 1 ) )
|
|
end
|
|
end
|
|
end
|
|
|
|
local old = self.SearchBox.OnGetFocus
|
|
function self.SearchBox:OnGetFocus()
|
|
if self:GetValue() == "Search..." then -- If "Search...", erase it
|
|
self:SetValue( "" )
|
|
end
|
|
old( self )
|
|
end
|
|
|
|
-- On lose focus
|
|
local old = self.SearchBox.OnLoseFocus
|
|
function self.SearchBox:OnLoseFocus()
|
|
if self.Tabbed then -- regain focus if tabbed
|
|
self:RequestFocus()
|
|
self.Tabbed = nil
|
|
else
|
|
if self:GetValue() == "" then -- if empty, reset "Search..." text
|
|
timer.Simple( 0, function() self:SetValue( "Search..." ) end )
|
|
end
|
|
old( self )
|
|
end
|
|
end
|
|
|
|
-- detecting tab to select next item in search result
|
|
local old = self.SearchBox.OnKeyCodeTyped
|
|
function self.SearchBox:OnKeyCodeTyped( code )
|
|
if code == 67 then -- tab
|
|
self:OnEnter( true )
|
|
self.Tabbed = true
|
|
else
|
|
old( self, code )
|
|
end
|
|
end
|
|
|
|
self.SearchBox:SetValue( "Search..." )
|
|
|
|
local searching
|
|
function self.SearchBox:OnTextChanged()
|
|
timer.Remove( "wire_customspawnmenu_hidesearchbox" )
|
|
|
|
local text = self:GetValue()
|
|
if text ~= "" then
|
|
if not searching then
|
|
searching = true
|
|
local x,y = parent.List:GetPos()
|
|
local w,h = parent.List:GetSize()
|
|
parent.SearchList:SetPos( x + w, y )
|
|
parent.SearchList:MoveTo( x, y, 0.1, 0, 1 )
|
|
parent.SearchList:SetSize( w, h )
|
|
parent.SearchList:SetVisible( true )
|
|
self.clearsearch:SetVisible( true )
|
|
parent.List:AlphaTo( 0, 0.1, 0 )
|
|
end
|
|
local results = parent:Search( text )
|
|
parent.SearchList:Clear()
|
|
for i=1,#results do
|
|
local result = results[i]
|
|
local line = parent.SearchList:AddLine( result.item.Text, result.item.Category )
|
|
line.Name = result.item.ItemName
|
|
line.WireFavouritesCookieText = result.item.WireFavouritesCookieText
|
|
|
|
function line:OnRightClick()
|
|
-- the menu wasn't clickable unless the search list had focus for some reason
|
|
parent.SearchList:RequestFocus()
|
|
|
|
local menu = DermaMenu()
|
|
|
|
local b = cookie.GetNumber( self.WireFavouritesCookieText )
|
|
if b and b == 1 then
|
|
menu:AddOption( "Remove from favourites", function() cookie.Set( self.WireFavouritesCookieText, 0 ) parent:ReloadEverything() end )
|
|
else
|
|
menu:AddOption( "Add to favourites", function() cookie.Set( self.WireFavouritesCookieText, 1 ) parent:ReloadEverything() end )
|
|
end
|
|
menu:Open()
|
|
|
|
return true
|
|
end
|
|
end
|
|
else
|
|
if searching then
|
|
searching = false
|
|
local x,y = parent.List:GetPos()
|
|
local w,h = parent.List:GetSize()
|
|
parent.SearchList:SetPos( x, y )
|
|
parent.SearchList:MoveTo( x + w, y, 0.1, 0, 1 )
|
|
parent.SearchList:SetSize( w, h )
|
|
timer.Create( "wire_customspawnmenu_hidesearchbox", 0.1, 1, function()
|
|
if IsValid( parent ) then
|
|
parent.SearchList:SetVisible( false )
|
|
end
|
|
end )
|
|
self.clearsearch:SetVisible( false )
|
|
parent.List:AlphaTo( 255, 0.1, 0 )
|
|
end
|
|
parent.SearchList:Clear()
|
|
end
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
-- Search algorithm
|
|
----------------------------------------------------------------------
|
|
|
|
local string_find = string.find
|
|
local table_SortByMember = table.SortByMember
|
|
local string_lower = string.lower
|
|
local language_GetPhrase = language.GetPhrase
|
|
local string_gsub = string.gsub
|
|
|
|
-- Searching algorithm
|
|
function PANEL:Search( text )
|
|
text = string_lower(text)
|
|
|
|
local results = {}
|
|
for categoryID,categories in pairs( self.ToolTable ) do
|
|
for _, v in pairs( categories ) do
|
|
local name = language_GetPhrase(string_gsub(v.Text,"^#",""))
|
|
local lowname = string_lower( name )
|
|
|
|
if string_find( lowname, text, 1, true ) and not string_find( lowname, "(legacy)", 1, true ) and not v.Alias then
|
|
results[#results+1] = {
|
|
item = v,
|
|
dist = WireLib.levenshtein( text, lowname )
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
table_SortByMember( results, "dist", true )
|
|
|
|
return results
|
|
end
|
|
|
|
-- Helper function
|
|
local function AddNode( list, text, icon, cookietext )
|
|
local node = list:AddNode( text, icon )
|
|
|
|
node.Label:SetFont( "DermaDefaultBold" )
|
|
|
|
cookietext = "ToolMenu.Wire." .. cookietext
|
|
node.WireCookieText = cookietext
|
|
|
|
function node:DoClick()
|
|
if autocollapse:GetBool() then
|
|
local parent = (list.RootNode and list.RootNode.ChildNodes:GetChildren() or list.ChildNodes:GetChildren())
|
|
expandall( false, parent )
|
|
end
|
|
|
|
local b = not self.m_bExpanded
|
|
self:SetExpanded( b )
|
|
|
|
cookie.Set( cookietext, b and 1 or 0 )
|
|
end
|
|
node.Expander.DoClick = function() node:DoClick() end
|
|
|
|
function node:DoRightClick()
|
|
local menu = DermaMenu()
|
|
|
|
local b = self.m_bExpanded
|
|
if b then
|
|
menu:AddOption( "Collapse all", function()
|
|
self:SetExpanded( false )
|
|
expandall( false, self.ChildNodes:GetChildren() )
|
|
end )
|
|
else
|
|
menu:AddOption( "Expand all", function()
|
|
self:SetExpanded( true )
|
|
expandall( true, self.ChildNodes:GetChildren() )
|
|
end )
|
|
end
|
|
menu:Open()
|
|
|
|
return true
|
|
end
|
|
|
|
return node
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
-- CreateCategories
|
|
-- Creates the categories before placing tools in them to ensure
|
|
-- they are created in the correct order, and only once
|
|
----------------------------------------------------------------------
|
|
function PANEL:CreateCategories()
|
|
for k,v in pairs( self.ToolTable ) do
|
|
if istable( v ) then
|
|
local category = v.ItemName
|
|
|
|
local expl = string.Explode("/",category)
|
|
|
|
if not separate_wire_extras:GetBool() and expl[1] == "Wire Extras" then
|
|
table.remove( expl, 1 )
|
|
v.ItemName = string.gsub( v.ItemName, "Wire Extras/", "" )
|
|
v.Text = string.gsub( v.Text, "Wire Extras/", "" )
|
|
category = v.ItemName
|
|
end
|
|
|
|
if #expl == 1 then
|
|
if not self.CategoryLookup[category] then
|
|
local node = AddNode( self.List, v.Text, v.Icon, category )
|
|
self.CategoryLookup[category] = node
|
|
end
|
|
else
|
|
local category = expl[1]
|
|
if not self.CategoryLookup[category] then
|
|
local node = AddNode( self.List, category, nil, category )
|
|
self.CategoryLookup[category] = node
|
|
end
|
|
|
|
for i=2,#expl do
|
|
local str = expl[i]
|
|
|
|
local path = table.concat(expl,"/",1,i)
|
|
if not self.CategoryLookup[path] then
|
|
local node = AddNode( self.CategoryLookup[table.concat(expl,"/",1,i-1)], str, nil, path )
|
|
self.CategoryLookup[path] = node
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
----------------------------------------------------------------------
|
|
-- AddToolToCategories
|
|
-- Handles multiple categories by copying the tool and moving the copies into said categories
|
|
----------------------------------------------------------------------
|
|
function PANEL:AddToolToCategories( tool, categories )
|
|
for i=1,#categories do
|
|
local categoryName = categories[i]
|
|
|
|
local added = false
|
|
|
|
local copy = table.Copy( tool )
|
|
copy.Alias = true
|
|
|
|
for _, category in pairs( self.ToolTable ) do
|
|
if category.ItemName == categoryName then
|
|
added = true
|
|
category[#category+1] = copy
|
|
table_SortByMember( category, "Text", true )
|
|
end
|
|
end
|
|
|
|
if not added then
|
|
local new = {
|
|
ItemName = categoryName,
|
|
Text = categoryName,
|
|
}
|
|
|
|
new[1] = copy
|
|
self.ToolTable[#self.ToolTable+1] = new
|
|
end
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
-- FixWireCategories
|
|
-- Handles multi categories and favourites
|
|
----------------------------------------------------------------------
|
|
function PANEL:FixWireCategories()
|
|
local t = table.Copy( self.ToolTable )
|
|
|
|
for _,category in pairs( t ) do
|
|
if istable(category) then
|
|
for _, tool in pairs( category ) do
|
|
if istable(tool) then
|
|
-- favourites
|
|
local fav = cookie.GetNumber( "ToolMenu.Wire.Favourites." .. tool.ItemName )
|
|
if fav and fav == 1 then
|
|
self:AddToolToCategories( tool, {"Favourites"} )
|
|
end
|
|
|
|
-- multi categories
|
|
if not hide_duplicates:GetBool() then
|
|
local tooltbl = weapons.Get("gmod_tool").Tool[tool.ItemName]
|
|
if tooltbl then
|
|
if tooltbl.Wire_MultiCategories then
|
|
self:AddToolToCategories( tool, tooltbl.Wire_MultiCategories )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------
|
|
-- Name: LoadToolsFromTable
|
|
-----------------------------------------------------------
|
|
function PANEL:LoadToolsFromTable( inTable )
|
|
self.OriginalToolTable = table.Copy( inTable )
|
|
self.ToolTable = table.Copy( inTable )
|
|
|
|
-- If this tab has no favourites category, add one at the top
|
|
if self.ToolTable[1].ItemName ~= "Favourites" then
|
|
table.insert( self.ToolTable, 1, { ItemName = "Favourites", Text = "Favourites", Icon = "icon16/star.png" } )
|
|
|
|
-- If this tab DOES have a favourites category, set its icon to a star
|
|
elseif self.ToolTable[1].ItemName == "Favourites" then
|
|
self.ToolTable[1].Icon = "icon16/star.png"
|
|
end
|
|
|
|
-- First, we copy all tools into their multi categories
|
|
self:FixWireCategories()
|
|
|
|
-- Then we create the categories, so everything goes to the right place
|
|
self:CreateCategories()
|
|
|
|
-- Then, we add all tools to the DTree
|
|
for k, v in pairs( self.ToolTable ) do
|
|
|
|
if ( istable( v ) ) then
|
|
|
|
-- Remove these from the table so we can
|
|
-- send the rest of the table to the other
|
|
-- function
|
|
|
|
local Name = v.ItemName
|
|
local Label = v.Text
|
|
v.ItemName = nil
|
|
v.Text = nil
|
|
v.Icon = nil
|
|
|
|
self:AddCategory( Name, Label, v )
|
|
end
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------
|
|
-- Name: AddCategory
|
|
-----------------------------------------------------------
|
|
function PANEL:AddCategory( Name, Label, tItems, CategoryID )
|
|
|
|
local Category = self.CategoryLookup[Name]
|
|
if not Category then
|
|
return
|
|
end
|
|
|
|
for k, v in pairs( tItems ) do
|
|
|
|
v.Category = Label
|
|
v.CategoryID = CategoryID
|
|
|
|
local icon = "icon16/wrench.png"
|
|
|
|
if custom_icons:GetBool() then
|
|
local tooltbl = weapons.Get("gmod_tool").Tool[v.ItemName]
|
|
if tooltbl then
|
|
if tooltbl.Wire_ToolMenuIcon then
|
|
icon = tooltbl.Wire_ToolMenuIcon
|
|
end
|
|
end
|
|
end
|
|
|
|
local item = Category:AddNode( v.Text, icon )
|
|
|
|
function item:DoClick()
|
|
|
|
spawnmenu.ActivateTool( self.Name )
|
|
|
|
end
|
|
|
|
local parent = self
|
|
function item:DoRightClick()
|
|
local menu = DermaMenu()
|
|
|
|
local b = cookie.GetNumber( self.WireFavouritesCookieText )
|
|
if b and b == 1 then
|
|
menu:AddOption( "Remove from favourites", function() cookie.Set( self.WireFavouritesCookieText, 0 ) parent:ReloadEverything() end )
|
|
else
|
|
menu:AddOption( "Add to favourites", function() cookie.Set( self.WireFavouritesCookieText, 1 ) parent:ReloadEverything() end )
|
|
end
|
|
menu:Open()
|
|
|
|
return true
|
|
end
|
|
|
|
item.WireFavouritesCookieText = "ToolMenu.Wire.Favourites." .. v.ItemName
|
|
v.WireFavouritesCookieText = item.WireFavouritesCookieText
|
|
item.ControlPanelBuildFunction = v.CPanelFunction
|
|
item.Command = v.Command
|
|
item.Name = v.ItemName
|
|
item.Controls = v.Controls
|
|
item.Text = v.Text
|
|
|
|
end
|
|
|
|
self:InvalidateLayout()
|
|
end
|
|
|
|
function PANEL:SetActive( cp )
|
|
local kids = self.Content:GetCanvas():GetChildren()
|
|
for k, v in pairs( kids ) do
|
|
v:SetVisible( false )
|
|
end
|
|
|
|
self.Content:AddItem( cp )
|
|
cp:SetVisible( true )
|
|
cp:Dock( TOP )
|
|
end
|
|
|
|
vgui.Register( "WireToolPanel", PANEL, "Panel" )
|
|
|
|
local wire_tab
|
|
local all_tabs = {}
|
|
|
|
local function setUpTabReloadOnChange( checkbox )
|
|
checkbox.first = true
|
|
function checkbox:OnChange( value )
|
|
if self.oldval == value then return end -- wtfgarry
|
|
self.oldval = value
|
|
|
|
if self.first then self.first = false return end
|
|
|
|
timer.Simple( 0.1, function()
|
|
if IsValid( wire_tab ) then
|
|
wire_tab:ReloadEverything()
|
|
end
|
|
end )
|
|
end
|
|
end
|
|
|
|
local function CreateCPanel( panel )
|
|
local checkbox = panel:CheckBox( "Use wire's custom tool menu for all tabs", "wire_tool_menu_custom_menu_for_all_tabs" )
|
|
checkbox:SetToolTip( "Requires rejoin to take effect" )
|
|
|
|
if WireLib.WireExtrasInstalled then
|
|
local SeparateWireExtras = panel:CheckBox( "Separate Wire Extras", "wire_tool_menu_separate_wire_extras" )
|
|
SeparateWireExtras:SetToolTip( "Whether or not to separate wire extras tools into its own category." )
|
|
|
|
setUpTabReloadOnChange( SeparateWireExtras )
|
|
end
|
|
|
|
local HideDuplicates = panel:CheckBox( "Hide tool duplicates", "wire_tool_menu_hide_duplicates" )
|
|
setUpTabReloadOnChange( HideDuplicates )
|
|
panel:Help( "It makes sense to have certain tools in multiple categories at once. However, if you don't want this, you can disable it here. The tools will then only appear in their primary category." )
|
|
|
|
local UseIcons = panel:CheckBox( "Use custom icons", "wire_tool_menu_custom_icons" )
|
|
setUpTabReloadOnChange( UseIcons )
|
|
UseIcons:SetToolTip( "If disabled, all tools will use the 'wrench' icon." )
|
|
|
|
local AutoCollapse = panel:CheckBox( "Autocollapse", "wire_tool_menu_autocollapse" )
|
|
AutoCollapse:SetToolTip( "If enabled, opening a category will collapse other categories." )
|
|
|
|
local TabWidth = panel:NumSlider( "Tab width", "wire_tool_menu_tab_width", 300, 3000, 0 )
|
|
panel:Help( [[Set the width of all tabs.
|
|
Defaults:
|
|
Screen width > 1600px: 548px,
|
|
Screen width > 1280px: 460px,
|
|
Screen width < 1280px: 390px.
|
|
Note:
|
|
Can't be smaller than the width of any non-custom tab, and can't be greater than screenwidth * 0.6.
|
|
Changes will take effect 3 seconds after you edit the value.]] )
|
|
|
|
function TabWidth:ValueChanged( value )
|
|
timer.Remove( "wire_tab_width_changed" )
|
|
timer.Create( "wire_tab_width_changed", 3, 1, function()
|
|
all_tabs[1]:GetParent():SetWide( 390 )
|
|
for i=1,#all_tabs do -- change the width of all registered tabs
|
|
all_tabs[i]:SetWidth( math.Clamp( value, 390, ScrW() * 0.6 ) )
|
|
end
|
|
all_tabs[1]:GetParent():PerformLayout()
|
|
end)
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
-- Incoming garry hack
|
|
----------------------------------------------------------------------
|
|
|
|
local tabs = {}
|
|
|
|
-- Allow any addon to register to be given a custom menu
|
|
function WireLib.registerTabForCustomMenu( tab )
|
|
tabs[tab] = true
|
|
end
|
|
|
|
-- Register ourselves
|
|
WireLib.registerTabForCustomMenu( "Wire" )
|
|
|
|
local old
|
|
hook.Add( "PopulateToolMenu", "Wire_CustomSpawnMenu", function()
|
|
spawnmenu.AddToolMenuOption( "Wire", "Options", "Custom Tool Menu Options", "Custom Tool Menu Options", "", "", CreateCPanel )
|
|
|
|
local ToolMenu = vgui.GetControlTable( "ToolMenu" )
|
|
|
|
old = ToolMenu.AddToolPanel
|
|
function ToolMenu:AddToolPanel( Name, ToolTable )
|
|
if tabs[ToolTable.Name] or custom_for_all_tabs:GetBool() == true then
|
|
local Panel = vgui.Create( "WireToolPanel" )
|
|
|
|
if ToolTable.Name == "Wire" then
|
|
wire_tab = Panel -- for wire tab options menu
|
|
end
|
|
all_tabs[#all_tabs+1] = Panel -- list of all registered tabs
|
|
|
|
Panel:SetTabID( Name )
|
|
Panel:LoadToolsFromTable( ToolTable.Items )
|
|
|
|
self:AddSheet( ToolTable.Label, Panel, ToolTable.Icon )
|
|
self.ToolPanels[ Name ] = Panel
|
|
else
|
|
return old( self, Name, ToolTable )
|
|
end
|
|
end
|
|
end)
|
|
|
|
hook.Add( "PostReloadToolsMenu", "Wire_CustomSpawnMenu", function()
|
|
local ToolMenu = vgui.GetControlTable( "ToolMenu" )
|
|
ToolMenu.AddToolPanel = old
|
|
old = nil
|
|
end)
|