src/vehicle_gui.cpp
branchNewGRF_ports
changeset 10994 cd9968b6f96b
parent 10991 d8811e327d12
equal deleted inserted replaced
10991:d8811e327d12 10994:cd9968b6f96b
    29 #include "functions.h"
    29 #include "functions.h"
    30 #include "window_func.h"
    30 #include "window_func.h"
    31 #include "vehicle_func.h"
    31 #include "vehicle_func.h"
    32 #include "autoreplace_gui.h"
    32 #include "autoreplace_gui.h"
    33 #include "core/alloc_func.hpp"
    33 #include "core/alloc_func.hpp"
       
    34 #include "core/mem_func.hpp"
       
    35 #include "core/sort_func.hpp"
    34 #include "string_func.h"
    36 #include "string_func.h"
    35 #include "settings_type.h"
    37 #include "settings_type.h"
    36 #include "widgets/dropdown_func.h"
    38 #include "widgets/dropdown_func.h"
    37 #include "order_func.h"
    39 #include "order_func.h"
    38 #include "timetable.h"
    40 #include "timetable.h"
    40 
    42 
    41 #include "table/sprites.h"
    43 #include "table/sprites.h"
    42 #include "table/strings.h"
    44 #include "table/strings.h"
    43 
    45 
    44 Sorting _sorting;
    46 Sorting _sorting;
    45 static bool   _internal_sort_order;     // descending/ascending
    47 
    46 
    48 typedef int CDECL VehicleSortListingTypeFunction(const Vehicle* const *, const Vehicle* const *);
    47 typedef int CDECL VehicleSortListingTypeFunction(const void*, const void*);
       
    48 
    49 
    49 static VehicleSortListingTypeFunction VehicleNumberSorter;
    50 static VehicleSortListingTypeFunction VehicleNumberSorter;
    50 static VehicleSortListingTypeFunction VehicleNameSorter;
    51 static VehicleSortListingTypeFunction VehicleNameSorter;
    51 static VehicleSortListingTypeFunction VehicleAgeSorter;
    52 static VehicleSortListingTypeFunction VehicleAgeSorter;
    52 static VehicleSortListingTypeFunction VehicleProfitThisYearSorter;
    53 static VehicleSortListingTypeFunction VehicleProfitThisYearSorter;
    87 	INVALID_STRING_ID
    88 	INVALID_STRING_ID
    88 };
    89 };
    89 
    90 
    90 void BuildVehicleList(VehicleListBase *vl, PlayerID owner, uint16 index, uint16 window_type)
    91 void BuildVehicleList(VehicleListBase *vl, PlayerID owner, uint16 index, uint16 window_type)
    91 {
    92 {
    92 	if (!(vl->vehicles.flags & VL_REBUILD)) return;
    93 	if (!vl->vehicles.NeedRebuild()) return;
    93 
    94 
    94 	DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index);
    95 	DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index);
    95 
    96 
    96 	GenerateVehicleSortList(&vl->vehicles, vl->vehicle_type, owner, index, window_type);
    97 	GenerateVehicleSortList(&vl->vehicles, vl->vehicle_type, owner, index, window_type);
    97 
    98 
    98 	vl->vehicles.flags &= ~VL_REBUILD;
    99 	vl->vehicles.RebuildDone();
    99 	vl->vehicles.flags |= VL_RESORT;
       
   100 }
   100 }
   101 
   101 
   102 /* cached values for VehicleNameSorter to spare many GetString() calls */
   102 /* cached values for VehicleNameSorter to spare many GetString() calls */
   103 static const Vehicle *_last_vehicle[2] = { NULL, NULL };
   103 static const Vehicle *_last_vehicle[2] = { NULL, NULL };
   104 static char           _last_name[2][64] = { "", "" };
       
   105 
   104 
   106 void SortVehicleList(VehicleListBase *vl)
   105 void SortVehicleList(VehicleListBase *vl)
   107 {
   106 {
   108 	if (!(vl->vehicles.flags & VL_RESORT)) return;
   107 	if (vl->vehicles.Sort(_vehicle_sorter[vl->vehicles.SortType()])) return;
   109 
   108 
   110 	/* invalidate cached values for name sorter - vehicle names could change */
   109 	/* invalidate cached values for name sorter - vehicle names could change */
   111 	_last_vehicle[0] = _last_vehicle[1] = NULL;
   110 	_last_vehicle[0] = _last_vehicle[1] = NULL;
   112 
       
   113 	_internal_sort_order = (vl->vehicles.flags & VL_DESC) != 0;
       
   114 	qsort((void*)vl->vehicles.Begin(), vl->vehicles.Length(), sizeof(*vl->vehicles.Begin()),
       
   115 		_vehicle_sorter[vl->vehicles.sort_type]);
       
   116 
       
   117 	vl->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
       
   118 	vl->vehicles.flags &= ~VL_RESORT;
       
   119 }
   111 }
   120 
   112 
   121 void DepotSortList(VehicleList *list)
   113 void DepotSortList(VehicleList *list)
   122 {
   114 {
   123 	_internal_sort_order = 0;
       
   124 	if (list->Length() < 2) return;
   115 	if (list->Length() < 2) return;
   125 	qsort((void*)list->Begin(), list->Length(), sizeof(*list->Begin()), _vehicle_sorter[0]);
   116 	QSortT(list->Begin(), list->Length(), _vehicle_sorter[0]);
   126 }
   117 }
   127 
   118 
   128 /** draw the vehicle profit button in the vehicle list window. */
   119 /** draw the vehicle profit button in the vehicle list window. */
   129 void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
   120 void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
   130 {
   121 {
   505 
   496 
   506 	return DrawStringMultiLine(x, y, STR_SPEC_USERSTRING, w);
   497 	return DrawStringMultiLine(x, y, STR_SPEC_USERSTRING, w);
   507 }
   498 }
   508 
   499 
   509 
   500 
   510 /* if the sorting criteria had the same value, sort vehicle by unitnumber */
   501 /** Sort vehicles by their number */
   511 #define VEHICLEUNITNUMBERSORTER(r, a, b) {if (r == 0) {r = a->unitnumber - b->unitnumber;}}
   502 static int CDECL VehicleNumberSorter(const Vehicle* const *a, const Vehicle* const *b)
   512 
   503 {
   513 static int CDECL VehicleNumberSorter(const void *a, const void *b)
   504 	return (*a)->unitnumber - (*b)->unitnumber;
   514 {
   505 }
   515 	const Vehicle* va = *(const Vehicle**)a;
   506 
   516 	const Vehicle* vb = *(const Vehicle**)b;
   507 /** Sort vehicles by their name */
   517 	int r = va->unitnumber - vb->unitnumber;
   508 static int CDECL VehicleNameSorter(const Vehicle* const *a, const Vehicle* const *b)
   518 
   509 {
   519 	return (_internal_sort_order & 1) ? -r : r;
   510 	static char last_name[2][64];
   520 }
   511 
   521 
   512 	if (*a != _last_vehicle[0]) {
   522 static int CDECL VehicleNameSorter(const void *a, const void *b)
   513 		_last_vehicle[0] = *a;
   523 {
   514 		SetDParam(0, (*a)->index);
   524 	const Vehicle* va = *(const Vehicle**)a;
   515 		GetString(last_name[0], STR_VEHICLE_NAME, lastof(last_name[0]));
   525 	const Vehicle* vb = *(const Vehicle**)b;
   516 	}
   526 	int r;
   517 
   527 
   518 	if (*b != _last_vehicle[1]) {
   528 	if (va != _last_vehicle[0]) {
   519 		_last_vehicle[1] = *b;
   529 		_last_vehicle[0] = va;
   520 		SetDParam(0, (*b)->index);
   530 		SetDParam(0, va->index);
   521 		GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1]));
   531 		GetString(_last_name[0], STR_VEHICLE_NAME, lastof(_last_name[0]));
   522 	}
   532 	}
   523 
   533 
   524 	int r = strcmp(last_name[0], last_name[1]);
   534 	if (vb != _last_vehicle[1]) {
   525 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   535 		_last_vehicle[1] = vb;
   526 }
   536 		SetDParam(0, vb->index);
   527 
   537 		GetString(_last_name[1], STR_VEHICLE_NAME, lastof(_last_name[1]));
   528 /** Sort vehicles by their age */
   538 	}
   529 static int CDECL VehicleAgeSorter(const Vehicle* const *a, const Vehicle* const *b)
   539 
   530 {
   540 	r = strcmp(_last_name[0], _last_name[1]); // sort by name
   531 	int r = (*a)->age - (*b)->age;
   541 
   532 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   542 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   533 }
   543 
   534 
   544 	return (_internal_sort_order & 1) ? -r : r;
   535 /** Sort vehicles by this year profit */
   545 }
   536 static int CDECL VehicleProfitThisYearSorter(const Vehicle* const *a, const Vehicle* const *b)
   546 
   537 {
   547 static int CDECL VehicleAgeSorter(const void *a, const void *b)
   538 	int r = ClampToI32((*a)->GetDisplayProfitThisYear() - (*b)->GetDisplayProfitThisYear());
   548 {
   539 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   549 	const Vehicle* va = *(const Vehicle**)a;
   540 }
   550 	const Vehicle* vb = *(const Vehicle**)b;
   541 
   551 	int r = va->age - vb->age;
   542 /** Sort vehicles by last year profit */
   552 
   543 static int CDECL VehicleProfitLastYearSorter(const Vehicle* const *a, const Vehicle* const *b)
   553 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   544 {
   554 
   545 	int r = ClampToI32((*a)->GetDisplayProfitLastYear() - (*b)->GetDisplayProfitLastYear());
   555 	return (_internal_sort_order & 1) ? -r : r;
   546 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   556 }
   547 }
   557 
   548 
   558 static int CDECL VehicleProfitThisYearSorter(const void *a, const void *b)
   549 /** Sort vehicles by their cargo */
   559 {
   550 static int CDECL VehicleCargoSorter(const Vehicle* const *a, const Vehicle* const *b)
   560 	const Vehicle* va = *(const Vehicle**)a;
   551 {
   561 	const Vehicle* vb = *(const Vehicle**)b;
   552 	const Vehicle *v;
   562 	int r = ClampToI32(va->GetDisplayProfitThisYear() - vb->GetDisplayProfitThisYear());
   553 	AcceptedCargo diff;
   563 
   554 	MemSetT(diff, 0);
   564 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   555 
   565 
   556 	/* Append the cargo of the connected weagons */
   566 	return (_internal_sort_order & 1) ? -r : r;
   557 	for (v = *a; v != NULL; v = v->Next()) diff[v->cargo_type] += v->cargo_cap;
   567 }
   558 	for (v = *b; v != NULL; v = v->Next()) diff[v->cargo_type] -= v->cargo_cap;
   568 
   559 
   569 static int CDECL VehicleProfitLastYearSorter(const void *a, const void *b)
       
   570 {
       
   571 	const Vehicle* va = *(const Vehicle**)a;
       
   572 	const Vehicle* vb = *(const Vehicle**)b;
       
   573 	int r = ClampToI32(va->GetDisplayProfitLastYear() - vb->GetDisplayProfitLastYear());
       
   574 
       
   575 	VEHICLEUNITNUMBERSORTER(r, va, vb);
       
   576 
       
   577 	return (_internal_sort_order & 1) ? -r : r;
       
   578 }
       
   579 
       
   580 static int CDECL VehicleCargoSorter(const void *a, const void *b)
       
   581 {
       
   582 	const Vehicle* va = *(const Vehicle**)a;
       
   583 	const Vehicle* vb = *(const Vehicle**)b;
       
   584 	const Vehicle* v;
       
   585 	AcceptedCargo cargoa;
       
   586 	AcceptedCargo cargob;
       
   587 	int r = 0;
   560 	int r = 0;
   588 
       
   589 	memset(cargoa, 0, sizeof(cargoa));
       
   590 	memset(cargob, 0, sizeof(cargob));
       
   591 	for (v = va; v != NULL; v = v->Next()) cargoa[v->cargo_type] += v->cargo_cap;
       
   592 	for (v = vb; v != NULL; v = v->Next()) cargob[v->cargo_type] += v->cargo_cap;
       
   593 
       
   594 	for (CargoID i = 0; i < NUM_CARGO; i++) {
   561 	for (CargoID i = 0; i < NUM_CARGO; i++) {
   595 		r = cargoa[i] - cargob[i];
   562 		r = diff[i];
   596 		if (r != 0) break;
   563 		if (r != 0) break;
   597 	}
   564 	}
   598 
   565 
   599 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   566 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   600 
   567 }
   601 	return (_internal_sort_order & 1) ? -r : r;
   568 
   602 }
   569 /** Sort vehicles by their reliability */
   603 
   570 static int CDECL VehicleReliabilitySorter(const Vehicle* const *a, const Vehicle* const *b)
   604 static int CDECL VehicleReliabilitySorter(const void *a, const void *b)
   571 {
   605 {
   572 	int r = (*a)->reliability - (*b)->reliability;
   606 	const Vehicle* va = *(const Vehicle**)a;
   573 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   607 	const Vehicle* vb = *(const Vehicle**)b;
   574 }
   608 	int r = va->reliability - vb->reliability;
   575 
   609 
   576 /** Sort vehicles by their max speed */
   610 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   577 static int CDECL VehicleMaxSpeedSorter(const Vehicle* const *a, const Vehicle* const *b)
   611 
   578 {
   612 	return (_internal_sort_order & 1) ? -r : r;
   579 	int r = 0;
   613 }
   580 	if ((*a)->type == VEH_TRAIN && (*b)->type == VEH_TRAIN) {
   614 
   581 		r = (*a)->u.rail.cached_max_speed - (*b)->u.rail.cached_max_speed;
   615 static int CDECL VehicleMaxSpeedSorter(const void *a, const void *b)
       
   616 {
       
   617 	const Vehicle* va = *(const Vehicle**)a;
       
   618 	const Vehicle* vb = *(const Vehicle**)b;
       
   619 	int r;
       
   620 
       
   621 	if (va->type == VEH_TRAIN && vb->type == VEH_TRAIN) {
       
   622 		r = va->u.rail.cached_max_speed - vb->u.rail.cached_max_speed;
       
   623 	} else {
   582 	} else {
   624 		r = va->max_speed - vb->max_speed;
   583 		r = (*a)->max_speed - (*b)->max_speed;
   625 	}
   584 	}
   626 
   585 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   627 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   586 }
   628 
   587 
   629 	return (_internal_sort_order & 1) ? -r : r;
   588 /** Sort vehicles by model */
   630 }
   589 static int CDECL VehicleModelSorter(const Vehicle* const *a, const Vehicle* const *b)
   631 
   590 {
   632 static int CDECL VehicleModelSorter(const void *a, const void *b)
   591 	int r = (*a)->engine_type - (*b)->engine_type;
   633 {
   592 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   634 	const Vehicle* va = *(const Vehicle**)a;
   593 }
   635 	const Vehicle* vb = *(const Vehicle**)b;
   594 
   636 	int r = va->engine_type - vb->engine_type;
   595 /** Sort vehciles by their value */
   637 
   596 static int CDECL VehicleValueSorter(const Vehicle* const *a, const Vehicle* const *b)
   638 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   597 {
   639 
       
   640 	return (_internal_sort_order & 1) ? -r : r;
       
   641 }
       
   642 
       
   643 static int CDECL VehicleValueSorter(const void *a, const void *b)
       
   644 {
       
   645 	const Vehicle* va = *(const Vehicle**)a;
       
   646 	const Vehicle* vb = *(const Vehicle**)b;
       
   647 	const Vehicle *u;
   598 	const Vehicle *u;
   648 	Money valuea = 0, valueb = 0;
   599 	Money diff = 0;
   649 
   600 
   650 	for (u = va; u != NULL; u = u->Next()) valuea += u->value;
   601 	for (u = *a; u != NULL; u = u->Next()) diff += u->value;
   651 	for (u = vb; u != NULL; u = u->Next()) valueb += u->value;
   602 	for (u = *b; u != NULL; u = u->Next()) diff -= u->value;
   652 
   603 
   653 	int r = ClampToI32(valuea - valueb);
   604 	int r = ClampToI32(diff);
   654 
   605 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   655 	VEHICLEUNITNUMBERSORTER(r, va, vb);
   606 }
   656 
   607 
   657 	return (_internal_sort_order & 1) ? -r : r;
   608 /** Sort vehicles by their length */
   658 }
   609 static int CDECL VehicleLengthSorter(const Vehicle* const *a, const Vehicle* const *b)
   659 
   610 {
   660 static int CDECL VehicleLengthSorter(const void *a, const void *b)
       
   661 {
       
   662 	const Vehicle *va = *(const Vehicle**)a;
       
   663 	const Vehicle *vb = *(const Vehicle**)b;
       
   664 	int r = 0;
   611 	int r = 0;
   665 
   612 	switch ((*a)->type) {
   666 	switch (va->type) {
       
   667 		case VEH_TRAIN:
   613 		case VEH_TRAIN:
   668 			r = va->u.rail.cached_total_length - vb->u.rail.cached_total_length;
   614 			r = (*a)->u.rail.cached_total_length - (*b)->u.rail.cached_total_length;
   669 			break;
   615 			break;
   670 
   616 
   671 		case VEH_ROAD:
   617 		case VEH_ROAD: {
   672 			for (const Vehicle *u = va; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length;
   618 			const Vehicle *u;
   673 			for (const Vehicle *u = vb; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length;
   619 			for (u = *a; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length;
   674 			break;
   620 			for (u = *b; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length;
       
   621 		} break;
   675 
   622 
   676 		default: NOT_REACHED();
   623 		default: NOT_REACHED();
   677 	}
   624 	}
   678 
   625 	return (r != 0) ? r : VehicleNumberSorter(a, b);
   679 	VEHICLEUNITNUMBERSORTER(r, va, vb);
       
   680 
       
   681 	return (_internal_sort_order & 1) ? -r : r;
       
   682 }
   626 }
   683 
   627 
   684 void InitializeGUI()
   628 void InitializeGUI()
   685 {
   629 {
   686 	memset(&_sorting, 0, sizeof(_sorting));
   630 	MemSetT(&_sorting, 0);
   687 }
   631 }
   688 
   632 
   689 /** Assigns an already open vehicle window to a new vehicle.
   633 /** Assigns an already open vehicle window to a new vehicle.
   690  * Assigns an already open vehicle window to a new vehicle. If the vehicle got
   634  * Assigns an already open vehicle window to a new vehicle. If the vehicle got
   691  * any sub window open (orders and so on) it will change owner too.
   635  * any sub window open (orders and so on) it will change owner too.
   913 			case VEH_SHIP:     this->sorting = &_sorting.ship; break;
   857 			case VEH_SHIP:     this->sorting = &_sorting.ship; break;
   914 			case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break;
   858 			case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break;
   915 			default: NOT_REACHED(); break;
   859 			default: NOT_REACHED(); break;
   916 		}
   860 		}
   917 
   861 
   918 		this->vehicles.flags = VL_REBUILD | (this->sorting->order ? VL_DESC : VL_NONE);
   862 		this->vehicles.SetListing(*this->sorting);
   919 		this->vehicles.sort_type = this->sorting->criteria;
   863 		this->vehicles.ForceRebuild();
   920 		this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
   864 		this->vehicles.NeedResort();
   921 
   865 
   922 		this->FindWindowPlacementAndResize(desc);
   866 		this->FindWindowPlacementAndResize(desc);
   923 	}
   867 	}
   924 
   868 
   925 	~VehicleListWindow()
   869 	~VehicleListWindow()
   926 	{
   870 	{
       
   871 		*this->sorting = this->vehicles.GetListing();
   927 	}
   872 	}
   928 
   873 
   929 	virtual void OnPaint()
   874 	virtual void OnPaint()
   930 	{
   875 	{
   931 		int x = 2;
   876 		int x = 2;
   986 			WIDGET_LIST_END);
   931 			WIDGET_LIST_END);
   987 
   932 
   988 		this->DrawWidgets();
   933 		this->DrawWidgets();
   989 
   934 
   990 		/* draw sorting criteria string */
   935 		/* draw sorting criteria string */
   991 		DrawString(85, 15, _vehicle_sort_listing[this->vehicles.sort_type], TC_BLACK);
   936 		DrawString(85, 15, _vehicle_sort_listing[this->vehicles.SortType()], TC_BLACK);
   992 		/* draw arrow pointing up/down for ascending/descending sorting */
   937 		/* draw arrow pointing up/down for ascending/descending sorting */
   993 		this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP);
   938 		this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
   994 
   939 
   995 		max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length());
   940 		max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length());
   996 		for (i = this->vscroll.pos; i < max; ++i) {
   941 		for (i = this->vscroll.pos; i < max; ++i) {
   997 			const Vehicle *v = this->vehicles[i];
   942 			const Vehicle *v = this->vehicles[i];
   998 			StringID str;
   943 			StringID str;
  1028 
   973 
  1029 	virtual void OnClick(Point pt, int widget)
   974 	virtual void OnClick(Point pt, int widget)
  1030 	{
   975 	{
  1031 		switch (widget) {
   976 		switch (widget) {
  1032 			case VLW_WIDGET_SORT_ORDER: /* Flip sorting method ascending/descending */
   977 			case VLW_WIDGET_SORT_ORDER: /* Flip sorting method ascending/descending */
  1033 				this->vehicles.flags ^= VL_DESC;
   978 				this->vehicles.ToggleSortOrder();
  1034 				this->vehicles.flags |= VL_RESORT;
       
  1035 
       
  1036 				this->sorting->order = !!(this->vehicles.flags & VL_DESC);
       
  1037 				this->SetDirty();
   979 				this->SetDirty();
  1038 				break;
   980 				break;
  1039 			case VLW_WIDGET_SORT_BY_PULLDOWN:/* Select sorting criteria dropdown menu */
   981 			case VLW_WIDGET_SORT_BY_PULLDOWN:/* Select sorting criteria dropdown menu */
  1040 				ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.sort_type, VLW_WIDGET_SORT_BY_PULLDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10));
   982 				ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.SortType(), VLW_WIDGET_SORT_BY_PULLDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10));
  1041 				return;
   983 				return;
  1042 			case VLW_WIDGET_LIST: { /* Matrix to show vehicles */
   984 			case VLW_WIDGET_LIST: { /* Matrix to show vehicles */
  1043 				uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / this->resize.step_height;
   985 				uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / this->resize.step_height;
  1044 				const Vehicle *v;
   986 				const Vehicle *v;
  1045 
   987 
  1088 
  1030 
  1089 	virtual void OnDropdownSelect(int widget, int index)
  1031 	virtual void OnDropdownSelect(int widget, int index)
  1090 	{
  1032 	{
  1091 		switch (widget) {
  1033 		switch (widget) {
  1092 			case VLW_WIDGET_SORT_BY_PULLDOWN:
  1034 			case VLW_WIDGET_SORT_BY_PULLDOWN:
  1093 				if (this->vehicles.sort_type != index) {
  1035 				this->vehicles.SetSortType(index);
  1094 					/* value has changed -> resort */
       
  1095 					this->vehicles.flags |= VL_RESORT;
       
  1096 					this->vehicles.sort_type = index;
       
  1097 					this->sorting->criteria = this->vehicles.sort_type;
       
  1098 				}
       
  1099 				break;
  1036 				break;
  1100 			case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN:
  1037 			case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN:
  1101 				assert(this->vehicles.Length() != 0);
  1038 				assert(this->vehicles.Length() != 0);
  1102 
  1039 
  1103 				switch (index) {
  1040 				switch (index) {
  1126 	}
  1063 	}
  1127 
  1064 
  1128 	virtual void OnTick()
  1065 	virtual void OnTick()
  1129 	{
  1066 	{
  1130 		if (_pause_game != 0) return;
  1067 		if (_pause_game != 0) return;
  1131 		if (--this->vehicles.resort_timer == 0) {
  1068 		if (this->vehicles.NeedResort()) {
  1132 			StationID station = ((this->window_number & VLW_MASK) == VLW_STATION_LIST) ? GB(this->window_number, 16, 16) : INVALID_STATION;
  1069 			StationID station = ((this->window_number & VLW_MASK) == VLW_STATION_LIST) ? GB(this->window_number, 16, 16) : INVALID_STATION;
  1133 			PlayerID owner = (PlayerID)this->caption_color;
  1070 			PlayerID owner = (PlayerID)this->caption_color;
  1134 
  1071 
  1135 			DEBUG(misc, 3, "Periodic resort %d list player %d at station %d", this->vehicle_type, owner, station);
  1072 			DEBUG(misc, 3, "Periodic resort %d list player %d at station %d", this->vehicle_type, owner, station);
  1136 			this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
       
  1137 			this->vehicles.flags |= VL_RESORT;
       
  1138 			this->SetDirty();
  1073 			this->SetDirty();
  1139 		}
  1074 		}
  1140 	}
  1075 	}
  1141 
  1076 
  1142 	virtual void OnResize(Point new_size, Point delta)
  1077 	virtual void OnResize(Point new_size, Point delta)
  1145 		this->widget[VLW_WIDGET_LIST].data = (this->vscroll.cap << 8) + 1;
  1080 		this->widget[VLW_WIDGET_LIST].data = (this->vscroll.cap << 8) + 1;
  1146 	}
  1081 	}
  1147 
  1082 
  1148 	virtual void OnInvalidateData(int data)
  1083 	virtual void OnInvalidateData(int data)
  1149 	{
  1084 	{
  1150 		this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
  1085 		if (data == 0) {
       
  1086 			this->vehicles.ForceRebuild();
       
  1087 		} else {
       
  1088 			this->vehicles.ForceResort();
       
  1089 		}
  1151 	}
  1090 	}
  1152 };
  1091 };
  1153 
  1092 
  1154 static const WindowDesc _player_vehicle_list_train_desc = {
  1093 static const WindowDesc _player_vehicle_list_train_desc = {
  1155 	WDP_AUTO, WDP_AUTO, 260, 182, 260, 182,
  1094 	WDP_AUTO, WDP_AUTO, 260, 182, 260, 182,