WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   How do you loop k,v pairs to create fontstrings? (https://www.wowinterface.com/forums/showthread.php?t=58734)

Jokertito 05-13-21 10:21 PM

How do you loop k,v pairs to create fontstrings?
 
Similar to this
Lua Code:
  1. local table = {"entry", "entry2", "entry3"}
  2.  
  3. for i = 1,20 do
  4.     local fsname = frame:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  5.     fsname:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -10*(i-1))
  6.     fsname:SetText(table[i])
  7. end

But how do you do it for a table constructed like this

Lua Code:
  1. local table = {
  2.     ["entry"] = "One",
  3.     ["entry2"] = "Two",
  4.     ["entry3"] = "Three",
  5. }

So that when looped the fontstring comes out like this?

entry One
entry2 Two
entry3 Three

Thanks in advance :)

Edit: This is the method I found that works, if anyone knows a better way I'm all ears :D

Lua Code:
  1. local i = 1
  2. for k,v in pairs(table) do
  3.     local fsname = frame:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  4.     fsname:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -10*(i-1))
  5.     fsname:SetText(k)
  6.  
  7.     local fsname2 = frame:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  8.     fsname:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -10*(i-1))
  9.     fsname:SetText(v)
  10. end

I have this in a function a button calls so 'i' always starts as 1

Fizzlemizz 05-14-21 12:43 AM

I think you'd be better explaining more of what you are wanting to do with the fontstrings after they are created. From what you've posted it seems like you are thinking you have to create a new frontstring every time you want to display something different whereas you only need to create a fonstring once and there after, just change the text it displays.

eg.

