2 --Copyright (C) 2013 sapier
4 --This program is free software; you can redistribute it and/or modify
5 --it under the terms of the GNU Lesser General Public License as published by
6 --the Free Software Foundation; either version 2.1 of the License, or
7 --(at your option) any later version.
9 --This program is distributed in the hope that it will be useful,
10 --but WITHOUT ANY WARRANTY; without even the implied warranty of
11 --MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 --GNU Lesser General Public License for more details.
14 --You should have received a copy of the GNU Lesser General Public License along
15 --with this program; if not, write to the Free Software Foundation, Inc.,
16 --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 --------------------------------------------------------------------------------
19 -- Generic implementation of a filter/sortable list --
20 --------------------------------------------------------------------------------
23 --------------------------------------------------------------------------------
24 function filterlist.refresh(this)
25 this.m_raw_list = this.m_raw_list_fct(this.m_fetch_param)
26 filterlist.process(this)
29 --------------------------------------------------------------------------------
30 function filterlist.create(raw_fct,compare_fct,uid_match_fct,filter_fct,fetch_param)
32 assert((raw_fct ~= nil) and (type(raw_fct) == "function"))
33 assert((compare_fct ~= nil) and (type(compare_fct) == "function"))
37 this.m_raw_list_fct = raw_fct
38 this.m_compare_fct = compare_fct
39 this.m_filter_fct = filter_fct
40 this.m_uid_match_fct = uid_match_fct
42 this.m_filtercriteria = nil
43 this.m_fetch_param = fetch_param
45 this.m_sortmode = "none"
48 this.m_processed_list = nil
49 this.m_raw_list = this.m_raw_list_fct(this.m_fetch_param)
51 filterlist.process(this)
56 --------------------------------------------------------------------------------
57 function filterlist.add_sort_mechanism(this,name,fct)
58 this.m_sort_list[name] = fct
61 --------------------------------------------------------------------------------
62 function filterlist.set_filtercriteria(this,criteria)
63 if criteria == this.m_filtercriteria and
64 type(criteria) ~= "table" then
67 this.m_filtercriteria = criteria
68 filterlist.process(this)
71 --------------------------------------------------------------------------------
72 function filterlist.get_filtercriteria(this)
73 return this.m_filtercriteria
76 --------------------------------------------------------------------------------
77 --supported sort mode "alphabetic|none"
78 function filterlist.set_sortmode(this,mode)
79 if (mode == this.m_sortmode) then
82 this.m_sortmode = mode
83 filterlist.process(this)
86 --------------------------------------------------------------------------------
87 function filterlist.get_list(this)
88 return this.m_processed_list
91 --------------------------------------------------------------------------------
92 function filterlist.get_raw_list(this)
93 return this.m_raw_list
96 --------------------------------------------------------------------------------
97 function filterlist.get_raw_element(this,idx)
98 if type(idx) ~= "number" then
102 if idx ~= nil and idx > 0 and idx < #this.m_raw_list then
103 return this.m_raw_list[idx]
109 --------------------------------------------------------------------------------
110 function filterlist.get_raw_index(this,listindex)
111 assert(this.m_processed_list ~= nil)
113 if listindex ~= nil and listindex > 0 and
114 listindex <= #this.m_processed_list then
115 local entry = this.m_processed_list[listindex]
117 for i,v in ipairs(this.m_raw_list) do
119 if this.m_compare_fct(v,entry) then
128 --------------------------------------------------------------------------------
129 function filterlist.get_current_index(this,listindex)
130 assert(this.m_processed_list ~= nil)
132 if listindex ~= nil and listindex > 0 and
133 listindex <= #this.m_raw_list then
134 local entry = this.m_raw_list[listindex]
136 for i,v in ipairs(this.m_processed_list) do
138 if this.m_compare_fct(v,entry) then
147 --------------------------------------------------------------------------------
148 function filterlist.process(this)
149 assert(this.m_raw_list ~= nil)
151 if this.m_sortmode == "none" and
152 this.m_filtercriteria == nil then
153 this.m_processed_list = this.m_raw_list
157 this.m_processed_list = {}
159 for k,v in pairs(this.m_raw_list) do
160 if this.m_filtercriteria == nil or
161 this.m_filter_fct(v,this.m_filtercriteria) then
162 table.insert(this.m_processed_list,v)
166 if this.m_sortmode == "none" then
170 if this.m_sort_list[this.m_sortmode] ~= nil and
171 type(this.m_sort_list[this.m_sortmode]) == "function" then
173 this.m_sort_list[this.m_sortmode](this)
177 --------------------------------------------------------------------------------
178 function filterlist.size(this)
179 if this.m_processed_list == nil then
183 return #this.m_processed_list
186 --------------------------------------------------------------------------------
187 function filterlist.uid_exists_raw(this,uid)
188 for i,v in ipairs(this.m_raw_list) do
189 if this.m_uid_match_fct(v,uid) then
196 --------------------------------------------------------------------------------
197 function filterlist.raw_index_by_uid(this, uid)
198 local elementcount = 0
200 for i,v in ipairs(this.m_raw_list) do
201 if this.m_uid_match_fct(v,uid) then
202 elementcount = elementcount +1
208 -- If there are more elements than one with same name uid can't decide which
209 -- one is meant. This shouldn't be possible but just for sure.
210 if elementcount > 1 then
217 --------------------------------------------------------------------------------
218 -- COMMON helper functions --
219 --------------------------------------------------------------------------------
221 --------------------------------------------------------------------------------
222 function compare_worlds(world1,world2)
224 if world1.path ~= world2.path then
228 if world1.name ~= world2.name then
232 if world1.gameid ~= world2.gameid then
239 --------------------------------------------------------------------------------
240 function sort_worlds_alphabetic(this)
242 table.sort(this.m_processed_list, function(a, b)
243 --fixes issue #857 (crash due to sorting nil in worldlist)
244 if a == nil or b == nil then
245 if a == nil and b ~= nil then return false end
246 if b == nil and a ~= nil then return true end
249 if a.name:lower() == b.name:lower() then
250 return a.name < b.name
252 return a.name:lower() < b.name:lower()
256 --------------------------------------------------------------------------------
257 function sort_mod_list(this)
259 table.sort(this.m_processed_list, function(a, b)
260 -- Show game mods at bottom
261 if a.typ ~= b.typ then
262 return b.typ == "game_mod"
264 -- If in same or no modpack, sort by name
265 if a.modpack == b.modpack then
266 if a.name:lower() == b.name:lower() then
267 return a.name < b.name
269 return a.name:lower() < b.name:lower()
270 -- Else compare name to modpack name
272 -- Always show modpack pseudo-mod on top of modpack mod list
273 if a.name == b.modpack then
275 elseif b.name == a.modpack then
279 local name_a = a.modpack or a.name
280 local name_b = b.modpack or b.name
281 if name_a:lower() == name_b:lower() then
282 return name_a < name_b
284 return name_a:lower() < name_b:lower()