sortlist_type.h

Go to the documentation of this file.
00001 /* $Id: sortlist_type.h 20286 2010-08-01 19:44:49Z frosch $ */
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 
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     /* 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 
00257   bool Sort(SortFunction *compare)
00258   {
00259     /* Do not sort if the resort bit is not set */
00260     if (!(this->flags & VL_RESORT)) return false;
00261 
00262     CLRBITS(this->flags, VL_RESORT);
00263 
00264     this->ResetResortTimer();
00265 
00266     /* Do not sort when the list is not sortable */
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     /* Do not filter if the filter bit is not set */
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 /* SORTLIST_TYPE_H */

Generated on Fri Dec 31 17:15:38 2010 for OpenTTD by  doxygen 1.6.1