(svn r2079) -Add: signlist, shows all signs in the map. Clicking on them, and you go

to the sign. Very needed for coop. You can find it under World Map.
This commit is contained in:
truelight 2005-03-26 21:22:29 +00:00
parent 45425bedca
commit e416fe8066
7 changed files with 178 additions and 5 deletions

View File

@ -6,6 +6,9 @@
#include "gfx.h"
#include "player.h"
#include "economy.h"
#include "signs.h"
#include "strings.h"
#include "debug.h"
static uint _legend_excludebits;
static uint _legend_cargobits;
@ -1098,3 +1101,149 @@ void ShowPerformanceRatingDetail(void)
{
AllocateWindowDescFront(&_performance_rating_detail_desc, 0);
}
static uint16 _num_sign_sort;
static char _bufcache[64];
static uint16 _last_sign_idx;
static int CDECL SignNameSorter(const void *a, const void *b)
{
char buf1[64];
SignStruct *ss;
const uint16 cmp1 = *(const uint16 *)a;
const uint16 cmp2 = *(const uint16 *)b;
ss = GetSign(cmp1);
GetString(buf1, ss->str);
if (cmp2 != _last_sign_idx) {
_last_sign_idx = cmp2;
ss = GetSign(cmp2);
GetString(_bufcache, ss->str);
}
return strcmp(buf1, _bufcache); // sort by name
}
static void GlobalSortSignList(void)
{
const SignStruct *ss;
uint32 n = 0;
_num_sign_sort = 0;
/* Create array for sorting */
_sign_sort = realloc(_sign_sort, GetSignPoolSize() * sizeof(_sign_sort[0]));
if (_sign_sort == NULL)
error("Could not allocate memory for the sign-sorting-list");
FOR_ALL_SIGNS(ss) {
if(ss->str != STR_NULL) {
_sign_sort[n++] = ss->index;
_num_sign_sort++;
}
}
qsort(_sign_sort, n, sizeof(_sign_sort[0]), SignNameSorter);
_sign_sort_dirty = false;
DEBUG(misc, 1) ("Resorting global sign list...");
}
static void SignListWndProc(Window *w, WindowEvent *e)
{
switch (e->event) {
case WE_PAINT: {
uint32 i;
int y = 16; // offset from top of widget
if (_sign_sort_dirty)
GlobalSortSignList();
SetVScrollCount(w, _num_sign_sort);
SetDParam(0, w->vscroll.count);
DrawWindowWidgets(w);
/* No signs? */
if (w->vscroll.count == 0) {
DrawString(2, y, STR_304A_NONE, 0);
return;
}
{
SignStruct *ss;
/* Start drawing the signs */
i = 0;
for (i = w->vscroll.pos; i < (uint)w->vscroll.cap + w->vscroll.pos && i < w->vscroll.count; i++) {
ss = GetSign(_sign_sort[i]);
if (ss->owner != OWNER_NONE)
DrawPlayerIcon(ss->owner, 4, y + 1);
DrawString(22, y, ss->str, 8);
y += 10;
}
}
} break;
case WE_CLICK: {
switch (e->click.widget) {
case 3: {
uint32 id_v = (e->click.pt.y - 15) / 10;
SignStruct *ss;
if (id_v >= w->vscroll.cap)
return;
id_v += w->vscroll.pos;
if (id_v >= w->vscroll.count)
return;
ss = GetSign(_sign_sort[id_v]);
ScrollMainWindowToTile(TILE_FROM_XY(ss->x, ss->y));
} break;
}
} break;
case WE_RESIZE:
w->vscroll.cap += e->sizing.diff.y / 10;
break;
}
}
static const Widget _sign_list_widget[] = {
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 345, 0, 13, STR_SIGN_LIST_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
{ WWT_STICKYBOX, RESIZE_LR, 14, 346, 357, 0, 13, 0x0, STR_STICKY_BUTTON},
{ WWT_PANEL, RESIZE_RB, 14, 0, 345, 14, 137, 0x0, STR_NULL},
{ WWT_SCROLLBAR, RESIZE_LRB, 14, 346, 357, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 346, 357, 126, 137, 0x0, STR_RESIZE_BUTTON},
{ WIDGETS_END},
};
static const WindowDesc _sign_list_desc = {
-1, -1, 358, 138,
WC_SIGN_LIST,0,
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_RESIZABLE,
_sign_list_widget,
SignListWndProc
};
void ShowSignList(void)
{
Window *w;
w = AllocateWindowDescFront(&_sign_list_desc, 0);
if (w != NULL) {
w->vscroll.cap = 12;
w->resize.step_height = 10;
w->resize.height = w->height - 10 * 7; // minimum if 5 in the list
}
}

