sortlist_type.h

Go to the documentation of this file.
00001 /* $Id: sortlist_type.h 15377 2009-02-06 18:00:05Z rubidium $ */
00002 
00005 #ifndef SORTLIST_TYPE_H
00006 #define SORTLIST_TYPE_H
00007 
00008 #include "core/enum_type.hpp"
00009 #include "core/bitmath_func.hpp"
00010 #include "core/mem_func.hpp"
00011 #include "core/sort_func.hpp"
00012 #include "core/smallvec_type.hpp"
00013 #include "date_type.h"
00014 
00015 enum SortListFlags {
00016   VL_NONE       = 0,      
00017   VL_DESC       = 1 << 0, 
00018   VL_RESORT     = 1 << 1, 
00019   VL_REBUILD    = 1 << 2, 
00020   VL_FIRST_SORT = 1 << 3, 
00021   VL_FILTER     = 1 << 4, 
00022   VL_END        = 1 << 5,
00023 };
00024 DECLARE_ENUM_AS_BIT_SET(SortListFlags);
00025 
00026 struct Listing {
00027   bool order;    
00028   byte criteria; 
00029 };
00030 struct Filtering {
00031   bool state;    
00032   byte criteria; 
00033 };
00034 
00035 template <typename T, typename F = const char*>
00036 class GUIList : public SmallVector<T, 32> {
00037 public:
00038   typedef int CDECL SortFunction(const T*, const T*);
00039   typedef bool CDECL FilterFunction(const T*, F);
00040 
00041 protected:
00042   SortFunction * const *sort_func_list;     
00043   FilterFunction * const *filter_func_list; 
00044   SortListFlags flags;                      
00045   uint8 sort_type;                          
00046   uint8 filter_type;                        
00047   uint16 resort_timer;                      
00048 
00054   bool IsSortable() const
00055   {
00056     return (this->data != NULL && this->items >= 2);
00057   }
00058 
00062   void ResetResortTimer()
00063   {
00064     /* Resort every 10 days */
00065     this->resort_timer = DAY_TICKS * 10;
00066   }
00067 
00068 public:
00069   GUIList() :
00070     sort_func_list(NULL),
00071     filter_func_list(NULL),
00072     flags(VL_FIRST_SORT),
00073     sort_type(0),
00074     filter_type(0),
00075     resort_timer(1)
00076   {};
00077 
00083   uint8 SortType() const
00084   {
00085     return this->sort_type;
00086   }
00087 
00093   void SetSortType(uint8 n_type)
00094   {
00095     if (this->sort_type != n_type) {
00096       SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
00097       this->sort_type = n_type;
00098     }
00099   }
00100 
00106   Listing GetListing() const
00107   {
00108     Listing l;
00109     l.order = HASBITS(this->flags, VL_DESC);
00110     l.criteria = this->sort_type;
00111 
00112     return l;
00113   }
00114 
00120   void SetListing(Listing l)
00121   {
00122     if (l.order) {
00123       SETBITS(this->flags, VL_DESC);
00124     } else {
00125       CLRBITS(this->flags, VL_DESC);
00126     }
00127     this->sort_type = l.criteria;
00128 
00129     SETBITS(this->flags, VL_FIRST_SORT);
00130   }
00131 
00137   uint8 FilterType() const
00138   {
00139     return this->filter_type;
00140   }
00141 
00147   void SetFilterType(uint8 n_type)
00148   {
00149     if (this->filter_type != n_type) {
00150       this->filter_type = n_type;
00151     }
00152   }
00153 
00159   Filtering GetFiltering() const
00160   {
00161     Filtering f;
00162     f.state = HASBITS(this->flags, VL_FILTER);
00163     f.criteria = this->filter_type;
00164 
00165     return f;
00166   }
00167 
00173   void SetFiltering(Filtering f)
00174   {
00175     if (f.state) {
00176       SETBITS(this->flags, VL_FILTER);
00177     } else {
00178       CLRBITS(this->flags, VL_FILTER);
00179     }
00180     this->filter_type = f.criteria;
00181   }
00182 
00191   bool NeedResort()
00192   {
00193     if (--this->resort_timer == 0) {
00194       SETBITS(this->flags, VL_RESORT);
00195       this->ResetResortTimer();
00196       return true;
00197     }
00198     return false;
00199   }
00200 
00205   void ForceResort()
00206   {
00207     SETBITS(this->flags, VL_RESORT);
00208   }
00209 
00215   bool IsDescSortOrder() const
00216   {
00217     return HASBITS(this->flags, VL_DESC);
00218   }
00219 
00225   void ToggleSortOrder()
00226   {
00227     this->flags ^= VL_DESC;
00228 
00229     if (this->IsSortable()) MemReverseT(this->data, this->items);
00230   }
00231 
00241   bool Sort(SortFunction *compare)
00242   {
00243     /* Do not sort if the resort bit is not set */
00244     if (!HASBITS(this->flags, VL_RESORT)) return false;
00245 
00246     CLRBITS(this->flags, VL_RESORT);
00247 
00248     this->ResetResortTimer();
00249 
00250     /* Do not sort when the list is not sortable */
00251     if (!this->IsSortable()) return false;
00252 
00253     const bool desc = HASBITS(this->flags, VL_DESC);
00254 
00255     if (HASBITS(this->flags, VL_FIRST_SORT)) {
00256       CLRBITS(this->flags, VL_FIRST_SORT);
00257 
00258       QSortT(this->data, this->items, compare, desc);
00259       return true;
00260     }
00261 
00262     GSortT(this->data, this->items, compare, desc);
00263     return true;
00264   }
00265 
00271   void SetSortFuncs(SortFunction * const *n_funcs)
00272   {
00273     this->sort_func_list = n_funcs;
00274   }
00275 
00282   bool Sort()
00283   {
00284     assert(this->sort_func_list != NULL);
00285     return this->Sort(this->sort_func_list[this->sort_type]);
00286   }
00287 
00293   bool IsFilterEnabled() const
00294   {
00295     return HASBITS(this->flags, VL_FILTER);
00296   }
00297 
00303   void SetFilterState(bool state)
00304   {
00305     if (state) {
00306       SETBITS(this->flags, VL_FILTER);
00307     } else {
00308       CLRBITS(this->flags, VL_FILTER);
00309     }
00310   }
00311 
00319   bool Filter(FilterFunction *decide, F filter_data)
00320   {
00321     /* Do not filter if the filter bit is not set */
00322     if (!HASBITS(this->flags, VL_FILTER)) return false;
00323 
00324     bool changed = false;
00325     for (uint iter = 0; iter < this->items;) {
00326       T *item = &this->data[iter];
00327       if (!decide(item, filter_data)) {
00328         this->Erase(item);
00329         changed = true;
00330       } else {
00331         iter++;
00332       }
00333     }
00334 
00335     return changed;
00336   }
00337 
00343   void SetFilterFuncs(FilterFunction * const *n_funcs)
00344   {
00345     this->filter_func_list = n_funcs;
00346   }
00347 
00354   bool Filter(F filter_data)
00355   {
00356     if (this->filter_func_list == NULL) return false;
00357     return this->Filter(this->filter_func_list[this->filter_type], filter_data);
00358   }
00359 
00364   bool NeedRebuild() const
00365   {
00366     return HASBITS(this->flags, VL_REBUILD);
00367   }
00368 
00372   void ForceRebuild()
00373   {
00374     SETBITS(this->flags, VL_REBUILD);
00375   }
00376 
00382   void RebuildDone()
00383   {
00384     CLRBITS(this->flags, VL_REBUILD);
00385     SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
00386   }
00387 };
00388 
00389 #endif /* SORTLIST_TYPE_H */

Generated on Mon Mar 9 23:33:50 2009 for openttd by  doxygen 1.5.6