• Multiple 'For Loops'
    28 replies, posted
Is it possible to use multiple for loops in each other? I have scanned through wiki, it only shows single for loops. I am trying to have 10 buttons create with a for loop. I can get the buttons to spawn, but my next for loop below the 10 button creation is naming the buttons from a table. I can also get that to work. The issue being is that the buttons spawn, but it's an infinite loop of them. (Using DHorizontalScroller).
I don't understand. Is this what you want? [lua]for i1 = 1, 10 do for i2 = 1, 10 do end end[/lua]
[lua] local CScroller = vgui.Create("DHorizontalScroller", MFrame) CScroller:SetSize(ClassPanel:GetWide() - 8, 40) CScroller:AlignBottom(1) CScroller:AlignLeft(1) CScroller:SetOverlap(-5) local ClassButtons = {} local ButtonsText = {"Citizen", "CP", "Mayor", "Gangster", "DrugLord", "Doctor", "Chef", "Chief", "Reporter"} for i=1, 10 do for k, v in pairs(ButtonsText) do ClassButtons[i] = vgui.Create("DButton", CScroller) --Create the button ClassButtons[i]:SetSize(140, 40) ClassButtons[i]:SetText(v) CScroller:AddPanel(ClassButtons[i]) --Add each button to our Scroller after we create it. end end [/lua] Current code ^ That is causing infinite loop.
That code works perfectly for me, save that it is creating each button 10 times.
-snip- misread.
Thats the problem, I don't want to have each button created *10. I only want 10 total, buttons, 1 for each class to be created. Yet this, for loop I have doesn't allow that, as you said, it creates each button *10.
Toss one of the loops and you're done.
Toss the tables loop, you have to add 40'odd more lines of code, Toss the button spawn loop, again, you have 40'odd lines of code. I thought using a loop would help optimize it. + I wouldn't mind learning how to work with multiple for loops, in case I need to use them in the future.
[QUOTE=Sykore;22270669]Toss the tables loop, you have to add 40'odd more lines of code, Toss the button spawn loop, again, you have 40'odd lines of code. I thought using a loop would help optimize it. + I wouldn't mind learning how to work with multiple for loops, in case I need to use them in the future.[/QUOTE] [lua] local CScroller = vgui.Create("DHorizontalScroller", MFrame) CScroller:SetSize(ClassPanel:GetWide() - 8, 40) CScroller:AlignBottom(1) CScroller:AlignLeft(1) CScroller:SetOverlap(-5) local ClassButtons = {} local ButtonsText = {"Citizen", "CP", "Mayor", "Gangster", "DrugLord", "Doctor", "Chef", "Chief", "Reporter"} for k, v in pairs(ButtonsText) do ClassButtons[i] = vgui.Create("DButton", CScroller) --Create the button ClassButtons[i]:SetSize(140, 40) ClassButtons[i]:SetText(v) CScroller:AddPanel(ClassButtons[i]) --Add each button to our Scroller after we create it. end [/lua] There you go.
Thank you, after removing the [i], it worked like a charm. How ever I have run into another dilemma, Instead of using DButton in the Scroller, I would like to use SpawnIcons. How ever when attempting to do this, I get the following error; [QUOTE] addons\derma\lua\vgui\dhorizontalscroller.lua:99: attempt to call method 'ApplySchemeSettings' (a nil value) [/QUOTE] [lua] local ClassPanel = vgui.Create( "DPanelList", MFrame) ClassPanel:EnableHorizontal(true) --ClassPanel:EnableVerticalScrollbar(false) ClassPanel:SetPadding(1) ClassPanel:SetSize(425, 90) ClassPanel:SetPos(50, 35) local CScroller = vgui.Create("DHorizontalScroller", MFrame) CScroller:SetSize(ClassPanel:GetWide() - 8, 40) CScroller:AlignBottom(1) CScroller:AlignLeft(1) CScroller:SetOverlap(-5) local ClassButtons = {} local ButtonsText = {"models/Humans/Group01/male_06.mdl", "models/player/police.mdl", "models/player/breen.mdl", "models/player/group03/male_01.mdl", "models/player/gman_high.mdl", "models/player/kleiner.mdl", "models/player/mossman.mdl", "models/player/police.mdl", "models/Eli.mdl"} for k, v in pairs(ButtonsText) do ClassButtons = vgui.Create("SpawnIcon", CScroller) --Create the button ClassButtons:SetIconSize(64) ClassButtons:SetModel(v) CScroller:AddPanel(ClassButtons) --Add each button to our Scroller after we create it. end [/lua]
Try ClassPanel:AddItem(ClassButtons) and below the for loop CScroller:AddPanel(ClassPanel)
[QUOTE] addons\derma\lua\vgui\dhorizontalscroller.lua:99: attempt to call method 'ApplySchemeSettings' (a nil value) [/QUOTE] Still receiving that error. [lua]for k, v in pairs(ButtonsText) do ClassButtons = vgui.Create("SpawnIcon", CScroller) --Create the button ClassButtons:SetModel(v) ClassPanel:AddItem(ClassButtons) --Add each button to our Scroller after we create it. end CScroller:AddPanel(ClassPanel) [/lua]
I'll fire up the good 'ol notepad and Gmod Wiki. If I'm not ninja'd i'll try to fix. :f5: [editline]12:19AM[/editline] Idea: have you used SetUp on the scrollbar?
Negative.
*facepalm* Nevermind, scratch that. I misread somthing [editline]12:29AM[/editline] Try this: [code] local ClassPanel = vgui.Create( "DPanelList", MFrame) ClassPanel:EnableHorizontal(true) --ClassPanel:EnableVerticalScrollbar(false) ClassPanel:SetPadding(1) ClassPanel:SetSize(425, 90) ClassPanel:SetPos(50, 35) local CScroller = vgui.Create("DHorizontalScroller", MFrame) CScroller:SetSize(ClassPanel:GetWide() - 8, 40) CScroller:AlignBottom(1) CScroller:AlignLeft(1) CScroller:SetOverlap(-5) local ClassButtons = {} local ButtonsText = {"models/Humans/Group01/male_06.mdl", "models/player/police.mdl", "models/player/breen.mdl", "models/player/group03/male_01.mdl", "models/player/gman_high.mdl", "models/player/kleiner.mdl", "models/player/mossman.mdl", "models/player/police.mdl", "models/Eli.mdl"} for k, v in pairs(ButtonsText) do ClassButtons[k] = vgui.Create("SpawnIcon", CScroller) --Create the button ClassButtons[k]:SetIconSize(64) ClassButtons[k]:SetModel(v) CScroller:AddPanel(ClassButtons[k]) --Add each button to our Scroller after we create it. end [/code] [editline]12:30AM[/editline] (You tried to add a table as a panel, and that was a problem. You previously told lua that ClassButtons was a table)
I am still getting the exact same error [QUOTE] addons\derma\lua\vgui\dhorizontalscroller.lua:99: attempt to call method 'ApplySchemeSettings' (a nil value) [/QUOTE]
That's very odd. I'll talk to you in a minute, I have to check somthing
No worries. Appreciate the help you're giving.
I don't think SpawnIcon will work for that. I doubt SpawnIcon has ApplySchemeSettings as a function. [editline]12:40AM[/editline] Sadly, I think you will have to compensate. [editline]12:41AM[/editline] Confirmed, you have to compensate.
That's a real shame. I was experimenting with DPanelList and Horizontal scroll bar, buggered if I could get the H-bar to show. I'll work on it, see how it goes. Once again, thank you for the help.
Ok, filthy hack, try this [code] [code] local ClassPanel = vgui.Create( "DPanelList", MFrame) ClassPanel:EnableHorizontal(true) --ClassPanel:EnableVerticalScrollbar(false) ClassPanel:SetPadding(1) ClassPanel:SetSize(425, 90) ClassPanel:SetPos(50, 35) local CScroller = vgui.Create("DHorizontalScroller", MFrame) CScroller:SetSize(ClassPanel:GetWide() - 8, 40) CScroller:AlignBottom(1) CScroller:AlignLeft(1) CScroller:SetOverlap(-5) local ClassButtons = {} local ButtonsText = {"models/Humans/Group01/male_06.mdl", "models/player/police.mdl", "models/player/breen.mdl", "models/player/group03/male_01.mdl", "models/player/gman_high.mdl", "models/player/kleiner.mdl", "models/player/mossman.mdl", "models/player/police.mdl", "models/Eli.mdl"} for k, v in pairs(ButtonsText) do ClassButtons[k] = vgui.Create("SpawnIcon", CScroller) --Create the button function ClassButtons[k]:ApplySchemeSettings() end ClassButtons[k]:SetIconSize(64) ClassButtons[k]:SetModel(v) CScroller:AddPanel(ClassButtons[k]) --Add each button to our Scroller after we create it. end [/code]
[QUOTE] lua\autorun\client\model_select.lua:103: '(' expected near '[' [/QUOTE]
What is line 103?
[lua]function ClassButtons[k]:ApplySchemeSettings() end[/lua]
I find the way you guys attempt to help people here quite revolting, because you don't even take time to understand what they want to do and which mistakes they did. I'm going to start over with the initial code: [lua] local CScroller = vgui.Create("DHorizontalScroller", MFrame) CScroller:SetSize(ClassPanel:GetWide() - 8, 40) CScroller:AlignBottom(1) CScroller:AlignLeft(1) CScroller:SetOverlap(-5) local ClassButtons = {} local ButtonsText = {"Citizen", "CP", "Mayor", "Gangster", "DrugLord", "Doctor", "Chef", "Chief", "Reporter"} for i=1, 10 do for k, v in pairs(ButtonsText) do ClassButtons[i] = vgui.Create("DButton", CScroller) --Create the button ClassButtons[i]:SetSize(140, 40) ClassButtons[i]:SetText(v) CScroller:AddPanel(ClassButtons[i]) --Add each button to our Scroller after we create it. end end [/lua] If I understand correctly, you want to create 10 buttons, each one having a different text. However, you are doing it completely wrong here, because you are using two for loops inside each other. To understand why it doesn't make sense at all, try to imagine how that code would run, and see what happens. You are entering the first for loop, i = 1. Then, you enter the second for loop, which goes through the whole list you called ButtonText. It will then proceed to create 10 buttons, each one with a different text. Then, it leaves the second loop, and goes back to the first loop, and then you have i = 2. And so on, until i = 10. So basically you are creating each button 10 times, which is completely unnecessary. The first solution would be this: [lua] for i=1, 10 do ClassButtons[i] = vgui.Create("DButton", CScroller) --Create the button ClassButtons[i]:SetSize(140, 40) ClassButtons[i]:SetText(ButtonsText[i]) CScroller:AddPanel(ClassButtons[i]) --Add each button to our Scroller after we create it. end [/lua] See what I did there? When i=1, ButtonsText[i] will be equal to "Citizen", when i=2, ButtonsText[i] will be equal to "CP", and so on. Another solution would be this: [lua] for k,v in ipairs(ButtonsText) do ClassButtons[k] = vgui.Create("DButton", CScroller) --Create the button ClassButtons[k]:SetSize(140, 40) ClassButtons[k]:SetText(v) CScroller:AddPanel(ClassButtons[k]) --Add each button to our Scroller after we create it. end [/lua] You'd better use ipairs in this situation, because unlike pairs, it iterates through the elements of your list in the right order. pairs iterates through them in a completely arbitrary order, so you can't know in which order every element will appear. Note that I used k instead of i. I'm not sure if you know how pairs and ipairs work, but basically, when used in a for loop like that, before each iteration, k is set to a different key, and v is set to the corresponding value. Since ipairs is ordered, you would have k=1, v="Citizen" at the first iteration, k=2, v="CP" at the second iteration, and so on. That's quite convenient if you use it properly. Oh, and for the ApplySchemeSettings thing, I'm pretty much sure there is another way to avoid that error, but in the meantime, just force your spawnicon to have a function called ApplySchemeSettings which does nothing: [lua] for k,v in ipairs(ButtonsText) do ClassButtons[k] = vgui.Create("DButton", CScroller) --Create the button ClassButtons[k]:SetSize(140, 40) ClassButtons[k]:SetText(v) ClassButtons[k].ApplySchemeSettings = function() end CScroller:AddPanel(ClassButtons[k]) --Add each button to our Scroller after we create it. end [/lua] [editline]12:38PM[/editline] [QUOTE=Map in a box;22273809]Ok, filthy hack, try this [code] function ClassButtons[k]:ApplySchemeSettings() end [/code][/QUOTE] Lua doesn't like that if I remember correctly. You can't index a table and declare a function like that at the same time.
Really appreciate you explaining it all KillBurn, Your code worked like a charm, and I understood how it worked. I changed the DButton to SpawnIcon again, It works but with 1 small error, upon opening the frame it loads every second SpawnIcon, When I press the horizontal scroll bar, it loads all the spawn icons. Is there a way I can get it to load all of them successfully upon the frame opening.
[QUOTE=_Kilburn;22276807]Lua doesn't like that if I remember correctly. You can't index a table and declare a function like that at the same time.[/QUOTE] Lua will produce an error if you define a function like that, however these will work: [lua]Table[Index].Method = function(s) end -- for non string index[/lua] [lua]function Table.Index:Method() end -- for string index[/lua]
Fixed my dilemma. Removed the SetSize as it wasn't needed and was causing the script to be faulty.
What? I tried :\ [editline]03:38PM[/editline] You don't have to say it was revolting ._.
Sorry, you need to Log In to post a reply to this thread.