summaryrefslogtreecommitdiff
path: root/src/town_gui.cpp
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2008-05-27 20:05:36 +0000
committerpeter1138 <peter1138@openttd.org>2008-05-27 20:05:36 +0000
commitcfb962c7f135111891c28c6577f27f42d5365aa1 (patch)
treea21d7ea96d49a5cabdc5dfee9fc089ffed41e91c /src/town_gui.cpp
parentee9a9503cee6b65d1258c808ede2523116b61af4 (diff)
downloadopenttd-cfb962c7f135111891c28c6577f27f42d5365aa1.tar.xz
(svn r13297) -Codechange: Use GUIList for the town directory window
Diffstat (limited to 'src/town_gui.cpp')
-rw-r--r--src/town_gui.cpp173
1 files changed, 103 insertions, 70 deletions
diff --git a/src/town_gui.cpp b/src/town_gui.cpp
index 5d7715e95..aed740d8f 100644
--- a/src/town_gui.cpp
+++ b/src/town_gui.cpp
@@ -24,10 +24,13 @@
#include "settings_type.h"
#include "tilehighlight_func.h"
#include "string_func.h"
+#include "sortlist_type.h"
#include "table/sprites.h"
#include "table/strings.h"
+typedef GUIList<const Town*> GUITownList;
+
extern bool GenerateTowns();
static int _scengen_town_size = 1; // depress medium-sized towns per default
@@ -448,71 +451,72 @@ static const Widget _town_directory_widgets[] = {
};
-/* used to get a sorted list of the towns */
-static uint _num_town_sort;
-
-static char _bufcache[64];
-static const Town* _last_town;
+struct TownDirectoryWindow : public Window {
+private:
+ enum TownDirectoryWidget {
+ TDW_SORTNAME = 3,
+ TDW_SORTPOPULATION,
+ TDW_CENTERTOWN,
+ };
-static int CDECL TownNameSorter(const void *a, const void *b)
-{
- const Town* ta = *(const Town**)a;
- const Town* tb = *(const Town**)b;
- char buf1[64];
- int r;
-
- SetDParam(0, ta->index);
- GetString(buf1, STR_TOWN, lastof(buf1));
-
- /* If 'b' is the same town as in the last round, use the cached value
- * We do this to speed stuff up ('b' is called with the same value a lot of
- * times after eachother) */
- if (tb != _last_town) {
- _last_town = tb;
- SetDParam(0, tb->index);
- GetString(_bufcache, STR_TOWN, lastof(_bufcache));
- }
+ /* Runtime saved values */
+ static Listing last_sorting;
+ static const Town *last_town;
- r = strcmp(buf1, _bufcache);
- if (_town_sort_order & 1) r = -r;
- return r;
-}
+ /* Constants for sorting towns */
+ static const GUITownList::SortFunction * const sorter_funcs[];
-static int CDECL TownPopSorter(const void *a, const void *b)
-{
- const Town* ta = *(const Town**)a;
- const Town* tb = *(const Town**)b;
- int r = ta->population - tb->population;
- if (_town_sort_order & 1) r = -r;
- return r;
-}
+ GUITownList towns;
-static void MakeSortedTownList()
-{
- const Town* t;
- uint n = 0;
+ void BuildTownList()
+ {
+ if (!this->towns.NeedRebuild()) return;
- /* Create array for sorting */
- _town_sort = ReallocT(_town_sort, GetMaxTownIndex() + 1);
+ this->towns.Clear();
- FOR_ALL_TOWNS(t) _town_sort[n++] = t;
+ const Town *t;
+ FOR_ALL_TOWNS(t) {
+ *this->towns.Append() = t;
+ }
- _num_town_sort = n;
+ this->towns.Compact();
+ this->towns.RebuildDone();
+ }
- _last_town = NULL; // used for "cache"
- qsort((void*)_town_sort, n, sizeof(_town_sort[0]), _town_sort_order & 2 ? TownPopSorter : TownNameSorter);
+ void SortTownList()
+ {
+ last_town = NULL;
+ this->towns.Sort();
+ }
- DEBUG(misc, 3, "Resorting towns list");
-}
+ /** Sort by town name */
+ static int CDECL TownNameSorter(const Town * const *a, const Town * const *b)
+ {
+ static char buf_cache[64];
+ const Town *ta = *a;
+ const Town *tb = *b;
+ char buf[64];
+
+ SetDParam(0, ta->index);
+ GetString(buf, STR_TOWN, lastof(buf));
+
+ /* If 'b' is the same town as in the last round, use the cached value
+ * We do this to speed stuff up ('b' is called with the same value a lot of
+ * times after eachother) */
+ if (tb != last_town) {
+ last_town = tb;
+ SetDParam(0, tb->index);
+ GetString(buf_cache, STR_TOWN, lastof(buf_cache));
+ }
+ return strcmp(buf, buf_cache);
+ }
-struct TownDirectoryWindow : public Window {
-private:
- enum TownDirectoryWidget {
- TDW_SORTNAME = 3,
- TDW_SORTPOPULATION,
- TDW_CENTERTOWN,
- };
+ /** Sort by population */
+ static int CDECL TownPopulationSorter(const Town * const *a, const Town * const *b)
+ {
+ return (*a)->population - (*b)->population;
+ }
public:
TownDirectoryWindow(const WindowDesc *desc) : Window(desc, 0)
@@ -521,28 +525,35 @@ public:
this->resize.step_height = 10;
this->resize.height = this->height - 10 * 6; // minimum of 10 items in the list, each item 10 high
+ this->towns.SetListing(this->last_sorting);
+ this->towns.SetSortFuncs(this->sorter_funcs);
+ this->towns.ForceRebuild();
+
this->FindWindowPlacementAndResize(desc);
}
+ ~TownDirectoryWindow()
+ {
+ this->last_sorting = this->towns.GetListing();
+ }
+
virtual void OnPaint()
{
- if (_town_sort_dirty) {
- _town_sort_dirty = false;
- MakeSortedTownList();
- }
+ this->BuildTownList();
+ this->SortTownList();
- SetVScrollCount(this, _num_town_sort);
+ SetVScrollCount(this, this->towns.Length());
this->DrawWidgets();
- this->DrawSortButtonState((_town_sort_order <= 1) ? TDW_SORTNAME : TDW_SORTPOPULATION, _town_sort_order & 1 ? SBS_DOWN : SBS_UP);
+ this->DrawSortButtonState(this->towns.sort_type == 0 ? TDW_SORTNAME : TDW_SORTPOPULATION, this->towns.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
{
int n = 0;
uint16 i = this->vscroll.pos;
int y = 28;
- while (i < _num_town_sort) {
- const Town* t = _town_sort[i];
+ while (i < this->towns.Length()) {
+ const Town *t = this->towns[i];
assert(t->xy);
@@ -564,29 +575,33 @@ public:
{
switch (widget) {
case TDW_SORTNAME: /* Sort by Name ascending/descending */
- _town_sort_order = (_town_sort_order == 0) ? 1 : 0;
- _town_sort_dirty = true;
+ if (this->towns.SortType() == 0) {
+ this->towns.ToggleSortOrder();
+ } else {
+ this->towns.SetSortType(0);
+ }
this->SetDirty();
break;
case TDW_SORTPOPULATION: /* Sort by Population ascending/descending */
- _town_sort_order = (_town_sort_order == 2) ? 3 : 2;
- _town_sort_dirty = true;
+ if (this->towns.SortType() == 1) {
+ this->towns.ToggleSortOrder();
+ } else {
+ this->towns.SetSortType(1);
+ }
this->SetDirty();
break;
case TDW_CENTERTOWN: { /* Click on Town Matrix */
- const Town* t;
-
uint16 id_v = (pt.y - 28) / 10;
if (id_v >= this->vscroll.cap) return; // click out of bounds
id_v += this->vscroll.pos;
- if (id_v >= _num_town_sort) return; // click out of town bounds
+ if (id_v >= this->towns.Length()) return; // click out of town bounds
- t = _town_sort[id_v];
+ const Town *t = this->towns[id_v];
assert(t->xy);
if (_ctrl_pressed) {
ShowExtraViewPortWindow(t->xy);
@@ -607,6 +622,24 @@ public:
{
this->vscroll.cap += delta.y / 10;
}
+
+ virtual void OnInvalidateData(int data)
+ {
+ if (data == 0) {
+ this->towns.ForceRebuild();
+ } else {
+ this->towns.ForceResort();
+ }
+ }
+};
+
+Listing TownDirectoryWindow::last_sorting = {false, 0};
+const Town *TownDirectoryWindow::last_town = NULL;
+
+/* Available town directory sorting functions */
+const GUITownList::SortFunction * const TownDirectoryWindow::sorter_funcs[] = {
+ &TownNameSorter,
+ &TownPopulationSorter,
};
static const WindowDesc _town_directory_desc = {