mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-18 06:03:47 +03:00
Upload
This commit is contained in:
86
lua/pac3/editor/client/panels/browser.lua
Normal file
86
lua/pac3/editor/client/panels/browser.lua
Normal file
@@ -0,0 +1,86 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
local L = pace.LanguageString
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "browser"
|
||||
PANEL.Base = "DListView"
|
||||
|
||||
PANEL.Dir = ""
|
||||
AccessorFunc(PANEL, "Dir", "Dir")
|
||||
|
||||
function PANEL:SetDir(str)
|
||||
self.Dir = str
|
||||
self:PopulateFromClient()
|
||||
end
|
||||
|
||||
function PANEL:Init()
|
||||
self:AddColumn(L"name")
|
||||
self:AddColumn(L"size")
|
||||
self:AddColumn(L"modified")
|
||||
self:PopulateFromClient()
|
||||
self:FixColumnsLayout()
|
||||
end
|
||||
|
||||
local function OnMousePressed(self, mcode)
|
||||
if mcode == MOUSE_RIGHT then
|
||||
self:GetListView():OnRowRightClick(self:GetID(), self)
|
||||
elseif mcode == MOUSE_LEFT then
|
||||
self:GetListView():OnClickLine(self, true)
|
||||
self:OnSelect()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:AddOutfits(folder, callback)
|
||||
for i, name in pairs(file.Find(folder.."*", "DATA")) do
|
||||
if name:find("%.txt") then
|
||||
local outfit = folder .. name
|
||||
if file.Exists(outfit, "DATA") then
|
||||
local filenode = self:AddLine(
|
||||
name:gsub("%.txt", ""),
|
||||
string.NiceSize(file.Size(outfit, "DATA")),
|
||||
os.date("%m/%d/%Y %H:%M", file.Time(outfit, "DATA"))
|
||||
)
|
||||
filenode.FileName = name
|
||||
filenode.OnSelect = callback
|
||||
filenode.OnMousePressed = OnMousePressed
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PopulateFromClient()
|
||||
self:Clear()
|
||||
|
||||
self:AddOutfits("pac3/" .. self.Dir, function(node)
|
||||
pace.LoadParts(self.Dir .. node.FileName, true)
|
||||
pace.RefreshTree()
|
||||
end)
|
||||
end
|
||||
|
||||
function PANEL.OnRowRightClick(_self,id, self)
|
||||
local m=DermaMenu()
|
||||
m:AddOption(L"View",function()
|
||||
self:GetListView():OnClickLine(self, true)
|
||||
self:OnSelect()
|
||||
end)
|
||||
m:AddOption(L"wear on server",function()
|
||||
self:GetListView():OnClickLine(self, true)
|
||||
self:OnSelect()
|
||||
timer.Simple(0,function()
|
||||
RunConsoleCommand"pac_wear_parts"
|
||||
end)
|
||||
end)
|
||||
|
||||
m:Open()
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
494
lua/pac3/editor/client/panels/editor.lua
Normal file
494
lua/pac3/editor/client/panels/editor.lua
Normal file
@@ -0,0 +1,494 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
local L = pace.LanguageString
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "editor"
|
||||
PANEL.Base = "DFrame"
|
||||
PANEL.menu_bar = NULL
|
||||
|
||||
PANEL.pac3_PanelsToRemove = {
|
||||
'btnMaxim', 'btnMinim'
|
||||
}
|
||||
|
||||
local BAR_SIZE = 17
|
||||
local RENDERSCORE_SIZE = 20
|
||||
|
||||
local use_tabs = CreateClientConVar("pac_property_tabs", 1, true)
|
||||
|
||||
local zoom_persistent = CreateClientConVar("pac_zoom_persistent", 0, true, false, 'Keep zoom between sessions.')
|
||||
local zoom_mousewheel = CreateClientConVar("pac_zoom_mousewheel", 0, true, false, 'Enable zooming with mouse wheel.')
|
||||
local zoom_smooth = CreateClientConVar("pac_zoom_smooth", 0, true, false, 'Enable smooth zooming.')
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetTitle("")
|
||||
self:SetSizable(true)
|
||||
--self:DockPadding(2, 23, 2, 2)
|
||||
|
||||
surface.SetFont(pace.CurrentFont)
|
||||
local _, h = surface.GetTextSize("|")
|
||||
RENDERSCORE_SIZE = h + 1
|
||||
|
||||
local div = vgui.Create("DVerticalDivider", self)
|
||||
|
||||
div:SetDividerHeight(RENDERSCORE_SIZE)
|
||||
div:Dock(FILL)
|
||||
div:SetTopMin(40)
|
||||
div:SetBottomMin(40)
|
||||
div:SetCookieName("pac3_editor")
|
||||
div:SetTopHeight(ScrH() / 1.4)
|
||||
div:LoadCookies()
|
||||
|
||||
self.div = div
|
||||
|
||||
self.treePanel = pace.CreatePanel("tree")
|
||||
self:SetTop(self.treePanel)
|
||||
|
||||
local pnl = pace.CreatePanel("properties", div)
|
||||
pace.properties = pnl
|
||||
|
||||
self.exit_button = vgui.Create("DButton")
|
||||
self.exit_button:SetText("")
|
||||
self.exit_button.DoClick = function() self:Close() end
|
||||
self.exit_button.Paint = function(self, w, h) derma.SkinHook("Paint", "WindowCloseButton", self, w, h) end
|
||||
self.exit_button:SetSize(31, 26)
|
||||
|
||||
self.zoomframe = vgui.Create( "DPanel" )
|
||||
self.zoomframe:SetSize( 180, 150 )
|
||||
|
||||
self.zoomsettings = vgui.Create("DPanel", self.zoomframe)
|
||||
self.zoomsettings:Dock(TOP)
|
||||
self.zoomsettings:DockPadding(4,0,4,4)
|
||||
|
||||
local SETTING_MARGIN_TOP = 6
|
||||
self.persistcheckbox = vgui.Create("DCheckBoxLabel", self.zoomsettings)
|
||||
self.persistcheckbox:SetText("Persistent camera FOV")
|
||||
self.persistcheckbox:Dock(TOP)
|
||||
self.persistcheckbox:SetDark(true)
|
||||
self.persistcheckbox:DockMargin(0,SETTING_MARGIN_TOP,0,0)
|
||||
self.persistcheckbox:SetConVar("pac_zoom_persistent")
|
||||
|
||||
self.persistlabel = vgui.Create("DLabel", self.zoomsettings)
|
||||
self.persistlabel:Dock(TOP)
|
||||
self.persistlabel:SetDark(true)
|
||||
self.persistlabel:SetText("Keep the zoom when reopening the editor.")
|
||||
self.persistlabel:SetWrap(true)
|
||||
self.persistlabel:SetAutoStretchVertical(true)
|
||||
|
||||
self.mwheelcheckbox = vgui.Create("DCheckBoxLabel", self.zoomsettings)
|
||||
self.mwheelcheckbox:SetText("Enable mouse wheel")
|
||||
self.mwheelcheckbox:Dock(TOP)
|
||||
self.mwheelcheckbox:SetDark(true)
|
||||
self.mwheelcheckbox:DockMargin(0,SETTING_MARGIN_TOP,0,0)
|
||||
self.mwheelcheckbox:SetConVar("pac_zoom_mousewheel")
|
||||
|
||||
self.mwheellabel = vgui.Create("DLabel", self.zoomsettings)
|
||||
self.mwheellabel:Dock(TOP)
|
||||
self.mwheellabel:SetDark(true)
|
||||
self.mwheellabel:SetText("Enable zooming with mouse wheel.\n+CTRL: Precise\n+SHIFT: Fast")
|
||||
self.mwheellabel:SetWrap(true)
|
||||
self.mwheellabel:SetAutoStretchVertical(true)
|
||||
|
||||
self.smoothcheckbox = vgui.Create("DCheckBoxLabel", self.zoomsettings)
|
||||
self.smoothcheckbox:SetText("Smooth zooming")
|
||||
self.smoothcheckbox:Dock(TOP)
|
||||
self.smoothcheckbox:SetDark(true)
|
||||
self.smoothcheckbox:DockMargin(0,SETTING_MARGIN_TOP,0,0)
|
||||
self.smoothcheckbox:SetConVar("pac_zoom_smooth")
|
||||
|
||||
self.smoothlabel = vgui.Create("DLabel", self.zoomsettings)
|
||||
self.smoothlabel:Dock(TOP)
|
||||
self.smoothlabel:SetDark(true)
|
||||
self.smoothlabel:SetText("Enable smooth zooming.")
|
||||
self.smoothlabel:SetWrap(true)
|
||||
self.smoothlabel:SetAutoStretchVertical(true)
|
||||
|
||||
self.sliderpanel = vgui.Create("DPanel", self.zoomframe)
|
||||
self.sliderpanel:SetSize(180, 20)
|
||||
self.sliderpanel:Dock(TOP)
|
||||
|
||||
self.zoomslider = vgui.Create("DNumSlider", self.sliderpanel)
|
||||
self.zoomslider:DockPadding(4,0,0,0)
|
||||
self.zoomslider:SetSize(200, 20)
|
||||
self.zoomslider:SetMin( 0 )
|
||||
self.zoomslider:SetMax( 100 )
|
||||
self.zoomslider:SetDecimals( 0 )
|
||||
self.zoomslider:SetText("Camera FOV")
|
||||
self.zoomslider:SetDark(true)
|
||||
self.zoomslider:SetDefaultValue( 75 )
|
||||
|
||||
if zoom_persistent:GetInt() == 1 then
|
||||
self.zoomslider:SetValue( pace.ViewFOV )
|
||||
else
|
||||
self.zoomslider:SetValue( 75 )
|
||||
end
|
||||
|
||||
self.btnClose.Paint = function() end
|
||||
|
||||
self:SetBottom(pnl)
|
||||
|
||||
self:SetCookieName("pac3_editor")
|
||||
self:SetPos(self:GetCookieNumber("x"), BAR_SIZE)
|
||||
|
||||
self:MakeBar()
|
||||
self.lastTopBarHover = 0
|
||||
self.rendertime_data = {}
|
||||
self.okay = true
|
||||
end
|
||||
|
||||
function PANEL:OnMousePressed()
|
||||
if self.m_bSizable and gui.MouseX() > ( self.x + self:GetWide() - 20 ) then
|
||||
self.Sizing = { gui.MouseX() - self:GetWide(), gui.MouseY() - self:GetTall() }
|
||||
self:MouseCapture( true )
|
||||
return
|
||||
end
|
||||
|
||||
if self:GetDraggable() and gui.MouseY() < (self.y + 24) then
|
||||
self.Dragging = { gui.MouseX() - self.x, gui.MouseY() - self.y }
|
||||
self:MouseCapture( true )
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:OnMouseReleased(mc)
|
||||
if mc == MOUSE_RIGHT then
|
||||
self:Close()
|
||||
end
|
||||
|
||||
self.BaseClass.OnMouseReleased(self,mc)
|
||||
|
||||
end
|
||||
|
||||
function PANEL:MakeBar()
|
||||
if self.menu_bar:IsValid() then self.menu_bar:Remove() end
|
||||
|
||||
local bar = vgui.Create("DMenuBar", self)
|
||||
bar:SetSize(self:GetWide(), BAR_SIZE)
|
||||
pace.Call("MenuBarPopulate", bar)
|
||||
pace.MenuBar = bar
|
||||
|
||||
self.menu_bar = bar
|
||||
|
||||
self:DockMargin(2, 2, 2, 2)
|
||||
self:DockPadding(2, 2, 2, 2)
|
||||
end
|
||||
|
||||
function PANEL:OnRemove()
|
||||
if self.menu_bar:IsValid() then
|
||||
self.menu_bar:Remove()
|
||||
end
|
||||
|
||||
if self.exit_button:IsValid() then
|
||||
self.exit_button:Remove()
|
||||
end
|
||||
|
||||
if self.zoomframe:IsValid() then
|
||||
self.zoomframe:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Think(...)
|
||||
if not self.okay then return end
|
||||
DFrame.Think(self, ...)
|
||||
|
||||
if self.Hovered and self.m_bSizable and gui.MouseX() > (self.x + self:GetWide() - 20) then
|
||||
self:SetCursor("sizewe")
|
||||
return
|
||||
end
|
||||
|
||||
for k,v in pairs(pac.GetRenderTimeInfo(pac.LocalPlayer)) do
|
||||
self.rendertime_data[k] = Lerp(0.03, self.rendertime_data[k] or 0, v)
|
||||
end
|
||||
|
||||
local bar = self.menu_bar
|
||||
|
||||
self:SetTall(ScrH())
|
||||
local w = math.max(self:GetWide(), 200)
|
||||
self:SetWide(w)
|
||||
self:SetPos(math.Clamp(self:GetPos(), 0, ScrW() - w), 0)
|
||||
|
||||
if x ~= self.last_x then
|
||||
self:SetCookie("x", x)
|
||||
self.last_x = x
|
||||
end
|
||||
|
||||
if self.exit_button:IsValid() then
|
||||
|
||||
if self:GetPos() + self:GetWide() / 2 < ScrW() / 2 then
|
||||
self.exit_button:SetPos(ScrW() - self.exit_button:GetWide() + 4, -4)
|
||||
else
|
||||
self.exit_button:SetPos(-4, -4)
|
||||
end
|
||||
end
|
||||
|
||||
if self.zoomframe:IsValid() then
|
||||
|
||||
self.zoomsettings:InvalidateLayout( true )
|
||||
self.zoomsettings:SizeToChildren( false, true )
|
||||
|
||||
self.zoomframe:InvalidateLayout( true )
|
||||
self.zoomframe:SizeToChildren( false, true )
|
||||
|
||||
if self:GetPos() + self:GetWide() / 2 < ScrW() / 2 then
|
||||
self.zoomframe:SetPos(ScrW() - self.zoomframe:GetWide(), ScrH() - self.zoomframe:GetTall())
|
||||
|
||||
else
|
||||
self.zoomframe:SetPos(0,ScrH() - self.zoomframe:GetTall())
|
||||
end
|
||||
|
||||
local x, y = self.zoomframe:GetPos()
|
||||
|
||||
if pace.timeline.IsActive() then
|
||||
self.zoomframe:SetPos(x,y-pace.timeline.frame:GetTall())
|
||||
end
|
||||
|
||||
if pace.zoom_reset then
|
||||
self.zoomslider:SetValue(75)
|
||||
pace.zoom_reset = nil
|
||||
end
|
||||
|
||||
if zoom_smooth:GetInt() == 1 then
|
||||
pace.SetZoom(self.zoomslider:GetValue(),true)
|
||||
else
|
||||
pace.SetZoom(self.zoomslider:GetValue(),false)
|
||||
end
|
||||
|
||||
local mx, my = input.GetCursorPos()
|
||||
local x, y = self.zoomframe:GetPos()
|
||||
local xs, xy = self.zoomframe:GetSize()
|
||||
|
||||
if mx > x and my > y and mx < x + xs and my < y + xy then
|
||||
self.zoomsettings:SetVisible(true)
|
||||
self.zoomsettings:RequestFocus()
|
||||
else
|
||||
self.zoomsettings:SetVisible(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local auto_size = CreateClientConVar("pac_auto_size_properties", 1, true)
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
if not self.okay then return end
|
||||
|
||||
DFrame.PerformLayout(self)
|
||||
|
||||
for i, val in pairs(self.pac3_PanelsToRemove) do
|
||||
if IsValid(self[val]) then
|
||||
self[val].SetSize(self[val], 0, 0) -- Hacky
|
||||
end
|
||||
end
|
||||
|
||||
if self.old_part ~= pace.current_part then
|
||||
self.div:InvalidateLayout()
|
||||
self.bottom:PerformLayout()
|
||||
pace.properties:PerformLayout()
|
||||
self.old_part = pace.current_part
|
||||
|
||||
local sz = auto_size:GetInt()
|
||||
|
||||
if sz > 0 then
|
||||
local newh = sz > 0 and (ScrH() - math.min(pace.properties:GetHeight() + RENDERSCORE_SIZE + BAR_SIZE - 6, ScrH() / 1.5))
|
||||
|
||||
if sz >= 2 then
|
||||
local oldh = self.div:GetTopHeight()
|
||||
|
||||
if newh<oldh then
|
||||
self.div:SetTopHeight(newh)
|
||||
end
|
||||
elseif sz >= 1 then
|
||||
self.div:SetTopHeight(newh)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetTop(pnl)
|
||||
self.top = pnl
|
||||
self.div:SetTop(pnl)
|
||||
end
|
||||
|
||||
function PANEL:SetBottom(pnl)
|
||||
self.bottom = pnl
|
||||
self.div:SetBottom(pnl)
|
||||
end
|
||||
|
||||
pace.Focused = false
|
||||
|
||||
function pace.IsFocused()
|
||||
return pace.Focused
|
||||
end
|
||||
|
||||
local fade_time = 0.1
|
||||
|
||||
function pace.GainFocus(show_editor)
|
||||
local self = pace.Editor
|
||||
if self:IsValid() then
|
||||
if self.allowclick ~= false then
|
||||
self:MakePopup()
|
||||
pace.Focused = true
|
||||
|
||||
timer.Remove("pac_editor_visibility")
|
||||
|
||||
self:SetVisible(true)
|
||||
self.exit_button:SetVisible(true)
|
||||
self.zoomframe:SetVisible(true)
|
||||
|
||||
self:AlphaTo(255, fade_time, 0)
|
||||
self.exit_button:AlphaTo(255, fade_time, 0)
|
||||
self.zoomframe:AlphaTo(255, fade_time, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function pace.KillFocus(show_editor)
|
||||
local self = pace.Editor
|
||||
if self:IsValid() then
|
||||
self:KillFocus()
|
||||
self:SetMouseInputEnabled(false)
|
||||
self:SetKeyBoardInputEnabled(false)
|
||||
gui.EnableScreenClicker(false)
|
||||
pace.Focused = false
|
||||
|
||||
if not show_editor then
|
||||
self:AlphaTo(0, fade_time, 0)
|
||||
self.exit_button:AlphaTo(0, fade_time, 0)
|
||||
self.zoomframe:AlphaTo(0, fade_time, 0)
|
||||
|
||||
timer.Create("pac_editor_visibility", fade_time, 1, function()
|
||||
self:SetVisible(false)
|
||||
self.exit_button:SetVisible(false)
|
||||
self.zoomframe:SetVisible(false)
|
||||
end)
|
||||
end
|
||||
|
||||
self.allowclick = false
|
||||
|
||||
timer.Simple(0.2, function()
|
||||
if self:IsValid() then
|
||||
self.allowclick = true
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local drawProfileInfos = 0
|
||||
local textCol, drawBox
|
||||
local boxW, boxH
|
||||
|
||||
local function drawTimeBox(text, time, x, y)
|
||||
local str = string.format("%s: %.3f ms", L(text), time)
|
||||
drawBox(x, y, boxW - 5, RENDERSCORE_SIZE - 1)
|
||||
|
||||
surface.SetTextPos(x + 5, y)
|
||||
surface.DrawText(str)
|
||||
return y + RENDERSCORE_SIZE
|
||||
end
|
||||
|
||||
local function PostRenderVGUI()
|
||||
|
||||
end
|
||||
|
||||
pac.AddHook('PostRenderVGUI', 'pac_DrawProfileInfos', PostRenderVGUI)
|
||||
|
||||
function PANEL:PaintOver(w, h)
|
||||
if not self.okay then return end
|
||||
textCol = self:GetSkin().Colours.Category.Line.Text
|
||||
local text = _G.PAC_VERSION and PAC_VERSION()
|
||||
if text then
|
||||
surface.SetFont("DermaDefault")
|
||||
local x, y = self:LocalToScreen()
|
||||
local w, h = surface.GetTextSize(text)
|
||||
x = x + self:GetWide() + 4
|
||||
y = y + self:GetTall() - 4 - h
|
||||
|
||||
local mx, my = gui.MousePos()
|
||||
local cx, cy = self:LocalToScreen(x, y)
|
||||
|
||||
local hovering = false
|
||||
DisableClipping(true)
|
||||
|
||||
if mx > x and mx < x + w and my > y and my < y + h then
|
||||
hovering = true
|
||||
text = "pac version: " .. text
|
||||
w, h = surface.GetTextSize(text)
|
||||
|
||||
surface.SetDrawColor(0,0,0,255)
|
||||
surface.DrawRect(x,y,w,h)
|
||||
end
|
||||
|
||||
surface.SetTextPos(x,y)
|
||||
surface.SetTextColor(255,255,255,hovering and 255 or 100)
|
||||
surface.DrawText(text)
|
||||
DisableClipping(false )
|
||||
end
|
||||
|
||||
local data = self.rendertime_data
|
||||
|
||||
local x = 2
|
||||
local y = 2
|
||||
y = y + self.menu_bar:GetTall()
|
||||
y = y + self.top:GetTall()
|
||||
boxW, boxH = w, h
|
||||
|
||||
surface.SetFont(pace.CurrentFont)
|
||||
|
||||
textCol = self:GetSkin().Colours.Category.Line.Text
|
||||
drawBox = self:GetSkin().tex.Menu_Strip
|
||||
surface.SetTextColor(textCol)
|
||||
cam.IgnoreZ(true)
|
||||
|
||||
local total = 0
|
||||
for k,v in pairs(data) do
|
||||
total = total + v
|
||||
end
|
||||
|
||||
local str = string.format("%s: %.3f ms", L("average render time"), total * 1000)
|
||||
drawBox(x, y, w - 5, RENDERSCORE_SIZE - 1)
|
||||
|
||||
local mx, my = input.GetCursorPos()
|
||||
local cx, cy = self:LocalToScreen(x, y)
|
||||
|
||||
if cx <= mx and cy <= my and mx <= cx + w - 5 and my <= cy + RENDERSCORE_SIZE - 1 and self:IsChildHovered() then
|
||||
surface.SetFont(pace.CurrentFont)
|
||||
surface.SetTextColor(textCol)
|
||||
|
||||
local x, y = input.GetCursorPos()
|
||||
x = x + 3
|
||||
y = y + 3
|
||||
|
||||
DisableClipping(true)
|
||||
for type, time in pairs(self.rendertime_data) do
|
||||
y = drawTimeBox(type, time * 1000, x, y)
|
||||
end
|
||||
DisableClipping(false)
|
||||
end
|
||||
|
||||
surface.SetTextPos(x + 5, y)
|
||||
surface.DrawText(str)
|
||||
cam.IgnoreZ(false)
|
||||
end
|
||||
|
||||
function PANEL:Paint(w,h)
|
||||
if not self.okay then return end
|
||||
|
||||
|
||||
--surface.SetDrawColor(0, 0, 0, 255)
|
||||
--surface.DrawRect(0,0,w,h)
|
||||
-- there are some skins that have a transparent dframe
|
||||
-- so the categories that the properties draw will be transparent
|
||||
|
||||
self:GetSkin().tex.Tab_Control( 0, 0, w, h )
|
||||
|
||||
--DFrame.Paint(self, w,h)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
767
lua/pac3/editor/client/panels/extra_properties.lua
Normal file
767
lua/pac3/editor/client/panels/extra_properties.lua
Normal file
@@ -0,0 +1,767 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
local L = pace.LanguageString
|
||||
|
||||
local function populate_part_menu(menu, part, func)
|
||||
if part:HasChildren() then
|
||||
local menu, pnl = menu:AddSubMenu(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName(), function()
|
||||
func(part)
|
||||
end)
|
||||
|
||||
pnl:SetImage(part.Icon)
|
||||
|
||||
for key, part in ipairs(part:GetChildren()) do
|
||||
populate_part_menu(menu, part, func)
|
||||
end
|
||||
else
|
||||
menu:AddOption(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName(), function()
|
||||
func(part)
|
||||
end):SetImage(part.Icon)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function get_friendly_name(ent)
|
||||
if not IsValid(ent) then return "NULL" end
|
||||
local name = ent.GetName and ent:GetName()
|
||||
if not name or name == "" then
|
||||
name = ent:GetClass()
|
||||
end
|
||||
|
||||
if ent:EntIndex() == -1 then
|
||||
|
||||
if name == "10C_BaseFlex" then
|
||||
return "csentity - " .. ent:GetModel()
|
||||
end
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
if ent == pac.LocalPlayer then
|
||||
return name
|
||||
end
|
||||
|
||||
return ent:EntIndex() .. " - " .. name
|
||||
end
|
||||
|
||||
do -- bone
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_bone"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:MoreOptionsLeftClick()
|
||||
if not pace.current_part:IsValid() or not pace.current_part:GetParentOwner():IsValid() then return end
|
||||
|
||||
pace.SelectBone(pace.current_part:GetParentOwner(), function(data)
|
||||
if not self:IsValid() then return end
|
||||
self:SetValue(L(data.friendly))
|
||||
self.OnValueChanged(data.friendly)
|
||||
end, pace.current_part.ClassName == "bone" or pace.current_part.ClassName == "timeline_dummy_bone")
|
||||
end
|
||||
|
||||
function PANEL:MoreOptionsRightClick()
|
||||
local bones = pac.GetModelBones(pace.current_part:GetParentOwner())
|
||||
|
||||
local menu = DermaMenu()
|
||||
|
||||
menu:MakePopup()
|
||||
|
||||
local list = {}
|
||||
for k,v in pairs(bones) do
|
||||
table.insert(list, v.friendly)
|
||||
end
|
||||
|
||||
pace.CreateSearchList(
|
||||
self,
|
||||
self.CurrentKey,
|
||||
L"bones",
|
||||
function(list)
|
||||
list:AddColumn(L"name")
|
||||
end,
|
||||
function()
|
||||
return list
|
||||
end,
|
||||
function()
|
||||
return pace.current_part:GetBone()
|
||||
end,
|
||||
function(list, key, val)
|
||||
return list:AddLine(val)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- part
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_part"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:EncodeEdit(uid)
|
||||
local part = pac.GetPartFromUniqueID(pac.Hash(pac.LocalPlayer), uid)
|
||||
|
||||
if part:IsValid() then
|
||||
return part:GetName()
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
|
||||
function PANEL:DecodeEdit(name)
|
||||
|
||||
if name:Trim() ~= "" then
|
||||
local part = pac.FindPartByName(pac.Hash(pac.LocalPlayer), name, pace.current_part)
|
||||
if part:IsValid() then
|
||||
return part:GetUniqueID()
|
||||
end
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
|
||||
function PANEL:OnValueSet(val)
|
||||
if not IsValid(self.part) then return end
|
||||
local part = pac.GetPartFromUniqueID(pac.Hash(pac.LocalPlayer), val)
|
||||
|
||||
if IsValid(self.Icon) then self.Icon:Remove() end
|
||||
|
||||
|
||||
if not part:IsValid() then
|
||||
if self.CurrentKey == "TargetEntityUID" then
|
||||
local owner = pace.current_part:GetOwner()
|
||||
self:SetText(" " .. get_friendly_name(owner))
|
||||
local pnl = vgui.Create("DImage", self)
|
||||
pnl:SetImage(pace.GroupsIcons.entity)
|
||||
self.Icon = pnl
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if self.CurrentKey == "TargetEntityUID" then
|
||||
if part.Owner:IsValid() then
|
||||
local owner = part:GetOwner()
|
||||
self:SetText(" " .. part:GetName())
|
||||
else
|
||||
local owner = part:GetOwner()
|
||||
self:SetText(" " .. get_friendly_name(owner))
|
||||
end
|
||||
local pnl = vgui.Create("DImage", self)
|
||||
pnl:SetImage(pace.GroupsIcons.entity)
|
||||
self.Icon = pnl
|
||||
return
|
||||
end
|
||||
|
||||
self:SetText(" " .. (pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName()))
|
||||
|
||||
if
|
||||
GetConVar("pac_editor_model_icons"):GetBool() and
|
||||
part.is_model_part and
|
||||
part.GetModel and
|
||||
part:GetOwner():IsValid() and
|
||||
part.ClassName ~= "entity2" and
|
||||
part.ClassName ~= "weapon" -- todo: is_model_part is true, class inheritance issues?
|
||||
then
|
||||
local pnl = vgui.Create("SpawnIcon", self)
|
||||
pnl:SetModel(part:GetOwner():GetModel() or "")
|
||||
self.Icon = pnl
|
||||
elseif isstring(part.Icon) then
|
||||
local pnl = vgui.Create("DImage", self)
|
||||
pnl:SetImage(part.Icon)
|
||||
self.Icon = pnl
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
if not IsValid(self.Icon) then return end
|
||||
self:SetTextInset(11, 0)
|
||||
self.Icon:SetPos(4,0)
|
||||
surface.SetFont(pace.CurrentFont)
|
||||
local w,h = surface.GetTextSize(".")
|
||||
h = h / 1.5
|
||||
self.Icon:SetSize(h, h)
|
||||
self.Icon:CenterVertical()
|
||||
end
|
||||
|
||||
function PANEL:MoreOptionsLeftClick()
|
||||
pace.SelectPart(pac.GetLocalParts(), function(part)
|
||||
if not self:IsValid() then return end
|
||||
self:SetValue(part:GetUniqueID())
|
||||
self.OnValueChanged(part)
|
||||
end)
|
||||
end
|
||||
|
||||
function PANEL:MoreOptionsRightClick(key)
|
||||
local menu = DermaMenu()
|
||||
|
||||
menu:MakePopup()
|
||||
|
||||
for _, part in pairs(pac.GetLocalParts()) do
|
||||
if not part:HasParent() and part:GetShowInEditor() then
|
||||
populate_part_menu(menu, part, function(part)
|
||||
if not self:IsValid() then return end
|
||||
self:SetValue(part:GetUniqueID())
|
||||
self.OnValueChanged(part)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if key ~= "ParentUID" then
|
||||
menu:AddOption("none", function()
|
||||
self:SetValue("")
|
||||
self.OnValueChanged("")
|
||||
end):SetImage(pace.MiscIcons.clear)
|
||||
end
|
||||
|
||||
pace.FixMenu(menu)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- owner
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_ownername"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:MoreOptionsLeftClick()
|
||||
pace.SelectEntity(function(ent)
|
||||
if not self:IsValid() then return end
|
||||
pace.current_part:SetOwnerName(ent:EntIndex())
|
||||
local name = pace.current_part:GetOwnerName()
|
||||
self.OnValueChanged(name)
|
||||
self:SetValue(L(name))
|
||||
end)
|
||||
end
|
||||
|
||||
function PANEL:MoreOptionsRightClick()
|
||||
local menu = DermaMenu()
|
||||
menu:MakePopup()
|
||||
|
||||
for key, name in pairs(pac.OwnerNames) do
|
||||
menu:AddOption(name, function() pace.current_part:SetOwnerName(name) self.OnValueChanged(name) end)
|
||||
end
|
||||
|
||||
local entities = menu:AddSubMenu(L"entities", function() end)
|
||||
entities.GetDeleteSelf = function() return false end
|
||||
for _, ent in pairs(ents.GetAll()) do
|
||||
if ent:EntIndex() > 0 then
|
||||
entities:AddOption(get_friendly_name(ent), function()
|
||||
pace.current_part:SetOwnerName(ent:EntIndex())
|
||||
self.OnValueChanged(ent:EntIndex())
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
pace.FixMenu(menu)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- sequence list
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_sequence"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:MoreOptionsLeftClick()
|
||||
pace.CreateSearchList(
|
||||
self,
|
||||
self.CurrentKey,
|
||||
L"animations",
|
||||
|
||||
function(list)
|
||||
list:AddColumn(L"id"):SetFixedWidth(25)
|
||||
list:AddColumn(L"name")
|
||||
end,
|
||||
|
||||
function()
|
||||
return pace.current_part:GetSequenceList()
|
||||
end,
|
||||
|
||||
function()
|
||||
return pace.current_part.SequenceName or pace.current_part.GestureName
|
||||
end,
|
||||
|
||||
function(list, key, val)
|
||||
return list:AddLine(key, val)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
|
||||
do -- model
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_model"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:MoreOptionsRightClick()
|
||||
pace.SafeRemoveSpecialPanel()
|
||||
g_SpawnMenu:Open()
|
||||
end
|
||||
|
||||
function PANEL:MoreOptionsLeftClick(key)
|
||||
pace.close_spawn_menu = true
|
||||
pace.SafeRemoveSpecialPanel()
|
||||
|
||||
local part = pace.current_part
|
||||
|
||||
|
||||
pace.AssetBrowser(function(path)
|
||||
if not part:IsValid() then return end
|
||||
-- because we refresh the properties
|
||||
|
||||
if IsValid(self) and self.OnValueChanged then
|
||||
self.OnValueChanged(path)
|
||||
end
|
||||
|
||||
if pace.current_part.SetMaterials then
|
||||
local model = pace.current_part:GetModel()
|
||||
local part = pace.current_part
|
||||
if part.pace_last_model and part.pace_last_model ~= model then
|
||||
part:SetMaterials("")
|
||||
end
|
||||
part.pace_last_model = model
|
||||
end
|
||||
|
||||
pace.PopulateProperties(pace.current_part)
|
||||
|
||||
for k,v in ipairs(pace.properties.List) do
|
||||
if v.panel and v.panel.part == part and v.key == key then
|
||||
self = v.panel
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
end, "models")
|
||||
|
||||
pac.AddHook("Think", "pace_close_browser", function()
|
||||
if part ~= pace.current_part then
|
||||
pac.RemoveHook("Think", "pace_close_browser")
|
||||
pace.model_browser:SetVisible(false)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- materials and textures
|
||||
local PANEL_MATERIAL = {}
|
||||
|
||||
PANEL_MATERIAL.ClassName = "properties_material"
|
||||
PANEL_MATERIAL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL_MATERIAL:MoreOptionsLeftClick(key)
|
||||
pace.AssetBrowser(function(path)
|
||||
if not self:IsValid() then return end
|
||||
path = path:match("materials/(.+)%.vmt") or "error"
|
||||
self:SetValue(path)
|
||||
self.OnValueChanged(path)
|
||||
end, "materials", key)
|
||||
end
|
||||
|
||||
function PANEL_MATERIAL:MoreOptionsRightClick()
|
||||
pace.SafeRemoveSpecialPanel()
|
||||
|
||||
local pnl = pace.CreatePanel("mat_browser")
|
||||
|
||||
pace.ShowSpecial(pnl, self, 300)
|
||||
|
||||
function pnl.MaterialSelected(_, path)
|
||||
self:SetValue(path)
|
||||
self.OnValueChanged(path)
|
||||
end
|
||||
|
||||
pace.ActiveSpecialPanel = pnl
|
||||
end
|
||||
|
||||
local PANEL = {}
|
||||
local pace_material_display
|
||||
|
||||
PANEL.ClassName = "properties_textures"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:MoreOptionsLeftClick()
|
||||
pace.AssetBrowser(function(path)
|
||||
if not self:IsValid() then return end
|
||||
path = path:match("materials/(.+)%.vtf") or "error"
|
||||
self:SetValue(path)
|
||||
self.OnValueChanged(path)
|
||||
end, "textures")
|
||||
end
|
||||
|
||||
function PANEL:MoreOptionsRightClick()
|
||||
pace.SafeRemoveSpecialPanel()
|
||||
|
||||
local pnl = pace.CreatePanel("mat_browser")
|
||||
|
||||
pace.ShowSpecial(pnl, self, 300)
|
||||
|
||||
function pnl.MaterialSelected(_, path)
|
||||
self:SetValue(path)
|
||||
self.OnValueChanged(path)
|
||||
end
|
||||
|
||||
pace.ActiveSpecialPanel = pnl
|
||||
end
|
||||
|
||||
function PANEL:HUDPaint()
|
||||
if IsValid(self.editing) then return self:MustHideTexture() end
|
||||
-- Near Button?
|
||||
-- local w, h = self:GetSize()
|
||||
-- local x, y = self:LocalToScreen(w, 0)
|
||||
|
||||
-- Near cursor
|
||||
local W, H = ScrW(), ScrH()
|
||||
local x, y = input.GetCursorPos()
|
||||
local w, h = 256, 256
|
||||
x = x + 12
|
||||
y = y + 4
|
||||
|
||||
if x + w > W then
|
||||
x = x - w - 24
|
||||
end
|
||||
|
||||
if y + h > H then
|
||||
y = y - h - 8
|
||||
end
|
||||
|
||||
surface.SetDrawColor(255, 255, 255, 255)
|
||||
surface.SetAlphaMultiplier(1)
|
||||
surface.SetMaterial(pace_material_display)
|
||||
surface.DrawTexturedRect(x, y, w, h)
|
||||
end
|
||||
|
||||
PANEL_MATERIAL.HUDPaint = PANEL.HUDPaint
|
||||
|
||||
function PANEL:MustShowTexture()
|
||||
if self.isShownTexture then return end
|
||||
|
||||
if not pace_material_display then
|
||||
pace_material_display = CreateMaterial('pace_material_display', "UnlitGeneric", {})
|
||||
end
|
||||
|
||||
if pace.current_part[self.CurrentKey] then
|
||||
if pace.current_part[self.CurrentKey] == "" then
|
||||
pace_material_display:SetTexture("$basetexture", "models/debug/debugwhite")
|
||||
elseif not string.find(pace.current_part[self.CurrentKey], '^https?://') then
|
||||
pace_material_display:SetTexture("$basetexture", pace.current_part[self.CurrentKey])
|
||||
else
|
||||
local function callback(mat, tex)
|
||||
if not tex then return end
|
||||
pace_material_display:SetTexture("$basetexture", tex)
|
||||
end
|
||||
|
||||
pac.urltex.GetMaterialFromURL(pace.current_part[self.CurrentKey], callback, false, 'UnlitGeneric')
|
||||
end
|
||||
end
|
||||
|
||||
local id = tostring(self)
|
||||
pac.AddHook("PostRenderVGUI", id, function()
|
||||
if self:IsValid() then
|
||||
self:HUDPaint()
|
||||
else
|
||||
pac.RemoveHook("PostRenderVGUI", id)
|
||||
end
|
||||
end)
|
||||
self.isShownTexture = true
|
||||
end
|
||||
|
||||
PANEL_MATERIAL.MustShowTexture = PANEL.MustShowTexture
|
||||
|
||||
function PANEL:MustHideTexture()
|
||||
if not self.isShownTexture then return end
|
||||
self.isShownTexture = false
|
||||
pac.RemoveHook('PostRenderVGUI', tostring(self))
|
||||
end
|
||||
|
||||
PANEL_MATERIAL.MustHideTexture = PANEL.MustHideTexture
|
||||
|
||||
function PANEL:ThinkTextureDisplay()
|
||||
if self.preTextureThink then self:preTextureThink() end
|
||||
if not IsValid(self.textureButton) or IsValid(self.editing) then return end
|
||||
local rTime = RealTime()
|
||||
self.lastHovered = self.lastHovered or rTime
|
||||
|
||||
if not self.textureButton:IsHovered() and not self:IsHovered() then
|
||||
self.lastHovered = rTime
|
||||
end
|
||||
|
||||
if self.lastHovered + 0.5 < rTime then
|
||||
self:MustShowTexture()
|
||||
else
|
||||
self:MustHideTexture()
|
||||
end
|
||||
end
|
||||
|
||||
PANEL_MATERIAL.ThinkTextureDisplay = PANEL.ThinkTextureDisplay
|
||||
|
||||
function PANEL:OnMoreOptionsLeftClickButton(btn)
|
||||
self.preTextureThink = self.Think
|
||||
self.Think = self.ThinkTextureDisplay
|
||||
self.textureButton = btn
|
||||
end
|
||||
|
||||
PANEL_MATERIAL.OnMoreOptionsLeftClickButton = PANEL.OnMoreOptionsLeftClickButton
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
pace.RegisterPanel(PANEL_MATERIAL)
|
||||
end
|
||||
|
||||
|
||||
do -- sound
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_sound"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:MoreOptionsLeftClick()
|
||||
pace.AssetBrowser(function(path)
|
||||
if not self:IsValid() then return end
|
||||
|
||||
self:SetValue(path)
|
||||
self.OnValueChanged(path)
|
||||
|
||||
if pace.current_part:IsValid() then
|
||||
pace.current_part:OnShow()
|
||||
end
|
||||
end, "sound")
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- script
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_code"
|
||||
PANEL.Base = "pace_properties_base_type"
|
||||
|
||||
function PANEL:MoreOptionsLeftClick()
|
||||
pace.SafeRemoveSpecialPanel()
|
||||
|
||||
local frame = vgui.Create("DFrame")
|
||||
frame:SetTitle(L"script")
|
||||
pace.ShowSpecial(frame, self, 512)
|
||||
frame:SetSizable(true)
|
||||
|
||||
local editor = vgui.Create("pace_luapad", frame)
|
||||
editor:Dock(FILL)
|
||||
|
||||
editor:SetText(pace.current_part:GetCode())
|
||||
editor.OnTextChanged = function(self)
|
||||
pace.current_part:SetCode(self:GetValue())
|
||||
end
|
||||
|
||||
editor.last_error = ""
|
||||
|
||||
function editor:CheckGlobal(str)
|
||||
local part = pace.current_part
|
||||
|
||||
if not part:IsValid() then frame:Remove() return end
|
||||
|
||||
return part:ShouldHighlight(str)
|
||||
end
|
||||
|
||||
function editor:Think()
|
||||
local part = pace.current_part
|
||||
|
||||
if not part:IsValid() then frame:Remove() return end
|
||||
|
||||
local title = L"script editor"
|
||||
|
||||
if part.Error then
|
||||
title = part.Error
|
||||
|
||||
local line = tonumber(title:match("SCRIPT_ENV:(%d-):"))
|
||||
|
||||
if line then
|
||||
title = title:match("SCRIPT_ENV:(.+)")
|
||||
if self.last_error ~= title then
|
||||
editor:SetScrollPosition(line)
|
||||
editor:SetErrorLine(line)
|
||||
self.last_error = title
|
||||
end
|
||||
end
|
||||
else
|
||||
editor:SetErrorLine(nil)
|
||||
|
||||
if part.script_printing then
|
||||
title = part.script_printing
|
||||
part.script_printing = nil
|
||||
end
|
||||
end
|
||||
|
||||
frame:SetTitle(title)
|
||||
end
|
||||
|
||||
pace.ActiveSpecialPanel = frame
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- hull
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_hull"
|
||||
PANEL.Base = "pace_properties_number"
|
||||
|
||||
function PANEL:OnValueSet()
|
||||
local function stop()
|
||||
RunConsoleCommand("-duck")
|
||||
hook.Remove("PostDrawOpaqueRenderables", "pace_draw_hull")
|
||||
end
|
||||
|
||||
local time = os.clock() + 3
|
||||
|
||||
hook.Add("PostDrawOpaqueRenderables", "pace_draw_hull", function()
|
||||
|
||||
if not pace.current_part:IsValid() then stop() return end
|
||||
if pace.current_part.ClassName ~= "entity2" then stop() return end
|
||||
|
||||
local ent = pace.current_part:GetOwner()
|
||||
if not ent.GetHull then stop() return end
|
||||
if not ent.GetHullDuck then stop() return end
|
||||
|
||||
local min, max = ent:GetHull()
|
||||
|
||||
if self.udata and self.udata.crouch then
|
||||
min, max = ent:GetHullDuck()
|
||||
RunConsoleCommand("+duck")
|
||||
end
|
||||
|
||||
min = min * ent:GetModelScale()
|
||||
max = max * ent:GetModelScale()
|
||||
|
||||
render.DrawWireframeBox( ent:GetPos(), Angle(0), min, max, Color(255, 204, 51, 255), true )
|
||||
|
||||
if time < os.clock() then
|
||||
stop()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- event ranger
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_ranger"
|
||||
PANEL.Base = "pace_properties_number"
|
||||
|
||||
function PANEL:OnValueSet()
|
||||
local function stop()
|
||||
hook.Remove("PostDrawOpaqueRenderables", "pace_draw_ranger")
|
||||
end
|
||||
|
||||
local last_part = pace.current_part
|
||||
|
||||
hook.Add("PostDrawOpaqueRenderables", "pace_draw_ranger", function()
|
||||
local part = pace.current_part
|
||||
if not part:IsValid() then stop() return end
|
||||
if part ~= last_part then stop() return end
|
||||
if part.ClassName ~= "event" then stop() return end
|
||||
if part:GetEvent() ~= "ranger" then stop() return end
|
||||
|
||||
local distance = part:GetProperty("distance")
|
||||
local compare = part:GetProperty("compare")
|
||||
local trigger = part.event_triggered
|
||||
local parent = part:GetParent()
|
||||
if not parent:IsValid() or not parent.GetWorldPosition then stop() return end
|
||||
local startpos = parent:GetWorldPosition()
|
||||
local endpos
|
||||
local color
|
||||
|
||||
if self.udata then
|
||||
if self.udata.ranger_property == "distance" then
|
||||
endpos = startpos + parent:GetWorldAngles():Forward() * distance
|
||||
color = Color(255,255,255)
|
||||
elseif self.udata.ranger_property == "compare" then
|
||||
endpos = startpos + parent:GetWorldAngles():Forward() * compare
|
||||
color = Color(10,255,10)
|
||||
end
|
||||
render.DrawLine( startpos, endpos, trigger and Color(255,0,0) or color)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
|
||||
do -- event is_touching
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "properties_is_touching"
|
||||
PANEL.Base = "pace_properties_number"
|
||||
|
||||
function PANEL:OnValueSet()
|
||||
local function stop()
|
||||
hook.Remove("PostDrawOpaqueRenderables", "pace_draw_is_touching")
|
||||
end
|
||||
local last_part = pace.current_part
|
||||
|
||||
hook.Add("PostDrawOpaqueRenderables", "pace_draw_is_touching", function()
|
||||
local part = pace.current_part
|
||||
if part ~= last_part then stop() return end
|
||||
if not part:IsValid() then stop() return end
|
||||
if part.ClassName ~= "event" then stop() return end
|
||||
if part:GetEvent() ~= "is_touching" then stop() return end
|
||||
|
||||
local extra_radius = part:GetProperty("extra_radius") or 0
|
||||
local ent
|
||||
if part.RootOwner then
|
||||
ent = part:GetRootPart():GetOwner()
|
||||
else
|
||||
ent = part:GetOwner()
|
||||
end
|
||||
|
||||
if not IsValid(ent) then stop() return end
|
||||
local radius = ent:BoundingRadius()
|
||||
|
||||
if radius == 0 and IsValid(ent.pac_projectile) then
|
||||
radius = ent.pac_projectile:GetRadius()
|
||||
end
|
||||
|
||||
radius = math.max(radius + extra_radius + 1, 1)
|
||||
|
||||
local mins = Vector(-1,-1,-1)
|
||||
local maxs = Vector(1,1,1)
|
||||
local startpos = ent:WorldSpaceCenter()
|
||||
mins = mins * radius
|
||||
maxs = maxs * radius
|
||||
|
||||
local tr = util.TraceHull( {
|
||||
start = startpos,
|
||||
endpos = startpos,
|
||||
maxs = maxs,
|
||||
mins = mins,
|
||||
filter = ent
|
||||
} )
|
||||
|
||||
if self.udata then
|
||||
render.DrawWireframeBox( startpos, Angle( 0, 0, 0 ), mins, maxs, tr.Hit and Color(255,0,0) or Color(255,255,255), true )
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
end
|
||||
110
lua/pac3/editor/client/panels/list.lua
Normal file
110
lua/pac3/editor/client/panels/list.lua
Normal file
@@ -0,0 +1,110 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
local function list(mid, name, store, populate)
|
||||
local list = vgui.Create("DListView", mid)
|
||||
list:AddColumn(name)
|
||||
|
||||
function list:Refresh()
|
||||
self:Clear()
|
||||
|
||||
self.data = populate()
|
||||
|
||||
for _, kv in ipairs(self.data) do
|
||||
self:AddLine(kv.name)
|
||||
end
|
||||
end
|
||||
|
||||
function list:Store()
|
||||
for _, line in ipairs(list:GetSelected()) do
|
||||
local i = line:GetID()
|
||||
local kv = self.data[i]
|
||||
if kv then
|
||||
store(kv)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function list:Populate()
|
||||
self:Clear()
|
||||
self.data = populate()
|
||||
end
|
||||
|
||||
list:Refresh()
|
||||
|
||||
return list
|
||||
end
|
||||
|
||||
return function(form, name, props)
|
||||
local pnl = vgui.Create("Panel", form)
|
||||
pnl:SetTall(200)
|
||||
|
||||
pnl.left = list(pnl, props.name_left, props.store_left, props.populate_left)
|
||||
pnl.right = list(pnl, props.name_right, props.store_right, props.populate_right)
|
||||
|
||||
local button = vgui.Create("DButton", pnl)
|
||||
button:SetText(props.empty_message)
|
||||
|
||||
local store = function() end
|
||||
local selected_side = pnl.left
|
||||
|
||||
pnl.left.OnRowSelected = function()
|
||||
pnl.right:ClearSelection()
|
||||
store = function() pnl.left:Store() end
|
||||
button:SetText("add to " .. name)
|
||||
end
|
||||
|
||||
pnl.right.OnRowSelected = function()
|
||||
pnl.left:ClearSelection()
|
||||
store = function() pnl.right:Store() end
|
||||
button:SetText("remove from " .. name)
|
||||
end
|
||||
|
||||
local function select()
|
||||
if #pnl.left:GetLines() == 0 then
|
||||
selected_side = pnl.right
|
||||
end
|
||||
|
||||
if #pnl.right:GetLines() == 0 then
|
||||
selected_side = pnl.left
|
||||
end
|
||||
|
||||
selected_side:SelectFirstItem()
|
||||
end
|
||||
|
||||
button.DoClick = function()
|
||||
store()
|
||||
|
||||
pnl.left:Refresh()
|
||||
pnl.right:Refresh()
|
||||
|
||||
select()
|
||||
end
|
||||
|
||||
select()
|
||||
|
||||
pnl.Think = function()
|
||||
local p = 5
|
||||
local w = pnl:GetWide() / 2
|
||||
local h = pnl:GetTall() - button:GetTall() - p
|
||||
|
||||
pnl.left:SetWide(w)
|
||||
pnl.left:SetTall(h)
|
||||
|
||||
pnl.right:SetWide(w + 1)
|
||||
pnl.right:SetTall(h)
|
||||
|
||||
pnl.right:MoveRightOf(pnl.left, -1)
|
||||
|
||||
button:MoveBelow(pnl.left, p)
|
||||
button:CopyWidth(pnl)
|
||||
end
|
||||
end
|
||||
1055
lua/pac3/editor/client/panels/lua_editor.lua
Normal file
1055
lua/pac3/editor/client/panels/lua_editor.lua
Normal file
File diff suppressed because it is too large
Load Diff
673
lua/pac3/editor/client/panels/mat_browser.lua
Normal file
673
lua/pac3/editor/client/panels/mat_browser.lua
Normal file
@@ -0,0 +1,673 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
pace.Materials = {}
|
||||
|
||||
pace.Materials.materials =
|
||||
{
|
||||
"models/weapons/v_crowbar/crowbar_cyl",
|
||||
"models/weapons/v_crowbar/head_uvw",
|
||||
"models/weapons/v_bugbait/bugbait_sheet",
|
||||
"models/combine_advisor/arm",
|
||||
"models/combine_advisor/hose",
|
||||
"models/combine_advisor/face5",
|
||||
"models/combine_advisor/body9",
|
||||
"models/barnacle/barnacle_sheet",
|
||||
"models/headcrab_black/blackcrab_sheet",
|
||||
"models/headcrab/allinonebacup2",
|
||||
"models/headcrab_classic/headcrabsheet",
|
||||
"models/stalker/stalker_sheet",
|
||||
"models/zombie_poison/poisonzombie_sheet",
|
||||
"models/zombie_fast/fast_zombie_sheet",
|
||||
|
||||
"models/gunship/gunshipsheet",
|
||||
"models/shield_scanner/minelayer_sheet",
|
||||
"models/roller/rollermine_sheet",
|
||||
"models/dog/dog_sheet",
|
||||
"models/gibs/combine_helicopter_gibs/combine_helicopter01",
|
||||
"models/synth/mainbody",
|
||||
"models/combine_room/combine_monitor001",
|
||||
"models/items/combinerifle_ammo",
|
||||
"models/shadertest/shader2",
|
||||
"models/props_combine/combine_train001",
|
||||
"models/props_combine/combinethumper001",
|
||||
"models/props_combine/health_charger001",
|
||||
"models/props_combine/masterinterface01",
|
||||
"models/props_combine/introomarea_sheet",
|
||||
"models/props_combine/combine_bunker01",
|
||||
"models/props_combine/weaponstripper_sheet",
|
||||
"models/props_combine/tpcontroller_sheet",
|
||||
"models/props_combine/combine_tower01a",
|
||||
"models/combine_mine/combine_mine03",
|
||||
"models/magnusson_teleporter/magnusson_teleporter",
|
||||
"models/combine_strider/strider_brain",
|
||||
"models/combine_advisor_pod/combine_advisor_pod",
|
||||
"models/magnusson_device/magnusson_device_basecolor",
|
||||
|
||||
"models/antlion_grub/antlion_grub",
|
||||
"models/antlion/antlion_worker_wing",
|
||||
"models/antlion/antlion_worker",
|
||||
"models/ministrider/mini_skin_basecolor",
|
||||
"models/ministrider/mini_armor_basecolor",
|
||||
"models/spitball/spitball",
|
||||
|
||||
"models/mossman/mossman_hair",
|
||||
"models/alyx/hairbits",
|
||||
|
||||
"models/brokenglass/glassbroken_piece1",
|
||||
"models/props_halloween/flask",
|
||||
"models/props_halloween/flask_liquid",
|
||||
"models/props_halloween/flask_glass",
|
||||
"models/props_halloween/pumpkin",
|
||||
"models/props_mining/dustbowl_roof01",
|
||||
"models/props_mvm/mvm_museum_coal",
|
||||
"models/effects/partyhat",
|
||||
"models/props_gameplay/ball001",
|
||||
"models/props_gameplay/orange_cone001",
|
||||
|
||||
"models/player/items/soldier/dappertopper",
|
||||
"models/weapons/c_items/c_candy_cane_red",
|
||||
"models/props_halloween/halloween_blk",
|
||||
"models/props_halloween/halloween_demoeye_glass_2",
|
||||
"models/props_halloween/halloween_demoeye_glass",
|
||||
"models/weapons/c_items/c_saxxy",
|
||||
"models/props_halloween/scary_ghost",
|
||||
"models/weapons/c_items/c_urinejar_urine",
|
||||
"models/weapons/c_items/c_xms_cold_shoulder",
|
||||
"models/props_wasteland/rockcliff02c",
|
||||
"models/props_lakeside/flat_wall_02",
|
||||
"models/props_manor/table_01b",
|
||||
"models/props_manor/volume_light_01",
|
||||
"models/props_medieval/stone_base001",
|
||||
"models/props_medieval/fort_wall",
|
||||
"models/props_mining/quarryrock02",
|
||||
"models/props_nature/rock_worn001",
|
||||
"models/props_swamp/tallgrass_01",
|
||||
"models/props_swamp/shrub_03",
|
||||
"models/props_viaduct_event/fog_plane03",
|
||||
"models/weapons/v_baseball/baseball_sheet",
|
||||
"hunter/myplastic",
|
||||
"models/player/items/all_class/all_class_ring_diamond",
|
||||
|
||||
"models/effects/invulnfx_blue",
|
||||
"models/effects/invulnfx_red",
|
||||
"models/effects/goldenwrench",
|
||||
"models/effects/cappoint_beam_neutral",
|
||||
"models/effects/cappoint_beam_blue",
|
||||
"models/effects/cappoint_beam_red",
|
||||
"models/effects/medicyell",
|
||||
"models/effects/pyro/pilotlight",
|
||||
"models/effects/pyro/pilotlight_cloak",
|
||||
"models/effects/pyro/pilotlight_motion",
|
||||
"models/effects/invulnerability/invulnerability_red",
|
||||
"models/effects/invulnerability/invulnerability_blue",
|
||||
"models/effects/muzzleflash/blurmuzzle",
|
||||
"models/effects/muzzleflash/brightmuzzle",
|
||||
"models/lilchewchew/embers",
|
||||
"models/pl_hoodoo/metaldoor001",
|
||||
"models/thundermountain_fx/ibeam002_vert",
|
||||
"models/thundermountain_fx/wall025_vert",
|
||||
"models/thundermountain_fx/wood_beam03_vert",
|
||||
"models/thundermountain_fx/wood_bridge001_vert",
|
||||
"models/thundermountain_fx/wood_wall002_vert",
|
||||
|
||||
"models/shadertest/envball_1",
|
||||
"models/shadertest/envball_2",
|
||||
"models/shadertest/envball_3",
|
||||
"models/shadertest/envball_4",
|
||||
"models/shadertest/envball_5",
|
||||
"models/shadertest/envball_6",
|
||||
"models/shadertest/glassbrick",
|
||||
"models/shadertest/point_camera",
|
||||
"models/shadertest/shader1",
|
||||
"models/shadertest/shader1_dudv",
|
||||
"models/shadertest/shield",
|
||||
"models/shadertest/unlitgenericmodel",
|
||||
"models/shadertest/vertexlitalphatestedtexture",
|
||||
|
||||
"models/ihvtest/arm",
|
||||
"models/ihvtest/boot",
|
||||
"models/ihvtest/eyeball_l",
|
||||
|
||||
-- zpankr's material list
|
||||
-- http://www.garrysmod.org/downloads/?a=view&id=18470
|
||||
"models/wireframe",
|
||||
"debug/env_cubemap_model",
|
||||
"models/shadertest/shader3",
|
||||
"models/shadertest/shader4",
|
||||
"models/shadertest/shader5",
|
||||
"models/shiny",
|
||||
"models/debug/debugwhite",
|
||||
"Models/effects/comball_sphere",
|
||||
"Models/effects/comball_tape",
|
||||
"Models/effects/splodearc_sheet",
|
||||
"Models/effects/vol_light001",
|
||||
"models/props_combine/stasisshield_sheet",
|
||||
"models/props_combine/portalball001_sheet",
|
||||
"models/props_combine/com_shield001a",
|
||||
"models/props_c17/frostedglass_01a",
|
||||
"models/props_lab/Tank_Glass001",
|
||||
"models/props_combine/tprings_globe",
|
||||
"models/rendertarget",
|
||||
"models/screenspace",
|
||||
"brick/brick_model",
|
||||
"models/props_pipes/GutterMetal01a",
|
||||
"models/props_pipes/Pipesystem01a_skin3",
|
||||
"models/props_wasteland/wood_fence01a",
|
||||
"models/props_c17/FurnitureFabric003a",
|
||||
"models/props_c17/FurnitureMetal001a",
|
||||
"models/props_c17/paper01",
|
||||
"models/flesh",
|
||||
"models/airboat/airboat_blur02",
|
||||
"models/alyx/emptool_glow",
|
||||
"models/antlion/antlion_innards",
|
||||
"models/barnacle/roots",
|
||||
"models/combine_advisor/body9",
|
||||
"models/combine_advisor/mask",
|
||||
"models/combine_scanner/scanner_eye",
|
||||
"models/debug/debugwhite",
|
||||
"models/dog/eyeglass",
|
||||
"models/effects/comball_glow1",
|
||||
"models/effects/comball_glow2",
|
||||
"models/effects/portalrift_sheet",
|
||||
"models/effects/slimebubble_sheet",
|
||||
"models/effects/splode1_sheet",
|
||||
"models/effects/splodearc_sheet",
|
||||
"models/effects/splode_sheet",
|
||||
"models/effects/vol_light001",
|
||||
"models/gibs/woodgibs/woodgibs01",
|
||||
"models/gibs/woodgibs/woodgibs02",
|
||||
"models/gibs/woodgibs/woodgibs03",
|
||||
"models/gibs/metalgibs/metal_gibs",
|
||||
"models/items/boxsniperrounds",
|
||||
"models/player/player_chrome1",
|
||||
"models/props_animated_breakable/smokestack/brickwall002a",
|
||||
"models/props_building_details/courtyard_template001c_bars",
|
||||
"models/props_building_details/courtyard_template001c_bars",
|
||||
"models/props_buildings/destroyedbuilldingwall01a",
|
||||
"models/props_buildings/plasterwall021a",
|
||||
"models/props_c17/frostedglass_01a",
|
||||
"models/props_c17/furniturefabric001a",
|
||||
"models/props_c17/furniturefabric002a",
|
||||
"models/props_c17/furnituremetal001a",
|
||||
"models/props_c17/gate_door02a",
|
||||
"models/props_c17/metalladder001",
|
||||
"models/props_c17/metalladder002",
|
||||
"models/props_c17/metalladder003",
|
||||
"models/props_canal/canalmap_sheet",
|
||||
"models/props_canal/canal_bridge_railing_01a",
|
||||
"models/props_canal/canal_bridge_railing_01b",
|
||||
"models/props_canal/canal_bridge_railing_01c",
|
||||
"models/props_canal/coastmap_sheet",
|
||||
"models/props_canal/metalcrate001d",
|
||||
"models/props_canal/metalwall005b",
|
||||
"models/props_canal/rock_riverbed01a",
|
||||
"models/props_combine/citadel_cable",
|
||||
"models/props_combine/combine_interface_disp",
|
||||
"models/props_combine/combine_monitorbay_disp",
|
||||
"models/props_combine/com_shield001a",
|
||||
"models/props_combine/health_charger_glass",
|
||||
"models/props_combine/metal_combinebridge001",
|
||||
"models/props_combine/pipes01",
|
||||
"models/props_combine/pipes03",
|
||||
"models/props_combine/prtl_sky_sheet",
|
||||
"models/props_combine/stasisfield_beam",
|
||||
"models/props_debris/building_template010a",
|
||||
"models/props_debris/building_template022j",
|
||||
"models/props_debris/composite_debris",
|
||||
"models/props_debris/concretefloor013a",
|
||||
"models/props_debris/concretefloor020a",
|
||||
"models/props_debris/concretewall019a",
|
||||
"models/props_debris/metalwall001a",
|
||||
"models/props_debris/plasterceiling008a",
|
||||
"models/props_debris/plasterwall009d",
|
||||
"models/props_debris/plasterwall021a",
|
||||
"models/props_debris/plasterwall034a",
|
||||
"models/props_debris/plasterwall034d",
|
||||
"models/props_debris/plasterwall039c",
|
||||
"models/props_debris/plasterwall040c",
|
||||
"models/props_debris/tilefloor001c",
|
||||
"models/props_foliage/driftwood_01a",
|
||||
"models/props_foliage/oak_tree01",
|
||||
"models/props_interiors/metalfence007a",
|
||||
"models/props_junk/plasticcrate01a",
|
||||
"models/props_junk/plasticcrate01b",
|
||||
"models/props_junk/plasticcrate01c",
|
||||
"models/props_junk/plasticcrate01d",
|
||||
"models/props_junk/plasticcrate01e",
|
||||
"models/props_lab/cornerunit_cloud",
|
||||
"models/props_lab/door_klab01",
|
||||
"models/props_lab/security_screens",
|
||||
"models/props_lab/security_screens2",
|
||||
"models/props_lab/Tank_Glass001",
|
||||
"models/props_lab/warp_sheet",
|
||||
"models/props_lab/xencrystal_sheet",
|
||||
"models/props_pipes/destroyedpipes01a",
|
||||
"models/props_pipes/GutterMetal01a",
|
||||
"models/props_pipes/pipeset_metal02",
|
||||
"models/props_pipes/pipesystem01a_skin1",
|
||||
"models/props_pipes/pipesystem01a_skin2",
|
||||
"models/props_vents/borealis_vent001",
|
||||
"models/props_vents/borealis_vent001b",
|
||||
"models/props_vents/borealis_vent001c",
|
||||
"models/props_wasteland/concretefloor010a",
|
||||
"models/props_wasteland/concretewall064b",
|
||||
"models/props_wasteland/concretewall066a",
|
||||
"models/props_wasteland/dirtwall001a",
|
||||
"models/props_wasteland/metal_tram001a",
|
||||
"models/props_wasteland/quarryobjects01",
|
||||
"models/props_wasteland/rockcliff02a",
|
||||
"models/props_wasteland/rockcliff02b",
|
||||
"models/props_wasteland/rockcliff02c",
|
||||
"models/props_wasteland/rockcliff04a",
|
||||
"models/props_wasteland/rockgranite02a",
|
||||
"models/props_wasteland/tugboat01",
|
||||
"models/props_wasteland/tugboat02",
|
||||
"models/props_wasteland/wood_fence01a",
|
||||
"models/props_wasteland/wood_fence01a_skin2",
|
||||
"models/roller/rollermine_glow",
|
||||
"models/weapons/v_crossbow/rebar_glow",
|
||||
"models/weapons/v_crowbar/crowbar_cyl",
|
||||
"models/weapons/v_grenade/grenade body",
|
||||
"models/weapons/v_smg1/texture5",
|
||||
"models/weapons/w_smg1/smg_crosshair",
|
||||
"models/weapons/v_slam/new light2",
|
||||
"models/weapons/v_slam/new light1",
|
||||
"models/props/cs_assault/dollar",
|
||||
"models/props/cs_assault/fireescapefloor",
|
||||
"models/props/cs_assault/metal_stairs1",
|
||||
"models/props/cs_assault/moneywrap",
|
||||
"models/props/cs_assault/moneywrap02",
|
||||
"models/props/cs_assault/moneytop",
|
||||
"models/props/cs_assault/pylon",
|
||||
"models/props/CS_militia/boulder01",
|
||||
"models/props/CS_militia/milceil001",
|
||||
"models/props/CS_militia/militiarock",
|
||||
"models/props/CS_militia/militiarockb",
|
||||
"models/props/CS_militia/milwall006",
|
||||
"models/props/CS_militia/rocks01",
|
||||
"models/props/CS_militia/roofbeams01",
|
||||
"models/props/CS_militia/roofbeams02",
|
||||
"models/props/CS_militia/roofbeams03",
|
||||
"models/props/CS_militia/RoofEdges",
|
||||
"models/props/cs_office/clouds",
|
||||
"models/props/cs_office/file_cabinet2",
|
||||
"models/props/cs_office/file_cabinet3",
|
||||
"models/props/cs_office/screen",
|
||||
"models/props/cs_office/snowmana",
|
||||
"models/props/de_inferno/de_inferno_boulder_03",
|
||||
"models/props/de_inferno/infflra",
|
||||
"models/props/de_inferno/infflrd",
|
||||
"models/props/de_inferno/inftowertop",
|
||||
"models/props/de_inferno/offwndwb_break",
|
||||
"models/props/de_inferno/roofbits",
|
||||
"models/props/de_inferno/tileroof01",
|
||||
"models/props/de_inferno/woodfloor008a",
|
||||
"models/props/de_nuke/nukconcretewalla",
|
||||
"models/props/de_nuke/nukecardboard",
|
||||
"models/props/de_nuke/pipeset_metal",
|
||||
"models/shadertest/predator",
|
||||
}
|
||||
|
||||
pace.Materials.trails =
|
||||
{
|
||||
"trails/plasma",
|
||||
"trails/tube",
|
||||
"trails/electric",
|
||||
"trails/smoke",
|
||||
"trails/laser",
|
||||
"trails/physbeam",
|
||||
"trails/love",
|
||||
"trails/lol",
|
||||
"sprites/rollermine_shock_yellow",
|
||||
"sprites/yellowlaser1",
|
||||
"particle/beam_smoke_01",
|
||||
"particle/beam_smoke_02",
|
||||
"particle/bendibeam_nofog",
|
||||
"sprites/physbeam",
|
||||
"sprites/physbeama",
|
||||
"sprites/rollermine_shock",
|
||||
"sprites/hydraspinalcord",
|
||||
"particle/Particle_Square_Gradient",
|
||||
"particle/Particle_Square_Gradient_NoFog",
|
||||
}
|
||||
|
||||
pace.Materials.sprites =
|
||||
{
|
||||
"sprites/glow04_noz",
|
||||
"sprites/grip",
|
||||
"sprites/key_0",
|
||||
"sprites/key_1",
|
||||
"sprites/key_10",
|
||||
"sprites/key_11",
|
||||
"sprites/key_12",
|
||||
"sprites/key_13",
|
||||
"sprites/key_14",
|
||||
"sprites/key_15",
|
||||
"sprites/key_2",
|
||||
"sprites/key_3",
|
||||
"sprites/key_4",
|
||||
"sprites/key_5",
|
||||
"sprites/key_6",
|
||||
"sprites/key_7",
|
||||
"sprites/key_8",
|
||||
"sprites/key_9",
|
||||
"sprites/light_ignorez",
|
||||
"sprites/muzzleflash4",
|
||||
"sprites/orangecore1",
|
||||
"sprites/orangecore2",
|
||||
"sprites/orangeflare1",
|
||||
"sprites/physg_glow1",
|
||||
"sprites/physg_glow2",
|
||||
"sprites/physgbeamb",
|
||||
"sprites/redglow1",
|
||||
"sprites/animglow02",
|
||||
"sprites/ar2_muzzle1",
|
||||
"sprites/ar2_muzzle3",
|
||||
"sprites/ar2_muzzle4",
|
||||
"sprites/arrow",
|
||||
"sprites/blueglow2",
|
||||
"sprites/bluelaser1",
|
||||
"sprites/dot",
|
||||
"sprites/flamelet1",
|
||||
"sprites/flamelet2",
|
||||
"sprites/flamelet3",
|
||||
"sprites/flamelet4",
|
||||
"sprites/flamelet5",
|
||||
"sprites/heatwave",
|
||||
"sprites/heatwavedx70",
|
||||
"sprites/hydragutbeam",
|
||||
"sprites/hydragutbeamcap",
|
||||
"sprites/light_glow02_add",
|
||||
"sprites/light_glow02_add_noz",
|
||||
"sprites/plasmaember",
|
||||
"sprites/predator",
|
||||
"sprites/qi_center",
|
||||
"sprites/reticle",
|
||||
"sprites/reticle1",
|
||||
"sprites/reticle2",
|
||||
"sprites/rico1",
|
||||
"sprites/rico1_noz",
|
||||
"sprites/scanner",
|
||||
"sprites/scanner_bottom",
|
||||
"sprites/scanner_dots1",
|
||||
"sprites/scanner_dots2",
|
||||
"sprites/strider_blackball",
|
||||
"sprites/strider_bluebeam",
|
||||
"sprites/tp_beam001",
|
||||
"sprites/bucket_bat_blue",
|
||||
"sprites/bucket_bat_red",
|
||||
"sprites/bucket_bonesaw",
|
||||
"sprites/bucket_bottle_blue",
|
||||
"sprites/bucket_bottle_red",
|
||||
"sprites/bucket_fireaxe",
|
||||
"sprites/bucket_fists_blue",
|
||||
"sprites/bucket_fists_red",
|
||||
"sprites/bucket_flamethrower_blue",
|
||||
"sprites/bucket_flamethrower_red",
|
||||
"sprites/bucket_grenlaunch",
|
||||
"sprites/bucket_knife",
|
||||
"sprites/bucket_machete",
|
||||
"sprites/bucket_medigun_blue",
|
||||
"sprites/bucket_medigun_red",
|
||||
"sprites/bucket_minigun",
|
||||
"sprites/bucket_nailgun",
|
||||
"sprites/bucket_pda",
|
||||
"sprites/bucket_pda_build",
|
||||
"sprites/bucket_pda_destroy",
|
||||
"sprites/bucket_pipelaunch",
|
||||
"sprites/bucket_pistol",
|
||||
"sprites/bucket_revolver",
|
||||
"sprites/bucket_rl",
|
||||
"sprites/bucket_sapper",
|
||||
"sprites/bucket_scatgun",
|
||||
"sprites/bucket_shotgun",
|
||||
"sprites/bucket_shovel",
|
||||
"sprites/bucket_smg",
|
||||
"sprites/bucket_sniper",
|
||||
"sprites/bucket_syrgun_blue",
|
||||
"sprites/bucket_syrgun_red",
|
||||
"sprites/bucket_tranq",
|
||||
"sprites/bucket_wrench",
|
||||
"sprites/healbeam",
|
||||
"sprites/healbeam_blue",
|
||||
"sprites/healbeam_red",
|
||||
"sprites/640_pain_down",
|
||||
"sprites/640_pain_left",
|
||||
"sprites/640_pain_right",
|
||||
"sprites/640_pain_up",
|
||||
"sprites/bomb_carried",
|
||||
"sprites/bomb_carried_ring",
|
||||
"sprites/bomb_carried_ring_offscreen",
|
||||
"sprites/bomb_dropped",
|
||||
"sprites/bomb_dropped_ring",
|
||||
"sprites/bomb_planted",
|
||||
"sprites/bomb_planted_ring",
|
||||
"sprites/c4",
|
||||
"sprites/defuser",
|
||||
"sprites/hostage_following",
|
||||
"sprites/hostage_following_offscreen",
|
||||
"sprites/hostage_rescue",
|
||||
"sprites/numbers",
|
||||
"sprites/objective_rescue",
|
||||
"sprites/objective_site_a",
|
||||
"sprites/objective_site_b",
|
||||
"sprites/player_blue_dead",
|
||||
"sprites/player_blue_dead_offscreen",
|
||||
"sprites/player_blue_offscreen",
|
||||
"sprites/player_blue_self",
|
||||
"sprites/player_blue_small",
|
||||
"sprites/player_hostage_dead",
|
||||
"sprites/player_hostage_dead_offscreen",
|
||||
"sprites/player_hostage_offscreen",
|
||||
"sprites/player_hostage_small",
|
||||
"sprites/player_radio_ring",
|
||||
"sprites/player_radio_ring_offscreen",
|
||||
"sprites/player_red_dead",
|
||||
"sprites/player_red_dead_offscreen",
|
||||
"sprites/player_red_offscreen",
|
||||
"sprites/player_red_self",
|
||||
"sprites/player_red_small",
|
||||
"sprites/player_tick",
|
||||
"sprites/radar",
|
||||
"sprites/radar_trans",
|
||||
"sprites/radio",
|
||||
"sprites/scope_arc",
|
||||
"sprites/shopping_cart",
|
||||
"sprites/spectator_3rdcam",
|
||||
"sprites/spectator_eye",
|
||||
"sprites/spectator_freecam",
|
||||
"sprites/cloudglow1_nofog",
|
||||
"sprites/core_beam1",
|
||||
"sprites/bluelight",
|
||||
"sprites/grav_flare",
|
||||
"sprites/grav_light",
|
||||
"sprites/orangelight",
|
||||
"sprites/portalgun_effects",
|
||||
"sprites/sphere_silhouette",
|
||||
"sprites/redglow_mp1",
|
||||
"sprites/sent_ball",
|
||||
"particle/fire",
|
||||
"particle/particle_composite",
|
||||
"particle/Particle_Crescent",
|
||||
"particle/Particle_Crescent_Additive",
|
||||
"particle/Particle_Glow_02",
|
||||
"particle/Particle_Glow_03",
|
||||
"particle/Particle_Glow_03_Additive",
|
||||
"particle/Particle_Glow_04",
|
||||
"particle/Particle_Glow_04_Additive",
|
||||
"particle/Particle_Glow_05",
|
||||
"particle/particle_noisesphere",
|
||||
"particle/Particle_Ring_Blur",
|
||||
"particle/particle_ring_refract_01",
|
||||
"particle/Particle_Ring_Sharp",
|
||||
"particle/Particle_Ring_Sharp_Additive",
|
||||
"particle/Particle_Ring_Wave_8",
|
||||
"particle/Particle_Ring_Wave_8_15OB_NoFog",
|
||||
"particle/Particle_Ring_Wave_Additive",
|
||||
"particle/Particle_Ring_Wave_AddNoFog",
|
||||
"particle/particle_smokegrenade",
|
||||
"particle/particle_smokegrenade1",
|
||||
"particle/particle_sphere",
|
||||
"particle/rain",
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016",
|
||||
"particle/SmokeStack",
|
||||
"particle/snow",
|
||||
"particle/sparkles",
|
||||
"particle/warp1_warp",
|
||||
"particle/warp2_warp",
|
||||
"particle/warp3_warp_NoZ",
|
||||
"particle/warp4_warp",
|
||||
"particle/warp4_warp_NoZ",
|
||||
"particle/warp5_warp",
|
||||
"particle/warp_ripple",
|
||||
"particle/glow_haze_nofog",
|
||||
"particle/smoke_black_smokestack000",
|
||||
"particle/smoke_black_smokestack001",
|
||||
"particle/smoke_black_smokestack_all",
|
||||
"particle/smokestack_nofog",
|
||||
"particle/particle_rockettrail2",
|
||||
"particles/balloon_bit",
|
||||
"particles/fire1",
|
||||
"particles/fire_glow",
|
||||
"particles/flamelet1",
|
||||
"particles/flamelet2",
|
||||
"particles/flamelet3",
|
||||
"particles/flamelet4",
|
||||
"particles/flamelet5",
|
||||
"particles/smokey",
|
||||
}
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "mat_browser_sheet"
|
||||
PANEL.Base = "DPanel"
|
||||
|
||||
AccessorFunc(PANEL, "m_Selected", "Selected")
|
||||
|
||||
function PANEL:Init()
|
||||
local list = vgui.Create("DPanelList", self)
|
||||
list:SetPadding(2)
|
||||
list:SetSpacing(2)
|
||||
list:EnableVerticalScrollbar(true)
|
||||
list:EnableHorizontal(true)
|
||||
list:Dock(FILL)
|
||||
self.MatList = list
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
surface.SetDrawColor(0,0,0, 255)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
local cache = {}
|
||||
local function IsError(path)
|
||||
if cache[path] then return true end
|
||||
if Material(path):IsError() then
|
||||
cache[path] = truer
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetMaterialList(tbl)
|
||||
self:SetSelected()
|
||||
|
||||
self.MaterialList = tbl
|
||||
|
||||
self.MatList:Clear(true)
|
||||
|
||||
for i, material in pairs(self.MaterialList) do
|
||||
-- if IsError(material) then continue end
|
||||
|
||||
local image = vgui.Create("DImageButton")
|
||||
image.m_Image.LoadMaterial = function(s) s:DoLoadMaterial() end
|
||||
image:SetOnViewMaterial(material, material)
|
||||
image:SetSize(64, 64)
|
||||
image.Value = material
|
||||
|
||||
self.MatList:AddItem(image)
|
||||
|
||||
image.DoClick = function(image) self:SetSelected(image.Value) end
|
||||
|
||||
if self:GetSelected() then
|
||||
image.PaintOver = HighlightedButtonPaint
|
||||
self:SetSelected(material)
|
||||
end
|
||||
end
|
||||
|
||||
self:InvalidateLayout(true)
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.Base = "DFrame"
|
||||
PANEL.ClassName = "mat_browser"
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetTitle("materials")
|
||||
|
||||
local list =
|
||||
{
|
||||
{key = "default", val = table.Merge(list.Get("OverrideMaterials"), pace.Materials.materials)},
|
||||
{key = "sprites", val = pace.Materials.sprites},
|
||||
{key = "trails", val = pace.Materials.trails},
|
||||
}
|
||||
|
||||
local sheet = vgui.Create("DPropertySheet", self)
|
||||
sheet:Dock(FILL)
|
||||
|
||||
for _, data in pairs(list) do
|
||||
local name, tbl = data.key, data.val
|
||||
local pnl = pace.CreatePanel("mat_browser_sheet", self)
|
||||
pnl:SetMaterialList(tbl)
|
||||
pnl.SetSelected = function(_, path) self:SetSelected(path) end
|
||||
sheet:AddSheet(name, pnl)
|
||||
end
|
||||
|
||||
local entry = vgui.Create("DTextEntry", self)
|
||||
entry.OnEnter = function() self:SetSelected(self.Entry:GetValue()) end
|
||||
entry:Dock(BOTTOM)
|
||||
entry:SetTall(20)
|
||||
self.Entry = entry
|
||||
|
||||
self:SetDrawOnTop(true)
|
||||
self:SetSize(300, 300)
|
||||
self:SetSizable(true)
|
||||
self:Center()
|
||||
end
|
||||
|
||||
function PANEL:SetSelected(value)
|
||||
self.Entry:SetText(value or "")
|
||||
|
||||
self.m_Selected = value
|
||||
|
||||
self:MaterialSelected(value)
|
||||
end
|
||||
|
||||
function PANEL:MaterialSelected(path) end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
567
lua/pac3/editor/client/panels/pac_tree.lua
Normal file
567
lua/pac3/editor/client/panels/pac_tree.lua
Normal file
@@ -0,0 +1,567 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
local PANEL = vgui.Register("pac_dtree_node_button", {}, "DButton")
|
||||
pace.pac_dtree_node_button = PANEL
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetTextInset(32, 0)
|
||||
self:SetContentAlignment(4)
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
derma.SkinHook("Paint", "TreeNodeButton", self, w, h)
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:UpdateColours(skin)
|
||||
if self:IsSelected() then return self:SetTextStyleColor(skin.Colours.Tree.Selected) end
|
||||
if self.Hovered then return self:SetTextStyleColor(skin.Colours.Tree.Hover) end
|
||||
|
||||
return self:SetTextStyleColor(skin.Colours.Tree.Normal)
|
||||
end
|
||||
|
||||
local PANEL = vgui.Register("pac_dtree", {}, "DScrollPanel")
|
||||
pace.pac_dtree = PANEL
|
||||
|
||||
AccessorFunc(PANEL, "m_bShowIcons", "ShowIcons")
|
||||
AccessorFunc(PANEL, "m_iIndentSize", "IndentSize")
|
||||
AccessorFunc(PANEL, "m_iLineHeight", "LineHeight")
|
||||
AccessorFunc(PANEL, "m_pSelectedItem", "SelectedItem")
|
||||
AccessorFunc(PANEL, "m_bClickOnDragHover", "ClickOnDragHover")
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetShowIcons(true)
|
||||
self:SetIndentSize(14)
|
||||
self:SetLineHeight(17)
|
||||
|
||||
self.RootNode = self:GetCanvas():Add("pac_dtree_node")
|
||||
self.RootNode:SetRoot(self)
|
||||
self.RootNode:SetParentNode(self)
|
||||
self.RootNode:SetSize(5,5)
|
||||
self.RootNode:Dock(TOP)
|
||||
self.RootNode:SetText("")
|
||||
self.RootNode:SetExpanded(true, true)
|
||||
self.RootNode:DockMargin(0, 0, 0, 0)
|
||||
|
||||
self:SetPaintBackground(true)
|
||||
end
|
||||
|
||||
function PANEL:Root()
|
||||
return self.RootNode
|
||||
end
|
||||
|
||||
function PANEL:AddNode(strName, strIcon)
|
||||
return self.RootNode:AddNode(strName, strIcon)
|
||||
end
|
||||
|
||||
function PANEL:ChildExpanded(bExpand)
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:ShowIcons()
|
||||
return self.m_bShowIcons
|
||||
end
|
||||
|
||||
function PANEL:ExpandTo(bExpand)
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetExpanded(bExpand)
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Clear()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
derma.SkinHook("Paint", "Tree", self, w, h)
|
||||
return true
|
||||
end
|
||||
|
||||
function PANEL:DoClick(node)
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:DoRightClick(node)
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:SetSelectedItem(node)
|
||||
if IsValid(self.m_pSelectedItem) then
|
||||
self.m_pSelectedItem:SetSelected(false)
|
||||
self:OnNodeDeselected(self.m_pSelectedItem)
|
||||
end
|
||||
|
||||
self.m_pSelectedItem = node
|
||||
|
||||
if node then
|
||||
node:SetSelected(true)
|
||||
node:OnNodeSelected(node)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:OnNodeSelected(node)
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnNodeDeselected(node)
|
||||
|
||||
end
|
||||
|
||||
function PANEL:MoveChildTo(child, pos)
|
||||
self:InsertAtTop(child)
|
||||
end
|
||||
|
||||
function PANEL:LayoutTree()
|
||||
self:InvalidateChildren(true)
|
||||
end
|
||||
|
||||
local PANEL = vgui.Register("pac_dtree_node", {}, "DPanel")
|
||||
pace.pac_dtree_node = PANEL
|
||||
|
||||
AccessorFunc(PANEL, "m_pRoot", "Root")
|
||||
|
||||
AccessorFunc(PANEL, "m_pParentNode", "ParentNode")
|
||||
|
||||
AccessorFunc(PANEL, "m_strPathID", "PathID")
|
||||
AccessorFunc(PANEL, "m_strWildCard", "WildCard")
|
||||
AccessorFunc(PANEL, "m_bNeedsPopulating", "NeedsPopulating")
|
||||
|
||||
AccessorFunc(PANEL, "m_bDirty", "Dirty", FORCE_BOOL)
|
||||
AccessorFunc(PANEL, "m_bNeedsChildSearch", "NeedsChildSearch", FORCE_BOOL)
|
||||
|
||||
AccessorFunc(PANEL, "m_bForceShowExpander", "ForceShowExpander", FORCE_BOOL)
|
||||
AccessorFunc(PANEL, "m_bHideExpander", "HideExpander", FORCE_BOOL)
|
||||
AccessorFunc(PANEL, "m_bDoubleClickToOpen", "DoubleClickToOpen", FORCE_BOOL)
|
||||
|
||||
AccessorFunc(PANEL, "m_bLastChild", "LastChild", FORCE_BOOL)
|
||||
AccessorFunc(PANEL, "m_bDrawLines", "DrawLines", FORCE_BOOL)
|
||||
AccessorFunc(PANEL, "m_strDraggableName", "DraggableName")
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetDoubleClickToOpen(true)
|
||||
|
||||
self.Label = vgui.Create("pac_dtree_node_button", self)
|
||||
self.Label:SetDragParent(self)
|
||||
self.Label.DoClick = function() self:InternalDoClick() end
|
||||
self.Label.DoDoubleClick = function() self:InternalDoClick() end
|
||||
self.Label.DoRightClick = function() self:InternalDoRightClick() end
|
||||
self.Label.DragHover = function(s, t) self:DragHover(t) end
|
||||
|
||||
self.Expander = vgui.Create("DExpandButton", self)
|
||||
self.Expander.DoClick = function() self:SetExpanded( not self.m_bExpanded) end
|
||||
self.Expander:SetVisible(false)
|
||||
|
||||
self.Icon = vgui.Create("DImage", self)
|
||||
self.Icon:SetImage("icon16/folder.png")
|
||||
self.Icon:SizeToContents()
|
||||
|
||||
self.fLastClick = SysTime()
|
||||
|
||||
self:SetDrawLines(false)
|
||||
self:SetLastChild(false)
|
||||
end
|
||||
|
||||
function PANEL:SetRoot(root)
|
||||
self.m_pRoot = root
|
||||
|
||||
root.added_nodes = root.added_nodes or {}
|
||||
for i,v in ipairs(root.added_nodes) do
|
||||
if v == self then return end
|
||||
end
|
||||
table.insert(root.added_nodes, self)
|
||||
end
|
||||
|
||||
function PANEL:OnRemove()
|
||||
local root = self:GetRoot()
|
||||
|
||||
if not IsValid(root) then return end
|
||||
|
||||
root.added_nodes = root.added_nodes or {}
|
||||
for i,v in ipairs(root.added_nodes) do
|
||||
if v == self then
|
||||
table.remove(root.added_nodes, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:IsRootNode()
|
||||
return self.m_pRoot == self.m_pParentNode
|
||||
end
|
||||
|
||||
function PANEL:InternalDoClick()
|
||||
self:GetRoot():SetSelectedItem(self)
|
||||
|
||||
if self:DoClick() then return end
|
||||
if self:GetRoot():DoClick(self) then return end
|
||||
|
||||
if not self.m_bDoubleClickToOpen or (SysTime() - self.fLastClick < 0.3) then
|
||||
self:SetExpanded( not self.m_bExpanded)
|
||||
end
|
||||
|
||||
self.fLastClick = SysTime()
|
||||
end
|
||||
|
||||
function PANEL:OnNodeSelected(node)
|
||||
local parent = self:GetParentNode()
|
||||
if IsValid(parent) and parent.OnNodeSelected then
|
||||
parent:OnNodeSelected(node)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:InternalDoRightClick()
|
||||
if self:DoRightClick() then return end
|
||||
if self:GetRoot():DoRightClick(self) then return end
|
||||
end
|
||||
|
||||
function PANEL:DoClick()
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:DoRightClick()
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:SetIcon(str)
|
||||
if not str then return end
|
||||
if str == "" then return end
|
||||
|
||||
self.Icon:SetImage(str)
|
||||
end
|
||||
|
||||
function PANEL:ShowIcons()
|
||||
return self:GetParentNode():ShowIcons()
|
||||
end
|
||||
|
||||
function PANEL:GetLineHeight()
|
||||
return self:GetParentNode():GetLineHeight()
|
||||
end
|
||||
|
||||
function PANEL:GetIndentSize()
|
||||
return self:GetParentNode():GetIndentSize()
|
||||
end
|
||||
|
||||
function PANEL:SetText(strName)
|
||||
self.Label:SetText(strName)
|
||||
end
|
||||
|
||||
function PANEL:ExpandRecurse(bExpand)
|
||||
self:SetExpanded(bExpand, true)
|
||||
|
||||
if not self.ChildNodes then return end
|
||||
|
||||
for k, Child in pairs(self.ChildNodes:GetItems()) do
|
||||
if Child.ExpandRecurse then
|
||||
Child:ExpandRecurse(bExpand)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:ExpandTo(bExpand)
|
||||
self:SetExpanded(bExpand, true)
|
||||
self:GetParentNode():ExpandTo(bExpand)
|
||||
end
|
||||
|
||||
|
||||
function PANEL:IsExpanded()
|
||||
local parent = self:GetParent():GetParent()
|
||||
|
||||
while IsValid(parent) and parent.m_bExpanded ~= nil do
|
||||
if parent.m_bExpanded == false then
|
||||
return false
|
||||
end
|
||||
parent = parent:GetParent():GetParent()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function PANEL:SetExpanded(bExpand)
|
||||
|
||||
if self.m_pParentNode:IsValid() then
|
||||
self:GetParentNode():ChildExpanded(bExpand)
|
||||
end
|
||||
self.Expander:SetExpanded(bExpand)
|
||||
self.m_bExpanded = bExpand
|
||||
self:InvalidateLayout(true)
|
||||
|
||||
if not self.ChildNodes then return end
|
||||
|
||||
local StartTall = self:GetTall()
|
||||
|
||||
if self.ChildNodes then
|
||||
self.ChildNodes:SetVisible(bExpand)
|
||||
if bExpand then
|
||||
self.ChildNodes:InvalidateLayout(true)
|
||||
end
|
||||
end
|
||||
|
||||
self:InvalidateLayout(true)
|
||||
end
|
||||
|
||||
function PANEL:ChildExpanded(bExpand)
|
||||
self.ChildNodes:InvalidateLayout(true)
|
||||
self:InvalidateLayout(true)
|
||||
self:GetParentNode():ChildExpanded(bExpand)
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
end
|
||||
|
||||
function PANEL:HasChildren()
|
||||
if not IsValid(self.ChildNodes) then return false end
|
||||
return self.ChildNodes:HasChildren()
|
||||
end
|
||||
|
||||
|
||||
function PANEL:DoChildrenOrder()
|
||||
if not self.ChildNodes then return end
|
||||
|
||||
local last = table.Count(self.ChildNodes:GetChildren())
|
||||
for k, Child in pairs(self.ChildNodes:GetChildren()) do
|
||||
Child:SetLastChild(k == last)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PerformRootNodeLayout()
|
||||
self.Expander:SetVisible(false)
|
||||
self.Label:SetVisible(false)
|
||||
self.Icon:SetVisible(false)
|
||||
|
||||
if IsValid(self.ChildNodes) then
|
||||
self.ChildNodes:Dock(TOP)
|
||||
self:SetTall(self.ChildNodes:GetTall())
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
if self:IsRootNode() then
|
||||
return self:PerformRootNodeLayout()
|
||||
end
|
||||
|
||||
local LineHeight = self:GetLineHeight()
|
||||
|
||||
if self.m_bHideExpander then
|
||||
self.Expander:SetPos(-11, 0)
|
||||
self.Expander:SetSize(15, 15)
|
||||
self.Expander:SetVisible(false)
|
||||
else
|
||||
self.Expander:SetPos(2, 0)
|
||||
self.Expander:SetSize(15, 15)
|
||||
self.Expander:SetVisible(self:HasChildren() or self:GetForceShowExpander())
|
||||
self.Expander:SetZPos(10)
|
||||
end
|
||||
|
||||
self.Label:StretchToParent(0, nil, 0, nil)
|
||||
self.Label:SetTall(LineHeight)
|
||||
|
||||
if self:ShowIcons() then
|
||||
self.Icon:SetVisible(true)
|
||||
self.Icon:SetPos(self.Expander.x + self.Expander:GetWide() + 4, (LineHeight - self.Icon:GetTall()) * 0.5)
|
||||
self.Label:SetTextInset(self.Icon.x + self.Icon:GetWide() + 4, 0)
|
||||
else
|
||||
self.Icon:SetVisible(false)
|
||||
self.Label:SetTextInset(self.Expander.x + self.Expander:GetWide() + 4, 0)
|
||||
end
|
||||
|
||||
if not self.ChildNodes or not self.ChildNodes:IsVisible() then
|
||||
self:SetTall(LineHeight)
|
||||
return end
|
||||
|
||||
self.ChildNodes:SizeToContents()
|
||||
self:SetTall(LineHeight + self.ChildNodes:GetTall())
|
||||
|
||||
self.ChildNodes:StretchToParent(LineHeight, LineHeight, 0, 0)
|
||||
|
||||
self:DoChildrenOrder()
|
||||
end
|
||||
|
||||
function PANEL:CreateChildNodes()
|
||||
if self.ChildNodes then return end
|
||||
|
||||
self.ChildNodes = vgui.Create("DListLayout", self)
|
||||
self.ChildNodes:SetDropPos("852")
|
||||
self.ChildNodes:SetVisible(self.m_bExpanded)
|
||||
self.ChildNodes.OnChildRemoved = function()
|
||||
self.ChildNodes:InvalidateLayout()
|
||||
end
|
||||
|
||||
self.ChildNodes.OnModified = function()
|
||||
self:OnModified()
|
||||
end
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:AddPanel(pPanel)
|
||||
self:CreateChildNodes()
|
||||
|
||||
self.ChildNodes:Add(pPanel)
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:AddNode(strName, strIcon)
|
||||
self:CreateChildNodes()
|
||||
|
||||
local pNode = vgui.Create("pac_dtree_node", self)
|
||||
pNode:SetText(strName)
|
||||
pNode:SetParentNode(self)
|
||||
pNode:SetRoot(self:GetRoot())
|
||||
pNode:SetIcon(strIcon)
|
||||
pNode:SetDrawLines( not self:IsRootNode())
|
||||
|
||||
self:InstallDraggable(pNode)
|
||||
|
||||
self.ChildNodes:Add(pNode)
|
||||
self:InvalidateLayout()
|
||||
|
||||
return pNode
|
||||
end
|
||||
|
||||
function PANEL:InsertNode(pNode)
|
||||
self:CreateChildNodes()
|
||||
|
||||
pNode:SetParentNode(self)
|
||||
pNode:SetRoot(self:GetRoot())
|
||||
self:InstallDraggable(pNode)
|
||||
|
||||
self.ChildNodes:Add(pNode)
|
||||
self:InvalidateLayout()
|
||||
|
||||
return pNode
|
||||
end
|
||||
|
||||
function PANEL:InstallDraggable(pNode)
|
||||
local DragName = self:GetDraggableName()
|
||||
if not DragName then return end
|
||||
|
||||
-- Make this node draggable
|
||||
pNode:SetDraggableName(DragName)
|
||||
pNode:Droppable(DragName)
|
||||
|
||||
-- Allow item dropping onto us
|
||||
self.ChildNodes:MakeDroppable(DragName, true, true)
|
||||
end
|
||||
|
||||
function PANEL:DroppedOn(pnl)
|
||||
self:InsertNode(pnl)
|
||||
self:SetExpanded(true)
|
||||
end
|
||||
|
||||
function PANEL:SetSelected(b)
|
||||
self.Label:SetSelected(b)
|
||||
self.Label:InvalidateLayout()
|
||||
if self.OnSelected then
|
||||
self:OnSelected(b)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:DragHoverClick(HoverTime)
|
||||
if not self.m_bExpanded then
|
||||
self:SetExpanded(true)
|
||||
end
|
||||
|
||||
if self:GetRoot():GetClickOnDragHover() then
|
||||
self:InternalDoClick()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function PANEL:MoveToTop()
|
||||
local parent = self:GetParentNode()
|
||||
if not IsValid(parent) then return end
|
||||
|
||||
self:GetParentNode():MoveChildTo(self, 1)
|
||||
end
|
||||
|
||||
function PANEL:MoveChildTo(child)
|
||||
self.ChildNodes:InsertAtTop(child)
|
||||
end
|
||||
|
||||
function PANEL:GetText()
|
||||
return self.Label:GetText()
|
||||
end
|
||||
|
||||
function PANEL:GetIcon()
|
||||
return self.Icon:GetImage()
|
||||
end
|
||||
|
||||
function PANEL:CleanList()
|
||||
for k, panel in pairs(self.Items) do
|
||||
|
||||
if not IsValid(panel) or panel:GetParent() ~= self.pnlCanvas then
|
||||
self.Items[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Insert(pNode, pNodeNextTo, bBefore)
|
||||
pNode:SetParentNode(self)
|
||||
pNode:SetRoot(self:GetRoot())
|
||||
|
||||
self:CreateChildNodes()
|
||||
|
||||
if bBefore then
|
||||
self.ChildNodes:InsertBefore(pNodeNextTo, pNode)
|
||||
else
|
||||
self.ChildNodes:InsertAfter(pNodeNextTo, pNode)
|
||||
end
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:LeaveTree(pnl)
|
||||
self.ChildNodes:RemoveItem(pnl, true)
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
|
||||
function PANEL:OnModified()
|
||||
end
|
||||
|
||||
function PANEL:GetChildNode(iNum)
|
||||
if not IsValid(self.ChildNodes) then return end
|
||||
return self.ChildNodes:GetChild(iNum)
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
derma.SkinHook("Paint", "TreeNode", self, w, h)
|
||||
end
|
||||
|
||||
function PANEL:Copy()
|
||||
local copy = vgui.Create("pac_dtree_node", self:GetParent())
|
||||
copy:SetText(self:GetText())
|
||||
copy:SetIcon(self:GetIcon())
|
||||
copy:SetRoot(self:GetRoot())
|
||||
copy:SetParentNode(self:GetParentNode())
|
||||
|
||||
if self.ChildNodes then
|
||||
for k, v in pairs(self.ChildNodes:GetChildren()) do
|
||||
local childcopy = v:Copy()
|
||||
copy:InsertNode(childcopy)
|
||||
end
|
||||
end
|
||||
|
||||
self:SetupCopy(copy)
|
||||
|
||||
return copy
|
||||
end
|
||||
|
||||
function PANEL:SetupCopy(copy)
|
||||
|
||||
end
|
||||
|
||||
if Entity(1):IsPlayer() and not PAC_RESTART and not VLL2_FILEDEF then
|
||||
pace.OpenEditor()
|
||||
pace.RefreshTree(true)
|
||||
end
|
||||
1579
lua/pac3/editor/client/panels/properties.lua
Normal file
1579
lua/pac3/editor/client/panels/properties.lua
Normal file
File diff suppressed because it is too large
Load Diff
423
lua/pac3/editor/client/panels/scrollpanel_horizontal.lua
Normal file
423
lua/pac3/editor/client/panels/scrollpanel_horizontal.lua
Normal file
@@ -0,0 +1,423 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
do
|
||||
local PANEL = vgui.Register("pac_horizontal_scrollbar", {}, "Panel")
|
||||
|
||||
AccessorFunc( PANEL, "m_HideButtons", "HideButtons" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.Offset = 0
|
||||
self.Scroll = 0
|
||||
self.CanvasSize = 1
|
||||
self.BarSize = 1
|
||||
|
||||
self.btnLeft = vgui.Create( "DButton", self )
|
||||
self.btnLeft:SetText( "" )
|
||||
self.btnLeft.DoClick = function( self ) self:GetParent():AddScroll( -1 ) end
|
||||
self.btnLeft.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonLeft", panel, w, h ) end
|
||||
|
||||
self.btnRight = vgui.Create( "DButton", self )
|
||||
self.btnRight:SetText( "" )
|
||||
self.btnRight.DoClick = function( self ) self:GetParent():AddScroll( 1 ) end
|
||||
self.btnRight.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonRight", panel, w, h ) end
|
||||
|
||||
self.btnGrip = vgui.Create( "DScrollBarGrip", self )
|
||||
self.btnGrip.Paint = function(panel,w,h)
|
||||
local skin = panel:GetSkin()
|
||||
if ( panel:GetDisabled() ) then
|
||||
skin.tex.Scroller.ButtonH_Disabled( 0, 0, w, h )
|
||||
elseif ( panel.Depressed ) then
|
||||
return skin.tex.Scroller.ButtonH_Down( 0, 0, w, h )
|
||||
elseif ( panel.Hovered ) then
|
||||
return skin.tex.Scroller.ButtonH_Hover( 0, 0, w, h )
|
||||
else
|
||||
skin.tex.Scroller.ButtonH_Normal( 0, 0, w, h )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
self:SetSize( 15, 15 )
|
||||
self:SetHideButtons( false )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetEnabled( b )
|
||||
|
||||
if ( !b ) then
|
||||
|
||||
self.Offset = 0
|
||||
self:SetScroll( 0 )
|
||||
self.HasChanged = true
|
||||
|
||||
end
|
||||
|
||||
self:SetMouseInputEnabled( b )
|
||||
self:SetVisible( b )
|
||||
|
||||
-- We're probably changing the width of something in our parent
|
||||
-- by appearing or hiding, so tell them to re-do their layout.
|
||||
if ( self.Enabled != b ) then
|
||||
|
||||
self:GetParent():InvalidateLayout()
|
||||
|
||||
if ( self:GetParent().OnScrollbarAppear ) then
|
||||
self:GetParent():OnScrollbarAppear()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.Enabled = b
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Value()
|
||||
|
||||
return self.Pos
|
||||
|
||||
end
|
||||
|
||||
function PANEL:BarScale()
|
||||
|
||||
if ( self.BarSize == 0 ) then return 1 end
|
||||
|
||||
return self.BarSize / ( self.CanvasSize + self.BarSize )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetUp( _barsize_, _canvassize_ )
|
||||
|
||||
self.BarSize = _barsize_
|
||||
self.CanvasSize = math.max( _canvassize_ - _barsize_, 1 )
|
||||
|
||||
self:SetEnabled( _canvassize_ > _barsize_ )
|
||||
|
||||
self:InvalidateLayout()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnMouseWheeled( dlta )
|
||||
|
||||
if ( !self:IsVisible() ) then return false end
|
||||
|
||||
-- We return true if the scrollbar changed.
|
||||
-- If it didn't, we feed the mousehweeling to the parent panel
|
||||
|
||||
return self:AddScroll( dlta * -2 )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AddScroll( dlta )
|
||||
|
||||
local OldScroll = self:GetScroll()
|
||||
|
||||
dlta = dlta * 25
|
||||
self:SetScroll( self:GetScroll() + dlta )
|
||||
|
||||
return OldScroll != self:GetScroll()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetScroll( scrll )
|
||||
|
||||
if ( !self.Enabled ) then self.Scroll = 0 return end
|
||||
|
||||
self.Scroll = math.Clamp( scrll, 0, self.CanvasSize )
|
||||
|
||||
self:InvalidateLayout()
|
||||
|
||||
-- If our parent has a OnVScroll function use that, if
|
||||
-- not then invalidate layout (which can be pretty slow)
|
||||
|
||||
local func = self:GetParent().OnVScroll
|
||||
if ( func ) then
|
||||
|
||||
func( self:GetParent(), self:GetOffset() )
|
||||
|
||||
else
|
||||
|
||||
self:GetParent():InvalidateLayout()
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AnimateTo( scrll, length, delay, ease )
|
||||
|
||||
local anim = self:NewAnimation( length, delay, ease )
|
||||
anim.StartPos = self.Scroll
|
||||
anim.TargetPos = scrll
|
||||
anim.Think = function( anim, pnl, fraction )
|
||||
|
||||
pnl:SetScroll( Lerp( fraction, anim.StartPos, anim.TargetPos ) )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:GetScroll()
|
||||
|
||||
if ( !self.Enabled ) then self.Scroll = 0 end
|
||||
return self.Scroll
|
||||
|
||||
end
|
||||
|
||||
function PANEL:GetOffset()
|
||||
|
||||
if ( !self.Enabled ) then return 0 end
|
||||
return self.Scroll * -1
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
end
|
||||
|
||||
function PANEL:Paint( w, h )
|
||||
|
||||
self:GetSkin().tex.Scroller.TrackH(0,0,w,h)
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnMousePressed()
|
||||
|
||||
local x, y = self:CursorPos()
|
||||
|
||||
local PageSize = self.BarSize
|
||||
|
||||
if ( x > self.btnGrip.x ) then
|
||||
self:SetScroll( self:GetScroll() + PageSize )
|
||||
else
|
||||
self:SetScroll( self:GetScroll() - PageSize )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnMouseReleased()
|
||||
|
||||
self.Dragging = false
|
||||
self.DraggingCanvas = nil
|
||||
self:MouseCapture( false )
|
||||
|
||||
self.btnGrip.Depressed = false
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnCursorMoved( x, y )
|
||||
|
||||
if ( !self.Enabled ) then return end
|
||||
if ( !self.Dragging ) then return end
|
||||
|
||||
local x, y = self:ScreenToLocal( gui.MouseX(), 0 )
|
||||
|
||||
-- Uck.
|
||||
x = x - self.btnLeft:GetWide()
|
||||
x = x - self.HoldPos
|
||||
|
||||
local BtnHeight = self:GetTall()
|
||||
if ( self:GetHideButtons() ) then BtnHeight = 0 end
|
||||
|
||||
local TrackSize = self:GetWide() - BtnHeight * 2 - self.btnGrip:GetWide()
|
||||
|
||||
x = x / TrackSize
|
||||
|
||||
self:SetScroll( x * self.CanvasSize )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Grip()
|
||||
|
||||
if ( !self.Enabled ) then return end
|
||||
if ( self.BarSize == 0 ) then return end
|
||||
|
||||
self:MouseCapture( true )
|
||||
self.Dragging = true
|
||||
|
||||
local x, y = self.btnGrip:ScreenToLocal( gui.MouseX(), 0 )
|
||||
self.HoldPos = x
|
||||
|
||||
self.btnGrip.Depressed = true
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local Wide = self:GetTall()
|
||||
local BtnHeight = Wide
|
||||
if ( self:GetHideButtons() ) then BtnHeight = 0 end
|
||||
local Scroll = self:GetScroll() / self.CanvasSize
|
||||
local BarSize = math.max( self:BarScale() * ( self:GetWide() - ( BtnHeight * 2 ) ), 10 )
|
||||
local Track = self:GetWide() - ( BtnHeight * 2 ) - BarSize
|
||||
Track = Track + 1
|
||||
|
||||
Scroll = Scroll * Track
|
||||
|
||||
self.btnGrip:SetPos( BtnHeight + Scroll, 0 )
|
||||
self.btnGrip:SetSize( BarSize, Wide )
|
||||
|
||||
if ( BtnHeight > 0 ) then
|
||||
self.btnLeft:SetPos( 0, 0, Wide, Wide )
|
||||
self.btnLeft:SetSize( BtnHeight, Wide )
|
||||
|
||||
self.btnRight:SetPos( self:GetWide() - BtnHeight, 0 )
|
||||
self.btnRight:SetSize(BtnHeight, Wide )
|
||||
|
||||
self.btnLeft:SetVisible( true )
|
||||
self.btnRight:SetVisible( true )
|
||||
else
|
||||
self.btnLeft:SetVisible( false )
|
||||
self.btnRight:SetVisible( false )
|
||||
self.btnRight:SetSize( BtnHeight, Wide )
|
||||
self.btnLeft:SetSize( BtnHeight, Wide )
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
local PANEL = vgui.Register("pac_scrollpanel_horizontal", {}, "DPanel")
|
||||
|
||||
AccessorFunc( PANEL, "Padding", "Padding" )
|
||||
AccessorFunc( PANEL, "pnlCanvas", "Canvas" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.pnlCanvas = vgui.Create( "Panel", self )
|
||||
self.pnlCanvas.OnMousePressed = function( self, code ) self:GetParent():OnMousePressed( code ) end
|
||||
self.pnlCanvas:SetMouseInputEnabled( true )
|
||||
self.pnlCanvas.PerformLayout = function( pnl )
|
||||
|
||||
self:PerformLayout()
|
||||
self:InvalidateParent()
|
||||
|
||||
end
|
||||
|
||||
-- Create the scroll bar
|
||||
self.VBar = vgui.Create( "pac_horizontal_scrollbar", self )
|
||||
self.VBar:Dock( BOTTOM )
|
||||
|
||||
self:SetPadding( 0 )
|
||||
self:SetMouseInputEnabled( true )
|
||||
|
||||
-- This turns off the engine drawing
|
||||
self:SetPaintBackgroundEnabled( false )
|
||||
self:SetPaintBorderEnabled( false )
|
||||
self:SetPaintBackground( false )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AddItem( pnl )
|
||||
|
||||
pnl:SetParent( self:GetCanvas() )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnChildAdded( child )
|
||||
|
||||
self:AddItem( child )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SizeToContents()
|
||||
|
||||
self:SetSize( self.pnlCanvas:GetSize() )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:GetVBar()
|
||||
|
||||
return self.VBar
|
||||
|
||||
end
|
||||
|
||||
function PANEL:GetCanvas()
|
||||
|
||||
return self.pnlCanvas
|
||||
|
||||
end
|
||||
|
||||
function PANEL:InnerWidth()
|
||||
|
||||
return self:GetCanvas():GetTall()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Rebuild()
|
||||
|
||||
self:GetCanvas():SizeToChildren( true, false )
|
||||
|
||||
-- Although this behaviour isn't exactly implied, center vertically too
|
||||
if ( self.m_bNoSizing && self:GetCanvas():GetWide() < self:GetWide() ) then
|
||||
|
||||
self:GetCanvas():SetPos( ( self:GetWide() - self:GetCanvas():GetWide() ) * 0.5, 0 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnMouseWheeled( dlta )
|
||||
|
||||
return self.VBar:OnMouseWheeled( dlta )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnVScroll( iOffset )
|
||||
|
||||
self.pnlCanvas:SetPos( iOffset, 0 )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:ScrollToChild( panel )
|
||||
|
||||
self:PerformLayout()
|
||||
|
||||
local x, y = self.pnlCanvas:GetChildPosition( panel )
|
||||
local w, h = panel:GetSize()
|
||||
|
||||
x = x + w * 0.5
|
||||
x = x - self:GetWide() * 0.5
|
||||
|
||||
self.VBar:AnimateTo( x, 0.5, 0, 0.5 )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local Tall = self.pnlCanvas:GetWide()
|
||||
local Wide = self:GetWide()
|
||||
local YPos = 0
|
||||
|
||||
self:Rebuild()
|
||||
|
||||
self.VBar:SetUp( self:GetWide(), self.pnlCanvas:GetWide() )
|
||||
YPos = self.VBar:GetOffset()
|
||||
|
||||
if ( self.VBar.Enabled ) then Wide = Wide - self.VBar:GetWide() end
|
||||
|
||||
self.pnlCanvas:SetPos( YPos, 0 )
|
||||
self.pnlCanvas:SetWide( Wide )
|
||||
|
||||
self:Rebuild()
|
||||
|
||||
if ( Tall != self.pnlCanvas:GetWide() ) then
|
||||
self.VBar:SetScroll( self.VBar:GetScroll() ) -- Make sure we are not too far down!
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Clear()
|
||||
|
||||
return self.pnlCanvas:Clear()
|
||||
|
||||
end
|
||||
end
|
||||
593
lua/pac3/editor/client/panels/tree.lua
Normal file
593
lua/pac3/editor/client/panels/tree.lua
Normal file
@@ -0,0 +1,593 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
local L = pace.LanguageString
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.ClassName = "tree"
|
||||
PANEL.Base = "pac_dtree"
|
||||
|
||||
function PANEL:Init()
|
||||
pace.pac_dtree.Init(self)
|
||||
|
||||
self:SetLineHeight(18)
|
||||
self:SetIndentSize(10)
|
||||
|
||||
self.parts = {}
|
||||
|
||||
self:Populate()
|
||||
|
||||
pace.tree = self
|
||||
end
|
||||
|
||||
do
|
||||
local function get_added_nodes(self)
|
||||
local added_nodes = {}
|
||||
for i,v in ipairs(self.added_nodes) do
|
||||
if v.part and v:IsVisible() and v:IsExpanded() then
|
||||
table.insert(added_nodes, v)
|
||||
end
|
||||
end
|
||||
table.sort(added_nodes, function(a, b) return select(2, a:LocalToScreen()) < select(2, b:LocalToScreen()) end)
|
||||
return added_nodes
|
||||
end
|
||||
|
||||
local function scroll_to_node(self, node)
|
||||
timer.Simple(0.1, function()
|
||||
if not self:IsValid() then return end
|
||||
if not node:IsValid() then return end
|
||||
|
||||
local _, y = self:LocalToScreen()
|
||||
local h = self:GetTall()
|
||||
|
||||
local _, node_y = node:LocalToScreen()
|
||||
|
||||
if node_y > y + h or node_y < y then
|
||||
self:ScrollToChild(node)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local info_image = {
|
||||
pace.MiscIcons.info,
|
||||
pace.MiscIcons.warning,
|
||||
pace.MiscIcons.error,
|
||||
}
|
||||
|
||||
function PANEL:Think(...)
|
||||
if not pace.current_part:IsValid() then return end
|
||||
|
||||
if
|
||||
pace.current_part.pace_tree_node and
|
||||
pace.current_part.pace_tree_node:IsValid() and not
|
||||
(
|
||||
pace.BusyWithProperties:IsValid() or
|
||||
pace.ActiveSpecialPanel:IsValid() or
|
||||
pace.editing_viewmodel or
|
||||
pace.editing_hands or
|
||||
pace.properties.search:HasFocus()
|
||||
) and
|
||||
not gui.IsConsoleVisible()
|
||||
then
|
||||
if input.IsKeyDown(KEY_LEFT) then
|
||||
pace.Call("VariableChanged", pace.current_part, "EditorExpand", false)
|
||||
elseif input.IsKeyDown(KEY_RIGHT) then
|
||||
pace.Call("VariableChanged", pace.current_part, "EditorExpand", true)
|
||||
end
|
||||
|
||||
if input.IsKeyDown(KEY_UP) or input.IsKeyDown(KEY_PAGEUP) then
|
||||
local added_nodes = get_added_nodes(self)
|
||||
local offset = input.IsKeyDown(KEY_PAGEUP) and 10 or 1
|
||||
if not self.scrolled_up or self.scrolled_up < os.clock() then
|
||||
for i,v in ipairs(added_nodes) do
|
||||
if v == pace.current_part.pace_tree_node then
|
||||
local node = added_nodes[i - offset] or added_nodes[1]
|
||||
if node then
|
||||
node:DoClick()
|
||||
scroll_to_node(self, node)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.scrolled_up = self.scrolled_up or os.clock() + 0.4
|
||||
end
|
||||
else
|
||||
self.scrolled_up = nil
|
||||
end
|
||||
|
||||
if input.IsKeyDown(KEY_DOWN) or input.IsKeyDown(KEY_PAGEDOWN) then
|
||||
local added_nodes = get_added_nodes(self)
|
||||
local offset = input.IsKeyDown(KEY_PAGEDOWN) and 10 or 1
|
||||
if not self.scrolled_down or self.scrolled_down < os.clock() then
|
||||
for i,v in ipairs(added_nodes) do
|
||||
if v == pace.current_part.pace_tree_node then
|
||||
local node = added_nodes[i + offset] or added_nodes[#added_nodes]
|
||||
if node then
|
||||
node:DoClick()
|
||||
--scroll_to_node(self, node)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.scrolled_down = self.scrolled_down or os.clock() + 0.4
|
||||
end
|
||||
else
|
||||
self.scrolled_down = nil
|
||||
end
|
||||
end
|
||||
|
||||
for _, part in pairs(pac.GetLocalParts()) do
|
||||
local node = part.pace_tree_node
|
||||
if not node or not node:IsValid() then continue end
|
||||
|
||||
if node.add_button then
|
||||
node.add_button:SetVisible(false)
|
||||
end
|
||||
|
||||
if part.Info then
|
||||
local info = part.Info
|
||||
node.info:SetTooltip(info.message)
|
||||
node.info:SetImage(info_image[info.type])
|
||||
node.info:SetVisible(true)
|
||||
else
|
||||
node.info:SetVisible(false)
|
||||
end
|
||||
|
||||
if part.ClassName == "event" then
|
||||
if part.is_active then
|
||||
node.Icon:SetImage("icon16/clock_red.png")
|
||||
else
|
||||
node.Icon:SetImage(part.Icon)
|
||||
end
|
||||
end
|
||||
|
||||
if part.ClassName == "custom_animation" then
|
||||
local anim = part:GetLuaAnimation()
|
||||
if anim then
|
||||
node:SetText(part:GetName() .. " [" .. string.format("%.2f", anim.Frame + anim.FrameDelta) .. "]")
|
||||
end
|
||||
end
|
||||
|
||||
if (part.ClassName == "proxy" or part.ClassName == "event") and part.Name == "" then
|
||||
node:SetText(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName())
|
||||
end
|
||||
|
||||
if part:IsHiddenCached() then
|
||||
if not node.Icon.event_icon then
|
||||
local pnl = vgui.Create("DImage", node.Icon)
|
||||
pnl:SetImage("icon16/clock_red.png")
|
||||
pnl:SetSize(8, 8)
|
||||
pnl:SetPos(8, 8)
|
||||
pnl:SetVisible(false)
|
||||
node.Icon.event_icon = pnl
|
||||
end
|
||||
|
||||
node.Icon.event_icon:SetVisible(true)
|
||||
else
|
||||
if node.Icon.event_icon then
|
||||
node.Icon.event_icon:SetVisible(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local pnl = vgui.GetHoveredPanel() or NULL
|
||||
|
||||
if pnl:IsValid() then
|
||||
local pnl = pnl:GetParent()
|
||||
|
||||
if IsValid(pnl) and IsValid(pnl.part) then
|
||||
pace.Call("HoverPart", pnl.part)
|
||||
if pnl.add_button then
|
||||
pnl.add_button:SetVisible(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:OnMouseReleased(mc)
|
||||
if mc == MOUSE_RIGHT then
|
||||
pace.Call("PartMenu")
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetModel(path)
|
||||
if not file.Exists(path, "GAME") then
|
||||
path = player_manager.TranslatePlayerModel(path)
|
||||
if not file.Exists(path, "GAME") then
|
||||
print(path, "is invalid")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local pnl = vgui.Create("SpawnIcon", self)
|
||||
pnl:SetModel(path or "")
|
||||
pnl:SetSize(16, 16)
|
||||
|
||||
self.Icon:Remove()
|
||||
self.Icon = pnl
|
||||
|
||||
self.ModelPath = path
|
||||
end
|
||||
|
||||
function PANEL:GetModel()
|
||||
return self.ModelPath
|
||||
end
|
||||
|
||||
local function install_drag(node)
|
||||
node:SetDraggableName("pac3")
|
||||
|
||||
local old = node.OnDrop
|
||||
function node:OnDrop(child, ...)
|
||||
-- we're hovering on the label, not the actual node
|
||||
-- so get the parent node instead
|
||||
if not child.part then
|
||||
child = child:GetParent()
|
||||
end
|
||||
|
||||
if child.part and child.part:IsValid() then
|
||||
if self.part and self.part:IsValid() and self.part:GetParent() ~= child.part then
|
||||
pace.RecordUndoHistory()
|
||||
self.part:SetParent(child.part)
|
||||
pace.RecordUndoHistory()
|
||||
end
|
||||
elseif self.part and self.part:IsValid() then
|
||||
if self.part.ClassName ~= "group" then
|
||||
pace.RecordUndoHistory()
|
||||
local group = pac.CreatePart("group", self.part:GetPlayerOwner())
|
||||
group:SetEditorExpand(true)
|
||||
self.part:SetParent(group)
|
||||
pace.RecordUndoHistory()
|
||||
pace.TrySelectPart()
|
||||
|
||||
else
|
||||
pace.RecordUndoHistory()
|
||||
self.part:SetParent()
|
||||
pace.RecordUndoHistory()
|
||||
pace.RefreshTree(true)
|
||||
end
|
||||
end
|
||||
|
||||
return old(self, child, ...)
|
||||
end
|
||||
|
||||
function node:DroppedOn(child)
|
||||
|
||||
if not child.part then
|
||||
child = child:GetParent()
|
||||
end
|
||||
|
||||
self:InsertNode(child)
|
||||
self:SetExpanded(true)
|
||||
|
||||
if child.part and child.part:IsValid() then
|
||||
if self.part and self.part:IsValid() and child.part:GetParent() ~= self.part then
|
||||
pace.RecordUndoHistory()
|
||||
child.part:SetParent(self.part)
|
||||
pace.RecordUndoHistory()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local function install_expand(node)
|
||||
local old = node.SetExpanded
|
||||
node.SetExpanded = function(self, b, ...)
|
||||
if self.part and self.part:IsValid() then
|
||||
self.part:SetEditorExpand(b)
|
||||
return old(self, b, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local old = node.Expander.OnMousePressed
|
||||
node.Expander.OnMousePressed = function(pnl, code, ...)
|
||||
old(pnl, code, ...)
|
||||
|
||||
if code == MOUSE_RIGHT then
|
||||
local menu = DermaMenu()
|
||||
menu:SetPos(input.GetCursorPos())
|
||||
menu:MakePopup()
|
||||
|
||||
menu:AddOption(L"collapse all", function()
|
||||
node.part:CallRecursive('SetEditorExpand', false)
|
||||
pace.RefreshTree(true)
|
||||
end):SetImage('icon16/arrow_in.png')
|
||||
|
||||
menu:AddOption(L"expand all", function()
|
||||
node.part:CallRecursive('SetEditorExpand', true)
|
||||
pace.RefreshTree(true)
|
||||
end):SetImage('icon16/arrow_down.png')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local fix_folder_funcs = function(tbl)
|
||||
tbl.MakeFolder = function() end
|
||||
tbl.FilePopulateCallback = function() end
|
||||
tbl.FilePopulate = function() end
|
||||
tbl.PopulateChildren = function() end
|
||||
tbl.ChildExpanded = function() end
|
||||
tbl.PopulateChildrenAndSelf = function() end
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function node_layout(self, ...)
|
||||
pace.pac_dtree_node.PerformLayout(self, ...)
|
||||
if self.Label then
|
||||
self.Label:SetFont(pace.CurrentFont)
|
||||
--self.Label:SetTextColor(derma.Color("text_dark", self, color_black))
|
||||
end
|
||||
|
||||
if self.add_button then
|
||||
local x = self.Label:GetPos() + self.Label:GetTextInset() + 4
|
||||
surface.SetFont(pace.CurrentFont)
|
||||
local w = surface.GetTextSize(self.Label:GetText())
|
||||
self.add_button:SetPos(x + w, (self.Label:GetTall() - self.add_button:GetTall()) / 2)
|
||||
end
|
||||
|
||||
if self.info then
|
||||
local is_adding = self.add_button:IsVisible()
|
||||
local x = self.Label:GetPos() + self.Label:GetTextInset() + (is_adding and self.add_button:GetWide() + 4 or 4)
|
||||
surface.SetFont(pace.CurrentFont)
|
||||
local w = surface.GetTextSize(self.Label:GetText())
|
||||
self.info:SetPos(x + w, (self.Label:GetTall() - self.info:GetTall()) / 2)
|
||||
end
|
||||
end
|
||||
|
||||
local function add_parts_menu(node)
|
||||
pace.Call("AddPartMenu", node.part)
|
||||
end
|
||||
|
||||
-- a hack, because creating a new node button will mess up the layout
|
||||
function PANEL:AddNode(...)
|
||||
|
||||
if self.RootNode then
|
||||
install_drag(self.RootNode)
|
||||
end
|
||||
|
||||
local node = fix_folder_funcs((self.RootNode and pace.pac_dtree.AddNode or pace.pac_dtree_node.AddNode)(self, ...))
|
||||
install_expand(node)
|
||||
install_drag(node)
|
||||
|
||||
local add_button = node:Add("DImageButton")
|
||||
add_button:SetImage(pace.MiscIcons.new)
|
||||
add_button:SetSize(16, 16)
|
||||
add_button:SetVisible(false)
|
||||
add_button.DoClick = function() add_parts_menu(node) pace.Call("PartSelected", node.part) end
|
||||
add_button.DoRightClick = function() node:DoRightClick() end
|
||||
node.add_button = add_button
|
||||
node.SetModel = self.SetModel
|
||||
node.GetModel = self.GetModel
|
||||
node.AddNode = PANEL.AddNode
|
||||
node.PerformLayout = node_layout
|
||||
|
||||
local info = node:Add("DImageButton")
|
||||
info:SetImage(pace.MiscIcons.info)
|
||||
info:SetSize(16, 16)
|
||||
info:SetVisible(false)
|
||||
info.DoClick = function() pace.MessagePrompt(info:GetTooltip()) end
|
||||
node.info = info
|
||||
|
||||
return node
|
||||
end
|
||||
|
||||
local enable_model_icons = CreateClientConVar("pac_editor_model_icons", "1")
|
||||
|
||||
function PANEL:PopulateParts(node, parts, children)
|
||||
fix_folder_funcs(node)
|
||||
|
||||
local temp = {}
|
||||
for k,v in pairs(parts) do
|
||||
table.insert(temp, v)
|
||||
end
|
||||
parts = temp
|
||||
|
||||
local tbl = {}
|
||||
|
||||
table.sort(parts, function(a,b)
|
||||
return a and b and a:GetName() < b:GetName()
|
||||
end)
|
||||
|
||||
for key, val in pairs(parts) do
|
||||
if not val:HasChildren() then
|
||||
table.insert(tbl, val)
|
||||
end
|
||||
end
|
||||
|
||||
for key, val in pairs(parts) do
|
||||
if val:HasChildren() then
|
||||
table.insert(tbl, val)
|
||||
end
|
||||
end
|
||||
|
||||
for key, part in pairs(tbl) do
|
||||
key = part.Id
|
||||
|
||||
if not part:GetShowInEditor() then goto CONTINUE end
|
||||
|
||||
if not part:HasParent() or children then
|
||||
local part_node
|
||||
|
||||
if IsValid(part.pace_tree_node) then
|
||||
part_node = part.pace_tree_node
|
||||
elseif IsValid(self.parts[key]) then
|
||||
part_node = self.parts[key]
|
||||
else
|
||||
part_node = node:AddNode(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName())
|
||||
end
|
||||
|
||||
fix_folder_funcs(part_node)
|
||||
|
||||
if part.Description then part_node:SetTooltip(L(part.Description)) end
|
||||
|
||||
part.pace_tree_node = part_node
|
||||
part_node.part = part
|
||||
|
||||
self.parts[key] = part_node
|
||||
|
||||
part_node.DoClick = function()
|
||||
if not part:IsValid() then return end
|
||||
pace.Call("PartSelected", part)
|
||||
|
||||
--part_node.add_button:SetVisible(true)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
part_node.DoRightClick = function()
|
||||
if not part:IsValid() then return end
|
||||
|
||||
pace.Call("PartMenu", part)
|
||||
pace.Call("PartSelected", part)
|
||||
part_node:InternalDoClick()
|
||||
return true
|
||||
end
|
||||
|
||||
if
|
||||
enable_model_icons:GetBool() and
|
||||
part.is_model_part and
|
||||
part.GetModel and
|
||||
part:GetOwner():IsValid()
|
||||
then
|
||||
part_node:SetModel(part:GetOwner():GetModel(), part.Icon)
|
||||
elseif isstring(part.Icon) then
|
||||
part_node.Icon:SetImage(part.Icon)
|
||||
end
|
||||
|
||||
self:PopulateParts(part_node, part:GetChildren(), true)
|
||||
|
||||
if part.newly_created then
|
||||
part_node:SetSelected(true)
|
||||
|
||||
local function expand(part)
|
||||
if part:HasParent() and part.Parent.pace_tree_node then
|
||||
part.Parent.pace_tree_node:SetExpanded(true)
|
||||
expand(part.Parent)
|
||||
end
|
||||
end
|
||||
|
||||
expand(part)
|
||||
|
||||
part_node:SetSelected(true)
|
||||
part.newly_created = nil
|
||||
else
|
||||
part_node:SetSelected(false)
|
||||
part_node:SetExpanded(part:GetEditorExpand())
|
||||
end
|
||||
end
|
||||
::CONTINUE::
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SelectPart(part)
|
||||
for key, node in pairs(self.parts) do
|
||||
if not node.part or not node.part:IsValid() then
|
||||
node:Remove()
|
||||
self.parts[key] = nil
|
||||
else
|
||||
if node.part == part then
|
||||
node:SetSelected(true)
|
||||
else
|
||||
node:SetSelected(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:Populate(reset)
|
||||
|
||||
self:SetLineHeight(18)
|
||||
self:SetIndentSize(2)
|
||||
|
||||
for key, node in pairs(self.parts) do
|
||||
if reset or (not node.part or not node.part:IsValid()) then
|
||||
node:Remove()
|
||||
self.parts[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--[[self.m_pSelectedItem = nil
|
||||
|
||||
for key, node in pairs(self:GetItems()) do
|
||||
node:Remove()
|
||||
end]]
|
||||
|
||||
self:PopulateParts(self, pac.GetLocalParts())
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
|
||||
local function remove_node(part)
|
||||
if not part:GetShowInEditor() then return end
|
||||
|
||||
if (part.pace_tree_node or NULL):IsValid() then
|
||||
part.pace_tree_node:SetForceShowExpander()
|
||||
part.pace_tree_node:GetRoot().m_pSelectedItem = nil
|
||||
part.pace_tree_node:Remove()
|
||||
pace.RefreshTree()
|
||||
end
|
||||
end
|
||||
|
||||
pac.AddHook("pac_OnPartRemove", "pace_remove_tree_nodes", remove_node)
|
||||
|
||||
|
||||
local last_refresh = 0
|
||||
local function refresh(part)
|
||||
if last_refresh > SysTime() then return end
|
||||
if not part:GetShowInEditor() then return end
|
||||
|
||||
|
||||
last_refresh = SysTime() + 0.1
|
||||
timer.Simple(0, function()
|
||||
if not part:IsValid() then return end
|
||||
if not part:GetShowInEditor() then return end
|
||||
|
||||
pace.RefreshTree(true)
|
||||
end)
|
||||
end
|
||||
|
||||
pac.AddHook("pac_OnWoreOutfit", "pace_refresh_tree_nodes", refresh)
|
||||
pac.AddHook("pac_OnPartParent", "pace_refresh_tree_nodes", refresh)
|
||||
pac.AddHook("pac_OnPartCreated", "pace_refresh_tree_nodes", refresh)
|
||||
|
||||
pac.AddHook("pace_OnVariableChanged", "pace_create_tree_nodes", function(part, key, val)
|
||||
if key == "EditorExpand" then
|
||||
local node = part.pace_tree_node
|
||||
if IsValid(node) then
|
||||
node:SetExpanded(val)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function pace.RefreshTree(reset)
|
||||
if pace.tree:IsValid() then
|
||||
timer.Create("pace_refresh_tree", 0.01, 1, function()
|
||||
if pace.tree:IsValid() then
|
||||
pace.tree:Populate(reset)
|
||||
pace.tree.RootNode:SetExpanded(true, true) -- why do I have to do this?
|
||||
|
||||
pace.TrySelectPart()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if Entity(1):IsPlayer() and not PAC_RESTART and not VLL2_FILEDEF then
|
||||
pace.OpenEditor()
|
||||
pace.RefreshTree(true)
|
||||
end
|
||||
209
lua/pac3/editor/client/panels/web_browser.lua
Normal file
209
lua/pac3/editor/client/panels/web_browser.lua
Normal file
@@ -0,0 +1,209 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
PANEL.Base = "DFrame"
|
||||
PANEL.ClassName = "web_browser"
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetTitle("Web Browser")
|
||||
self:SetDeleteOnClose(false)
|
||||
self:ShowCloseButton(true)
|
||||
self:SetDraggable(true)
|
||||
self:SetSizable(true)
|
||||
|
||||
local top = vgui.Create("EditablePanel", self)
|
||||
top:Dock(TOP)
|
||||
top:SetTall(24)
|
||||
self.top = top
|
||||
|
||||
local btn = vgui.Create("DButton", top)
|
||||
btn:SetText("Back")
|
||||
btn:SizeToContents()
|
||||
btn:SetWide(btn:GetWide()+8)
|
||||
btn:Dock(LEFT)
|
||||
btn.DoClick = function()
|
||||
self.browser:RunJavascript("history.back();")
|
||||
end
|
||||
|
||||
local btn = vgui.Create("DButton", top)
|
||||
btn:SetText("Forward")
|
||||
btn:SizeToContents()
|
||||
btn:SetWide(btn:GetWide()+8)
|
||||
btn:Dock(LEFT)
|
||||
btn.DoClick = function()
|
||||
self.browser:RunJavascript("history.forward();")
|
||||
end
|
||||
|
||||
local btn = vgui.Create("DButton", top)
|
||||
btn:SetText("Refresh")
|
||||
btn:SizeToContents()
|
||||
btn:SetWide(btn:GetWide() + 8)
|
||||
btn:Dock(LEFT)
|
||||
|
||||
btn.DoClick = function()
|
||||
self.browser:RunJavascript("location.reload(true);")
|
||||
end
|
||||
|
||||
btn.Paint = function(btn,w,h)
|
||||
DButton.Paint(btn,w,h)
|
||||
|
||||
if self.loaded then
|
||||
if self.browser:IsLoading() then
|
||||
self.loaded = false
|
||||
end
|
||||
|
||||
surface.SetDrawColor(100, 240, 50, 200)
|
||||
surface.DrawRect(1, 1, w-2, h-2)
|
||||
end
|
||||
|
||||
if self.browser:IsLoading() then
|
||||
surface.SetDrawColor(240 + math.sin(RealTime()*10)*15, 100, 50, 200)
|
||||
surface.DrawRect(1, 1, w-2, h-2)
|
||||
end
|
||||
end
|
||||
|
||||
local entry = vgui.Create("DTextEntry", top)
|
||||
self.entry = entry
|
||||
entry:Dock(FILL)
|
||||
entry:SetTall( 24)
|
||||
|
||||
entry.OnEnter = function(entry)
|
||||
local val = entry:GetText()
|
||||
local js,txt = val:match("javascript:(.+)")
|
||||
|
||||
if js and txt then
|
||||
self.browser:QueueJavascript(txt)
|
||||
return
|
||||
end
|
||||
|
||||
self:OpenURL(val)
|
||||
end
|
||||
|
||||
local browser = vgui.Create("DHTML", self)
|
||||
self.browser = browser
|
||||
browser:Dock(FILL)
|
||||
browser.Paint = function() end
|
||||
browser.OpeningURL = pac.Message
|
||||
browser.FinishedURL = pac.Message
|
||||
browser:AddFunction("gmod", "LoadedURL", function(url, title)
|
||||
self:LoadedURL(url,title)
|
||||
end)
|
||||
browser:AddFunction("gmod", "dbg", function(...)
|
||||
pac.Message('[Browser] ', ...)
|
||||
end)
|
||||
browser:AddFunction("gmod", "status", function(txt)
|
||||
self:StatusChanged(txt)
|
||||
end)
|
||||
browser.ActionSignal = function(...)
|
||||
pac.Message('[BrowserACT] ', ...)
|
||||
end
|
||||
|
||||
browser.OnKeyCodePressed = function(browser,code)
|
||||
if code == 96 then
|
||||
self.browser:RunJavascript[[location.reload(true);]]
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local status = vgui.Create("DLabel", self)
|
||||
self.status = status
|
||||
status:SetText""
|
||||
status:Dock(BOTTOM)
|
||||
end
|
||||
|
||||
function PANEL:StatusChanged(txt)
|
||||
if self.statustxt ~= txt then
|
||||
self.statustxt = txt
|
||||
self.status:SetText(txt or "")
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:LoadedURL(url,title)
|
||||
if self.entry:HasFocus() then return end
|
||||
self.entry:SetText(url)
|
||||
self.loaded = true
|
||||
self:SetTitle(title and title ~= "" and title or "Web browser")
|
||||
end
|
||||
|
||||
function PANEL:OpenURL(url)
|
||||
self.browser:OpenURL(url)
|
||||
self.entry:SetText(url)
|
||||
end
|
||||
|
||||
function PANEL:Think(w,h)
|
||||
self.BaseClass.Think(self,w,h)
|
||||
if input.IsKeyDown(KEY_ESCAPE) then
|
||||
self:Close()
|
||||
end
|
||||
|
||||
if not self.wasloading and self.browser:IsLoading() then
|
||||
self.wasloading = true
|
||||
end
|
||||
if self.wasloading and not self.browser:IsLoading() then
|
||||
self.wasloading = false
|
||||
self.browser:QueueJavascript[[gmod.LoadedURL(document.location.href,document.title); gmod.status(""); ]]
|
||||
self.browser:QueueJavascript[[function alert(str) { console.log("Alert: "+str); }]]
|
||||
self.browser:QueueJavascript[[if (!document.body.style.background) { document.body.style.background = 'white'; }; void 0;]]
|
||||
self.browser:QueueJavascript[[
|
||||
function getLink() {
|
||||
gmod.status(this.href || "-");
|
||||
}
|
||||
function clickLink() {
|
||||
if (this.href) {
|
||||
gmod.LoadedURL(this.href,"Loading...");
|
||||
}
|
||||
gmod.status("Loading...");
|
||||
}
|
||||
var links = document.getElementsByTagName("a");
|
||||
for (i = 0; i < links.length; i++) {
|
||||
links[i].addEventListener('mouseover',getLink,false)
|
||||
links[i].addEventListener('click',clickLink,false)
|
||||
}
|
||||
|
||||
]]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Show()
|
||||
if not self:IsVisible() then
|
||||
self:SetVisible(true)
|
||||
self:MakePopup()
|
||||
self:SetKeyboardInputEnabled(true)
|
||||
self:SetMouseInputEnabled(true)
|
||||
end
|
||||
|
||||
if ValidPanel(self.browser) then
|
||||
self.browser:RequestFocus()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Close()
|
||||
self:SetVisible(false)
|
||||
end
|
||||
|
||||
pace.wiki_panel = NULL
|
||||
|
||||
function pace.ShowWiki(url)
|
||||
if pace.wiki_panel:IsValid() then
|
||||
pace.wiki_panel:Remove()
|
||||
end
|
||||
|
||||
local pnl = pace.CreatePanel("web_browser")
|
||||
pnl:OpenURL(url or pace.WikiURL)
|
||||
pnl:SetSize(ScrW()*0.9, ScrH()*0.8)
|
||||
pnl:Center()
|
||||
pnl:MakePopup()
|
||||
pace.wiki_panel = pnl
|
||||
end
|
||||
|
||||
pace.RegisterPanel(PANEL)
|
||||
Reference in New Issue
Block a user