Translations update
[openttd/fttd.git] / src / sortlist_type.h
blob1cbdb9cd7e9d0d978cf3df29d6fc713d9fa2115d
1 /* $Id$ */
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 */
10 /** @file sortlist_type.h Base types for having sorted lists in GUIs. */
12 #ifndef SORTLIST_TYPE_H
13 #define SORTLIST_TYPE_H
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"
21 /** Flags of the sort list. */
22 enum SortListFlags {
23 VL_NONE = 0, ///< no sort
24 VL_DESC = 1 << 0, ///< sort descending or ascending
25 VL_RESORT = 1 << 1, ///< instruct the code to resort the list in the next loop
26 VL_REBUILD = 1 << 2, ///< rebuild the sort list
27 VL_FIRST_SORT = 1 << 3, ///< sort with quick sort first
28 VL_FILTER = 1 << 4, ///< filter disabled/enabled
29 VL_END = 1 << 5,
31 DECLARE_ENUM_AS_BIT_SET(SortListFlags)
33 /** Data structure describing how to show the list (what sort direction and criteria). */
34 struct Listing {
35 bool order; ///< Ascending/descending
36 byte criteria; ///< Sorting criteria
39 /**
40 * List template of 'things' \p T to sort in a GUI.
41 * @tparam T Type of data stored in the list to represent each item.
43 template <typename T>
44 class GUIList : public SmallVector<T, 32> {
45 public:
46 typedef int CDECL SortFunction(const T*, const T*); ///< Signature of sort function.
48 protected:
49 SortFunction * const *sort_func_list; ///< the sort criteria functions
50 SortListFlags flags; ///< used to control sorting/resorting/etc.
51 uint8 sort_type; ///< what criteria to sort on
52 uint16 resort_timer; ///< resort list after a given amount of ticks if set
54 /**
55 * Check if the list is sortable
57 * @return true if we can sort the list
59 bool IsSortable() const
61 return (this->data != NULL && this->items >= 2);
64 /**
65 * Reset the resort timer
67 void ResetResortTimer()
69 /* Resort every 10 days */
70 this->resort_timer = DAY_TICKS * 10;
73 public:
74 GUIList() :
75 sort_func_list(NULL),
76 flags(VL_FIRST_SORT),
77 sort_type(0),
78 resort_timer(1)
79 {};
81 /**
82 * Get the sorttype of the list
84 * @return The current sorttype
86 uint8 SortType() const
88 return this->sort_type;
91 /**
92 * Set the sorttype of the list
94 * @param n_type the new sort type
96 void SetSortType(uint8 n_type)
98 if (this->sort_type != n_type) {
99 SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
100 this->sort_type = n_type;
105 * Export current sort conditions
107 * @return the current sort conditions
109 Listing GetListing() const
111 Listing l;
112 l.order = (this->flags & VL_DESC) != 0;
113 l.criteria = this->sort_type;
115 return l;
119 * Import sort conditions
121 * @param l The sort conditions we want to use
123 void SetListing(Listing l)
125 if (l.order) {
126 SETBITS(this->flags, VL_DESC);
127 } else {
128 CLRBITS(this->flags, VL_DESC);
130 this->sort_type = l.criteria;
132 SETBITS(this->flags, VL_FIRST_SORT);
136 * Check if a resort is needed next loop
137 * If used the resort timer will decrease every call
138 * till 0. If 0 reached the resort bit will be set and
139 * the timer will be reset.
141 * @return true if resort bit is set for next loop
143 bool NeedResort()
145 if (--this->resort_timer == 0) {
146 SETBITS(this->flags, VL_RESORT);
147 this->ResetResortTimer();
148 return true;
150 return false;
154 * Force a resort next Sort call
155 * Reset the resort timer if used too.
157 void ForceResort()
159 SETBITS(this->flags, VL_RESORT);
163 * Check if the sort order is descending
165 * @return true if the sort order is descending
167 bool IsDescSortOrder() const
169 return (this->flags & VL_DESC) != 0;
173 * Toggle the sort order
174 * Since that is the worst condition for the sort function
175 * reverse the list here.
177 void ToggleSortOrder()
179 this->flags ^= VL_DESC;
181 if (this->IsSortable()) MemReverseT(this->data, this->items);
185 * Sort the list.
186 * For the first sorting we use quick sort since it is
187 * faster for irregular sorted data. After that we
188 * use gsort.
190 * @param compare The function to compare two list items
191 * @return true if the list sequence has been altered
194 bool Sort(SortFunction *compare)
196 /* Do not sort if the resort bit is not set */
197 if (!(this->flags & VL_RESORT)) return false;
199 CLRBITS(this->flags, VL_RESORT);
201 this->ResetResortTimer();
203 /* Do not sort when the list is not sortable */
204 if (!this->IsSortable()) return false;
206 const bool desc = (this->flags & VL_DESC) != 0;
208 if (this->flags & VL_FIRST_SORT) {
209 CLRBITS(this->flags, VL_FIRST_SORT);
211 QSortT(this->data, this->items, compare, desc);
212 return true;
215 GSortT(this->data, this->items, compare, desc);
216 return true;
220 * Hand the array of sort function pointers to the sort list
222 * @param n_funcs The pointer to the first sort func
224 void SetSortFuncs(SortFunction * const *n_funcs)
226 this->sort_func_list = n_funcs;
230 * Overload of #Sort(SortFunction *compare)
231 * Overloaded to reduce external code
233 * @return true if the list sequence has been altered
235 bool Sort()
237 assert(this->sort_func_list != NULL);
238 return this->Sort(this->sort_func_list[this->sort_type]);
242 * Check if the filter is enabled
244 * @return true if the filter is enabled
246 bool IsFilterEnabled() const
248 return (this->flags & VL_FILTER) != 0;
252 * Enable or disable the filter
254 * @param state If filtering should be enabled or disabled
256 void SetFilterState(bool state)
258 if (state) {
259 SETBITS(this->flags, VL_FILTER);
260 } else {
261 CLRBITS(this->flags, VL_FILTER);
266 * Filter the list.
267 * @tparam F Type of data fed as additional value to the filter function.
268 * @param decide The function to decide about an item
269 * @param filter_data Additional data passed to the filter function
270 * @return true if the list has been altered by filtering
272 template <typename F>
273 bool Filter (bool CDECL decide (const T*, F), F filter_data)
275 /* Do not filter if the filter bit is not set */
276 if (!(this->flags & VL_FILTER)) return false;
278 bool changed = false;
279 for (uint iter = 0; iter < this->items;) {
280 T *item = &this->data[iter];
281 if (!decide(item, filter_data)) {
282 this->Erase(item);
283 changed = true;
284 } else {
285 iter++;
289 return changed;
293 * Check if a rebuild is needed
294 * @return true if a rebuild is needed
296 bool NeedRebuild() const
298 return (this->flags & VL_REBUILD) != 0;
302 * Force that a rebuild is needed
304 void ForceRebuild()
306 SETBITS(this->flags, VL_REBUILD);
310 * Notify the sortlist that the rebuild is done
312 * @note This forces a resort
314 void RebuildDone()
316 CLRBITS(this->flags, VL_REBUILD);
317 SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
321 #endif /* SORTLIST_TYPE_H */