--[[ | 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 = {} function PANEL:Init() self:SetSize( 700, 200 ) self:Center() self:DockPadding( 10, 24 + 10, 10, 10 ) self:SetTitle( "#ugc_upload.frametitle" ) self:SetBackgroundBlur( true ) -- Indicate that the background elements won't be usable --self:SetSizable( true ) self.AddonList = self:Add( "DListView" ) self.AddonList:Dock( RIGHT ) self.AddonList:SetWide( 200 ) self.AddonList:AddColumn( "#ugc_upload.existing" ) self.AddonList:DockMargin( 10, 0, 0, 0 ) self.AddonList:SetMultiSelect( false ) self.AddonList:SetMouseInputEnabled( false ) self.AddonList.OnRowSelected = function( s, ... ) self:OnRowSelected( ... ) end self.AddonListLabel = self.AddonList:Add( "DLabel" ) self.AddonListLabel:Dock( FILL ) self.AddonListLabel:SetTextColor( color_black ) self.AddonListLabel:SetContentAlignment( 5 ) self.AddonListLabel:SetZPos( 100 ) self.AddonListLabel.Paint = function( s, w, h ) draw.RoundedBox( 0, 0, 0, w, h, Color( 0, 0, 0, 100 ) ) end -- TODO: Prolly should be hooked to skin local topContainer = self:Add( "Panel" ) topContainer:Dock( TOP ) topContainer:SetTall( 200 ) self.Image = topContainer:Add( "DImage" ) self.Image:Dock( LEFT ) self.Image:SetWide( 200 ) self.Image:DockMargin( 0, 0, 5, 0 ) local titleLabel = topContainer:Add( "DLabel" ) titleLabel:Dock( TOP ) titleLabel:SetText( "#ugc_upload.title" ) self.Title = topContainer:Add( "DTextEntry" ) self.Title:Dock( TOP ) self.Title:SetUpdateOnType( true ) self.Title.OnTextChanged = function( s ) self:CheckInput() end local descLabel = topContainer:Add( "DLabel" ) descLabel:Dock( TOP ) descLabel:SetText( "#ugc_upload.description" ) self.Description = topContainer:Add( "DTextEntry" ) self.Description:Dock( FILL ) self.Description:SetMultiline( true ) self.TagsLabel = self:Add( "DLabel" ) self.TagsLabel:Dock( TOP ) self.TagsLabel:SetText( "#ugc_upload.tags" ) self.Tags = self:Add( "Panel" ) self.Tags:Dock( TOP ) self.ChangeNotesLabel = self:Add( "DLabel" ) self.ChangeNotesLabel:Dock( TOP ) self.ChangeNotesLabel:DockMargin( 0, 5, 0, 0 ) self.ChangeNotesLabel:SetText( "#ugc_upload.changenotes" ) self.ChangeNotes = self:Add( "DTextEntry" ) self.ChangeNotes:Dock( TOP ) self.ChangeNotes:SetPlaceholderText( "ugc_upload.changenotes.help" ) self.ChangeNotes:SetVisible( false ) self.ChangeNotes:SetUpdateOnType( true ) self.ChangeNotes:SetMultiline( true ) self.ChangeNotes:SetTall( 80 ) self.Publish = self:Add( "DButton" ) self.Publish:Dock( TOP ) self.Publish:SetEnabled( false ) self.Publish:SetText( "#ugc_upload.publish" ) self.Publish:DockMargin( 0, 5, 0, 0 ) self.Publish.DoClick = function( s ) self:DoPublish() end self.UpdateProgress = self:Add( "DLabel" ) self.UpdateProgress:SetText( "Publising your content, please wait..." ) self.UpdateProgress:SetTextColor( color_black ) self.UpdateProgress:SetContentAlignment( 5 ) self.UpdateProgress:SetZPos( 100 ) self.UpdateProgress:SetVisible( false ) self.UpdateProgress.Paint = function( s, w, h ) s:StretchToParent( 4, 4, 4, 4 ) draw.RoundedBox( 0, 0, 0, w, h, Color( 200, 200, 200, 255 ) ) -- TODO: Prolly should be hooked to skin end end PANEL.TagsPerType = { save = { scenes = "#ugc_upload.tag_scenes_save", courses = "#ugc_upload.tag_courses", machines = "#ugc_upload.tag_machines", buildings = "#ugc_upload.tag_buildings", others = "#ugc_upload.tag_others" }, dupe = { posed = "#ugc_upload.tag_posed", scenes = "#ugc_upload.tag_scenes", vehicles = "#ugc_upload.tag_vehicles", machines = "#ugc_upload.tag_machines", buildings = "#ugc_upload.tag_buildings", others = "#ugc_upload.tag_others" } } function PANEL:FitContents() -- Make this panel smaller, stuff below won't shrink it, only expand it self:SetTall( 200 ) -- Set the window height to nicely fit everything, no extra space anywhere self:InvalidateLayout( true ) self:SizeToChildren( false, true ) end function PANEL:OnRowSelected( rowID, row ) -- Create new node, reset the fields if ( !row.WorkshopData ) then self.Publish:SetText( "#ugc_upload.publish" ) self.ChangeNotes:SetVisible( false ) self.ChangeNotesLabel:SetVisible( false ) self.Title:SetText( "" ) self.Description:SetText( "" ) for k, v in pairs( self.Tags:GetChildren() ) do v:SetChecked( false ) end -- SetChecked to not invoke OnChange self:FitContents() self:CheckInput() return end local dat = row.WorkshopData self.Title:SetText( dat.title ) self.Description:SetText( dat.description ) for k, v in pairs( self.Tags:GetChildren() ) do if ( dat.tags:find( v:GetName() ) ) then v:SetValue( true ) break end end self.Publish:SetText( "#ugc_upload.update" ) self.ChangeNotes:SetVisible( true ) self.ChangeNotesLabel:SetVisible( true ) self:FitContents() self:CheckInput() end function PANEL:Setup( ugcType, file, imageFile, handler ) self.ugcType = ugcType self.ugcFile = file self.ugcImage = imageFile self.ugcHandler = handler self.Image:SetImage( "../" .. self.ugcImage ) if ( self.TagsPerType[ self.ugcType ] ) then for k, v in pairs( self.TagsPerType[ self.ugcType ] ) do local rb = self.Tags:Add( "DCheckBoxLabel" ) rb:Dock( TOP ) rb:SetText( v ) rb:SetName( k ) rb:DockMargin( 4, 0, 0, 2 ) rb.OnChange = function( s, val ) self:CheckInput() local num = 0 for id, pnl in pairs( s:GetParent():GetChildren() ) do if ( pnl:GetChecked() ) then num = num + 1 end if ( pnl == s or !val ) then continue end pnl:SetValue( false ) -- Validate that only 1 is selected end if ( !val && num == 0 ) then s:SetValue( true ) end -- Don't allow to unselect the only 1 selected end Derma_Hook( rb.Button, "Paint", "Paint", "RadioButton" ) end self.Tags:InvalidateChildren( false ) -- Update position of all the docked elements self.Tags:SizeToChildren( false, true ) -- Set nice size for the tags container else self.TagsLabel:SetVisible( false ) self.Tags:SetVisible( false ) end self:FitContents() self:UpdateWorkshopItems() end function PANEL:UpdateWorkshopItems() self.AddonListLabel:SetVisible( true ) self.AddonListLabel:SetText( "#ugc_upload.loading" ) self.AddonList:Clear() self.AddonList:AddLine( "#ugc_upload.createnew" ) self.AddonList:SelectFirstItem() steamworks.GetList( "mine", { self.ugcType }, 0, 9999, 0, "1", function( data ) for i, id in pairs( data.results ) do steamworks.FileInfo( id, function( info ) local a = self.AddonList:AddLine( info.title ) a:SetTooltip( "#ugc_upload.rightclickopen" ) a.WorkshopID = id a.WorkshopData = info a.OnRightClick = function( s ) if ( !s.WorkshopID ) then return end steamworks.ViewFile( s.WorkshopID ) end self.AddonList:SetMouseInputEnabled( true ) self.AddonListLabel:SetVisible( false ) end ) end if ( data.totalresults == 0 ) then self.AddonListLabel:SetText( "#ugc_upload.nothingfound" ) end end ) end function PANEL:GetChosenTag() for k, v in pairs( self.Tags:GetChildren() ) do if ( v:GetChecked() ) then return v:GetName() end end end function PANEL:CheckInput() if ( self.TagsPerType[ self.ugcType ] && !self:GetChosenTag() ) then return self.Publish:SetEnabled( false ) end if ( self.Title:GetText() == "" ) then return self.Publish:SetEnabled( false ) end self.Publish:SetEnabled( true ) end local errors = {} errors[ "badhandle" ] = "Generic error while trying to create item." errors[ "createid" ] = "Generic error while trying to create workshop item ID." errors[ "badupdatehandle" ] = "Generic error while trying to update item." errors[ "badsubmitupdatehandle" ] = "Could not submit update to Steam." errors[ "cantupdate" ] = "Failed to upload workshop files to Steam." errors[ "badwords" ] = "Please refrain from uploading spam, vulgar, sexual or offensive content to Steam Workshop." function PANEL:DisplayError( err ) -- Unlock the UI and allow user to try again/make changes self.UpdateProgress:SetVisible( false ) self:SetMouseInputEnabled( true ) if ( err == "termsofservice" ) then err = "You must accept Steam Workshop Terms of Service before you can upload content!\nWould you like to open it right now?" Derma_Query( err, "Error while publishing content!", "Yes", function() gui.OpenURL( "http://steamcommunity.com/sharedfiles/workshoplegalagreement" ) end, "Nah" ) return end if ( errors[ err ] ) then err = errors[ err ] end Derma_Message( err or "UNKNOWN ERROR", "Error while publishing content!", "OK" ) end function PANEL:OnPublishFinished( wsid, err ) if ( !wsid ) then self:DisplayError( err ) return end -- TODO: Show "View item"/"Close" buttons instead? steamworks.ViewFile( wsid ) self:Remove() end function PANEL:DoPublish() local ChosenTag = self:GetChosenTag() if ( self.TagsPerType[ self.ugcType ] && ChosenTag == nil ) then self:DisplayError( "You must choose a tag!") return end if ( self.Title:GetText() == "" ) then self:DisplayError( "You must provide a title!" ) return end local workshopUpdateID = nil local updateButtonID, updateButton = self.AddonList:GetSelectedLine() if ( IsValid( updateButton ) ) then workshopUpdateID = updateButton.WorkshopID end -- Lock down the UI self.UpdateProgress:SetVisible( true ) self:SetMouseInputEnabled( false ) -- TODO: Display update progress? -- TODO: Confirmation dialog? -- Start the process local err = self.ugcHandler:FinishPublish( self.ugcFile, self.ugcImage, self.Title:GetText(), self.Description:GetText(), ChosenTag, { WorkshopID = workshopUpdateID, ChangeNotes = self.ChangeNotes:GetText(), Callback = function( wsid, erro ) self:OnPublishFinished( wsid, erro ) end } ) if ( err ) then self:DisplayError( err ) end end vgui.Register( "UGCPublishWindow", PANEL, "DFrame" )