Lua Code:
  1. local f = CreateFrame("Frame", nil, UIParent)
  2. f:SetSize(5, 5)
  3. f:SetPoint("LEFT", 10, 0)
  4. f.FontStrings = {}
  5. for i=1, 20 do
  6.     -- add a fontstring to the f.FontStrings table so we can re-use them as required
  7.     tinsert(f.FontStrings, f:CreateFontString(nil, "OVERLAY", "GameTooltipText"))
  8.     -- set them up in a column for demonstration purposes
  9.     if i == 1 then
  10.         f.FontStrings[i]:SetPoint("LEFT")
  11.     else
  12.         f.FontStrings[i]:SetPoint("TOPLEFT", f.FontStrings[i-1], "BOTTOMLEFT", 0, -1)
  13.     end
  14. end
  15.  
  16. -- set the initial texts (which could also be done after creating the fontstring but this is for demonstration.
  17. for i=1, #f.FontStrings do
  18.     f.FontStrings[i]:SetText("Entry"..i)
  19. end
  20. -- Some time later you might need to change your displayed texts too:
  21.  
  22. for i=1, #f.FontStrings do
  23.     f.FontStrings[i]:SetText("Exit"..i)
  24. end

Jokertito 05-14-21 08:59 AM

Quote:

Originally Posted by Fizzlemizz (Post 339123)
I think you'd be better explaining more of what you are wanting to do with the fontstrings after they are created.

I just want to display a table of information with its k,v pairs together. After the information is displayed that's the end lol. I don't need any animations, tooltips, textures or anything just a list where I want it.

Fizzlemizz 05-14-21 10:11 AM

You can't pre-determine the order of a table using strings as keys. You could do something like:

Lua Code:
  1. local table = {
  2.         { display="entry", value="One" },
  3.         { display="entry2", value= "Two" },
  4.         { display="entry3", value= "Three" },
  5. }
  6.  
  7. for k, v in ipairs(table) do
  8.     fsname:SetText(v.display) -- set the text to "entry", entry2" ...
  9. -- or
  10.     fsname:SetText(v.value) -- set the text to "One", two" ...
  11. end

Jokertito 05-14-21 11:17 AM

This is all I wanted

Lua Code:
  1. local table = {
  2.     ["entry"] = "one",
  3.     ["entry2"] = "two",
  4.     ["entry3"] = "three",
  5. }
  6.  
  7. local f = CreateFrame("Frame", nil, UIParent, "BasicFrameTemplateWithInset")
  8. f:SetSize(250, 400)
  9. f:SetPoint("CENTER")
  10.  
  11. f.grabdata = CreateFrame("Button", nil, f, "SharedButtonTemplate")
  12. f.grabdata:SetText("G")
  13. f.grabdata:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
  14. f.grabdata:SetSize(40, 20)
  15. f.grabdata:SetScript("OnClick",
  16.     function()
  17.         local i = 0
  18.         for k,v in pairs(table) do
  19.             local fsname = f:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  20.             fsname:SetPoint("TOPLEFT", f, "TOPLEFT", 9, -17*(i-(-2)))
  21.             fsname:SetText(k)
  22.            
  23.             local fsname2 = f:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  24.             fsname2:SetPoint("TOPRIGHT", f, "TOPRIGHT", -10, -17*(i-(-2)))
  25.             fsname2:SetText(v)             
  26.             i = i + 1
  27.         end
  28.     end
  29. )



Click the "G" button and the data is presented.

Fizzlemizz 05-14-21 12:04 PM

This has both problems I described.
Every time you press the G button you are creating a new set of fonstrings on top of the previous set of fontstring.

Because you've been lucky with the display order doesn't mean you will continue to be lucky if you change or extend the table entries:

The offsetting is to display what's happening if you press the G button multiple times
Lua Code:
  1. local table = {
  2.     ["entry"] = "one",
  3.     ["entry2"] = "two",
  4.     ["entry3"] = "three",
  5.     ["entry4"] = "Four",
  6.     ["entry5"] = "Five",
  7.     ["entry6"] = "Six",
  8.     ["entry7"] = "Seven",
  9.     ["entry8"] = "Eight",
  10.     ["entry9"] = "Nine",
  11.     ["entry10"] = "Ten",
  12. }
  13.  
  14. local f = CreateFrame("Frame", nil, UIParent, "BasicFrameTemplateWithInset")
  15. f:SetSize(250, 400)
  16. f:SetPoint("CENTER")
  17.  
  18. f.Title = f:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  19. f.Title:SetPoint("TOP", 0, -2)
  20. f.Title:SetText("Original")
  21.  
  22. f.grabdata = CreateFrame("Button", nil, f, "SharedButtonTemplate")
  23. f.grabdata:SetText("G")
  24. f.grabdata:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
  25. f.grabdata:SetSize(40, 20)
  26. local offset = 0
  27. f.grabdata:SetScript("OnClick",
  28.     function()
  29.         local i = 0
  30.         offset = offset + 1
  31.         for k,v in pairs(table) do
  32.             local fsname = f:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  33.             fsname:SetPoint("TOPLEFT", f, "TOPLEFT", offset, -17*(i-(-2)))
  34.             fsname:SetText(k)
  35.            
  36.             local fsname2 = f:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  37.             fsname2:SetPoint("TOPRIGHT", f, "TOPRIGHT", -offset, -17*(i-(-2)))
  38.             fsname2:SetText(v)              
  39.             i = i + 1
  40.         end
  41.     end
  42. )
  43.  
  44. -- Constant ordered display
  45. local table2 = {
  46.     { display="entry", value="one" },
  47.     { display="entry2", value="two" },
  48.     { display="entry3", value="three" },
  49.     { display="entry4", value="Four" },
  50.     { display="entry5", value="Five" },
  51.     { display="entry6", value="Six" },
  52.     { display="entry7", value="Seven" },
  53.     { display="entry8", value="Eight" },
  54.     { display="entry9", value="Nine" },
  55.     { display="entry10", value="Ten" },
  56. }
  57.  
  58. local f2 = CreateFrame("Frame", nil, UIParent, "BasicFrameTemplateWithInset")
  59. f2:SetSize(250, 400)
  60. f2:SetPoint("LEFT", f, "RIGHT")
  61.  
  62. f2.Title = f2:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  63. f2.Title:SetPoint("TOP", 0, -2)
  64. f2.Title:SetText("Constant Ordered")
  65.  
  66. f2.grabdata = CreateFrame("Button", nil, f2, "SharedButtonTemplate")
  67. f2.grabdata:SetText("G")
  68. f2.grabdata:SetPoint("TOPLEFT", f2, "TOPLEFT", 0, 0)
  69. f2.grabdata:SetSize(40, 20)
  70. local offset = 0
  71. f2.Fonstrings = {}
  72. f2.grabdata:SetScript("OnClick", function(self)
  73.     local parent = self:GetParent()
  74.     local left, right
  75.     offset = offset + 1
  76.     for k,v in ipairs(table2) do
  77.         if not parent.Fonstrings[i] then
  78.             left = self:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  79.             right = self:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  80.             if k == 1 then
  81.                 left:SetPoint("TOPLEFT", self:GetParent(), 9, -22)
  82.                 right:SetPoint("TOPRIGHT", self:GetParent(), -9, -22)
  83.             else
  84.                 left:SetPoint("TOPLEFT", parent.Fonstrings[k-1].left, "BOTTOMLEFT", offset, -2)
  85.                 right:SetPoint("TOPRIGHT", parent.Fonstrings[k-1].right, "BOTTOMRIGHT", -offset, -2)
  86.             end
  87.             tinsert(parent.Fonstrings, {left=left, right=right})
  88.         end
  89.         parent.Fonstrings[k].left:SetText(v.display)
  90.         parent.Fonstrings[k].right:SetText(v.value)
  91.     end
  92. end)

Jokertito 05-14-21 01:37 PM

Thanks, I noticed the constant creation of entries as well when clicking and shall look over your code to make sense of it lol :D

Fizzlemizz 05-14-21 01:45 PM

It's just saving a list of already created fontstrings into the f2.Fonstrings table as {left, right} pairs and re-using them if they exist or creating additional if required. It's just a demonstration so it's not handling things like hiding fonststrings if subsequent clicks contain a shorter list etc.

This would really be better as a scroll list if you're likely to have more entries than you can display vertically in the frame. This contains a link in the OP to one way this might work.


All times are GMT -6. The time now is 10:27 AM.

vBulletin © 2021, Jelsoft Enterprises Ltd
© 2004 - 2021 MMOUI