1
0
Fork 0

(svn r13866) -Codechange: Use sortlist for sign windows

release/0.7
peter1138 2008-07-29 10:26:48 +00:00
parent b49814c537
commit ca703d3701
3 changed files with 90 additions and 59 deletions

View File

@ -24,7 +24,6 @@
#include "table/strings.h" #include "table/strings.h"
SignID _new_sign_id; SignID _new_sign_id;
bool _sign_sort_dirty;
/* Initialize the sign-pool */ /* Initialize the sign-pool */
DEFINE_OLD_POOL_GENERIC(Sign, Sign) DEFINE_OLD_POOL_GENERIC(Sign, Sign)
@ -111,8 +110,7 @@ CommandCost CmdPlaceSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
si->z = GetSlopeZ(x, y); si->z = GetSlopeZ(x, y);
UpdateSignVirtCoords(si); UpdateSignVirtCoords(si);
MarkSignDirty(si); MarkSignDirty(si);
InvalidateWindow(WC_SIGN_LIST, 0); InvalidateWindowData(WC_SIGN_LIST, 0, 0);
_sign_sort_dirty = true;
_new_sign_id = si->index; _new_sign_id = si->index;
} }
@ -148,8 +146,7 @@ CommandCost CmdRenameSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
MarkSignDirty(si); MarkSignDirty(si);
UpdateSignVirtCoords(si); UpdateSignVirtCoords(si);
MarkSignDirty(si); MarkSignDirty(si);
InvalidateWindow(WC_SIGN_LIST, 0); InvalidateWindowData(WC_SIGN_LIST, 0, 1);
_sign_sort_dirty = true;
} }
} else { // Delete sign } else { // Delete sign
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -158,8 +155,7 @@ CommandCost CmdRenameSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
MarkSignDirty(si); MarkSignDirty(si);
delete si; delete si;
InvalidateWindow(WC_SIGN_LIST, 0); InvalidateWindowData(WC_SIGN_LIST, 0, 1);
_sign_sort_dirty = true;
} }
} }
@ -242,8 +238,6 @@ static void Load_SIGN()
Sign *si = new (index) Sign(); Sign *si = new (index) Sign();
SlObject(si, _sign_desc); SlObject(si, _sign_desc);
} }
_sign_sort_dirty = true;
} }
extern const ChunkHandler _sign_chunk_handlers[] = { extern const ChunkHandler _sign_chunk_handlers[] = {

View File

@ -8,7 +8,6 @@
#include "signs_type.h" #include "signs_type.h"
extern SignID _new_sign_id; extern SignID _new_sign_id;
extern bool _sign_sort_dirty;
void UpdateAllSignVirtCoords(); void UpdateAllSignVirtCoords();
void PlaceProc_Sign(TileIndex tile); void PlaceProc_Sign(TileIndex tile);

View File

@ -21,67 +21,80 @@
#include "gfx_func.h" #include "gfx_func.h"
#include "viewport_func.h" #include "viewport_func.h"
#include "querystring_gui.h" #include "querystring_gui.h"
#include "sortlist_type.h"
#include "table/strings.h" #include "table/strings.h"
#include "table/sprites.h" #include "table/sprites.h"
static const Sign **_sign_sort; struct SignList {
static uint _num_sign_sort; typedef GUIList<const Sign *> GUISignList;
static char _bufcache[64]; static const Sign *last_sign;
static const Sign *_last_sign; GUISignList signs;
static int CDECL SignNameSorter(const void *a, const void *b) void BuildSignsList()
{ {
const Sign *sign0 = *(const Sign**)a; if (!this->signs.NeedRebuild()) return;
const Sign *sign1 = *(const Sign**)b;
char buf1[64];
SetDParam(0, sign0->index); DEBUG(misc, 3, "Building sign list");
GetString(buf1, STR_SIGN_NAME, lastof(buf1));
if (sign1 != _last_sign) { this->signs.Clear();
_last_sign = sign1;
SetDParam(0, sign1->index); const Sign *si;
GetString(_bufcache, STR_SIGN_NAME, lastof(_bufcache)); FOR_ALL_SIGNS(si) *this->signs.Append() = si;
this->signs.Compact();
this->signs.RebuildDone();
} }
return strcmp(buf1, _bufcache); // sort by name /** Sort signs by their name */
} static int CDECL SignNameSorter(const Sign* const *a, const Sign* const *b)
{
static char buf_cache[64];
char buf[64];
static void GlobalSortSignList() SetDParam(0, (*a)->index);
{ GetString(buf, STR_SIGN_NAME, lastof(buf));
const Sign *si;
uint n = 0;
/* Create array for sorting */ if (*b != last_sign) {
_sign_sort = ReallocT(_sign_sort, GetMaxSignIndex() + 1); last_sign = *b;
SetDParam(0, (*b)->index);
GetString(buf_cache, STR_SIGN_NAME, lastof(buf_cache));
}
FOR_ALL_SIGNS(si) _sign_sort[n++] = si; return strcasecmp(buf, buf_cache);
_num_sign_sort = n; }
qsort((void*)_sign_sort, n, sizeof(_sign_sort[0]), SignNameSorter); void SortSignsList()
{
if (!this->signs.Sort(&SignNameSorter)) return;
_sign_sort_dirty = false; /* Reset the name sorter sort cache */
this->last_sign = NULL;
}
};
DEBUG(misc, 3, "Resorting global signs list"); const Sign *SignList::last_sign = NULL;
}
struct SignListWindow : Window { struct SignListWindow : Window, SignList {
SignListWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number) SignListWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
{ {
this->vscroll.cap = 12; this->vscroll.cap = 12;
this->resize.step_height = 10; this->resize.step_height = 10;
this->resize.height = this->height - 10 * 7; // minimum if 5 in the list this->resize.height = this->height - 10 * 7; // minimum if 5 in the list
this->signs.ForceRebuild();
this->signs.NeedResort();
this->FindWindowPlacementAndResize(desc); this->FindWindowPlacementAndResize(desc);
} }
virtual void OnPaint() virtual void OnPaint()
{ {
if (_sign_sort_dirty) GlobalSortSignList(); BuildSignsList();
SortSignsList();
SetVScrollCount(this, _num_sign_sort); SetVScrollCount(this, this->signs.Length());
SetDParam(0, this->vscroll.count); SetDParam(0, this->vscroll.count);
this->DrawWidgets(); this->DrawWidgets();
@ -95,7 +108,7 @@ struct SignListWindow : Window {
/* Start drawing the signs */ /* Start drawing the signs */
for (uint16 i = this->vscroll.pos; i < this->vscroll.cap + this->vscroll.pos && i < this->vscroll.count; i++) { for (uint16 i = this->vscroll.pos; i < this->vscroll.cap + this->vscroll.pos && i < this->vscroll.count; i++) {
const Sign *si = _sign_sort[i]; const Sign *si = this->signs[i];
if (si->owner != OWNER_NONE) DrawPlayerIcon(si->owner, 4, y + 1); if (si->owner != OWNER_NONE) DrawPlayerIcon(si->owner, 4, y + 1);
@ -114,7 +127,7 @@ struct SignListWindow : Window {
id_v += this->vscroll.pos; id_v += this->vscroll.pos;
if (id_v >= this->vscroll.count) return; if (id_v >= this->vscroll.count) return;
const Sign *si = _sign_sort[id_v]; const Sign *si = this->signs[id_v];
ScrollMainWindowToTile(TileVirtXY(si->x, si->y)); ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
} }
} }
@ -123,6 +136,15 @@ struct SignListWindow : Window {
{ {
this->vscroll.cap += delta.y / 10; this->vscroll.cap += delta.y / 10;
} }
virtual void OnInvalidateData(int data)
{
if (data == 0) {
this->signs.ForceRebuild();
} else {
this->signs.ForceResort();
}
}
}; };
static const Widget _sign_list_widget[] = { static const Widget _sign_list_widget[] = {
@ -163,7 +185,7 @@ enum QueryEditSignWidgets {
QUERY_EDIT_SIGN_WIDGET_NEXT, QUERY_EDIT_SIGN_WIDGET_NEXT,
}; };
struct SignWindow : QueryStringBaseWindow { struct SignWindow : QueryStringBaseWindow, SignList {
SignID cur_sign; SignID cur_sign;
SignWindow(const WindowDesc *desc, const Sign *si) : QueryStringBaseWindow(desc) SignWindow(const WindowDesc *desc, const Sign *si) : QueryStringBaseWindow(desc)
@ -210,36 +232,52 @@ struct SignWindow : QueryStringBaseWindow {
{ {
switch (widget) { switch (widget) {
case QUERY_EDIT_SIGN_WIDGET_PREVIOUS: { case QUERY_EDIT_SIGN_WIDGET_PREVIOUS: {
if (_sign_sort_dirty) GlobalSortSignList(); /* Rebuild the sign list */
SignID sign_index = _sign_sort[_num_sign_sort - 1]->index; this->signs.ForceRebuild();
for (uint i = 1; i < _num_sign_sort; i++) { this->signs.NeedResort();
if (this->cur_sign == _sign_sort[i]->index) { this->BuildSignsList();
sign_index = _sign_sort[i - 1]->index; this->SortSignsList();
/* By default pick the last entry */
const Sign *si = this->signs[this->signs.Length(
) - 1];
for (uint i = 1; i < this->signs.Length(); i++) {
if (this->cur_sign == this->signs[i]->index) {
si = this->signs[i - 1];
break; break;
} }
} }
const Sign *si = GetSign(sign_index);
/* Scroll to sign and reopen window */ /* Scroll to sign and reopen window */
ScrollMainWindowToTile(TileVirtXY(si->x, si->y)); ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
UpdateSignEditWindow(si); UpdateSignEditWindow(si);
} break; break;
}
case QUERY_EDIT_SIGN_WIDGET_NEXT: { case QUERY_EDIT_SIGN_WIDGET_NEXT: {
if (_sign_sort_dirty) GlobalSortSignList(); /* Rebuild the sign list */
SignID sign_index = _sign_sort[0]->index; this->signs.ForceRebuild();
for (uint i = 0; i < _num_sign_sort - 1; i++) { this->signs.NeedResort();
if (this->cur_sign == _sign_sort[i]->index) { this->BuildSignsList();
sign_index = _sign_sort[i + 1]->index; this->SortSignsList();
/* By default pick the last entry */
const Sign *si = this->signs[this->signs.Length(
) - 1];
for (uint i = 0; i < this->signs.Length() - 1; i++) {
if (this->cur_sign == this->signs[i]->index) {
si = this->signs[i + 1];
break; break;
} }
} }
const Sign *si = GetSign(sign_index);
/* Scroll to sign and reopen window */ /* Scroll to sign and reopen window */
ScrollMainWindowToTile(TileVirtXY(si->x, si->y)); ScrollMainWindowToTile(TileVirtXY(si->x, si->y));
UpdateSignEditWindow(si); UpdateSignEditWindow(si);
} break; break;
}
case QUERY_EDIT_SIGN_WIDGET_TEXT: case QUERY_EDIT_SIGN_WIDGET_TEXT:
ShowOnScreenKeyboard(this, widget, QUERY_EDIT_SIGN_WIDGET_CANCEL, QUERY_EDIT_SIGN_WIDGET_OK); ShowOnScreenKeyboard(this, widget, QUERY_EDIT_SIGN_WIDGET_CANCEL, QUERY_EDIT_SIGN_WIDGET_OK);