mirror of https://github.com/OpenTTD/OpenTTD
(svn r13174) -Codechange: make a class of the IndustryDirectoryWindow.
parent
09b5320a81
commit
17a1873843
|
@ -354,9 +354,6 @@ static inline Industry *GetRandomIndustry()
|
||||||
#define FOR_ALL_INDUSTRIES_FROM(i, start) for (i = GetIndustry(start); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) if (i->IsValid())
|
#define FOR_ALL_INDUSTRIES_FROM(i, start) for (i = GetIndustry(start); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) if (i->IsValid())
|
||||||
#define FOR_ALL_INDUSTRIES(i) FOR_ALL_INDUSTRIES_FROM(i, 0)
|
#define FOR_ALL_INDUSTRIES(i) FOR_ALL_INDUSTRIES_FROM(i, 0)
|
||||||
|
|
||||||
extern const Industry **_industry_sort;
|
|
||||||
extern bool _industry_sort_dirty;
|
|
||||||
|
|
||||||
static const uint8 IT_INVALID = 255;
|
static const uint8 IT_INVALID = 255;
|
||||||
|
|
||||||
#endif /* INDUSTRY_H */
|
#endif /* INDUSTRY_H */
|
||||||
|
|
|
@ -55,9 +55,6 @@ static TileIndex _industry_sound_tile;
|
||||||
int _total_industries; //general counter
|
int _total_industries; //general counter
|
||||||
uint16 _industry_counts[NUM_INDUSTRYTYPES]; // Number of industries per type ingame
|
uint16 _industry_counts[NUM_INDUSTRYTYPES]; // Number of industries per type ingame
|
||||||
|
|
||||||
const Industry **_industry_sort;
|
|
||||||
bool _industry_sort_dirty;
|
|
||||||
|
|
||||||
IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
|
IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
|
||||||
IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
|
IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
|
||||||
|
|
||||||
|
@ -168,12 +165,11 @@ Industry::~Industry()
|
||||||
} END_TILE_LOOP(tile_cur, 42, 42, this->xy - TileDiff(21, 21))
|
} END_TILE_LOOP(tile_cur, 42, 42, this->xy - TileDiff(21, 21))
|
||||||
}
|
}
|
||||||
|
|
||||||
_industry_sort_dirty = true;
|
|
||||||
DecIndustryTypeCount(this->type);
|
DecIndustryTypeCount(this->type);
|
||||||
|
|
||||||
DeleteSubsidyWithIndustry(this->index);
|
DeleteSubsidyWithIndustry(this->index);
|
||||||
DeleteWindowById(WC_INDUSTRY_VIEW, this->index);
|
DeleteWindowById(WC_INDUSTRY_VIEW, this->index);
|
||||||
InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
|
InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0);
|
||||||
this->xy = 0;
|
this->xy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1556,8 +1552,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, int type, const Ind
|
||||||
if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) {
|
if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) {
|
||||||
for (j = 0; j != 50; j++) PlantRandomFarmField(i);
|
for (j = 0; j != 50; j++) PlantRandomFarmField(i);
|
||||||
}
|
}
|
||||||
_industry_sort_dirty = true;
|
InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0);
|
||||||
InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper function for Build/Fund an industry
|
/** Helper function for Build/Fund an industry
|
||||||
|
@ -2240,8 +2235,7 @@ void IndustryMonthlyLoop()
|
||||||
_current_player = old_player;
|
_current_player = old_player;
|
||||||
|
|
||||||
/* production-change */
|
/* production-change */
|
||||||
_industry_sort_dirty = true;
|
InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 1);
|
||||||
InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2251,7 +2245,6 @@ void InitializeIndustries()
|
||||||
_Industry_pool.AddBlockToPool();
|
_Industry_pool.AddBlockToPool();
|
||||||
|
|
||||||
ResetIndustryCounts();
|
ResetIndustryCounts();
|
||||||
_industry_sort_dirty = true;
|
|
||||||
_industry_sound_tile = 0;
|
_industry_sound_tile = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "tilehighlight_func.h"
|
#include "tilehighlight_func.h"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
|
#include "sortlist_type.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
@ -697,7 +698,7 @@ enum IndustryDirectoryWidgets {
|
||||||
IDW_SORTBYPROD,
|
IDW_SORTBYPROD,
|
||||||
IDW_SORTBYTRANSPORT,
|
IDW_SORTBYTRANSPORT,
|
||||||
IDW_SPACER,
|
IDW_SPACER,
|
||||||
IDW_INDUSRTY_LIST,
|
IDW_INDUSTRY_LIST,
|
||||||
IDW_SCROLLBAR,
|
IDW_SCROLLBAR,
|
||||||
IDW_RESIZE,
|
IDW_RESIZE,
|
||||||
};
|
};
|
||||||
|
@ -718,12 +719,9 @@ static const Widget _industry_directory_widgets[] = {
|
||||||
{ WIDGETS_END},
|
{ WIDGETS_END},
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint _num_industry_sort;
|
|
||||||
|
|
||||||
static char _bufcache[96];
|
static char _bufcache[96];
|
||||||
static const Industry* _last_industry;
|
static const Industry* _last_industry;
|
||||||
|
static int _internal_sort_order;
|
||||||
static byte _industry_sort_order;
|
|
||||||
|
|
||||||
static int CDECL GeneralIndustrySorter(const void *a, const void *b)
|
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;
|
const Industry* j = *(const Industry**)b;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (_industry_sort_order >> 1) {
|
switch (_internal_sort_order >> 1) {
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
case 0: /* Sort by Name (handled later) */
|
case 0: /* Sort by Name (handled later) */
|
||||||
r = 0;
|
r = 0;
|
||||||
|
@ -798,56 +796,93 @@ static int CDECL GeneralIndustrySorter(const void *a, const void *b)
|
||||||
r = strcmp(buf1, _bufcache);
|
r = strcmp(buf1, _bufcache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_industry_sort_order & 1) r = -r;
|
if (_internal_sort_order & 1) r = -r;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef GUIList<const Industry*> GUIIndustryList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a sorted industry list.
|
* Rebuild industries list if the VL_REBUILD flag is set
|
||||||
* 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
|
* @param sl pointer to industry list
|
||||||
* the list is not populated with invalid industries from the previous game.
|
|
||||||
*/
|
*/
|
||||||
static void MakeSortedIndustryList()
|
static void BuildIndustriesList(GUIIndustryList *sl)
|
||||||
{
|
{
|
||||||
|
uint n = 0;
|
||||||
const Industry *i;
|
const Industry *i;
|
||||||
int n = 0;
|
|
||||||
|
if (!(sl->flags & VL_REBUILD)) return;
|
||||||
|
|
||||||
/* Create array for sorting */
|
/* 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 */
|
DEBUG(misc, 3, "Building industry list");
|
||||||
if (GetNumIndustries() != 0) {
|
|
||||||
FOR_ALL_INDUSTRIES(i) _industry_sort[n++] = i;
|
|
||||||
qsort((void*)_industry_sort, n, sizeof(_industry_sort[0]), GeneralIndustrySorter);
|
|
||||||
}
|
|
||||||
|
|
||||||
_num_industry_sort = n;
|
FOR_ALL_INDUSTRIES(i) industry_sort[n++] = i;
|
||||||
_last_industry = NULL; // used for "cache"
|
|
||||||
|
|
||||||
DEBUG(misc, 3, "Resorting industries list");
|
free((void*)sl->sort_list);
|
||||||
|
sl->sort_list = MallocT<const Industry*>(n);
|
||||||
|
sl->list_length = n;
|
||||||
|
|
||||||
|
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) {
|
if (!(sl->flags & VL_RESORT)) return;
|
||||||
case WE_PAINT: {
|
|
||||||
if (_industry_sort_dirty) {
|
_internal_sort_order = (sl->sort_type << 1) | (sl->flags & VL_DESC);
|
||||||
_industry_sort_dirty = false;
|
_last_industry = NULL; // used for "cache" in namesorting
|
||||||
MakeSortedIndustryList();
|
qsort((void*)sl->sort_list, sl->list_length, sizeof(sl->sort_list[0]), &GeneralIndustrySorter);
|
||||||
|
|
||||||
|
sl->flags &= ~VL_RESORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetVScrollCount(w, _num_industry_sort);
|
/**
|
||||||
|
* The list of industries.
|
||||||
|
*/
|
||||||
|
struct IndustryDirectoryWindow : public Window, public GUIIndustryList {
|
||||||
|
static Listing industry_sort;
|
||||||
|
|
||||||
w->DrawWidgets();
|
IndustryDirectoryWindow(const WindowDesc *desc, WindowNumber number) : Window(desc, number)
|
||||||
w->DrawSortButtonState(IDW_SORTBYNAME + (_industry_sort_order >> 1), _industry_sort_order & 1 ? SBS_DOWN : SBS_UP);
|
{
|
||||||
|
this->vscroll.cap = 16;
|
||||||
|
this->resize.height = this->height - 6 * 10; // minimum 10 items
|
||||||
|
this->resize.step_height = 10;
|
||||||
|
this->FindWindowPlacementAndResize(desc);
|
||||||
|
|
||||||
uint pos = w->vscroll.pos;
|
this->sort_list = NULL;
|
||||||
int n = 0;
|
this->flags = VL_REBUILD;
|
||||||
|
this->sort_type = industry_sort.criteria;
|
||||||
|
if (industry_sort.order) this->flags |= VL_DESC;
|
||||||
|
}
|
||||||
|
|
||||||
while (pos < _num_industry_sort) {
|
virtual void OnPaint()
|
||||||
const Industry* i = _industry_sort[pos];
|
{
|
||||||
|
BuildIndustriesList(this);
|
||||||
|
SortIndustriesList(this);
|
||||||
|
|
||||||
|
SetVScrollCount(this, this->list_length);
|
||||||
|
|
||||||
|
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);
|
const IndustrySpec *indsp = GetIndustrySpec(i->type);
|
||||||
byte p = 0;
|
byte p = 0;
|
||||||
|
|
||||||
|
@ -871,83 +906,70 @@ static void IndustryDirectoryWndProc(Window *w, WindowEvent *e)
|
||||||
/* Drawing the right string */
|
/* Drawing the right string */
|
||||||
StringID str = STR_INDUSTRYDIR_ITEM_NOPROD;
|
StringID str = STR_INDUSTRYDIR_ITEM_NOPROD;
|
||||||
if (p != 1) str = (p == 5) ? STR_INDUSTRYDIR_ITEM : STR_INDUSTRYDIR_ITEM_TWO;
|
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);
|
DrawStringTruncated(4, y, str, TC_FROMSTRING, this->widget[IDW_INDUSTRY_LIST].right - 4);
|
||||||
|
|
||||||
pos++;
|
y += 10;
|
||||||
if (++n == w->vscroll.cap) break;
|
}
|
||||||
}
|
}
|
||||||
} break;
|
|
||||||
|
|
||||||
case WE_CLICK:
|
virtual void OnClick(Point pt, int widget)
|
||||||
switch (e->we.click.widget) {
|
{
|
||||||
case IDW_SORTBYNAME: {
|
switch (widget) {
|
||||||
_industry_sort_order = _industry_sort_order == 0 ? 1 : 0;
|
case IDW_SORTBYNAME:
|
||||||
_industry_sort_dirty = true;
|
case IDW_SORTBYTYPE:
|
||||||
w->SetDirty();
|
case IDW_SORTBYPROD:
|
||||||
} break;
|
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_SORTBYTYPE: {
|
case IDW_INDUSTRY_LIST: {
|
||||||
_industry_sort_order = _industry_sort_order == 2 ? 3 : 2;
|
int y = (pt.y - 28) / 10;
|
||||||
_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;
|
uint16 p;
|
||||||
|
|
||||||
if (!IsInsideMM(y, 0, w->vscroll.cap)) return;
|
if (!IsInsideMM(y, 0, this->vscroll.cap)) return;
|
||||||
p = y + w->vscroll.pos;
|
p = y + this->vscroll.pos;
|
||||||
if (p < _num_industry_sort) {
|
if (p < this->list_length) {
|
||||||
if (_ctrl_pressed) {
|
if (_ctrl_pressed) {
|
||||||
ShowExtraViewPortWindow(_industry_sort[p]->xy);
|
ShowExtraViewPortWindow(this->sort_list[p]->xy);
|
||||||
} else {
|
} else {
|
||||||
ScrollMainWindowToTile(_industry_sort[p]->xy);
|
ScrollMainWindowToTile(this->sort_list[p]->xy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case WE_100_TICKS:
|
|
||||||
w->SetDirty();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WE_RESIZE:
|
|
||||||
w->vscroll.cap += e->we.sizing.diff.y / 10;
|
|
||||||
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 */
|
/** Window definition of the industy directory gui */
|
||||||
static const WindowDesc _industry_directory_desc = {
|
static const WindowDesc _industry_directory_desc = {
|
||||||
WDP_AUTO, WDP_AUTO, 508, 190, 508, 190,
|
WDP_AUTO, WDP_AUTO, 508, 190, 508, 190,
|
||||||
WC_INDUSTRY_DIRECTORY, WC_NONE,
|
WC_INDUSTRY_DIRECTORY, WC_NONE,
|
||||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
|
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
|
||||||
_industry_directory_widgets,
|
_industry_directory_widgets,
|
||||||
IndustryDirectoryWndProc
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
void ShowIndustryDirectory()
|
void ShowIndustryDirectory()
|
||||||
{
|
{
|
||||||
Window *w = AllocateWindowDescFront<Window>(&_industry_directory_desc, 0);
|
AllocateWindowDescFront<IndustryDirectoryWindow>(&_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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,6 @@ static void InitializeDynamicVariables()
|
||||||
{
|
{
|
||||||
/* Dynamic stuff needs to be initialized somewhere... */
|
/* Dynamic stuff needs to be initialized somewhere... */
|
||||||
_town_sort = NULL;
|
_town_sort = NULL;
|
||||||
_industry_sort = NULL;
|
|
||||||
_industry_mngr.ResetMapping();
|
_industry_mngr.ResetMapping();
|
||||||
_industile_mngr.ResetMapping();
|
_industile_mngr.ResetMapping();
|
||||||
}
|
}
|
||||||
|
@ -320,7 +319,6 @@ static void ShutdownGame()
|
||||||
_Engine_pool.CleanPool();
|
_Engine_pool.CleanPool();
|
||||||
|
|
||||||
free((void*)_town_sort);
|
free((void*)_town_sort);
|
||||||
free((void*)_industry_sort);
|
|
||||||
|
|
||||||
free(_config_file);
|
free(_config_file);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue