summaryrefslogtreecommitdiff
path: root/src/industry_gui.cpp
diff options
context:
space:
mode:
authorglx <glx@openttd.org>2008-05-18 23:36:33 +0000
committerglx <glx@openttd.org>2008-05-18 23:36:33 +0000
commitdc1c529a31c927071a6954119fc8b58b651285ac (patch)
tree56c95a32e3bdbc1e3ab2bdaf15350b285b9c051e /src/industry_gui.cpp
parent01a569f0d75bbc532d212ea16a9844148c159881 (diff)
downloadopenttd-dc1c529a31c927071a6954119fc8b58b651285ac.tar.xz
(svn r13174) -Codechange: make a class of the IndustryDirectoryWindow.
Diffstat (limited to 'src/industry_gui.cpp')
-rw-r--r--src/industry_gui.cpp258
1 files changed, 140 insertions, 118 deletions
diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp
index 94818c72b..70b8e4fb2 100644
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -26,6 +26,7 @@
#include "settings_type.h"
#include "tilehighlight_func.h"
#include "string_func.h"
+#include "sortlist_type.h"
#include "table/strings.h"
#include "table/sprites.h"
@@ -697,7 +698,7 @@ enum IndustryDirectoryWidgets {
IDW_SORTBYPROD,
IDW_SORTBYTRANSPORT,
IDW_SPACER,
- IDW_INDUSRTY_LIST,
+ IDW_INDUSTRY_LIST,
IDW_SCROLLBAR,
IDW_RESIZE,
};
@@ -718,12 +719,9 @@ static const Widget _industry_directory_widgets[] = {
{ WIDGETS_END},
};
-static uint _num_industry_sort;
-
static char _bufcache[96];
static const Industry* _last_industry;
-
-static byte _industry_sort_order;
+static int _internal_sort_order;
static int CDECL GeneralIndustrySorter(const void *a, const void *b)
{
@@ -731,7 +729,7 @@ static int CDECL GeneralIndustrySorter(const void *a, const void *b)
const Industry* j = *(const Industry**)b;
int r;
- switch (_industry_sort_order >> 1) {
+ switch (_internal_sort_order >> 1) {
default: NOT_REACHED();
case 0: /* Sort by Name (handled later) */
r = 0;
@@ -798,138 +796,169 @@ static int CDECL GeneralIndustrySorter(const void *a, const void *b)
r = strcmp(buf1, _bufcache);
}
- if (_industry_sort_order & 1) r = -r;
+ if (_internal_sort_order & 1) r = -r;
return r;
}
+typedef GUIList<const Industry*> GUIIndustryList;
+
/**
- * Makes a sorted industry list.
- * When there are no industries, the list has to be made. This so when one
- * starts a new game without industries after playing a game with industries
- * the list is not populated with invalid industries from the previous game.
+ * Rebuild industries list if the VL_REBUILD flag is set
+ *
+ * @param sl pointer to industry list
*/
-static void MakeSortedIndustryList()
+static void BuildIndustriesList(GUIIndustryList *sl)
{
- const Industry* i;
- int n = 0;
+ uint n = 0;
+ const Industry *i;
+
+ if (!(sl->flags & VL_REBUILD)) return;
/* Create array for sorting */
- _industry_sort = ReallocT(_industry_sort, GetMaxIndustryIndex() + 1);
+ const Industry **industry_sort = MallocT<const Industry*>(GetMaxIndustryIndex() + 1);
- /* Don't attempt a sort if there are no industries */
- if (GetNumIndustries() != 0) {
- FOR_ALL_INDUSTRIES(i) _industry_sort[n++] = i;
- qsort((void*)_industry_sort, n, sizeof(_industry_sort[0]), GeneralIndustrySorter);
- }
+ DEBUG(misc, 3, "Building industry list");
+
+ FOR_ALL_INDUSTRIES(i) industry_sort[n++] = i;
- _num_industry_sort = n;
- _last_industry = NULL; // used for "cache"
+ free((void*)sl->sort_list);
+ sl->sort_list = MallocT<const Industry*>(n);
+ sl->list_length = n;
- DEBUG(misc, 3, "Resorting industries list");
+ for (uint i = 0; i < n; ++i) sl->sort_list[i] = industry_sort[i];
+
+ sl->flags &= ~VL_REBUILD;
+ sl->flags |= VL_RESORT;
+ free((void*)industry_sort);
}
-static void IndustryDirectoryWndProc(Window *w, WindowEvent *e)
+/**
+ * Sort industry list if the VL_RESORT flag is set
+ *
+ * @param sl pointer to industry list
+ */
+static void SortIndustriesList(GUIIndustryList *sl)
{
- switch (e->event) {
- case WE_PAINT: {
- if (_industry_sort_dirty) {
- _industry_sort_dirty = false;
- MakeSortedIndustryList();
- }
+ if (!(sl->flags & VL_RESORT)) return;
- SetVScrollCount(w, _num_industry_sort);
+ _internal_sort_order = (sl->sort_type << 1) | (sl->flags & VL_DESC);
+ _last_industry = NULL; // used for "cache" in namesorting
+ qsort((void*)sl->sort_list, sl->list_length, sizeof(sl->sort_list[0]), &GeneralIndustrySorter);
- w->DrawWidgets();
- w->DrawSortButtonState(IDW_SORTBYNAME + (_industry_sort_order >> 1), _industry_sort_order & 1 ? SBS_DOWN : SBS_UP);
+ sl->flags &= ~VL_RESORT;
+}
- uint pos = w->vscroll.pos;
- int n = 0;
+/**
+ * The list of industries.
+ */
+struct IndustryDirectoryWindow : public Window, public GUIIndustryList {
+ static Listing industry_sort;
- while (pos < _num_industry_sort) {
- const Industry* i = _industry_sort[pos];
- const IndustrySpec *indsp = GetIndustrySpec(i->type);
- byte p = 0;
+ IndustryDirectoryWindow(const WindowDesc *desc, WindowNumber number) : Window(desc, number)
+ {
+ this->vscroll.cap = 16;
+ this->resize.height = this->height - 6 * 10; // minimum 10 items
+ this->resize.step_height = 10;
+ this->FindWindowPlacementAndResize(desc);
- /* Industry name */
- SetDParam(p++, i->index);
+ this->sort_list = NULL;
+ this->flags = VL_REBUILD;
+ this->sort_type = industry_sort.criteria;
+ if (industry_sort.order) this->flags |= VL_DESC;
+ }
- /* Industry productions */
- for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
- if (i->produced_cargo[j] == CT_INVALID) continue;
- SetDParam(p++, i->produced_cargo[j]);
- SetDParam(p++, i->last_month_production[j]);
- SetDParam(p++, GetCargoSuffix(j + 3, CST_DIR, (Industry*)i, i->type, indsp));
- }
+ virtual void OnPaint()
+ {
+ BuildIndustriesList(this);
+ SortIndustriesList(this);
- /* Transported productions */
- for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
- if (i->produced_cargo[j] == CT_INVALID) continue;
- SetDParam(p++, i->last_month_pct_transported[j] * 100 >> 8);
- }
+ SetVScrollCount(this, this->list_length);
- /* Drawing the right string */
- StringID str = STR_INDUSTRYDIR_ITEM_NOPROD;
- if (p != 1) str = (p == 5) ? STR_INDUSTRYDIR_ITEM : STR_INDUSTRYDIR_ITEM_TWO;
- DrawStringTruncated(4, 28 + n * 10, str, TC_FROMSTRING, w->widget[IDW_INDUSRTY_LIST].right - 4);
+ this->DrawWidgets();
+ this->DrawSortButtonState(IDW_SORTBYNAME + this->sort_type, this->flags & VL_DESC ? SBS_DOWN : SBS_UP);
+
+ int max = min(this->vscroll.pos + this->vscroll.cap, this->list_length);
+ int y = 28; // start of the list-widget
+
+ for (int n = this->vscroll.pos; n < max; ++n) {
+ const Industry* i = this->sort_list[n];
+ const IndustrySpec *indsp = GetIndustrySpec(i->type);
+ byte p = 0;
- pos++;
- if (++n == w->vscroll.cap) break;
+ /* Industry name */
+ SetDParam(p++, i->index);
+
+ /* Industry productions */
+ for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
+ if (i->produced_cargo[j] == CT_INVALID) continue;
+ SetDParam(p++, i->produced_cargo[j]);
+ SetDParam(p++, i->last_month_production[j]);
+ SetDParam(p++, GetCargoSuffix(j + 3, CST_DIR, (Industry*)i, i->type, indsp));
}
- } break;
-
- case WE_CLICK:
- switch (e->we.click.widget) {
- case IDW_SORTBYNAME: {
- _industry_sort_order = _industry_sort_order == 0 ? 1 : 0;
- _industry_sort_dirty = true;
- w->SetDirty();
- } break;
-
- case IDW_SORTBYTYPE: {
- _industry_sort_order = _industry_sort_order == 2 ? 3 : 2;
- _industry_sort_dirty = true;
- w->SetDirty();
- } break;
-
- case IDW_SORTBYPROD: {
- _industry_sort_order = _industry_sort_order == 4 ? 5 : 4;
- _industry_sort_dirty = true;
- w->SetDirty();
- } break;
-
- case IDW_SORTBYTRANSPORT: {
- _industry_sort_order = _industry_sort_order == 6 ? 7 : 6;
- _industry_sort_dirty = true;
- w->SetDirty();
- } break;
-
- case IDW_INDUSRTY_LIST: {
- int y = (e->we.click.pt.y - 28) / 10;
- uint16 p;
-
- if (!IsInsideMM(y, 0, w->vscroll.cap)) return;
- p = y + w->vscroll.pos;
- if (p < _num_industry_sort) {
- if (_ctrl_pressed) {
- ShowExtraViewPortWindow(_industry_sort[p]->xy);
- } else {
- ScrollMainWindowToTile(_industry_sort[p]->xy);
- }
- }
- } break;
+
+ /* Transported productions */
+ for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
+ if (i->produced_cargo[j] == CT_INVALID) continue;
+ SetDParam(p++, i->last_month_pct_transported[j] * 100 >> 8);
}
- break;
- case WE_100_TICKS:
- w->SetDirty();
- break;
+ /* Drawing the right string */
+ StringID str = STR_INDUSTRYDIR_ITEM_NOPROD;
+ if (p != 1) str = (p == 5) ? STR_INDUSTRYDIR_ITEM : STR_INDUSTRYDIR_ITEM_TWO;
+ DrawStringTruncated(4, y, str, TC_FROMSTRING, this->widget[IDW_INDUSTRY_LIST].right - 4);
- case WE_RESIZE:
- w->vscroll.cap += e->we.sizing.diff.y / 10;
- break;
+ y += 10;
+ }
}
-}
+
+ virtual void OnClick(Point pt, int widget)
+ {
+ switch (widget) {
+ case IDW_SORTBYNAME:
+ case IDW_SORTBYTYPE:
+ case IDW_SORTBYPROD:
+ case IDW_SORTBYTRANSPORT:
+ if (this->sort_type == (widget - IDW_SORTBYNAME)) {
+ this->flags ^= VL_DESC;
+ } else {
+ this->sort_type = widget - IDW_SORTBYNAME;
+ this->flags &= ~VL_DESC;
+ }
+ this->flags |= VL_RESORT;
+ this->SetDirty();
+ break;
+
+ case IDW_INDUSTRY_LIST: {
+ int y = (pt.y - 28) / 10;
+ uint16 p;
+
+ if (!IsInsideMM(y, 0, this->vscroll.cap)) return;
+ p = y + this->vscroll.pos;
+ if (p < this->list_length) {
+ if (_ctrl_pressed) {
+ ShowExtraViewPortWindow(this->sort_list[p]->xy);
+ } else {
+ ScrollMainWindowToTile(this->sort_list[p]->xy);
+ }
+ }
+ } break;
+ }
+ }
+
+ virtual void OnResize(Point new_size, Point delta)
+ {
+ this->vscroll.cap += delta.y / 10;
+ }
+
+ virtual void OnInvalidateData(int data)
+ {
+ this->flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
+ this->InvalidateWidget(IDW_INDUSTRY_LIST);
+ }
+};
+
+Listing IndustryDirectoryWindow::industry_sort = {0, 0};
/** Window definition of the industy directory gui */
static const WindowDesc _industry_directory_desc = {
@@ -937,17 +966,10 @@ static const WindowDesc _industry_directory_desc = {
WC_INDUSTRY_DIRECTORY, WC_NONE,
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
_industry_directory_widgets,
- IndustryDirectoryWndProc
+ NULL
};
void ShowIndustryDirectory()
{
- Window *w = AllocateWindowDescFront<Window>(&_industry_directory_desc, 0);
-
- if (w != NULL) {
- w->vscroll.cap = 16;
- w->resize.height = w->height - 6 * 10; // minimum 10 items
- w->resize.step_height = 10;
- w->SetDirty();
- }
+ AllocateWindowDescFront<IndustryDirectoryWindow>(&_industry_directory_desc, 0);
}