@@ -119,12 +119,11 @@ function ListWindow:Clear()
119119 self .listPanel :ClearChildren ()
120120 self .scrollChildren = 0
121121 self .itemNames = {}
122- self .itemForceToColumFunc = {}
123- self .itemPanelMapping = {}
124- self .orderPanelMapping = {}
122+ self .itemPanelMapping = {} -- {id = panel{Index = placeinlist, id = id, inFilter = bool}}, maps
123+ self .orderPanelMapping = {} -- {index = panel{Index = placeinlist, id = id, inFilter = bool}}
125124end
126125
127- function ListWindow :AddRow (items , id , forceToColumnFunc )
126+ function ListWindow :AddRow (items , id )
128127 if self .itemPanelMapping [id ] then
129128 -- Spring.Log("Chobby", LOG.ERROR, "Tried to add duplicate list window item", id)
130129 return
@@ -137,7 +136,6 @@ function ListWindow:AddRow(items, id, forceToColumnFunc)
137136 end
138137
139138 self .itemNames [id ] = itemNames
140- self .itemForceToColumFunc [id ] = forceToColumnFunc
141139
142140 local container = Control :New {
143141 name = " container" ,
@@ -158,7 +156,7 @@ function ListWindow:AddRow(items, id, forceToColumnFunc)
158156 }
159157
160158 local index = self .scrollChildren + 1
161- local x ,y ,width ,height = self :CalulatePosition (index )
159+ local x ,y ,width ,height = self :CalculatePosition (index )
162160 local w = Control :New {
163161 x = x ,
164162 width = width ,
@@ -177,6 +175,7 @@ function ListWindow:AddRow(items, id, forceToColumnFunc)
177175 self .orderPanelMapping [index ] = w
178176
179177 w .inFilter = self :ItemInFilter (id )
178+ w :SetVisibility (w .inFilter )
180179 self :RecalculateOrder (id )
181180end
182181
@@ -190,7 +189,7 @@ function ListWindow:GetRowItems(id)
190189 return self .itemNames [id ]
191190end
192191
193- function ListWindow :CalulatePosition (index )
192+ function ListWindow :CalculatePosition (index )
194193 local xAcross = ((index - 1 )% self .columns )/ self .columns
195194 local row = math.floor ((index - 1 )/ self .columns )
196195
@@ -202,7 +201,7 @@ function ListWindow:CalulatePosition(index)
202201end
203202
204203function ListWindow :RecalculatePosition (index )
205- local x , y , width , height = self :CalulatePosition (index )
204+ local x ,y , width ,height = self :CalculatePosition (index )
206205
207206 local child = self .orderPanelMapping [index ]
208207
@@ -221,12 +220,61 @@ function ListWindow:ItemInFilter(id)
221220 return true
222221end
223222
223+ function ListWindow :SetPosition (panel , index )
224+ local x ,y , width , height = self :CalculatePosition (index )
225+ panel ._relativeBounds .left = x
226+ panel ._relativeBounds .width = width
227+ panel :SetPos (nil ,y , nil , adjustFeatureHeight )
228+ panel :UpdateClientArea ()
229+ end
230+
224231function ListWindow :UpdateFilters ()
225- for i = 1 , self .scrollChildren do
226- self .orderPanelMapping [i ].inFilter = self :ItemInFilter (self .orderPanelMapping [i ].id )
232+ -- this updates all the elements
233+ -- should only be really called when filter parameters change,
234+ -- but is now fast enough to not really care about that
235+ -- dont even sort filtered out items
236+ -- filtered item positions are also set to the end of the list.
237+
238+ -- refresh filtered items
239+ local infilters = {} -- array of visible IDs
240+ local numinfilters = 0
241+ local invisible = {} -- array of invisible IDs
242+ local numinvisible = 0
243+ for index , panel in ipairs (self .orderPanelMapping ) do
244+ local oldFilter = panel .inFilter
245+ panel .inFilter = self :ItemInFilter (panel .id )
246+ if panel .inFilter then
247+ numinfilters = numinfilters + 1
248+ infilters [numinfilters ] = panel .id
249+ else
250+ numinvisible = numinvisible + 1
251+ invisible [numinvisible ] = panel .id
252+ end
253+
254+ if oldFilter ~= panel .inFilter then -- only update on status change
255+ panel :SetVisibility (panel .inFilter )
256+ end
227257 end
228- for id , _ in pairs (self .itemPanelMapping ) do
229- self :RecalculateOrder (id )
258+
259+ -- Create a localized lambda sort function and sort the visible ones
260+ local listWindow = self
261+ local lambda = function (id1 , id2 )
262+ return listWindow :CompareItems (id1 ,id2 )
263+ end
264+ table.sort (infilters , lambda )
265+
266+ -- add the invisible ones to the end of the sorted list
267+ for i = 1 , numinvisible do
268+ infilters [numinfilters + i ] = invisible [i ]
269+ end
270+ -- set the position of all of them one by one if it has changed
271+ for newindex , id in ipairs (infilters ) do
272+ local panel = self .itemPanelMapping [id ]
273+ if panel .index ~= newindex then
274+ self :SetPosition (panel , newindex )
275+ self .orderPanelMapping [newindex ] = panel
276+ panel .index = newindex
277+ end
230278 end
231279end
232280
@@ -305,6 +353,5 @@ function ListWindow:RemoveRow(id)
305353 self .listPanel :RemoveChild (panel )
306354 self .scrollChildren = self .scrollChildren - 1
307355 self .itemNames [id ] = nil
308- self .itemForceToColumFunc [id ] = nil
309356 self .itemPanelMapping [id ] = nil
310357end
0 commit comments