|
|
@ -165,8 +165,7 @@ static int CDECL StationRatingMaxSorter(const void *a, const void *b)
|
|
|
|
return (_internal_sort_order & 1) ? maxr2 - maxr1 : maxr1 - maxr2;
|
|
|
|
return (_internal_sort_order & 1) ? maxr2 - maxr1 : maxr1 - maxr2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
typedef GUIList<const Station*> plstations_d;
|
|
|
|
typedef GUIList<const Station*> GUIStationList;
|
|
|
|
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(plstations_d));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Set the station sort flag for all station-list windows.
|
|
|
|
* Set the station sort flag for all station-list windows.
|
|
|
@ -179,7 +178,7 @@ static void SetStationListsFlag(SortListFlags sl_flag)
|
|
|
|
FOR_ALL_WINDOWS(wz) {
|
|
|
|
FOR_ALL_WINDOWS(wz) {
|
|
|
|
Window *w = *wz;
|
|
|
|
Window *w = *wz;
|
|
|
|
if (w->window_class == WC_STATION_LIST) {
|
|
|
|
if (w->window_class == WC_STATION_LIST) {
|
|
|
|
WP(w, plstations_d).flags |= sl_flag;
|
|
|
|
dynamic_cast<GUIStationList*>(w)->flags |= sl_flag;
|
|
|
|
w->SetDirty();
|
|
|
|
w->SetDirty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -210,7 +209,7 @@ void ResortStationLists()
|
|
|
|
* @param cargo_filter bitmap of cargo types to include
|
|
|
|
* @param cargo_filter bitmap of cargo types to include
|
|
|
|
* @param include_empty whether we should include stations without waiting cargo
|
|
|
|
* @param include_empty whether we should include stations without waiting cargo
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static void BuildStationsList(plstations_d *sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty)
|
|
|
|
static void BuildStationsList(GUIStationList *sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint n = 0;
|
|
|
|
uint n = 0;
|
|
|
|
const Station *st;
|
|
|
|
const Station *st;
|
|
|
@ -260,7 +259,7 @@ static void BuildStationsList(plstations_d *sl, PlayerID owner, byte facilities,
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param sl pointer to plstations_d (station list and flags)
|
|
|
|
* @param sl pointer to plstations_d (station list and flags)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static void SortStationsList(plstations_d *sl)
|
|
|
|
static void SortStationsList(GUIStationList *sl)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
static StationSortListingTypeFunction *const _station_sorter[] = {
|
|
|
|
static StationSortListingTypeFunction *const _station_sorter[] = {
|
|
|
|
&StationNameSorter,
|
|
|
|
&StationNameSorter,
|
|
|
@ -280,287 +279,340 @@ static void SortStationsList(plstations_d *sl)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Fuction called when any WindowEvent occurs for PlayerStations window
|
|
|
|
* The list of stations per player.
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param w pointer to the PlayerStations window
|
|
|
|
|
|
|
|
* @param e pointer to window event
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static void PlayerStationsWndProc(Window *w, WindowEvent *e)
|
|
|
|
struct PlayerStationsWindow : public Window, public GUIStationList
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const PlayerID owner = (PlayerID)w->window_number;
|
|
|
|
static Listing station_sort;
|
|
|
|
static byte facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
|
|
|
|
static byte facilities;
|
|
|
|
static Listing station_sort = {0, 0};
|
|
|
|
static bool include_empty;
|
|
|
|
static bool include_empty = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plstations_d *sl = &WP(w, plstations_d);
|
|
|
|
PlayerStationsWindow(const WindowDesc *desc, void *data, WindowNumber window_number) : Window(desc, data, window_number)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this->caption_color = (byte)this->window_number;
|
|
|
|
|
|
|
|
this->vscroll.cap = 12;
|
|
|
|
|
|
|
|
this->resize.step_height = 10;
|
|
|
|
|
|
|
|
this->resize.height = this->height - 10 * 7; // minimum if 5 in the list
|
|
|
|
|
|
|
|
|
|
|
|
switch (e->event) {
|
|
|
|
/* Add cargo filter buttons */
|
|
|
|
case WE_CREATE:
|
|
|
|
uint num_active = 0;
|
|
|
|
if (_cargo_filter == _cargo_filter_max) _cargo_filter = _cargo_mask;
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
if (GetCargo(c)->IsValid()) num_active++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < 5; i++) {
|
|
|
|
this->widget_count += num_active;
|
|
|
|
if (HasBit(facilities, i)) w->LowerWidget(i + SLW_TRAIN);
|
|
|
|
this->widget = ReallocT(this->widget, this->widget_count + 1);
|
|
|
|
}
|
|
|
|
this->widget[this->widget_count].type = WWT_LAST;
|
|
|
|
w->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
|
|
|
|
|
|
|
|
w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
|
|
|
|
|
|
|
|
w->SetWidgetLoweredState(SLW_NOCARGOWAITING, include_empty);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sl->sort_list = NULL;
|
|
|
|
uint i = 0;
|
|
|
|
sl->flags = VL_REBUILD;
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
sl->sort_type = station_sort.criteria;
|
|
|
|
if (!GetCargo(c)->IsValid()) continue;
|
|
|
|
if (station_sort.order) sl->flags |= VL_DESC;
|
|
|
|
|
|
|
|
|
|
|
|
Widget *wi = &this->widget[SLW_CARGOSTART + i];
|
|
|
|
|
|
|
|
wi->type = WWT_PANEL;
|
|
|
|
|
|
|
|
wi->display_flags = RESIZE_NONE;
|
|
|
|
|
|
|
|
wi->color = 14;
|
|
|
|
|
|
|
|
wi->left = 89 + i * 14;
|
|
|
|
|
|
|
|
wi->right = wi->left + 13;
|
|
|
|
|
|
|
|
wi->top = 14;
|
|
|
|
|
|
|
|
wi->bottom = 24;
|
|
|
|
|
|
|
|
wi->data = 0;
|
|
|
|
|
|
|
|
wi->tooltips = STR_USE_CTRL_TO_SELECT_MORE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (HasBit(_cargo_filter, c)) this->LowerWidget(SLW_CARGOSTART + i);
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* set up resort timer */
|
|
|
|
this->widget[SLW_NOCARGOWAITING].left += num_active * 14;
|
|
|
|
sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
|
|
|
|
this->widget[SLW_NOCARGOWAITING].right += num_active * 14;
|
|
|
|
break;
|
|
|
|
this->widget[SLW_CARGOALL].left += num_active * 14;
|
|
|
|
|
|
|
|
this->widget[SLW_CARGOALL].right += num_active * 14;
|
|
|
|
|
|
|
|
this->widget[SLW_PAN_RIGHT].left += num_active * 14;
|
|
|
|
|
|
|
|
|
|
|
|
case WE_PAINT: {
|
|
|
|
if (num_active > 15) {
|
|
|
|
BuildStationsList(sl, owner, facilities, _cargo_filter, include_empty);
|
|
|
|
/* Resize and fix the minimum width, if necessary */
|
|
|
|
SortStationsList(sl);
|
|
|
|
ResizeWindow(this, (num_active - 15) * 14, 0);
|
|
|
|
|
|
|
|
this->resize.width = this->width;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SetVScrollCount(w, sl->list_length);
|
|
|
|
if (_cargo_filter == _cargo_filter_max) _cargo_filter = _cargo_mask;
|
|
|
|
|
|
|
|
|
|
|
|
/* draw widgets, with player's name in the caption */
|
|
|
|
for (uint i = 0; i < 5; i++) {
|
|
|
|
SetDParam(0, owner);
|
|
|
|
if (HasBit(facilities, i)) this->LowerWidget(i + SLW_TRAIN);
|
|
|
|
SetDParam(1, w->vscroll.count);
|
|
|
|
}
|
|
|
|
|
|
|
|
this->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
|
|
|
|
|
|
|
|
this->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
|
|
|
|
|
|
|
|
this->SetWidgetLoweredState(SLW_NOCARGOWAITING, include_empty);
|
|
|
|
|
|
|
|
|
|
|
|
/* Set text of sort by dropdown */
|
|
|
|
this->sort_list = NULL;
|
|
|
|
w->widget[SLW_SORTDROPBTN].data = _station_sort_listing[sl->sort_type];
|
|
|
|
this->flags = VL_REBUILD;
|
|
|
|
|
|
|
|
this->sort_type = station_sort.criteria;
|
|
|
|
|
|
|
|
if (station_sort.order) this->flags |= VL_DESC;
|
|
|
|
|
|
|
|
|
|
|
|
DrawWindowWidgets(w);
|
|
|
|
/* set up resort timer */
|
|
|
|
|
|
|
|
this->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* draw arrow pointing up/down for ascending/descending sorting */
|
|
|
|
virtual void OnPaint()
|
|
|
|
DrawSortButtonState(w, SLW_SORTBY, sl->flags & VL_DESC ? SBS_DOWN : SBS_UP);
|
|
|
|
{
|
|
|
|
|
|
|
|
PlayerID owner = (PlayerID)this->window_number;
|
|
|
|
|
|
|
|
|
|
|
|
int cg_ofst;
|
|
|
|
BuildStationsList(this, owner, facilities, _cargo_filter, include_empty);
|
|
|
|
int x = 89;
|
|
|
|
SortStationsList(this);
|
|
|
|
int y = 14;
|
|
|
|
|
|
|
|
int xb = 2; ///< offset from left of widget
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint i = 0;
|
|
|
|
SetVScrollCount(this, this->list_length);
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
const CargoSpec *cs = GetCargo(c);
|
|
|
|
|
|
|
|
if (!cs->IsValid()) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cg_ofst = HasBit(_cargo_filter, c) ? 2 : 1;
|
|
|
|
/* draw widgets, with player's name in the caption */
|
|
|
|
GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour);
|
|
|
|
SetDParam(0, owner);
|
|
|
|
DrawStringCentered(x + 6 + cg_ofst, y + cg_ofst, cs->abbrev, TC_BLACK);
|
|
|
|
SetDParam(1, this->vscroll.count);
|
|
|
|
x += 14;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x += 6;
|
|
|
|
/* Set text of sort by dropdown */
|
|
|
|
cg_ofst = w->IsWidgetLowered(SLW_NOCARGOWAITING) ? 2 : 1;
|
|
|
|
this->widget[SLW_SORTDROPBTN].data = _station_sort_listing[this->sort_type];
|
|
|
|
DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_NONE, TC_BLACK);
|
|
|
|
|
|
|
|
|
|
|
|
DrawWindowWidgets(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* draw arrow pointing up/down for ascending/descending sorting */
|
|
|
|
|
|
|
|
DrawSortButtonState(this, SLW_SORTBY, this->flags & VL_DESC ? SBS_DOWN : SBS_UP);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int cg_ofst;
|
|
|
|
|
|
|
|
int x = 89;
|
|
|
|
|
|
|
|
int y = 14;
|
|
|
|
|
|
|
|
int xb = 2; ///< offset from left of widget
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint i = 0;
|
|
|
|
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
const CargoSpec *cs = GetCargo(c);
|
|
|
|
|
|
|
|
if (!cs->IsValid()) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cg_ofst = HasBit(_cargo_filter, c) ? 2 : 1;
|
|
|
|
|
|
|
|
GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour);
|
|
|
|
|
|
|
|
DrawStringCentered(x + 6 + cg_ofst, y + cg_ofst, cs->abbrev, TC_BLACK);
|
|
|
|
x += 14;
|
|
|
|
x += 14;
|
|
|
|
cg_ofst = w->IsWidgetLowered(SLW_CARGOALL) ? 2 : 1;
|
|
|
|
i++;
|
|
|
|
DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_ALL, TC_BLACK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cg_ofst = w->IsWidgetLowered(SLW_FACILALL) ? 2 : 1;
|
|
|
|
x += 6;
|
|
|
|
DrawString(71 + cg_ofst, y + cg_ofst, STR_ABBREV_ALL, TC_BLACK);
|
|
|
|
cg_ofst = this->IsWidgetLowered(SLW_NOCARGOWAITING) ? 2 : 1;
|
|
|
|
|
|
|
|
DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_NONE, TC_BLACK);
|
|
|
|
|
|
|
|
x += 14;
|
|
|
|
|
|
|
|
cg_ofst = this->IsWidgetLowered(SLW_CARGOALL) ? 2 : 1;
|
|
|
|
|
|
|
|
DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_ALL, TC_BLACK);
|
|
|
|
|
|
|
|
|
|
|
|
if (w->vscroll.count == 0) { // player has no stations
|
|
|
|
cg_ofst = this->IsWidgetLowered(SLW_FACILALL) ? 2 : 1;
|
|
|
|
DrawString(xb, 40, STR_304A_NONE, TC_FROMSTRING);
|
|
|
|
DrawString(71 + cg_ofst, y + cg_ofst, STR_ABBREV_ALL, TC_BLACK);
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int max = min(w->vscroll.pos + w->vscroll.cap, sl->list_length);
|
|
|
|
if (this->vscroll.count == 0) { // player has no stations
|
|
|
|
y = 40; // start of the list-widget
|
|
|
|
DrawString(xb, 40, STR_304A_NONE, TC_FROMSTRING);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = w->vscroll.pos; i < max; ++i) { // do until max number of stations of owner
|
|
|
|
int max = min(this->vscroll.pos + this->vscroll.cap, this->list_length);
|
|
|
|
const Station *st = sl->sort_list[i];
|
|
|
|
y = 40; // start of the list-widget
|
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(st->xy != 0);
|
|
|
|
for (int i = this->vscroll.pos; i < max; ++i) { // do until max number of stations of owner
|
|
|
|
|
|
|
|
const Station *st = this->sort_list[i];
|
|
|
|
|
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
|
|
/* Do not do the complex check HasStationInUse here, it may be even false
|
|
|
|
assert(st->xy != 0);
|
|
|
|
* when the order had been removed and the station list hasn't been removed yet */
|
|
|
|
|
|
|
|
assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SetDParam(0, st->index);
|
|
|
|
/* Do not do the complex check HasStationInUse here, it may be even false
|
|
|
|
SetDParam(1, st->facilities);
|
|
|
|
* when the order had been removed and the station list hasn't been removed yet */
|
|
|
|
x = DrawString(xb, y, STR_3049_0, TC_FROMSTRING) + 5;
|
|
|
|
assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
|
|
|
|
|
|
|
|
|
|
|
|
/* show cargo waiting and station ratings */
|
|
|
|
SetDParam(0, st->index);
|
|
|
|
for (CargoID j = 0; j < NUM_CARGO; j++) {
|
|
|
|
SetDParam(1, st->facilities);
|
|
|
|
if (!st->goods[j].cargo.Empty()) {
|
|
|
|
x = DrawString(xb, y, STR_3049_0, TC_FROMSTRING) + 5;
|
|
|
|
StationsWndShowStationRating(x, y, j, st->goods[j].cargo.Count(), st->goods[j].rating);
|
|
|
|
|
|
|
|
x += 20;
|
|
|
|
/* show cargo waiting and station ratings */
|
|
|
|
}
|
|
|
|
for (CargoID j = 0; j < NUM_CARGO; j++) {
|
|
|
|
|
|
|
|
if (!st->goods[j].cargo.Empty()) {
|
|
|
|
|
|
|
|
StationsWndShowStationRating(x, y, j, st->goods[j].cargo.Count(), st->goods[j].rating);
|
|
|
|
|
|
|
|
x += 20;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
y += 10;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
y += 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case WE_CLICK:
|
|
|
|
virtual void OnClick(Point pt, int widget)
|
|
|
|
switch (e->we.click.widget) {
|
|
|
|
{
|
|
|
|
case SLW_LIST: {
|
|
|
|
PlayerID owner = (PlayerID)this->window_number;
|
|
|
|
uint32 id_v = (e->we.click.pt.y - 41) / 10;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (id_v >= w->vscroll.cap) return; // click out of bounds
|
|
|
|
switch (widget) {
|
|
|
|
|
|
|
|
case SLW_LIST: {
|
|
|
|
|
|
|
|
uint32 id_v = (pt.y - 41) / 10;
|
|
|
|
|
|
|
|
|
|
|
|
id_v += w->vscroll.pos;
|
|
|
|
if (id_v >= this->vscroll.cap) return; // click out of bounds
|
|
|
|
|
|
|
|
|
|
|
|
if (id_v >= sl->list_length) return; // click out of list bound
|
|
|
|
id_v += this->vscroll.pos;
|
|
|
|
|
|
|
|
|
|
|
|
const Station *st = sl->sort_list[id_v];
|
|
|
|
if (id_v >= this->list_length) return; // click out of list bound
|
|
|
|
/* do not check HasStationInUse - it is slow and may be invalid */
|
|
|
|
|
|
|
|
assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
const Station *st = this->sort_list[id_v];
|
|
|
|
ShowExtraViewPortWindow(st->xy);
|
|
|
|
/* do not check HasStationInUse - it is slow and may be invalid */
|
|
|
|
} else {
|
|
|
|
assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
|
|
|
|
ScrollMainWindowToTile(st->xy);
|
|
|
|
|
|
|
|
}
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
break;
|
|
|
|
ShowExtraViewPortWindow(st->xy);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ScrollMainWindowToTile(st->xy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_TRAIN:
|
|
|
|
case SLW_TRAIN:
|
|
|
|
case SLW_TRUCK:
|
|
|
|
case SLW_TRUCK:
|
|
|
|
case SLW_BUS:
|
|
|
|
case SLW_BUS:
|
|
|
|
case SLW_AIRPLANE:
|
|
|
|
case SLW_AIRPLANE:
|
|
|
|
case SLW_SHIP:
|
|
|
|
case SLW_SHIP:
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
ToggleBit(facilities, e->we.click.widget - SLW_TRAIN);
|
|
|
|
ToggleBit(facilities, widget - SLW_TRAIN);
|
|
|
|
w->ToggleWidgetLoweredState(e->we.click.widget);
|
|
|
|
this->ToggleWidgetLoweredState(widget);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
uint i;
|
|
|
|
uint i;
|
|
|
|
FOR_EACH_SET_BIT(i, facilities) {
|
|
|
|
FOR_EACH_SET_BIT(i, facilities) {
|
|
|
|
w->RaiseWidget(i + SLW_TRAIN);
|
|
|
|
this->RaiseWidget(i + SLW_TRAIN);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetBit(facilities, e->we.click.widget - SLW_TRAIN);
|
|
|
|
|
|
|
|
w->LowerWidget(e->we.click.widget);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
w->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
|
|
|
|
|
|
|
|
sl->flags |= VL_REBUILD;
|
|
|
|
|
|
|
|
w->SetDirty();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_FACILALL:
|
|
|
|
|
|
|
|
for (uint i = 0; i < 5; i++) {
|
|
|
|
|
|
|
|
w->LowerWidget(i + SLW_TRAIN);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w->LowerWidget(SLW_FACILALL);
|
|
|
|
SetBit(facilities, widget - SLW_TRAIN);
|
|
|
|
|
|
|
|
this->LowerWidget(widget);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
|
|
|
|
|
|
|
|
this->flags |= VL_REBUILD;
|
|
|
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
|
|
|
|
case SLW_FACILALL:
|
|
|
|
sl->flags |= VL_REBUILD;
|
|
|
|
for (uint i = 0; i < 5; i++) {
|
|
|
|
w->SetDirty();
|
|
|
|
this->LowerWidget(i + SLW_TRAIN);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->LowerWidget(SLW_FACILALL);
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_CARGOALL: {
|
|
|
|
facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
|
|
|
|
uint i = 0;
|
|
|
|
this->flags |= VL_REBUILD;
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
this->SetDirty();
|
|
|
|
if (!GetCargo(c)->IsValid()) continue;
|
|
|
|
break;
|
|
|
|
w->LowerWidget(i + SLW_CARGOSTART);
|
|
|
|
|
|
|
|
i++;
|
|
|
|
case SLW_CARGOALL: {
|
|
|
|
|
|
|
|
uint i = 0;
|
|
|
|
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
if (!GetCargo(c)->IsValid()) continue;
|
|
|
|
|
|
|
|
this->LowerWidget(i + SLW_CARGOSTART);
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this->LowerWidget(SLW_NOCARGOWAITING);
|
|
|
|
|
|
|
|
this->LowerWidget(SLW_CARGOALL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_cargo_filter = _cargo_mask;
|
|
|
|
|
|
|
|
include_empty = true;
|
|
|
|
|
|
|
|
this->flags |= VL_REBUILD;
|
|
|
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_SORTBY: // flip sorting method asc/desc
|
|
|
|
|
|
|
|
this->flags ^= VL_DESC; //DESC-flag
|
|
|
|
|
|
|
|
station_sort.order = HasBit(this->flags, 0);
|
|
|
|
|
|
|
|
this->flags |= VL_RESORT;
|
|
|
|
|
|
|
|
this->flags4 |= 5 << WF_TIMEOUT_SHL;
|
|
|
|
|
|
|
|
this->LowerWidget(SLW_SORTBY);
|
|
|
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_SORTDROPBTN: // select sorting criteria dropdown menu
|
|
|
|
|
|
|
|
ShowDropDownMenu(this, _station_sort_listing, this->sort_type, SLW_SORTDROPBTN, 0, 0);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_NOCARGOWAITING:
|
|
|
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
|
|
|
|
include_empty = !include_empty;
|
|
|
|
|
|
|
|
this->ToggleWidgetLoweredState(SLW_NOCARGOWAITING);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
for (uint i = SLW_CARGOSTART; i < this->widget_count; i++) {
|
|
|
|
|
|
|
|
this->RaiseWidget(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w->LowerWidget(SLW_NOCARGOWAITING);
|
|
|
|
|
|
|
|
w->LowerWidget(SLW_CARGOALL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_cargo_filter = _cargo_mask;
|
|
|
|
_cargo_filter = 0;
|
|
|
|
include_empty = true;
|
|
|
|
include_empty = true;
|
|
|
|
sl->flags |= VL_REBUILD;
|
|
|
|
|
|
|
|
w->SetDirty();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_SORTBY: // flip sorting method asc/desc
|
|
|
|
this->LowerWidget(SLW_NOCARGOWAITING);
|
|
|
|
sl->flags ^= VL_DESC; //DESC-flag
|
|
|
|
}
|
|
|
|
station_sort.order = HasBit(sl->flags, 0);
|
|
|
|
this->flags |= VL_REBUILD;
|
|
|
|
sl->flags |= VL_RESORT;
|
|
|
|
this->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
|
|
|
|
w->flags4 |= 5 << WF_TIMEOUT_SHL;
|
|
|
|
this->SetDirty();
|
|
|
|
w->LowerWidget(SLW_SORTBY);
|
|
|
|
break;
|
|
|
|
w->SetDirty();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_SORTDROPBTN: // select sorting criteria dropdown menu
|
|
|
|
default:
|
|
|
|
ShowDropDownMenu(w, _station_sort_listing, sl->sort_type, SLW_SORTDROPBTN, 0, 0);
|
|
|
|
if (widget >= SLW_CARGOSTART) { // change cargo_filter
|
|
|
|
break;
|
|
|
|
/* Determine the selected cargo type */
|
|
|
|
|
|
|
|
CargoID c;
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
for (c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
if (!GetCargo(c)->IsValid()) continue;
|
|
|
|
|
|
|
|
if (widget - SLW_CARGOSTART == i) break;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case SLW_NOCARGOWAITING:
|
|
|
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
include_empty = !include_empty;
|
|
|
|
ToggleBit(_cargo_filter, c);
|
|
|
|
w->ToggleWidgetLoweredState(SLW_NOCARGOWAITING);
|
|
|
|
this->ToggleWidgetLoweredState(widget);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
for (uint i = SLW_CARGOSTART; i < w->widget_count; i++) {
|
|
|
|
for (uint i = SLW_CARGOSTART; i < this->widget_count; i++) {
|
|
|
|
w->RaiseWidget(i);
|
|
|
|
this->RaiseWidget(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this->RaiseWidget(SLW_NOCARGOWAITING);
|
|
|
|
|
|
|
|
|
|
|
|
_cargo_filter = 0;
|
|
|
|
_cargo_filter = 0;
|
|
|
|
include_empty = true;
|
|
|
|
include_empty = false;
|
|
|
|
|
|
|
|
|
|
|
|
w->LowerWidget(SLW_NOCARGOWAITING);
|
|
|
|
SetBit(_cargo_filter, c);
|
|
|
|
|
|
|
|
this->LowerWidget(widget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sl->flags |= VL_REBUILD;
|
|
|
|
this->flags |= VL_REBUILD;
|
|
|
|
w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
|
|
|
|
this->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
|
|
|
|
w->SetDirty();
|
|
|
|
this->SetDirty();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
if (e->we.click.widget >= SLW_CARGOSTART) { // change cargo_filter
|
|
|
|
}
|
|
|
|
/* Determine the selected cargo type */
|
|
|
|
|
|
|
|
CargoID c;
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
for (c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
if (!GetCargo(c)->IsValid()) continue;
|
|
|
|
|
|
|
|
if (e->we.click.widget - SLW_CARGOSTART == i) break;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_ctrl_pressed) {
|
|
|
|
|
|
|
|
ToggleBit(_cargo_filter, c);
|
|
|
|
|
|
|
|
w->ToggleWidgetLoweredState(e->we.click.widget);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
for (uint i = SLW_CARGOSTART; i < w->widget_count; i++) {
|
|
|
|
|
|
|
|
w->RaiseWidget(i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
w->RaiseWidget(SLW_NOCARGOWAITING);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_cargo_filter = 0;
|
|
|
|
virtual void OnDropdownSelect(int widget, int index)
|
|
|
|
include_empty = false;
|
|
|
|
{
|
|
|
|
|
|
|
|
if (this->sort_type != index) {
|
|
|
|
|
|
|
|
/* value has changed -> resort */
|
|
|
|
|
|
|
|
this->sort_type = index;
|
|
|
|
|
|
|
|
station_sort.criteria = this->sort_type;
|
|
|
|
|
|
|
|
this->flags |= VL_RESORT;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SetBit(_cargo_filter, c);
|
|
|
|
virtual void OnTick()
|
|
|
|
w->LowerWidget(e->we.click.widget);
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if (_pause_game != 0) return;
|
|
|
|
sl->flags |= VL_REBUILD;
|
|
|
|
if (--this->resort_timer == 0) {
|
|
|
|
w->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
|
|
|
|
DEBUG(misc, 3, "Periodic rebuild station list player %d", this->window_number);
|
|
|
|
w->SetDirty();
|
|
|
|
this->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
|
|
|
|
}
|
|
|
|
this->flags |= VL_REBUILD;
|
|
|
|
break;
|
|
|
|
this->SetDirty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list
|
|
|
|
|
|
|
|
if (sl->sort_type != e->we.dropdown.index) {
|
|
|
|
|
|
|
|
/* value has changed -> resort */
|
|
|
|
|
|
|
|
sl->sort_type = e->we.dropdown.index;
|
|
|
|
|
|
|
|
station_sort.criteria = sl->sort_type;
|
|
|
|
|
|
|
|
sl->flags |= VL_RESORT;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
w->SetDirty();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case WE_TICK:
|
|
|
|
|
|
|
|
if (_pause_game != 0) break;
|
|
|
|
|
|
|
|
if (--sl->resort_timer == 0) {
|
|
|
|
|
|
|
|
DEBUG(misc, 3, "Periodic rebuild station list player %d", owner);
|
|
|
|
|
|
|
|
sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
|
|
|
|
|
|
|
|
sl->flags |= VL_REBUILD;
|
|
|
|
|
|
|
|
w->SetDirty();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case WE_TIMEOUT:
|
|
|
|
virtual void OnTimeout()
|
|
|
|
w->RaiseWidget(SLW_SORTBY);
|
|
|
|
{
|
|
|
|
w->SetDirty();
|
|
|
|
this->RaiseWidget(SLW_SORTBY);
|
|
|
|
break;
|
|
|
|
this->SetDirty();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case WE_RESIZE:
|
|
|
|
virtual void OnResize(Point new_size, Point delta)
|
|
|
|
w->vscroll.cap += e->we.sizing.diff.y / 10;
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
this->vscroll.cap += delta.y / 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Listing PlayerStationsWindow::station_sort = {0, 0};
|
|
|
|
|
|
|
|
byte PlayerStationsWindow::facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
|
|
|
|
|
|
|
|
bool PlayerStationsWindow::include_empty = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const Widget _player_stations_widgets[] = {
|
|
|
|
static const Widget _player_stations_widgets[] = {
|
|
|
|
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // SLW_CLOSEBOX
|
|
|
|
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // SLW_CLOSEBOX
|
|
|
@ -593,7 +645,7 @@ static const WindowDesc _player_stations_desc = {
|
|
|
|
WC_STATION_LIST, WC_NONE,
|
|
|
|
WC_STATION_LIST, WC_NONE,
|
|
|
|
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_RESIZABLE,
|
|
|
|
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_RESIZABLE,
|
|
|
|
_player_stations_widgets,
|
|
|
|
_player_stations_widgets,
|
|
|
|
PlayerStationsWndProc
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -605,54 +657,7 @@ void ShowPlayerStations(PlayerID player)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!IsValidPlayer(player)) return;
|
|
|
|
if (!IsValidPlayer(player)) return;
|
|
|
|
|
|
|
|
|
|
|
|
Window *w = AllocateWindowDescFront<Window>(&_player_stations_desc, player);
|
|
|
|
AllocateWindowDescFront<PlayerStationsWindow>(&_player_stations_desc, player);
|
|
|
|
if (w == NULL) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w->caption_color = (byte)w->window_number;
|
|
|
|
|
|
|
|
w->vscroll.cap = 12;
|
|
|
|
|
|
|
|
w->resize.step_height = 10;
|
|
|
|
|
|
|
|
w->resize.height = w->height - 10 * 7; // minimum if 5 in the list
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Add cargo filter buttons */
|
|
|
|
|
|
|
|
uint num_active = 0;
|
|
|
|
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
if (GetCargo(c)->IsValid()) num_active++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w->widget_count += num_active;
|
|
|
|
|
|
|
|
w->widget = ReallocT(w->widget, w->widget_count + 1);
|
|
|
|
|
|
|
|
w->widget[w->widget_count].type = WWT_LAST;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint i = 0;
|
|
|
|
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
|
|
|
|
|
|
|
if (!GetCargo(c)->IsValid()) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Widget *wi = &w->widget[SLW_CARGOSTART + i];
|
|
|
|
|
|
|
|
wi->type = WWT_PANEL;
|
|
|
|
|
|
|
|
wi->display_flags = RESIZE_NONE;
|
|
|
|
|
|
|
|
wi->color = 14;
|
|
|
|
|
|
|
|
wi->left = 89 + i * 14;
|
|
|
|
|
|
|
|
wi->right = wi->left + 13;
|
|
|
|
|
|
|
|
wi->top = 14;
|
|
|
|
|
|
|
|
wi->bottom = 24;
|
|
|
|
|
|
|
|
wi->data = 0;
|
|
|
|
|
|
|
|
wi->tooltips = STR_USE_CTRL_TO_SELECT_MORE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (HasBit(_cargo_filter, c)) w->LowerWidget(SLW_CARGOSTART + i);
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w->widget[SLW_NOCARGOWAITING].left += num_active * 14;
|
|
|
|
|
|
|
|
w->widget[SLW_NOCARGOWAITING].right += num_active * 14;
|
|
|
|
|
|
|
|
w->widget[SLW_CARGOALL].left += num_active * 14;
|
|
|
|
|
|
|
|
w->widget[SLW_CARGOALL].right += num_active * 14;
|
|
|
|
|
|
|
|
w->widget[SLW_PAN_RIGHT].left += num_active * 14;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (num_active > 15) {
|
|
|
|
|
|
|
|
/* Resize and fix the minimum width, if necessary */
|
|
|
|
|
|
|
|
ResizeWindow(w, (num_active - 15) * 14, 0);
|
|
|
|
|
|
|
|
w->resize.width = w->width;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const Widget _station_view_widgets[] = {
|
|
|
|
static const Widget _station_view_widgets[] = {
|
|
|
|