@@ -35,6 +35,7 @@ local CreateFrame = _G.CreateFrame
3535local ExpandCurrencyList = _G .C_CurrencyInfo .ExpandCurrencyList
3636local format = _G .format
3737local GetCurrencyListInfo = _G .C_CurrencyInfo .GetCurrencyListInfo
38+ local GetCurrencyInfo = _G .C_CurrencyInfo .GetCurrencyInfo
3839local GetCurrencyListSize = _G .C_CurrencyInfo .GetCurrencyListSize
3940local hooksecurefunc = _G .hooksecurefunc
4041local ipairs = _G .ipairs
@@ -52,13 +53,16 @@ mod.uiName = L['Currency']
5253mod .uiDesc = L [' Display character currency at bottom left of the backpack.' ]
5354
5455function mod :OnInitialize ()
56+ self .currencyToCell = {}
57+ self .columns = {}
5558 self .db = addon .db :RegisterNamespace (
5659 self .moduleName ,
5760 {
5861 profile = {
5962 shown = { [' *' ] = true },
6063 hideZeroes = true ,
61- text = addon :GetFontDefaults (NumberFontNormalLarge )
64+ text = addon :GetFontDefaults (NumberFontNormalLarge ),
65+ width = 4 ,
6266 }
6367 }
6468 )
@@ -75,6 +79,7 @@ function mod:OnEnable()
7579 if self .widget then
7680 self .widget :Show ()
7781 end
82+
7883 self :RegisterEvent (' CURRENCY_DISPLAY_UPDATE' , " Update" )
7984 if not self .hooked then
8085 if IsAddOnLoaded (' Blizzard_TokenUI' ) then
@@ -104,18 +109,47 @@ function mod:OnBagFrameCreated(bag)
104109 if bag .bagName ~= " Backpack" then return end
105110 local frame = bag :GetFrame ()
106111
107- local widget = CreateFrame (" Button" , addonName .. " CurrencyFrame" , frame )
112+ local widget = CreateFrame (" Button" , addonName .. " CurrencyFrame" , frame )
108113 self .widget = widget
109114 widget :SetHeight (16 )
110- widget :RegisterForClicks (" RightButtonUp" )
111- widget :SetScript (' OnClick' , function () self :OpenOptions () end )
112- addon .SetupTooltip (widget , { L [' Currency' ], L [' Right-click to configure.' ] }, " ANCHOR_BOTTOMLEFT" )
113115
114- local fs = widget :CreateFontString (nil , " OVERLAY" )
115- fs :SetFontObject (self .font )
116- fs :SetPoint (" BOTTOMLEFT" , 0 , 1 )
117- self .fontstring = fs
116+ -- Create the columns used for currency display. Each column has the maximum amount
117+ -- of possible cells for the minimum width / the max number of currencies.
118+ for i = 1 , 10 do
119+ local columnFrame = CreateFrame (" Button" , string.format (" %sCurrencyColumnFrame%d" , addonName , i ), widget )
120+ columnFrame :Show ()
121+ if i == 1 then
122+ columnFrame :SetPoint (" TOPLEFT" , widget , " TOPLEFT" )
123+ else
124+ columnFrame :SetPoint (" TOPLEFT" , self .columns [i - 1 ].frame , " TOPRIGHT" )
125+ end
126+ local column = {
127+ frame = columnFrame ,
128+ cells = {}
129+ }
118130
131+ for ii = 1 , ceil (GetCurrencyListSize () / 3 )+ 1 do
132+ local cellFrame = CreateFrame (" Button" , string.format (" %sCurrencyCellFrame%d%d" , addonName , i , ii ), columnFrame )
133+ if ii == 1 then
134+ cellFrame :SetPoint (" TOPLEFT" , columnFrame , " TOPLEFT" )
135+ else
136+ cellFrame :SetPoint (" TOPLEFT" , column .cells [ii - 1 ].frame , " BOTTOMLEFT" )
137+ end
138+
139+ cellFrame :Show ()
140+ local fs = cellFrame :CreateFontString (nil , " OVERLAY" )
141+ fs :SetFontObject (self .font )
142+ fs :SetPoint (" BOTTOMLEFT" , 0 , 1 )
143+ table.insert (column .cells , {
144+ frame = cellFrame ,
145+ fs = fs ,
146+ text = " " ,
147+ icon = " " ,
148+ name = " " ,
149+ })
150+ end
151+ table.insert (self .columns , column )
152+ end
119153 self :Update ()
120154 frame :AddBottomWidget (widget , " LEFT" , 50 )
121155end
@@ -156,31 +190,99 @@ local ICON_STRING = " \124T%s:0:0:0:0:64:64:5:59:5:59\124t "
156190
157191local values = {}
158192local updating
159- function mod :Update ()
193+ function mod :Update (event , currencyType , currencyQuantity )
160194 if not self .widget or updating then return end
161195 updating = true
162196
197+ -- Refresh only the affected cell.
198+ if currencyType ~= nil then
199+ local info = GetCurrencyInfo (currencyType )
200+ local cell = self .currencyToCell [info .name ]
201+ cell .text = cell .icon .. currencyQuantity
202+ cell .fs :SetText (cell .text )
203+ cell .frame :SetSize (
204+ cell .fs :GetStringWidth (),
205+ ceil (cell .fs :GetStringHeight ())+ 3
206+ )
207+ local column = cell .frame :GetParent ()
208+ if column :GetWidth () < cell .frame :GetWidth () then
209+ column :SetWidth (cell .frame :GetWidth ())
210+ end
211+ updating = false
212+ return
213+ end
214+
215+ -- This is a full refresh of all cells, called on first load or layout changes.
216+
217+ -- Clear the currency -> cell map.
218+ wipe (self .currencyToCell )
219+
220+ -- Clear all cells and columns completely.
221+ for i , column in ipairs (self .columns ) do
222+ for ii , cell in ipairs (column .cells ) do
223+ cell .fs :SetText (" " )
224+ cell .text = " "
225+ cell .name = " "
226+ cell .icon = " "
227+ addon .RemoveTooltip (cell .frame )
228+ end
229+ column .frame :SetSize (0 ,0 )
230+ end
231+
232+ -- Get all the currency information from the player and store it.
163233 local shown , hideZeroes = self .db .profile .shown , self .db .profile .hideZeroes
164234 for i , currencyListInfo in IterateCurrencies () do
165235 if shown [currencyListInfo .name ] and (currencyListInfo .quantity > 0 or not hideZeroes ) then
166- tinsert (values , BreakUpLargeNumbers (currencyListInfo .quantity ))
167- tinsert (values , format (ICON_STRING , currencyListInfo .iconFileID ))
236+ tinsert (values , {
237+ quantity = BreakUpLargeNumbers (currencyListInfo .quantity ),
238+ icon = format (ICON_STRING , currencyListInfo .iconFileID ),
239+ name = currencyListInfo .name
240+ })
168241 end
169242 end
170243
171244 local widget , fs = self .widget , self .fontstring
245+ -- Set the cell values.
172246 if # values > 0 then
173- fs :SetText (tconcat (values , " " ))
174- widget :Show ()
175- widget :SetSize (
176- fs :GetStringWidth (),
177- ceil (fs :GetStringHeight ()) + 3
178- )
247+ for i , value in ipairs (values ) do
248+ local columnPosition = ((i - 1 ) % self .db .profile .width )+ 1
249+ local rowPosition = ceil (i / self .db .profile .width )
250+ local column = self .columns [columnPosition ]
251+ local cell = column .cells [rowPosition ]
252+ cell .icon = value .icon
253+ cell .name = value .name
254+ cell .text = value .icon .. value .quantity
255+ cell .fs :SetText (cell .text )
256+ cell .frame :SetSize (
257+ cell .fs :GetStringWidth (),
258+ ceil (cell .fs :GetStringHeight ())+ 3
259+ )
260+ -- Set the cell's tooltip.
261+ addon .SetupTooltip (cell .frame , cell .name , " ANCHOR_BOTTOMLEFT" )
262+
263+ -- Resize the columns as needed.
264+ if column .frame :GetWidth () < cell .frame :GetWidth () then
265+ column .frame :SetWidth (cell .frame :GetWidth ())
266+ end
267+ column .frame :SetHeight (column .frame :GetHeight () + cell .frame :GetHeight ())
268+ self .currencyToCell [value .name ] = cell
269+ end
270+
271+ -- Loop over every active column and get the total width
272+ -- of all columns for the parent widget.
273+ local totalWidth = 0
274+ for i = 1 , self .db .profile .width do
275+ totalWidth = totalWidth + self .columns [i ].frame :GetWidth ()
276+ end
277+
278+ -- The first column will always be the longest column, so get the height
279+ -- of the first column and set the parent widget to this size.
280+ widget :SetSize (totalWidth , self .columns [1 ].frame :GetHeight ())
179281 wipe (values )
180282 else
181283 widget :Hide ()
182284 end
183-
285+ widget : Show ()
184286 updating = false
185287end
186288
@@ -206,6 +308,21 @@ function mod:GetOptions()
206308 type = ' toggle' ,
207309 order = 20 ,
208310 },
209- text = addon :CreateFontOptions (self .font , nil , 30 )
311+ text = addon :CreateFontOptions (self .font , nil , 30 ),
312+ layout = {
313+ name = L [' Layout' ],
314+ type = ' group' ,
315+ order = 100 ,
316+ inline = true ,
317+ args = {
318+ width = {
319+ name = L [' Currencies per row' ],
320+ type = ' range' ,
321+ min = 3 ,
322+ max = 10 ,
323+ step = 1
324+ }
325+ }
326+ },
210327 }, addon :GetOptionHandler (self , false , function () return self :Update () end )
211328end
0 commit comments