sortlist_type.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef SORTLIST_TYPE_H
00013 #define SORTLIST_TYPE_H
00014
00015 #include "core/enum_type.hpp"
00016 #include "core/bitmath_func.hpp"
00017 #include "core/sort_func.hpp"
00018 #include "core/smallvec_type.hpp"
00019 #include "date_type.h"
00020
00022 enum SortListFlags {
00023 VL_NONE = 0,
00024 VL_DESC = 1 << 0,
00025 VL_RESORT = 1 << 1,
00026 VL_REBUILD = 1 << 2,
00027 VL_FIRST_SORT = 1 << 3,
00028 VL_FILTER = 1 << 4,
00029 VL_END = 1 << 5,
00030 };
00031 DECLARE_ENUM_AS_BIT_SET(SortListFlags)
00032
00033
00034 struct Listing {
00035 bool order;
00036 byte criteria;
00037 };
00039 struct Filtering {
00040 bool state;
00041 byte criteria;
00042 };
00043
00049 template <typename T, typename F = const char*>
00050 class GUIList : public SmallVector<T, 32> {
00051 public:
00052 typedef int CDECL SortFunction(const T*, const T*);
00053 typedef bool CDECL FilterFunction(const T*, F);
00054
00055 protected:
00056 SortFunction * const *sort_func_list;
00057 FilterFunction * const *filter_func_list;
00058 SortListFlags flags;
00059 uint8 sort_type;
00060 uint8 filter_type;
00061 uint16 resort_timer;
00062
00068 bool IsSortable() const
00069 {
00070 return (this->data != NULL && this->items >= 2);
00071 }
00072
00076 void ResetResortTimer()
00077 {
00078
00079 this->resort_timer = DAY_TICKS * 10;
00080 }
00081
00082 public:
00083 GUIList() :
00084 sort_func_list(NULL),
00085 filter_func_list(NULL),
00086 flags(VL_FIRST_SORT),
00087 sort_type(0),
00088 filter_type(0),
00089 resort_timer(1)
00090 {};
00091
00097 uint8 SortType() const
00098 {
00099 return this->sort_type;
00100 }
00101
00107 void SetSortType(uint8 n_type)
00108 {
00109 if (this->sort_type != n_type) {
00110 SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
00111 this->sort_type = n_type;
00112 }
00113 }
00114
00120 Listing GetListing() const
00121 {
00122 Listing l;
00123 l.order = (this->flags & VL_DESC) != 0;
00124 l.criteria = this->sort_type;
00125
00126 return l;
00127 }
00128
00134 void SetListing(Listing l)
00135 {
00136 if (l.order) {
00137 SETBITS(this->flags, VL_DESC);
00138 } else {
00139 CLRBITS(this->flags, VL_DESC);
00140 }
00141 this->sort_type = l.criteria;
00142
00143 SETBITS(this->flags, VL_FIRST_SORT);
00144 }
00145
00151 uint8 FilterType() const
00152 {
00153 return this->filter_type;
00154 }
00155
00161 void SetFilterType(uint8 n_type)
00162 {
00163 if (this->filter_type != n_type) {
00164 this->filter_type = n_type;
00165 }
00166 }
00167
00173 Filtering GetFiltering() const
00174 {
00175 Filtering f;
00176 f.state = (this->flags & VL_FILTER) != 0;
00177 f.criteria = this->filter_type;
00178
00179 return f;
00180 }
00181
00187 void SetFiltering(Filtering f)
00188 {
00189 if (f.state) {
00190 SETBITS(this->flags, VL_FILTER);
00191 } else {
00192 CLRBITS(this->flags, VL_FILTER);
00193 }
00194 this->filter_type = f.criteria;
00195 }
00196
00205 bool NeedResort()
00206 {
00207 if (--this->resort_timer == 0) {
00208 SETBITS(this->flags, VL_RESORT);
00209 this->ResetResortTimer();
00210 return true;
00211 }
00212 return false;
00213 }
00214
00219 void ForceResort()
00220 {
00221 SETBITS(this->flags, VL_RESORT);
00222 }
00223
00229 bool IsDescSortOrder() const
00230 {
00231 return (this->flags & VL_DESC) != 0;
00232 }
00233
00239 void ToggleSortOrder()
00240 {
00241 this->flags ^= VL_DESC;
00242
00243 if (this->IsSortable()) MemReverseT(this->data, this->items);
00244 }
00245
00256 bool Sort(SortFunction *compare)
00257 {
00258
00259 if (!(this->flags & VL_RESORT)) return false;
00260
00261 CLRBITS(this->flags, VL_RESORT);
00262
00263 this->ResetResortTimer();
00264
00265
00266 if (!this->IsSortable()) return false;
00267
00268 const bool desc = (this->flags & VL_DESC) != 0;
00269
00270 if (this->flags & VL_FIRST_SORT) {
00271 CLRBITS(this->flags, VL_FIRST_SORT);
00272
00273 QSortT(this->data, this->items, compare, desc);
00274 return true;
00275 }
00276
00277 GSortT(this->data, this->items, compare, desc);
00278 return true;
00279 }
00280
00286 void SetSortFuncs(SortFunction * const *n_funcs)
00287 {
00288 this->sort_func_list = n_funcs;
00289 }
00290
00297 bool Sort()
00298 {
00299 assert(this->sort_func_list != NULL);
00300 return this->Sort(this->sort_func_list[this->sort_type]);
00301 }
00302
00308 bool IsFilterEnabled() const
00309 {
00310 return (this->flags & VL_FILTER) != 0;
00311 }
00312
00318 void SetFilterState(bool state)
00319 {
00320 if (state) {
00321 SETBITS(this->flags, VL_FILTER);
00322 } else {
00323 CLRBITS(this->flags, VL_FILTER);
00324 }
00325 }
00326
00334 bool Filter(FilterFunction *decide, F filter_data)
00335 {
00336
00337 if (!(this->flags & VL_FILTER)) return false;
00338
00339 bool changed = false;
00340 for (uint iter = 0; iter < this->items;) {
00341 T *item = &this->data[iter];
00342 if (!decide(item, filter_data)) {
00343 this->Erase(item);
00344 changed = true;
00345 } else {
00346 iter++;
00347 }
00348 }
00349
00350 return changed;
00351 }
00352
00358 void SetFilterFuncs(FilterFunction * const *n_funcs)
00359 {
00360 this->filter_func_list = n_funcs;
00361 }
00362
00369 bool Filter(F filter_data)
00370 {
00371 if (this->filter_func_list == NULL) return false;
00372 return this->Filter(this->filter_func_list[this->filter_type], filter_data);
00373 }
00374
00379 bool NeedRebuild() const
00380 {
00381 return (this->flags & VL_REBUILD) != 0;
00382 }
00383
00387 void ForceRebuild()
00388 {
00389 SETBITS(this->flags, VL_REBUILD);
00390 }
00391
00397 void RebuildDone()
00398 {
00399 CLRBITS(this->flags, VL_REBUILD);
00400 SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
00401 }
00402 };
00403
00404 #endif