OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

sortlist_type.h
Go to the documentation of this file.
1 /* $Id: sortlist_type.h 24900 2013-01-08 22:46:42Z planetmaker $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
9
12 #ifndef SORTLIST_TYPE_H
13 #define SORTLIST_TYPE_H
14
15 #include "core/enum_type.hpp"
16 #include "core/bitmath_func.hpp"
17 #include "core/sort_func.hpp"
18 #include "core/smallvec_type.hpp"
19 #include "date_type.h"
20
22 enum SortListFlags {
23 VL_NONE = 0,
24 VL_DESC = 1 << 0,
25 VL_RESORT = 1 << 1,
26 VL_REBUILD = 1 << 2,
27 VL_FIRST_SORT = 1 << 3,
28 VL_FILTER = 1 << 4,
29 VL_END = 1 << 5,
30 };
31 DECLARE_ENUM_AS_BIT_SET(SortListFlags)
32
33
34 struct Listing {
35 bool order;
36 byte criteria;
37 };
39 struct Filtering {
40 bool state;
41 byte criteria;
42 };
43
49 template <typename T, typename F = const char*>
50 class GUIList : public SmallVector<T, 32> {
51 public:
52 typedef int CDECL SortFunction(const T*, const T*);
53 typedef bool CDECL FilterFunction(const T*, F);
54
55 protected:
56 SortFunction * const *sort_func_list;
57 FilterFunction * const *filter_func_list;
58 SortListFlags flags;
59 uint8 sort_type;
60 uint8 filter_type;
61 uint16 resort_timer;
62
68 bool IsSortable() const
69 {
70 return (this->data != NULL && this->items >= 2);
71 }
72
76 void ResetResortTimer()
77 {
78 /* Resort every 10 days */
79 this->resort_timer = DAY_TICKS * 10;
80 }
81
82 public:
83 GUIList() :
84 sort_func_list(NULL),
85 filter_func_list(NULL),
86 flags(VL_FIRST_SORT),
87 sort_type(0),
88 filter_type(0),
89 resort_timer(1)
90 {};
91
97 uint8 SortType() const
98 {
99 return this->sort_type;
100 }
101
107 void SetSortType(uint8 n_type)
108 {
109 if (this->sort_type != n_type) {
110 SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
111 this->sort_type = n_type;
112 }
113 }
114
120 Listing GetListing() const
121 {
122 Listing l;
123 l.order = (this->flags & VL_DESC) != 0;
124 l.criteria = this->sort_type;
125
126 return l;
127 }
128
134 void SetListing(Listing l)
135 {
136 if (l.order) {
137 SETBITS(this->flags, VL_DESC);
138 } else {
139 CLRBITS(this->flags, VL_DESC);
140 }
141 this->sort_type = l.criteria;
142
143 SETBITS(this->flags, VL_FIRST_SORT);
144 }
145
151 uint8 FilterType() const
152 {
153 return this->filter_type;
154 }
155
161 void SetFilterType(uint8 n_type)
162 {
163 if (this->filter_type != n_type) {
164 this->filter_type = n_type;
165 }
166 }
167
173 Filtering GetFiltering() const
174 {
175 Filtering f;
176 f.state = (this->flags & VL_FILTER) != 0;
177 f.criteria = this->filter_type;
178
179 return f;
180 }
181
187 void SetFiltering(Filtering f)
188 {
189 if (f.state) {
190 SETBITS(this->flags, VL_FILTER);
191 } else {
192 CLRBITS(this->flags, VL_FILTER);
193 }
194 this->filter_type = f.criteria;
195 }
196
205 bool NeedResort()
206 {
207 if (--this->resort_timer == 0) {
208 SETBITS(this->flags, VL_RESORT);
209 this->ResetResortTimer();
210 return true;
211 }
212 return false;
213 }
214
219 void ForceResort()
220 {
221 SETBITS(this->flags, VL_RESORT);
222 }
223
229 bool IsDescSortOrder() const
230 {
231 return (this->flags & VL_DESC) != 0;
232 }
233
239 void ToggleSortOrder()
240 {
241 this->flags ^= VL_DESC;
242
243 if (this->IsSortable()) MemReverseT(this->data, this->items);
244 }
245
256 bool Sort(SortFunction *compare)
257 {
258 /* Do not sort if the resort bit is not set */
259 if (!(this->flags & VL_RESORT)) return false;
260
261 CLRBITS(this->flags, VL_RESORT);
262
263 this->ResetResortTimer();
264
265 /* Do not sort when the list is not sortable */
266 if (!this->IsSortable()) return false;
267
268 const bool desc = (this->flags & VL_DESC) != 0;
269
270 if (this->flags & VL_FIRST_SORT) {
271 CLRBITS(this->flags, VL_FIRST_SORT);
272
273 QSortT(this->data, this->items, compare, desc);
274 return true;
275 }
276
277 GSortT(this->data, this->items, compare, desc);
278 return true;
279 }
280
286 void SetSortFuncs(SortFunction * const *n_funcs)
287 {
288 this->sort_func_list = n_funcs;
289 }
290
297 bool Sort()
298 {
299 assert(this->sort_func_list != NULL);
300 return this->Sort(this->sort_func_list[this->sort_type]);
301 }
302
308 bool IsFilterEnabled() const
309 {
310 return (this->flags & VL_FILTER) != 0;
311 }
312
318 void SetFilterState(bool state)
319 {
320 if (state) {
321 SETBITS(this->flags, VL_FILTER);
322 } else {
323 CLRBITS(this->flags, VL_FILTER);
324 }
325 }
326
334 bool Filter(FilterFunction *decide, F filter_data)
335 {
336 /* Do not filter if the filter bit is not set */
337 if (!(this->flags & VL_FILTER)) return false;
338
339 bool changed = false;
340 for (uint iter = 0; iter < this->items;) {
341 T *item = &this->data[iter];
342 if (!decide(item, filter_data)) {
343 this->Erase(item);
344 changed = true;
345 } else {
346 iter++;
347 }
348 }
349
350 return changed;
351 }
352
358 void SetFilterFuncs(FilterFunction * const *n_funcs)
359 {
360 this->filter_func_list = n_funcs;
361 }
362
369 bool Filter(F filter_data)
370 {
371 if (this->filter_func_list == NULL) return false;
372 return this->Filter(this->filter_func_list[this->filter_type], filter_data);
373 }
374
379 bool NeedRebuild() const
380 {
381 return (this->flags & VL_REBUILD) != 0;
382 }
383
387 void ForceRebuild()
388 {
389 SETBITS(this->flags, VL_REBUILD);
390 }
391
397 void RebuildDone()
398 {
399 CLRBITS(this->flags, VL_REBUILD);
400 SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
401 }
402 };
403
404 #endif /* SORTLIST_TYPE_H */