sortlist_type.h

Go to the documentation of this file.
00001 /* $Id: sortlist_type.h 17530 2009-09-13 17:47:07Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
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 
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     /* Resort every 10 days */
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 
00256   bool Sort(SortFunction *compare)
00257   {
00258     /* Do not sort if the resort bit is not set */
00259     if (!(this->flags & VL_RESORT)) return false;
00260 
00261     CLRBITS(this->flags, VL_RESORT);
00262 
00263     this->ResetResortTimer();
00264 
00265     /* Do not sort when the list is not sortable */
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     /* Do not filter if the filter bit is not set */
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 /* SORTLIST_TYPE_H */

Generated on Sat Apr 17 23:24:53 2010 for OpenTTD by  doxygen 1.6.1