1
gui.h
View File

@ -75,6 +75,7 @@ void ShowSubsidiesList(void);
void ShowPlayerStations(int player);
void ShowPlayerFinances(int player);
void ShowPlayerCompany(int player);
void ShowSignList(void);
void ShowEstimatedCostOrIncome(int32 cost, int x, int y);
void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y);

View File

@ -772,6 +772,7 @@ STR_02DC_DISPLAY_SUBSIDIES :{BLACK}Display subsidies
STR_02DD_SUBSIDIES :Subsidies
STR_02DE_MAP_OF_WORLD :Map of world
STR_EXTRA_VIEW_PORT :Extra viewport
STR_SIGN_LIST :Sign list
STR_02DF_TOWN_DIRECTORY :Town directory
STR_TOWN_POPULATION :{BLACK}World population: {COMMA32}
STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Viewport {COMMA16}
@ -2796,6 +2797,7 @@ STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Displays which engine the left sele
STR_REPLACE_HELP :{BLACK}This allows you to replace one engine type with another type, when trains of the original type enter a depot
STR_SHORT_DATE :{WHITE}{DATE_TINY}
STR_SIGN_LIST_CAPTION :{WHITE}Sign List - {COMMA16} Signs
############ Lists rail types

View File

@ -233,6 +233,7 @@ static void MenuClickMap(int index)
switch(index) {
case 0: ShowSmallMap(); break;
case 1: ShowExtraViewPortWindow(); break;
case 2: ShowSignList(); break;
}
}
@ -778,7 +779,7 @@ static void ToolbarSaveClick(Window *w)
static void ToolbarMapClick(Window *w)
{
PopupMainToolbMenu(w, 96, 4, STR_02DE_MAP_OF_WORLD, 2);
PopupMainToolbMenu(w, 96, 4, STR_02DE_MAP_OF_WORLD, 3);
}
static void ToolbarTownClick(Window *w)

24
signs.c
View File

@ -4,6 +4,7 @@
#include "signs.h"
#include "saveload.h"
#include "command.h"
#include "strings.h"
enum {
/* Max signs: 64000 (4 * 16000) */
@ -75,10 +76,17 @@ static void MarkSignDirty(SignStruct *ss)
*/
static SignStruct *AllocateSign(void)
{
SignStruct *s;
FOR_ALL_SIGNS(s)
if (s->str == 0)
return s;
SignStruct *ss;
FOR_ALL_SIGNS(ss) {
if (ss->str == 0) {
uint index = ss->index;
memset(ss, 0, sizeof(SignStruct));
ss->index = index;
return ss;
}
}
/* Check if we can add a block to the pool */
if (AddBlockToPool(&_sign_pool))
@ -112,6 +120,8 @@ int32 CmdPlaceSign(int x, int y, uint32 flags, uint32 p1, uint32 p2)
ss->z = GetSlopeZ(x,y);
UpdateSignVirtCoords(ss);
MarkSignDirty(ss);
InvalidateWindow(WC_SIGN_LIST, 0);
_sign_sort_dirty = true;
_new_sign_struct = ss;
}
@ -151,6 +161,8 @@ int32 CmdRenameSign(int x, int y, uint32 flags, uint32 sign_id, uint32 owner)
/* Update */
UpdateSignVirtCoords(ss);
MarkSignDirty(ss);
InvalidateWindow(WC_SIGN_LIST, 0);
_sign_sort_dirty = true;
} else {
/* Free the name, because we did not assign it yet */
DeleteName(str);
@ -165,6 +177,8 @@ int32 CmdRenameSign(int x, int y, uint32 flags, uint32 sign_id, uint32 owner)
ss->str = 0;
MarkSignDirty(ss);
InvalidateWindow(WC_SIGN_LIST, 0);
_sign_sort_dirty = true;
}
}
@ -252,6 +266,8 @@ static void Load_SIGN(void)
ss = GetSign(index);
SlObject(ss, _sign_desc);
}
_sign_sort_dirty = true;
}
const ChunkHandler _sign_chunk_handlers[] = {

View File

@ -46,6 +46,9 @@ static inline uint16 GetSignPoolSize(void)
VARDEF SignStruct *_new_sign_struct;
VARDEF bool _sign_sort_dirty;
VARDEF uint16 *_sign_sort;
void UpdateAllSignVirtCoords(void);
void PlaceProc_Sign(uint tile);

1
ttd.h
View File

@ -425,6 +425,7 @@ enum {
WC_CUSTOM_CURRENCY = 0x4B,
WC_REPLACE_VEHICLE = 0x4C,
WC_HIGHSCORE_ENDSCREEN = 0x4D,
WC_SIGN_LIST = 0x4E,
};