sortlist_type.h

Go to the documentation of this file.
00001 /* $Id: sortlist_type.h 21890 2011-01-22 14:52:20Z 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/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     /* Resort every 10 days */
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     /* 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 Fri Mar 18 23:17:38 2011 for OpenTTD by  doxygen 1.6.1