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